diff --git a/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/archive/Jar.java b/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/archive/Jar.java
index 2ea0f8ce4..14cde3ac2 100644
--- a/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/archive/Jar.java
+++ b/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/archive/Jar.java
@@ -22,8 +22,8 @@ import java.util.zip.ZipFile;
import org.apache.aut.zip.ZipOutputStream;
import org.apache.myrmidon.api.TaskException;
import org.apache.tools.ant.taskdefs.manifest.Manifest;
-import org.apache.aut.manifest.ManifestException;
-import org.apache.aut.manifest.ManifestUtil;
+import org.apache.tools.ant.taskdefs.manifest.ManifestException;
+import org.apache.tools.ant.taskdefs.manifest.ManifestUtil;
import org.apache.tools.ant.types.FileScanner;
/**
diff --git a/proposal/myrmidon/src/java/org/apache/aut/manifest/Attribute.java b/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/manifest/Attribute.java
similarity index 98%
rename from proposal/myrmidon/src/java/org/apache/aut/manifest/Attribute.java
rename to proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/manifest/Attribute.java
index 117de0bf8..a891f62ae 100644
--- a/proposal/myrmidon/src/java/org/apache/aut/manifest/Attribute.java
+++ b/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/manifest/Attribute.java
@@ -5,7 +5,7 @@
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
-package org.apache.aut.manifest;
+package org.apache.tools.ant.taskdefs.manifest;
/**
* Class to hold manifest attributes
diff --git a/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/manifest/Manifest.java b/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/manifest/Manifest.java
index c7839802d..39fc5a113 100644
--- a/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/manifest/Manifest.java
+++ b/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/manifest/Manifest.java
@@ -13,9 +13,6 @@ import java.util.Hashtable;
import java.util.Iterator;
import java.util.Set;
import org.apache.myrmidon.api.TaskException;
-import org.apache.aut.manifest.Attribute;
-import org.apache.aut.manifest.ManifestException;
-import org.apache.aut.manifest.ManifestUtil;
/**
* Class to manage Manifest information
diff --git a/proposal/myrmidon/src/java/org/apache/aut/manifest/ManifestException.java b/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/manifest/ManifestException.java
similarity index 96%
rename from proposal/myrmidon/src/java/org/apache/aut/manifest/ManifestException.java
rename to proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/manifest/ManifestException.java
index bdd515d6d..fc5a9f0f4 100644
--- a/proposal/myrmidon/src/java/org/apache/aut/manifest/ManifestException.java
+++ b/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/manifest/ManifestException.java
@@ -5,7 +5,7 @@
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
-package org.apache.aut.manifest;
+package org.apache.tools.ant.taskdefs.manifest;
/**
* ManifestException is thrown when there is a problem parsing, generating or
diff --git a/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/manifest/ManifestTask.java b/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/manifest/ManifestTask.java
index 1463d664d..400fd87dd 100644
--- a/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/manifest/ManifestTask.java
+++ b/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/manifest/ManifestTask.java
@@ -17,9 +17,6 @@ import java.util.Iterator;
import org.apache.avalon.excalibur.io.IOUtil;
import org.apache.myrmidon.api.AbstractTask;
import org.apache.myrmidon.api.TaskException;
-import org.apache.aut.manifest.Attribute;
-import org.apache.aut.manifest.ManifestException;
-import org.apache.aut.manifest.ManifestUtil;
/**
* Class to manage Manifest information
diff --git a/proposal/myrmidon/src/java/org/apache/aut/manifest/ManifestUtil.java b/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/manifest/ManifestUtil.java
similarity index 98%
rename from proposal/myrmidon/src/java/org/apache/aut/manifest/ManifestUtil.java
rename to proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/manifest/ManifestUtil.java
index 78cc34f50..eb22f9993 100644
--- a/proposal/myrmidon/src/java/org/apache/aut/manifest/ManifestUtil.java
+++ b/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/manifest/ManifestUtil.java
@@ -5,7 +5,7 @@
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
-package org.apache.aut.manifest;
+package org.apache.tools.ant.taskdefs.manifest;
import java.io.BufferedReader;
import java.io.IOException;
@@ -15,8 +15,6 @@ import java.io.PrintWriter;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.util.jar.Attributes;
-import org.apache.tools.ant.taskdefs.manifest.Manifest;
-import org.apache.tools.ant.taskdefs.manifest.Section;
/**
* Utility methods for manifest stuff.
diff --git a/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/manifest/Section.java b/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/manifest/Section.java
index cfd577e0b..2213a6b71 100644
--- a/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/manifest/Section.java
+++ b/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/manifest/Section.java
@@ -14,9 +14,6 @@ import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;
-import org.apache.aut.manifest.Attribute;
-import org.apache.aut.manifest.ManifestException;
-import org.apache.aut.manifest.ManifestUtil;
/**
* Class to represent an individual section in the Manifest. A section
diff --git a/proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/archive/Jar.java b/proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/archive/Jar.java
index 2ea0f8ce4..14cde3ac2 100644
--- a/proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/archive/Jar.java
+++ b/proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/archive/Jar.java
@@ -22,8 +22,8 @@ import java.util.zip.ZipFile;
import org.apache.aut.zip.ZipOutputStream;
import org.apache.myrmidon.api.TaskException;
import org.apache.tools.ant.taskdefs.manifest.Manifest;
-import org.apache.aut.manifest.ManifestException;
-import org.apache.aut.manifest.ManifestUtil;
+import org.apache.tools.ant.taskdefs.manifest.ManifestException;
+import org.apache.tools.ant.taskdefs.manifest.ManifestUtil;
import org.apache.tools.ant.types.FileScanner;
/**
diff --git a/proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/manifest/Attribute.java b/proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/manifest/Attribute.java
new file mode 100644
index 000000000..a891f62ae
--- /dev/null
+++ b/proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/manifest/Attribute.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) The Apache Software Foundation. All rights reserved.
+ *
+ * This software is published under the terms of the Apache Software License
+ * version 1.1, a copy of which has been included with this distribution in
+ * the LICENSE.txt file.
+ */
+package org.apache.tools.ant.taskdefs.manifest;
+
+/**
+ * Class to hold manifest attributes
+ *
+ * @author Peter Donald
+ * @author Conor MacNeill
+ * @author Stefan Bodewig
+ * @version $Revision$ $Date$
+ */
+public class Attribute
+{
+ /**
+ * The attribute's name
+ */
+ private String m_name;
+
+ /**
+ * The attribute's value
+ */
+ private String m_value;
+
+ /**
+ * Construct an empty attribute
+ */
+ public Attribute()
+ {
+ }
+
+ /**
+ * Construct a manifest by specifying its name and value
+ *
+ * @param name the attribute's name
+ * @param value the Attribute's value
+ */
+ public Attribute( final String name, final String value )
+ {
+ m_name = name;
+ m_value = value;
+ }
+
+ /**
+ * Set the Attribute's name
+ *
+ * @param name the attribute's name
+ */
+ public void setName( final String name )
+ {
+ m_name = name;
+ }
+
+ /**
+ * Set the Attribute's value
+ *
+ * @param value the attribute's value
+ */
+ public void setValue( final String value )
+ {
+ m_value = value;
+ }
+
+ /**
+ * Get the Attribute's name
+ *
+ * @return the attribute's name.
+ */
+ public String getName()
+ {
+ return m_name;
+ }
+
+ /**
+ * Get the Attribute's value
+ *
+ * @return the attribute's value.
+ */
+ public String getValue()
+ {
+ return m_value;
+ }
+
+ /**
+ * Add a continuation line from the Manifest file 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 feature to be added to the Continuation attribute
+ */
+ public void addContinuation( final String line )
+ {
+ m_value += line.substring( 1 );
+ }
+
+ public boolean equals( Object object )
+ {
+ if( !( object instanceof Attribute ) )
+ {
+ return false;
+ }
+
+ final Attribute other = (Attribute)object;
+ final String name = other.m_name;
+ return
+ ( null != m_name && null != name &&
+ m_name.toLowerCase().equals( name.toLowerCase() ) &&
+ null != m_value && m_value.equals( other.m_value ) );
+ }
+
+}
diff --git a/proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/manifest/Manifest.java b/proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/manifest/Manifest.java
index c7839802d..39fc5a113 100644
--- a/proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/manifest/Manifest.java
+++ b/proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/manifest/Manifest.java
@@ -13,9 +13,6 @@ import java.util.Hashtable;
import java.util.Iterator;
import java.util.Set;
import org.apache.myrmidon.api.TaskException;
-import org.apache.aut.manifest.Attribute;
-import org.apache.aut.manifest.ManifestException;
-import org.apache.aut.manifest.ManifestUtil;
/**
* Class to manage Manifest information
diff --git a/proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/manifest/ManifestException.java b/proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/manifest/ManifestException.java
new file mode 100644
index 000000000..fc5a9f0f4
--- /dev/null
+++ b/proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/manifest/ManifestException.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) The Apache Software Foundation. All rights reserved.
+ *
+ * This software is published under the terms of the Apache Software License
+ * version 1.1, a copy of which has been included with this distribution in
+ * the LICENSE.txt file.
+ */
+package org.apache.tools.ant.taskdefs.manifest;
+
+/**
+ * ManifestException is thrown when there is a problem parsing, generating or
+ * handling a Manifest.
+ *
+ * @author Peter Donald
+ * @version $Revision$ $Date$
+ */
+public class ManifestException
+ extends Exception
+{
+ /**
+ * The Throwable that caused this exception to be thrown.
+ */
+ private final Throwable m_throwable;
+
+ /**
+ * Basic constructor for exception that does not specify a message
+ */
+ public ManifestException()
+ {
+ this( "", null );
+ }
+
+ /**
+ * Basic constructor with a message
+ *
+ * @param message the message
+ */
+ public ManifestException( final String message )
+ {
+ this( message, null );
+ }
+
+ /**
+ * Constructor that builds cascade so that other exception information can be retained.
+ *
+ * @param message the message
+ * @param throwable the throwable
+ */
+ public ManifestException( final String message, final Throwable throwable )
+ {
+ super( message );
+ m_throwable = throwable;
+ }
+
+ /**
+ * Retrieve root cause of the exception.
+ *
+ * @return the root cause
+ */
+ public final Throwable getCause()
+ {
+ return m_throwable;
+ }
+}
diff --git a/proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/manifest/ManifestTask.java b/proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/manifest/ManifestTask.java
index 1463d664d..400fd87dd 100644
--- a/proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/manifest/ManifestTask.java
+++ b/proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/manifest/ManifestTask.java
@@ -17,9 +17,6 @@ import java.util.Iterator;
import org.apache.avalon.excalibur.io.IOUtil;
import org.apache.myrmidon.api.AbstractTask;
import org.apache.myrmidon.api.TaskException;
-import org.apache.aut.manifest.Attribute;
-import org.apache.aut.manifest.ManifestException;
-import org.apache.aut.manifest.ManifestUtil;
/**
* Class to manage Manifest information
diff --git a/proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/manifest/ManifestUtil.java b/proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/manifest/ManifestUtil.java
new file mode 100644
index 000000000..eb22f9993
--- /dev/null
+++ b/proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/manifest/ManifestUtil.java
@@ -0,0 +1,239 @@
+/*
+ * Copyright (C) The Apache Software Foundation. All rights reserved.
+ *
+ * This software is published under the terms of the Apache Software License
+ * version 1.1, a copy of which has been included with this distribution in
+ * the LICENSE.txt file.
+ */
+package org.apache.tools.ant.taskdefs.manifest;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.io.Reader;
+import java.io.UnsupportedEncodingException;
+import java.util.jar.Attributes;
+
+/**
+ * Utility methods for manifest stuff.
+ *
+ * @author Conor MacNeill
+ * @author Stefan Bodewig
+ * @author Peter Donald
+ * @version $Revision$ $Date$
+ */
+public final class ManifestUtil
+{
+ /**
+ * The Name Attribute is the first in a named section
+ */
+ public final static String ATTRIBUTE_NAME = "Name";
+ /**
+ * The From Header is disallowed in a Manifest
+ */
+ public final static String ATTRIBUTE_FROM = "From";
+ /**
+ * The Class-Path Header is special - it can be duplicated
+ */
+ public final static String ATTRIBUTE_CLASSPATH = Attributes.Name.CLASS_PATH.toString();
+ /**
+ * Default Manifest version if one is not specified
+ */
+ public final static String DEFAULT_MANIFEST_VERSION = "1.0";
+ /**
+ * The max length of a line in a Manifest
+ */
+ public final static int MAX_LINE_LENGTH = 70;
+
+ public static Attribute buildAttribute( final String line )
+ throws ManifestException
+ {
+ final Attribute attribute = new Attribute();
+ parse( attribute, line );
+ return attribute;
+ }
+
+ public static Manifest buildManifest( final Reader reader )
+ throws ManifestException, IOException
+ {
+ final Manifest manifest = new Manifest();
+ BufferedReader bufferedReader = new BufferedReader( reader );
+ // This should be the manifest version
+ final Section mainSection = manifest.getMainSection();
+ String nextSectionName = mainSection.read( bufferedReader );
+ final String readManifestVersion =
+ mainSection.getAttributeValue( Attributes.Name.MANIFEST_VERSION.toString() );
+ if( readManifestVersion != null )
+ {
+ manifest.setManifestVersion( readManifestVersion );
+ mainSection.removeAttribute( Attributes.Name.MANIFEST_VERSION.toString() );
+ }
+
+ String line = null;
+ while( ( line = bufferedReader.readLine() ) != null )
+ {
+ if( line.length() == 0 )
+ {
+ continue;
+ }
+
+ Section section = new Section();
+ if( nextSectionName == null )
+ {
+ Attribute sectionName = ManifestUtil.buildAttribute( line );
+ if( !sectionName.getName().equalsIgnoreCase( ManifestUtil.ATTRIBUTE_NAME ) )
+ {
+ throw new ManifestException( "Manifest sections should start with a \"" + ManifestUtil.ATTRIBUTE_NAME +
+ "\" attribute and not \"" + sectionName.getName() + "\"" );
+ }
+ nextSectionName = sectionName.getValue();
+ }
+ 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
+ Attribute firstAttribute = ManifestUtil.buildAttribute( line );
+ section.addAttributeAndCheck( firstAttribute );
+ }
+
+ section.setName( nextSectionName );
+ nextSectionName = section.read( bufferedReader );
+ manifest.addSection( section );
+ }
+
+ return manifest;
+ }
+
+ /**
+ * Construct a manifest from Ant's default manifest file.
+ */
+ public static Manifest getDefaultManifest()
+ throws ManifestException
+ {
+ try
+ {
+ final InputStream input = getInputStream();
+ final InputStreamReader reader = getReader( input );
+ return buildManifest( reader );
+ }
+ catch( final IOException ioe )
+ {
+ throw new ManifestException( "Unable to read default manifest", ioe );
+ }
+ }
+
+ private static InputStream getInputStream()
+ throws ManifestException
+ {
+ final String location = "default.mf";
+ final InputStream input = ManifestUtil.class.getResourceAsStream( location );
+ if( null == input )
+ {
+ throw new ManifestException( "Could not find default manifest: " + location );
+ }
+ return input;
+ }
+
+ private static InputStreamReader getReader( final InputStream input )
+ {
+ try
+ {
+ return new InputStreamReader( input, "ASCII" );
+ }
+ catch( final UnsupportedEncodingException uee )
+ {
+ return new InputStreamReader( input );
+ }
+ }
+
+ /**
+ * Parse a line into name and value pairs
+ *
+ * @param line the line to be parsed
+ * @throws ManifestException if the line does not contain a colon
+ * separating the name and value
+ */
+ public static void parse( final Attribute attribute, final String line )
+ throws ManifestException
+ {
+ final 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 ': ' " );
+ }
+ final String name = line.substring( 0, index );
+ final String value = line.substring( index + 2 );
+ attribute.setName( name );
+ attribute.setValue( value );
+ }
+
+ public static void write( final Attribute attribute, final PrintWriter writer )
+ throws IOException
+ {
+ final String name = attribute.getName();
+ final String value = attribute.getValue();
+ 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 )
+ {
+ breakIndex--;
+ section = line.substring( 0, breakIndex );
+ }
+ if( breakIndex == 0 )
+ {
+ throw new IOException( "Unable to write manifest line " + name + ": " + value );
+ }
+ writer.println( section );
+ line = " " + line.substring( breakIndex );
+ }
+ writer.println( line );
+ }
+
+ /**
+ * Write the manifest out to a print writer.
+ *
+ * @param writer the Writer to which the manifest is written
+ * @throws IOException if the manifest cannot be written
+ */
+ public static void write( Manifest manifest, PrintWriter writer )
+ throws IOException
+ {
+ final String sigVersionKey = Attributes.Name.SIGNATURE_VERSION.toString();
+
+ writer.println( Attributes.Name.MANIFEST_VERSION + ": " + manifest.getManifestVersion() );
+
+ final String signatureVersion =
+ manifest.getMainSection().getAttributeValue( sigVersionKey );
+ if( signatureVersion != null )
+ {
+ writer.println( Attributes.Name.SIGNATURE_VERSION + ": " + signatureVersion );
+ manifest.getMainSection().removeAttribute( sigVersionKey );
+ }
+ manifest.getMainSection().write( writer );
+ if( signatureVersion != null )
+ {
+ try
+ {
+ manifest.getMainSection().addAttribute( new Attribute( sigVersionKey, signatureVersion ) );
+ }
+ catch( ManifestException e )
+ {
+ // shouldn't happen - ignore
+ }
+ }
+
+ final Section[] sections = manifest.getSections();
+ for( int i = 0; i < sections.length; i++ )
+ {
+ sections[ i ].write( writer );
+ }
+ }
+}
diff --git a/proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/manifest/Section.java b/proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/manifest/Section.java
index cfd577e0b..2213a6b71 100644
--- a/proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/manifest/Section.java
+++ b/proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/manifest/Section.java
@@ -14,9 +14,6 @@ import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;
-import org.apache.aut.manifest.Attribute;
-import org.apache.aut.manifest.ManifestException;
-import org.apache.aut.manifest.ManifestUtil;
/**
* Class to represent an individual section in the Manifest. A section