• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * ProGuard -- shrinking, optimization, obfuscation, and preverification
3  *             of Java bytecode.
4  *
5  * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
6  *
7  * This program is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU General Public License as published by the Free
9  * Software Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * This program is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15  * more details.
16  *
17  * You should have received a copy of the GNU General Public License along
18  * with this program; if not, write to the Free Software Foundation, Inc.,
19  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20  */
21 package proguard.io;
22 
23 import proguard.util.ExtensionMatcher;
24 
25 import java.io.*;
26 
27 
28 /**
29  * This DataEntryReader writes the ZIP entries and files that it reads to a
30  * given DataEntryWriter.
31  *
32  * @author Eric Lafortune
33  */
34 public class DataEntryCopier implements DataEntryReader
35 {
36     private static final int BUFFER_SIZE = 1024;
37 
38     private final DataEntryWriter dataEntryWriter;
39     private final byte[]          buffer = new byte[BUFFER_SIZE];
40 
41 
42 
DataEntryCopier(DataEntryWriter dataEntryWriter)43     public DataEntryCopier(DataEntryWriter dataEntryWriter)
44     {
45         this.dataEntryWriter = dataEntryWriter;
46     }
47 
48 
49     // Implementations for DataEntryReader.
50 
read(DataEntry dataEntry)51     public void read(DataEntry dataEntry) throws IOException
52     {
53         try
54         {
55             if (dataEntry.isDirectory())
56             {
57                 dataEntryWriter.createDirectory(dataEntry);
58             }
59             else
60             {
61                 // Get the output entry corresponding to this input entry.
62                 OutputStream outputStream = dataEntryWriter.getOutputStream(dataEntry);
63                 if (outputStream != null)
64                 {
65                     InputStream inputStream = dataEntry.getInputStream();
66 
67                     try
68                     {
69                         // Copy the data from the input entry to the output entry.
70                         copyData(inputStream, outputStream);
71                     }
72                     finally
73                     {
74                         // Close the data entries.
75                         dataEntry.closeInputStream();
76                     }
77                 }
78             }
79         }
80         catch (IOException ex)
81         {
82             System.err.println("Warning: can't write resource [" + dataEntry.getName() + "] (" + ex.getMessage() + ")");
83         }
84         catch (Exception ex)
85         {
86             throw (IOException)new IOException("Can't write resource ["+dataEntry.getName()+"] ("+ex.getMessage()+")").initCause(ex);
87         }
88     }
89 
90 
91     /**
92      * Copies all data that it can read from the given input stream to the
93      * given output stream.
94      */
copyData(InputStream inputStream, OutputStream outputStream)95     protected void copyData(InputStream  inputStream,
96                             OutputStream outputStream)
97     throws IOException
98     {
99         while (true)
100         {
101             int count = inputStream.read(buffer);
102             if (count < 0)
103             {
104                 break;
105             }
106             outputStream.write(buffer, 0, count);
107         }
108 
109         outputStream.flush();
110     }
111 
112 
113     /**
114      * A main method for testing file/jar/war/directory copying.
115      */
main(String[] args)116     public static void main(String[] args)
117     {
118         try
119         {
120             String input  = args[0];
121             String output = args[1];
122 
123             boolean outputIsJar = output.endsWith(".jar");
124             boolean outputIsWar = output.endsWith(".war");
125             boolean outputIsEar = output.endsWith(".ear");
126             boolean outputIsZip = output.endsWith(".zip");
127 
128             DataEntryWriter writer = new DirectoryWriter(new File(output),
129                                                          outputIsJar ||
130                                                          outputIsWar ||
131                                                          outputIsEar ||
132                                                          outputIsZip);
133 
134         if (!outputIsJar)
135         {
136             // Zip up any zips, if necessary.
137             DataEntryWriter zipWriter = new JarWriter(writer);
138             if (outputIsZip)
139             {
140                 // Always zip.
141                 writer = zipWriter;
142             }
143             else
144             {
145                 // Only zip up zips.
146                 writer = new FilteredDataEntryWriter(new DataEntryParentFilter(
147                                                      new DataEntryNameFilter(
148                                                      new ExtensionMatcher(".zip"))),
149                                                      zipWriter,
150                                                      writer);
151             }
152 
153             // Zip up any wars, if necessary.
154             DataEntryWriter warWriter = new JarWriter(writer);
155             if (outputIsWar)
156             {
157                 // Always zip.
158                 writer = warWriter;
159             }
160             else
161             {
162                 // Only zip up wars.
163                 writer = new FilteredDataEntryWriter(new DataEntryParentFilter(
164                                                      new DataEntryNameFilter(
165                                                      new ExtensionMatcher(".war"))),
166                                                      warWriter,
167                                                      writer);
168             }
169         }
170 
171         // Zip up any jars, if necessary.
172         DataEntryWriter jarWriter = new JarWriter(writer);
173         if (outputIsJar)
174         {
175             // Always zip.
176             writer = jarWriter;
177         }
178         else
179         {
180             // Only zip up jars.
181             writer = new FilteredDataEntryWriter(new DataEntryParentFilter(
182                                                  new DataEntryNameFilter(
183                                                  new ExtensionMatcher(".jar"))),
184                                                  jarWriter,
185                                                  writer);
186         }
187 
188 
189             // Create the copying DataEntryReader.
190             DataEntryReader reader = new DataEntryCopier(writer);
191 
192 
193             boolean inputIsJar = input.endsWith(".jar");
194             boolean inputIsWar = input.endsWith(".war");
195             boolean inputIsZip = input.endsWith(".zip");
196 
197             // Unzip any jars, if necessary.
198             DataEntryReader jarReader = new JarReader(reader);
199             if (inputIsJar)
200             {
201                 // Always unzip.
202                 reader = jarReader;
203             }
204             else
205             {
206                 // Only unzip jar entries.
207                 reader = new FilteredDataEntryReader(new DataEntryNameFilter(
208                                                      new ExtensionMatcher(".jar")),
209                                                      jarReader,
210                                                      reader);
211 
212                 // Unzip any wars, if necessary.
213                 DataEntryReader warReader = new JarReader(reader);
214                 if (inputIsWar)
215                 {
216                     // Always unzip.
217                     reader = warReader;
218                 }
219                 else
220                 {
221                     // Only unzip war entries.
222                     reader = new FilteredDataEntryReader(new DataEntryNameFilter(
223                                                          new ExtensionMatcher(".war")),
224                                                          warReader,
225                                                          reader);
226                 }
227 
228                 // Unzip any zips, if necessary.
229                 DataEntryReader zipReader = new JarReader(reader);
230                 if (inputIsZip)
231                 {
232                     // Always unzip.
233                     reader = zipReader;
234                 }
235                 else
236                 {
237                     // Only unzip zip entries.
238                     reader = new FilteredDataEntryReader(new DataEntryNameFilter(
239                                                          new ExtensionMatcher(".zip")),
240                                                          zipReader,
241                                                          reader);
242                 }
243             }
244 
245             DirectoryPump directoryReader = new DirectoryPump(new File(input));
246 
247             directoryReader.pumpDataEntries(reader);
248 
249             writer.close();
250         }
251         catch (Exception ex)
252         {
253             ex.printStackTrace();
254         }
255     }
256 }
257