diff --git a/WHATSNEW b/WHATSNEW
index ac1b61fec..6f80387dd 100644
--- a/WHATSNEW
+++ b/WHATSNEW
@@ -89,7 +89,8 @@ Other changes:
* Added support for specifying CVS_RSH in the 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
diff --git a/docs/manual/CoreTasks/manifest.html b/docs/manual/CoreTasks/manifest.html
new file mode 100644
index 000000000..997ddadfb
--- /dev/null
+++ b/docs/manual/CoreTasks/manifest.html
@@ -0,0 +1,78 @@
+
+
+
+
+Manifest Task
+
+
+
+
+
+Description
+Creates a manifest file.
+
+This task can be used to write a Manifest file, optionally
+replacing or updating an existing file.
+
+Parameters
+
+
+ Attribute |
+ Description |
+ Required |
+
+
+ file |
+ the manifest-file to create/update. |
+ Yes |
+
+
+ mode |
+ One of "update" or "replace", default is "update". |
+ No |
+
+
+
+Nested elements
+
+One attribute for the manifest file. Those attributes that are
+not nested into a section will be added to the "Main" section.
+
+
+ Attribute |
+ Description |
+ Required |
+
+
+ name |
+ the name of the attribute. |
+ Yes |
+
+
+ value |
+ the name of the attribute. |
+ Yes |
+
+
+
+
+section
+A manifest section - you can nest attribute elements into sections.
+
+
+
+ Attribute |
+ Description |
+ Required |
+
+
+ name |
+ the name of the section. |
+ No, if ommitted it will be assumed
+ to be the main section. |
+
+
+
+
+
diff --git a/docs/manual/coretasklist.html b/docs/manual/coretasklist.html
index aa52c496a..d25364fd6 100644
--- a/docs/manual/coretasklist.html
+++ b/docs/manual/coretasklist.html
@@ -57,6 +57,7 @@
Javac
Javadoc/Javadoc2
Mail
+Manifest
Mkdir
Move
Parallel
diff --git a/src/main/org/apache/tools/ant/taskdefs/Jar.java b/src/main/org/apache/tools/ant/taskdefs/Jar.java
index 0ea0a29bb..ae40a674a 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Jar.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Jar.java
@@ -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);
diff --git a/src/main/org/apache/tools/ant/taskdefs/Manifest.java b/src/main/org/apache/tools/ant/taskdefs/Manifest.java
index 2ada2e808..6864b4195 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Manifest.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Manifest.java
@@ -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 Conor MacNeill
+ * @author Stefan Bodewig
*/
-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();
+ }
+ }
+ }
+
}
diff --git a/src/main/org/apache/tools/ant/taskdefs/defaults.properties b/src/main/org/apache/tools/ant/taskdefs/defaults.properties
index d6cf5bb84..c680c8f92 100644
--- a/src/main/org/apache/tools/ant/taskdefs/defaults.properties
+++ b/src/main/org/apache/tools/ant/taskdefs/defaults.properties
@@ -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