manifest file. PR: 5190 git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@270131 13f79535-47bb-0310-9956-ffa450edef68master
| @@ -89,7 +89,8 @@ Other changes: | |||
| * Added support for specifying CVS_RSH in the <cvs/> task | |||
| * New tasks bzip2 and bunzip2 to pack and unpack files using the | |||
| BZip2 alogrithm, replaceregexp, checksum, translate, waitfor, input | |||
| BZip2 alogrithm, replaceregexp, checksum, translate, waitfor, input, | |||
| manifest | |||
| * The attributes zipfile, jarfile, warfile and earfile (from the Zip, | |||
| Jar, War and Ear tasks) have been deprecated and superseded by a | |||
| @@ -0,0 +1,78 @@ | |||
| <html> | |||
| <head> | |||
| <meta http-equiv="Content-Language" content="en-us"> | |||
| <title>Manifest Task</title> | |||
| </head> | |||
| <body> | |||
| <h2><a name="manifest">Manifest</a></h2> | |||
| <h3>Description</h3> | |||
| <p>Creates a manifest file.</p> | |||
| <p>This task can be used to write a Manifest file, optionally | |||
| replacing or updating an existing file.</p> | |||
| <h3>Parameters</h3> | |||
| <table border="1" cellpadding="2" cellspacing="0"> | |||
| <tr> | |||
| <td valign="top"><b>Attribute</b></td> | |||
| <td valign="top"><b>Description</b></td> | |||
| <td align="center" valign="top"><b>Required</b></td> | |||
| </tr> | |||
| <tr> | |||
| <td valign="top">file</td> | |||
| <td valign="top">the manifest-file to create/update.</td> | |||
| <td valign="top" align="center">Yes</td> | |||
| </tr> | |||
| <tr> | |||
| <td valign="top">mode</td> | |||
| <td valign="top">One of "update" or "replace", default is "update".</td> | |||
| <td valign="top" align="center">No</td> | |||
| </tr> | |||
| </table> | |||
| <h3>Nested elements</h3> | |||
| <h4><a name="attribute">attribute</h4></h4> | |||
| <p>One attribute for the manifest file. Those attributes that are | |||
| not nested into a section will be added to the "Main" section.</p> | |||
| <table border="1" cellpadding="2" cellspacing="0"> | |||
| <tr> | |||
| <td valign="top"><b>Attribute</b></td> | |||
| <td valign="top"><b>Description</b></td> | |||
| <td align="center" valign="top"><b>Required</b></td> | |||
| </tr> | |||
| <tr> | |||
| <td valign="top">name</td> | |||
| <td valign="top">the name of the attribute.</td> | |||
| <td valign="top" align="center">Yes</td> | |||
| </tr> | |||
| <tr> | |||
| <td valign="top">value</td> | |||
| <td valign="top">the name of the attribute.</td> | |||
| <td valign="top" align="center">Yes</td> | |||
| </tr> | |||
| </table> | |||
| <h4>section</h4> | |||
| <p>A manifest section - you can nest <a | |||
| href="#attribute">attribute</a> elements into sections.</p> | |||
| <table border="1" cellpadding="2" cellspacing="0"> | |||
| <tr> | |||
| <td valign="top"><b>Attribute</b></td> | |||
| <td valign="top"><b>Description</b></td> | |||
| <td align="center" valign="top"><b>Required</b></td> | |||
| </tr> | |||
| <tr> | |||
| <td valign="top">name</td> | |||
| <td valign="top">the name of the section.</td> | |||
| <td valign="top" align="center">No, if ommitted it will be assumed | |||
| to be the main section.</td> | |||
| </tr> | |||
| </table> | |||
| </body> | |||
| </html> | |||
| @@ -57,6 +57,7 @@ | |||
| <a href="CoreTasks/javac.html">Javac</a><br> | |||
| <a href="CoreTasks/javadoc.html">Javadoc/<i>Javadoc2</i></a><br> | |||
| <a href="CoreTasks/mail.html">Mail</a><br> | |||
| <a href="CoreTasks/manifest.html">Manifest</a><br> | |||
| <a href="CoreTasks/mkdir.html">Mkdir</a><br> | |||
| <a href="CoreTasks/move.html">Move</a><br> | |||
| <a href="CoreTasks/parallel.html">Parallel</a><br> | |||
| @@ -114,7 +114,7 @@ public class Jar extends Zip { | |||
| public void addConfiguredManifest(Manifest newManifest) throws ManifestException { | |||
| if (manifest == null) { | |||
| manifest = getDefaultManifest(); | |||
| manifest = Manifest.getDefaultManifest(); | |||
| } | |||
| manifest.merge(newManifest); | |||
| buildFileManifest = true; | |||
| @@ -133,7 +133,7 @@ public class Jar extends Zip { | |||
| r = new FileReader(manifestFile); | |||
| Manifest newManifest = new Manifest(r); | |||
| if (manifest == null) { | |||
| manifest = getDefaultManifest(); | |||
| manifest = Manifest.getDefaultManifest(); | |||
| } | |||
| manifest.merge(newManifest); | |||
| } | |||
| @@ -166,7 +166,7 @@ public class Jar extends Zip { | |||
| throws IOException, BuildException | |||
| { | |||
| try { | |||
| execManifest = getDefaultManifest(); | |||
| execManifest = Manifest.getDefaultManifest(); | |||
| if (manifest != null) { | |||
| execManifest.merge(manifest); | |||
| @@ -252,29 +252,6 @@ public class Jar extends Zip { | |||
| private Manifest getDefaultManifest() { | |||
| try { | |||
| String s = "/org/apache/tools/ant/defaultManifest.mf"; | |||
| InputStream in = this.getClass().getResourceAsStream(s); | |||
| if (in == null) { | |||
| throw new BuildException("Could not find default manifest: " + s); | |||
| } | |||
| try { | |||
| return new Manifest(new InputStreamReader(in, "ASCII")); | |||
| } catch (UnsupportedEncodingException e) { | |||
| // impossible with ASCII encoding | |||
| log("ASCII encoding not supported by JVM", Project.MSG_ERR); | |||
| return new Manifest(new InputStreamReader(in)); | |||
| } | |||
| } | |||
| catch (ManifestException e) { | |||
| throw new BuildException("Default manifest is invalid !!"); | |||
| } | |||
| catch (IOException e) { | |||
| throw new BuildException("Unable to read default manifest", e); | |||
| } | |||
| } | |||
| /** | |||
| * Handle situation when we encounter a manifest file | |||
| * | |||
| @@ -352,7 +329,7 @@ public class Jar extends Zip { | |||
| } | |||
| Manifest currentManifest = new Manifest(new InputStreamReader(theZipFile.getInputStream(entry))); | |||
| if (manifest == null) { | |||
| manifest = getDefaultManifest(); | |||
| manifest = Manifest.getDefaultManifest(); | |||
| } | |||
| if (!currentManifest.equals(manifest)) { | |||
| log("Updating jar since jar manifest has changed", Project.MSG_VERBOSE); | |||
| @@ -57,20 +57,29 @@ package org.apache.tools.ant.taskdefs; | |||
| import java.util.Vector; | |||
| import java.util.Hashtable; | |||
| import java.util.Enumeration; | |||
| 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.BufferedReader; | |||
| import java.io.Reader; | |||
| import java.io.StringWriter; | |||
| import java.io.UnsupportedEncodingException; | |||
| import org.apache.tools.ant.BuildException; | |||
| import org.apache.tools.ant.Task; | |||
| import org.apache.tools.ant.types.EnumeratedAttribute; | |||
| /** | |||
| * Class to manage Manifest information | |||
| * | |||
| * @author <a href="mailto:conor@apache.org">Conor MacNeill</a> | |||
| * @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a> | |||
| */ | |||
| public class Manifest { | |||
| public class Manifest extends Task { | |||
| /** The standard manifest version header */ | |||
| public final static String ATTRIBUTE_MANIFEST_VERSION = "Manifest-Version"; | |||
| @@ -92,6 +101,15 @@ public class Manifest { | |||
| /** The max length of a line in a Manifest */ | |||
| public final static int MAX_LINE_LENGTH = 70; | |||
| /** | |||
| * Helper class for Manifest's mode attribute. | |||
| */ | |||
| public static class Mode extends EnumeratedAttribute { | |||
| public String[] getValues() { | |||
| return new String[] {"update", "replace"}; | |||
| } | |||
| } | |||
| /** | |||
| * Class to hold manifest attributes | |||
| */ | |||
| @@ -498,8 +516,34 @@ public class Manifest { | |||
| /** The named sections of this manifest */ | |||
| private Hashtable sections = new Hashtable(); | |||
| /** | |||
| * Construct a manifest from Ant's default manifest file. | |||
| */ | |||
| public static Manifest getDefaultManifest() throws BuildException { | |||
| try { | |||
| String s = "/org/apache/tools/ant/defaultManifest.mf"; | |||
| InputStream in = Manifest.class.getResourceAsStream(s); | |||
| if (in == null) { | |||
| throw new BuildException("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 BuildException("Default manifest is invalid !!"); | |||
| } | |||
| catch (IOException e) { | |||
| throw new BuildException("Unable to read default manifest", e); | |||
| } | |||
| } | |||
| /** Construct an empty manifest */ | |||
| public Manifest() { | |||
| mode = new Mode(); | |||
| mode.setValue("replace"); | |||
| } | |||
| /** | |||
| @@ -681,4 +725,73 @@ public class Manifest { | |||
| return true; | |||
| } | |||
| private File manifestFile; | |||
| /** | |||
| * The name of the manifest file to write (if used as a task). | |||
| */ | |||
| public void setFile(File f) { | |||
| manifestFile = f; | |||
| } | |||
| private Mode mode; | |||
| /** | |||
| * Shall we update or replace an existing manifest? | |||
| */ | |||
| public void setMode(Mode m) { | |||
| mode = m; | |||
| } | |||
| /** | |||
| * Create or update the Manifest when used as a task. | |||
| */ | |||
| public void execute() throws BuildException { | |||
| if (manifestFile == null) { | |||
| throw new BuildException("the file attribute is required"); | |||
| } | |||
| Manifest toWrite = getDefaultManifest(); | |||
| if (mode.getValue().equals("update") && manifestFile.exists()) { | |||
| FileReader f = null; | |||
| try { | |||
| f = new FileReader(manifestFile); | |||
| toWrite.merge(new Manifest(f)); | |||
| } catch (ManifestException m) { | |||
| throw new BuildException("Existing manifest "+manifestFile | |||
| + " is invalid", m, location); | |||
| } catch (IOException e) { | |||
| throw new BuildException("Failed to read "+manifestFile, | |||
| e, location); | |||
| } finally { | |||
| if (f != null) { | |||
| try { | |||
| f.close(); | |||
| } catch (IOException e) {} | |||
| } | |||
| } | |||
| } | |||
| try { | |||
| toWrite.merge(this); | |||
| } catch (ManifestException m) { | |||
| throw new BuildException("Manifest is invalid", m, location); | |||
| } | |||
| PrintWriter w = null; | |||
| try { | |||
| w = new PrintWriter(new FileWriter(manifestFile)); | |||
| toWrite.write(w); | |||
| } catch (IOException e) { | |||
| throw new BuildException("Failed to write "+manifestFile, | |||
| e, location); | |||
| } finally { | |||
| if (w != null) { | |||
| w.close(); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| @@ -58,6 +58,7 @@ bunzip2=org.apache.tools.ant.taskdefs.BUnzip2 | |||
| checksum=org.apache.tools.ant.taskdefs.Checksum | |||
| waitfor=org.apache.tools.ant.taskdefs.WaitFor | |||
| input=org.apache.tools.ant.taskdefs.Input | |||
| manifest=org.apache.tools.ant.taskdefs.Manifest | |||
| # optional tasks | |||
| script=org.apache.tools.ant.taskdefs.optional.Script | |||