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 | * Added support for specifying CVS_RSH in the <cvs/> task | ||||
* New tasks bzip2 and bunzip2 to pack and unpack files using the | * 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, | * The attributes zipfile, jarfile, warfile and earfile (from the Zip, | ||||
Jar, War and Ear tasks) have been deprecated and superseded by a | 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/javac.html">Javac</a><br> | ||||
<a href="CoreTasks/javadoc.html">Javadoc/<i>Javadoc2</i></a><br> | <a href="CoreTasks/javadoc.html">Javadoc/<i>Javadoc2</i></a><br> | ||||
<a href="CoreTasks/mail.html">Mail</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/mkdir.html">Mkdir</a><br> | ||||
<a href="CoreTasks/move.html">Move</a><br> | <a href="CoreTasks/move.html">Move</a><br> | ||||
<a href="CoreTasks/parallel.html">Parallel</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 { | public void addConfiguredManifest(Manifest newManifest) throws ManifestException { | ||||
if (manifest == null) { | if (manifest == null) { | ||||
manifest = getDefaultManifest(); | |||||
manifest = Manifest.getDefaultManifest(); | |||||
} | } | ||||
manifest.merge(newManifest); | manifest.merge(newManifest); | ||||
buildFileManifest = true; | buildFileManifest = true; | ||||
@@ -133,7 +133,7 @@ public class Jar extends Zip { | |||||
r = new FileReader(manifestFile); | r = new FileReader(manifestFile); | ||||
Manifest newManifest = new Manifest(r); | Manifest newManifest = new Manifest(r); | ||||
if (manifest == null) { | if (manifest == null) { | ||||
manifest = getDefaultManifest(); | |||||
manifest = Manifest.getDefaultManifest(); | |||||
} | } | ||||
manifest.merge(newManifest); | manifest.merge(newManifest); | ||||
} | } | ||||
@@ -166,7 +166,7 @@ public class Jar extends Zip { | |||||
throws IOException, BuildException | throws IOException, BuildException | ||||
{ | { | ||||
try { | try { | ||||
execManifest = getDefaultManifest(); | |||||
execManifest = Manifest.getDefaultManifest(); | |||||
if (manifest != null) { | if (manifest != null) { | ||||
execManifest.merge(manifest); | 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 | * 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))); | Manifest currentManifest = new Manifest(new InputStreamReader(theZipFile.getInputStream(entry))); | ||||
if (manifest == null) { | if (manifest == null) { | ||||
manifest = getDefaultManifest(); | |||||
manifest = Manifest.getDefaultManifest(); | |||||
} | } | ||||
if (!currentManifest.equals(manifest)) { | if (!currentManifest.equals(manifest)) { | ||||
log("Updating jar since jar manifest has changed", Project.MSG_VERBOSE); | 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.Vector; | ||||
import java.util.Hashtable; | import java.util.Hashtable; | ||||
import java.util.Enumeration; | 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.IOException; | ||||
import java.io.InputStream; | |||||
import java.io.InputStreamReader; | |||||
import java.io.PrintWriter; | import java.io.PrintWriter; | ||||
import java.io.BufferedReader; | |||||
import java.io.Reader; | import java.io.Reader; | ||||
import java.io.StringWriter; | import java.io.StringWriter; | ||||
import java.io.UnsupportedEncodingException; | |||||
import org.apache.tools.ant.BuildException; | import org.apache.tools.ant.BuildException; | ||||
import org.apache.tools.ant.Task; | |||||
import org.apache.tools.ant.types.EnumeratedAttribute; | |||||
/** | /** | ||||
* Class to manage Manifest information | * Class to manage Manifest information | ||||
* | * | ||||
* @author <a href="mailto:conor@apache.org">Conor MacNeill</a> | * @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 */ | /** The standard manifest version header */ | ||||
public final static String ATTRIBUTE_MANIFEST_VERSION = "Manifest-Version"; | 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 */ | /** The max length of a line in a Manifest */ | ||||
public final static int MAX_LINE_LENGTH = 70; | 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 | * Class to hold manifest attributes | ||||
*/ | */ | ||||
@@ -498,8 +516,34 @@ public class Manifest { | |||||
/** The named sections of this manifest */ | /** The named sections of this manifest */ | ||||
private Hashtable sections = new Hashtable(); | 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 */ | /** Construct an empty manifest */ | ||||
public Manifest() { | public Manifest() { | ||||
mode = new Mode(); | |||||
mode.setValue("replace"); | |||||
} | } | ||||
/** | /** | ||||
@@ -681,4 +725,73 @@ public class Manifest { | |||||
return true; | 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 | checksum=org.apache.tools.ant.taskdefs.Checksum | ||||
waitfor=org.apache.tools.ant.taskdefs.WaitFor | waitfor=org.apache.tools.ant.taskdefs.WaitFor | ||||
input=org.apache.tools.ant.taskdefs.Input | input=org.apache.tools.ant.taskdefs.Input | ||||
manifest=org.apache.tools.ant.taskdefs.Manifest | |||||
# optional tasks | # optional tasks | ||||
script=org.apache.tools.ant.taskdefs.optional.Script | script=org.apache.tools.ant.taskdefs.optional.Script | ||||