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.myrmidon.api.TaskException; | |||
| import org.apache.tools.ant.taskdefs.manifest.Manifest; | |||
| import org.apache.aut.manifest.ManifestException; | |||
| import org.apache.aut.manifest.ManifestUtil; | |||
| import org.apache.tools.ant.taskdefs.manifest.ManifestException; | |||
| import org.apache.tools.ant.taskdefs.manifest.ManifestUtil; | |||
| import org.apache.tools.ant.types.FileScanner; | |||
| /** | |||
| @@ -5,7 +5,7 @@ | |||
| * version 1.1, a copy of which has been included with this distribution in | |||
| * the LICENSE.txt file. | |||
| */ | |||
| package org.apache.aut.manifest; | |||
| package org.apache.tools.ant.taskdefs.manifest; | |||
| /** | |||
| * Class to hold manifest attributes | |||
| @@ -13,9 +13,6 @@ import java.util.Hashtable; | |||
| import java.util.Iterator; | |||
| import java.util.Set; | |||
| import org.apache.myrmidon.api.TaskException; | |||
| import org.apache.aut.manifest.Attribute; | |||
| import org.apache.aut.manifest.ManifestException; | |||
| import org.apache.aut.manifest.ManifestUtil; | |||
| /** | |||
| * Class to manage Manifest information | |||
| @@ -5,7 +5,7 @@ | |||
| * version 1.1, a copy of which has been included with this distribution in | |||
| * the LICENSE.txt file. | |||
| */ | |||
| package org.apache.aut.manifest; | |||
| package org.apache.tools.ant.taskdefs.manifest; | |||
| /** | |||
| * ManifestException is thrown when there is a problem parsing, generating or | |||
| @@ -17,9 +17,6 @@ import java.util.Iterator; | |||
| import org.apache.avalon.excalibur.io.IOUtil; | |||
| import org.apache.myrmidon.api.AbstractTask; | |||
| import org.apache.myrmidon.api.TaskException; | |||
| import org.apache.aut.manifest.Attribute; | |||
| import org.apache.aut.manifest.ManifestException; | |||
| import org.apache.aut.manifest.ManifestUtil; | |||
| /** | |||
| * Class to manage Manifest information | |||
| @@ -5,7 +5,7 @@ | |||
| * version 1.1, a copy of which has been included with this distribution in | |||
| * the LICENSE.txt file. | |||
| */ | |||
| package org.apache.aut.manifest; | |||
| package org.apache.tools.ant.taskdefs.manifest; | |||
| import java.io.BufferedReader; | |||
| import java.io.IOException; | |||
| @@ -15,8 +15,6 @@ import java.io.PrintWriter; | |||
| import java.io.Reader; | |||
| import java.io.UnsupportedEncodingException; | |||
| import java.util.jar.Attributes; | |||
| import org.apache.tools.ant.taskdefs.manifest.Manifest; | |||
| import org.apache.tools.ant.taskdefs.manifest.Section; | |||
| /** | |||
| * Utility methods for manifest stuff. | |||
| @@ -14,9 +14,6 @@ import java.util.ArrayList; | |||
| import java.util.Enumeration; | |||
| import java.util.Hashtable; | |||
| import java.util.Iterator; | |||
| import org.apache.aut.manifest.Attribute; | |||
| import org.apache.aut.manifest.ManifestException; | |||
| import org.apache.aut.manifest.ManifestUtil; | |||
| /** | |||
| * Class to represent an individual section in the Manifest. A section | |||
| @@ -22,8 +22,8 @@ import java.util.zip.ZipFile; | |||
| import org.apache.aut.zip.ZipOutputStream; | |||
| import org.apache.myrmidon.api.TaskException; | |||
| import org.apache.tools.ant.taskdefs.manifest.Manifest; | |||
| import org.apache.aut.manifest.ManifestException; | |||
| import org.apache.aut.manifest.ManifestUtil; | |||
| import org.apache.tools.ant.taskdefs.manifest.ManifestException; | |||
| import org.apache.tools.ant.taskdefs.manifest.ManifestUtil; | |||
| import org.apache.tools.ant.types.FileScanner; | |||
| /** | |||
| @@ -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.Set; | |||
| import org.apache.myrmidon.api.TaskException; | |||
| import org.apache.aut.manifest.Attribute; | |||
| import org.apache.aut.manifest.ManifestException; | |||
| import org.apache.aut.manifest.ManifestUtil; | |||
| /** | |||
| * Class to manage Manifest information | |||
| @@ -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.myrmidon.api.AbstractTask; | |||
| import org.apache.myrmidon.api.TaskException; | |||
| import org.apache.aut.manifest.Attribute; | |||
| import org.apache.aut.manifest.ManifestException; | |||
| import org.apache.aut.manifest.ManifestUtil; | |||
| /** | |||
| * Class to manage Manifest information | |||
| @@ -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.Hashtable; | |||
| import java.util.Iterator; | |||
| import org.apache.aut.manifest.Attribute; | |||
| import org.apache.aut.manifest.ManifestException; | |||
| import org.apache.aut.manifest.ManifestUtil; | |||
| /** | |||
| * Class to represent an individual section in the Manifest. A section | |||