Browse Source

Started some massive refactoring of the Manifest classes so that eventually they can be completely decoupled from ant

git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@271240 13f79535-47bb-0310-9956-ffa450edef68
master
Peter Donald 23 years ago
parent
commit
78a7fbf3d9
12 changed files with 1000 additions and 842 deletions
  1. +14
    -10
      proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/archive/Jar.java
  2. +5
    -3
      proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/manifest/Attribute.java
  3. +68
    -355
      proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/manifest/Manifest.java
  4. +196
    -0
      proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/manifest/ManifestTask.java
  5. +165
    -3
      proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/manifest/ManifestUtil.java
  6. +52
    -50
      proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/manifest/Section.java
  7. +14
    -10
      proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/archive/Jar.java
  8. +5
    -3
      proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/manifest/Attribute.java
  9. +68
    -355
      proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/manifest/Manifest.java
  10. +196
    -0
      proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/manifest/ManifestTask.java
  11. +165
    -3
      proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/manifest/ManifestUtil.java
  12. +52
    -50
      proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/manifest/Section.java

+ 14
- 10
proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/archive/Jar.java View File

@@ -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 )


+ 5
- 3
proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/manifest/Attribute.java View File

@@ -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 ) );
} }


} }

+ 68
- 355
proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/manifest/Manifest.java View File

@@ -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 );
}
}

} }

+ 196
- 0
proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/manifest/ManifestTask.java View File

@@ -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 );
}
}
}

+ 165
- 3
proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/manifest/ManifestUtil.java View File

@@ -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 );
}
}
} }

+ 52
- 50
proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/manifest/Section.java View File

@@ -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 )


+ 14
- 10
proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/archive/Jar.java View File

@@ -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 )


+ 5
- 3
proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/manifest/Attribute.java View File

@@ -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 ) );
} }


} }

+ 68
- 355
proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/manifest/Manifest.java View File

@@ -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 );
}
}

} }

+ 196
- 0
proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/manifest/ManifestTask.java View File

@@ -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 );
}
}
}

+ 165
- 3
proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/manifest/ManifestUtil.java View File

@@ -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 );
}
}
} }

+ 52
- 50
proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/manifest/Section.java View File

@@ -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 )


Loading…
Cancel
Save