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