git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@271240 13f79535-47bb-0310-9956-ffa450edef68remotes/1776816827838153613/tmp_25f451bd36ab3145e487fcb2cd5c62c571e5b602
| @@ -18,12 +18,12 @@ import java.io.OutputStreamWriter; | |||||
| import java.io.PrintWriter; | import java.io.PrintWriter; | ||||
| import java.io.Reader; | import java.io.Reader; | ||||
| import java.util.Enumeration; | import java.util.Enumeration; | ||||
| import java.util.Iterator; | |||||
| import java.util.zip.ZipFile; | import java.util.zip.ZipFile; | ||||
| import org.apache.aut.zip.ZipOutputStream; | import org.apache.aut.zip.ZipOutputStream; | ||||
| import org.apache.myrmidon.api.TaskException; | import org.apache.myrmidon.api.TaskException; | ||||
| import org.apache.tools.ant.taskdefs.manifest.Manifest; | import org.apache.tools.ant.taskdefs.manifest.Manifest; | ||||
| import org.apache.tools.ant.taskdefs.manifest.ManifestException; | import org.apache.tools.ant.taskdefs.manifest.ManifestException; | ||||
| import org.apache.tools.ant.taskdefs.manifest.ManifestUtil; | |||||
| import org.apache.tools.ant.types.FileScanner; | import org.apache.tools.ant.types.FileScanner; | ||||
| /** | /** | ||||
| @@ -89,10 +89,10 @@ public class Jar | |||||
| try | try | ||||
| { | { | ||||
| r = new FileReader( manifestFile ); | r = new FileReader( manifestFile ); | ||||
| Manifest newManifest = new Manifest( r ); | |||||
| Manifest newManifest = ManifestUtil.buildManifest( r ); | |||||
| if( m_manifest == null ) | if( m_manifest == null ) | ||||
| { | { | ||||
| m_manifest = Manifest.getDefaultManifest(); | |||||
| m_manifest = ManifestUtil.getDefaultManifest(); | |||||
| } | } | ||||
| m_manifest.merge( newManifest ); | m_manifest.merge( newManifest ); | ||||
| } | } | ||||
| @@ -134,7 +134,7 @@ public class Jar | |||||
| { | { | ||||
| if( m_manifest == null ) | if( m_manifest == null ) | ||||
| { | { | ||||
| m_manifest = Manifest.getDefaultManifest(); | |||||
| m_manifest = ManifestUtil.getDefaultManifest(); | |||||
| } | } | ||||
| m_manifest.merge( newManifest ); | m_manifest.merge( newManifest ); | ||||
| buildFileManifest = true; | buildFileManifest = true; | ||||
| @@ -172,10 +172,10 @@ public class Jar | |||||
| getLogger().debug( "Updating jar since the current jar has no manifest" ); | getLogger().debug( "Updating jar since the current jar has no manifest" ); | ||||
| return false; | return false; | ||||
| } | } | ||||
| Manifest currentManifest = new Manifest( new InputStreamReader( theZipFile.getInputStream( entry ) ) ); | |||||
| Manifest currentManifest = ManifestUtil.buildManifest( new InputStreamReader( theZipFile.getInputStream( entry ) ) ); | |||||
| if( m_manifest == null ) | if( m_manifest == null ) | ||||
| { | { | ||||
| m_manifest = Manifest.getDefaultManifest(); | |||||
| m_manifest = ManifestUtil.getDefaultManifest(); | |||||
| } | } | ||||
| if( !currentManifest.equals( m_manifest ) ) | if( !currentManifest.equals( m_manifest ) ) | ||||
| { | { | ||||
| @@ -231,22 +231,25 @@ public class Jar | |||||
| { | { | ||||
| try | try | ||||
| { | { | ||||
| m_execManifest = Manifest.getDefaultManifest(); | |||||
| m_execManifest = ManifestUtil.getDefaultManifest(); | |||||
| if( m_manifest != null ) | if( m_manifest != null ) | ||||
| { | { | ||||
| m_execManifest.merge( m_manifest ); | m_execManifest.merge( m_manifest ); | ||||
| } | } | ||||
| /* | |||||
| for( Iterator e = m_execManifest.getWarnings(); e.hasNext(); ) | for( Iterator e = m_execManifest.getWarnings(); e.hasNext(); ) | ||||
| { | { | ||||
| getLogger().warn( "Manifest warning: " + (String)e.next() ); | getLogger().warn( "Manifest warning: " + (String)e.next() ); | ||||
| } | } | ||||
| */ | |||||
| zipDir( null, zOut, "META-INF/" ); | zipDir( null, zOut, "META-INF/" ); | ||||
| // time to write the manifest | // time to write the manifest | ||||
| ByteArrayOutputStream baos = new ByteArrayOutputStream(); | ByteArrayOutputStream baos = new ByteArrayOutputStream(); | ||||
| PrintWriter writer = new PrintWriter( baos ); | PrintWriter writer = new PrintWriter( baos ); | ||||
| m_execManifest.write( writer ); | |||||
| Manifest manifest = m_execManifest; | |||||
| ManifestUtil.write( manifest, writer ); | |||||
| writer.flush(); | writer.flush(); | ||||
| ByteArrayInputStream bais = new ByteArrayInputStream( baos.toByteArray() ); | ByteArrayInputStream bais = new ByteArrayInputStream( baos.toByteArray() ); | ||||
| @@ -375,11 +378,12 @@ public class Jar | |||||
| { | { | ||||
| if( m_execManifest == null ) | if( m_execManifest == null ) | ||||
| { | { | ||||
| m_execManifest = new Manifest( new InputStreamReader( is ) ); | |||||
| m_execManifest = ManifestUtil.buildManifest( new InputStreamReader( is ) ); | |||||
| } | } | ||||
| else if( isAddingNewFiles() ) | else if( isAddingNewFiles() ) | ||||
| { | { | ||||
| m_execManifest.merge( new Manifest( new InputStreamReader( is ) ) ); | |||||
| final Manifest other = ManifestUtil.buildManifest( new InputStreamReader( is ) ); | |||||
| m_execManifest.merge( other ); | |||||
| } | } | ||||
| } | } | ||||
| catch( ManifestException e ) | catch( ManifestException e ) | ||||
| @@ -9,6 +9,7 @@ package org.apache.tools.ant.taskdefs.manifest; | |||||
| import java.io.PrintWriter; | import java.io.PrintWriter; | ||||
| import java.io.IOException; | import java.io.IOException; | ||||
| import java.util.jar.Attributes; | |||||
| /** | /** | ||||
| * Class to hold manifest attributes | * Class to hold manifest attributes | ||||
| @@ -110,10 +111,11 @@ public class Attribute | |||||
| } | } | ||||
| final Attribute other = (Attribute)object; | final Attribute other = (Attribute)object; | ||||
| final String name = other.m_name; | |||||
| return | return | ||||
| ( null != m_name && null != other.m_name && | |||||
| m_name.toLowerCase().equals( other.m_name.toLowerCase() ) && | |||||
| m_value != null && m_value.equals( other.m_value ) ); | |||||
| ( null != m_name && null != name && | |||||
| m_name.toLowerCase().equals( name.toLowerCase() ) && | |||||
| null != m_value && m_value.equals( other.m_value ) ); | |||||
| } | } | ||||
| } | } | ||||
| @@ -7,23 +7,11 @@ | |||||
| */ | */ | ||||
| package org.apache.tools.ant.taskdefs.manifest; | package org.apache.tools.ant.taskdefs.manifest; | ||||
| import java.io.BufferedReader; | |||||
| import java.io.File; | |||||
| import java.io.FileReader; | |||||
| import java.io.FileWriter; | |||||
| import java.io.IOException; | |||||
| import java.io.InputStream; | |||||
| import java.io.InputStreamReader; | |||||
| import java.io.PrintWriter; | |||||
| import java.io.Reader; | |||||
| import java.io.StringWriter; | |||||
| import java.io.UnsupportedEncodingException; | |||||
| import java.util.ArrayList; | |||||
| import java.util.Collection; | |||||
| import java.util.Enumeration; | import java.util.Enumeration; | ||||
| import java.util.Hashtable; | import java.util.Hashtable; | ||||
| import java.util.Iterator; | import java.util.Iterator; | ||||
| import java.util.jar.Attributes; | |||||
| import org.apache.myrmidon.api.AbstractTask; | |||||
| import java.util.Set; | |||||
| import org.apache.myrmidon.api.TaskException; | import org.apache.myrmidon.api.TaskException; | ||||
| /** | /** | ||||
| @@ -35,42 +23,11 @@ import org.apache.myrmidon.api.TaskException; | |||||
| * @version $Revision$ $Date$ | * @version $Revision$ $Date$ | ||||
| */ | */ | ||||
| public class Manifest | public class Manifest | ||||
| extends AbstractTask | |||||
| { | { | ||||
| /** | |||||
| * The standard Signature Version header | |||||
| */ | |||||
| public final static String ATTRIBUTE_SIGNATURE_VERSION = Attributes.Name.SIGNATURE_VERSION.toString(); | |||||
| /** | |||||
| * 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; | |||||
| /** | /** | ||||
| * The version of this manifest | * The version of this manifest | ||||
| */ | */ | ||||
| private String m_manifestVersion = DEFAULT_MANIFEST_VERSION; | |||||
| private String m_manifestVersion = ManifestUtil.DEFAULT_MANIFEST_VERSION; | |||||
| /** | /** | ||||
| * The main section of this manifest | * The main section of this manifest | ||||
| @@ -82,211 +39,112 @@ public class Manifest | |||||
| */ | */ | ||||
| private Hashtable m_sections = new Hashtable(); | private Hashtable m_sections = new Hashtable(); | ||||
| private File m_manifestFile; | |||||
| private ManifestMode m_mode; | |||||
| /** | |||||
| * Construct an empty manifest | |||||
| */ | |||||
| public Manifest() | |||||
| throws TaskException | |||||
| public void setManifestVersion( final String manifestVersion ) | |||||
| { | { | ||||
| m_mode = new ManifestMode(); | |||||
| m_mode.setValue( "replace" ); | |||||
| m_manifestVersion = null; | |||||
| m_manifestVersion = manifestVersion; | |||||
| } | } | ||||
| /** | |||||
| * Read a manifest file from the given reader | |||||
| * | |||||
| * @param r Description of Parameter | |||||
| * @exception ManifestException Description of Exception | |||||
| * @exception IOException Description of Exception | |||||
| * @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, TaskException, IOException | |||||
| public void setMainSection( final Section mainSection ) | |||||
| { | { | ||||
| BufferedReader reader = new BufferedReader( r ); | |||||
| // This should be the manifest version | |||||
| String nextSectionName = m_mainSection.read( reader ); | |||||
| String readManifestVersion = m_mainSection.getAttributeValue( Attributes.Name.MANIFEST_VERSION.toString() ); | |||||
| if( readManifestVersion != null ) | |||||
| { | |||||
| m_manifestVersion = readManifestVersion; | |||||
| m_mainSection.removeAttribute( Attributes.Name.MANIFEST_VERSION.toString() ); | |||||
| } | |||||
| String line = null; | |||||
| while( ( line = reader.readLine() ) != null ) | |||||
| { | |||||
| if( line.length() == 0 ) | |||||
| { | |||||
| continue; | |||||
| } | |||||
| Section section = new Section(); | |||||
| if( nextSectionName == null ) | |||||
| { | |||||
| Attribute sectionName = ManifestUtil.buildAttribute( line ); | |||||
| if( !sectionName.getName().equalsIgnoreCase( ATTRIBUTE_NAME ) ) | |||||
| { | |||||
| throw new ManifestException( "Manifest sections should start with a \"" + 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 ); | |||||
| } | |||||
| m_mainSection = mainSection; | |||||
| } | |||||
| section.setName( nextSectionName ); | |||||
| nextSectionName = section.read( reader ); | |||||
| addSection( section ); | |||||
| } | |||||
| public void addAttribute( final Attribute attribute ) | |||||
| throws ManifestException | |||||
| { | |||||
| m_mainSection.addAttribute( attribute ); | |||||
| } | } | ||||
| /** | |||||
| * Construct a manifest from Ant's default manifest file. | |||||
| * | |||||
| * @return The DefaultManifest value | |||||
| * @exception TaskException Description of Exception | |||||
| */ | |||||
| public static Manifest getDefaultManifest() | |||||
| throws TaskException | |||||
| public void addSection( final Section section ) | |||||
| throws ManifestException | |||||
| { | { | ||||
| try | |||||
| { | |||||
| String s = "/org/apache/tools/ant/defaultManifest.mf"; | |||||
| InputStream in = Manifest.class.getResourceAsStream( s ); | |||||
| if( in == null ) | |||||
| { | |||||
| throw new TaskException( "Could not find default manifest: " + s ); | |||||
| } | |||||
| try | |||||
| { | |||||
| return new Manifest( new InputStreamReader( in, "ASCII" ) ); | |||||
| } | |||||
| catch( UnsupportedEncodingException e ) | |||||
| { | |||||
| return new Manifest( new InputStreamReader( in ) ); | |||||
| } | |||||
| } | |||||
| catch( ManifestException e ) | |||||
| { | |||||
| throw new TaskException( "Default manifest is invalid !!" ); | |||||
| } | |||||
| catch( IOException e ) | |||||
| if( section.getName() == null ) | |||||
| { | { | ||||
| throw new TaskException( "Unable to read default manifest", e ); | |||||
| final String message = "Sections must have a name"; | |||||
| throw new ManifestException( message ); | |||||
| } | } | ||||
| m_sections.put( section.getName().toLowerCase(), section ); | |||||
| } | } | ||||
| /** | |||||
| * The name of the manifest file to write (if used as a task). | |||||
| * | |||||
| * @param f The new File value | |||||
| */ | |||||
| public void setFile( File f ) | |||||
| public String[] getSectionNames( final Manifest other ) | |||||
| { | { | ||||
| m_manifestFile = f; | |||||
| final Set keys = other.m_sections.keySet(); | |||||
| return (String[])keys.toArray( new String[ keys.size() ] ); | |||||
| } | } | ||||
| /** | |||||
| * Shall we update or replace an existing manifest? | |||||
| * | |||||
| * @param m The new ManifestMode value | |||||
| */ | |||||
| public void setMode( ManifestMode m ) | |||||
| public String getManifestVersion() | |||||
| { | { | ||||
| m_mode = m; | |||||
| return m_manifestVersion; | |||||
| } | } | ||||
| /** | |||||
| * Get the warnings for this manifest. | |||||
| * | |||||
| * @return an enumeration of warning strings | |||||
| */ | |||||
| public Iterator getWarnings() | |||||
| public Section getMainSection() | |||||
| { | { | ||||
| ArrayList warnings = new ArrayList(); | |||||
| for( Iterator e2 = m_mainSection.getWarnings(); e2.hasNext(); ) | |||||
| { | |||||
| warnings.add( e2.next() ); | |||||
| } | |||||
| // create a vector and add in the warnings for all the sections | |||||
| for( Enumeration e = m_sections.elements(); e.hasMoreElements(); ) | |||||
| { | |||||
| Section section = (Section)e.nextElement(); | |||||
| for( Iterator e2 = section.getWarnings(); e2.hasNext(); ) | |||||
| { | |||||
| warnings.add( e2.next() ); | |||||
| } | |||||
| } | |||||
| return m_mainSection; | |||||
| } | |||||
| return warnings.iterator(); | |||||
| public Section getSection( final String name ) | |||||
| { | |||||
| return (Section)m_sections.get( name ); | |||||
| } | } | ||||
| public void addAttribute( final Attribute attribute ) | |||||
| throws ManifestException, TaskException | |||||
| public Section[] getSections() | |||||
| { | { | ||||
| m_mainSection.addAttribute( attribute ); | |||||
| final Collection sections = m_sections.values(); | |||||
| return (Section[])sections.toArray( new Section[ sections.size() ] ); | |||||
| } | } | ||||
| public void addSection( final Section section ) | |||||
| throws ManifestException, TaskException | |||||
| /** | |||||
| * Merge the contents of the given manifest into this manifest | |||||
| * | |||||
| * @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. | |||||
| */ | |||||
| public void merge( final Manifest other ) | |||||
| throws ManifestException | |||||
| { | { | ||||
| if( section.getName() == null ) | |||||
| if( other.m_manifestVersion != null ) | |||||
| { | { | ||||
| throw new TaskException( "Sections must have a name" ); | |||||
| m_manifestVersion = other.m_manifestVersion; | |||||
| } | } | ||||
| m_sections.put( section.getName().toLowerCase(), section ); | |||||
| m_mainSection.merge( other.m_mainSection ); | |||||
| mergeSections( other ); | |||||
| } | } | ||||
| public boolean equals( Object rhs ) | |||||
| public boolean equals( final Object object ) | |||||
| { | { | ||||
| if( !( rhs instanceof Manifest ) ) | |||||
| if( !( object instanceof Manifest ) ) | |||||
| { | { | ||||
| return false; | return false; | ||||
| } | } | ||||
| Manifest rhsManifest = (Manifest)rhs; | |||||
| if( m_manifestVersion == null ) | |||||
| final Manifest other = (Manifest)object; | |||||
| if( m_manifestVersion == null && other.m_manifestVersion != null ) | |||||
| { | { | ||||
| if( rhsManifest.m_manifestVersion != null ) | |||||
| { | |||||
| return false; | |||||
| } | |||||
| return false; | |||||
| } | } | ||||
| else if( !m_manifestVersion.equals( rhsManifest.m_manifestVersion ) ) | |||||
| else if( !m_manifestVersion.equals( other.m_manifestVersion ) ) | |||||
| { | { | ||||
| return false; | return false; | ||||
| } | } | ||||
| if( m_sections.size() != rhsManifest.m_sections.size() ) | |||||
| if( m_sections.size() != other.m_sections.size() ) | |||||
| { | { | ||||
| return false; | return false; | ||||
| } | } | ||||
| if( !m_mainSection.equals( rhsManifest.m_mainSection ) ) | |||||
| if( !m_mainSection.equals( other.m_mainSection ) ) | |||||
| { | { | ||||
| return false; | return false; | ||||
| } | } | ||||
| for( Enumeration e = m_sections.elements(); e.hasMoreElements(); ) | |||||
| final Iterator e = m_sections.values().iterator(); | |||||
| while( e.hasNext() ) | |||||
| { | { | ||||
| Section section = (Section)e.nextElement(); | |||||
| Section rhsSection = (Section)rhsManifest.m_sections.get( section.getName().toLowerCase() ); | |||||
| if( !section.equals( rhsSection ) ) | |||||
| final Section section = (Section)e.next(); | |||||
| final String key = section.getName().toLowerCase(); | |||||
| final Section otherSection = (Section)other.m_sections.get( key ); | |||||
| if( !section.equals( otherSection ) ) | |||||
| { | { | ||||
| return false; | return false; | ||||
| } | } | ||||
| @@ -295,168 +153,23 @@ public class Manifest | |||||
| return true; | return true; | ||||
| } | } | ||||
| /** | |||||
| * Create or update the Manifest when used as a task. | |||||
| * | |||||
| * @exception TaskException Description of Exception | |||||
| */ | |||||
| public void execute() | |||||
| throws TaskException | |||||
| { | |||||
| if( m_manifestFile == null ) | |||||
| { | |||||
| throw new TaskException( "the file attribute is required" ); | |||||
| } | |||||
| Manifest toWrite = getDefaultManifest(); | |||||
| if( m_mode.getValue().equals( "update" ) && m_manifestFile.exists() ) | |||||
| { | |||||
| FileReader f = null; | |||||
| try | |||||
| { | |||||
| f = new FileReader( m_manifestFile ); | |||||
| toWrite.merge( new Manifest( f ) ); | |||||
| } | |||||
| catch( ManifestException m ) | |||||
| { | |||||
| throw new TaskException( "Existing manifest " + m_manifestFile | |||||
| + " is invalid", m ); | |||||
| } | |||||
| catch( IOException e ) | |||||
| { | |||||
| throw new | |||||
| TaskException( "Failed to read " + m_manifestFile, e ); | |||||
| } | |||||
| finally | |||||
| { | |||||
| if( f != null ) | |||||
| { | |||||
| try | |||||
| { | |||||
| f.close(); | |||||
| } | |||||
| catch( IOException e ) | |||||
| { | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| try | |||||
| { | |||||
| toWrite.merge( this ); | |||||
| } | |||||
| catch( ManifestException m ) | |||||
| { | |||||
| throw new TaskException( "Manifest is invalid", m ); | |||||
| } | |||||
| PrintWriter w = null; | |||||
| try | |||||
| { | |||||
| w = new PrintWriter( new FileWriter( m_manifestFile ) ); | |||||
| toWrite.write( w ); | |||||
| } | |||||
| catch( IOException e ) | |||||
| { | |||||
| throw new TaskException( "Failed to write " + m_manifestFile, e ); | |||||
| } | |||||
| finally | |||||
| { | |||||
| if( w != null ) | |||||
| { | |||||
| w.close(); | |||||
| } | |||||
| } | |||||
| } | |||||
| /** | |||||
| * Merge the contents of the given manifest into this manifest | |||||
| * | |||||
| * @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. | |||||
| */ | |||||
| public void merge( Manifest other ) | |||||
| private void mergeSections( final Manifest other ) | |||||
| throws ManifestException | throws ManifestException | ||||
| { | { | ||||
| if( other.m_manifestVersion != null ) | |||||
| { | |||||
| m_manifestVersion = other.m_manifestVersion; | |||||
| } | |||||
| m_mainSection.merge( other.m_mainSection ); | |||||
| for( Enumeration e = other.m_sections.keys(); e.hasMoreElements(); ) | |||||
| final String[] sections = getSectionNames( other ); | |||||
| for( int i = 0; i < sections.length; i++ ) | |||||
| { | { | ||||
| String sectionName = (String)e.nextElement(); | |||||
| Section ourSection = (Section)m_sections.get( sectionName ); | |||||
| Section otherSection = (Section)other.m_sections.get( sectionName ); | |||||
| if( ourSection == null ) | |||||
| final String sectionName = sections[ i ]; | |||||
| final Section section = getSection( sectionName ); | |||||
| final Section otherSection = other.getSection( sectionName ); | |||||
| if( section == null ) | |||||
| { | { | ||||
| m_sections.put( sectionName.toLowerCase(), otherSection ); | m_sections.put( sectionName.toLowerCase(), otherSection ); | ||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| ourSection.merge( otherSection ); | |||||
| section.merge( otherSection ); | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /** | |||||
| * Convert the manifest to its string representation | |||||
| * | |||||
| * @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( Exception e ) | |||||
| { | |||||
| return null; | |||||
| } | |||||
| return sw.toString(); | |||||
| } | |||||
| /** | |||||
| * 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 void write( PrintWriter writer ) | |||||
| throws IOException, TaskException | |||||
| { | |||||
| writer.println( Attributes.Name.MANIFEST_VERSION + ": " + m_manifestVersion ); | |||||
| String signatureVersion = m_mainSection.getAttributeValue( ATTRIBUTE_SIGNATURE_VERSION ); | |||||
| if( signatureVersion != null ) | |||||
| { | |||||
| writer.println( ATTRIBUTE_SIGNATURE_VERSION + ": " + signatureVersion ); | |||||
| m_mainSection.removeAttribute( ATTRIBUTE_SIGNATURE_VERSION ); | |||||
| } | |||||
| m_mainSection.write( writer ); | |||||
| if( signatureVersion != null ) | |||||
| { | |||||
| try | |||||
| { | |||||
| m_mainSection.addAttribute( new Attribute( ATTRIBUTE_SIGNATURE_VERSION, signatureVersion ) ); | |||||
| } | |||||
| catch( ManifestException e ) | |||||
| { | |||||
| // shouldn't happen - ignore | |||||
| } | |||||
| } | |||||
| for( Enumeration e = m_sections.elements(); e.hasMoreElements(); ) | |||||
| { | |||||
| Section section = (Section)e.nextElement(); | |||||
| section.write( writer ); | |||||
| } | |||||
| } | |||||
| } | } | ||||
| @@ -0,0 +1,196 @@ | |||||
| /* | |||||
| * 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.File; | |||||
| import java.io.FileReader; | |||||
| import java.io.FileWriter; | |||||
| import java.io.IOException; | |||||
| import java.io.PrintWriter; | |||||
| import java.util.ArrayList; | |||||
| import java.util.Iterator; | |||||
| import org.apache.avalon.excalibur.io.IOUtil; | |||||
| import org.apache.myrmidon.api.AbstractTask; | |||||
| import org.apache.myrmidon.api.TaskException; | |||||
| /** | |||||
| * Class to manage Manifest information | |||||
| * | |||||
| * @author <a href="mailto:peter@apache.org">Peter Donald</a> | |||||
| * @author <a href="mailto:conor@apache.org">Conor MacNeill</a> | |||||
| * @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a> | |||||
| * @version $Revision$ $Date$ | |||||
| */ | |||||
| public class ManifestTask | |||||
| extends AbstractTask | |||||
| { | |||||
| private File m_destFile; | |||||
| private ManifestMode m_mode; | |||||
| private Manifest m_manifest = new Manifest(); | |||||
| /** | |||||
| * Construct an empty manifest | |||||
| */ | |||||
| public ManifestTask() | |||||
| throws TaskException | |||||
| { | |||||
| m_mode = new ManifestMode(); | |||||
| m_mode.setValue( "replace" ); | |||||
| } | |||||
| /** | |||||
| * The name of the manifest file to write. | |||||
| */ | |||||
| public void setDestFile( final File destFile ) | |||||
| { | |||||
| m_destFile = destFile; | |||||
| } | |||||
| /** | |||||
| * Shall we update or replace an existing manifest? | |||||
| */ | |||||
| public void setMode( final ManifestMode mode ) | |||||
| { | |||||
| m_mode = mode; | |||||
| } | |||||
| public void setManifestVersion( String manifestVersion ) | |||||
| { | |||||
| m_manifest.setManifestVersion( manifestVersion ); | |||||
| } | |||||
| public void addMainSection( Section mainSection ) | |||||
| throws Exception | |||||
| { | |||||
| m_manifest.setMainSection( mainSection ); | |||||
| } | |||||
| /** | |||||
| * Get the warnings for this manifest. | |||||
| * | |||||
| * @return an enumeration of warning strings | |||||
| */ | |||||
| public Iterator getWarnings() | |||||
| { | |||||
| ArrayList warnings = new ArrayList(); | |||||
| for( Iterator e2 = m_manifest.getMainSection().getWarnings(); e2.hasNext(); ) | |||||
| { | |||||
| warnings.add( e2.next() ); | |||||
| } | |||||
| final Section[] sections = m_manifest.getSections(); | |||||
| for( int i = 0; i < sections.length; i++ ) | |||||
| { | |||||
| final Section section = sections[ i ]; | |||||
| for( Iterator e2 = section.getWarnings(); e2.hasNext(); ) | |||||
| { | |||||
| warnings.add( e2.next() ); | |||||
| } | |||||
| } | |||||
| return warnings.iterator(); | |||||
| } | |||||
| public void addAttribute( final Attribute attribute ) | |||||
| throws ManifestException, TaskException | |||||
| { | |||||
| m_manifest.addAttribute( attribute ); | |||||
| } | |||||
| public void addSection( final Section section ) | |||||
| throws TaskException | |||||
| { | |||||
| try | |||||
| { | |||||
| m_manifest.addSection( section ); | |||||
| } | |||||
| catch( final ManifestException me ) | |||||
| { | |||||
| throw new TaskException( me.getMessage(), me ); | |||||
| } | |||||
| } | |||||
| /** | |||||
| * Create or update the Manifest when used as a task. | |||||
| * | |||||
| * @exception TaskException Description of Exception | |||||
| */ | |||||
| public void execute() | |||||
| throws TaskException | |||||
| { | |||||
| if( null == m_destFile ) | |||||
| { | |||||
| throw new TaskException( "the file attribute is required" ); | |||||
| } | |||||
| Manifest toWrite = getDefaultManifest(); | |||||
| if( m_mode.getValue().equals( "update" ) && m_destFile.exists() ) | |||||
| { | |||||
| FileReader f = null; | |||||
| try | |||||
| { | |||||
| f = new FileReader( m_destFile ); | |||||
| final Manifest other = ManifestUtil.buildManifest( f ); | |||||
| toWrite.merge( other ); | |||||
| } | |||||
| catch( ManifestException m ) | |||||
| { | |||||
| throw new TaskException( "Existing manifest " + m_destFile | |||||
| + " is invalid", m ); | |||||
| } | |||||
| catch( IOException e ) | |||||
| { | |||||
| throw new | |||||
| TaskException( "Failed to read " + m_destFile, e ); | |||||
| } | |||||
| finally | |||||
| { | |||||
| IOUtil.shutdownReader( f ); | |||||
| } | |||||
| } | |||||
| try | |||||
| { | |||||
| toWrite.merge( m_manifest ); | |||||
| } | |||||
| catch( ManifestException m ) | |||||
| { | |||||
| throw new TaskException( "Manifest is invalid", m ); | |||||
| } | |||||
| PrintWriter w = null; | |||||
| try | |||||
| { | |||||
| w = new PrintWriter( new FileWriter( m_destFile ) ); | |||||
| ManifestUtil.write( toWrite, w ); | |||||
| } | |||||
| catch( IOException e ) | |||||
| { | |||||
| throw new TaskException( "Failed to write " + m_destFile, e ); | |||||
| } | |||||
| finally | |||||
| { | |||||
| IOUtil.shutdownWriter( w ); | |||||
| } | |||||
| } | |||||
| private Manifest getDefaultManifest() | |||||
| throws TaskException | |||||
| { | |||||
| try | |||||
| { | |||||
| return ManifestUtil.getDefaultManifest(); | |||||
| } | |||||
| catch( final ManifestException me ) | |||||
| { | |||||
| throw new TaskException( me.getMessage(), me ); | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -8,7 +8,14 @@ | |||||
| package org.apache.tools.ant.taskdefs.manifest; | package org.apache.tools.ant.taskdefs.manifest; | ||||
| import java.io.IOException; | import java.io.IOException; | ||||
| import java.io.InputStream; | |||||
| import java.io.InputStreamReader; | |||||
| import java.io.PrintWriter; | import java.io.PrintWriter; | ||||
| import java.io.Reader; | |||||
| import java.io.UnsupportedEncodingException; | |||||
| import java.io.BufferedReader; | |||||
| import java.util.jar.Attributes; | |||||
| import org.apache.myrmidon.api.TaskException; | |||||
| /** | /** | ||||
| * Utility methods for manifest stuff. | * Utility methods for manifest stuff. | ||||
| @@ -20,6 +27,27 @@ import java.io.PrintWriter; | |||||
| */ | */ | ||||
| public final class ManifestUtil | 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 ) | public static Attribute buildAttribute( final String line ) | ||||
| throws ManifestException | throws ManifestException | ||||
| { | { | ||||
| @@ -28,6 +56,100 @@ public final class ManifestUtil | |||||
| return attribute; | 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 | * Parse a line into name and value pairs | ||||
| * | * | ||||
| @@ -56,12 +178,12 @@ public final class ManifestUtil | |||||
| final String name = attribute.getName(); | final String name = attribute.getName(); | ||||
| final String value = attribute.getValue(); | final String value = attribute.getValue(); | ||||
| String line = name + ": " + value; | String line = name + ": " + value; | ||||
| while( line.getBytes().length > Manifest.MAX_LINE_LENGTH ) | |||||
| while( line.getBytes().length > MAX_LINE_LENGTH ) | |||||
| { | { | ||||
| // try to find a MAX_LINE_LENGTH byte section | // try to find a MAX_LINE_LENGTH byte section | ||||
| int breakIndex = Manifest.MAX_LINE_LENGTH; | |||||
| int breakIndex = MAX_LINE_LENGTH; | |||||
| String section = line.substring( 0, breakIndex ); | String section = line.substring( 0, breakIndex ); | ||||
| while( section.getBytes().length > Manifest.MAX_LINE_LENGTH && breakIndex > 0 ) | |||||
| while( section.getBytes().length > MAX_LINE_LENGTH && breakIndex > 0 ) | |||||
| { | { | ||||
| breakIndex--; | breakIndex--; | ||||
| section = line.substring( 0, breakIndex ); | section = line.substring( 0, breakIndex ); | ||||
| @@ -75,4 +197,44 @@ public final class ManifestUtil | |||||
| } | } | ||||
| writer.println( line ); | 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 ); | |||||
| } | |||||
| } | |||||
| } | } | ||||
| @@ -14,7 +14,6 @@ import java.util.ArrayList; | |||||
| import java.util.Enumeration; | import java.util.Enumeration; | ||||
| import java.util.Hashtable; | import java.util.Hashtable; | ||||
| import java.util.Iterator; | import java.util.Iterator; | ||||
| import org.apache.myrmidon.api.TaskException; | |||||
| /** | /** | ||||
| * Class to represent an individual section in the Manifest. A section | * Class to represent an individual section in the Manifest. A section | ||||
| @@ -28,26 +27,26 @@ import org.apache.myrmidon.api.TaskException; | |||||
| */ | */ | ||||
| public class Section | public class Section | ||||
| { | { | ||||
| private ArrayList warnings = new ArrayList(); | |||||
| private final ArrayList m_warnings = new ArrayList(); | |||||
| /** | /** | ||||
| * 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; | |||||
| private String m_name; | |||||
| /** | /** | ||||
| * The section's attributes. | * The section's attributes. | ||||
| */ | */ | ||||
| private Hashtable attributes = new Hashtable(); | |||||
| private final Hashtable m_attributes = new Hashtable(); | |||||
| /** | /** | ||||
| * Set the Section's name | * Set the Section's name | ||||
| * | * | ||||
| * @param name the section's name | * @param name the section's name | ||||
| */ | */ | ||||
| public void setName( String name ) | |||||
| public void setName( final String name ) | |||||
| { | { | ||||
| this.name = name; | |||||
| m_name = name; | |||||
| } | } | ||||
| /** | /** | ||||
| @@ -57,23 +56,26 @@ public class Section | |||||
| * @return the attribute's value or null if the attribute does not exist | * @return the attribute's value or null if the attribute does not exist | ||||
| * in the section | * in the section | ||||
| */ | */ | ||||
| public String getAttributeValue( String attributeName ) | |||||
| public String getAttributeValue( final String attributeName ) | |||||
| { | { | ||||
| Object attribute = attributes.get( attributeName.toLowerCase() ); | |||||
| if( attribute == null ) | |||||
| final Object attributeObject = m_attributes.get( attributeName.toLowerCase() ); | |||||
| if( null == attributeObject ) | |||||
| { | { | ||||
| return null; | return null; | ||||
| } | } | ||||
| if( attribute instanceof Attribute ) | |||||
| else if( attributeObject instanceof Attribute ) | |||||
| { | { | ||||
| return ( (Attribute)attribute ).getValue(); | |||||
| final Attribute attribute = (Attribute)attributeObject; | |||||
| return attribute.getValue(); | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| String value = ""; | String value = ""; | ||||
| for( Iterator e = ( (ArrayList)attribute ).iterator(); e.hasNext(); ) | |||||
| final ArrayList attributes = (ArrayList)attributeObject; | |||||
| Iterator e = attributes.iterator(); | |||||
| while( e.hasNext() ) | |||||
| { | { | ||||
| Attribute classpathAttribute = (Attribute)e.next(); | |||||
| final Attribute classpathAttribute = (Attribute)e.next(); | |||||
| value += classpathAttribute.getValue() + " "; | value += classpathAttribute.getValue() + " "; | ||||
| } | } | ||||
| return value.trim(); | return value.trim(); | ||||
| @@ -87,12 +89,12 @@ public class Section | |||||
| */ | */ | ||||
| public String getName() | public String getName() | ||||
| { | { | ||||
| return name; | |||||
| return m_name; | |||||
| } | } | ||||
| public Iterator getWarnings() | public Iterator getWarnings() | ||||
| { | { | ||||
| return warnings.iterator(); | |||||
| return m_warnings.iterator(); | |||||
| } | } | ||||
| /** | /** | ||||
| @@ -105,59 +107,59 @@ public class Section | |||||
| * section. | * section. | ||||
| */ | */ | ||||
| public String addAttributeAndCheck( Attribute attribute ) | public String addAttributeAndCheck( Attribute attribute ) | ||||
| throws ManifestException, TaskException | |||||
| throws ManifestException | |||||
| { | { | ||||
| if( attribute.getName() == null || attribute.getValue() == null ) | if( attribute.getName() == null || attribute.getValue() == null ) | ||||
| { | { | ||||
| throw new TaskException( "Attributes must have name and value" ); | |||||
| throw new ManifestException( "Attributes must have name and value" ); | |||||
| } | } | ||||
| if( attribute.getName().equalsIgnoreCase( Manifest.ATTRIBUTE_NAME ) ) | |||||
| if( attribute.getName().equalsIgnoreCase( ManifestUtil.ATTRIBUTE_NAME ) ) | |||||
| { | { | ||||
| warnings.add( "\"" + Manifest.ATTRIBUTE_NAME + "\" attributes should not occur in the " + | |||||
| m_warnings.add( "\"" + ManifestUtil.ATTRIBUTE_NAME + "\" attributes should not occur in the " + | |||||
| "main section and must be the first element in all " + | "main section and must be the first element in all " + | ||||
| "other sections: \"" + attribute.getName() + ": " + attribute.getValue() + "\"" ); | "other sections: \"" + attribute.getName() + ": " + attribute.getValue() + "\"" ); | ||||
| return attribute.getValue(); | return attribute.getValue(); | ||||
| } | } | ||||
| if( attribute.getName().toLowerCase().startsWith( Manifest.ATTRIBUTE_FROM.toLowerCase() ) ) | |||||
| if( attribute.getName().toLowerCase().startsWith( ManifestUtil.ATTRIBUTE_FROM.toLowerCase() ) ) | |||||
| { | { | ||||
| warnings.add( "Manifest attributes should not start with \"" + | |||||
| Manifest.ATTRIBUTE_FROM + "\" in \"" + attribute.getName() + ": " + attribute.getValue() + "\"" ); | |||||
| m_warnings.add( "Manifest attributes should not start with \"" + | |||||
| ManifestUtil.ATTRIBUTE_FROM + "\" in \"" + attribute.getName() + ": " + attribute.getValue() + "\"" ); | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| // classpath attributes go into a vector | // classpath attributes go into a vector | ||||
| String attributeName = attribute.getName().toLowerCase(); | String attributeName = attribute.getName().toLowerCase(); | ||||
| if( attributeName.equals( Manifest.ATTRIBUTE_CLASSPATH ) ) | |||||
| if( attributeName.equals( ManifestUtil.ATTRIBUTE_CLASSPATH ) ) | |||||
| { | { | ||||
| ArrayList classpathAttrs = (ArrayList)attributes.get( attributeName ); | |||||
| ArrayList classpathAttrs = (ArrayList)m_attributes.get( attributeName ); | |||||
| if( classpathAttrs == null ) | if( classpathAttrs == null ) | ||||
| { | { | ||||
| classpathAttrs = new ArrayList(); | classpathAttrs = new ArrayList(); | ||||
| attributes.put( attributeName, classpathAttrs ); | |||||
| m_attributes.put( attributeName, classpathAttrs ); | |||||
| } | } | ||||
| classpathAttrs.add( attribute ); | classpathAttrs.add( attribute ); | ||||
| } | } | ||||
| else if( attributes.containsKey( attributeName ) ) | |||||
| else if( m_attributes.containsKey( attributeName ) ) | |||||
| { | { | ||||
| throw new ManifestException( "The attribute \"" + attribute.getName() + "\" may not " + | throw new ManifestException( "The attribute \"" + attribute.getName() + "\" may not " + | ||||
| "occur more than once in the same section" ); | "occur more than once in the same section" ); | ||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| attributes.put( attributeName, attribute ); | |||||
| m_attributes.put( attributeName, attribute ); | |||||
| } | } | ||||
| } | } | ||||
| return null; | return null; | ||||
| } | } | ||||
| public void addAttribute( Attribute attribute ) | |||||
| throws ManifestException, TaskException | |||||
| public void addAttribute( final Attribute attribute ) | |||||
| throws ManifestException | |||||
| { | { | ||||
| String check = addAttributeAndCheck( attribute ); | String check = addAttributeAndCheck( attribute ); | ||||
| if( check != null ) | if( check != null ) | ||||
| { | { | ||||
| throw new TaskException( "Specify the section name using the \"name\" attribute of the <section> element rather " + | |||||
| throw new ManifestException( "Specify the section name using the \"name\" attribute of the <section> element rather " + | |||||
| "than using a \"Name\" manifest attribute" ); | "than using a \"Name\" manifest attribute" ); | ||||
| } | } | ||||
| } | } | ||||
| @@ -170,15 +172,15 @@ public class Section | |||||
| } | } | ||||
| Section rhsSection = (Section)rhs; | Section rhsSection = (Section)rhs; | ||||
| if( attributes.size() != rhsSection.attributes.size() ) | |||||
| if( m_attributes.size() != rhsSection.m_attributes.size() ) | |||||
| { | { | ||||
| return false; | return false; | ||||
| } | } | ||||
| for( Enumeration e = attributes.elements(); e.hasMoreElements(); ) | |||||
| for( Enumeration e = m_attributes.elements(); e.hasMoreElements(); ) | |||||
| { | { | ||||
| Attribute attribute = (Attribute)e.nextElement(); | Attribute attribute = (Attribute)e.nextElement(); | ||||
| Attribute rshAttribute = (Attribute)rhsSection.attributes.get( attribute.getName().toLowerCase() ); | |||||
| Attribute rshAttribute = (Attribute)rhsSection.m_attributes.get( attribute.getName().toLowerCase() ); | |||||
| if( !attribute.equals( rshAttribute ) ) | if( !attribute.equals( rshAttribute ) ) | ||||
| { | { | ||||
| return false; | return false; | ||||
| @@ -197,21 +199,21 @@ public class Section | |||||
| public void merge( Section section ) | public void merge( Section section ) | ||||
| throws ManifestException | throws ManifestException | ||||
| { | { | ||||
| if( name == null && section.getName() != null || | |||||
| name != null && !( name.equalsIgnoreCase( section.getName() ) ) ) | |||||
| if( m_name == null && section.getName() != null || | |||||
| m_name != null && !( m_name.equalsIgnoreCase( section.getName() ) ) ) | |||||
| { | { | ||||
| throw new ManifestException( "Unable to merge sections with different names" ); | throw new ManifestException( "Unable to merge sections with different names" ); | ||||
| } | } | ||||
| for( Enumeration e = section.attributes.keys(); e.hasMoreElements(); ) | |||||
| for( Enumeration e = section.m_attributes.keys(); e.hasMoreElements(); ) | |||||
| { | { | ||||
| String attributeName = (String)e.nextElement(); | String attributeName = (String)e.nextElement(); | ||||
| if( attributeName.equals( Manifest.ATTRIBUTE_CLASSPATH ) && | |||||
| attributes.containsKey( attributeName ) ) | |||||
| if( attributeName.equals( ManifestUtil.ATTRIBUTE_CLASSPATH ) && | |||||
| m_attributes.containsKey( attributeName ) ) | |||||
| { | { | ||||
| // classpath entries are vetors which are merged | // classpath entries are vetors which are merged | ||||
| ArrayList classpathAttrs = (ArrayList)section.attributes.get( attributeName ); | |||||
| ArrayList ourClasspathAttrs = (ArrayList)attributes.get( attributeName ); | |||||
| ArrayList classpathAttrs = (ArrayList)section.m_attributes.get( attributeName ); | |||||
| ArrayList ourClasspathAttrs = (ArrayList)m_attributes.get( attributeName ); | |||||
| for( Iterator e2 = classpathAttrs.iterator(); e2.hasNext(); ) | for( Iterator e2 = classpathAttrs.iterator(); e2.hasNext(); ) | ||||
| { | { | ||||
| ourClasspathAttrs.add( e2.next() ); | ourClasspathAttrs.add( e2.next() ); | ||||
| @@ -220,14 +222,14 @@ public class Section | |||||
| else | else | ||||
| { | { | ||||
| // the merge file always wins | // the merge file always wins | ||||
| attributes.put( attributeName, section.attributes.get( attributeName ) ); | |||||
| m_attributes.put( attributeName, section.m_attributes.get( attributeName ) ); | |||||
| } | } | ||||
| } | } | ||||
| // add in the warnings | // add in the warnings | ||||
| for( Iterator e = section.warnings.iterator(); e.hasNext(); ) | |||||
| for( Iterator e = section.m_warnings.iterator(); e.hasNext(); ) | |||||
| { | { | ||||
| warnings.add( e.next() ); | |||||
| m_warnings.add( e.next() ); | |||||
| } | } | ||||
| } | } | ||||
| @@ -242,7 +244,7 @@ public class Section | |||||
| * @throws IOException if the section cannot be read from the reader. | * @throws IOException if the section cannot be read from the reader. | ||||
| */ | */ | ||||
| public String read( BufferedReader reader ) | public String read( BufferedReader reader ) | ||||
| throws ManifestException, IOException, TaskException | |||||
| throws ManifestException, IOException | |||||
| { | { | ||||
| Attribute attribute = null; | Attribute attribute = null; | ||||
| while( true ) | while( true ) | ||||
| @@ -257,11 +259,11 @@ public class Section | |||||
| // continuation line | // continuation line | ||||
| if( attribute == null ) | if( attribute == null ) | ||||
| { | { | ||||
| if( name != null ) | |||||
| if( m_name != null ) | |||||
| { | { | ||||
| // a continuation on the first line is a continuation of the name - concatenate | // a continuation on the first line is a continuation of the name - concatenate | ||||
| // this line and the name | // this line and the name | ||||
| name += line.substring( 1 ); | |||||
| m_name += line.substring( 1 ); | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| @@ -292,7 +294,7 @@ public class Section | |||||
| */ | */ | ||||
| public void removeAttribute( String attributeName ) | public void removeAttribute( String attributeName ) | ||||
| { | { | ||||
| attributes.remove( attributeName.toLowerCase() ); | |||||
| m_attributes.remove( attributeName.toLowerCase() ); | |||||
| } | } | ||||
| /** | /** | ||||
| @@ -304,12 +306,12 @@ public class Section | |||||
| public void write( PrintWriter writer ) | public void write( PrintWriter writer ) | ||||
| throws IOException | throws IOException | ||||
| { | { | ||||
| if( name != null ) | |||||
| if( m_name != null ) | |||||
| { | { | ||||
| Attribute nameAttr = new Attribute( Manifest.ATTRIBUTE_NAME, name ); | |||||
| Attribute nameAttr = new Attribute( ManifestUtil.ATTRIBUTE_NAME, m_name ); | |||||
| ManifestUtil.write( nameAttr, writer ); | ManifestUtil.write( nameAttr, writer ); | ||||
| } | } | ||||
| for( Enumeration e = attributes.elements(); e.hasMoreElements(); ) | |||||
| for( Enumeration e = m_attributes.elements(); e.hasMoreElements(); ) | |||||
| { | { | ||||
| Object object = e.nextElement(); | Object object = e.nextElement(); | ||||
| if( object instanceof Attribute ) | if( object instanceof Attribute ) | ||||
| @@ -18,12 +18,12 @@ import java.io.OutputStreamWriter; | |||||
| import java.io.PrintWriter; | import java.io.PrintWriter; | ||||
| import java.io.Reader; | import java.io.Reader; | ||||
| import java.util.Enumeration; | import java.util.Enumeration; | ||||
| import java.util.Iterator; | |||||
| import java.util.zip.ZipFile; | import java.util.zip.ZipFile; | ||||
| import org.apache.aut.zip.ZipOutputStream; | import org.apache.aut.zip.ZipOutputStream; | ||||
| import org.apache.myrmidon.api.TaskException; | import org.apache.myrmidon.api.TaskException; | ||||
| import org.apache.tools.ant.taskdefs.manifest.Manifest; | import org.apache.tools.ant.taskdefs.manifest.Manifest; | ||||
| import org.apache.tools.ant.taskdefs.manifest.ManifestException; | import org.apache.tools.ant.taskdefs.manifest.ManifestException; | ||||
| import org.apache.tools.ant.taskdefs.manifest.ManifestUtil; | |||||
| import org.apache.tools.ant.types.FileScanner; | import org.apache.tools.ant.types.FileScanner; | ||||
| /** | /** | ||||
| @@ -89,10 +89,10 @@ public class Jar | |||||
| try | try | ||||
| { | { | ||||
| r = new FileReader( manifestFile ); | r = new FileReader( manifestFile ); | ||||
| Manifest newManifest = new Manifest( r ); | |||||
| Manifest newManifest = ManifestUtil.buildManifest( r ); | |||||
| if( m_manifest == null ) | if( m_manifest == null ) | ||||
| { | { | ||||
| m_manifest = Manifest.getDefaultManifest(); | |||||
| m_manifest = ManifestUtil.getDefaultManifest(); | |||||
| } | } | ||||
| m_manifest.merge( newManifest ); | m_manifest.merge( newManifest ); | ||||
| } | } | ||||
| @@ -134,7 +134,7 @@ public class Jar | |||||
| { | { | ||||
| if( m_manifest == null ) | if( m_manifest == null ) | ||||
| { | { | ||||
| m_manifest = Manifest.getDefaultManifest(); | |||||
| m_manifest = ManifestUtil.getDefaultManifest(); | |||||
| } | } | ||||
| m_manifest.merge( newManifest ); | m_manifest.merge( newManifest ); | ||||
| buildFileManifest = true; | buildFileManifest = true; | ||||
| @@ -172,10 +172,10 @@ public class Jar | |||||
| getLogger().debug( "Updating jar since the current jar has no manifest" ); | getLogger().debug( "Updating jar since the current jar has no manifest" ); | ||||
| return false; | return false; | ||||
| } | } | ||||
| Manifest currentManifest = new Manifest( new InputStreamReader( theZipFile.getInputStream( entry ) ) ); | |||||
| Manifest currentManifest = ManifestUtil.buildManifest( new InputStreamReader( theZipFile.getInputStream( entry ) ) ); | |||||
| if( m_manifest == null ) | if( m_manifest == null ) | ||||
| { | { | ||||
| m_manifest = Manifest.getDefaultManifest(); | |||||
| m_manifest = ManifestUtil.getDefaultManifest(); | |||||
| } | } | ||||
| if( !currentManifest.equals( m_manifest ) ) | if( !currentManifest.equals( m_manifest ) ) | ||||
| { | { | ||||
| @@ -231,22 +231,25 @@ public class Jar | |||||
| { | { | ||||
| try | try | ||||
| { | { | ||||
| m_execManifest = Manifest.getDefaultManifest(); | |||||
| m_execManifest = ManifestUtil.getDefaultManifest(); | |||||
| if( m_manifest != null ) | if( m_manifest != null ) | ||||
| { | { | ||||
| m_execManifest.merge( m_manifest ); | m_execManifest.merge( m_manifest ); | ||||
| } | } | ||||
| /* | |||||
| for( Iterator e = m_execManifest.getWarnings(); e.hasNext(); ) | for( Iterator e = m_execManifest.getWarnings(); e.hasNext(); ) | ||||
| { | { | ||||
| getLogger().warn( "Manifest warning: " + (String)e.next() ); | getLogger().warn( "Manifest warning: " + (String)e.next() ); | ||||
| } | } | ||||
| */ | |||||
| zipDir( null, zOut, "META-INF/" ); | zipDir( null, zOut, "META-INF/" ); | ||||
| // time to write the manifest | // time to write the manifest | ||||
| ByteArrayOutputStream baos = new ByteArrayOutputStream(); | ByteArrayOutputStream baos = new ByteArrayOutputStream(); | ||||
| PrintWriter writer = new PrintWriter( baos ); | PrintWriter writer = new PrintWriter( baos ); | ||||
| m_execManifest.write( writer ); | |||||
| Manifest manifest = m_execManifest; | |||||
| ManifestUtil.write( manifest, writer ); | |||||
| writer.flush(); | writer.flush(); | ||||
| ByteArrayInputStream bais = new ByteArrayInputStream( baos.toByteArray() ); | ByteArrayInputStream bais = new ByteArrayInputStream( baos.toByteArray() ); | ||||
| @@ -375,11 +378,12 @@ public class Jar | |||||
| { | { | ||||
| if( m_execManifest == null ) | if( m_execManifest == null ) | ||||
| { | { | ||||
| m_execManifest = new Manifest( new InputStreamReader( is ) ); | |||||
| m_execManifest = ManifestUtil.buildManifest( new InputStreamReader( is ) ); | |||||
| } | } | ||||
| else if( isAddingNewFiles() ) | else if( isAddingNewFiles() ) | ||||
| { | { | ||||
| m_execManifest.merge( new Manifest( new InputStreamReader( is ) ) ); | |||||
| final Manifest other = ManifestUtil.buildManifest( new InputStreamReader( is ) ); | |||||
| m_execManifest.merge( other ); | |||||
| } | } | ||||
| } | } | ||||
| catch( ManifestException e ) | catch( ManifestException e ) | ||||
| @@ -9,6 +9,7 @@ package org.apache.tools.ant.taskdefs.manifest; | |||||
| import java.io.PrintWriter; | import java.io.PrintWriter; | ||||
| import java.io.IOException; | import java.io.IOException; | ||||
| import java.util.jar.Attributes; | |||||
| /** | /** | ||||
| * Class to hold manifest attributes | * Class to hold manifest attributes | ||||
| @@ -110,10 +111,11 @@ public class Attribute | |||||
| } | } | ||||
| final Attribute other = (Attribute)object; | final Attribute other = (Attribute)object; | ||||
| final String name = other.m_name; | |||||
| return | return | ||||
| ( null != m_name && null != other.m_name && | |||||
| m_name.toLowerCase().equals( other.m_name.toLowerCase() ) && | |||||
| m_value != null && m_value.equals( other.m_value ) ); | |||||
| ( null != m_name && null != name && | |||||
| m_name.toLowerCase().equals( name.toLowerCase() ) && | |||||
| null != m_value && m_value.equals( other.m_value ) ); | |||||
| } | } | ||||
| } | } | ||||
| @@ -7,23 +7,11 @@ | |||||
| */ | */ | ||||
| package org.apache.tools.ant.taskdefs.manifest; | package org.apache.tools.ant.taskdefs.manifest; | ||||
| import java.io.BufferedReader; | |||||
| import java.io.File; | |||||
| import java.io.FileReader; | |||||
| import java.io.FileWriter; | |||||
| import java.io.IOException; | |||||
| import java.io.InputStream; | |||||
| import java.io.InputStreamReader; | |||||
| import java.io.PrintWriter; | |||||
| import java.io.Reader; | |||||
| import java.io.StringWriter; | |||||
| import java.io.UnsupportedEncodingException; | |||||
| import java.util.ArrayList; | |||||
| import java.util.Collection; | |||||
| import java.util.Enumeration; | import java.util.Enumeration; | ||||
| import java.util.Hashtable; | import java.util.Hashtable; | ||||
| import java.util.Iterator; | import java.util.Iterator; | ||||
| import java.util.jar.Attributes; | |||||
| import org.apache.myrmidon.api.AbstractTask; | |||||
| import java.util.Set; | |||||
| import org.apache.myrmidon.api.TaskException; | import org.apache.myrmidon.api.TaskException; | ||||
| /** | /** | ||||
| @@ -35,42 +23,11 @@ import org.apache.myrmidon.api.TaskException; | |||||
| * @version $Revision$ $Date$ | * @version $Revision$ $Date$ | ||||
| */ | */ | ||||
| public class Manifest | public class Manifest | ||||
| extends AbstractTask | |||||
| { | { | ||||
| /** | |||||
| * The standard Signature Version header | |||||
| */ | |||||
| public final static String ATTRIBUTE_SIGNATURE_VERSION = Attributes.Name.SIGNATURE_VERSION.toString(); | |||||
| /** | |||||
| * 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; | |||||
| /** | /** | ||||
| * The version of this manifest | * The version of this manifest | ||||
| */ | */ | ||||
| private String m_manifestVersion = DEFAULT_MANIFEST_VERSION; | |||||
| private String m_manifestVersion = ManifestUtil.DEFAULT_MANIFEST_VERSION; | |||||
| /** | /** | ||||
| * The main section of this manifest | * The main section of this manifest | ||||
| @@ -82,211 +39,112 @@ public class Manifest | |||||
| */ | */ | ||||
| private Hashtable m_sections = new Hashtable(); | private Hashtable m_sections = new Hashtable(); | ||||
| private File m_manifestFile; | |||||
| private ManifestMode m_mode; | |||||
| /** | |||||
| * Construct an empty manifest | |||||
| */ | |||||
| public Manifest() | |||||
| throws TaskException | |||||
| public void setManifestVersion( final String manifestVersion ) | |||||
| { | { | ||||
| m_mode = new ManifestMode(); | |||||
| m_mode.setValue( "replace" ); | |||||
| m_manifestVersion = null; | |||||
| m_manifestVersion = manifestVersion; | |||||
| } | } | ||||
| /** | |||||
| * Read a manifest file from the given reader | |||||
| * | |||||
| * @param r Description of Parameter | |||||
| * @exception ManifestException Description of Exception | |||||
| * @exception IOException Description of Exception | |||||
| * @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, TaskException, IOException | |||||
| public void setMainSection( final Section mainSection ) | |||||
| { | { | ||||
| BufferedReader reader = new BufferedReader( r ); | |||||
| // This should be the manifest version | |||||
| String nextSectionName = m_mainSection.read( reader ); | |||||
| String readManifestVersion = m_mainSection.getAttributeValue( Attributes.Name.MANIFEST_VERSION.toString() ); | |||||
| if( readManifestVersion != null ) | |||||
| { | |||||
| m_manifestVersion = readManifestVersion; | |||||
| m_mainSection.removeAttribute( Attributes.Name.MANIFEST_VERSION.toString() ); | |||||
| } | |||||
| String line = null; | |||||
| while( ( line = reader.readLine() ) != null ) | |||||
| { | |||||
| if( line.length() == 0 ) | |||||
| { | |||||
| continue; | |||||
| } | |||||
| Section section = new Section(); | |||||
| if( nextSectionName == null ) | |||||
| { | |||||
| Attribute sectionName = ManifestUtil.buildAttribute( line ); | |||||
| if( !sectionName.getName().equalsIgnoreCase( ATTRIBUTE_NAME ) ) | |||||
| { | |||||
| throw new ManifestException( "Manifest sections should start with a \"" + 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 ); | |||||
| } | |||||
| m_mainSection = mainSection; | |||||
| } | |||||
| section.setName( nextSectionName ); | |||||
| nextSectionName = section.read( reader ); | |||||
| addSection( section ); | |||||
| } | |||||
| public void addAttribute( final Attribute attribute ) | |||||
| throws ManifestException | |||||
| { | |||||
| m_mainSection.addAttribute( attribute ); | |||||
| } | } | ||||
| /** | |||||
| * Construct a manifest from Ant's default manifest file. | |||||
| * | |||||
| * @return The DefaultManifest value | |||||
| * @exception TaskException Description of Exception | |||||
| */ | |||||
| public static Manifest getDefaultManifest() | |||||
| throws TaskException | |||||
| public void addSection( final Section section ) | |||||
| throws ManifestException | |||||
| { | { | ||||
| try | |||||
| { | |||||
| String s = "/org/apache/tools/ant/defaultManifest.mf"; | |||||
| InputStream in = Manifest.class.getResourceAsStream( s ); | |||||
| if( in == null ) | |||||
| { | |||||
| throw new TaskException( "Could not find default manifest: " + s ); | |||||
| } | |||||
| try | |||||
| { | |||||
| return new Manifest( new InputStreamReader( in, "ASCII" ) ); | |||||
| } | |||||
| catch( UnsupportedEncodingException e ) | |||||
| { | |||||
| return new Manifest( new InputStreamReader( in ) ); | |||||
| } | |||||
| } | |||||
| catch( ManifestException e ) | |||||
| { | |||||
| throw new TaskException( "Default manifest is invalid !!" ); | |||||
| } | |||||
| catch( IOException e ) | |||||
| if( section.getName() == null ) | |||||
| { | { | ||||
| throw new TaskException( "Unable to read default manifest", e ); | |||||
| final String message = "Sections must have a name"; | |||||
| throw new ManifestException( message ); | |||||
| } | } | ||||
| m_sections.put( section.getName().toLowerCase(), section ); | |||||
| } | } | ||||
| /** | |||||
| * The name of the manifest file to write (if used as a task). | |||||
| * | |||||
| * @param f The new File value | |||||
| */ | |||||
| public void setFile( File f ) | |||||
| public String[] getSectionNames( final Manifest other ) | |||||
| { | { | ||||
| m_manifestFile = f; | |||||
| final Set keys = other.m_sections.keySet(); | |||||
| return (String[])keys.toArray( new String[ keys.size() ] ); | |||||
| } | } | ||||
| /** | |||||
| * Shall we update or replace an existing manifest? | |||||
| * | |||||
| * @param m The new ManifestMode value | |||||
| */ | |||||
| public void setMode( ManifestMode m ) | |||||
| public String getManifestVersion() | |||||
| { | { | ||||
| m_mode = m; | |||||
| return m_manifestVersion; | |||||
| } | } | ||||
| /** | |||||
| * Get the warnings for this manifest. | |||||
| * | |||||
| * @return an enumeration of warning strings | |||||
| */ | |||||
| public Iterator getWarnings() | |||||
| public Section getMainSection() | |||||
| { | { | ||||
| ArrayList warnings = new ArrayList(); | |||||
| for( Iterator e2 = m_mainSection.getWarnings(); e2.hasNext(); ) | |||||
| { | |||||
| warnings.add( e2.next() ); | |||||
| } | |||||
| // create a vector and add in the warnings for all the sections | |||||
| for( Enumeration e = m_sections.elements(); e.hasMoreElements(); ) | |||||
| { | |||||
| Section section = (Section)e.nextElement(); | |||||
| for( Iterator e2 = section.getWarnings(); e2.hasNext(); ) | |||||
| { | |||||
| warnings.add( e2.next() ); | |||||
| } | |||||
| } | |||||
| return m_mainSection; | |||||
| } | |||||
| return warnings.iterator(); | |||||
| public Section getSection( final String name ) | |||||
| { | |||||
| return (Section)m_sections.get( name ); | |||||
| } | } | ||||
| public void addAttribute( final Attribute attribute ) | |||||
| throws ManifestException, TaskException | |||||
| public Section[] getSections() | |||||
| { | { | ||||
| m_mainSection.addAttribute( attribute ); | |||||
| final Collection sections = m_sections.values(); | |||||
| return (Section[])sections.toArray( new Section[ sections.size() ] ); | |||||
| } | } | ||||
| public void addSection( final Section section ) | |||||
| throws ManifestException, TaskException | |||||
| /** | |||||
| * Merge the contents of the given manifest into this manifest | |||||
| * | |||||
| * @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. | |||||
| */ | |||||
| public void merge( final Manifest other ) | |||||
| throws ManifestException | |||||
| { | { | ||||
| if( section.getName() == null ) | |||||
| if( other.m_manifestVersion != null ) | |||||
| { | { | ||||
| throw new TaskException( "Sections must have a name" ); | |||||
| m_manifestVersion = other.m_manifestVersion; | |||||
| } | } | ||||
| m_sections.put( section.getName().toLowerCase(), section ); | |||||
| m_mainSection.merge( other.m_mainSection ); | |||||
| mergeSections( other ); | |||||
| } | } | ||||
| public boolean equals( Object rhs ) | |||||
| public boolean equals( final Object object ) | |||||
| { | { | ||||
| if( !( rhs instanceof Manifest ) ) | |||||
| if( !( object instanceof Manifest ) ) | |||||
| { | { | ||||
| return false; | return false; | ||||
| } | } | ||||
| Manifest rhsManifest = (Manifest)rhs; | |||||
| if( m_manifestVersion == null ) | |||||
| final Manifest other = (Manifest)object; | |||||
| if( m_manifestVersion == null && other.m_manifestVersion != null ) | |||||
| { | { | ||||
| if( rhsManifest.m_manifestVersion != null ) | |||||
| { | |||||
| return false; | |||||
| } | |||||
| return false; | |||||
| } | } | ||||
| else if( !m_manifestVersion.equals( rhsManifest.m_manifestVersion ) ) | |||||
| else if( !m_manifestVersion.equals( other.m_manifestVersion ) ) | |||||
| { | { | ||||
| return false; | return false; | ||||
| } | } | ||||
| if( m_sections.size() != rhsManifest.m_sections.size() ) | |||||
| if( m_sections.size() != other.m_sections.size() ) | |||||
| { | { | ||||
| return false; | return false; | ||||
| } | } | ||||
| if( !m_mainSection.equals( rhsManifest.m_mainSection ) ) | |||||
| if( !m_mainSection.equals( other.m_mainSection ) ) | |||||
| { | { | ||||
| return false; | return false; | ||||
| } | } | ||||
| for( Enumeration e = m_sections.elements(); e.hasMoreElements(); ) | |||||
| final Iterator e = m_sections.values().iterator(); | |||||
| while( e.hasNext() ) | |||||
| { | { | ||||
| Section section = (Section)e.nextElement(); | |||||
| Section rhsSection = (Section)rhsManifest.m_sections.get( section.getName().toLowerCase() ); | |||||
| if( !section.equals( rhsSection ) ) | |||||
| final Section section = (Section)e.next(); | |||||
| final String key = section.getName().toLowerCase(); | |||||
| final Section otherSection = (Section)other.m_sections.get( key ); | |||||
| if( !section.equals( otherSection ) ) | |||||
| { | { | ||||
| return false; | return false; | ||||
| } | } | ||||
| @@ -295,168 +153,23 @@ public class Manifest | |||||
| return true; | return true; | ||||
| } | } | ||||
| /** | |||||
| * Create or update the Manifest when used as a task. | |||||
| * | |||||
| * @exception TaskException Description of Exception | |||||
| */ | |||||
| public void execute() | |||||
| throws TaskException | |||||
| { | |||||
| if( m_manifestFile == null ) | |||||
| { | |||||
| throw new TaskException( "the file attribute is required" ); | |||||
| } | |||||
| Manifest toWrite = getDefaultManifest(); | |||||
| if( m_mode.getValue().equals( "update" ) && m_manifestFile.exists() ) | |||||
| { | |||||
| FileReader f = null; | |||||
| try | |||||
| { | |||||
| f = new FileReader( m_manifestFile ); | |||||
| toWrite.merge( new Manifest( f ) ); | |||||
| } | |||||
| catch( ManifestException m ) | |||||
| { | |||||
| throw new TaskException( "Existing manifest " + m_manifestFile | |||||
| + " is invalid", m ); | |||||
| } | |||||
| catch( IOException e ) | |||||
| { | |||||
| throw new | |||||
| TaskException( "Failed to read " + m_manifestFile, e ); | |||||
| } | |||||
| finally | |||||
| { | |||||
| if( f != null ) | |||||
| { | |||||
| try | |||||
| { | |||||
| f.close(); | |||||
| } | |||||
| catch( IOException e ) | |||||
| { | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| try | |||||
| { | |||||
| toWrite.merge( this ); | |||||
| } | |||||
| catch( ManifestException m ) | |||||
| { | |||||
| throw new TaskException( "Manifest is invalid", m ); | |||||
| } | |||||
| PrintWriter w = null; | |||||
| try | |||||
| { | |||||
| w = new PrintWriter( new FileWriter( m_manifestFile ) ); | |||||
| toWrite.write( w ); | |||||
| } | |||||
| catch( IOException e ) | |||||
| { | |||||
| throw new TaskException( "Failed to write " + m_manifestFile, e ); | |||||
| } | |||||
| finally | |||||
| { | |||||
| if( w != null ) | |||||
| { | |||||
| w.close(); | |||||
| } | |||||
| } | |||||
| } | |||||
| /** | |||||
| * Merge the contents of the given manifest into this manifest | |||||
| * | |||||
| * @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. | |||||
| */ | |||||
| public void merge( Manifest other ) | |||||
| private void mergeSections( final Manifest other ) | |||||
| throws ManifestException | throws ManifestException | ||||
| { | { | ||||
| if( other.m_manifestVersion != null ) | |||||
| { | |||||
| m_manifestVersion = other.m_manifestVersion; | |||||
| } | |||||
| m_mainSection.merge( other.m_mainSection ); | |||||
| for( Enumeration e = other.m_sections.keys(); e.hasMoreElements(); ) | |||||
| final String[] sections = getSectionNames( other ); | |||||
| for( int i = 0; i < sections.length; i++ ) | |||||
| { | { | ||||
| String sectionName = (String)e.nextElement(); | |||||
| Section ourSection = (Section)m_sections.get( sectionName ); | |||||
| Section otherSection = (Section)other.m_sections.get( sectionName ); | |||||
| if( ourSection == null ) | |||||
| final String sectionName = sections[ i ]; | |||||
| final Section section = getSection( sectionName ); | |||||
| final Section otherSection = other.getSection( sectionName ); | |||||
| if( section == null ) | |||||
| { | { | ||||
| m_sections.put( sectionName.toLowerCase(), otherSection ); | m_sections.put( sectionName.toLowerCase(), otherSection ); | ||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| ourSection.merge( otherSection ); | |||||
| section.merge( otherSection ); | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /** | |||||
| * Convert the manifest to its string representation | |||||
| * | |||||
| * @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( Exception e ) | |||||
| { | |||||
| return null; | |||||
| } | |||||
| return sw.toString(); | |||||
| } | |||||
| /** | |||||
| * 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 void write( PrintWriter writer ) | |||||
| throws IOException, TaskException | |||||
| { | |||||
| writer.println( Attributes.Name.MANIFEST_VERSION + ": " + m_manifestVersion ); | |||||
| String signatureVersion = m_mainSection.getAttributeValue( ATTRIBUTE_SIGNATURE_VERSION ); | |||||
| if( signatureVersion != null ) | |||||
| { | |||||
| writer.println( ATTRIBUTE_SIGNATURE_VERSION + ": " + signatureVersion ); | |||||
| m_mainSection.removeAttribute( ATTRIBUTE_SIGNATURE_VERSION ); | |||||
| } | |||||
| m_mainSection.write( writer ); | |||||
| if( signatureVersion != null ) | |||||
| { | |||||
| try | |||||
| { | |||||
| m_mainSection.addAttribute( new Attribute( ATTRIBUTE_SIGNATURE_VERSION, signatureVersion ) ); | |||||
| } | |||||
| catch( ManifestException e ) | |||||
| { | |||||
| // shouldn't happen - ignore | |||||
| } | |||||
| } | |||||
| for( Enumeration e = m_sections.elements(); e.hasMoreElements(); ) | |||||
| { | |||||
| Section section = (Section)e.nextElement(); | |||||
| section.write( writer ); | |||||
| } | |||||
| } | |||||
| } | } | ||||
| @@ -0,0 +1,196 @@ | |||||
| /* | |||||
| * 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.File; | |||||
| import java.io.FileReader; | |||||
| import java.io.FileWriter; | |||||
| import java.io.IOException; | |||||
| import java.io.PrintWriter; | |||||
| import java.util.ArrayList; | |||||
| import java.util.Iterator; | |||||
| import org.apache.avalon.excalibur.io.IOUtil; | |||||
| import org.apache.myrmidon.api.AbstractTask; | |||||
| import org.apache.myrmidon.api.TaskException; | |||||
| /** | |||||
| * Class to manage Manifest information | |||||
| * | |||||
| * @author <a href="mailto:peter@apache.org">Peter Donald</a> | |||||
| * @author <a href="mailto:conor@apache.org">Conor MacNeill</a> | |||||
| * @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a> | |||||
| * @version $Revision$ $Date$ | |||||
| */ | |||||
| public class ManifestTask | |||||
| extends AbstractTask | |||||
| { | |||||
| private File m_destFile; | |||||
| private ManifestMode m_mode; | |||||
| private Manifest m_manifest = new Manifest(); | |||||
| /** | |||||
| * Construct an empty manifest | |||||
| */ | |||||
| public ManifestTask() | |||||
| throws TaskException | |||||
| { | |||||
| m_mode = new ManifestMode(); | |||||
| m_mode.setValue( "replace" ); | |||||
| } | |||||
| /** | |||||
| * The name of the manifest file to write. | |||||
| */ | |||||
| public void setDestFile( final File destFile ) | |||||
| { | |||||
| m_destFile = destFile; | |||||
| } | |||||
| /** | |||||
| * Shall we update or replace an existing manifest? | |||||
| */ | |||||
| public void setMode( final ManifestMode mode ) | |||||
| { | |||||
| m_mode = mode; | |||||
| } | |||||
| public void setManifestVersion( String manifestVersion ) | |||||
| { | |||||
| m_manifest.setManifestVersion( manifestVersion ); | |||||
| } | |||||
| public void addMainSection( Section mainSection ) | |||||
| throws Exception | |||||
| { | |||||
| m_manifest.setMainSection( mainSection ); | |||||
| } | |||||
| /** | |||||
| * Get the warnings for this manifest. | |||||
| * | |||||
| * @return an enumeration of warning strings | |||||
| */ | |||||
| public Iterator getWarnings() | |||||
| { | |||||
| ArrayList warnings = new ArrayList(); | |||||
| for( Iterator e2 = m_manifest.getMainSection().getWarnings(); e2.hasNext(); ) | |||||
| { | |||||
| warnings.add( e2.next() ); | |||||
| } | |||||
| final Section[] sections = m_manifest.getSections(); | |||||
| for( int i = 0; i < sections.length; i++ ) | |||||
| { | |||||
| final Section section = sections[ i ]; | |||||
| for( Iterator e2 = section.getWarnings(); e2.hasNext(); ) | |||||
| { | |||||
| warnings.add( e2.next() ); | |||||
| } | |||||
| } | |||||
| return warnings.iterator(); | |||||
| } | |||||
| public void addAttribute( final Attribute attribute ) | |||||
| throws ManifestException, TaskException | |||||
| { | |||||
| m_manifest.addAttribute( attribute ); | |||||
| } | |||||
| public void addSection( final Section section ) | |||||
| throws TaskException | |||||
| { | |||||
| try | |||||
| { | |||||
| m_manifest.addSection( section ); | |||||
| } | |||||
| catch( final ManifestException me ) | |||||
| { | |||||
| throw new TaskException( me.getMessage(), me ); | |||||
| } | |||||
| } | |||||
| /** | |||||
| * Create or update the Manifest when used as a task. | |||||
| * | |||||
| * @exception TaskException Description of Exception | |||||
| */ | |||||
| public void execute() | |||||
| throws TaskException | |||||
| { | |||||
| if( null == m_destFile ) | |||||
| { | |||||
| throw new TaskException( "the file attribute is required" ); | |||||
| } | |||||
| Manifest toWrite = getDefaultManifest(); | |||||
| if( m_mode.getValue().equals( "update" ) && m_destFile.exists() ) | |||||
| { | |||||
| FileReader f = null; | |||||
| try | |||||
| { | |||||
| f = new FileReader( m_destFile ); | |||||
| final Manifest other = ManifestUtil.buildManifest( f ); | |||||
| toWrite.merge( other ); | |||||
| } | |||||
| catch( ManifestException m ) | |||||
| { | |||||
| throw new TaskException( "Existing manifest " + m_destFile | |||||
| + " is invalid", m ); | |||||
| } | |||||
| catch( IOException e ) | |||||
| { | |||||
| throw new | |||||
| TaskException( "Failed to read " + m_destFile, e ); | |||||
| } | |||||
| finally | |||||
| { | |||||
| IOUtil.shutdownReader( f ); | |||||
| } | |||||
| } | |||||
| try | |||||
| { | |||||
| toWrite.merge( m_manifest ); | |||||
| } | |||||
| catch( ManifestException m ) | |||||
| { | |||||
| throw new TaskException( "Manifest is invalid", m ); | |||||
| } | |||||
| PrintWriter w = null; | |||||
| try | |||||
| { | |||||
| w = new PrintWriter( new FileWriter( m_destFile ) ); | |||||
| ManifestUtil.write( toWrite, w ); | |||||
| } | |||||
| catch( IOException e ) | |||||
| { | |||||
| throw new TaskException( "Failed to write " + m_destFile, e ); | |||||
| } | |||||
| finally | |||||
| { | |||||
| IOUtil.shutdownWriter( w ); | |||||
| } | |||||
| } | |||||
| private Manifest getDefaultManifest() | |||||
| throws TaskException | |||||
| { | |||||
| try | |||||
| { | |||||
| return ManifestUtil.getDefaultManifest(); | |||||
| } | |||||
| catch( final ManifestException me ) | |||||
| { | |||||
| throw new TaskException( me.getMessage(), me ); | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -8,7 +8,14 @@ | |||||
| package org.apache.tools.ant.taskdefs.manifest; | package org.apache.tools.ant.taskdefs.manifest; | ||||
| import java.io.IOException; | import java.io.IOException; | ||||
| import java.io.InputStream; | |||||
| import java.io.InputStreamReader; | |||||
| import java.io.PrintWriter; | import java.io.PrintWriter; | ||||
| import java.io.Reader; | |||||
| import java.io.UnsupportedEncodingException; | |||||
| import java.io.BufferedReader; | |||||
| import java.util.jar.Attributes; | |||||
| import org.apache.myrmidon.api.TaskException; | |||||
| /** | /** | ||||
| * Utility methods for manifest stuff. | * Utility methods for manifest stuff. | ||||
| @@ -20,6 +27,27 @@ import java.io.PrintWriter; | |||||
| */ | */ | ||||
| public final class ManifestUtil | 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 ) | public static Attribute buildAttribute( final String line ) | ||||
| throws ManifestException | throws ManifestException | ||||
| { | { | ||||
| @@ -28,6 +56,100 @@ public final class ManifestUtil | |||||
| return attribute; | 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 | * Parse a line into name and value pairs | ||||
| * | * | ||||
| @@ -56,12 +178,12 @@ public final class ManifestUtil | |||||
| final String name = attribute.getName(); | final String name = attribute.getName(); | ||||
| final String value = attribute.getValue(); | final String value = attribute.getValue(); | ||||
| String line = name + ": " + value; | String line = name + ": " + value; | ||||
| while( line.getBytes().length > Manifest.MAX_LINE_LENGTH ) | |||||
| while( line.getBytes().length > MAX_LINE_LENGTH ) | |||||
| { | { | ||||
| // try to find a MAX_LINE_LENGTH byte section | // try to find a MAX_LINE_LENGTH byte section | ||||
| int breakIndex = Manifest.MAX_LINE_LENGTH; | |||||
| int breakIndex = MAX_LINE_LENGTH; | |||||
| String section = line.substring( 0, breakIndex ); | String section = line.substring( 0, breakIndex ); | ||||
| while( section.getBytes().length > Manifest.MAX_LINE_LENGTH && breakIndex > 0 ) | |||||
| while( section.getBytes().length > MAX_LINE_LENGTH && breakIndex > 0 ) | |||||
| { | { | ||||
| breakIndex--; | breakIndex--; | ||||
| section = line.substring( 0, breakIndex ); | section = line.substring( 0, breakIndex ); | ||||
| @@ -75,4 +197,44 @@ public final class ManifestUtil | |||||
| } | } | ||||
| writer.println( line ); | 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 ); | |||||
| } | |||||
| } | |||||
| } | } | ||||
| @@ -14,7 +14,6 @@ import java.util.ArrayList; | |||||
| import java.util.Enumeration; | import java.util.Enumeration; | ||||
| import java.util.Hashtable; | import java.util.Hashtable; | ||||
| import java.util.Iterator; | import java.util.Iterator; | ||||
| import org.apache.myrmidon.api.TaskException; | |||||
| /** | /** | ||||
| * Class to represent an individual section in the Manifest. A section | * Class to represent an individual section in the Manifest. A section | ||||
| @@ -28,26 +27,26 @@ import org.apache.myrmidon.api.TaskException; | |||||
| */ | */ | ||||
| public class Section | public class Section | ||||
| { | { | ||||
| private ArrayList warnings = new ArrayList(); | |||||
| private final ArrayList m_warnings = new ArrayList(); | |||||
| /** | /** | ||||
| * 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; | |||||
| private String m_name; | |||||
| /** | /** | ||||
| * The section's attributes. | * The section's attributes. | ||||
| */ | */ | ||||
| private Hashtable attributes = new Hashtable(); | |||||
| private final Hashtable m_attributes = new Hashtable(); | |||||
| /** | /** | ||||
| * Set the Section's name | * Set the Section's name | ||||
| * | * | ||||
| * @param name the section's name | * @param name the section's name | ||||
| */ | */ | ||||
| public void setName( String name ) | |||||
| public void setName( final String name ) | |||||
| { | { | ||||
| this.name = name; | |||||
| m_name = name; | |||||
| } | } | ||||
| /** | /** | ||||
| @@ -57,23 +56,26 @@ public class Section | |||||
| * @return the attribute's value or null if the attribute does not exist | * @return the attribute's value or null if the attribute does not exist | ||||
| * in the section | * in the section | ||||
| */ | */ | ||||
| public String getAttributeValue( String attributeName ) | |||||
| public String getAttributeValue( final String attributeName ) | |||||
| { | { | ||||
| Object attribute = attributes.get( attributeName.toLowerCase() ); | |||||
| if( attribute == null ) | |||||
| final Object attributeObject = m_attributes.get( attributeName.toLowerCase() ); | |||||
| if( null == attributeObject ) | |||||
| { | { | ||||
| return null; | return null; | ||||
| } | } | ||||
| if( attribute instanceof Attribute ) | |||||
| else if( attributeObject instanceof Attribute ) | |||||
| { | { | ||||
| return ( (Attribute)attribute ).getValue(); | |||||
| final Attribute attribute = (Attribute)attributeObject; | |||||
| return attribute.getValue(); | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| String value = ""; | String value = ""; | ||||
| for( Iterator e = ( (ArrayList)attribute ).iterator(); e.hasNext(); ) | |||||
| final ArrayList attributes = (ArrayList)attributeObject; | |||||
| Iterator e = attributes.iterator(); | |||||
| while( e.hasNext() ) | |||||
| { | { | ||||
| Attribute classpathAttribute = (Attribute)e.next(); | |||||
| final Attribute classpathAttribute = (Attribute)e.next(); | |||||
| value += classpathAttribute.getValue() + " "; | value += classpathAttribute.getValue() + " "; | ||||
| } | } | ||||
| return value.trim(); | return value.trim(); | ||||
| @@ -87,12 +89,12 @@ public class Section | |||||
| */ | */ | ||||
| public String getName() | public String getName() | ||||
| { | { | ||||
| return name; | |||||
| return m_name; | |||||
| } | } | ||||
| public Iterator getWarnings() | public Iterator getWarnings() | ||||
| { | { | ||||
| return warnings.iterator(); | |||||
| return m_warnings.iterator(); | |||||
| } | } | ||||
| /** | /** | ||||
| @@ -105,59 +107,59 @@ public class Section | |||||
| * section. | * section. | ||||
| */ | */ | ||||
| public String addAttributeAndCheck( Attribute attribute ) | public String addAttributeAndCheck( Attribute attribute ) | ||||
| throws ManifestException, TaskException | |||||
| throws ManifestException | |||||
| { | { | ||||
| if( attribute.getName() == null || attribute.getValue() == null ) | if( attribute.getName() == null || attribute.getValue() == null ) | ||||
| { | { | ||||
| throw new TaskException( "Attributes must have name and value" ); | |||||
| throw new ManifestException( "Attributes must have name and value" ); | |||||
| } | } | ||||
| if( attribute.getName().equalsIgnoreCase( Manifest.ATTRIBUTE_NAME ) ) | |||||
| if( attribute.getName().equalsIgnoreCase( ManifestUtil.ATTRIBUTE_NAME ) ) | |||||
| { | { | ||||
| warnings.add( "\"" + Manifest.ATTRIBUTE_NAME + "\" attributes should not occur in the " + | |||||
| m_warnings.add( "\"" + ManifestUtil.ATTRIBUTE_NAME + "\" attributes should not occur in the " + | |||||
| "main section and must be the first element in all " + | "main section and must be the first element in all " + | ||||
| "other sections: \"" + attribute.getName() + ": " + attribute.getValue() + "\"" ); | "other sections: \"" + attribute.getName() + ": " + attribute.getValue() + "\"" ); | ||||
| return attribute.getValue(); | return attribute.getValue(); | ||||
| } | } | ||||
| if( attribute.getName().toLowerCase().startsWith( Manifest.ATTRIBUTE_FROM.toLowerCase() ) ) | |||||
| if( attribute.getName().toLowerCase().startsWith( ManifestUtil.ATTRIBUTE_FROM.toLowerCase() ) ) | |||||
| { | { | ||||
| warnings.add( "Manifest attributes should not start with \"" + | |||||
| Manifest.ATTRIBUTE_FROM + "\" in \"" + attribute.getName() + ": " + attribute.getValue() + "\"" ); | |||||
| m_warnings.add( "Manifest attributes should not start with \"" + | |||||
| ManifestUtil.ATTRIBUTE_FROM + "\" in \"" + attribute.getName() + ": " + attribute.getValue() + "\"" ); | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| // classpath attributes go into a vector | // classpath attributes go into a vector | ||||
| String attributeName = attribute.getName().toLowerCase(); | String attributeName = attribute.getName().toLowerCase(); | ||||
| if( attributeName.equals( Manifest.ATTRIBUTE_CLASSPATH ) ) | |||||
| if( attributeName.equals( ManifestUtil.ATTRIBUTE_CLASSPATH ) ) | |||||
| { | { | ||||
| ArrayList classpathAttrs = (ArrayList)attributes.get( attributeName ); | |||||
| ArrayList classpathAttrs = (ArrayList)m_attributes.get( attributeName ); | |||||
| if( classpathAttrs == null ) | if( classpathAttrs == null ) | ||||
| { | { | ||||
| classpathAttrs = new ArrayList(); | classpathAttrs = new ArrayList(); | ||||
| attributes.put( attributeName, classpathAttrs ); | |||||
| m_attributes.put( attributeName, classpathAttrs ); | |||||
| } | } | ||||
| classpathAttrs.add( attribute ); | classpathAttrs.add( attribute ); | ||||
| } | } | ||||
| else if( attributes.containsKey( attributeName ) ) | |||||
| else if( m_attributes.containsKey( attributeName ) ) | |||||
| { | { | ||||
| throw new ManifestException( "The attribute \"" + attribute.getName() + "\" may not " + | throw new ManifestException( "The attribute \"" + attribute.getName() + "\" may not " + | ||||
| "occur more than once in the same section" ); | "occur more than once in the same section" ); | ||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| attributes.put( attributeName, attribute ); | |||||
| m_attributes.put( attributeName, attribute ); | |||||
| } | } | ||||
| } | } | ||||
| return null; | return null; | ||||
| } | } | ||||
| public void addAttribute( Attribute attribute ) | |||||
| throws ManifestException, TaskException | |||||
| public void addAttribute( final Attribute attribute ) | |||||
| throws ManifestException | |||||
| { | { | ||||
| String check = addAttributeAndCheck( attribute ); | String check = addAttributeAndCheck( attribute ); | ||||
| if( check != null ) | if( check != null ) | ||||
| { | { | ||||
| throw new TaskException( "Specify the section name using the \"name\" attribute of the <section> element rather " + | |||||
| throw new ManifestException( "Specify the section name using the \"name\" attribute of the <section> element rather " + | |||||
| "than using a \"Name\" manifest attribute" ); | "than using a \"Name\" manifest attribute" ); | ||||
| } | } | ||||
| } | } | ||||
| @@ -170,15 +172,15 @@ public class Section | |||||
| } | } | ||||
| Section rhsSection = (Section)rhs; | Section rhsSection = (Section)rhs; | ||||
| if( attributes.size() != rhsSection.attributes.size() ) | |||||
| if( m_attributes.size() != rhsSection.m_attributes.size() ) | |||||
| { | { | ||||
| return false; | return false; | ||||
| } | } | ||||
| for( Enumeration e = attributes.elements(); e.hasMoreElements(); ) | |||||
| for( Enumeration e = m_attributes.elements(); e.hasMoreElements(); ) | |||||
| { | { | ||||
| Attribute attribute = (Attribute)e.nextElement(); | Attribute attribute = (Attribute)e.nextElement(); | ||||
| Attribute rshAttribute = (Attribute)rhsSection.attributes.get( attribute.getName().toLowerCase() ); | |||||
| Attribute rshAttribute = (Attribute)rhsSection.m_attributes.get( attribute.getName().toLowerCase() ); | |||||
| if( !attribute.equals( rshAttribute ) ) | if( !attribute.equals( rshAttribute ) ) | ||||
| { | { | ||||
| return false; | return false; | ||||
| @@ -197,21 +199,21 @@ public class Section | |||||
| public void merge( Section section ) | public void merge( Section section ) | ||||
| throws ManifestException | throws ManifestException | ||||
| { | { | ||||
| if( name == null && section.getName() != null || | |||||
| name != null && !( name.equalsIgnoreCase( section.getName() ) ) ) | |||||
| if( m_name == null && section.getName() != null || | |||||
| m_name != null && !( m_name.equalsIgnoreCase( section.getName() ) ) ) | |||||
| { | { | ||||
| throw new ManifestException( "Unable to merge sections with different names" ); | throw new ManifestException( "Unable to merge sections with different names" ); | ||||
| } | } | ||||
| for( Enumeration e = section.attributes.keys(); e.hasMoreElements(); ) | |||||
| for( Enumeration e = section.m_attributes.keys(); e.hasMoreElements(); ) | |||||
| { | { | ||||
| String attributeName = (String)e.nextElement(); | String attributeName = (String)e.nextElement(); | ||||
| if( attributeName.equals( Manifest.ATTRIBUTE_CLASSPATH ) && | |||||
| attributes.containsKey( attributeName ) ) | |||||
| if( attributeName.equals( ManifestUtil.ATTRIBUTE_CLASSPATH ) && | |||||
| m_attributes.containsKey( attributeName ) ) | |||||
| { | { | ||||
| // classpath entries are vetors which are merged | // classpath entries are vetors which are merged | ||||
| ArrayList classpathAttrs = (ArrayList)section.attributes.get( attributeName ); | |||||
| ArrayList ourClasspathAttrs = (ArrayList)attributes.get( attributeName ); | |||||
| ArrayList classpathAttrs = (ArrayList)section.m_attributes.get( attributeName ); | |||||
| ArrayList ourClasspathAttrs = (ArrayList)m_attributes.get( attributeName ); | |||||
| for( Iterator e2 = classpathAttrs.iterator(); e2.hasNext(); ) | for( Iterator e2 = classpathAttrs.iterator(); e2.hasNext(); ) | ||||
| { | { | ||||
| ourClasspathAttrs.add( e2.next() ); | ourClasspathAttrs.add( e2.next() ); | ||||
| @@ -220,14 +222,14 @@ public class Section | |||||
| else | else | ||||
| { | { | ||||
| // the merge file always wins | // the merge file always wins | ||||
| attributes.put( attributeName, section.attributes.get( attributeName ) ); | |||||
| m_attributes.put( attributeName, section.m_attributes.get( attributeName ) ); | |||||
| } | } | ||||
| } | } | ||||
| // add in the warnings | // add in the warnings | ||||
| for( Iterator e = section.warnings.iterator(); e.hasNext(); ) | |||||
| for( Iterator e = section.m_warnings.iterator(); e.hasNext(); ) | |||||
| { | { | ||||
| warnings.add( e.next() ); | |||||
| m_warnings.add( e.next() ); | |||||
| } | } | ||||
| } | } | ||||
| @@ -242,7 +244,7 @@ public class Section | |||||
| * @throws IOException if the section cannot be read from the reader. | * @throws IOException if the section cannot be read from the reader. | ||||
| */ | */ | ||||
| public String read( BufferedReader reader ) | public String read( BufferedReader reader ) | ||||
| throws ManifestException, IOException, TaskException | |||||
| throws ManifestException, IOException | |||||
| { | { | ||||
| Attribute attribute = null; | Attribute attribute = null; | ||||
| while( true ) | while( true ) | ||||
| @@ -257,11 +259,11 @@ public class Section | |||||
| // continuation line | // continuation line | ||||
| if( attribute == null ) | if( attribute == null ) | ||||
| { | { | ||||
| if( name != null ) | |||||
| if( m_name != null ) | |||||
| { | { | ||||
| // a continuation on the first line is a continuation of the name - concatenate | // a continuation on the first line is a continuation of the name - concatenate | ||||
| // this line and the name | // this line and the name | ||||
| name += line.substring( 1 ); | |||||
| m_name += line.substring( 1 ); | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| @@ -292,7 +294,7 @@ public class Section | |||||
| */ | */ | ||||
| public void removeAttribute( String attributeName ) | public void removeAttribute( String attributeName ) | ||||
| { | { | ||||
| attributes.remove( attributeName.toLowerCase() ); | |||||
| m_attributes.remove( attributeName.toLowerCase() ); | |||||
| } | } | ||||
| /** | /** | ||||
| @@ -304,12 +306,12 @@ public class Section | |||||
| public void write( PrintWriter writer ) | public void write( PrintWriter writer ) | ||||
| throws IOException | throws IOException | ||||
| { | { | ||||
| if( name != null ) | |||||
| if( m_name != null ) | |||||
| { | { | ||||
| Attribute nameAttr = new Attribute( Manifest.ATTRIBUTE_NAME, name ); | |||||
| Attribute nameAttr = new Attribute( ManifestUtil.ATTRIBUTE_NAME, m_name ); | |||||
| ManifestUtil.write( nameAttr, writer ); | ManifestUtil.write( nameAttr, writer ); | ||||
| } | } | ||||
| for( Enumeration e = attributes.elements(); e.hasMoreElements(); ) | |||||
| for( Enumeration e = m_attributes.elements(); e.hasMoreElements(); ) | |||||
| { | { | ||||
| Object object = e.nextElement(); | Object object = e.nextElement(); | ||||
| if( object instanceof Attribute ) | if( object instanceof Attribute ) | ||||