conor 02/03/20 04:11:57
Modified: src/etc/testcases/taskdefs manifest.xml
src/main/org/apache/tools/ant/taskdefs Manifest.java
src/testcases/org/apache/tools/ant/taskdefs
ManifestTest.java
Log:
Retain order of sections and attributes in manifests.
Revision Changes Path
1.5 +36 -0 jakarta-ant/src/etc/testcases/taskdefs/manifest.xml
Index: manifest.xml
===================================================================
RCS file: /home/cvs/jakarta-ant/src/etc/testcases/taskdefs/manifest.xml,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -w -u -r1.4 -r1.5
--- manifest.xml 14 Feb 2002 00:22:22 -0000 1.4
+++ manifest.xml 20 Mar 2002 12:11:57 -0000 1.5
@@ -128,6 +128,42 @@
</unjar>
</target>
+ <target name="testOrder1">
+ <jar file="mftestOrder1.jar">
+ <manifest>
+ <section name="Test1">
+ <attribute name="TestAttr1" value="Test1"/>
+ <attribute name="TestAttr2" value="Test2"/>
+ </section>
+ <section name="Test2">
+ <attribute name="TestAttrx" value="Testx"/>
+ </section>
+ </manifest>
+ </jar>
+ <unjar src="mftestOrder1.jar" dest="manifests">
+ <include name="META-INF/MANIFEST.MF"/>
+ </unjar>
+ </target>
+
+ <target name="testOrder2">
+ <jar file="mftestOrder2.jar">
+ <manifest>
+ <section name="Test2">
+ <attribute name="TestAttrx" value="Testx"/>
+ </section>
+ <section name="Test1">
+ <attribute name="TestAttr2" value="Test2"/>
+ <attribute name="TestAttr1" value="Test1"/>
+ </section>
+ </manifest>
+ </jar>
+ <unjar src="mftestOrder2.jar" dest="manifests">
+ <include name="META-INF/MANIFEST.MF"/>
+ </unjar>
+ </target>
+
+
+
<target name="testReplace">
<copy file="manifests/test2.mf" toFile="mftest.mf" />
<manifest file="mftest.mf" />
1.25 +354 -163
jakarta-ant/src/main/org/apache/tools/ant/taskdefs/Manifest.java
Index: Manifest.java
===================================================================
RCS file:
/home/cvs/jakarta-ant/src/main/org/apache/tools/ant/taskdefs/Manifest.java,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -w -u -r1.24 -r1.25
--- Manifest.java 20 Mar 2002 00:06:18 -0000 1.24
+++ Manifest.java 20 Mar 2002 12:11:57 -0000 1.25
@@ -83,30 +83,37 @@
*/
public class Manifest extends Task {
/** The standard manifest version header */
- public final static String ATTRIBUTE_MANIFEST_VERSION =
"Manifest-Version";
+ public static final String ATTRIBUTE_MANIFEST_VERSION
+ = "Manifest-Version";
/** The standard Signature Version header */
- public final static String ATTRIBUTE_SIGNATURE_VERSION =
"Signature-Version";
+ public static final String ATTRIBUTE_SIGNATURE_VERSION
+ = "Signature-Version";
/** The Name Attribute is the first in a named section */
- public final static String ATTRIBUTE_NAME = "Name";
+ public static final String ATTRIBUTE_NAME = "Name";
/** The From Header is disallowed in a Manifest */
- public final static String ATTRIBUTE_FROM = "From";
+ public static final String ATTRIBUTE_FROM = "From";
/** The Class-Path Header is special - it can be duplicated */
- public final static String ATTRIBUTE_CLASSPATH = "class-path";
+ public static final String ATTRIBUTE_CLASSPATH = "class-path";
/** Default Manifest version if one is not specified */
- public final static String DEFAULT_MANIFEST_VERSION = "1.0";
+ public static final String DEFAULT_MANIFEST_VERSION = "1.0";
/** The max length of a line in a Manifest */
- public final static int MAX_LINE_LENGTH = 72;
+ public static final int MAX_LINE_LENGTH = 72;
/**
* Helper class for Manifest's mode attribute.
*/
public static class Mode extends EnumeratedAttribute {
+ /**
+ * Get Allowed values for the mode attribute.
+ *
+ * @return a String array of the allowed values.
+ */
public String[] getValues() {
return new String[] {"update", "replace"};
}
@@ -120,7 +127,13 @@
private String name = null;
/** The attribute's value */
- private String value = null;
+ private Vector values = new Vector();
+
+ /**
+ * For multivalued attributes, this is the index of the attribute
+ * currently being defined.
+ */
+ private int currentIndex = 0;
/**
* Construct an empty attribute */
@@ -146,9 +159,12 @@
*/
public Attribute(String name, String value) {
this.name = name;
- this.value = value;
+ setValue(value);
}
+ /**
+ * @see java.lang.Object#equals
+ */
public boolean equals(Object rhs) {
if (!(rhs instanceof Attribute)) {
return false;
@@ -156,8 +172,8 @@
Attribute rhsAttribute = (Attribute)rhs;
return (name != null && rhsAttribute.name != null &&
-
name.toLowerCase().equals(rhsAttribute.name.toLowerCase()) &&
- value != null && value.equals(rhsAttribute.value));
+ getKey().equals(rhsAttribute.getKey()) &&
+ values != null && values.equals(rhsAttribute.values));
}
/**
@@ -171,11 +187,12 @@
public void parse(String line) throws ManifestException {
int index = line.indexOf(": ");
if (index == -1) {
- throw new ManifestException("Manifest line \"" + line + "\"
is not valid as it does not " +
- "contain a name and a value
separated by ': ' ");
+ throw new ManifestException("Manifest line \"" + line
+ + "\" is not valid as it does not "
+ + "contain a name and a value separated by ': ' ");
}
name = line.substring(0, index);
- value = line.substring(index + 2);
+ setValue(line.substring(index + 2));
}
/**
@@ -197,12 +214,29 @@
}
/**
+ * Get the attribute's Key - its name in lower case.
+ *
+ * @return the attribute's key.
+ */
+ public String getKey() {
+ if (name == null) {
+ return null;
+ }
+ return name.toLowerCase();
+ }
+
+ /**
* Set the Attribute's value
*
* @param value the attribute's value
*/
public void setValue(String value) {
- this.value = value;
+ if (currentIndex >= values.size()) {
+ values.addElement(value);
+ currentIndex = values.size() - 1;
+ } else {
+ values.setElementAt(value, currentIndex);
+ }
}
/**
@@ -211,7 +245,35 @@
* @return the attribute's value.
*/
public String getValue() {
- return value;
+ if (values.size() == 0) {
+ return null;
+ }
+
+ String fullValue = "";
+ for (Enumeration e = getValues(); e.hasMoreElements();) {
+ String value = (String)e.nextElement();
+ fullValue += value + " ";
+ }
+ return fullValue.trim();
+ }
+
+ /**
+ * Add a new value to this attribute - making it multivalued
+ *
+ * @param value the attribute's additional value
+ */
+ public void addValue(String value) {
+ currentIndex++;
+ setValue(value);
+ }
+
+ /**
+ * Get all the attribute's values
+ *
+ * @return an enumeration of the attributes values
+ */
+ public Enumeration getValues() {
+ return values.elements();
}
/**
@@ -220,9 +282,12 @@
* When lines are too long in a manifest, they are continued on the
* next line by starting with a space. This method adds the
continuation
* data to the attribute value by skipping the first character.
+ *
+ * @param line the continuation line.
*/
public void addContinuation(String line) {
- value += line.substring(1);
+ String currentValue = (String)values.elementAt(currentIndex);
+ setValue(currentValue + line.substring(1));
}
/**
@@ -233,17 +298,34 @@
* @throws IOException if the attribte value cannot be written
*/
public void write(PrintWriter writer) throws IOException {
+ for (Enumeration e = getValues(); e.hasMoreElements();) {
+ writeValue(writer, (String)e.nextElement());
+ }
+ }
+
+ /**
+ * Write a single attribute value out
+ *
+ * @param writer the Writer to which the attribute is written
+ * @param value the attribute value
+ *
+ * @throws IOException if the attribte value cannot be written
+ */
+ private void writeValue(PrintWriter writer, String value)
+ throws IOException {
String line = name + ": " + value;
while (line.getBytes().length > MAX_LINE_LENGTH) {
// try to find a MAX_LINE_LENGTH byte section
int breakIndex = MAX_LINE_LENGTH;
String section = line.substring(0, breakIndex);
- while (section.getBytes().length > MAX_LINE_LENGTH &&
breakIndex > 0) {
+ while (section.getBytes().length > MAX_LINE_LENGTH
+ && breakIndex > 0) {
breakIndex--;
section = line.substring(0, breakIndex);
}
if (breakIndex == 0) {
- throw new IOException("Unable to write manifest line " +
name + ": " + value);
+ throw new IOException("Unable to write manifest line "
+ + name + ": " + value);
}
writer.println(section);
line = " " + line.substring(breakIndex);
@@ -258,14 +340,21 @@
* separated from other sections by a blank line.
*/
public static class Section {
+ /** Warnings for this section */
private Vector warnings = new Vector();
- /** The section's name if any. The main section in a manifest is
unnamed.*/
+ /**
+ * The section's name if any. The main section in a
+ * manifest is unnamed.
+ */
private String name = null;
/** The section's attributes.*/
private Hashtable attributes = new Hashtable();
+ /** Index used to retain the attribute ordering */
+ private Vector attributeIndex = new Vector();
+
/**
* Set the Section's name
*
@@ -289,13 +378,16 @@
*
* @param reader the reader from which the section is read
*
- * @return the name of the next section if it has been read as part
of this
- * section - This only happens if the Manifest is malformed.
+ * @return the name of the next section if it has been read as
+ * part of this section - This only happens if the
+ * Manifest is malformed.
*
- * @throws ManifestException if the section is not valid according
to the JAR spec
+ * @throws ManifestException if the section is not valid according
+ * to the JAR spec
* @throws IOException if the section cannot be read from the reader.
*/
- public String read(BufferedReader reader) throws ManifestException,
IOException {
+ public String read(BufferedReader reader)
+ throws ManifestException, IOException {
Attribute attribute = null;
while (true) {
String line = reader.readLine();
@@ -306,19 +398,18 @@
// continuation line
if (attribute == null) {
if (name != null) {
- // a continuation on the first line is a
continuation of the name - concatenate
- // this line and the name
+ // a continuation on the first line is a
+ // continuation of the name - concatenate this
+ // line and the name
name += line.substring(1);
+ } else {
+ throw new ManifestException("Can't start an "
+ + "attribute with a continuation line " +
line);
}
- else {
- throw new ManifestException("Can't start an
attribute with a continuation line " + line);
- }
- }
- else {
+ } else {
attribute.addContinuation(line);
}
- }
- else {
+ } else {
attribute = new Attribute(line);
String nameReadAhead = addAttributeAndCheck(attribute);
if (nameReadAhead != null) {
@@ -336,31 +427,35 @@
* @throws ManifestException if the sections cannot be merged.
*/
public void merge(Section section) throws ManifestException {
- if (name == null && section.getName() != null ||
- name != null &&
!(name.equalsIgnoreCase(section.getName()))) {
- throw new ManifestException("Unable to merge sections with
different names");
+ if (name == null && section.getName() != null
+ || name != null
+ && !(name.equalsIgnoreCase(section.getName()))) {
+ throw new ManifestException("Unable to merge sections "
+ + "with different names");
}
- for (Enumeration e = section.attributes.keys();
e.hasMoreElements();) {
+ Enumeration e = section.getAttributeKeys();
+ while (e.hasMoreElements()) {
String attributeName = (String)e.nextElement();
+ Attribute attribute = section.getAttribute(attributeName);
if (attributeName.equals(ATTRIBUTE_CLASSPATH) &&
attributes.containsKey(attributeName)) {
- // classpath entries are vetors which are merged
- Vector classpathAttrs =
(Vector)section.attributes.get(attributeName);
- Vector ourClasspathAttrs =
(Vector)attributes.get(attributeName);
- for (Enumeration e2 = classpathAttrs.elements();
e2.hasMoreElements();) {
- ourClasspathAttrs.addElement(e2.nextElement());
+ Attribute ourClassPath = getAttribute(attributeName);
+ Enumeration cpe = attribute.getValues();
+ while (cpe.hasMoreElements()) {
+ String value = (String)cpe.nextElement();
+ ourClassPath.addValue(value);
}
- }
- else {
+ } else {
// the merge file always wins
- attributes.put(attributeName,
section.attributes.get(attributeName));
+ storeAttribute(attribute);
}
}
// add in the warnings
- for (Enumeration e = section.warnings.elements();
e.hasMoreElements();) {
- warnings.addElement(e.nextElement());
+ Enumeration warnEnum = section.warnings.elements();
+ while (warnEnum.hasMoreElements()) {
+ warnings.addElement(warnEnum.nextElement());
}
}
@@ -376,20 +471,12 @@
Attribute nameAttr = new Attribute(ATTRIBUTE_NAME, name);
nameAttr.write(writer);
}
- for (Enumeration e = attributes.elements();
e.hasMoreElements();) {
- Object object = e.nextElement();
- if (object instanceof Attribute) {
- Attribute attribute = (Attribute)object;
- attribute.write(writer);
- }
- else {
- Vector attrList = (Vector)object;
- for (Enumeration e2 = attrList.elements();
e2.hasMoreElements();) {
- Attribute attribute = (Attribute)e2.nextElement();
+ Enumeration e = getAttributeKeys();
+ while (e.hasMoreElements()) {
+ String key = (String)e.nextElement();
+ Attribute attribute = getAttribute(key);
attribute.write(writer);
}
- }
- }
writer.println();
}
@@ -401,8 +488,18 @@
* single-valued, otherwise a Vector of Manifest.Attribute
* instances.
*/
- public Object getAttribute(String attributeName) {
- return attributes.get(attributeName.toLowerCase());
+ public Attribute getAttribute(String attributeName) {
+ return (Attribute)attributes.get(attributeName.toLowerCase());
+ }
+
+ /**
+ * Get the attribute keys.
+ *
+ * @return an Enumeration of Strings, each string being the lower
case
+ * key of an attribute of the section.
+ */
+ public Enumeration getAttributeKeys() {
+ return attributeIndex.elements();
}
/**
@@ -414,21 +511,11 @@
* in the section
*/
public String getAttributeValue(String attributeName) {
- Object attribute = attributes.get(attributeName.toLowerCase());
+ Attribute attribute = getAttribute(attributeName.toLowerCase());
if (attribute == null) {
return null;
}
- if (attribute instanceof Attribute) {
- return ((Attribute)attribute).getValue();
- }
- else {
- String value = "";
- for (Enumeration e = ((Vector)attribute).elements();
e.hasMoreElements();) {
- Attribute classpathAttribute =
(Attribute)e.nextElement();
- value += classpathAttribute.getValue() + " ";
- }
- return value.trim();
- }
+ return attribute.getValue();
}
/**
@@ -437,14 +524,25 @@
* @param attributeName the name of the attribute to be removed.
*/
public void removeAttribute(String attributeName) {
- attributes.remove(attributeName.toLowerCase());
+ String key = attributeName.toLowerCase();
+ attributes.remove(key);
+ attributeIndex.removeElement(key);
}
- public void addConfiguredAttribute(Attribute attribute) throws
ManifestException {
+ /**
+ * Add an attribute to the section.
+ *
+ * @param attribute the attribute to be added to the section
+ *
+ * @exception ManifestException if the attribute is not valid.
+ */
+ public void addConfiguredAttribute(Attribute attribute)
+ throws ManifestException {
String check = addAttributeAndCheck(attribute);
if (check != null) {
- throw new BuildException("Specify the section name using the
\"name\" attribute of the <section> element rather " +
- "than using a \"Name\" manifest
attribute");
+ throw new BuildException("Specify the section name using "
+ + "the \"name\" attribute of the <section> element
rather "
+ + "than using a \"Name\" manifest attribute");
}
}
@@ -453,51 +551,84 @@
*
* @param attribute the attribute to be added.
*
- * @return the value of the attribute if it is a name attribute -
null other wise
+ * @return the value of the attribute if it is a name
+ * attribute - null other wise
*
- * @throws ManifestException if the attribute already exists in this
section.
+ * @exception ManifestException if the attribute already
+ * exists in this section.
*/
- public String addAttributeAndCheck(Attribute attribute) throws
ManifestException {
+ public String addAttributeAndCheck(Attribute attribute)
+ throws ManifestException {
if (attribute.getName() == null || attribute.getValue() == null)
{
throw new BuildException("Attributes must have name and
value");
}
- if (attribute.getName().equalsIgnoreCase(ATTRIBUTE_NAME)) {
- warnings.addElement("\"" + ATTRIBUTE_NAME + "\" attributes
should not occur in the " +
- "main section and must be the first
element in all " +
- "other sections: \""
+attribute.getName() + ": " + attribute.getValue() + "\"");
+ if (attribute.getKey().equalsIgnoreCase(ATTRIBUTE_NAME)) {
+ warnings.addElement("\"" + ATTRIBUTE_NAME + "\" attributes "
+ + "should not occur in the main section and must be the "
+ + "first element in all other sections: \""
+ + attribute.getName() + ": " + attribute.getValue() +
"\"");
return attribute.getValue();
}
- if
(attribute.getName().toLowerCase().startsWith(ATTRIBUTE_FROM.toLowerCase())) {
- warnings.addElement("Manifest attributes should not start
with \"" +
- ATTRIBUTE_FROM + "\" in \""
+attribute.getName() + ": " + attribute.getValue() + "\"");
- }
- else {
+ if (attribute.getKey().startsWith(ATTRIBUTE_FROM.toLowerCase()))
{
+ warnings.addElement("Manifest attributes should not start "
+ + "with \"" + ATTRIBUTE_FROM + "\" in \""
+ + attribute.getName() + ": " + attribute.getValue() +
"\"");
+ } else {
// classpath attributes go into a vector
- String attributeName = attribute.getName().toLowerCase();
- if (attributeName.equals(ATTRIBUTE_CLASSPATH)) {
- Vector classpathAttrs =
(Vector)attributes.get(attributeName);
- if (classpathAttrs == null) {
- classpathAttrs = new Vector();
- attributes.put(attributeName, classpathAttrs);
- }
- classpathAttrs.addElement(attribute);
- }
- else if (attributes.containsKey(attributeName)) {
- throw new ManifestException("The attribute \"" +
attribute.getName() + "\" may not " +
- "occur more than once in the
same section");
- }
- else {
- attributes.put(attributeName, attribute);
+ String attributeKey = attribute.getKey();
+ if (attributeKey.equals(ATTRIBUTE_CLASSPATH)) {
+ Attribute classpathAttribute =
+ (Attribute)attributes.get(attributeKey);
+
+ if (classpathAttribute == null) {
+ storeAttribute(attribute);
+ } else {
+ Enumeration e = attribute.getValues();
+ while (e.hasMoreElements()) {
+ String value = (String)e.nextElement();
+ classpathAttribute.addValue(value);
+ }
+ }
+ } else if (attributes.containsKey(attributeKey)) {
+ throw new ManifestException("The attribute \""
+ + attribute.getName() + "\" may not occur more "
+ + "than once in the same section");
+ } else {
+ storeAttribute(attribute);
}
}
return null;
}
+ /**
+ * Store an attribute and update the index.
+ *
+ * @param attribute the attribute to be stored
+ */
+ private void storeAttribute(Attribute attribute) {
+ if (attribute == null) {
+ return;
+ }
+ String attributeKey = attribute.getKey();
+ attributes.put(attributeKey, attribute);
+ if (!attributeIndex.contains(attributeKey)) {
+ attributeIndex.addElement(attributeKey);
+ }
+ }
+
+ /**
+ * Get the warnings for this section.
+ *
+ * @return an Enumeration of warning strings.
+ */
public Enumeration getWarnings() {
return warnings.elements();
}
+ /**
+ * @see java.lang.Object#equals
+ */
public boolean equals(Object rhs) {
if (!(rhs instanceof Section)) {
return false;
@@ -511,7 +642,8 @@
for (Enumeration e = attributes.keys(); e.hasMoreElements();) {
String attributeName = (String)e.nextElement();
Object attributeValue = attributes.get(attributeName);
- Object rshAttributeValue =
rhsSection.attributes.get(attributeName);
+ Object rshAttributeValue
+ = rhsSection.attributes.get(attributeName);
if (!attributeValue.equals(rshAttributeValue)) {
return false;
}
@@ -531,26 +663,43 @@
/** The named sections of this manifest */
private Hashtable sections = new Hashtable();
+ /** Index of sections - used to retain order of sections in manifest */
+ private Vector sectionIndex = new Vector();
+
+ /**
+ * The file to which the manifest should be written when used as a task
+ */
+ private File manifestFile;
+
+ /**
+ * The mode with which the manifest file is written
+ */
+ private Mode mode;
+
/**
* Construct a manifest from Ant's default manifest file.
+ *
+ *
+ * @return the default manifest.
+ * @exception BuildException if there is a problem loading the
+ * default manifest
*/
public static Manifest getDefaultManifest() throws BuildException {
try {
- String s = "/org/apache/tools/ant/defaultManifest.mf";
- InputStream in = Manifest.class.getResourceAsStream(s);
+ String defManifest = "/org/apache/tools/ant/defaultManifest.mf";
+ InputStream in = Manifest.class.getResourceAsStream(defManifest);
if (in == null) {
- throw new BuildException("Could not find default manifest: "
+ s);
+ throw new BuildException("Could not find default manifest: "
+ + defManifest);
}
try {
return new Manifest(new InputStreamReader(in, "ASCII"));
} catch (UnsupportedEncodingException e) {
return new Manifest(new InputStreamReader(in));
}
- }
- catch (ManifestException e) {
+ } catch (ManifestException e) {
throw new BuildException("Default manifest is invalid !!", e);
- }
- catch (IOException e) {
+ } catch (IOException e) {
throw new BuildException("Unable to read default manifest", e);
}
}
@@ -565,16 +714,18 @@
/**
* Read a manifest file from the given reader
*
- * @param is the reader from which the Manifest is read
+ * @param r is the reader from which the Manifest is read
*
- * @throws ManifestException if the manifest is not valid according to
the JAR spec
+ * @throws ManifestException if the manifest is not valid according
+ * to the JAR spec
* @throws IOException if the manifest cannot be read from the reader.
*/
public Manifest(Reader r) throws ManifestException, IOException {
BufferedReader reader = new BufferedReader(r);
// This should be the manifest version
String nextSectionName = mainSection.read(reader);
- String readManifestVersion =
mainSection.getAttributeValue(ATTRIBUTE_MANIFEST_VERSION);
+ String readManifestVersion
+ = mainSection.getAttributeValue(ATTRIBUTE_MANIFEST_VERSION);
if (readManifestVersion != null) {
manifestVersion = readManifestVersion;
mainSection.removeAttribute(ATTRIBUTE_MANIFEST_VERSION);
@@ -590,15 +741,16 @@
if (nextSectionName == null) {
Attribute sectionName = new Attribute(line);
if (!sectionName.getName().equalsIgnoreCase(ATTRIBUTE_NAME))
{
- throw new ManifestException("Manifest sections should
start with a \"" + ATTRIBUTE_NAME +
- "\" attribute and not \"" +
sectionName.getName() + "\"");
+ throw new ManifestException("Manifest sections should "
+ + "start with a \"" + ATTRIBUTE_NAME
+ + "\" attribute and not \""
+ + sectionName.getName() + "\"");
}
nextSectionName = sectionName.getValue();
- }
- else {
+ } else {
// we have already started reading this section
- // this line is the first attribute. set it and then let the
normal
- // read handle the rest
+ // this line is the first attribute. set it and then
+ // let the normal read handle the rest
Attribute firstAttribute = new Attribute(line);
section.addAttributeAndCheck(firstAttribute);
}
@@ -609,14 +761,34 @@
}
}
- public void addConfiguredSection(Section section) throws
ManifestException {
- if (section.getName() == null) {
+ /**
+ * Add a section to the manifest
+ *
+ * @param section the manifest section to be added
+ *
+ * @exception ManifestException if the secti0on is not valid.
+ */
+ public void addConfiguredSection(Section section)
+ throws ManifestException {
+ String sectionName = section.getName();
+ if (sectionName == null) {
throw new BuildException("Sections must have a name");
}
- sections.put(section.getName(), section);
+ sections.put(sectionName, section);
+ if (!sectionIndex.contains(sectionName)) {
+ sectionIndex.addElement(sectionName);
+ }
}
- public void addConfiguredAttribute(Attribute attribute) throws
ManifestException {
+ /**
+ * Add an attribute to the manifest - it is added to the main section.
+ *
+ * @param attribute the attribute to be added.
+ *
+ * @exception ManifestException if the attribute is not valid.
+ */
+ public void addConfiguredAttribute(Attribute attribute)
+ throws ManifestException {
mainSection.addConfiguredAttribute(attribute);
}
@@ -625,8 +797,8 @@
*
* @param other the Manifest to be merged with this one.
*
- * @throws ManifestException if there is a problem merging the manfest
according
- * to the Manifest spec.
+ * @throws ManifestException if there is a problem merging the
+ * manfest according to the Manifest spec.
*/
public void merge(Manifest other) throws ManifestException {
merge(other, false);
@@ -636,17 +808,18 @@
* 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 overwriteMain whether to overwrite the main section
+ * of the current manifest
*
- * @throws ManifestException if there is a problem merging the manfest
according
- * to the Manifest spec.
+ * @throws ManifestException if there is a problem merging the
+ * manfest according to the Manifest spec.
*/
- public void merge(Manifest other, boolean overwriteMain) throws
ManifestException {
+ public void merge(Manifest other, boolean overwriteMain)
+ throws ManifestException {
if (other != null) {
if (overwriteMain) {
mainSection = other.mainSection;
- }
- else {
+ } else {
mainSection.merge(other.mainSection);
}
@@ -654,16 +827,17 @@
manifestVersion = other.manifestVersion;
}
- for (Enumeration e = other.sections.keys();
e.hasMoreElements();) {
+ Enumeration e = other.getSectionNames();
+ while (e.hasMoreElements()) {
String sectionName = (String)e.nextElement();
Section ourSection = (Section)sections.get(sectionName);
- Section otherSection =
(Section)other.sections.get(sectionName);
+ Section otherSection
+ = (Section)other.sections.get(sectionName);
if (ourSection == null) {
if (otherSection != null) {
- sections.put(sectionName.toLowerCase(),
otherSection);
- }
+ addConfiguredSection(otherSection);
}
- else {
+ } else {
ourSection.merge(otherSection);
}
}
@@ -679,23 +853,30 @@
*/
public void write(PrintWriter writer) throws IOException {
writer.println(ATTRIBUTE_MANIFEST_VERSION + ": " + manifestVersion);
- String signatureVersion =
mainSection.getAttributeValue(ATTRIBUTE_SIGNATURE_VERSION);
+ String signatureVersion
+ = mainSection.getAttributeValue(ATTRIBUTE_SIGNATURE_VERSION);
if (signatureVersion != null) {
- writer.println(ATTRIBUTE_SIGNATURE_VERSION + ": " +
signatureVersion);
+ writer.println(ATTRIBUTE_SIGNATURE_VERSION + ": "
+ + signatureVersion);
mainSection.removeAttribute(ATTRIBUTE_SIGNATURE_VERSION);
}
mainSection.write(writer);
+
+ // add it back
if (signatureVersion != null) {
try {
- mainSection.addConfiguredAttribute(new
Attribute(ATTRIBUTE_SIGNATURE_VERSION, signatureVersion));
- }
- catch (ManifestException e) {
+ Attribute svAttr = new
Attribute(ATTRIBUTE_SIGNATURE_VERSION,
+ signatureVersion);
+ mainSection.addConfiguredAttribute(svAttr);
+ } catch (ManifestException e) {
// shouldn't happen - ignore
}
}
- for (Enumeration e = sections.elements(); e.hasMoreElements();) {
- Section section = (Section)e.nextElement();
+ Enumeration e = sectionIndex.elements();
+ while (e.hasMoreElements()) {
+ String sectionName = (String)e.nextElement();
+ Section section = getSection(sectionName);
section.write(writer);
}
}
@@ -703,14 +884,14 @@
/**
* Convert the manifest to its string representation
*
- * @return a multiline string with the Manifest as it appears in a
Manifest file.
+ * @return a multiline string with the Manifest as it
+ * appears in a Manifest file.
*/
public String toString() {
StringWriter sw = new StringWriter();
try {
write(new PrintWriter(sw));
- }
- catch (IOException e) {
+ } catch (IOException e) {
return null;
}
return sw.toString();
@@ -724,14 +905,17 @@
public Enumeration getWarnings() {
Vector warnings = new Vector();
- for (Enumeration e2 = mainSection.getWarnings();
e2.hasMoreElements();) {
- warnings.addElement(e2.nextElement());
+ Enumeration warnEnum = mainSection.getWarnings();
+ while (warnEnum.hasMoreElements()) {
+ warnings.addElement(warnEnum.nextElement());
}
// create a vector and add in the warnings for all the sections
- for (Enumeration e = sections.elements(); e.hasMoreElements();) {
+ Enumeration e = sections.elements();
+ while (e.hasMoreElements()) {
Section section = (Section)e.nextElement();
- for (Enumeration e2 = section.getWarnings();
e2.hasMoreElements();) {
+ Enumeration e2 = section.getWarnings();
+ while (e2.hasMoreElements()) {
warnings.addElement(e2.nextElement());
}
}
@@ -739,6 +923,9 @@
return warnings.elements();
}
+ /**
+ * @see java.lang.Object#equals
+ */
public boolean equals(Object rhs) {
if (!(rhs instanceof Manifest)) {
return false;
@@ -760,9 +947,11 @@
return false;
}
- for (Enumeration e = sections.elements(); e.hasMoreElements();) {
+ Enumeration e = sections.elements();
+ while (e.hasMoreElements()) {
Section section = (Section)e.nextElement();
- Section rhsSection =
(Section)rhsManifest.sections.get(section.getName());
+ Section rhsSection
+ = (Section)rhsManifest.sections.get(section.getName());
if (!section.equals(rhsSection)) {
return false;
}
@@ -771,19 +960,19 @@
return true;
}
- private File manifestFile;
-
/**
* The name of the manifest file to write (if used as a task).
+ *
+ * @param f the Manifest file to be written
*/
public void setFile(File f) {
manifestFile = f;
}
- private Mode mode;
-
/**
* Shall we update or replace an existing manifest?
+ *
+ * @param m the mode value - update or replace.
*/
public void setMode(Mode m) {
mode = m;
@@ -824,11 +1013,13 @@
* @return an Enumeration of section names
*/
public Enumeration getSectionNames() {
- return sections.keys();
+ return sectionIndex.elements();
}
/**
* Create or update the Manifest when used as a task.
+ *
+ * @throws BuildException if the manifst cannot be written.
*/
public void execute() throws BuildException {
if (manifestFile == null) {
1.7 +47 -2
jakarta-ant/src/testcases/org/apache/tools/ant/taskdefs/ManifestTest.java
Index: ManifestTest.java
===================================================================
RCS file:
/home/cvs/jakarta-ant/src/testcases/org/apache/tools/ant/taskdefs/ManifestTest.java,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -w -u -r1.6 -r1.7
--- ManifestTest.java 18 Mar 2002 02:44:30 -0000 1.6
+++ ManifestTest.java 20 Mar 2002 12:11:57 -0000 1.7
@@ -59,6 +59,7 @@
import java.io.IOException;
import java.util.Date;
import java.util.Vector;
+import java.util.Enumeration;
import org.apache.tools.ant.BuildFileTest;
import org.apache.tools.ant.Project;
@@ -222,8 +223,6 @@
String classpath = mainSection.getAttributeValue("class-path");
assertEquals("Class-Path attribute was not set correctly - ",
"Test1 Test2 Test3 Test4", classpath);
- Object classPathAttr = mainSection.getAttribute("class-PATH");
- assertTrue("Class path attribute should be a Vector", classPathAttr
instanceof Vector);
}
/**
@@ -239,6 +238,52 @@
String classpath = mainSection.getAttributeValue("class-path");
assertEquals("Class-Path attribute was not set correctly - ",
LONG_LINE, classpath);
+ }
+
+ /**
+ * Tests ordering of sections
+ */
+ public void testOrder1() throws IOException, ManifestException {
+ executeTarget("testOrder1");
+
+ Manifest manifest = getManifest(EXPANDED_MANIFEST);
+ Enumeration e = manifest.getSectionNames();
+ String section1 = (String)e.nextElement();
+ String section2 = (String)e.nextElement();
+ assertEquals("First section name unexpected", "Test1", section1);
+ assertEquals("Second section name unexpected", "Test2", section2);
+
+ Manifest.Section section = manifest.getSection("Test1");
+ e = section.getAttributeKeys();
+ String attr1Key = (String)e.nextElement();
+ String attr2Key = (String)e.nextElement();
+ String attr1 = section.getAttribute(attr1Key).getName();
+ String attr2 = section.getAttribute(attr2Key).getName();
+ assertEquals("First attribute name unexpected", "TestAttr1", attr1);
+ assertEquals("Second attribute name unexpected", "TestAttr2", attr2);
+ }
+
+ /**
+ * Tests ordering of sections
+ */
+ public void testOrder2() throws IOException, ManifestException {
+ executeTarget("testOrder2");
+
+ Manifest manifest = getManifest(EXPANDED_MANIFEST);
+ Enumeration e = manifest.getSectionNames();
+ String section1 = (String)e.nextElement();
+ String section2 = (String)e.nextElement();
+ assertEquals("First section name unexpected", "Test2", section1);
+ assertEquals("Second section name unexpected", "Test1", section2);
+
+ Manifest.Section section = manifest.getSection("Test1");
+ e = section.getAttributeKeys();
+ String attr1Key = (String)e.nextElement();
+ String attr2Key = (String)e.nextElement();
+ String attr1 = section.getAttribute(attr1Key).getName();
+ String attr2 = section.getAttribute(attr2Key).getName();
+ assertEquals("First attribute name unexpected", "TestAttr2", attr1);
+ assertEquals("Second attribute name unexpected", "TestAttr1", attr2);
}
/**
--
To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>