src/share/classes/sun/tools/jar/Main.java

Print this page

        

@@ -72,11 +72,10 @@
     boolean cflag, uflag, xflag, tflag, vflag, flag0, Mflag, iflag;
 
     static final String MANIFEST = JarFile.MANIFEST_NAME;
     static final String MANIFEST_DIR = "META-INF/";
     static final String VERSION = "1.0";
-    static final char SEPARATOR = File.separatorChar;
     static final String INDEX = JarIndex.INDEX_NAME;
 
     private static ResourceBundle rsrc;
 
     /**

@@ -225,23 +224,36 @@
                         tmpFile.delete();
                         throw new IOException(getMsg("error.write.file"));
                     }
                     tmpFile.delete();
                 }
-            } else if (xflag || tflag) {
-                InputStream in;
+            } else if (tflag) {
+                replaceFSC(files);
                 if (fname != null) {
-                    in = new FileInputStream(fname);
+                    list(fname, files);
                 } else {
-                    in = new FileInputStream(FileDescriptor.in);
-                }
-                if (xflag) {
-                    extract(new BufferedInputStream(in), files);
-                } else {
+                    InputStream in = new FileInputStream(FileDescriptor.in);
+                    try{
                     list(new BufferedInputStream(in), files);
+                    } finally {
+                        in.close();
                 }
+                }
+            } else if (xflag) {
+                replaceFSC(files);
+                if (fname != null && files != null) {
+                    extract(fname, files);
+                } else {
+                    InputStream in = (fname == null)
+                        ? new FileInputStream(FileDescriptor.in)
+                        : new FileInputStream(fname);
+                    try {
+                        extract(new BufferedInputStream(in), files);
+                    } finally {
                 in.close();
+                    }
+                }
             } else if (iflag) {
                 genIndex(rootjar, files);
             }
         } catch (IOException e) {
             fatalError(e);

@@ -758,31 +770,50 @@
                         "error.incorrect.length", f.getPath()));
         }
         e.setCrc(crc32.getValue());
     }
 
+    void replaceFSC(String files[]) {
+        if (files != null) {
+            for (String file : files) {
+                file = file.replace(File.separatorChar, '/');
+            } 
+        }
+    }
+
+    Set<ZipEntry> newDirSet() {
+        return new HashSet<ZipEntry>() {
+            public boolean add(ZipEntry e) {
+                return ((e == null || useExtractionTime) ? false : super.add(e));
+            }};
+    }
+
+    void updateLastModifiedTime(Set<ZipEntry> zes) throws IOException {
+        for (ZipEntry ze : zes) {
+            long lastModified = ze.getTime();
+            if (lastModified != -1) {
+                File f = new File(ze.getName().replace('/', File.separatorChar));
+                f.setLastModified(lastModified);
+            }
+        }
+    }
+
     /*
      * Extracts specified entries from JAR file.
      */
     void extract(InputStream in, String files[]) throws IOException {
         ZipInputStream zis = new ZipInputStream(in);
         ZipEntry e;
         // Set of all directory entries specified in archive.  Disallows
         // null entries.  Disallows all entries if using pre-6.0 behavior.
-        Set<ZipEntry> dirs = new HashSet<ZipEntry>() {
-            public boolean add(ZipEntry e) {
-                return ((e == null || useExtractionTime) ? false : super.add(e));
-            }};
-
+        Set<ZipEntry> dirs = newDirSet();
         while ((e = zis.getNextEntry()) != null) {
             if (files == null) {
                 dirs.add(extractFile(zis, e));
-
             } else {
                 String name = e.getName();
-                for (int i = 0; i < files.length; i++) {
-                    String file = files[i].replace(File.separatorChar, '/');
+                for (String file : files) {
                     if (name.startsWith(file)) {
                         dirs.add(extractFile(zis, e));
                         break;
                     }
                 }

@@ -791,25 +822,45 @@
 
         // Update timestamps of directories specified in archive with their
         // timestamps as given in the archive.  We do this after extraction,
         // instead of during, because creating a file in a directory changes
         // that directory's timestamp.
-        for (ZipEntry dirEntry : dirs) {
-            long lastModified = dirEntry.getTime();
-            if (lastModified != -1) {
-                File dir = new File(dirEntry.getName().replace('/', File.separatorChar));
-                dir.setLastModified(lastModified);
+        updateLastModifiedTime(dirs);
             }
+
+    /*
+     * Extracts specified entries from JAR file, via ZipFile.
+     */
+    void extract(String fname, String files[]) throws IOException {
+        ZipFile zf = new ZipFile(fname);
+        Set<ZipEntry> dirs = newDirSet();
+        Enumeration<? extends ZipEntry> zes = zf.entries();
+        while (zes.hasMoreElements()) {
+            ZipEntry e = zes.nextElement();
+            InputStream is;
+            if (files == null) {
+                dirs.add(extractFile(zf.getInputStream(e), e));
+            } else {
+                String name = e.getName();
+                for (String file : files) {
+                    if (name.startsWith(file)) {
+                        dirs.add(extractFile(zf.getInputStream(e), e));
+                        break;
         }
     }
+            }
+        }
+        zf.close();
+        updateLastModifiedTime(dirs);
+    }
 
     /*
      * Extracts next entry from JAR file, creating directories as needed.  If
      * the entry is for a directory which doesn't exist prior to this
      * invocation, returns that entry, otherwise returns null.
      */
-    ZipEntry extractFile(ZipInputStream zis, ZipEntry e) throws IOException {
+    ZipEntry extractFile(InputStream is, ZipEntry e) throws IOException {
         ZipEntry rc = null;
         String name = e.getName();
         File f = new File(e.getName().replace('/', File.separatorChar));
         if (e.isDirectory()) {
             if (f.exists()) {

@@ -836,17 +887,23 @@
                     throw new IOException(formatMsg(
                         "error.create.dir", d.getPath()));
                 }
             }
             OutputStream os = new FileOutputStream(f);
-            byte[] b = new byte[512];
+            byte[] b = new byte[8192];
             int len;
-            while ((len = zis.read(b, 0, b.length)) != -1) {
+            try {
+                while ((len = is.read(b, 0, b.length)) != -1) {
                 os.write(b, 0, len);
             }
-            zis.closeEntry();
+            } finally {
+                if (is instanceof ZipInputStream)
+                    ((ZipInputStream)is).closeEntry();
+                else 
+                    is.close();
             os.close();
+            }
             if (vflag) {
                 if (e.getMethod() == ZipEntry.DEFLATED) {
                     output(formatMsg("out.inflated", name));
                 } else {
                     output(formatMsg("out.extracted", name));

@@ -867,31 +924,32 @@
      */
     void list(InputStream in, String files[]) throws IOException {
         ZipInputStream zis = new ZipInputStream(in);
         ZipEntry e;
         while ((e = zis.getNextEntry()) != null) {
-            String name = e.getName();
             /*
              * In the case of a compressed (deflated) entry, the entry size
              * is stored immediately following the entry data and cannot be
              * determined until the entry is fully read. Therefore, we close
              * the entry first before printing out its attributes.
              */
             zis.closeEntry();
-            if (files == null) {
-                printEntry(e);
-            } else {
-                for (int i = 0; i < files.length; i++) {
-                    String file = files[i].replace(File.separatorChar, '/');
-                    if (name.startsWith(file)) {
-                        printEntry(e);
-                        break;
+            printEntry(e, files);
                     }
                 }
+
+    /*
+     * 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();
         }
-    }
 
     /**
      * Output the class index table to the INDEX.LIST file of the
      * root jar file.
      */

@@ -972,17 +1030,33 @@
         jarfiles = (String[])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) {
-            StringBuffer sb = new StringBuffer();
+            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());