001: /*
002: * ProGuard -- shrinking, optimization, obfuscation, and preverification
003: * of Java bytecode.
004: *
005: * Copyright (c) 2002-2007 Eric Lafortune (eric@graphics.cornell.edu)
006: *
007: * This program is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU General Public License as published by the Free
009: * Software Foundation; either version 2 of the License, or (at your option)
010: * any later version.
011: *
012: * This program is distributed in the hope that it will be useful, but WITHOUT
013: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
014: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
015: * more details.
016: *
017: * You should have received a copy of the GNU General Public License along
018: * with this program; if not, write to the Free Software Foundation, Inc.,
019: * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
020: */
021: package proguard.io;
022:
023: import proguard.util.ExtensionMatcher;
024:
025: import java.io.*;
026:
027: /**
028: * This DataEntryReader writes the ZIP entries and files that it reads to a
029: * given DataEntryWriter.
030: *
031: * @author Eric Lafortune
032: */
033: public class DataEntryCopier implements DataEntryReader {
034: private static final int BUFFER_SIZE = 1024;
035:
036: private final DataEntryWriter dataEntryWriter;
037: private final byte[] buffer = new byte[BUFFER_SIZE];
038:
039: public DataEntryCopier(DataEntryWriter dataEntryWriter) {
040: this .dataEntryWriter = dataEntryWriter;
041: }
042:
043: // Implementations for DataEntryReader.
044:
045: public void read(DataEntry dataEntry) throws IOException {
046: try {
047: // Get the output entry corresponding to this input entry.
048: OutputStream outputStream = dataEntryWriter
049: .getOutputStream(dataEntry);
050: if (outputStream != null) {
051: InputStream inputStream = dataEntry.getInputStream();
052:
053: // Copy the data from the input entry to the output entry.
054: copyData(inputStream, outputStream);
055:
056: // Close the data entries.
057: dataEntry.closeInputStream();
058: }
059: } catch (IOException ex) {
060: System.err.println("Warning: can't write resource ["
061: + dataEntry.getName() + "] (" + ex.getMessage()
062: + ")");
063: }
064: }
065:
066: // Small utility methods.
067:
068: /**
069: * Copies all data that it can read from the given input stream to the
070: * given output stream.
071: */
072: private void copyData(InputStream inputStream,
073: OutputStream outputStream) throws IOException {
074: while (true) {
075: int count = inputStream.read(buffer);
076: if (count < 0) {
077: break;
078: }
079: outputStream.write(buffer, 0, count);
080: }
081:
082: outputStream.flush();
083: }
084:
085: /**
086: * A main method for testing file/jar/war/directory copying.
087: */
088: public static void main(String[] args) {
089: try {
090: String input = args[0];
091: String output = args[1];
092:
093: boolean outputIsJar = output.endsWith(".jar");
094: boolean outputIsWar = output.endsWith(".war");
095: boolean outputIsEar = output.endsWith(".ear");
096: boolean outputIsZip = output.endsWith(".zip");
097:
098: DataEntryWriter writer = new DirectoryWriter(new File(
099: output), outputIsJar || outputIsWar || outputIsEar
100: || outputIsZip);
101:
102: if (!outputIsJar) {
103: // Zip up any zips, if necessary.
104: DataEntryWriter zipWriter = new JarWriter(writer);
105: if (outputIsZip) {
106: // Always zip.
107: writer = zipWriter;
108: } else {
109: // Only zip up zips.
110: writer = new FilteredDataEntryWriter(
111: new DataEntryParentFilter(
112: new DataEntryNameFilter(
113: new ExtensionMatcher(".zip"))),
114: zipWriter, writer);
115: }
116:
117: // Zip up any wars, if necessary.
118: DataEntryWriter warWriter = new JarWriter(writer);
119: if (outputIsWar) {
120: // Always zip.
121: writer = warWriter;
122: } else {
123: // Only zip up wars.
124: writer = new FilteredDataEntryWriter(
125: new DataEntryParentFilter(
126: new DataEntryNameFilter(
127: new ExtensionMatcher(".war"))),
128: warWriter, writer);
129: }
130: }
131:
132: // Zip up any jars, if necessary.
133: DataEntryWriter jarWriter = new JarWriter(writer);
134: if (outputIsJar) {
135: // Always zip.
136: writer = jarWriter;
137: } else {
138: // Only zip up jars.
139: writer = new FilteredDataEntryWriter(
140: new DataEntryParentFilter(
141: new DataEntryNameFilter(
142: new ExtensionMatcher(".jar"))),
143: jarWriter, writer);
144: }
145:
146: // Create the copying DataEntryReader.
147: DataEntryReader reader = new DataEntryCopier(writer);
148:
149: boolean inputIsJar = input.endsWith(".jar");
150: boolean inputIsWar = input.endsWith(".war");
151: boolean inputIsZip = input.endsWith(".zip");
152:
153: // Unzip any jars, if necessary.
154: DataEntryReader jarReader = new JarReader(reader);
155: if (inputIsJar) {
156: // Always unzip.
157: reader = jarReader;
158: } else {
159: // Only unzip jar entries.
160: reader = new FilteredDataEntryReader(
161: new DataEntryNameFilter(new ExtensionMatcher(
162: ".jar")), jarReader, reader);
163:
164: // Unzip any wars, if necessary.
165: DataEntryReader warReader = new JarReader(reader);
166: if (inputIsWar) {
167: // Always unzip.
168: reader = warReader;
169: } else {
170: // Only unzip war entries.
171: reader = new FilteredDataEntryReader(
172: new DataEntryNameFilter(
173: new ExtensionMatcher(".war")),
174: warReader, reader);
175: }
176:
177: // Unzip any zips, if necessary.
178: DataEntryReader zipReader = new JarReader(reader);
179: if (inputIsZip) {
180: // Always unzip.
181: reader = zipReader;
182: } else {
183: // Only unzip zip entries.
184: reader = new FilteredDataEntryReader(
185: new DataEntryNameFilter(
186: new ExtensionMatcher(".zip")),
187: zipReader, reader);
188: }
189: }
190:
191: DirectoryPump directoryReader = new DirectoryPump(new File(
192: input));
193:
194: directoryReader.pumpDataEntries(reader);
195:
196: writer.close();
197: } catch (Exception ex) {
198: ex.printStackTrace();
199: }
200: }
201: }
|