< prev index next >

test/jdk/java/util/zip/zip.java

Print this page
rev 53038 : 8215472: (zipfs) Cleanups in implementation classes of jdk.zipfs and tests


   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 import java.io.*;
  25 import java.nio.charset.Charset;
  26 import java.util.*;
  27 import java.util.zip.*;
  28 import java.text.MessageFormat;







  29 
  30 /**
  31  * A stripped-down version of Jar tool with a "-encoding" option to
  32  * support non-UTF8 encoidng for entry name and comment.
  33  */
  34 public class zip {
  35     String program;
  36     PrintStream out, err;
  37     String fname;
  38     String zname = "";
  39     String[] files;
  40     Charset cs = Charset.forName("UTF-8");
  41 
  42     Map<String, File> entryMap = new HashMap<String, File>();
  43     Set<File> entries = new LinkedHashSet<File>();
  44     List<String> paths = new ArrayList<String>();
  45 
  46     CRC32 crc32 = new CRC32();
  47     /*
  48      * cflag: create
  49      * uflag: update
  50      * xflag: xtract
  51      * tflag: table
  52      * vflag: verbose
  53      * flag0: no zip compression (store only)
  54      */
  55     boolean cflag, uflag, xflag, tflag, vflag, flag0;
  56 
  57     private static ResourceBundle rsrc;
  58     static {
  59         try {
  60             // just use the jar message
  61             rsrc = ResourceBundle.getBundle("sun.tools.jar.resources.jar");
  62         } catch (MissingResourceException e) {
  63             throw new Error("Fatal: Resource for jar is missing");
  64         }


 313                 }
 314             } else {
 315                 error(formatMsg("error.nosuch.fileordir", String.valueOf(f)));
 316                 ok = false;
 317             }
 318         }
 319     }
 320 
 321     void create(OutputStream out) throws IOException
 322     {
 323         try (ZipOutputStream zos = new ZipOutputStream(out, cs)) {
 324             if (flag0) {
 325                 zos.setMethod(ZipOutputStream.STORED);
 326             }
 327             for (File file: entries) {
 328                 addFile(zos, file);
 329             }
 330         }
 331     }
 332 
 333     boolean update(InputStream in, OutputStream out) throws IOException
 334     {
 335         try (ZipInputStream zis = new ZipInputStream(in, cs);
 336              ZipOutputStream zos = new ZipOutputStream(out, cs))
 337         {
 338             ZipEntry e = null;
 339             byte[] buf = new byte[1024];
 340             int n = 0;
 341             boolean updateOk = true;
 342 
 343             // put the old entries first, replace if necessary
 344             while ((e = zis.getNextEntry()) != null) {
 345                 String name = e.getName();
 346                 if (!entryMap.containsKey(name)) { // copy the old stuff
 347                     // do our own compression
 348                     ZipEntry e2 = new ZipEntry(name);
 349                     e2.setMethod(e.getMethod());
 350                     e2.setTime(e.getTime());
 351                     e2.setComment(e.getComment());
 352                     e2.setExtra(e.getExtra());
 353                     if (e.getMethod() == ZipEntry.STORED) {
 354                         e2.setSize(e.getSize());
 355                         e2.setCrc(e.getCrc());
 356                     }
 357                     zos.putNextEntry(e2);
 358                     while ((n = zis.read(buf, 0, buf.length)) != -1) {
 359                         zos.write(buf, 0, n);
 360                     }
 361                 } else { // replace with the new files
 362                     File f = entryMap.get(name);
 363                     addFile(zos, f);
 364                     entryMap.remove(name);
 365                     entries.remove(f);
 366                 }
 367             }
 368 
 369             // add the remaining new files
 370             for (File f: entries) {
 371                 addFile(zos, f);
 372             }
 373         }
 374         return updateOk;
 375     }
 376 
 377     private String entryName(String name) {
 378         name = name.replace(File.separatorChar, '/');
 379         String matchPath = "";
 380         for (String path : paths) {
 381             if (name.startsWith(path) && (path.length() > matchPath.length())) {
 382                 matchPath = path;
 383             }
 384         }
 385         name = name.substring(matchPath.length());
 386 
 387         if (name.startsWith("/")) {
 388             name = name.substring(1);
 389         } else if (name.startsWith("./")) {
 390             name = name.substring(2);
 391         }
 392         return name;
 393     }
 394 


 462             crc32.update(buf, 0, r);
 463         }
 464         is.close();
 465         if (nread != (int) len) {
 466             throw new ZipException(formatMsg(
 467                         "error.incorrect.length", f.getPath()));
 468         }
 469         e.setCrc(crc32.getValue());
 470     }
 471 
 472     void replaceFSC(String files[]) {
 473         if (files != null) {
 474             for (String file : files) {
 475                 file = file.replace(File.separatorChar, '/');
 476             }
 477         }
 478     }
 479 
 480     Set<ZipEntry> newDirSet() {
 481         return new HashSet<ZipEntry>() {


 482             public boolean add(ZipEntry e) {
 483                 return (e == null || super.add(e));
 484             }};
 485     }
 486 
 487     void updateLastModifiedTime(Set<ZipEntry> zes) throws IOException {
 488         for (ZipEntry ze : zes) {
 489             long lastModified = ze.getTime();
 490             if (lastModified != -1) {
 491                 File f = new File(ze.getName().replace('/', File.separatorChar));
 492                 f.setLastModified(lastModified);
 493             }
 494         }
 495     }
 496 
 497     void extract(InputStream in, String files[]) throws IOException {
 498         ZipInputStream zis = new ZipInputStream(in, cs);
 499         ZipEntry e;
 500         Set<ZipEntry> dirs = newDirSet();
 501         while ((e = zis.getNextEntry()) != null) {


 503                 dirs.add(extractFile(zis, e));
 504             } else {
 505                 String name = e.getName();
 506                 for (String file : files) {
 507                     if (name.startsWith(file)) {
 508                         dirs.add(extractFile(zis, e));
 509                         break;
 510                     }
 511                 }
 512             }
 513         }
 514         updateLastModifiedTime(dirs);
 515     }
 516 
 517     void extract(String fname, String files[]) throws IOException {
 518         try (ZipFile zf = new ZipFile(fname, cs)) {
 519             Set<ZipEntry> dirs = newDirSet();
 520             Enumeration<? extends ZipEntry> zes = zf.entries();
 521             while (zes.hasMoreElements()) {
 522                 ZipEntry e = zes.nextElement();
 523                 InputStream is;
 524                 if (files == null) {
 525                     dirs.add(extractFile(zf.getInputStream(e), e));
 526                 } else {
 527                     String name = e.getName();
 528                     for (String file : files) {
 529                         if (name.startsWith(file)) {
 530                             dirs.add(extractFile(zf.getInputStream(e), e));
 531                             break;
 532                         }
 533                     }
 534                 }
 535             }

 536         }
 537         updateLastModifiedTime(dirs);
 538     }
 539 
 540     ZipEntry extractFile(InputStream is, ZipEntry e) throws IOException {
 541         ZipEntry rc = null;
 542         String name = e.getName();
 543         File f = new File(e.getName().replace('/', File.separatorChar));
 544         if (e.isDirectory()) {
 545             if (f.exists()) {
 546                 if (!f.isDirectory()) {
 547                     throw new IOException(formatMsg("error.create.dir",
 548                         f.getPath()));
 549                 }
 550             } else {
 551                 if (!f.mkdirs()) {
 552                     throw new IOException(formatMsg("error.create.dir",
 553                         f.getPath()));
 554                 } else {
 555                     rc = e;
 556                 }
 557             }


 710                 } else {
 711                     loadCmdFile(arg, newArgs);
 712                 }
 713             } else {
 714                 newArgs.add(arg);
 715             }
 716         }
 717         return newArgs.toArray(new String[newArgs.size()]);
 718     }
 719 
 720     private static void loadCmdFile(String name, List<String> args) throws IOException
 721     {
 722         Reader r = new BufferedReader(new FileReader(name));
 723         StreamTokenizer st = new StreamTokenizer(r);
 724         st.resetSyntax();
 725         st.wordChars(' ', 255);
 726         st.whitespaceChars(0, ' ');
 727         st.commentChar('#');
 728         st.quoteChar('"');
 729         st.quoteChar('\'');
 730         while (st.nextToken() != st.TT_EOF) {
 731             args.add(st.sval);
 732         }
 733         r.close();
 734     }
 735 
 736     public static void main(String args[]) {
 737         zip z = new zip(System.out, System.err, "zip");
 738         System.exit(z.run(args) ? 0 : 1);
 739     }
 740 }
 741 


   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 import java.io.*;
  25 import java.nio.charset.Charset;


  26 import java.text.MessageFormat;
  27 import java.util.*;
  28 import java.util.zip.CRC32;
  29 import java.util.zip.ZipEntry;
  30 import java.util.zip.ZipException;
  31 import java.util.zip.ZipFile;
  32 import java.util.zip.ZipInputStream;
  33 import java.util.zip.ZipOutputStream;
  34 
  35 /**
  36  * A stripped-down version of Jar tool with a "-encoding" option to
  37  * support non-UTF8 encoidng for entry name and comment.
  38  */
  39 public class zip {
  40     String program;
  41     PrintStream out, err;
  42     String fname;
  43     String zname = "";
  44     String[] files;
  45     Charset cs = Charset.forName("UTF-8");
  46 
  47     Map<String, File> entryMap = new HashMap<>();
  48     Set<File> entries = new LinkedHashSet<>();
  49     List<String> paths = new ArrayList<>();
  50 
  51     CRC32 crc32 = new CRC32();
  52     /*
  53      * cflag: create
  54      * uflag: update
  55      * xflag: xtract
  56      * tflag: table
  57      * vflag: verbose
  58      * flag0: no zip compression (store only)
  59      */
  60     boolean cflag, uflag, xflag, tflag, vflag, flag0;
  61 
  62     private static ResourceBundle rsrc;
  63     static {
  64         try {
  65             // just use the jar message
  66             rsrc = ResourceBundle.getBundle("sun.tools.jar.resources.jar");
  67         } catch (MissingResourceException e) {
  68             throw new Error("Fatal: Resource for jar is missing");
  69         }


 318                 }
 319             } else {
 320                 error(formatMsg("error.nosuch.fileordir", String.valueOf(f)));
 321                 ok = false;
 322             }
 323         }
 324     }
 325 
 326     void create(OutputStream out) throws IOException
 327     {
 328         try (ZipOutputStream zos = new ZipOutputStream(out, cs)) {
 329             if (flag0) {
 330                 zos.setMethod(ZipOutputStream.STORED);
 331             }
 332             for (File file: entries) {
 333                 addFile(zos, file);
 334             }
 335         }
 336     }
 337 
 338     boolean update(InputStream in, OutputStream out) throws IOException {

 339         try (ZipInputStream zis = new ZipInputStream(in, cs);
 340              ZipOutputStream zos = new ZipOutputStream(out, cs))
 341         {
 342             ZipEntry e = null;
 343             byte[] buf = new byte[1024];
 344             int n = 0;

 345 
 346             // put the old entries first, replace if necessary
 347             while ((e = zis.getNextEntry()) != null) {
 348                 String name = e.getName();
 349                 if (!entryMap.containsKey(name)) { // copy the old stuff
 350                     // do our own compression
 351                     ZipEntry e2 = new ZipEntry(name);
 352                     e2.setMethod(e.getMethod());
 353                     e2.setTime(e.getTime());
 354                     e2.setComment(e.getComment());
 355                     e2.setExtra(e.getExtra());
 356                     if (e.getMethod() == ZipEntry.STORED) {
 357                         e2.setSize(e.getSize());
 358                         e2.setCrc(e.getCrc());
 359                     }
 360                     zos.putNextEntry(e2);
 361                     while ((n = zis.read(buf, 0, buf.length)) != -1) {
 362                         zos.write(buf, 0, n);
 363                     }
 364                 } else { // replace with the new files
 365                     File f = entryMap.get(name);
 366                     addFile(zos, f);
 367                     entryMap.remove(name);
 368                     entries.remove(f);
 369                 }
 370             }
 371 
 372             // add the remaining new files
 373             for (File f : entries) {
 374                 addFile(zos, f);
 375             }
 376         }
 377         return true;
 378     }
 379 
 380     private String entryName(String name) {
 381         name = name.replace(File.separatorChar, '/');
 382         String matchPath = "";
 383         for (String path : paths) {
 384             if (name.startsWith(path) && (path.length() > matchPath.length())) {
 385                 matchPath = path;
 386             }
 387         }
 388         name = name.substring(matchPath.length());
 389 
 390         if (name.startsWith("/")) {
 391             name = name.substring(1);
 392         } else if (name.startsWith("./")) {
 393             name = name.substring(2);
 394         }
 395         return name;
 396     }
 397 


 465             crc32.update(buf, 0, r);
 466         }
 467         is.close();
 468         if (nread != (int) len) {
 469             throw new ZipException(formatMsg(
 470                         "error.incorrect.length", f.getPath()));
 471         }
 472         e.setCrc(crc32.getValue());
 473     }
 474 
 475     void replaceFSC(String files[]) {
 476         if (files != null) {
 477             for (String file : files) {
 478                 file = file.replace(File.separatorChar, '/');
 479             }
 480         }
 481     }
 482 
 483     Set<ZipEntry> newDirSet() {
 484         return new HashSet<ZipEntry>() {
 485             private static final long serialVersionUID = 4547977575248028254L;
 486 
 487             public boolean add(ZipEntry e) {
 488                 return (e == null || super.add(e));
 489             }};
 490     }
 491 
 492     void updateLastModifiedTime(Set<ZipEntry> zes) throws IOException {
 493         for (ZipEntry ze : zes) {
 494             long lastModified = ze.getTime();
 495             if (lastModified != -1) {
 496                 File f = new File(ze.getName().replace('/', File.separatorChar));
 497                 f.setLastModified(lastModified);
 498             }
 499         }
 500     }
 501 
 502     void extract(InputStream in, String files[]) throws IOException {
 503         ZipInputStream zis = new ZipInputStream(in, cs);
 504         ZipEntry e;
 505         Set<ZipEntry> dirs = newDirSet();
 506         while ((e = zis.getNextEntry()) != null) {


 508                 dirs.add(extractFile(zis, e));
 509             } else {
 510                 String name = e.getName();
 511                 for (String file : files) {
 512                     if (name.startsWith(file)) {
 513                         dirs.add(extractFile(zis, e));
 514                         break;
 515                     }
 516                 }
 517             }
 518         }
 519         updateLastModifiedTime(dirs);
 520     }
 521 
 522     void extract(String fname, String files[]) throws IOException {
 523         try (ZipFile zf = new ZipFile(fname, cs)) {
 524             Set<ZipEntry> dirs = newDirSet();
 525             Enumeration<? extends ZipEntry> zes = zf.entries();
 526             while (zes.hasMoreElements()) {
 527                 ZipEntry e = zes.nextElement();

 528                 if (files == null) {
 529                     dirs.add(extractFile(zf.getInputStream(e), e));
 530                 } else {
 531                     String name = e.getName();
 532                     for (String file : files) {
 533                         if (name.startsWith(file)) {
 534                             dirs.add(extractFile(zf.getInputStream(e), e));
 535                             break;
 536                         }
 537                     }
 538                 }
 539             }
 540             updateLastModifiedTime(dirs);
 541         }

 542     }
 543 
 544     ZipEntry extractFile(InputStream is, ZipEntry e) throws IOException {
 545         ZipEntry rc = null;
 546         String name = e.getName();
 547         File f = new File(e.getName().replace('/', File.separatorChar));
 548         if (e.isDirectory()) {
 549             if (f.exists()) {
 550                 if (!f.isDirectory()) {
 551                     throw new IOException(formatMsg("error.create.dir",
 552                         f.getPath()));
 553                 }
 554             } else {
 555                 if (!f.mkdirs()) {
 556                     throw new IOException(formatMsg("error.create.dir",
 557                         f.getPath()));
 558                 } else {
 559                     rc = e;
 560                 }
 561             }


 714                 } else {
 715                     loadCmdFile(arg, newArgs);
 716                 }
 717             } else {
 718                 newArgs.add(arg);
 719             }
 720         }
 721         return newArgs.toArray(new String[newArgs.size()]);
 722     }
 723 
 724     private static void loadCmdFile(String name, List<String> args) throws IOException
 725     {
 726         Reader r = new BufferedReader(new FileReader(name));
 727         StreamTokenizer st = new StreamTokenizer(r);
 728         st.resetSyntax();
 729         st.wordChars(' ', 255);
 730         st.whitespaceChars(0, ' ');
 731         st.commentChar('#');
 732         st.quoteChar('"');
 733         st.quoteChar('\'');
 734         while (st.nextToken() != StreamTokenizer.TT_EOF) {
 735             args.add(st.sval);
 736         }
 737         r.close();
 738     }
 739 
 740     public static void main(String args[]) {
 741         zip z = new zip(System.out, System.err, "zip");
 742         System.exit(z.run(args) ? 0 : 1);
 743     }
 744 }

< prev index next >