1 /*
2 * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package com.sun.java.util.jar.pack;
27
28 import java.util.*;
29 import java.util.jar.*;
30 import java.util.zip.*;
31 import java.util.logging.*;
32 import java.io.*;
33
34 class Utils {
35 static final String COM_PREFIX = "com.sun.java.util.jar.pack.";
36 static final String METAINF = "META-INF";
37
38 /*
39 * Outputs various diagnostic support information.
40 * If >0, print summary comments (e.g., constant pool info).
41 * If >1, print unit comments (e.g., processing of classes).
42 * If >2, print many comments (e.g., processing of members).
43 * If >3, print tons of comments (e.g., processing of references).
44 * (installer only)
45 */
46 static final String DEBUG_VERBOSE = Utils.COM_PREFIX+"verbose";
47
48 /*
49 * Disables use of native code, prefers the Java-coded implementation.
50 * (installer only)
51 */
52 static final String DEBUG_DISABLE_NATIVE = COM_PREFIX+"disable.native";
95 // com...dump.bands=false dump band contents to local disk
96 // com...no.vary.codings=false turn off coding variation heuristics
97 // com...no.big.strings=false turn off "big string" feature
98
99 /*
100 * If this property is set to {@link #TRUE}, the packer will preserve
101 * the ordering of class files of the original jar in the output archive.
102 * The ordering is preserved only for class-files; resource files
103 * may be reordered.
104 * <p>
105 * If the packer is allowed to reorder class files, it can marginally
106 * decrease the transmitted size of the archive.
107 */
108 static final String PACK_KEEP_CLASS_ORDER = COM_PREFIX+"keep.class.order";
109 /*
110 * This string PACK200 is given as a zip comment on all JAR files
111 * produced by this utility.
112 */
113 static final String PACK_ZIP_ARCHIVE_MARKER_COMMENT = "PACK200";
114
115 // Keep a TLS point to the current Packer or Unpacker.
116 // This makes it simpler to supply environmental options
117 // to the engine code, especially the native code.
118 static final ThreadLocal currentInstance = new ThreadLocal();
119
120 static PropMap currentPropMap() {
121 Object obj = currentInstance.get();
122 if (obj instanceof PackerImpl)
123 return ((PackerImpl)obj)._props;
124 if (obj instanceof UnpackerImpl)
125 return ((UnpackerImpl)obj)._props;
126 return null;
127 }
128
129 static final boolean nolog
130 = Boolean.getBoolean(Utils.COM_PREFIX+"nolog");
131
132
133 static final Logger log
134 = new Logger("java.util.jar.Pack200", null) {
135 public void log(LogRecord record) {
136 int verbose = currentPropMap().getInteger(DEBUG_VERBOSE);
137 if (verbose > 0) {
138 if (nolog &&
139 record.getLevel().intValue() < Level.WARNING.intValue()) {
140 System.out.println(record.getMessage());
141 } else {
142 super.log(record);
143 }
144 }
145 }
169 // -0 mode helper
170 static void copyJarFile(JarInputStream in, JarOutputStream out) throws IOException {
171 if (in.getManifest() != null) {
172 ZipEntry me = new ZipEntry(JarFile.MANIFEST_NAME);
173 out.putNextEntry(me);
174 in.getManifest().write(out);
175 out.closeEntry();
176 }
177 byte[] buffer = new byte[1 << 14];
178 for (JarEntry je; (je = in.getNextJarEntry()) != null; ) {
179 out.putNextEntry(je);
180 for (int nr; 0 < (nr = in.read(buffer)); ) {
181 out.write(buffer, 0, nr);
182 }
183 }
184 in.close();
185 markJarFile(out); // add PACK200 comment
186 }
187 static void copyJarFile(JarFile in, JarOutputStream out) throws IOException {
188 byte[] buffer = new byte[1 << 14];
189 for (Enumeration e = in.entries(); e.hasMoreElements(); ) {
190 JarEntry je = (JarEntry) e.nextElement();
191 out.putNextEntry(je);
192 InputStream ein = in.getInputStream(je);
193 for (int nr; 0 < (nr = ein.read(buffer)); ) {
194 out.write(buffer, 0, nr);
195 }
196 }
197 in.close();
198 markJarFile(out); // add PACK200 comment
199 }
200 static void copyJarFile(JarInputStream in, OutputStream out) throws IOException {
201 // 4947205 : Peformance is slow when using pack-effort=0
202 out = new BufferedOutputStream(out);
203 out = new NonCloser(out); // protect from JarOutputStream.close()
204 JarOutputStream jout = new JarOutputStream(out);
205 copyJarFile(in, jout);
206 jout.close();
207 }
208 static void copyJarFile(JarFile in, OutputStream out) throws IOException {
209
210 // 4947205 : Peformance is slow when using pack-effort=0
213 JarOutputStream jout = new JarOutputStream(out);
214 copyJarFile(in, jout);
215 jout.close();
216 }
217 // Wrapper to prevent closing of client-supplied stream.
218 static private
219 class NonCloser extends FilterOutputStream {
220 NonCloser(OutputStream out) { super(out); }
221 public void close() throws IOException { flush(); }
222 }
223 static String getJarEntryName(String name) {
224 if (name == null) return null;
225 return name.replace(File.separatorChar, '/');
226 }
227
228 static String zeString(ZipEntry ze) {
229 int store = (ze.getCompressedSize() > 0) ?
230 (int)( (1.0 - ((double)ze.getCompressedSize()/(double)ze.getSize()))*100 )
231 : 0 ;
232 // Follow unzip -lv output
233 return (long)ze.getSize() + "\t" + ze.getMethod()
234 + "\t" + ze.getCompressedSize() + "\t"
235 + store + "%\t"
236 + new Date(ze.getTime()) + "\t"
237 + Long.toHexString(ze.getCrc()) + "\t"
238 + ze.getName() ;
239 }
240
241
242
243 static byte[] readMagic(BufferedInputStream in) throws IOException {
244 in.mark(4);
245 byte[] magic = new byte[4];
246 for (int i = 0; i < magic.length; i++) {
247 // read 1 byte at a time, so we always get 4
248 if (1 != in.read(magic, i, 1))
249 break;
250 }
251 in.reset();
252 return magic;
253 }
| 1 /*
2 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package com.sun.java.util.jar.pack;
27
28 import com.sun.java.util.jar.pack.Attribute.Layout;
29 import com.sun.java.util.jar.pack.ConstantPool.ClassEntry;
30 import com.sun.java.util.jar.pack.ConstantPool.DescriptorEntry;
31 import com.sun.java.util.jar.pack.ConstantPool.LiteralEntry;
32 import com.sun.java.util.jar.pack.ConstantPool.MemberEntry;
33 import com.sun.java.util.jar.pack.ConstantPool.SignatureEntry;
34 import com.sun.java.util.jar.pack.ConstantPool.Utf8Entry;
35 import java.io.BufferedInputStream;
36 import java.io.BufferedOutputStream;
37 import java.io.File;
38 import java.io.FilterOutputStream;
39 import java.io.IOException;
40 import java.io.InputStream;
41 import java.io.OutputStream;
42 import java.util.Date;
43 import java.util.Enumeration;
44 import java.util.Map;
45 import java.util.jar.JarEntry;
46 import java.util.jar.JarFile;
47 import java.util.jar.JarInputStream;
48 import java.util.jar.JarOutputStream;
49 import java.util.logging.Level;
50 import java.util.logging.Logger;
51 import java.util.logging.LogManager;
52 import java.util.logging.LogRecord;
53 import java.util.zip.ZipEntry;
54
55 class Utils {
56 static final String COM_PREFIX = "com.sun.java.util.jar.pack.";
57 static final String METAINF = "META-INF";
58
59 /*
60 * Outputs various diagnostic support information.
61 * If >0, print summary comments (e.g., constant pool info).
62 * If >1, print unit comments (e.g., processing of classes).
63 * If >2, print many comments (e.g., processing of members).
64 * If >3, print tons of comments (e.g., processing of references).
65 * (installer only)
66 */
67 static final String DEBUG_VERBOSE = Utils.COM_PREFIX+"verbose";
68
69 /*
70 * Disables use of native code, prefers the Java-coded implementation.
71 * (installer only)
72 */
73 static final String DEBUG_DISABLE_NATIVE = COM_PREFIX+"disable.native";
116 // com...dump.bands=false dump band contents to local disk
117 // com...no.vary.codings=false turn off coding variation heuristics
118 // com...no.big.strings=false turn off "big string" feature
119
120 /*
121 * If this property is set to {@link #TRUE}, the packer will preserve
122 * the ordering of class files of the original jar in the output archive.
123 * The ordering is preserved only for class-files; resource files
124 * may be reordered.
125 * <p>
126 * If the packer is allowed to reorder class files, it can marginally
127 * decrease the transmitted size of the archive.
128 */
129 static final String PACK_KEEP_CLASS_ORDER = COM_PREFIX+"keep.class.order";
130 /*
131 * This string PACK200 is given as a zip comment on all JAR files
132 * produced by this utility.
133 */
134 static final String PACK_ZIP_ARCHIVE_MARKER_COMMENT = "PACK200";
135
136 // Keep a TLS point to the global data and environment.
137 // This makes it simpler to supply environmental options
138 // to the engine code, especially the native code.
139 static final ThreadLocal<TLGlobals> currentInstance = new ThreadLocal<TLGlobals>();
140
141 // convenience methods to access the TL globals
142 static TLGlobals getTLGlobals() {
143 return currentInstance.get();
144 }
145
146 static Map<String, Utf8Entry> getUtf8Entries() {
147 return getTLGlobals().getUtf8Entries();
148 }
149
150 static Map<String, ClassEntry> getClassEntries() {
151 return getTLGlobals().getClassEntries();
152 }
153
154 static Map<Object, LiteralEntry> getLiteralEntries() {
155 return getTLGlobals().getLiteralEntries();
156 }
157
158 static Map<String, DescriptorEntry> getDescriptorEntries() {
159 return getTLGlobals().getDescriptorEntries();
160 }
161
162 static Map<String, SignatureEntry> getSignatureEntries() {
163 return getTLGlobals().getSignatureEntries();
164 }
165
166 static Map<String, MemberEntry> getMemberEntries() {
167 return getTLGlobals().getMemberEntries();
168 }
169
170 static PropMap currentPropMap() {
171 Object obj = currentInstance.get();
172 if (obj instanceof PackerImpl)
173 return ((PackerImpl)obj).props;
174 if (obj instanceof UnpackerImpl)
175 return ((UnpackerImpl)obj).props;
176 return null;
177 }
178
179 static final boolean nolog
180 = Boolean.getBoolean(Utils.COM_PREFIX+"nolog");
181
182
183 static final Logger log
184 = new Logger("java.util.jar.Pack200", null) {
185 public void log(LogRecord record) {
186 int verbose = currentPropMap().getInteger(DEBUG_VERBOSE);
187 if (verbose > 0) {
188 if (nolog &&
189 record.getLevel().intValue() < Level.WARNING.intValue()) {
190 System.out.println(record.getMessage());
191 } else {
192 super.log(record);
193 }
194 }
195 }
219 // -0 mode helper
220 static void copyJarFile(JarInputStream in, JarOutputStream out) throws IOException {
221 if (in.getManifest() != null) {
222 ZipEntry me = new ZipEntry(JarFile.MANIFEST_NAME);
223 out.putNextEntry(me);
224 in.getManifest().write(out);
225 out.closeEntry();
226 }
227 byte[] buffer = new byte[1 << 14];
228 for (JarEntry je; (je = in.getNextJarEntry()) != null; ) {
229 out.putNextEntry(je);
230 for (int nr; 0 < (nr = in.read(buffer)); ) {
231 out.write(buffer, 0, nr);
232 }
233 }
234 in.close();
235 markJarFile(out); // add PACK200 comment
236 }
237 static void copyJarFile(JarFile in, JarOutputStream out) throws IOException {
238 byte[] buffer = new byte[1 << 14];
239 for (Enumeration<JarEntry> e = in.entries(); e.hasMoreElements(); ) {
240 JarEntry je = e.nextElement();
241 out.putNextEntry(je);
242 InputStream ein = in.getInputStream(je);
243 for (int nr; 0 < (nr = ein.read(buffer)); ) {
244 out.write(buffer, 0, nr);
245 }
246 }
247 in.close();
248 markJarFile(out); // add PACK200 comment
249 }
250 static void copyJarFile(JarInputStream in, OutputStream out) throws IOException {
251 // 4947205 : Peformance is slow when using pack-effort=0
252 out = new BufferedOutputStream(out);
253 out = new NonCloser(out); // protect from JarOutputStream.close()
254 JarOutputStream jout = new JarOutputStream(out);
255 copyJarFile(in, jout);
256 jout.close();
257 }
258 static void copyJarFile(JarFile in, OutputStream out) throws IOException {
259
260 // 4947205 : Peformance is slow when using pack-effort=0
263 JarOutputStream jout = new JarOutputStream(out);
264 copyJarFile(in, jout);
265 jout.close();
266 }
267 // Wrapper to prevent closing of client-supplied stream.
268 static private
269 class NonCloser extends FilterOutputStream {
270 NonCloser(OutputStream out) { super(out); }
271 public void close() throws IOException { flush(); }
272 }
273 static String getJarEntryName(String name) {
274 if (name == null) return null;
275 return name.replace(File.separatorChar, '/');
276 }
277
278 static String zeString(ZipEntry ze) {
279 int store = (ze.getCompressedSize() > 0) ?
280 (int)( (1.0 - ((double)ze.getCompressedSize()/(double)ze.getSize()))*100 )
281 : 0 ;
282 // Follow unzip -lv output
283 return ze.getSize() + "\t" + ze.getMethod()
284 + "\t" + ze.getCompressedSize() + "\t"
285 + store + "%\t"
286 + new Date(ze.getTime()) + "\t"
287 + Long.toHexString(ze.getCrc()) + "\t"
288 + ze.getName() ;
289 }
290
291
292
293 static byte[] readMagic(BufferedInputStream in) throws IOException {
294 in.mark(4);
295 byte[] magic = new byte[4];
296 for (int i = 0; i < magic.length; i++) {
297 // read 1 byte at a time, so we always get 4
298 if (1 != in.read(magic, i, 1))
299 break;
300 }
301 in.reset();
302 return magic;
303 }
|