git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@806174 13f79535-47bb-0310-9956-ffa450edef68master
| @@ -439,6 +439,14 @@ Fixed bugs: | |||||
| * The update attribute of the modified selector was ignored. | * The update attribute of the modified selector was ignored. | ||||
| Bugzilla Report 32597. | Bugzilla Report 32597. | ||||
| * <manifest> and <jar> can now merge Class-Path attributes from | |||||
| multiple sources and optionally flatten them into a single | |||||
| attribute. | |||||
| The default behaviour still is to keep multiple Class-Path | |||||
| attributes if they have been specified and to only include the | |||||
| attributes of the last merged manifest. | |||||
| Bugzilla Report 39655. | |||||
| Other changes: | Other changes: | ||||
| -------------- | -------------- | ||||
| * The get task now also follows redirects from http to https | * The get task now also follows redirects from http to https | ||||
| @@ -245,6 +245,25 @@ to a value other than its default, <code>"add"</code>.</b></p> | |||||
| zip task page</a></td> | zip task page</a></td> | ||||
| <td align="center" valign="top">No, default is false</td> | <td align="center" valign="top">No, default is false</td> | ||||
| </tr> | </tr> | ||||
| <tr> | |||||
| <td valign="top">mergeClassPathAttributes</td> | |||||
| <td valign="top">Whether to merge the Class-Path attributes found | |||||
| in different manifests (if merging manifests). If false, only | |||||
| the attribute of the last merged manifest will be preserved. | |||||
| <em>Since Ant 1.8.0</em>. | |||||
| <br/>unless you also set flattenAttributes to true this may | |||||
| result in manifests containing multiple Class-Path attributes | |||||
| which violates the manifest specification.</td> | |||||
| <td align="center" valign="top">No, default is false</td> | |||||
| </tr> | |||||
| <tr> | |||||
| <td valign="top">flattenAttributes</td> | |||||
| <td valign="top">Whether to merge attributes occuring more than | |||||
| once in a section (this can only happen for the Class-Path | |||||
| attribute) into a single attribute. | |||||
| <em>Since Ant 1.8.0</em>.</td> | |||||
| <td align="center" valign="top">No, default is false</td> | |||||
| </tr> | |||||
| </table> | </table> | ||||
| <h3>Nested elements</h3> | <h3>Nested elements</h3> | ||||
| @@ -301,6 +301,25 @@ to a value other than its default, <code>"add"</code>.</b></p> | |||||
| zip task page</a></td> | zip task page</a></td> | ||||
| <td align="center" valign="top">No, default is false</td> | <td align="center" valign="top">No, default is false</td> | ||||
| </tr> | </tr> | ||||
| <tr> | |||||
| <td valign="top">mergeClassPathAttributes</td> | |||||
| <td valign="top">Whether to merge the Class-Path attributes found | |||||
| in different manifests (if merging manifests). If false, only | |||||
| the attribute of the last merged manifest will be preserved. | |||||
| <em>Since Ant 1.8.0</em>. | |||||
| <br/>unless you also set flattenAttributes to true this may | |||||
| result in manifests containing multiple Class-Path attributes | |||||
| which violates the manifest specification.</td> | |||||
| <td align="center" valign="top">No, default is false</td> | |||||
| </tr> | |||||
| <tr> | |||||
| <td valign="top">flattenAttributes</td> | |||||
| <td valign="top">Whether to merge attributes occuring more than | |||||
| once in a section (this can only happen for the Class-Path | |||||
| attribute) into a single attribute. | |||||
| <em>Since Ant 1.8.0</em>.</td> | |||||
| <td align="center" valign="top">No, default is false</td> | |||||
| </tr> | |||||
| </table> | </table> | ||||
| <h3>Nested elements</h3> | <h3>Nested elements</h3> | ||||
| @@ -82,6 +82,25 @@ line.</p> | |||||
| manifest.</td> | manifest.</td> | ||||
| <td valign="top" align="center">No, defaults to UTF-8 encoding.</td> | <td valign="top" align="center">No, defaults to UTF-8 encoding.</td> | ||||
| </tr> | </tr> | ||||
| <tr> | |||||
| <td valign="top">mergeClassPathAttributes</td> | |||||
| <td valign="top">Whether to merge the Class-Path attributes found | |||||
| in different manifests (if updating). If false, only the | |||||
| attribute of the most recent manifest will be preserved. | |||||
| <em>Since Ant 1.8.0</em>. | |||||
| <br/>unless you also set flattenAttributes to true this may | |||||
| result in manifests containing multiple Class-Path attributes | |||||
| which violates the manifest specification.</td> | |||||
| <td align="center" valign="top">No, default is false</td> | |||||
| </tr> | |||||
| <tr> | |||||
| <td valign="top">flattenAttributes</td> | |||||
| <td valign="top">Whether to merge attributes occuring more than | |||||
| once in a section (this can only happen for the Class-Path | |||||
| attribute) into a single attribute. | |||||
| <em>Since Ant 1.8.0</em>.</td> | |||||
| <td align="center" valign="top">No, default is false</td> | |||||
| </tr> | |||||
| </table> | </table> | ||||
| <h3>Nested elements</h3> | <h3>Nested elements</h3> | ||||
| @@ -248,6 +248,25 @@ to a value other than its default, <code>"add"</code>.</b></p> | |||||
| zip task page</a></td> | zip task page</a></td> | ||||
| <td align="center" valign="top">No, default is false</td> | <td align="center" valign="top">No, default is false</td> | ||||
| </tr> | </tr> | ||||
| <tr> | |||||
| <td valign="top">mergeClassPathAttributes</td> | |||||
| <td valign="top">Whether to merge the Class-Path attributes found | |||||
| in different manifests (if merging manifests). If false, only | |||||
| the attribute of the last merged manifest will be preserved. | |||||
| <em>Since Ant 1.8.0</em>. | |||||
| <br/>unless you also set flattenAttributes to true this may | |||||
| result in manifests containing multiple Class-Path attributes | |||||
| which violates the manifest specification.</td> | |||||
| <td align="center" valign="top">No, default is false</td> | |||||
| </tr> | |||||
| <tr> | |||||
| <td valign="top">flattenAttributes</td> | |||||
| <td valign="top">Whether to merge attributes occuring more than | |||||
| once in a section (this can only happen for the Class-Path | |||||
| attribute) into a single attribute. | |||||
| <em>Since Ant 1.8.0</em>.</td> | |||||
| <td align="center" valign="top">No, default is false</td> | |||||
| </tr> | |||||
| </table> | </table> | ||||
| <h3>Nested elements</h3> | <h3>Nested elements</h3> | ||||
| @@ -157,6 +157,16 @@ public class Jar extends Zip { | |||||
| // CheckStyle:LineLength ON | // CheckStyle:LineLength ON | ||||
| /** | |||||
| * whether to merge Class-Path attributes. | |||||
| */ | |||||
| private boolean mergeClassPaths = false; | |||||
| /** | |||||
| * whether to flatten Class-Path attributes into a single one. | |||||
| */ | |||||
| private boolean flattenClassPaths = false; | |||||
| /** | /** | ||||
| * Extra fields needed to make Solaris recognize the archive as a jar file. | * Extra fields needed to make Solaris recognize the archive as a jar file. | ||||
| * | * | ||||
| @@ -268,7 +278,7 @@ public class Jar extends Zip { | |||||
| if (configuredManifest == null) { | if (configuredManifest == null) { | ||||
| configuredManifest = newManifest; | configuredManifest = newManifest; | ||||
| } else { | } else { | ||||
| configuredManifest.merge(newManifest); | |||||
| configuredManifest.merge(newManifest, false, mergeClassPaths); | |||||
| } | } | ||||
| savedConfiguredManifest = configuredManifest; | savedConfiguredManifest = configuredManifest; | ||||
| } | } | ||||
| @@ -473,6 +483,24 @@ public class Jar extends Zip { | |||||
| } | } | ||||
| } | } | ||||
| /** | |||||
| * Whether to merge Class-Path attributes. | |||||
| * | |||||
| * @since Ant 1.8.0 | |||||
| */ | |||||
| public void setMergeClassPathAttributes(boolean b) { | |||||
| mergeClassPaths = b; | |||||
| } | |||||
| /** | |||||
| * Whether to flatten multi-valued attributes (i.e. Class-Path) | |||||
| * into a single one. | |||||
| * | |||||
| * @since Ant 1.8.0 | |||||
| */ | |||||
| public void setFlattenAttributes(boolean b) { | |||||
| flattenClassPaths = b; | |||||
| } | |||||
| /** | /** | ||||
| * Initialize the zip output stream. | * Initialize the zip output stream. | ||||
| @@ -512,11 +540,13 @@ public class Jar extends Zip { | |||||
| */ | */ | ||||
| if (isInUpdateMode()) { | if (isInUpdateMode()) { | ||||
| finalManifest.merge(originalManifest); | |||||
| finalManifest.merge(originalManifest, false, mergeClassPaths); | |||||
| } | } | ||||
| finalManifest.merge(filesetManifest); | |||||
| finalManifest.merge(configuredManifest, !mergeManifestsMain); | |||||
| finalManifest.merge(manifest, !mergeManifestsMain); | |||||
| finalManifest.merge(filesetManifest, false, mergeClassPaths); | |||||
| finalManifest.merge(configuredManifest, !mergeManifestsMain, | |||||
| mergeClassPaths); | |||||
| finalManifest.merge(manifest, !mergeManifestsMain, | |||||
| mergeClassPaths); | |||||
| return finalManifest; | return finalManifest; | ||||
| @@ -540,7 +570,7 @@ public class Jar extends Zip { | |||||
| ByteArrayOutputStream baos = new ByteArrayOutputStream(); | ByteArrayOutputStream baos = new ByteArrayOutputStream(); | ||||
| OutputStreamWriter osw = new OutputStreamWriter(baos, Manifest.JAR_ENCODING); | OutputStreamWriter osw = new OutputStreamWriter(baos, Manifest.JAR_ENCODING); | ||||
| PrintWriter writer = new PrintWriter(osw); | PrintWriter writer = new PrintWriter(osw); | ||||
| manifest.write(writer); | |||||
| manifest.write(writer, flattenClassPaths); | |||||
| if (writer.checkError()) { | if (writer.checkError()) { | ||||
| throw new IOException("Encountered an error writing the manifest"); | throw new IOException("Encountered an error writing the manifest"); | ||||
| } | } | ||||
| @@ -724,7 +754,7 @@ public class Jar extends Zip { | |||||
| if (filesetManifest == null) { | if (filesetManifest == null) { | ||||
| filesetManifest = newManifest; | filesetManifest = newManifest; | ||||
| } else { | } else { | ||||
| filesetManifest.merge(newManifest); | |||||
| filesetManifest.merge(newManifest, false, mergeClassPaths); | |||||
| } | } | ||||
| } catch (UnsupportedEncodingException e) { | } catch (UnsupportedEncodingException e) { | ||||
| throw new BuildException("Unsupported encoding while reading " | throw new BuildException("Unsupported encoding while reading " | ||||
| @@ -304,16 +304,37 @@ public class Manifest { | |||||
| } | } | ||||
| /** | /** | ||||
| * Write the attribute out to a print writer. | |||||
| * Write the attribute out to a print writer without | |||||
| * flattening multi-values attributes (i.e. Class-Path). | |||||
| * | * | ||||
| * @param writer the Writer to which the attribute is written | * @param writer the Writer to which the attribute is written | ||||
| * | * | ||||
| * @throws IOException if the attribute value cannot be written | * @throws IOException if the attribute value cannot be written | ||||
| */ | */ | ||||
| public void write(PrintWriter writer) throws IOException { | public void write(PrintWriter writer) throws IOException { | ||||
| write(writer, false); | |||||
| } | |||||
| /** | |||||
| * Write the attribute out to a print writer. | |||||
| * | |||||
| * @param writer the Writer to which the attribute is written | |||||
| * @param flatten whether to collapse multi-valued attributes | |||||
| * (i.e. potentially Class-Path) Class-Path into a | |||||
| * single attribute. | |||||
| * | |||||
| * @throws IOException if the attribute value cannot be written | |||||
| * @since Ant 1.8.0 | |||||
| */ | |||||
| public void write(PrintWriter writer, boolean flatten) | |||||
| throws IOException { | |||||
| if (!flatten) { | |||||
| for (Enumeration e = getValues(); e.hasMoreElements();) { | for (Enumeration e = getValues(); e.hasMoreElements();) { | ||||
| writeValue(writer, (String) e.nextElement()); | writeValue(writer, (String) e.nextElement()); | ||||
| } | } | ||||
| } else { | |||||
| writeValue(writer, getValue()); | |||||
| } | |||||
| } | } | ||||
| /** | /** | ||||
| @@ -448,13 +469,27 @@ public class Manifest { | |||||
| } | } | ||||
| /** | /** | ||||
| * Merge in another section | |||||
| * Merge in another section without merging Class-Path attributes. | |||||
| * | * | ||||
| * @param section the section to be merged with this one. | * @param section the section to be merged with this one. | ||||
| * | * | ||||
| * @throws ManifestException if the sections cannot be merged. | * @throws ManifestException if the sections cannot be merged. | ||||
| */ | */ | ||||
| public void merge(Section section) throws ManifestException { | public void merge(Section section) throws ManifestException { | ||||
| merge(section, false); | |||||
| } | |||||
| /** | |||||
| * Merge in another section | |||||
| * | |||||
| * @param section the section to be merged with this one. | |||||
| * @param mergeClassPaths whether Class-Path attributes should | |||||
| * be merged. | |||||
| * | |||||
| * @throws ManifestException if the sections cannot be merged. | |||||
| */ | |||||
| public void merge(Section section, boolean mergeClassPaths) | |||||
| throws ManifestException { | |||||
| if (name == null && section.getName() != null | if (name == null && section.getName() != null | ||||
| || name != null | || name != null | ||||
| && !(name.equalsIgnoreCase(section.getName()))) { | && !(name.equalsIgnoreCase(section.getName()))) { | ||||
| @@ -484,7 +519,16 @@ public class Manifest { | |||||
| } | } | ||||
| if (classpathAttribute != null) { | if (classpathAttribute != null) { | ||||
| // the merge file *always* wins, even for Class-Path | |||||
| if (mergeClassPaths) { | |||||
| Attribute currentCp = getAttribute(ATTRIBUTE_CLASSPATH); | |||||
| if (currentCp != null) { | |||||
| for (Enumeration attribEnum = currentCp.getValues(); | |||||
| attribEnum.hasMoreElements(); ) { | |||||
| String value = (String) attribEnum.nextElement(); | |||||
| classpathAttribute.addValue(value); | |||||
| } | |||||
| } | |||||
| } | |||||
| storeAttribute(classpathAttribute); | storeAttribute(classpathAttribute); | ||||
| } | } | ||||
| @@ -496,13 +540,30 @@ public class Manifest { | |||||
| } | } | ||||
| /** | /** | ||||
| * Write the section out to a print writer. | |||||
| * Write the section out to a print writer without flattening | |||||
| * multi-values attributes (i.e. Class-Path). | |||||
| * | * | ||||
| * @param writer the Writer to which the section is written | * @param writer the Writer to which the section is written | ||||
| * | * | ||||
| * @throws IOException if the section cannot be written | * @throws IOException if the section cannot be written | ||||
| */ | */ | ||||
| public void write(PrintWriter writer) throws IOException { | public void write(PrintWriter writer) throws IOException { | ||||
| write(writer, false); | |||||
| } | |||||
| /** | |||||
| * Write the section out to a print writer. | |||||
| * | |||||
| * @param writer the Writer to which the section is written | |||||
| * @param flatten whether to collapse multi-valued attributes | |||||
| * (i.e. potentially Class-Path) Class-Path into a | |||||
| * single attribute. | |||||
| * | |||||
| * @throws IOException if the section cannot be written | |||||
| * @since Ant 1.8.0 | |||||
| */ | |||||
| public void write(PrintWriter writer, boolean flatten) | |||||
| throws IOException { | |||||
| if (name != null) { | if (name != null) { | ||||
| Attribute nameAttr = new Attribute(ATTRIBUTE_NAME, name); | Attribute nameAttr = new Attribute(ATTRIBUTE_NAME, name); | ||||
| nameAttr.write(writer); | nameAttr.write(writer); | ||||
| @@ -511,7 +572,7 @@ public class Manifest { | |||||
| while (e.hasMoreElements()) { | while (e.hasMoreElements()) { | ||||
| String key = (String) e.nextElement(); | String key = (String) e.nextElement(); | ||||
| Attribute attribute = getAttribute(key); | Attribute attribute = getAttribute(key); | ||||
| attribute.write(writer); | |||||
| attribute.write(writer, flatten); | |||||
| } | } | ||||
| writer.print(EOL); | writer.print(EOL); | ||||
| } | } | ||||
| @@ -863,6 +924,7 @@ public class Manifest { | |||||
| /** | /** | ||||
| * Merge the contents of the given manifest into this manifest | * Merge the contents of the given manifest into this manifest | ||||
| * without merging Class-Path attributes. | |||||
| * | * | ||||
| * @param other the Manifest to be merged with this one. | * @param other the Manifest to be merged with this one. | ||||
| * | * | ||||
| @@ -875,6 +937,7 @@ public class Manifest { | |||||
| /** | /** | ||||
| * Merge the contents of the given manifest into this manifest | * Merge the contents of the given manifest into this manifest | ||||
| * without merging Class-Path attributes. | |||||
| * | * | ||||
| * @param other the Manifest to be merged with this one. | * @param other the Manifest to be merged with this one. | ||||
| * @param overwriteMain whether to overwrite the main section | * @param overwriteMain whether to overwrite the main section | ||||
| @@ -885,11 +948,31 @@ public class Manifest { | |||||
| */ | */ | ||||
| public void merge(Manifest other, boolean overwriteMain) | public void merge(Manifest other, boolean overwriteMain) | ||||
| throws ManifestException { | throws ManifestException { | ||||
| merge(other, overwriteMain, false); | |||||
| } | |||||
| /** | |||||
| * Merge the contents of the given manifest into this manifest | |||||
| * | |||||
| * @param other the Manifest to be merged with this one. | |||||
| * @param overwriteMain whether to overwrite the main section | |||||
| * of the current manifest | |||||
| * @param mergeClassPaths whether Class-Path attributes should be | |||||
| * merged. | |||||
| * | |||||
| * @throws ManifestException if there is a problem merging the | |||||
| * manifest according to the Manifest spec. | |||||
| * | |||||
| * @since Ant 1.8.0 | |||||
| */ | |||||
| public void merge(Manifest other, boolean overwriteMain, | |||||
| boolean mergeClassPaths) | |||||
| throws ManifestException { | |||||
| if (other != null) { | if (other != null) { | ||||
| if (overwriteMain) { | if (overwriteMain) { | ||||
| mainSection = (Section) other.mainSection.clone(); | mainSection = (Section) other.mainSection.clone(); | ||||
| } else { | } else { | ||||
| mainSection.merge(other.mainSection); | |||||
| mainSection.merge(other.mainSection, mergeClassPaths); | |||||
| } | } | ||||
| if (other.manifestVersion != null) { | if (other.manifestVersion != null) { | ||||
| @@ -907,20 +990,36 @@ public class Manifest { | |||||
| addConfiguredSection((Section) otherSection.clone()); | addConfiguredSection((Section) otherSection.clone()); | ||||
| } | } | ||||
| } else { | } else { | ||||
| ourSection.merge(otherSection); | |||||
| ourSection.merge(otherSection, mergeClassPaths); | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /** | |||||
| * Write the manifest out to a print writer without flattening | |||||
| * multi-values attributes (i.e. Class-Path). | |||||
| * | |||||
| * @param writer the Writer to which the manifest is written | |||||
| * | |||||
| * @throws IOException if the manifest cannot be written | |||||
| */ | |||||
| public void write(PrintWriter writer) throws IOException { | |||||
| write(writer, false); | |||||
| } | |||||
| /** | /** | ||||
| * Write the manifest out to a print writer. | * Write the manifest out to a print writer. | ||||
| * | * | ||||
| * @param writer the Writer to which the manifest is written | * @param writer the Writer to which the manifest is written | ||||
| * @param flatten whether to collapse multi-valued attributes | |||||
| * (i.e. potentially Class-Path) Class-Path into a single | |||||
| * attribute. | |||||
| * | * | ||||
| * @throws IOException if the manifest cannot be written | * @throws IOException if the manifest cannot be written | ||||
| * @since Ant 1.8.0 | |||||
| */ | */ | ||||
| public void write(PrintWriter writer) throws IOException { | |||||
| public void write(PrintWriter writer, boolean flatten) throws IOException { | |||||
| writer.print(ATTRIBUTE_MANIFEST_VERSION + ": " + manifestVersion + EOL); | writer.print(ATTRIBUTE_MANIFEST_VERSION + ": " + manifestVersion + EOL); | ||||
| String signatureVersion | String signatureVersion | ||||
| = mainSection.getAttributeValue(ATTRIBUTE_SIGNATURE_VERSION); | = mainSection.getAttributeValue(ATTRIBUTE_SIGNATURE_VERSION); | ||||
| @@ -929,7 +1028,7 @@ public class Manifest { | |||||
| + signatureVersion + EOL); | + signatureVersion + EOL); | ||||
| mainSection.removeAttribute(ATTRIBUTE_SIGNATURE_VERSION); | mainSection.removeAttribute(ATTRIBUTE_SIGNATURE_VERSION); | ||||
| } | } | ||||
| mainSection.write(writer); | |||||
| mainSection.write(writer, flatten); | |||||
| // add it back | // add it back | ||||
| if (signatureVersion != null) { | if (signatureVersion != null) { | ||||
| @@ -946,7 +1045,7 @@ public class Manifest { | |||||
| while (e.hasMoreElements()) { | while (e.hasMoreElements()) { | ||||
| String sectionName = (String) e.nextElement(); | String sectionName = (String) e.nextElement(); | ||||
| Section section = getSection(sectionName); | Section section = getSection(sectionName); | ||||
| section.write(writer); | |||||
| section.write(writer, flatten); | |||||
| } | } | ||||
| } | } | ||||
| @@ -72,6 +72,16 @@ public class ManifestTask extends Task { | |||||
| */ | */ | ||||
| private String encoding; | private String encoding; | ||||
| /** | |||||
| * whether to merge Class-Path attributes. | |||||
| */ | |||||
| private boolean mergeClassPaths = false; | |||||
| /** | |||||
| * whether to flatten Class-Path attributes into a single one. | |||||
| */ | |||||
| private boolean flattenClassPaths = false; | |||||
| /** | /** | ||||
| * Helper class for Manifest's mode attribute. | * Helper class for Manifest's mode attribute. | ||||
| */ | */ | ||||
| @@ -183,6 +193,25 @@ public class ManifestTask extends Task { | |||||
| mode = m; | mode = m; | ||||
| } | } | ||||
| /** | |||||
| * Whether to merge Class-Path attributes. | |||||
| * | |||||
| * @since Ant 1.8.0 | |||||
| */ | |||||
| public void setMergeClassPathAttributes(boolean b) { | |||||
| mergeClassPaths = b; | |||||
| } | |||||
| /** | |||||
| * Whether to flatten multi-valued attributes (i.e. Class-Path) | |||||
| * into a single one. | |||||
| * | |||||
| * @since Ant 1.8.0 | |||||
| */ | |||||
| public void setFlattenAttributes(boolean b) { | |||||
| flattenClassPaths = b; | |||||
| } | |||||
| /** | /** | ||||
| * Create or update the Manifest when used as a task. | * Create or update the Manifest when used as a task. | ||||
| * | * | ||||
| @@ -228,13 +257,13 @@ public class ManifestTask extends Task { | |||||
| try { | try { | ||||
| if (mode.getValue().equals("update") && manifestFile.exists()) { | if (mode.getValue().equals("update") && manifestFile.exists()) { | ||||
| if (current != null) { | if (current != null) { | ||||
| toWrite.merge(current); | |||||
| toWrite.merge(current, false, mergeClassPaths); | |||||
| } else if (error != null) { | } else if (error != null) { | ||||
| throw error; | throw error; | ||||
| } | } | ||||
| } | } | ||||
| toWrite.merge(nestedManifest); | |||||
| toWrite.merge(nestedManifest, false, mergeClassPaths); | |||||
| } catch (ManifestException m) { | } catch (ManifestException m) { | ||||
| throw new BuildException("Manifest is invalid", m, getLocation()); | throw new BuildException("Manifest is invalid", m, getLocation()); | ||||
| } | } | ||||
| @@ -250,7 +279,7 @@ public class ManifestTask extends Task { | |||||
| FileOutputStream fos = new FileOutputStream(manifestFile); | FileOutputStream fos = new FileOutputStream(manifestFile); | ||||
| OutputStreamWriter osw = new OutputStreamWriter(fos, Manifest.JAR_ENCODING); | OutputStreamWriter osw = new OutputStreamWriter(fos, Manifest.JAR_ENCODING); | ||||
| w = new PrintWriter(osw); | w = new PrintWriter(osw); | ||||
| toWrite.write(w); | |||||
| toWrite.write(w, flattenClassPaths); | |||||
| if (w.checkError()) { | if (w.checkError()) { | ||||
| throw new IOException("Encountered an error writing manifest"); | throw new IOException("Encountered an error writing manifest"); | ||||
| } | } | ||||
| @@ -91,4 +91,49 @@ | |||||
| resource="${file}" | resource="${file}" | ||||
| value="Class-Path: bar "/> | value="Class-Path: bar "/> | ||||
| </target> | </target> | ||||
| <target name="testMergeClassPathAttributes" depends="setUp"> | |||||
| <manifest file="${file}"> | |||||
| <attribute name="Class-Path" value="foo"/> | |||||
| <attribute name="Class-Path" value="bar"/> | |||||
| </manifest> | |||||
| <manifest file="${file}" mergeClassPathAttributes="true" mode="update"> | |||||
| <attribute name="Class-Path" value="baz"/> | |||||
| </manifest> | |||||
| <au:assertResourceContains | |||||
| resource="${file}" | |||||
| value="Class-Path: foo "/> | |||||
| <au:assertResourceContains | |||||
| resource="${file}" | |||||
| value="Class-Path: bar "/> | |||||
| <au:assertResourceContains | |||||
| resource="${file}" | |||||
| value="Class-Path: baz "/> | |||||
| </target> | |||||
| <target name="testFlattenMultipleClassPathAttributes" depends="setUp"> | |||||
| <manifest file="${file}" flattenAttributes="true"> | |||||
| <attribute name="Class-Path" value="foo"/> | |||||
| <attribute name="Class-Path" value="bar"/> | |||||
| </manifest> | |||||
| <au:assertResourceContains | |||||
| resource="${file}" | |||||
| value="Class-Path: foo bar "/> | |||||
| </target> | |||||
| <target name="testMergeAndFlattenClassPathAttributes" depends="setUp"> | |||||
| <manifest file="${file}"> | |||||
| <attribute name="Class-Path" value="foo"/> | |||||
| <attribute name="Class-Path" value="bar"/> | |||||
| </manifest> | |||||
| <manifest file="${file}" | |||||
| mergeClassPathAttributes="true" | |||||
| flattenAttributes="true" | |||||
| mode="update"> | |||||
| <attribute name="Class-Path" value="baz"/> | |||||
| </manifest> | |||||
| <au:assertResourceContains | |||||
| resource="${file}" | |||||
| value="Class-Path: baz foo bar "/> | |||||
| </target> | |||||
| </project> | </project> | ||||