📄 jar.java
字号:
*/ public void setFilesetmanifest(FilesetManifestConfig config) { filesetManifestConfig = config; mergeManifestsMain = "merge".equals(config.getValue()); if (filesetManifestConfig != null && !filesetManifestConfig.getValue().equals("skip")) { doubleFilePass = true; } } /** * Adds a zipfileset to include in the META-INF directory. * * @param fs zipfileset to add */ public void addMetainf(ZipFileSet fs) { // We just set the prefix for this fileset, and pass it up. fs.setPrefix("META-INF/"); super.addFileset(fs); } /** * Add a path to index jars. * @param p a path * @since Ant 1.6.2 */ public void addConfiguredIndexJars(Path p) { if (indexJars == null) { indexJars = new Path(getProject()); } indexJars.append(p); } /** * A nested SPI service element. * @param service the nested element. * @since Ant 1.7 */ public void addConfiguredService(Service service) { // Check if the service is configured correctly service.check(); serviceList.add(service); } /** * Write SPI Information to JAR */ private void writeServices(ZipOutputStream zOut) throws IOException { Iterator serviceIterator; Service service; serviceIterator = serviceList.iterator(); while (serviceIterator.hasNext()) { service = (Service) serviceIterator.next(); //stolen from writeManifest super.zipFile(service.getAsStream(), zOut, "META-INF/services/" + service.getType(), System.currentTimeMillis(), null, ZipFileSet.DEFAULT_FILE_MODE); } } /** * Initialize the zip output stream. * @param zOut the zip output stream * @throws IOException on I/O errors * @throws BuildException on other errors */ protected void initZipOutputStream(ZipOutputStream zOut) throws IOException, BuildException { if (!skipWriting) { Manifest jarManifest = createManifest(); writeManifest(zOut, jarManifest); writeServices(zOut); } } private Manifest createManifest() throws BuildException { try { Manifest finalManifest = Manifest.getDefaultManifest(); if (manifest == null) { if (manifestFile != null) { // if we haven't got the manifest yet, attempt to // get it now and have manifest be the final merge manifest = getManifest(manifestFile); } } /* * Precedence: manifestFile wins over inline manifest, * over manifests read from the filesets over the original * manifest. * * merge with null argument is a no-op */ if (isInUpdateMode()) { finalManifest.merge(originalManifest); } finalManifest.merge(filesetManifest); finalManifest.merge(configuredManifest); finalManifest.merge(manifest, !mergeManifestsMain); return finalManifest; } catch (ManifestException e) { log("Manifest is invalid: " + e.getMessage(), Project.MSG_ERR); throw new BuildException("Invalid Manifest", e, getLocation()); } } private void writeManifest(ZipOutputStream zOut, Manifest manifest) throws IOException { for (Enumeration e = manifest.getWarnings(); e.hasMoreElements();) { log("Manifest warning: " + e.nextElement(), Project.MSG_WARN); } zipDir(null, zOut, "META-INF/", ZipFileSet.DEFAULT_DIR_MODE, JAR_MARKER); // time to write the manifest ByteArrayOutputStream baos = new ByteArrayOutputStream(); OutputStreamWriter osw = new OutputStreamWriter(baos, Manifest.JAR_ENCODING); PrintWriter writer = new PrintWriter(osw); manifest.write(writer); writer.close(); ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); super.zipFile(bais, zOut, MANIFEST_NAME, System.currentTimeMillis(), null, ZipFileSet.DEFAULT_FILE_MODE); super.initZipOutputStream(zOut); } /** * Finalize the zip output stream. * This creates an index list if the index attribute is true. * @param zOut the zip output stream * @throws IOException on I/O errors * @throws BuildException on other errors */ protected void finalizeZipOutputStream(ZipOutputStream zOut) throws IOException, BuildException { if (index) { createIndexList(zOut); } } /** * Create the index list to speed up classloading. * This is a JDK 1.3+ specific feature and is enabled by default. See * <a href="http://java.sun.com/j2se/1.3/docs/guide/jar/jar.html#JAR%20Index"> * the JAR index specification</a> for more details. * * @param zOut the zip stream representing the jar being built. * @throws IOException thrown if there is an error while creating the * index and adding it to the zip stream. */ private void createIndexList(ZipOutputStream zOut) throws IOException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); // encoding must be UTF8 as specified in the specs. PrintWriter writer = new PrintWriter(new OutputStreamWriter(baos, "UTF8")); // version-info blankline writer.println("JarIndex-Version: 1.0"); writer.println(); // header newline writer.println(zipFile.getName()); writeIndexLikeList(new ArrayList(addedDirs.keySet()), rootEntries, writer); writer.println(); if (indexJars != null) { Manifest mf = createManifest(); Manifest.Attribute classpath = mf.getMainSection().getAttribute(Manifest.ATTRIBUTE_CLASSPATH); String[] cpEntries = null; if (classpath != null && classpath.getValue() != null) { StringTokenizer tok = new StringTokenizer(classpath.getValue(), " "); cpEntries = new String[tok.countTokens()]; int c = 0; while (tok.hasMoreTokens()) { cpEntries[c++] = tok.nextToken(); } } String[] indexJarEntries = indexJars.list(); for (int i = 0; i < indexJarEntries.length; i++) { String name = findJarName(indexJarEntries[i], cpEntries); if (name != null) { ArrayList dirs = new ArrayList(); ArrayList files = new ArrayList(); grabFilesAndDirs(indexJarEntries[i], dirs, files); if (dirs.size() + files.size() > 0) { writer.println(name); writeIndexLikeList(dirs, files, writer); writer.println(); } } } } writer.close(); ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); super.zipFile(bais, zOut, INDEX_NAME, System.currentTimeMillis(), null, ZipFileSet.DEFAULT_FILE_MODE); } /** * Overridden from Zip class to deal with manifests and index lists. * @param is the input stream * @param zOut the zip output stream * @param vPath the name this entry shall have in the archive * @param lastModified last modification time for the entry. * @param fromArchive the original archive we are copying this * entry from, will be null if we are not copying from an archive. * @param mode the Unix permissions to set. * @throws IOException on error */ protected void zipFile(InputStream is, ZipOutputStream zOut, String vPath, long lastModified, File fromArchive, int mode) throws IOException { if (MANIFEST_NAME.equalsIgnoreCase(vPath)) { if (!doubleFilePass || skipWriting) { filesetManifest(fromArchive, is); } } else if (INDEX_NAME.equalsIgnoreCase(vPath) && index) { log("Warning: selected " + archiveType + " files include a META-INF/INDEX.LIST which will" + " be replaced by a newly generated one.", Project.MSG_WARN); } else { if (index && vPath.indexOf("/") == -1) { rootEntries.addElement(vPath); } super.zipFile(is, zOut, vPath, lastModified, fromArchive, mode); } } private void filesetManifest(File file, InputStream is) throws IOException { if (manifestFile != null && manifestFile.equals(file)) { // If this is the same name specified in 'manifest', this // is the manifest to use log("Found manifest " + file, Project.MSG_VERBOSE); try { if (is != null) { InputStreamReader isr; if (manifestEncoding == null) { isr = new InputStreamReader(is); } else { isr = new InputStreamReader(is, manifestEncoding); } manifest = getManifest(isr); } else { manifest = getManifest(file); } } catch (UnsupportedEncodingException e) { throw new BuildException("Unsupported encoding while reading " + "manifest: " + e.getMessage(), e); } } else if (filesetManifestConfig != null && !filesetManifestConfig.getValue().equals("skip")) { // we add this to our group of fileset manifests log("Found manifest to merge in file " + file, Project.MSG_VERBOSE); try { Manifest newManifest = null; if (is != null) { InputStreamReader isr; if (manifestEncoding == null) { isr = new InputStreamReader(is); } else { isr = new InputStreamReader(is, manifestEncoding); } newManifest = getManifest(isr); } else { newManifest = getManifest(file); } if (filesetManifest == null) { filesetManifest = newManifest; } else { filesetManifest.merge(newManifest); } } catch (UnsupportedEncodingException e) { throw new BuildException("Unsupported encoding while reading " + "manifest: " + e.getMessage(), e); } catch (ManifestException e) { log("Manifest in file " + file + " is invalid: " + e.getMessage(), Project.MSG_ERR); throw new BuildException("Invalid Manifest", e, getLocation()); } } else { // assuming 'skip' otherwise // don't warn if skip has been requested explicitly, warn if user // didn't set the attribute // Hide warning also as it makes no sense since // the filesetmanifest attribute itself has been // hidden //int logLevel = filesetManifestConfig == null ? // Project.MSG_WARN : Project.MSG_VERBOSE; //log("File " + file // + " includes a META-INF/MANIFEST.MF which will be ignored. " // + "To include this file, set filesetManifest to a value other " // + "than 'skip'.", logLevel); } } /** * Collect the resources that are newer than the corresponding * entries (or missing) in the original archive. * * <p>If we are going to recreate the archive instead of updating * it, all resources should be considered as new, if a single one * is. Because of this, subclasses overriding this method must * call <code>super.getResourcesToAdd</code> and indicate with the * third arg if they already know that the archive is * out-of-date.</p> * * @param rcs The resource collections to grab resources from * @param zipFile intended archive file (may or may not exist) * @param needsUpdate whether we already know that the archive is * out-of-date. Subclasses overriding this method are supposed to * set this value correctly in their call to * super.getResourcesToAdd. * @return an array of resources to add for each fileset passed in as well * as a flag that indicates whether the archive is uptodate. * * @exception BuildException if it likes */ protected ArchiveState getResourcesToAdd(ResourceCollection[] rcs, File zipFile, boolean needsUpdate) throws BuildException { // need to handle manifest as a special check if (zipFile.exists()) { // if it doesn't exist, it will get created anyway, don't // bother with any up-to-date checks.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -