src/share/classes/sun/tools/jar/Main.java
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File jdk Sdiff src/share/classes/sun/tools/jar

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

Print this page




  30 import java.nio.file.Files;
  31 import java.util.*;
  32 import java.util.zip.*;
  33 import java.util.jar.*;
  34 import java.util.jar.Manifest;
  35 import java.text.MessageFormat;
  36 import sun.misc.JarIndex;
  37 import static sun.misc.JarIndex.INDEX_NAME;
  38 import static java.util.jar.JarFile.MANIFEST_NAME;
  39 import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
  40 
  41 /**
  42  * This class implements a simple utility for creating files in the JAR
  43  * (Java Archive) file format. The JAR format is based on the ZIP file
  44  * format, with optional meta-information stored in a MANIFEST entry.
  45  */
  46 public
  47 class Main {
  48     String program;
  49     PrintStream out, err;
  50     String fname, mname, ename;
  51     String zname = "";
  52     String[] files;
  53     String rootjar = null;
  54 
  55     // An entryName(path)->File map generated during "expand", it helps to
  56     // decide whether or not an existing entry in a jar file needs to be
  57     // replaced, during the "update" operation.
  58     Map<String, File> entryMap = new HashMap<String, File>();
  59 
  60     // All files need to be added/updated.
  61     Set<File> entries = new LinkedHashSet<File>();
  62 
  63     // Directories specified by "-C" operation.
  64     Set<String> paths = new HashSet<String>();
  65 
  66     /*
  67      * cflag: create
  68      * uflag: update
  69      * xflag: xtract
  70      * tflag: table
  71      * vflag: verbose
  72      * flag0: no zip compression (store only)
  73      * Mflag: DO NOT generate a manifest file (just ZIP)
  74      * iflag: generate jar index
  75      */
  76     boolean cflag, uflag, xflag, tflag, vflag, flag0, Mflag, iflag;
  77 
  78     static final String MANIFEST_DIR = "META-INF/";
  79     static final String VERSION = "1.0";
  80 



  81     private static ResourceBundle rsrc;
  82 
  83     /**
  84      * If true, maintain compatibility with JDK releases prior to 6.0 by
  85      * timestamping extracted files with the time at which they are extracted.
  86      * Default is to use the time given in the archive.
  87      */
  88     private static final boolean useExtractionTime =
  89         Boolean.getBoolean("sun.tools.jar.useExtractionTime");
  90 
  91     /**
  92      * Initialize ResourceBundle
  93      */
  94     static {
  95         try {
  96             rsrc = ResourceBundle.getBundle("sun.tools.jar.resources.jar");
  97         } catch (MissingResourceException e) {
  98             throw new Error("Fatal: Resource for jar is missing");
  99         }
 100     }


 167                 InputStream in = null;
 168 
 169                 if (!Mflag) {
 170                     if (mname != null) {
 171                         in = new FileInputStream(mname);
 172                         manifest = new Manifest(new BufferedInputStream(in));
 173                     } else {
 174                         manifest = new Manifest();
 175                     }
 176                     addVersion(manifest);
 177                     addCreatedBy(manifest);
 178                     if (isAmbiguousMainClass(manifest)) {
 179                         if (in != null) {
 180                             in.close();
 181                         }
 182                         return false;
 183                     }
 184                     if (ename != null) {
 185                         addMainClass(manifest, ename);
 186                     }








 187                 }
 188                 OutputStream out;
 189                 if (fname != null) {
 190                     out = new FileOutputStream(fname);
 191                 } else {
 192                     out = new FileOutputStream(FileDescriptor.out);
 193                     if (vflag) {
 194                         // Disable verbose output so that it does not appear
 195                         // on stdout along with file data
 196                         // error("Warning: -v option ignored");
 197                         vflag = false;
 198                     }
 199                 }
 200                 expand(null, files, false);
 201                 create(new BufferedOutputStream(out, 4096), manifest);
 202                 if (in != null) {
 203                     in.close();
 204                 }
 205                 out.close();
 206             } else if (uflag) {


 213                     in = new FileInputStream(inputFile);
 214                     out = new FileOutputStream(tmpFile);
 215                 } else {
 216                     in = new FileInputStream(FileDescriptor.in);
 217                     out = new FileOutputStream(FileDescriptor.out);
 218                     vflag = false;
 219                 }
 220                 InputStream manifest = (!Mflag && (mname != null)) ?
 221                     (new FileInputStream(mname)) : null;
 222                 expand(null, files, true);
 223                 boolean updateOk = update(in, new BufferedOutputStream(out),
 224                                           manifest, null);
 225                 if (ok) {
 226                     ok = updateOk;
 227                 }
 228                 in.close();
 229                 out.close();
 230                 if (manifest != null) {
 231                     manifest.close();
 232                 }
 233                 if (fname != null) {
 234                     // on Win32, we need this delete
 235                     inputFile.delete();
 236                     if (!tmpFile.renameTo(inputFile)) {
 237                         tmpFile.delete();
 238                         throw new IOException(getMsg("error.write.file"));
 239                     }
 240                     tmpFile.delete();
 241                 }
 242             } else if (tflag) {
 243                 replaceFSC(files);
 244                 if (fname != null) {
 245                     list(fname, files);
 246                 } else {
 247                     InputStream in = new FileInputStream(FileDescriptor.in);
 248                     try{
 249                         list(new BufferedInputStream(in), files);
 250                     } finally {
 251                         in.close();
 252                     }
 253                 }


 344                     fname = args[count++];
 345                     break;
 346                 case 'm':
 347                     mname = args[count++];
 348                     break;
 349                 case '0':
 350                     flag0 = true;
 351                     break;
 352                 case 'i':
 353                     if (cflag || uflag || xflag || tflag) {
 354                         usageError();
 355                         return false;
 356                     }
 357                     // do not increase the counter, files will contain rootjar
 358                     rootjar = args[count++];
 359                     iflag = true;
 360                     break;
 361                 case 'e':
 362                      ename = args[count++];
 363                      break;



 364                 default:
 365                     error(formatMsg("error.illegal.option",
 366                                 String.valueOf(flags.charAt(i))));
 367                     usageError();
 368                     return false;
 369                 }
 370             }
 371         } catch (ArrayIndexOutOfBoundsException e) {
 372             usageError();
 373             return false;
 374         }
 375         if (!cflag && !tflag && !xflag && !uflag && !iflag) {
 376             error(getMsg("error.bad.option"));
 377             usageError();
 378             return false;
 379         }
 380         /* parse file arguments */
 381         int n = args.length - count;
 382         if (n > 0) {
 383             int k = 0;


 393                         while (dir.indexOf("//") > -1) {
 394                             dir = dir.replace("//", "/");
 395                         }
 396                         paths.add(dir.replace(File.separatorChar, '/'));
 397                         nameBuf[k++] = dir + args[++i];
 398                     } else {
 399                         nameBuf[k++] = args[i];
 400                     }
 401                 }
 402             } catch (ArrayIndexOutOfBoundsException e) {
 403                 usageError();
 404                 return false;
 405             }
 406             files = new String[k];
 407             System.arraycopy(nameBuf, 0, files, 0, k);
 408         } else if (cflag && (mname == null)) {
 409             error(getMsg("error.bad.cflag"));
 410             usageError();
 411             return false;
 412         } else if (uflag) {
 413             if ((mname != null) || (ename != null)) {
 414                 /* just want to update the manifest */
 415                 return true;
 416             } else {
 417                 error(getMsg("error.bad.uflag"));
 418                 usageError();
 419                 return false;
 420             }
 421         }
 422         return true;
 423     }
 424 
 425     /**
 426      * Expands list of files to process into full list of all files that
 427      * can be found by recursively descending directories.
 428      */
 429     void expand(File dir, String[] files, boolean isUpdate) {
 430         if (files == null) {
 431             return;
 432         }
 433         for (int i = 0; i < files.length; i++) {


 527         ZipInputStream zis = new ZipInputStream(in);
 528         ZipOutputStream zos = new JarOutputStream(out);
 529         ZipEntry e = null;
 530         boolean foundManifest = false;
 531         boolean updateOk = true;
 532 
 533         if (jarIndex != null) {
 534             addIndex(jarIndex, zos);
 535         }
 536 
 537         // put the old entries first, replace if necessary
 538         while ((e = zis.getNextEntry()) != null) {
 539             String name = e.getName();
 540 
 541             boolean isManifestEntry = equalsIgnoreCase(name, MANIFEST_NAME);
 542 
 543             if ((jarIndex != null && equalsIgnoreCase(name, INDEX_NAME))
 544                 || (Mflag && isManifestEntry)) {
 545                 continue;
 546             } else if (isManifestEntry && ((newManifest != null) ||
 547                         (ename != null))) {
 548                 foundManifest = true;
 549                 if (newManifest != null) {
 550                     // Don't read from the newManifest InputStream, as we
 551                     // might need it below, and we can't re-read the same data
 552                     // twice.
 553                     FileInputStream fis = new FileInputStream(mname);
 554                     boolean ambiguous = isAmbiguousMainClass(new Manifest(fis));
 555                     fis.close();
 556                     if (ambiguous) {
 557                         return false;
 558                     }
 559                 }
 560 
 561                 // Update the manifest.
 562                 Manifest old = new Manifest(zis);
 563                 if (newManifest != null) {
 564                     old.read(newManifest);
 565                 }
 566                 updateManifest(old, zos);


 567             } else {
 568                 if (!entryMap.containsKey(name)) { // copy the old stuff
 569                     // do our own compression
 570                     ZipEntry e2 = new ZipEntry(name);
 571                     e2.setMethod(e.getMethod());
 572                     e2.setTime(e.getTime());
 573                     e2.setComment(e.getComment());
 574                     e2.setExtra(e.getExtra());
 575                     if (e.getMethod() == ZipEntry.STORED) {
 576                         e2.setSize(e.getSize());
 577                         e2.setCrc(e.getCrc());
 578                     }
 579                     zos.putNextEntry(e2);
 580                     copy(zis, zos);
 581                 } else { // replace with the new files
 582                     File f = entryMap.get(name);
 583                     addFile(zos, f);
 584                     entryMap.remove(name);
 585                     entries.remove(f);
 586                 }
 587             }
 588         }
 589 
 590         // add the remaining new files
 591         for (File f: entries) {
 592             addFile(zos, f);
 593         }
 594         if (!foundManifest) {
 595             if (newManifest != null) {
 596                 Manifest m = new Manifest(newManifest);
 597                 updateOk = !isAmbiguousMainClass(m);
 598                 if (updateOk) {
 599                     updateManifest(m, zos);






 600                 }
 601             } else if (ename != null) {
 602                 updateManifest(new Manifest(), zos);
 603             }
 604         }
 605         zis.close();
 606         zos.close();
 607         return updateOk;
 608     }
 609 
 610 
 611     private void addIndex(JarIndex index, ZipOutputStream zos)
 612         throws IOException
 613     {
 614         ZipEntry e = new ZipEntry(INDEX_NAME);
 615         e.setTime(System.currentTimeMillis());
 616         if (flag0) {
 617             CRC32OutputStream os = new CRC32OutputStream();
 618             index.write(os);
 619             os.updateEntry(e);
 620         }
 621         zos.putNextEntry(e);
 622         index.write(zos);
 623         zos.closeEntry();
 624     }
 625 
 626     private void updateManifest(Manifest m, ZipOutputStream zos)
 627         throws IOException
 628     {
 629         addVersion(m);
 630         addCreatedBy(m);
 631         if (ename != null) {
 632             addMainClass(m, ename);
 633         }





 634         ZipEntry e = new ZipEntry(MANIFEST_NAME);
 635         e.setTime(System.currentTimeMillis());
 636         if (flag0) {
 637             crc32Manifest(e, m);
 638         }
 639         zos.putNextEntry(e);
 640         m.write(zos);
 641         if (vflag) {
 642             output(getMsg("out.update.manifest"));
 643         }

 644     }
 645 
 646 
 647     private String entryName(String name) {
 648         name = name.replace(File.separatorChar, '/');
 649         String matchPath = "";
 650         for (String path : paths) {
 651             if (name.startsWith(path)
 652                 && (path.length() > matchPath.length())) {
 653                 matchPath = path;
 654             }
 655         }
 656         name = name.substring(matchPath.length());
 657 
 658         if (name.startsWith("/")) {
 659             name = name.substring(1);
 660         } else if (name.startsWith("./")) {
 661             name = name.substring(2);
 662         }
 663         return name;


 668         if (global.getValue(Attributes.Name.MANIFEST_VERSION) == null) {
 669             global.put(Attributes.Name.MANIFEST_VERSION, VERSION);
 670         }
 671     }
 672 
 673     private void addCreatedBy(Manifest m) {
 674         Attributes global = m.getMainAttributes();
 675         if (global.getValue(new Attributes.Name("Created-By")) == null) {
 676             String javaVendor = System.getProperty("java.vendor");
 677             String jdkVersion = System.getProperty("java.version");
 678             global.put(new Attributes.Name("Created-By"), jdkVersion + " (" +
 679                         javaVendor + ")");
 680         }
 681     }
 682 
 683     private void addMainClass(Manifest m, String mainApp) {
 684         Attributes global = m.getMainAttributes();
 685 
 686         // overrides any existing Main-Class attribute
 687         global.put(Attributes.Name.MAIN_CLASS, mainApp);






















 688     }
 689 
 690     private boolean isAmbiguousMainClass(Manifest m) {
 691         if (ename != null) {
 692             Attributes global = m.getMainAttributes();
 693             if ((global.get(Attributes.Name.MAIN_CLASS) != null)) {
 694                 error(getMsg("error.bad.eflag"));
 695                 usageError();
 696                 return true;
 697             }
 698         }
 699         return false;
 700     }
 701 
 702     /**
 703      * Adds a new file entry to the ZIP output stream.
 704      */
 705     void addFile(ZipOutputStream zos, File file) throws IOException {
 706         String name = file.getPath();
 707         boolean isDir = file.isDirectory();




  30 import java.nio.file.Files;
  31 import java.util.*;
  32 import java.util.zip.*;
  33 import java.util.jar.*;
  34 import java.util.jar.Manifest;
  35 import java.text.MessageFormat;
  36 import sun.misc.JarIndex;
  37 import static sun.misc.JarIndex.INDEX_NAME;
  38 import static java.util.jar.JarFile.MANIFEST_NAME;
  39 import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
  40 
  41 /**
  42  * This class implements a simple utility for creating files in the JAR
  43  * (Java Archive) file format. The JAR format is based on the ZIP file
  44  * format, with optional meta-information stored in a MANIFEST entry.
  45  */
  46 public
  47 class Main {
  48     String program;
  49     PrintStream out, err;
  50     String fname, mname, ename, pname;
  51     String zname = "";
  52     String[] files;
  53     String rootjar = null;
  54 
  55     // An entryName(path)->File map generated during "expand", it helps to
  56     // decide whether or not an existing entry in a jar file needs to be
  57     // replaced, during the "update" operation.
  58     Map<String, File> entryMap = new HashMap<String, File>();
  59 
  60     // All files need to be added/updated.
  61     Set<File> entries = new LinkedHashSet<File>();
  62 
  63     // Directories specified by "-C" operation.
  64     Set<String> paths = new HashSet<String>();
  65 
  66     /*
  67      * cflag: create
  68      * uflag: update
  69      * xflag: xtract
  70      * tflag: table
  71      * vflag: verbose
  72      * flag0: no zip compression (store only)
  73      * Mflag: DO NOT generate a manifest file (just ZIP)
  74      * iflag: generate jar index
  75      */
  76     boolean cflag, uflag, xflag, tflag, vflag, flag0, Mflag, iflag;
  77 
  78     static final String MANIFEST_DIR = "META-INF/";
  79     static final String VERSION = "1.0";
  80 
  81     // valid values for Profile attribute
  82     private static final String[] PROFILES = { "compact1", "compact2", "compact3" };
  83 
  84     private static ResourceBundle rsrc;
  85 
  86     /**
  87      * If true, maintain compatibility with JDK releases prior to 6.0 by
  88      * timestamping extracted files with the time at which they are extracted.
  89      * Default is to use the time given in the archive.
  90      */
  91     private static final boolean useExtractionTime =
  92         Boolean.getBoolean("sun.tools.jar.useExtractionTime");
  93 
  94     /**
  95      * Initialize ResourceBundle
  96      */
  97     static {
  98         try {
  99             rsrc = ResourceBundle.getBundle("sun.tools.jar.resources.jar");
 100         } catch (MissingResourceException e) {
 101             throw new Error("Fatal: Resource for jar is missing");
 102         }
 103     }


 170                 InputStream in = null;
 171 
 172                 if (!Mflag) {
 173                     if (mname != null) {
 174                         in = new FileInputStream(mname);
 175                         manifest = new Manifest(new BufferedInputStream(in));
 176                     } else {
 177                         manifest = new Manifest();
 178                     }
 179                     addVersion(manifest);
 180                     addCreatedBy(manifest);
 181                     if (isAmbiguousMainClass(manifest)) {
 182                         if (in != null) {
 183                             in.close();
 184                         }
 185                         return false;
 186                     }
 187                     if (ename != null) {
 188                         addMainClass(manifest, ename);
 189                     }
 190                     if (pname != null) {
 191                         if (!addProfileName(manifest, pname)) {
 192                             if (in != null) {
 193                                 in.close();
 194                             }
 195                             return false;
 196                         }
 197                     }
 198                 }
 199                 OutputStream out;
 200                 if (fname != null) {
 201                     out = new FileOutputStream(fname);
 202                 } else {
 203                     out = new FileOutputStream(FileDescriptor.out);
 204                     if (vflag) {
 205                         // Disable verbose output so that it does not appear
 206                         // on stdout along with file data
 207                         // error("Warning: -v option ignored");
 208                         vflag = false;
 209                     }
 210                 }
 211                 expand(null, files, false);
 212                 create(new BufferedOutputStream(out, 4096), manifest);
 213                 if (in != null) {
 214                     in.close();
 215                 }
 216                 out.close();
 217             } else if (uflag) {


 224                     in = new FileInputStream(inputFile);
 225                     out = new FileOutputStream(tmpFile);
 226                 } else {
 227                     in = new FileInputStream(FileDescriptor.in);
 228                     out = new FileOutputStream(FileDescriptor.out);
 229                     vflag = false;
 230                 }
 231                 InputStream manifest = (!Mflag && (mname != null)) ?
 232                     (new FileInputStream(mname)) : null;
 233                 expand(null, files, true);
 234                 boolean updateOk = update(in, new BufferedOutputStream(out),
 235                                           manifest, null);
 236                 if (ok) {
 237                     ok = updateOk;
 238                 }
 239                 in.close();
 240                 out.close();
 241                 if (manifest != null) {
 242                     manifest.close();
 243                 }
 244                 if (ok && fname != null) {
 245                     // on Win32, we need this delete
 246                     inputFile.delete();
 247                     if (!tmpFile.renameTo(inputFile)) {
 248                         tmpFile.delete();
 249                         throw new IOException(getMsg("error.write.file"));
 250                     }
 251                     tmpFile.delete();
 252                 }
 253             } else if (tflag) {
 254                 replaceFSC(files);
 255                 if (fname != null) {
 256                     list(fname, files);
 257                 } else {
 258                     InputStream in = new FileInputStream(FileDescriptor.in);
 259                     try{
 260                         list(new BufferedInputStream(in), files);
 261                     } finally {
 262                         in.close();
 263                     }
 264                 }


 355                     fname = args[count++];
 356                     break;
 357                 case 'm':
 358                     mname = args[count++];
 359                     break;
 360                 case '0':
 361                     flag0 = true;
 362                     break;
 363                 case 'i':
 364                     if (cflag || uflag || xflag || tflag) {
 365                         usageError();
 366                         return false;
 367                     }
 368                     // do not increase the counter, files will contain rootjar
 369                     rootjar = args[count++];
 370                     iflag = true;
 371                     break;
 372                 case 'e':
 373                      ename = args[count++];
 374                      break;
 375                 case 'p':
 376                      pname = args[count++];
 377                      break;
 378                 default:
 379                     error(formatMsg("error.illegal.option",
 380                                 String.valueOf(flags.charAt(i))));
 381                     usageError();
 382                     return false;
 383                 }
 384             }
 385         } catch (ArrayIndexOutOfBoundsException e) {
 386             usageError();
 387             return false;
 388         }
 389         if (!cflag && !tflag && !xflag && !uflag && !iflag) {
 390             error(getMsg("error.bad.option"));
 391             usageError();
 392             return false;
 393         }
 394         /* parse file arguments */
 395         int n = args.length - count;
 396         if (n > 0) {
 397             int k = 0;


 407                         while (dir.indexOf("//") > -1) {
 408                             dir = dir.replace("//", "/");
 409                         }
 410                         paths.add(dir.replace(File.separatorChar, '/'));
 411                         nameBuf[k++] = dir + args[++i];
 412                     } else {
 413                         nameBuf[k++] = args[i];
 414                     }
 415                 }
 416             } catch (ArrayIndexOutOfBoundsException e) {
 417                 usageError();
 418                 return false;
 419             }
 420             files = new String[k];
 421             System.arraycopy(nameBuf, 0, files, 0, k);
 422         } else if (cflag && (mname == null)) {
 423             error(getMsg("error.bad.cflag"));
 424             usageError();
 425             return false;
 426         } else if (uflag) {
 427             if ((mname != null) || (ename != null) || (pname != null)) {
 428                 /* just want to update the manifest */
 429                 return true;
 430             } else {
 431                 error(getMsg("error.bad.uflag"));
 432                 usageError();
 433                 return false;
 434             }
 435         }
 436         return true;
 437     }
 438 
 439     /**
 440      * Expands list of files to process into full list of all files that
 441      * can be found by recursively descending directories.
 442      */
 443     void expand(File dir, String[] files, boolean isUpdate) {
 444         if (files == null) {
 445             return;
 446         }
 447         for (int i = 0; i < files.length; i++) {


 541         ZipInputStream zis = new ZipInputStream(in);
 542         ZipOutputStream zos = new JarOutputStream(out);
 543         ZipEntry e = null;
 544         boolean foundManifest = false;
 545         boolean updateOk = true;
 546 
 547         if (jarIndex != null) {
 548             addIndex(jarIndex, zos);
 549         }
 550 
 551         // put the old entries first, replace if necessary
 552         while ((e = zis.getNextEntry()) != null) {
 553             String name = e.getName();
 554 
 555             boolean isManifestEntry = equalsIgnoreCase(name, MANIFEST_NAME);
 556 
 557             if ((jarIndex != null && equalsIgnoreCase(name, INDEX_NAME))
 558                 || (Mflag && isManifestEntry)) {
 559                 continue;
 560             } else if (isManifestEntry && ((newManifest != null) ||
 561                         (ename != null) || (pname != null))) {
 562                 foundManifest = true;
 563                 if (newManifest != null) {
 564                     // Don't read from the newManifest InputStream, as we
 565                     // might need it below, and we can't re-read the same data
 566                     // twice.
 567                     FileInputStream fis = new FileInputStream(mname);
 568                     boolean ambiguous = isAmbiguousMainClass(new Manifest(fis));
 569                     fis.close();
 570                     if (ambiguous) {
 571                         return false;
 572                     }
 573                 }
 574 
 575                 // Update the manifest.
 576                 Manifest old = new Manifest(zis);
 577                 if (newManifest != null) {
 578                     old.read(newManifest);
 579                 }
 580                 if (!updateManifest(old, zos)) {
 581                     return false;
 582                 }
 583             } else {
 584                 if (!entryMap.containsKey(name)) { // copy the old stuff
 585                     // do our own compression
 586                     ZipEntry e2 = new ZipEntry(name);
 587                     e2.setMethod(e.getMethod());
 588                     e2.setTime(e.getTime());
 589                     e2.setComment(e.getComment());
 590                     e2.setExtra(e.getExtra());
 591                     if (e.getMethod() == ZipEntry.STORED) {
 592                         e2.setSize(e.getSize());
 593                         e2.setCrc(e.getCrc());
 594                     }
 595                     zos.putNextEntry(e2);
 596                     copy(zis, zos);
 597                 } else { // replace with the new files
 598                     File f = entryMap.get(name);
 599                     addFile(zos, f);
 600                     entryMap.remove(name);
 601                     entries.remove(f);
 602                 }
 603             }
 604         }
 605 
 606         // add the remaining new files
 607         for (File f: entries) {
 608             addFile(zos, f);
 609         }
 610         if (!foundManifest) {
 611             if (newManifest != null) {
 612                 Manifest m = new Manifest(newManifest);
 613                 updateOk = !isAmbiguousMainClass(m);
 614                 if (updateOk) {
 615                     if (!updateManifest(m, zos)) {
 616                         updateOk = false;
 617                     }
 618                 }
 619             } else if (ename != null || pname != null) {
 620                 if (!updateManifest(new Manifest(), zos)) {
 621                     updateOk = false;
 622                 }


 623             }
 624         }
 625         zis.close();
 626         zos.close();
 627         return updateOk;
 628     }
 629 
 630 
 631     private void addIndex(JarIndex index, ZipOutputStream zos)
 632         throws IOException
 633     {
 634         ZipEntry e = new ZipEntry(INDEX_NAME);
 635         e.setTime(System.currentTimeMillis());
 636         if (flag0) {
 637             CRC32OutputStream os = new CRC32OutputStream();
 638             index.write(os);
 639             os.updateEntry(e);
 640         }
 641         zos.putNextEntry(e);
 642         index.write(zos);
 643         zos.closeEntry();
 644     }
 645 
 646     private boolean updateManifest(Manifest m, ZipOutputStream zos)
 647         throws IOException
 648     {
 649         addVersion(m);
 650         addCreatedBy(m);
 651         if (ename != null) {
 652             addMainClass(m, ename);
 653         }
 654         if (pname != null) {
 655             if (!addProfileName(m, pname)) {
 656                 return false;
 657             }
 658         }
 659         ZipEntry e = new ZipEntry(MANIFEST_NAME);
 660         e.setTime(System.currentTimeMillis());
 661         if (flag0) {
 662             crc32Manifest(e, m);
 663         }
 664         zos.putNextEntry(e);
 665         m.write(zos);
 666         if (vflag) {
 667             output(getMsg("out.update.manifest"));
 668         }
 669         return true;
 670     }
 671 
 672 
 673     private String entryName(String name) {
 674         name = name.replace(File.separatorChar, '/');
 675         String matchPath = "";
 676         for (String path : paths) {
 677             if (name.startsWith(path)
 678                 && (path.length() > matchPath.length())) {
 679                 matchPath = path;
 680             }
 681         }
 682         name = name.substring(matchPath.length());
 683 
 684         if (name.startsWith("/")) {
 685             name = name.substring(1);
 686         } else if (name.startsWith("./")) {
 687             name = name.substring(2);
 688         }
 689         return name;


 694         if (global.getValue(Attributes.Name.MANIFEST_VERSION) == null) {
 695             global.put(Attributes.Name.MANIFEST_VERSION, VERSION);
 696         }
 697     }
 698 
 699     private void addCreatedBy(Manifest m) {
 700         Attributes global = m.getMainAttributes();
 701         if (global.getValue(new Attributes.Name("Created-By")) == null) {
 702             String javaVendor = System.getProperty("java.vendor");
 703             String jdkVersion = System.getProperty("java.version");
 704             global.put(new Attributes.Name("Created-By"), jdkVersion + " (" +
 705                         javaVendor + ")");
 706         }
 707     }
 708 
 709     private void addMainClass(Manifest m, String mainApp) {
 710         Attributes global = m.getMainAttributes();
 711 
 712         // overrides any existing Main-Class attribute
 713         global.put(Attributes.Name.MAIN_CLASS, mainApp);
 714     }
 715 
 716     private boolean addProfileName(Manifest m, String profile) {
 717         // check profile name
 718         boolean found = false;
 719         int i = 0;
 720         while (i < PROFILES.length) {
 721             if (profile.equals(PROFILES[i])) {
 722                 found = true;
 723                 break;
 724             }
 725             i++;
 726         }
 727         if (!found) {
 728             error(formatMsg("error.bad.pvalue", profile));
 729             return false;
 730         }
 731 
 732         // overrides any existing Profile attribute
 733         Attributes global = m.getMainAttributes();
 734         global.put(Attributes.Name.PROFILE, profile);
 735         return true;
 736     }
 737 
 738     private boolean isAmbiguousMainClass(Manifest m) {
 739         if (ename != null) {
 740             Attributes global = m.getMainAttributes();
 741             if ((global.get(Attributes.Name.MAIN_CLASS) != null)) {
 742                 error(getMsg("error.bad.eflag"));
 743                 usageError();
 744                 return true;
 745             }
 746         }
 747         return false;
 748     }
 749 
 750     /**
 751      * Adds a new file entry to the ZIP output stream.
 752      */
 753     void addFile(ZipOutputStream zos, File file) throws IOException {
 754         String name = file.getPath();
 755         boolean isDir = file.isDirectory();


src/share/classes/sun/tools/jar/Main.java
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File