* Lists contents of JAR file, via ZipFile. */ void list(String fname, String files[]) throws IOException { ZipFile zf = new ZipFile(fname); Enumeration<? extends ZipEntry> zes = zf.entries(); while (zes.hasMoreElements()) { printEntry(zes.nextElement(), files); } zf.close(); } /** * Outputs the class index table to the INDEX.LIST file of the * root jar file. */ void dumpIndex(String rootjar, JarIndex index) throws IOException { File jarFile = new File(rootjar); Path jarPath = jarFile.toPath(); Path tmpPath = createTempFileInSameDirectoryAs(jarFile).toPath(); try { if (update(Files.newInputStream(jarPath), Files.newOutputStream(tmpPath), null, index)) { try { Files.move(tmpPath, jarPath, REPLACE_EXISTING); } catch (IOException e) { throw new IOException(getMsg("error.write.file"), e); } } } finally { Files.deleteIfExists(tmpPath); } } private HashSet<String> jarPaths = new HashSet<String>(); /** * Generates the transitive closure of the Class-Path attribute for * the specified jar file. */ List<String> getJarPath(String jar) throws IOException { List<String> files = new ArrayList<String>(); files.add(jar); jarPaths.add(jar); // take out the current path String path = jar.substring(0, Math.max(0, jar.lastIndexOf('/') + 1)); // class path attribute will give us jar file name with // '/' as separators, so we need to change them to the // appropriate one before we open the jar file. JarFile rf = new JarFile(jar.replace('/', File.separatorChar)); if (rf != null) { Manifest man = rf.getManifest(); if (man != null) { Attributes attr = man.getMainAttributes(); if (attr != null) { String value = attr.getValue(Attributes.Name.CLASS_PATH); if (value != null) { StringTokenizer st = new StringTokenizer(value); while (st.hasMoreTokens()) { String ajar = st.nextToken(); if (!ajar.endsWith("/")) { // it is a jar file ajar = path.concat(ajar); /* check on cyclic dependency */ if (! jarPaths.contains(ajar)) { files.addAll(getJarPath(ajar)); } } } } } } } rf.close(); return files; } /** * Generates class index file for the specified root jar file. */ void genIndex(String rootjar, String[] files) throws IOException { List<String> jars = getJarPath(rootjar); int njars = jars.size(); String[] jarfiles; if (njars == 1 && files != null) { // no class-path attribute defined in rootjar, will // use command line specified list of jars for (int i = 0; i < files.length; i++) { jars.addAll(getJarPath(files[i])); } njars = jars.size(); } jarfiles = jars.toArray(new String[njars]); JarIndex index = new JarIndex(jarfiles); dumpIndex(rootjar, index); } /** * Prints entry information, if requested. */ void printEntry(ZipEntry e, String[] files) throws IOException { if (files == null) { printEntry(e); } else { String name = e.getName(); for (String file : files) { if (name.startsWith(file)) { printEntry(e); return; } } } } /** * Prints entry information. */ void printEntry(ZipEntry e) throws IOException { if (vflag) { StringBuilder sb = new StringBuilder(); String s = Long.toString(e.getSize()); for (int i = 6 - s.length(); i > 0; --i) { sb.append(' '); } sb.append(s).append(' ').append(new Date(e.getTime()).toString()); sb.append(' ').append(e.getName()); output(sb.toString()); } else { output(e.getName()); } } /** * Prints usage message. */ void usageError() { error(getMsg("usage")); } /** * A fatal exception has been caught. No recovery possible */ void fatalError(Exception e) { e.printStackTrace(); } /** * A fatal condition has been detected; message is "s". * No recovery possible */ void fatalError(String s) { error(program + ": " + s); } /** * Print an output message; like verbose output and the like */ protected void output(String s) { out.println(s); } /** * Print an error mesage; like something is broken */ protected void error(String s) { err.println(s); } /** * Main routine to start program. */ public static void main(String args[]) { Main jartool = new Main(System.out, System.err, "jar"); System.exit(jartool.run(args) ? 0 : 1); } /** * An OutputStream that doesn't send its output anywhere, (but could). * It's here to find the CRC32 of an input file, necessary for STORED * mode in ZIP. */ private static class CRC32OutputStream extends java.io.OutputStream { final CRC32 crc = new CRC32(); long n = 0; CRC32OutputStream() {} public void write(int r) throws IOException { crc.update(r); n++; } public void write(byte[] b, int off, int len) throws IOException { crc.update(b, off, len); n += len; } /** * Updates a ZipEntry which describes the data read by this * output stream, in STORED mode. */ public void updateEntry(ZipEntry e) { e.setMethod(ZipEntry.STORED); e.setSize(n); e.setCrc(crc.getValue()); } }}Lines 1001–1211 of 1211. Previous lines
* Lists contents of JAR file, via ZipFile. */ void list(String fname, String files[]) throws IOException { ZipFile zf = new ZipFile(fname); Enumeration<? extends ZipEntry> zes = zf.entries(); while (zes.hasMoreElements()) { printEntry(zes.nextElement(), files); } zf.close(); } /** * Outputs the class index table to the INDEX.LIST file of the * root jar file. */ void dumpIndex(String rootjar, JarIndex index) throws IOException { File jarFile = new File(rootjar); Path jarPath = jarFile.toPath(); Path tmpPath = createTempFileInSameDirectoryAs(jarFile).toPath(); try { if (update(Files.newInputStream(jarPath), Files.newOutputStream(tmpPath), null, index)) { try { Files.move(tmpPath, jarPath, REPLACE_EXISTING); } catch (IOException e) { throw new IOException(getMsg("error.write.file"), e); } } } finally { Files.deleteIfExists(tmpPath); } } private HashSet<String> jarPaths = new HashSet<String>(); /** * Generates the transitive closure of the Class-Path attribute for * the specified jar file. */ List<String> getJarPath(String jar) throws IOException { List<String> files = new ArrayList<String>(); files.add(jar); jarPaths.add(jar); // take out the current path String path = jar.substring(0, Math.max(0, jar.lastIndexOf('/') + 1)); // class path attribute will give us jar file name with // '/' as separators, so we need to change them to the // appropriate one before we open the jar file. JarFile rf = new JarFile(jar.replace('/', File.separatorChar)); if (rf != null) { Manifest man = rf.getManifest(); if (man != null) { Attributes attr = man.getMainAttributes(); if (attr != null) { String value = attr.getValue(Attributes.Name.CLASS_PATH); if (value != null) { StringTokenizer st = new StringTokenizer(value); while (st.hasMoreTokens()) { String ajar = st.nextToken(); if (!ajar.endsWith("/")) { // it is a jar file ajar = path.concat(ajar); /* check on cyclic dependency */ if (! jarPaths.contains(ajar)) { files.addAll(getJarPath(ajar)); } } } } } } } rf.close(); return files; } /** * Generates class index file for the specified root jar file. */ void genIndex(String rootjar, String[] files) throws IOException { List<String> jars = getJarPath(rootjar); int njars = jars.size(); String[] jarfiles; if (njars == 1 && files != null) { // no class-path attribute defined in rootjar, will // use command line specified list of jars for (int i = 0; i < files.length; i++) { jars.addAll(getJarPath(files[i])); } njars = jars.size(); } jarfiles = jars.toArray(new String[njars]); JarIndex index = new JarIndex(jarfiles); dumpIndex(rootjar, index); } /** * Prints entry information, if requested. */ void printEntry(ZipEntry e, String[] files) throws IOException { if (files == null) { printEntry(e); } else { String name = e.getName(); for (String file : files) { if (name.startsWith(file)) { printEntry(e); return; } } } } /** * Prints entry information. */ void printEntry(ZipEntry e) throws IOException { if (vflag) { StringBuilder sb = new StringBuilder(); String s = Long.toString(e.getSize()); for (int i = 6 - s.length(); i > 0; --i) { sb.append(' '); } sb.append(s).append(' ').append(new Date(e.getTime()).toString()); sb.append(' ').append(e.getName()); output(sb.toString()); } else { output(e.getName()); } } /** * Prints usage message. */ void usageError() { error(getMsg("usage")); } /** * A fatal exception has been caught. No recovery possible */ void fatalError(Exception e) { e.printStackTrace(); } /** * A fatal condition has been detected; message is "s". * No recovery possible */ void fatalError(String s) { error(program + ": " + s); } /** * Print an output message; like verbose output and the like */ protected void output(String s) { out.println(s); } /** * Print an error mesage; like something is broken */ protected void error(String s) { err.println(s); } /** * Main routine to start program. */ public static void main(String args[]) { Main jartool = new Main(System.out, System.err, "jar"); System.exit(jartool.run(args) ? 0 : 1); } /** * An OutputStream that doesn't send its output anywhere, (but could). * It's here to find the CRC32 of an input file, necessary for STORED * mode in ZIP. */ private static class CRC32OutputStream extends java.io.OutputStream { final CRC32 crc = new CRC32(); long n = 0; CRC32OutputStream() {} public void write(int r) throws IOException { crc.update(r); n++; } public void write(byte[] b, int off, int len) throws IOException { crc.update(b, off, len); n += len; } /** * Updates a ZipEntry which describes the data read by this * output stream, in STORED mode. */ public void updateEntry(ZipEntry e) { e.setMethod(ZipEntry.STORED); e.setSize(n); e.setCrc(crc.getValue()); } } }