git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@271689 13f79535-47bb-0310-9956-ffa450edef68master
@@ -22,8 +22,8 @@ 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.aut.manifest.ManifestException; | |||||
import org.apache.aut.manifest.ManifestUtil; | |||||
import org.apache.tools.ant.taskdefs.manifest.ManifestException; | |||||
import org.apache.tools.ant.taskdefs.manifest.ManifestUtil; | |||||
import org.apache.tools.ant.types.FileScanner; | import org.apache.tools.ant.types.FileScanner; | ||||
/** | /** | ||||
@@ -5,7 +5,7 @@ | |||||
* version 1.1, a copy of which has been included with this distribution in | * version 1.1, a copy of which has been included with this distribution in | ||||
* the LICENSE.txt file. | * the LICENSE.txt file. | ||||
*/ | */ | ||||
package org.apache.aut.manifest; | |||||
package org.apache.tools.ant.taskdefs.manifest; | |||||
/** | /** | ||||
* Class to hold manifest attributes | * Class to hold manifest attributes |
@@ -13,9 +13,6 @@ import java.util.Hashtable; | |||||
import java.util.Iterator; | import java.util.Iterator; | ||||
import java.util.Set; | import java.util.Set; | ||||
import org.apache.myrmidon.api.TaskException; | import org.apache.myrmidon.api.TaskException; | ||||
import org.apache.aut.manifest.Attribute; | |||||
import org.apache.aut.manifest.ManifestException; | |||||
import org.apache.aut.manifest.ManifestUtil; | |||||
/** | /** | ||||
* Class to manage Manifest information | * Class to manage Manifest information | ||||
@@ -5,7 +5,7 @@ | |||||
* version 1.1, a copy of which has been included with this distribution in | * version 1.1, a copy of which has been included with this distribution in | ||||
* the LICENSE.txt file. | * the LICENSE.txt file. | ||||
*/ | */ | ||||
package org.apache.aut.manifest; | |||||
package org.apache.tools.ant.taskdefs.manifest; | |||||
/** | /** | ||||
* ManifestException is thrown when there is a problem parsing, generating or | * ManifestException is thrown when there is a problem parsing, generating or |
@@ -17,9 +17,6 @@ import java.util.Iterator; | |||||
import org.apache.avalon.excalibur.io.IOUtil; | import org.apache.avalon.excalibur.io.IOUtil; | ||||
import org.apache.myrmidon.api.AbstractTask; | import org.apache.myrmidon.api.AbstractTask; | ||||
import org.apache.myrmidon.api.TaskException; | import org.apache.myrmidon.api.TaskException; | ||||
import org.apache.aut.manifest.Attribute; | |||||
import org.apache.aut.manifest.ManifestException; | |||||
import org.apache.aut.manifest.ManifestUtil; | |||||
/** | /** | ||||
* Class to manage Manifest information | * Class to manage Manifest information | ||||
@@ -5,7 +5,7 @@ | |||||
* version 1.1, a copy of which has been included with this distribution in | * version 1.1, a copy of which has been included with this distribution in | ||||
* the LICENSE.txt file. | * the LICENSE.txt file. | ||||
*/ | */ | ||||
package org.apache.aut.manifest; | |||||
package org.apache.tools.ant.taskdefs.manifest; | |||||
import java.io.BufferedReader; | import java.io.BufferedReader; | ||||
import java.io.IOException; | import java.io.IOException; | ||||
@@ -15,8 +15,6 @@ import java.io.PrintWriter; | |||||
import java.io.Reader; | import java.io.Reader; | ||||
import java.io.UnsupportedEncodingException; | import java.io.UnsupportedEncodingException; | ||||
import java.util.jar.Attributes; | import java.util.jar.Attributes; | ||||
import org.apache.tools.ant.taskdefs.manifest.Manifest; | |||||
import org.apache.tools.ant.taskdefs.manifest.Section; | |||||
/** | /** | ||||
* Utility methods for manifest stuff. | * Utility methods for manifest stuff. |
@@ -14,9 +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.aut.manifest.Attribute; | |||||
import org.apache.aut.manifest.ManifestException; | |||||
import org.apache.aut.manifest.ManifestUtil; | |||||
/** | /** | ||||
* Class to represent an individual section in the Manifest. A section | * Class to represent an individual section in the Manifest. A section | ||||
@@ -22,8 +22,8 @@ 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.aut.manifest.ManifestException; | |||||
import org.apache.aut.manifest.ManifestUtil; | |||||
import org.apache.tools.ant.taskdefs.manifest.ManifestException; | |||||
import org.apache.tools.ant.taskdefs.manifest.ManifestUtil; | |||||
import org.apache.tools.ant.types.FileScanner; | import org.apache.tools.ant.types.FileScanner; | ||||
/** | /** | ||||
@@ -0,0 +1,117 @@ | |||||
/* | |||||
* Copyright (C) The Apache Software Foundation. All rights reserved. | |||||
* | |||||
* This software is published under the terms of the Apache Software License | |||||
* version 1.1, a copy of which has been included with this distribution in | |||||
* the LICENSE.txt file. | |||||
*/ | |||||
package org.apache.tools.ant.taskdefs.manifest; | |||||
/** | |||||
* Class to hold manifest attributes | |||||
* | |||||
* @author <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 Attribute | |||||
{ | |||||
/** | |||||
* The attribute's name | |||||
*/ | |||||
private String m_name; | |||||
/** | |||||
* The attribute's value | |||||
*/ | |||||
private String m_value; | |||||
/** | |||||
* Construct an empty attribute | |||||
*/ | |||||
public Attribute() | |||||
{ | |||||
} | |||||
/** | |||||
* Construct a manifest by specifying its name and value | |||||
* | |||||
* @param name the attribute's name | |||||
* @param value the Attribute's value | |||||
*/ | |||||
public Attribute( final String name, final String value ) | |||||
{ | |||||
m_name = name; | |||||
m_value = value; | |||||
} | |||||
/** | |||||
* Set the Attribute's name | |||||
* | |||||
* @param name the attribute's name | |||||
*/ | |||||
public void setName( final String name ) | |||||
{ | |||||
m_name = name; | |||||
} | |||||
/** | |||||
* Set the Attribute's value | |||||
* | |||||
* @param value the attribute's value | |||||
*/ | |||||
public void setValue( final String value ) | |||||
{ | |||||
m_value = value; | |||||
} | |||||
/** | |||||
* Get the Attribute's name | |||||
* | |||||
* @return the attribute's name. | |||||
*/ | |||||
public String getName() | |||||
{ | |||||
return m_name; | |||||
} | |||||
/** | |||||
* Get the Attribute's value | |||||
* | |||||
* @return the attribute's value. | |||||
*/ | |||||
public String getValue() | |||||
{ | |||||
return m_value; | |||||
} | |||||
/** | |||||
* Add a continuation line from the Manifest file When lines are too | |||||
* long in a manifest, they are continued on the next line by starting | |||||
* with a space. This method adds the continuation data to the attribute | |||||
* value by skipping the first character. | |||||
* | |||||
* @param line The feature to be added to the Continuation attribute | |||||
*/ | |||||
public void addContinuation( final String line ) | |||||
{ | |||||
m_value += line.substring( 1 ); | |||||
} | |||||
public boolean equals( Object object ) | |||||
{ | |||||
if( !( object instanceof Attribute ) ) | |||||
{ | |||||
return false; | |||||
} | |||||
final Attribute other = (Attribute)object; | |||||
final String name = other.m_name; | |||||
return | |||||
( null != m_name && null != name && | |||||
m_name.toLowerCase().equals( name.toLowerCase() ) && | |||||
null != m_value && m_value.equals( other.m_value ) ); | |||||
} | |||||
} |
@@ -13,9 +13,6 @@ import java.util.Hashtable; | |||||
import java.util.Iterator; | import java.util.Iterator; | ||||
import java.util.Set; | import java.util.Set; | ||||
import org.apache.myrmidon.api.TaskException; | import org.apache.myrmidon.api.TaskException; | ||||
import org.apache.aut.manifest.Attribute; | |||||
import org.apache.aut.manifest.ManifestException; | |||||
import org.apache.aut.manifest.ManifestUtil; | |||||
/** | /** | ||||
* Class to manage Manifest information | * Class to manage Manifest information | ||||
@@ -0,0 +1,64 @@ | |||||
/* | |||||
* Copyright (C) The Apache Software Foundation. All rights reserved. | |||||
* | |||||
* This software is published under the terms of the Apache Software License | |||||
* version 1.1, a copy of which has been included with this distribution in | |||||
* the LICENSE.txt file. | |||||
*/ | |||||
package org.apache.tools.ant.taskdefs.manifest; | |||||
/** | |||||
* ManifestException is thrown when there is a problem parsing, generating or | |||||
* handling a Manifest. | |||||
* | |||||
* @author <a href="mailto:peter@apache.org">Peter Donald</a> | |||||
* @version $Revision$ $Date$ | |||||
*/ | |||||
public class ManifestException | |||||
extends Exception | |||||
{ | |||||
/** | |||||
* The Throwable that caused this exception to be thrown. | |||||
*/ | |||||
private final Throwable m_throwable; | |||||
/** | |||||
* Basic constructor for exception that does not specify a message | |||||
*/ | |||||
public ManifestException() | |||||
{ | |||||
this( "", null ); | |||||
} | |||||
/** | |||||
* Basic constructor with a message | |||||
* | |||||
* @param message the message | |||||
*/ | |||||
public ManifestException( final String message ) | |||||
{ | |||||
this( message, null ); | |||||
} | |||||
/** | |||||
* Constructor that builds cascade so that other exception information can be retained. | |||||
* | |||||
* @param message the message | |||||
* @param throwable the throwable | |||||
*/ | |||||
public ManifestException( final String message, final Throwable throwable ) | |||||
{ | |||||
super( message ); | |||||
m_throwable = throwable; | |||||
} | |||||
/** | |||||
* Retrieve root cause of the exception. | |||||
* | |||||
* @return the root cause | |||||
*/ | |||||
public final Throwable getCause() | |||||
{ | |||||
return m_throwable; | |||||
} | |||||
} |
@@ -17,9 +17,6 @@ import java.util.Iterator; | |||||
import org.apache.avalon.excalibur.io.IOUtil; | import org.apache.avalon.excalibur.io.IOUtil; | ||||
import org.apache.myrmidon.api.AbstractTask; | import org.apache.myrmidon.api.AbstractTask; | ||||
import org.apache.myrmidon.api.TaskException; | import org.apache.myrmidon.api.TaskException; | ||||
import org.apache.aut.manifest.Attribute; | |||||
import org.apache.aut.manifest.ManifestException; | |||||
import org.apache.aut.manifest.ManifestUtil; | |||||
/** | /** | ||||
* Class to manage Manifest information | * Class to manage Manifest information | ||||
@@ -0,0 +1,239 @@ | |||||
/* | |||||
* Copyright (C) The Apache Software Foundation. All rights reserved. | |||||
* | |||||
* This software is published under the terms of the Apache Software License | |||||
* version 1.1, a copy of which has been included with this distribution in | |||||
* the LICENSE.txt file. | |||||
*/ | |||||
package org.apache.tools.ant.taskdefs.manifest; | |||||
import java.io.BufferedReader; | |||||
import java.io.IOException; | |||||
import java.io.InputStream; | |||||
import java.io.InputStreamReader; | |||||
import java.io.PrintWriter; | |||||
import java.io.Reader; | |||||
import java.io.UnsupportedEncodingException; | |||||
import java.util.jar.Attributes; | |||||
/** | |||||
* Utility methods for manifest stuff. | |||||
* | |||||
* @author <a href="mailto:conor@apache.org">Conor MacNeill</a> | |||||
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a> | |||||
* @author <a href="mailto:peter@apache.org">Peter Donald</a> | |||||
* @version $Revision$ $Date$ | |||||
*/ | |||||
public final class ManifestUtil | |||||
{ | |||||
/** | |||||
* The Name Attribute is the first in a named section | |||||
*/ | |||||
public final static String ATTRIBUTE_NAME = "Name"; | |||||
/** | |||||
* The From Header is disallowed in a Manifest | |||||
*/ | |||||
public final static String ATTRIBUTE_FROM = "From"; | |||||
/** | |||||
* The Class-Path Header is special - it can be duplicated | |||||
*/ | |||||
public final static String ATTRIBUTE_CLASSPATH = Attributes.Name.CLASS_PATH.toString(); | |||||
/** | |||||
* Default Manifest version if one is not specified | |||||
*/ | |||||
public final static String DEFAULT_MANIFEST_VERSION = "1.0"; | |||||
/** | |||||
* The max length of a line in a Manifest | |||||
*/ | |||||
public final static int MAX_LINE_LENGTH = 70; | |||||
public static Attribute buildAttribute( final String line ) | |||||
throws ManifestException | |||||
{ | |||||
final Attribute attribute = new Attribute(); | |||||
parse( attribute, line ); | |||||
return attribute; | |||||
} | |||||
public static Manifest buildManifest( final Reader reader ) | |||||
throws ManifestException, IOException | |||||
{ | |||||
final Manifest manifest = new Manifest(); | |||||
BufferedReader bufferedReader = new BufferedReader( reader ); | |||||
// This should be the manifest version | |||||
final Section mainSection = manifest.getMainSection(); | |||||
String nextSectionName = mainSection.read( bufferedReader ); | |||||
final String readManifestVersion = | |||||
mainSection.getAttributeValue( Attributes.Name.MANIFEST_VERSION.toString() ); | |||||
if( readManifestVersion != null ) | |||||
{ | |||||
manifest.setManifestVersion( readManifestVersion ); | |||||
mainSection.removeAttribute( Attributes.Name.MANIFEST_VERSION.toString() ); | |||||
} | |||||
String line = null; | |||||
while( ( line = bufferedReader.readLine() ) != null ) | |||||
{ | |||||
if( line.length() == 0 ) | |||||
{ | |||||
continue; | |||||
} | |||||
Section section = new Section(); | |||||
if( nextSectionName == null ) | |||||
{ | |||||
Attribute sectionName = ManifestUtil.buildAttribute( line ); | |||||
if( !sectionName.getName().equalsIgnoreCase( ManifestUtil.ATTRIBUTE_NAME ) ) | |||||
{ | |||||
throw new ManifestException( "Manifest sections should start with a \"" + ManifestUtil.ATTRIBUTE_NAME + | |||||
"\" attribute and not \"" + sectionName.getName() + "\"" ); | |||||
} | |||||
nextSectionName = sectionName.getValue(); | |||||
} | |||||
else | |||||
{ | |||||
// we have already started reading this section | |||||
// this line is the first attribute. set it and then let the normal | |||||
// read handle the rest | |||||
Attribute firstAttribute = ManifestUtil.buildAttribute( line ); | |||||
section.addAttributeAndCheck( firstAttribute ); | |||||
} | |||||
section.setName( nextSectionName ); | |||||
nextSectionName = section.read( bufferedReader ); | |||||
manifest.addSection( section ); | |||||
} | |||||
return manifest; | |||||
} | |||||
/** | |||||
* Construct a manifest from Ant's default manifest file. | |||||
*/ | |||||
public static Manifest getDefaultManifest() | |||||
throws ManifestException | |||||
{ | |||||
try | |||||
{ | |||||
final InputStream input = getInputStream(); | |||||
final InputStreamReader reader = getReader( input ); | |||||
return buildManifest( reader ); | |||||
} | |||||
catch( final IOException ioe ) | |||||
{ | |||||
throw new ManifestException( "Unable to read default manifest", ioe ); | |||||
} | |||||
} | |||||
private static InputStream getInputStream() | |||||
throws ManifestException | |||||
{ | |||||
final String location = "default.mf"; | |||||
final InputStream input = ManifestUtil.class.getResourceAsStream( location ); | |||||
if( null == input ) | |||||
{ | |||||
throw new ManifestException( "Could not find default manifest: " + location ); | |||||
} | |||||
return input; | |||||
} | |||||
private static InputStreamReader getReader( final InputStream input ) | |||||
{ | |||||
try | |||||
{ | |||||
return new InputStreamReader( input, "ASCII" ); | |||||
} | |||||
catch( final UnsupportedEncodingException uee ) | |||||
{ | |||||
return new InputStreamReader( input ); | |||||
} | |||||
} | |||||
/** | |||||
* Parse a line into name and value pairs | |||||
* | |||||
* @param line the line to be parsed | |||||
* @throws ManifestException if the line does not contain a colon | |||||
* separating the name and value | |||||
*/ | |||||
public static void parse( final Attribute attribute, final String line ) | |||||
throws ManifestException | |||||
{ | |||||
final int index = line.indexOf( ": " ); | |||||
if( index == -1 ) | |||||
{ | |||||
throw new ManifestException( "Manifest line \"" + line + "\" is not valid as it does not " + | |||||
"contain a name and a value separated by ': ' " ); | |||||
} | |||||
final String name = line.substring( 0, index ); | |||||
final String value = line.substring( index + 2 ); | |||||
attribute.setName( name ); | |||||
attribute.setValue( value ); | |||||
} | |||||
public static void write( final Attribute attribute, final PrintWriter writer ) | |||||
throws IOException | |||||
{ | |||||
final String name = attribute.getName(); | |||||
final String value = attribute.getValue(); | |||||
String line = name + ": " + value; | |||||
while( line.getBytes().length > MAX_LINE_LENGTH ) | |||||
{ | |||||
// try to find a MAX_LINE_LENGTH byte section | |||||
int breakIndex = MAX_LINE_LENGTH; | |||||
String section = line.substring( 0, breakIndex ); | |||||
while( section.getBytes().length > MAX_LINE_LENGTH && breakIndex > 0 ) | |||||
{ | |||||
breakIndex--; | |||||
section = line.substring( 0, breakIndex ); | |||||
} | |||||
if( breakIndex == 0 ) | |||||
{ | |||||
throw new IOException( "Unable to write manifest line " + name + ": " + value ); | |||||
} | |||||
writer.println( section ); | |||||
line = " " + line.substring( breakIndex ); | |||||
} | |||||
writer.println( line ); | |||||
} | |||||
/** | |||||
* Write the manifest out to a print writer. | |||||
* | |||||
* @param writer the Writer to which the manifest is written | |||||
* @throws IOException if the manifest cannot be written | |||||
*/ | |||||
public static void write( Manifest manifest, PrintWriter writer ) | |||||
throws IOException | |||||
{ | |||||
final String sigVersionKey = Attributes.Name.SIGNATURE_VERSION.toString(); | |||||
writer.println( Attributes.Name.MANIFEST_VERSION + ": " + manifest.getManifestVersion() ); | |||||
final String signatureVersion = | |||||
manifest.getMainSection().getAttributeValue( sigVersionKey ); | |||||
if( signatureVersion != null ) | |||||
{ | |||||
writer.println( Attributes.Name.SIGNATURE_VERSION + ": " + signatureVersion ); | |||||
manifest.getMainSection().removeAttribute( sigVersionKey ); | |||||
} | |||||
manifest.getMainSection().write( writer ); | |||||
if( signatureVersion != null ) | |||||
{ | |||||
try | |||||
{ | |||||
manifest.getMainSection().addAttribute( new Attribute( sigVersionKey, signatureVersion ) ); | |||||
} | |||||
catch( ManifestException e ) | |||||
{ | |||||
// shouldn't happen - ignore | |||||
} | |||||
} | |||||
final Section[] sections = manifest.getSections(); | |||||
for( int i = 0; i < sections.length; i++ ) | |||||
{ | |||||
sections[ i ].write( writer ); | |||||
} | |||||
} | |||||
} |
@@ -14,9 +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.aut.manifest.Attribute; | |||||
import org.apache.aut.manifest.ManifestException; | |||||
import org.apache.aut.manifest.ManifestUtil; | |||||
/** | /** | ||||
* Class to represent an individual section in the Manifest. A section | * Class to represent an individual section in the Manifest. A section | ||||