1211 lines · 39.7 KB · Java
RawDownload
     * 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