diff --git a/docs/index.html b/docs/index.html index f35137526..8c83b4128 100644 --- a/docs/index.html +++ b/docs/index.html @@ -2725,6 +2725,11 @@ You should not include META-INF/MANIFEST.MF in your set of files. If create (the default), the JAR is created anyway with only a manifest. If skip, the JAR is not created and a warning is issued. If fail, the JAR is not created and the build is halted with an error. +

(The Jar task is a shortcut for specifying the manifest file of a JAR file. +The same thing can be accomplished by using the fullpath +attribute of the filesets in a Zip task. The one difference is that if the +manifest attribute is not specified, the Jar task will +include an empty one for you.)

Parameters

@@ -2791,13 +2796,13 @@ If fail, the JAR is not created and the build is halted with an err

Examples

  <jar jarfile="${dist}/lib/app.jar" basedir="${build}/classes" />
-

jars all files in the ${build}/classes directory in a file +

jars all files in the ${build}/classes directory into a file called app.jar in the ${dist}/lib directory.

  <jar jarfile="${dist}/lib/app.jar"
        basedir="${build}/classes"
        excludes="**/Test.class"
   />
-

jars all files in the ${build}/classes directory in a file +

jars all files in the ${build}/classes directory into a file called app.jar in the ${dist}/lib directory. Files with the name Test.class are excluded.

  <jar jarfile="${dist}/lib/app.jar"
@@ -2805,7 +2810,7 @@ with the name Test.class are excluded.

includes="mypackage/test/**" excludes="**/Test.class" />
-

jars all files in the ${build}/classes directory in a file +

jars all files in the ${build}/classes directory into a file called app.jar in the ${dist}/lib directory. Only files under the directory mypackage/test are used, and files with the name Test.class are excluded.

@@ -2816,7 +2821,7 @@ the name Test.class are excluded.

<fileset dir="${src}/resources"/> </jar>

jars all files in the ${build}/classes directory and also -in the ${src}/resources directory together in a file +in the ${src}/resources directory together into a file called app.jar in the ${dist}/lib directory. Files with the name Test.class are excluded. If there are files such as ${build}/classes/mypackage/MyClass.class @@ -4434,14 +4439,14 @@ task to come up with a .tar.gz package.

Examples

  <tar tarfile="${dist}/manual.tar" basedir="htdocs/manual" />
   <gzip zipfile="${dist}/manual.tar.gz" src="${dist}/manual.tar" />
-

tars all files in the htdocs/manual directory in a file called manual.tar +

tars all files in the htdocs/manual directory into a file called manual.tar in the ${dist} directory, then applies the gzip task to compress it.

  <tar tarfile="${dist}/manual.tar"
        basedir="htdocs/manual"
        excludes="mydocs/**, **/todo.html"
   />
-

tars all files in the htdocs/manual directory in a file called manual.tar +

tars all files in the htdocs/manual directory into a file called manual.tar in the ${dist} directory. Files in the directory mydocs, or files with the name todo.html are excluded.


@@ -4779,10 +4784,10 @@ carried from tarfile.

An extension of the Jar task with special treatment for files that should end up in the WEB-INF/lib, WEB-INF/classes or -WEB-INF directories of the Web Application Archive. It -also gives you more control over where your files end up in the -archive by means of its nested prefixedfileset -element.

+WEB-INF directories of the Web Application Archive. +

(The War task is a shortcut for specifying the particular layout of a WAR file. +The same thing can be accomplished by using the prefix and fullpath +attributes of the filesets in a Zip or Jar task.)

Parameters

@@ -4866,60 +4871,6 @@ href="#fileset">FileSet. All files included in this fileset will end up in the WEB-INF directory of the war file. If this fileset includes a file named web.xml, the file is ignored and you will get a warning.

-

prefixedfileset

-

The nested prefixedfileset element specifies a FileSet with an additional prefix attribute. All -files included in this fileset will end up in the prefix -directory of the war file, where prefix is the value of the -prefix attribute.

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
AttributeDescriptionRequired
prefixThe prefix directory to add to each filename when - adding it to the archive. Default is none.No
dirThe root of the directory tree of this FileSet.Yes
defaultexcludesindicates whether default excludes should be used or not - ("yes"/"no"). Default excludes are used when omitted.No
includescomma separated list of patterns of files that must be - included. All files are included when omitted.No
includesfilethe name of a file. Each line of this file is - taken to be an include patternNo
excludescomma separated list of patterns of files that must be - excluded. No files (except default excludes) are excluded when omitted.No
excludesfilethe name of a file. Each line of this file is - taken to be an exclude patternNo

Examples

Assume the following structure in the project's base directory:

@@ -4941,7 +4892,7 @@ then the war file myapp.war created with
     <exclude name="jdbc1.jar" />
   </lib>
   <classes dir="build/main" />
-  <prefixedfileset dir="src/graphics/images/gifs" 
+  <fileset dir="src/graphics/images/gifs" 
                    prefix="images"/>
 </war>
 
@@ -4986,6 +4937,13 @@ if basedir is set. You may use any mixture of the implicit file set and optional subelements like <include>); explicit nested <fileset> elements so long as at least one fileset total is specified. The ZIP file will only reflect the relative paths of files within each fileset.

+

Inside of <zip> elements, nested filesets may include one of two special attributes: +prefix or fullpath. These attributes modify the location of the files when they are placed +inside the archive. If the prefix attribute is set, all the files in the fileset are prefixed +with that path in the archive. If the fullpath attribute is set, the file described by the filset is placed at that +exact location in the archive. (The fullpath attribute can only be set for filesets that +represent a single file. The prefix and fullpath attributes cannot both be set on the +same fileset.)

The whenempty parameter controls what happens when no files match. If skip (the default), the ZIP is not created and a warning is issued. If fail, the ZIP is not created and the build is halted with an error. @@ -5053,31 +5011,36 @@ which should be recognized as such by compliant ZIP manipulation tools.

  <zip zipfile="${dist}/manual.zip"
        basedir="htdocs/manual"
   />
-

zips all files in the htdocs/manual directory in a file called manual.zip +

zips all files in the htdocs/manual directory into a file called manual.zip in the ${dist} directory.

  <zip zipfile="${dist}/manual.zip"
        basedir="htdocs/manual"
        excludes="mydocs/**, **/todo.html"
   />
-

zips all files in the htdocs/manual directory in a file called manual.zip -in the ${dist} directory. Files in the directory mydocs, +

zips all files in the htdocs/manual directory. Files in the directory mydocs, or files with the name todo.html are excluded.

  <zip zipfile="${dist}/manual.zip"
        basedir="htdocs/manual"
        includes="api/**/*.html"
        excludes="**/todo.html"
   />
-

zips all files in the htdocs/manual directory in a file called manual.zip -in the ${dist} directory. Only html files under the directory api +

zips all files in the htdocs/manual directory. Only html files under the directory api are zipped, and files with the name todo.html are excluded.

  <zip zipfile="${dist}/manual.zip">
     <fileset dir="htdocs/manual"/>
     <fileset dir="." includes="ChangeLog.txt"/>
   </zip>
-

zips all files in the htdocs/manual directory in a file called manual.zip -in the ${dist} directory, and also adds the file ChangeLog.txt in the +

zips all files in the htdocs/manual directory, and also adds the file ChangeLog.txt in the current directory. ChangeLog.txt will be added to the top of the ZIP file, just as if it had been located at htdocs/manual/ChangeLog.txt.

+
  <zip zipfile="${dist}/manual.zip">
+    <fileset dir="htdocs/manual" prefix="docs/user-guide"/>
+    <fileset dir="." includes="ChangeLog27.txt" fullpath="docs/ChangeLog.txt"/>
+  </zip>
+

zips all files in the htdocs/manual directory into the docs/user-guide directory +in the archive, and also adds the file ChangeLog27.txt in the +current directory as docs/ChangeLog.txt. For example, the archive might end up containing two files: +docs/user-guide/html/index.html and docs/ChangeLog.txt


Optional tasks

@@ -5188,7 +5151,7 @@ supports all attributes of <fileset> basedir="htdocs/manual" /> -

cabs all files in the htdocs/manual directory in a file called +

cabs all files in the htdocs/manual directory into a file called manual.cab in the ${dist} directory.

 <cab cabfile="${dist}/manual.cab"
@@ -5196,7 +5159,7 @@ manual.cab in the ${dist} directory.

excludes="mydocs/**, **/todo.html" />
-

cabs all files in the htdocs/manual directory in a file called +

cabs all files in the htdocs/manual directory into a file called manual.cab in the ${dist} directory. Files in the directory mydocs, or files with the name todo.html are excluded.

@@ -5207,7 +5170,7 @@ or files with the name todo.html are excluded.

verbose="yes" />
-

cab all files in the htdocs/manual directory in a file called +

cab all files in the htdocs/manual directory into a file called manual.cab in the ${dist} directory. Only html files under the directory api are archived, and files with the name todo.html are excluded. Output from the cabarc tool is displayed in the build diff --git a/src/main/org/apache/tools/ant/taskdefs/Jar.java b/src/main/org/apache/tools/ant/taskdefs/Jar.java index 825a8f2ce..6dc3e6a31 100644 --- a/src/main/org/apache/tools/ant/taskdefs/Jar.java +++ b/src/main/org/apache/tools/ant/taskdefs/Jar.java @@ -68,35 +68,45 @@ import java.util.zip.*; public class Jar extends Zip { private File manifest; - + private boolean manifestAdded; + public Jar() { super(); archiveType = "jar"; emptyBehavior = "create"; } - public void execute() { - if (manifest != null && !manifest.exists()) - throw new BuildException("Manifest file: " + manifest + " does not exists."); - super.execute(); - } - public void setJarfile(File jarFile) { super.setZipfile(jarFile); } + + /** + * Adds a set of files (nested fileset attribute). + */ + public void addPrefixedfileset(PrefixedFileSet set) { + log("Warning: Prefixfileset is a deprecated feature. The fileset subelement can be used in it's place", Project.MSG_WARN); + addFileset(set); + } public void setManifest(File manifestFile) { manifest = manifestFile; + if (!manifest.exists()) + throw new BuildException("Manifest file: " + manifest + " does not exist."); + + // Create a PrefixedFileSet for this file, and pass it up. + PrefixedFileSet fs = new PrefixedFileSet(); + fs.setDir(new File(manifest.getParent())); + fs.setIncludes(manifest.getName()); + fs.setFullpath("META-INF/MANIFEST.MF"); + super.addFileset(fs); } + protected void initZipOutputStream(ZipOutputStream zOut) throws IOException, BuildException { - // add manifest first - if (manifest != null) { - zipDir(new File(manifest.getParent()), zOut, "META-INF/"); - super.zipFile(manifest, zOut, "META-INF/MANIFEST.MF"); - } else { + // If no manifest is specified, add the default one. + if (manifest == null) { String s = "/org/apache/tools/ant/defaultManifest.mf"; InputStream in = this.getClass().getResourceAsStream(s); if ( in == null ) @@ -104,53 +114,27 @@ public class Jar extends Zip { zipDir(null, zOut, "META-INF/"); zipFile(in, zOut, "META-INF/MANIFEST.MF", System.currentTimeMillis()); } - } - - protected boolean isUpToDate(FileScanner[] scanners, File zipFile) throws BuildException - { - File[] files = grabFiles(scanners); - - if (manifest != null) { - // just add the manifest file to the mix - - DirectoryScanner ds = new DirectoryScanner(); - ds.setBasedir(new File(manifest.getParent())); - ds.setIncludes(new String[] {manifest.getName()}); - ds.scan(); - FileScanner[] myScanners = new FileScanner[scanners.length+1]; - System.arraycopy(scanners, 0, myScanners, 0, scanners.length); - myScanners[scanners.length] = ds; - - boolean retval = super.isUpToDate(myScanners, zipFile); - if (!retval && files.length == 0) { - log("Note: creating empty "+archiveType+" archive " + zipFile, - Project.MSG_INFO); - } - return retval; - - } else if (emptyBehavior.equals("create") && files.length == 0) { - - log("Note: creating empty "+archiveType+" archive " + zipFile, - Project.MSG_INFO); - return false; - - } else { - // all other cases are handled correctly by Zip's method - return super.isUpToDate(scanners, zipFile); - } + super.initZipOutputStream(zOut); } protected void zipFile(File file, ZipOutputStream zOut, String vPath) throws IOException { - // We already added a META-INF/MANIFEST.MF - if (!vPath.equalsIgnoreCase("META-INF/MANIFEST.MF")) { - super.zipFile(file, zOut, vPath); + // If the file being added is META-INF/MANIFEST.MF, we warn if it's not the + // one specified in the "manifest" attribute - or if it's being added twice, + // meaning the same file is specified by the "manifeset" attribute and in + // a element. + if (vPath.equalsIgnoreCase("META-INF/MANIFEST.MF")) { + if (manifest == null || !manifest.equals(file) || manifestAdded) { + log("Warning: selected "+archiveType+" files include a META-INF/MANIFEST.MF which will be ignored " + + "(please use manifest attribute to "+archiveType+" task)", Project.MSG_WARN); + } else { + super.zipFile(file, zOut, vPath); + manifestAdded = true; + } } else { - log("Warning: selected "+archiveType+" files include a META-INF/MANIFEST.MF which will be ignored " + - "(please use manifest attribute to "+archiveType+" task)", Project.MSG_WARN); + super.zipFile(file, zOut, vPath); } } - } diff --git a/src/main/org/apache/tools/ant/taskdefs/War.java b/src/main/org/apache/tools/ant/taskdefs/War.java index 9a18a6ef3..9b65024e2 100644 --- a/src/main/org/apache/tools/ant/taskdefs/War.java +++ b/src/main/org/apache/tools/ant/taskdefs/War.java @@ -69,10 +69,7 @@ import java.util.zip.*; public class War extends Jar { private File deploymentDescriptor; - - private Vector libFileSets = new Vector(); - private Vector classesFileSets = new Vector(); - private Vector webInfFileSets = new Vector(); + private boolean descriptorAdded; public War() { super(); @@ -85,85 +82,64 @@ public class War extends Jar { } public void setWebxml(File descr) { - deploymentDescriptor = descr; + deploymentDescriptor = descr; + if (!deploymentDescriptor.exists()) + throw new BuildException("Deployment descriptor: " + deploymentDescriptor + " does not exist."); + + // Create a PrefixedFileSet for this file, and pass it up. + PrefixedFileSet fs = new PrefixedFileSet(); + fs.setDir(new File(deploymentDescriptor.getParent())); + fs.setIncludes(deploymentDescriptor.getName()); + fs.setFullpath("WEB-INF/web.xml"); + super.addFileset(fs); } - public void addLib(FileSet fs) { - libFileSets.addElement(fs); + public void addLib(PrefixedFileSet fs) { + // We just set the prefix for this fileset, and pass it up. + fs.setPrefix("WEB-INF/lib/"); + super.addFileset(fs); } - public void addClasses(FileSet fs) { - classesFileSets.addElement(fs); + public void addClasses(PrefixedFileSet fs) { + // We just set the prefix for this fileset, and pass it up. + fs.setPrefix("WEB-INF/classes/"); + super.addFileset(fs); } - public void addWebinf(FileSet fs) { - webInfFileSets.addElement(fs); + public void addWebinf(PrefixedFileSet fs) { + // We just set the prefix for this fileset, and pass it up. + fs.setPrefix("WEB-INF/"); + super.addFileset(fs); } - /** - * Add the deployment descriptor as well as all files added the - * special way of nested lib, classes or webinf filesets. - */ protected void initZipOutputStream(ZipOutputStream zOut) throws IOException, BuildException { - // add deployment descriptor first - if (deploymentDescriptor != null) { - zipDir(new File(deploymentDescriptor.getParent()), zOut, - "WEB-INF/"); - super.zipFile(deploymentDescriptor, zOut, "WEB-INF/web.xml"); - } else { - throw new BuildException("webxml attribute is required", location); - } - - addFiles(libFileSets, zOut, "WEB-INF/lib/"); - addFiles(classesFileSets, zOut, "WEB-INF/classes/"); - addFiles(webInfFileSets, zOut, "WEB-INF/"); - - super.initZipOutputStream(zOut); - } - - protected boolean isUpToDate(FileScanner[] scanners, File zipFile) throws BuildException - { + // If no webxml file is specified, it's an error. if (deploymentDescriptor == null) { throw new BuildException("webxml attribute is required", location); } - // just add some Scanners for our filesets and web.xml and let - // Jar/Zip do the rest of the work - - FileScanner[] myScanners = new FileScanner[scanners.length - + 1 // web.xml - + libFileSets.size() - + classesFileSets.size() - + webInfFileSets.size()]; - - System.arraycopy(scanners, 0, myScanners, 0, scanners.length); - - DirectoryScanner ds = new DirectoryScanner(); - ds.setBasedir(new File(deploymentDescriptor.getParent())); - ds.setIncludes(new String[] {deploymentDescriptor.getName()}); - ds.scan(); - myScanners[scanners.length] = ds; - - addScanners(myScanners, scanners.length+1, libFileSets); - addScanners(myScanners, scanners.length+1+libFileSets.size(), - classesFileSets); - addScanners(myScanners, scanners.length+1+libFileSets.size()+classesFileSets.size(), - webInfFileSets); - - return super.isUpToDate(myScanners, zipFile); + super.initZipOutputStream(zOut); } protected void zipFile(File file, ZipOutputStream zOut, String vPath) throws IOException { - // We already added a WEB-INF/web.xml - if (!vPath.equalsIgnoreCase("WEB-INF/web.xml")) { - super.zipFile(file, zOut, vPath); + // If the file being added is WEB-INF/web.xml, we warn if it's not the + // one specified in the "webxml" attribute - or if it's being added twice, + // meaning the same file is specified by the "webxml" attribute and in + // a element. + if (vPath.equalsIgnoreCase("WEB-INF/web.xml")) { + if (deploymentDescriptor == null || !deploymentDescriptor.equals(file) || descriptorAdded) { + log("Warning: selected "+archiveType+" files include a WEB-INF/web.xml which will be ignored " + + "(please use webxml attribute to "+archiveType+" task)", Project.MSG_WARN); + } else { + super.zipFile(file, zOut, vPath); + descriptorAdded = true; + } } else { - log("Warning: selected "+archiveType+" files include a WEB-INF/web.xml which will be ignored " + - "(please use webxml attribute to "+archiveType+" task)", Project.MSG_WARN); + super.zipFile(file, zOut, vPath); } } -} +} \ No newline at end of file diff --git a/src/main/org/apache/tools/ant/taskdefs/Zip.java b/src/main/org/apache/tools/ant/taskdefs/Zip.java index 67ead21ec..c4902f4ad 100644 --- a/src/main/org/apache/tools/ant/taskdefs/Zip.java +++ b/src/main/org/apache/tools/ant/taskdefs/Zip.java @@ -82,8 +82,7 @@ public class Zip extends MatchingTask { protected String emptyBehavior = "skip"; private Vector filesets = new Vector (); private Hashtable addedDirs = new Hashtable(); - private Vector locFileSets = new Vector(); - + /** * This is the name/location of where to * create the .zip file. @@ -110,26 +109,32 @@ public class Zip extends MatchingTask { /** * Adds a set of files (nested fileset attribute). */ - public void addFileset(FileSet set) { + public void addFileset(PrefixedFileSet set) { filesets.addElement(set); } /** * FileSet with an additional prefix attribute to specify the * location we want to move the files to (inside the archive). + * Or, if this FileSet represents only a single file, then the + * fullpath attribute can be set, which specifies the full path + * that the file should have when it is placed in the archive. */ public static class PrefixedFileSet extends FileSet { private String prefix = ""; + private String fullpath = ""; public void setPrefix(String loc) { prefix = loc; } public String getPrefix() {return prefix;} - } - public void addPrefixedFileSet(PrefixedFileSet fs) { - locFileSets.addElement(fs); + public void setFullpath(String loc) { + fullpath = loc; + } + + public String getFullpath() {return fullpath;} } /** @@ -150,8 +155,7 @@ public class Zip extends MatchingTask { } public void execute() throws BuildException { - if (baseDir == null && filesets.size() == 0 && - locFileSets.size() == 0 && "zip".equals(archiveType)) { + if (baseDir == null && filesets.size() == 0 && "zip".equals(archiveType)) { throw new BuildException( "basedir attribute must be set, or at least " + "one fileset or prefixedfileset must be given!" ); } @@ -160,6 +164,7 @@ public class Zip extends MatchingTask { throw new BuildException("You must specify the " + archiveType + " file to create!"); } + // Create the scanners to pass to isUpToDate(). Vector dss = new Vector (); if (baseDir != null) dss.addElement(getDirectoryScanner(baseDir)); @@ -168,11 +173,9 @@ public class Zip extends MatchingTask { dss.addElement (fs.getDirectoryScanner(project)); } int dssSize = dss.size(); - FileScanner[] scanners = new FileScanner[dssSize + locFileSets.size()]; + FileScanner[] scanners = new FileScanner[dssSize]; dss.copyInto(scanners); - addScanners(scanners, dssSize, locFileSets); - // quick exit if the target is up to date // can also handle empty archives if (isUpToDate(scanners, zipFile)) return; @@ -190,13 +193,12 @@ public class Zip extends MatchingTask { } initZipOutputStream(zOut); - addPrefixedFiles(locFileSets, zOut); - - for (int j = 0; j < dssSize; j++) { - addFiles(scanners[j], zOut, ""); - + // Add the implicit fileset to the archive. + if (baseDir != null) + addFiles(getDirectoryScanner(baseDir), zOut, "", ""); + // Add the explicit filesets to the archive. + addFiles(filesets, zOut); success = true; - } } finally { // Close the output stream. try { @@ -225,18 +227,6 @@ public class Zip extends MatchingTask { } } - /** - * Add a DirectoryScanner for each FileSet included in fileSets to scanners - * starting with index startIndex. - */ - protected void addScanners(FileScanner[] scanners, int startIndex, - Vector fileSets) { - for (int i=0; iEnsure parent directories have been added as well. */ protected void addFiles(FileScanner scanner, ZipOutputStream zOut, - String prefix) throws IOException { + String prefix, String fullpath) throws IOException { + if (prefix.length() > 0 && fullpath.length() > 0) + throw new BuildException("Both prefix and fullpath attributes may not be set on the same fileset."); + File thisBaseDir = scanner.getBasedir(); // directories that matched include patterns String[] dirs = scanner.getIncludedDirectories(); + if (dirs.length > 0 && fullpath.length() > 0) + throw new BuildException("fullpath attribute may only be specified for filesets that specify a single file."); for (int i = 0; i < dirs.length; i++) { String name = dirs[i].replace(File.separatorChar,'/'); if (!name.endsWith("/")) { @@ -259,11 +254,23 @@ public class Zip extends MatchingTask { // files that matched include patterns String[] files = scanner.getIncludedFiles(); + if (files.length > 1 && fullpath.length() > 0) + throw new BuildException("fullpath attribute may only be specified for filesets that specify a single file."); for (int i = 0; i < files.length; i++) { File f = new File(thisBaseDir, files[i]); - String name = files[i].replace(File.separatorChar,'/'); - addParentDirs(thisBaseDir, name, zOut, prefix); - zipFile(f, zOut, prefix+name); + if (fullpath.length() > 0) + { + // Add this file at the specified location. + addParentDirs(null, fullpath, zOut, ""); + zipFile(f, zOut, fullpath); + } + else + { + // Add this file with the specified prefix. + String name = files[i].replace(File.separatorChar,'/'); + addParentDirs(thisBaseDir, name, zOut, prefix); + zipFile(f, zOut, prefix+name); + } } } @@ -477,27 +484,15 @@ public class Zip extends MatchingTask { } } - /** - * Iterate over the given Vector of filesets and add all files to the - * ZipOutputStream using the given prefix. - */ - protected void addFiles(Vector v, ZipOutputStream zOut, String prefix) - throws IOException { - for (int i=0; i 0 @@ -505,11 +500,17 @@ public class Zip extends MatchingTask { && !prefix.endsWith("\\")) { prefix += "/"; } + String fullpath = fs.getFullpath(); + // Need to manually add either fullpath's parent directory, or + // the prefix directory, to the archive. if (prefix.length() > 0) { addParentDirs(null, prefix, zOut, ""); zipDir(null, zOut, prefix); - } - addFiles(ds, zOut, prefix); + } else if (fullpath.length() > 0) { + addParentDirs(null, fullpath, zOut, ""); + } + // Add the fileset. + addFiles(ds, zOut, prefix, fullpath); } } }