Return-Path: Mailing-List: contact ant-dev-help@jakarta.apache.org; run by ezmlm Delivered-To: mailing list ant-dev@jakarta.apache.org Received: (qmail 23235 invoked from network); 16 Jan 2001 03:02:45 -0000 Received: from unknown (HELO beamail.beasys.com) (63.96.163.38) by h31.sny.collab.net with SMTP; 16 Jan 2001 03:02:45 -0000 Received: from san-francisco.beasys.com (san-francisco.beasys.com [192.168.9.10]) by beamail.beasys.com (8.9.1b+Sun/8.9.1) with ESMTP id TAA28441 for ; Mon, 15 Jan 2001 19:02:31 -0800 (PST) Received: from ashbury.weblogic.com (ashbury.beasys.com [172.17.8.3]) by san-francisco.beasys.com (8.9.3+Sun/8.9.1) with ESMTP id TAA06446 for ; Mon, 15 Jan 2001 19:03:10 -0800 (PST) Received: from bea.com ([172.17.10.19]) by ashbury.weblogic.com (Post.Office MTA v3.5.3 release 223 ID# 0-53833U200L200S0V35) with ESMTP id com for ; Mon, 15 Jan 2001 19:23:06 -0800 Message-ID: <3A63B9AD.1010405@bea.com> Date: Mon, 15 Jan 2001 19:02:05 -0800 From: Don Ferguson User-Agent: Mozilla/5.0 (X11; U; Linux 2.2.13-7mdk i686; en-US; m18) Gecko/20001107 Netscape6/6.0 X-Accept-Language: en MIME-Version: 1.0 To: ant-dev@jakarta.apache.org Subject: Re: [PATCH] Zip.java and friends (take 2) References: <3A6384AB.4010108@bea.com> Content-Type: multipart/mixed; boundary="------------040702050002030603040207" X-Spam-Rating: h31.sny.collab.net 1.6.2 0/1000/N --------------040702050002030603040207 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit Peter and Jon, Thanks for the quick feedback. I've updated index.html to reflect the changes, and have updated the Zip task to accept a prefixedfileset, with a warning to the user that it has been deprecated. -Don Don Ferguson wrote: > With these patches, Zip (and derivative tasks such as Jar and War) can > merge the entries of multiple zip files into a single output zip file. > The contents of an input zip file may be selectively extracted based on > include/exclude patterns. > > An included zip file is specified using a with a "src" attribute, > as in: > > > > src="weblogic.jar" > includes="weblogic/utils/" > excludes="weblogic/utils/jars/,**/reflect/" > /> > > > > In this example, a subset of the "weblogic/utils" directory is extracted > from weblogic.jar, into utils.jar. > > The fileset may also contain "prefix" and "fullpath" attributes (the > functionality of PrefixedFileSet has been retained in the new class > ZipFileSet). Prefixes apply to directory-based and zip-based filesets. > The fullpath attributes applies only to a single file in a directory-based > fileset. > > The War task may extract entries from a zip file for all of its filesets > (including the files in "classes" and "lib"). > > > The motivation for this change is: > 1) There is significant overlap between "jlink" and "zip", and it seemed > better to combine them. > 2) "jlink" does not support include/exclude patterns which are extremely > useful for writing packaging-type tasks such as Zip/Jar/War. This > was my main motivation. > 3) By adding this functionality to the base task, it can also be used in > derivative tasks such as Jar and War. > > > This is my first submission jakarta-ant; I hope it is deemed worthy. > > > -Don > > > ------------------------------------------------------------------------ > > Index: src/main/org/apache/tools/ant/taskdefs/Zip.java > =================================================================== > RCS file: /home/cvspublic/jakarta-ant/src/main/org/apache/tools/ant/taskdefs/Zip.java,v > retrieving revision 1.26 > diff -u -r1.26 Zip.java > --- src/main/org/apache/tools/ant/taskdefs/Zip.java 2001/01/08 16:45:32 1.26 > +++ src/main/org/apache/tools/ant/taskdefs/Zip.java 2001/01/15 22:21:26 > @@ -109,40 +109,10 @@ > /** > * Adds a set of files (nested fileset attribute). > */ > - public void addFileset(FileSet set) { > + public void addFileset(ZipFileSet set) { > filesets.addElement(set); > } > > - /** > - * Adds a set of files (nested fileset attribute). > - */ > - public void addPrefixedfileset(PrefixedFileSet set) { > - addFileset(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 setFullpath(String loc) { > - fullpath = loc; > - } > - > - public String getFullpath() {return fullpath;} > - } > > /** > * Sets behavior of the task when no files match. > @@ -164,7 +134,7 @@ > public void execute() throws BuildException { > 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!" ); > + "one fileset must be given!" ); > } > > if (zipFile == null) { > @@ -191,7 +161,8 @@ > > try { > boolean success = false; > - ZipOutputStream zOut = new ZipOutputStream(new FileOutputStream(zipFile)); > + ZipOutputStream zOut = > + new ZipOutputStream(new FileOutputStream(zipFile)); > try { > if (doCompress) { > zOut.setMethod(ZipOutputStream.DEFLATED); > @@ -283,6 +254,26 @@ > } > } > > + protected void addZipEntries(ZipFileSet fs, DirectoryScanner ds, > + ZipOutputStream zOut, String prefix) > + throws IOException > + { > + ZipScanner zipScanner = (ZipScanner) ds; > + String zipSrc = fs.getSrc(); > + > + ZipEntry entry; > + ZipInputStream in = new ZipInputStream(new FileInputStream(new File(zipSrc))); > + while ((entry = in.getNextEntry()) != null) { > + String vPath = entry.getName(); > + if (zipScanner.match(vPath)) { > + addParentDirs(null, vPath, zOut, prefix); > + if (! entry.isDirectory()) { > + zipFile(in, zOut, prefix+vPath, entry.getTime()); > + } > + } > + } > + } > + > protected void initZipOutputStream(ZipOutputStream zOut) > throws IOException, BuildException > { > @@ -499,28 +490,22 @@ > } > > /** > - * Iterate over the given Vector of (prefixed)filesets and add > + * Iterate over the given Vector of zipfilesets and add > * all files to the ZipOutputStream using the given prefix. > */ > protected void addFiles(Vector filesets, ZipOutputStream zOut) > throws IOException { > // Add each fileset in the Vector. > for (int i = 0; i - FileSet fs = (FileSet) filesets.elementAt(i); > + ZipFileSet fs = (ZipFileSet) filesets.elementAt(i); > DirectoryScanner ds = fs.getDirectoryScanner(project); > - String prefix = ""; > - String fullpath = ""; > - if (fs instanceof PrefixedFileSet) { > - PrefixedFileSet pfs = (PrefixedFileSet) fs; > - prefix = pfs.getPrefix(); > - fullpath = pfs.getFullpath(); > - } > - > + String prefix = fs.getPrefix(); > if (prefix.length() > 0 > && !prefix.endsWith("/") > && !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) { > @@ -529,8 +514,13 @@ > } else if (fullpath.length() > 0) { > addParentDirs(null, fullpath, zOut, ""); > } > - // Add the fileset. > - addFiles(ds, zOut, prefix, fullpath); > + > + if (fs.getSrc() != null) { > + addZipEntries(fs, ds, zOut, prefix); > + } else { > + // Add the fileset. > + addFiles(ds, zOut, prefix, fullpath); > + } > } > } > > > > ------------------------------------------------------------------------ > > Index: src/main/org/apache/tools/ant/taskdefs/Jar.java > =================================================================== > RCS file: /home/cvspublic/jakarta-ant/src/main/org/apache/tools/ant/taskdefs/Jar.java,v > retrieving revision 1.14 > diff -u -r1.14 Jar.java > --- src/main/org/apache/tools/ant/taskdefs/Jar.java 2001/01/08 16:45:32 1.14 > +++ src/main/org/apache/tools/ant/taskdefs/Jar.java 2001/01/15 22:22:12 > @@ -55,6 +55,7 @@ > package org.apache.tools.ant.taskdefs; > > import org.apache.tools.ant.*; > +import org.apache.tools.ant.types.ZipFileSet; > > import java.io.*; > import java.util.zip.*; > @@ -85,12 +86,12 @@ > 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(); > + // Create a ZipFileSet for this file, and pass it up. > + ZipFileSet fs = new ZipFileSet(); > fs.setDir(new File(manifest.getParent())); > fs.setIncludes(manifest.getName()); > fs.setFullpath("META-INF/MANIFEST.MF"); > - super.addPrefixedfileset(fs); > + super.addFileset(fs); > } > > > > > ------------------------------------------------------------------------ > > Index: src/main/org/apache/tools/ant/taskdefs/War.java > =================================================================== > RCS file: /home/cvspublic/jakarta-ant/src/main/org/apache/tools/ant/taskdefs/War.java,v > retrieving revision 1.9 > diff -u -r1.9 War.java > --- src/main/org/apache/tools/ant/taskdefs/War.java 2001/01/08 16:45:32 1.9 > +++ src/main/org/apache/tools/ant/taskdefs/War.java 2001/01/15 22:22:33 > @@ -55,7 +55,7 @@ > package org.apache.tools.ant.taskdefs; > > import org.apache.tools.ant.*; > -import org.apache.tools.ant.types.FileSet; > +import org.apache.tools.ant.types.ZipFileSet; > > import java.io.*; > import java.util.Vector; > @@ -86,30 +86,30 @@ > 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(); > + // Create a ZipFileSet for this file, and pass it up. > + ZipFileSet fs = new ZipFileSet(); > fs.setDir(new File(deploymentDescriptor.getParent())); > fs.setIncludes(deploymentDescriptor.getName()); > fs.setFullpath("WEB-INF/web.xml"); > - super.addPrefixedfileset(fs); > + super.addFileset(fs); > } > > - public void addLib(PrefixedFileSet fs) { > + public void addLib(ZipFileSet fs) { > // We just set the prefix for this fileset, and pass it up. > fs.setPrefix("WEB-INF/lib/"); > - super.addPrefixedfileset(fs); > + super.addFileset(fs); > } > > - public void addClasses(PrefixedFileSet fs) { > + public void addClasses(ZipFileSet fs) { > // We just set the prefix for this fileset, and pass it up. > fs.setPrefix("WEB-INF/classes/"); > - super.addPrefixedfileset(fs); > + super.addFileset(fs); > } > > - public void addWebinf(PrefixedFileSet fs) { > + public void addWebinf(ZipFileSet fs) { > // We just set the prefix for this fileset, and pass it up. > fs.setPrefix("WEB-INF/"); > - super.addPrefixedfileset(fs); > + super.addFileset(fs); > } > > protected void initZipOutputStream(ZipOutputStream zOut) > > > ------------------------------------------------------------------------ > > /* > * The Apache Software License, Version 1.1 > * > * Copyright (c) 1999 The Apache Software Foundation. All rights > * reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions > * are met: > * > * 1. Redistributions of source code must retain the above copyright > * notice, this list of conditions and the following disclaimer. > * > * 2. Redistributions in binary form must reproduce the above copyright > * notice, this list of conditions and the following disclaimer in > * the documentation and/or other materials provided with the > * distribution. > * > * 3. The end-user documentation included with the redistribution, if > * any, must include the following acknowlegement: > * "This product includes software developed by the > * Apache Software Foundation (http://www.apache.org/)." > * Alternately, this acknowlegement may appear in the software itself, > * if and wherever such third-party acknowlegements normally appear. > * > * 4. The names "The Jakarta Project", "Ant", and "Apache Software > * Foundation" must not be used to endorse or promote products derived > * from this software without prior written permission. For written > * permission, please contact apache@apache.org. > * > * 5. Products derived from this software may not be called "Apache" > * nor may "Apache" appear in their names without prior written > * permission of the Apache Group. > * > * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED > * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES > * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE > * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR > * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, > * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT > * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF > * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND > * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, > * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT > * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF > * SUCH DAMAGE. > * ==================================================================== > * > * This software consists of voluntary contributions made by many > * individuals on behalf of the Apache Software Foundation. For more > * information on the Apache Software Foundation, please see > * . > */ > package org.apache.tools.ant.types; > > import java.io.File; > import java.util.Stack; > import org.apache.tools.ant.BuildException; > import org.apache.tools.ant.DirectoryScanner; > import org.apache.tools.ant.Project; > > /** > * A ZipFileSet is a FileSet with extra attributes useful in the context of > * Zip/Jar tasks. > * > * A ZipFileSet extends FileSets with the ability to extract a subset of the > * entries of a Zip file for inclusion in another Zip file. It also includes > * a prefix attribute which is prepended to each entry in the output Zip file. > * > * At present, ZipFileSets are not surfaced in the public API. FileSets > * nested in a Zip task are instantiated as ZipFileSets, and their attributes > * are only recognized in the context of the the Zip task. > * It is not possible to define a ZipFileSet outside of the Zip task and > * refer to it via a refid. However a standard FileSet may be included by > * reference in the Zip task, and attributes in the refering ZipFileSet > * can augment FileSet definition. > * > * @author Don Ferguson don@bea.com > */ > public class ZipFileSet extends FileSet { > > private String srcFileName = null; > private String prefix = ""; > private String fullpath = ""; > private boolean hasDir = false; > > /** > * Set the directory for the fileset. Prevents both "dir" and "src" > * from being specified. > */ > public void setDir(File dir) throws BuildException { > if (srcFileName != null) { > throw new BuildException("Cannot set both dir and src attributes"); > } else { > super.setDir(dir); > hasDir = true; > } > } > > /** > * Set the source Zip file for the zipfileset. Prevents both "dir" and "src" > * from being specified. > * > * @param srcFileName The zip file from which to extract entries. > */ > public void setSrc(String srcFileName) { > if (hasDir) { > throw new BuildException("Cannot set both dir and src attributes"); > } > this.srcFileName = srcFileName; > } > > /** > * Get the zip file from which entries will be extracted. > * References are not followed, since it is not possible > * to have a reference to a ZipFileSet, only to a FileSet. > */ > public String getSrc() { > return srcFileName; > } > > /** > * Prepend this prefix to the path for each zip entry. > * Does not perform reference test; the referenced file set > * can be augmented with a prefix. > * > * @param prefix The prefix to prepend to entries in the zip file. > */ > public void setPrefix(String prefix) { > this.prefix = prefix; > } > > /** > * Return the prefix prepended to entries in the zip file. > */ > public String getPrefix() { > return prefix; > } > > /** > * Set the full pathname of the single entry in this fileset. > * > * @param prefix The prefix to prepend to entries in the zip file. > */ > public void setFullpath(String fullpath) { > this.fullpath = fullpath; > } > > /** > * Return the full pathname of the single entry in this fileset. > */ > public String getFullpath() { > return fullpath; > } > > /** > * Return the DirectoryScanner associated with this FileSet. > * If the ZipFileSet defines a source Zip file, then a ZipScanner > * is returned instead. > */ > public DirectoryScanner getDirectoryScanner(Project p) { > if (isReference()) { > return getRef(p).getDirectoryScanner(p); > } > if (srcFileName != null) { > ZipScanner zs = new ZipScanner(); > zs.setSrc(srcFileName); > if (getDir(p) == null) { > super.setDir(new File(".")); > } > setupDirectoryScanner(zs, p); > zs.init(); > return zs; > } else { > return super.getDirectoryScanner(p); > } > } > > /** > * Performs the check for circular references and returns the > * referenced FileSet. > */ > private FileSet getRef(Project p) { > if (!checked) { > Stack stk = new Stack(); > stk.push(this); > dieOnCircularReference(stk, p); > } > > Object o = ref.getReferencedObject(p); > if (!(o instanceof FileSet)) { > String msg = ref.getRefId()+" doesn\'t denote a fileset"; > throw new BuildException(msg); > } else { > return (FileSet) o; > } > } > > } > > > ------------------------------------------------------------------------ > > /* > * The Apache Software License, Version 1.1 > * > * Copyright (c) 1999 The Apache Software Foundation. All rights > * reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions > * are met: > * > * 1. Redistributions of source code must retain the above copyright > * notice, this list of conditions and the following disclaimer. > * > * 2. Redistributions in binary form must reproduce the above copyright > * notice, this list of conditions and the following disclaimer in > * the documentation and/or other materials provided with the > * distribution. > * > * 3. The end-user documentation included with the redistribution, if > * any, must include the following acknowlegement: > * "This product includes software developed by the > * Apache Software Foundation (http://www.apache.org/)." > * Alternately, this acknowlegement may appear in the software itself, > * if and wherever such third-party acknowlegements normally appear. > * > * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software > * Foundation" must not be used to endorse or promote products derived > * from this software without prior written permission. For written > * permission, please contact apache@apache.org. > * > * 5. Products derived from this software may not be called "Apache" > * nor may "Apache" appear in their names without prior written > * permission of the Apache Group. > * > * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED > * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES > * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE > * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR > * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, > * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT > * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF > * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND > * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, > * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT > * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF > * SUCH DAMAGE. > * ==================================================================== > * > * This software consists of voluntary contributions made by many > * individuals on behalf of the Apache Software Foundation. For more > * information on the Apache Software Foundation, please see > * . > */ > > package org.apache.tools.ant.types; > > import org.apache.tools.ant.DirectoryScanner; > import java.io.File; > > /** > * ZipScanner accesses the pattern matching algorithm in DirectoryScanner, > * which are protected methods that can only be accessed by subclassing. > * > * This implementation of FileScanner defines getIncludedFiles to return > * only the Zip File which is being scanned, not the matching Zip entries. > * Arguably, it should return the matching entries, however this would > * complicate existing code which assumes that FileScanners return a > * set of file system files that can be accessed directly. > * > * @author Don Ferguson don@bea.com > */ > public class ZipScanner extends DirectoryScanner { > > /** > * The zip file which should be scanned. > */ > protected String srcFile; > > /** > * Sets the srcFile for scanning. This is the jar or zip file that is scanned > * for matching entries. > * > * @param srcFile the (non-null) zip file name for scanning > */ > public void setSrc(String srcFile) { > this.srcFile = srcFile; > } > > /** > * Returns the zip file itself, not the matching entries within the zip file. > * This keeps the uptodate test in the Zip task simple; otherwise we'd need > * to treat zip filesets specially. > * > * @return the source file from which entries will be extracted. > */ > public String[] getIncludedFiles() { > String[] result = new String[1]; > result[0] = srcFile; > return result; > } > > /** > * Returns an empty list of directories to create. > */ > public String[] getIncludedDirectories() { > return new String[0]; > } > > /** > * Initialize DirectoryScanner data structures. > */ > public void init() { > if (includes == null) { > // No includes supplied, so set it to 'matches all' > includes = new String[1]; > includes[0] = "**"; > } > if (excludes == null) { > excludes = new String[0]; > } > } > > /** > * Matches a jar entry against the includes/excludes list, > * normalizing the path separator. > * > * @param path the (non-null) path name to test for inclusion > * > * @return true if the path should be included > * false otherwise. > */ > public boolean match(String path) { > String vpath = path.replace('/', File.separatorChar). > replace('\\', File.separatorChar); > return isIncluded(vpath) && !isExcluded(vpath); > } > > } > > > > > ------------------------------------------------------------------------ > > --------------------------------------------------------------------- > To unsubscribe, e-mail: ant-dev-unsubscribe@jakarta.apache.org > For additional commands, e-mail: ant-dev-help@jakarta.apache.org > Zip.diff > > Content-Type: > > text/plain > Content-Encoding: > > 7bit > > > ------------------------------------------------------------------------ > Jar.diff > > Content-Type: > > text/plain > Content-Encoding: > > 7bit > > > ------------------------------------------------------------------------ > War.diff > > Content-Type: > > text/plain > Content-Encoding: > > 7bit > > > ------------------------------------------------------------------------ > ZipFileSet.java > > Content-Type: > > text/plain > Content-Encoding: > > 7bit > > > ------------------------------------------------------------------------ > ZipScanner.java > > Content-Type: > > text/plain > Content-Encoding: > > 7bit > > > ------------------------------------------------------------------------ > attachment.txt > > Content-Type: > > text/plain --------------040702050002030603040207 Content-Type: text/plain; name="index.diff" Content-Disposition: inline; filename="index.diff" Content-Transfer-Encoding: 7bit Index: docs/index.html =================================================================== RCS file: /home/cvspublic/jakarta-ant/docs/index.html,v retrieving revision 1.188 diff -u -r1.188 index.html --- docs/index.html 2001/01/15 01:22:55 1.188 +++ docs/index.html 2001/01/16 02:54:41 @@ -2943,6 +2943,8 @@ <patternset> elements.

You can also use nested file sets for more flexibility, and specify multiple ones to merge together different trees of files into one JAR. +The extended fileset attributes from the zip task are also available +in the jar task. See the Zip task for more details and examples.

If the manifest is omitted, a simple one will be supplied by Ant. You should not include META-INF/MANIFEST.MF in your set of files. @@ -2952,7 +2954,7 @@ 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 a prefixedfileset in a Zip task. The one difference is that if the +attribute of a fileset 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.)

@@ -5138,7 +5140,9 @@ 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 prefixedfilesets in a Zip or Jar task.)

+attributes of filesets in a Zip or Jar task.)

+

The extended fileset attributes from the zip task (prefix, fullpath, and src) are available for all filesets used in the War task.

+

Parameters

@@ -5243,8 +5247,8 @@ <exclude name="jdbc1.jar"/> </lib> <classes dir="build/main"/> - <prefixedfileset dir="src/graphics/images/gifs" - prefix="images"/> + <fileset dir="src/graphics/images/gifs" + prefix="images"/> </war> will consist of @@ -5287,16 +5291,7 @@ (with basedir set, and optional attributes like includes 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.

-

<zip> elements may contain both regular <fileset> elements -and also <prefixedfileset> elements. A <prefixedfileset> is an extended form of a fileset, -which 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 prefixedfileset are prefixed -with that path in the archive. If the fullpath attribute is set, the file described by the prefixedfileset is placed at that -exact location in the archive. (The fullpath attribute can only be set for prefixedfilesets that -represent a single file. The prefix and fullpath attributes cannot both be set on the -same prefixedfileset.)

+only reflect the relative paths of files within each fileset. A fileset has additional attributes that are available in the context of the Zip task and its derivatives (described below).

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. @@ -5360,6 +5355,18 @@

No
+

Parameters specified as nested elements

+

fileset

+The zip task supports any number of nested <fileset> elements to specify the files to be included in the archive. A <fileset> has three additional attributes when +used in the context of the <zip> task: prefix, fullpath, and src. The +prefix and fullpath attributes modify the location of the files when they are placed +inside the archive. If the prefix attribute is set, all files in the fileset are prefixed +with that path in the archive. If the fullpath attribute is set, the file described by the fileset 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 src attribute +may be used in place of the dir attribute to specify a zip file whose +contents will be extracted and included in the archive. As with directories, include and exclude patterns may be used to specify a subset of the zip file +for inclusion in the archive. +

Examples

  <zip zipfile="${dist}/manual.zip"
        basedir="htdocs/manual"
@@ -5387,13 +5394,18 @@
 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">
-    <prefixedfileset dir="htdocs/manual" prefix="docs/user-guide"/>
-    <prefixedfileset dir="." includes="ChangeLog27.txt" fullpath="docs/ChangeLog.txt"/>
+    <fileset dir="htdocs/manual" prefix="docs/user-guide"/>
+    <fileset dir="." includes="ChangeLog27.txt" fullpath="docs/ChangeLog.txt"/>
+    <fileset src="examples.zip" includes="**/*.html" prefix="docs/examples"/>
   </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

+in the archive, adds the file ChangeLog27.txt in the +current directory as docs/ChangeLog.txt, and includes all the html files in examples.zip under docs/examples. The archive might end up containing the files: +
    docs/user-guide/html/index.html
+    docs/ChangeLog.txt
+    docs/examples/index.html
+
+


Optional tasks

--------------040702050002030603040207 Content-Type: text/plain; name="Zip.diff" Content-Disposition: inline; filename="Zip.diff" Content-Transfer-Encoding: 7bit Index: src/main/org/apache/tools/ant/taskdefs/Zip.java =================================================================== RCS file: /home/cvspublic/jakarta-ant/src/main/org/apache/tools/ant/taskdefs/Zip.java,v retrieving revision 1.26 diff -u -r1.26 Zip.java --- src/main/org/apache/tools/ant/taskdefs/Zip.java 2001/01/08 16:45:32 1.26 +++ src/main/org/apache/tools/ant/taskdefs/Zip.java 2001/01/16 02:48:37 @@ -109,41 +109,19 @@ /** * Adds a set of files (nested fileset attribute). */ - public void addFileset(FileSet set) { + public void addFileset(ZipFileSet set) { filesets.addElement(set); } /** - * Adds a set of files (nested fileset attribute). + * @deprecated addPrefixedfileset is deprecated; replaced by ZipFileSet */ - public void addPrefixedfileset(PrefixedFileSet set) { - addFileset(set); + public void addPrefixedfileset(ZipFileSet set) { + log("WARNING: PrefixedFileSets are deprecated; use the fileset tag instead."); + 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 setFullpath(String loc) { - fullpath = loc; - } - - public String getFullpath() {return fullpath;} - } - /** * Sets behavior of the task when no files match. * Possible values are: fail (throw an exception @@ -164,7 +142,7 @@ public void execute() throws BuildException { 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!" ); + "one fileset must be given!" ); } if (zipFile == null) { @@ -191,7 +169,8 @@ try { boolean success = false; - ZipOutputStream zOut = new ZipOutputStream(new FileOutputStream(zipFile)); + ZipOutputStream zOut = + new ZipOutputStream(new FileOutputStream(zipFile)); try { if (doCompress) { zOut.setMethod(ZipOutputStream.DEFLATED); @@ -283,6 +262,26 @@ } } + protected void addZipEntries(ZipFileSet fs, DirectoryScanner ds, + ZipOutputStream zOut, String prefix) + throws IOException + { + ZipScanner zipScanner = (ZipScanner) ds; + String zipSrc = fs.getSrc(); + + ZipEntry entry; + ZipInputStream in = new ZipInputStream(new FileInputStream(new File(zipSrc))); + while ((entry = in.getNextEntry()) != null) { + String vPath = entry.getName(); + if (zipScanner.match(vPath)) { + addParentDirs(null, vPath, zOut, prefix); + if (! entry.isDirectory()) { + zipFile(in, zOut, prefix+vPath, entry.getTime()); + } + } + } + } + protected void initZipOutputStream(ZipOutputStream zOut) throws IOException, BuildException { @@ -499,28 +498,22 @@ } /** - * Iterate over the given Vector of (prefixed)filesets and add + * Iterate over the given Vector of zipfilesets and add * all files to the ZipOutputStream using the given prefix. */ protected void addFiles(Vector filesets, ZipOutputStream zOut) throws IOException { // Add each fileset in the Vector. for (int i = 0; i 0 && !prefix.endsWith("/") && !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) { @@ -529,8 +522,13 @@ } else if (fullpath.length() > 0) { addParentDirs(null, fullpath, zOut, ""); } - // Add the fileset. - addFiles(ds, zOut, prefix, fullpath); + + if (fs.getSrc() != null) { + addZipEntries(fs, ds, zOut, prefix); + } else { + // Add the fileset. + addFiles(ds, zOut, prefix, fullpath); + } } } --------------040702050002030603040207 Content-Type: text/plain; name="Jar.diff" Content-Disposition: inline; filename="Jar.diff" Content-Transfer-Encoding: 7bit Index: src/main/org/apache/tools/ant/taskdefs/Jar.java =================================================================== RCS file: /home/cvspublic/jakarta-ant/src/main/org/apache/tools/ant/taskdefs/Jar.java,v retrieving revision 1.14 diff -u -r1.14 Jar.java --- src/main/org/apache/tools/ant/taskdefs/Jar.java 2001/01/08 16:45:32 1.14 +++ src/main/org/apache/tools/ant/taskdefs/Jar.java 2001/01/15 22:22:12 @@ -55,6 +55,7 @@ package org.apache.tools.ant.taskdefs; import org.apache.tools.ant.*; +import org.apache.tools.ant.types.ZipFileSet; import java.io.*; import java.util.zip.*; @@ -85,12 +86,12 @@ 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(); + // Create a ZipFileSet for this file, and pass it up. + ZipFileSet fs = new ZipFileSet(); fs.setDir(new File(manifest.getParent())); fs.setIncludes(manifest.getName()); fs.setFullpath("META-INF/MANIFEST.MF"); - super.addPrefixedfileset(fs); + super.addFileset(fs); } --------------040702050002030603040207 Content-Type: text/plain; name="War.diff" Content-Disposition: inline; filename="War.diff" Content-Transfer-Encoding: 7bit Index: src/main/org/apache/tools/ant/taskdefs/War.java =================================================================== RCS file: /home/cvspublic/jakarta-ant/src/main/org/apache/tools/ant/taskdefs/War.java,v retrieving revision 1.9 diff -u -r1.9 War.java --- src/main/org/apache/tools/ant/taskdefs/War.java 2001/01/08 16:45:32 1.9 +++ src/main/org/apache/tools/ant/taskdefs/War.java 2001/01/15 22:22:33 @@ -55,7 +55,7 @@ package org.apache.tools.ant.taskdefs; import org.apache.tools.ant.*; -import org.apache.tools.ant.types.FileSet; +import org.apache.tools.ant.types.ZipFileSet; import java.io.*; import java.util.Vector; @@ -86,30 +86,30 @@ 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(); + // Create a ZipFileSet for this file, and pass it up. + ZipFileSet fs = new ZipFileSet(); fs.setDir(new File(deploymentDescriptor.getParent())); fs.setIncludes(deploymentDescriptor.getName()); fs.setFullpath("WEB-INF/web.xml"); - super.addPrefixedfileset(fs); + super.addFileset(fs); } - public void addLib(PrefixedFileSet fs) { + public void addLib(ZipFileSet fs) { // We just set the prefix for this fileset, and pass it up. fs.setPrefix("WEB-INF/lib/"); - super.addPrefixedfileset(fs); + super.addFileset(fs); } - public void addClasses(PrefixedFileSet fs) { + public void addClasses(ZipFileSet fs) { // We just set the prefix for this fileset, and pass it up. fs.setPrefix("WEB-INF/classes/"); - super.addPrefixedfileset(fs); + super.addFileset(fs); } - public void addWebinf(PrefixedFileSet fs) { + public void addWebinf(ZipFileSet fs) { // We just set the prefix for this fileset, and pass it up. fs.setPrefix("WEB-INF/"); - super.addPrefixedfileset(fs); + super.addFileset(fs); } protected void initZipOutputStream(ZipOutputStream zOut) --------------040702050002030603040207 Content-Type: text/plain; name="ZipFileSet.java" Content-Disposition: inline; filename="ZipFileSet.java" Content-Transfer-Encoding: 7bit /* * The Apache Software License, Version 1.1 * * Copyright (c) 1999 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, if * any, must include the following acknowlegement: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowlegement may appear in the software itself, * if and wherever such third-party acknowlegements normally appear. * * 4. The names "The Jakarta Project", "Ant", and "Apache Software * Foundation" must not be used to endorse or promote products derived * from this software without prior written permission. For written * permission, please contact apache@apache.org. * * 5. Products derived from this software may not be called "Apache" * nor may "Apache" appear in their names without prior written * permission of the Apache Group. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . */ package org.apache.tools.ant.types; import java.io.File; import java.util.Stack; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.DirectoryScanner; import org.apache.tools.ant.Project; /** * A ZipFileSet is a FileSet with extra attributes useful in the context of * Zip/Jar tasks. * * A ZipFileSet extends FileSets with the ability to extract a subset of the * entries of a Zip file for inclusion in another Zip file. It also includes * a prefix attribute which is prepended to each entry in the output Zip file. * * At present, ZipFileSets are not surfaced in the public API. FileSets * nested in a Zip task are instantiated as ZipFileSets, and their attributes * are only recognized in the context of the the Zip task. * It is not possible to define a ZipFileSet outside of the Zip task and * refer to it via a refid. However a standard FileSet may be included by * reference in the Zip task, and attributes in the refering ZipFileSet * can augment FileSet definition. * * @author Don Ferguson don@bea.com */ public class ZipFileSet extends FileSet { private String srcFileName = null; private String prefix = ""; private String fullpath = ""; private boolean hasDir = false; /** * Set the directory for the fileset. Prevents both "dir" and "src" * from being specified. */ public void setDir(File dir) throws BuildException { if (srcFileName != null) { throw new BuildException("Cannot set both dir and src attributes"); } else { super.setDir(dir); hasDir = true; } } /** * Set the source Zip file for the zipfileset. Prevents both "dir" and "src" * from being specified. * * @param srcFileName The zip file from which to extract entries. */ public void setSrc(String srcFileName) { if (hasDir) { throw new BuildException("Cannot set both dir and src attributes"); } this.srcFileName = srcFileName; } /** * Get the zip file from which entries will be extracted. * References are not followed, since it is not possible * to have a reference to a ZipFileSet, only to a FileSet. */ public String getSrc() { return srcFileName; } /** * Prepend this prefix to the path for each zip entry. * Does not perform reference test; the referenced file set * can be augmented with a prefix. * * @param prefix The prefix to prepend to entries in the zip file. */ public void setPrefix(String prefix) { this.prefix = prefix; } /** * Return the prefix prepended to entries in the zip file. */ public String getPrefix() { return prefix; } /** * Set the full pathname of the single entry in this fileset. * * @param prefix The prefix to prepend to entries in the zip file. */ public void setFullpath(String fullpath) { this.fullpath = fullpath; } /** * Return the full pathname of the single entry in this fileset. */ public String getFullpath() { return fullpath; } /** * Return the DirectoryScanner associated with this FileSet. * If the ZipFileSet defines a source Zip file, then a ZipScanner * is returned instead. */ public DirectoryScanner getDirectoryScanner(Project p) { if (isReference()) { return getRef(p).getDirectoryScanner(p); } if (srcFileName != null) { ZipScanner zs = new ZipScanner(); zs.setSrc(srcFileName); if (getDir(p) == null) { super.setDir(new File(".")); } setupDirectoryScanner(zs, p); zs.init(); return zs; } else { return super.getDirectoryScanner(p); } } /** * Performs the check for circular references and returns the * referenced FileSet. */ private FileSet getRef(Project p) { if (!checked) { Stack stk = new Stack(); stk.push(this); dieOnCircularReference(stk, p); } Object o = ref.getReferencedObject(p); if (!(o instanceof FileSet)) { String msg = ref.getRefId()+" doesn\'t denote a fileset"; throw new BuildException(msg); } else { return (FileSet) o; } } } --------------040702050002030603040207 Content-Type: text/plain; name="ZipScanner.java" Content-Disposition: inline; filename="ZipScanner.java" Content-Transfer-Encoding: 7bit /* * The Apache Software License, Version 1.1 * * Copyright (c) 1999 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, if * any, must include the following acknowlegement: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowlegement may appear in the software itself, * if and wherever such third-party acknowlegements normally appear. * * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software * Foundation" must not be used to endorse or promote products derived * from this software without prior written permission. For written * permission, please contact apache@apache.org. * * 5. Products derived from this software may not be called "Apache" * nor may "Apache" appear in their names without prior written * permission of the Apache Group. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . */ package org.apache.tools.ant.types; import org.apache.tools.ant.DirectoryScanner; import java.io.File; /** * ZipScanner accesses the pattern matching algorithm in DirectoryScanner, * which are protected methods that can only be accessed by subclassing. * * This implementation of FileScanner defines getIncludedFiles to return * only the Zip File which is being scanned, not the matching Zip entries. * Arguably, it should return the matching entries, however this would * complicate existing code which assumes that FileScanners return a * set of file system files that can be accessed directly. * * @author Don Ferguson don@bea.com */ public class ZipScanner extends DirectoryScanner { /** * The zip file which should be scanned. */ protected String srcFile; /** * Sets the srcFile for scanning. This is the jar or zip file that is scanned * for matching entries. * * @param srcFile the (non-null) zip file name for scanning */ public void setSrc(String srcFile) { this.srcFile = srcFile; } /** * Returns the zip file itself, not the matching entries within the zip file. * This keeps the uptodate test in the Zip task simple; otherwise we'd need * to treat zip filesets specially. * * @return the source file from which entries will be extracted. */ public String[] getIncludedFiles() { String[] result = new String[1]; result[0] = srcFile; return result; } /** * Returns an empty list of directories to create. */ public String[] getIncludedDirectories() { return new String[0]; } /** * Initialize DirectoryScanner data structures. */ public void init() { if (includes == null) { // No includes supplied, so set it to 'matches all' includes = new String[1]; includes[0] = "**"; } if (excludes == null) { excludes = new String[0]; } } /** * Matches a jar entry against the includes/excludes list, * normalizing the path separator. * * @param path the (non-null) path name to test for inclusion * * @return true if the path should be included * false otherwise. */ public boolean match(String path) { String vpath = path.replace('/', File.separatorChar). replace('\\', File.separatorChar); return isIncluded(vpath) && !isExcluded(vpath); } } --------------040702050002030603040207--