Browse Source

Patch to unify handling of prefix filesets between war/jar/zip.

It also removes a number of small errors in zip task.
Deprecated <prefixedfileset> element of war in favour of normal <fileset> element in zip

Submitted By: "Rosen, Alex" <arosen@silverstream.com>


git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@268344 13f79535-47bb-0310-9956-ffa450edef68
master
Peter Donald 24 years ago
parent
commit
8e955e3a2e
4 changed files with 165 additions and 241 deletions
  1. +38
    -75
      docs/index.html
  2. +36
    -52
      src/main/org/apache/tools/ant/taskdefs/Jar.java
  3. +39
    -63
      src/main/org/apache/tools/ant/taskdefs/War.java
  4. +52
    -51
      src/main/org/apache/tools/ant/taskdefs/Zip.java

+ 38
- 75
docs/index.html View File

@@ -2725,6 +2725,11 @@ You should not include <samp>META-INF/MANIFEST.MF</samp> in your set of files.
If <code>create</code> (the default), the JAR is created anyway with only a manifest.
If <code>skip</code>, the JAR is not created and a warning is issued.
If <code>fail</code>, the JAR is not created and the build is halted with an error.
<p>(The Jar task is a shortcut for specifying the manifest file of a JAR file.
The same thing can be accomplished by using the <i>fullpath</i>
attribute of the filesets in a Zip task. The one difference is that if the
<i>manifest</i> attribute is not specified, the Jar task will
include an empty one for you.)</p>
</p>
<h3>Parameters</h3>
<table border="1" cellpadding="2" cellspacing="0">
@@ -2791,13 +2796,13 @@ If <code>fail</code>, the JAR is not created and the build is halted with an err
</table>
<h3>Examples</h3>
<pre> &lt;jar jarfile=&quot;${dist}/lib/app.jar&quot; basedir=&quot;${build}/classes&quot; /&gt;</pre>
<p>jars all files in the <code>${build}/classes</code> directory in a file
<p>jars all files in the <code>${build}/classes</code> directory into a file
called <code>app.jar</code> in the <code>${dist}/lib</code> directory.</p>
<pre> &lt;jar jarfile=&quot;${dist}/lib/app.jar&quot;
basedir=&quot;${build}/classes&quot;
excludes=&quot;**/Test.class&quot;
/&gt;</pre>
<p>jars all files in the <code>${build}/classes</code> directory in a file
<p>jars all files in the <code>${build}/classes</code> directory into a file
called <code>app.jar</code> in the <code>${dist}/lib</code> directory. Files
with the name <code>Test.class</code> are excluded.</p>
<pre> &lt;jar jarfile=&quot;${dist}/lib/app.jar&quot;
@@ -2805,7 +2810,7 @@ with the name <code>Test.class</code> are excluded.</p>
includes=&quot;mypackage/test/**&quot;
excludes=&quot;**/Test.class&quot;
/&gt;</pre>
<p>jars all files in the <code>${build}/classes</code> directory in a file
<p>jars all files in the <code>${build}/classes</code> directory into a file
called <code>app.jar</code> in the <code>${dist}/lib</code> directory. Only
files under the directory <code>mypackage/test</code> are used, and files with
the name <code>Test.class</code> are excluded.</p>
@@ -2816,7 +2821,7 @@ the name <code>Test.class</code> are excluded.</p>
&lt;fileset dir=&quot;${src}/resources&quot;/&gt;
&lt;/jar&gt;</pre>
<p>jars all files in the <code>${build}/classes</code> directory and also
in the <code>${src}/resources</code> directory together in a file
in the <code>${src}/resources</code> directory together into a file
called <code>app.jar</code> in the <code>${dist}/lib</code> directory.
Files with the name <code>Test.class</code> are excluded.
If there are files such as <code>${build}/classes/mypackage/MyClass.class</code>
@@ -4434,14 +4439,14 @@ task to come up with a .tar.gz package.</p>
<h3>Examples</h3>
<pre> &lt;tar tarfile=&quot;${dist}/manual.tar&quot; basedir=&quot;htdocs/manual&quot; /&gt;
&lt;gzip zipfile=&quot;${dist}/manual.tar.gz&quot; src=&quot;${dist}/manual.tar&quot; /&gt;</pre>
<p>tars all files in the <code>htdocs/manual</code> directory in a file called <code>manual.tar</code>
<p>tars all files in the <code>htdocs/manual</code> directory into a file called <code>manual.tar</code>
in the <code>${dist}</code> directory, then applies the gzip task to compress
it.</p>
<pre> &lt;tar tarfile=&quot;${dist}/manual.tar&quot;
basedir=&quot;htdocs/manual&quot;
excludes=&quot;mydocs/**, **/todo.html&quot;
/&gt;</pre>
<p>tars all files in the <code>htdocs/manual</code> directory in a file called <code>manual.tar</code>
<p>tars all files in the <code>htdocs/manual</code> directory into a file called <code>manual.tar</code>
in the <code>${dist}</code> directory. Files in the directory <code>mydocs</code>,
or files with the name <code>todo.html</code> are excluded.</p>
<hr>
@@ -4779,10 +4784,10 @@ carried from tarfile.</p>
<p>An extension of the <a href="#jar">Jar</a> task with special
treatment for files that should end up in the
<code>WEB-INF/lib</code>, <code>WEB-INF/classes</code> or
<code>WEB-INF</code> 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 <code>prefixedfileset</code>
element.</p>
<code>WEB-INF</code> directories of the Web Application Archive.
<p>(The War task is a shortcut for specifying the particular layout of a WAR file.
The same thing can be accomplished by using the <i>prefix</i> and <i>fullpath</i>
attributes of the filesets in a Zip or Jar task.)</p>
<h3>Parameters</h3>
<table border="1" cellpadding="2" cellspacing="0">
<tr>
@@ -4866,60 +4871,6 @@ href="#fileset">FileSet</a>. All files included in this fileset will
end up in the <code>WEB-INF</code> directory of the war file. If this
fileset includes a file named <code>web.xml</code>, the file is
ignored and you will get a warning.</p>
<h4>prefixedfileset</h4>
<p>The nested <code>prefixedfileset</code> element specifies a <a
href="#fileset">FileSet</a> with an additional prefix attribute. All
files included in this fileset will end up in the <em>prefix</em>
directory of the war file, where <em>prefix</em> is the value of the
<code>prefix</code> attribute.</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">prefix</td>
<td valign="top">The prefix directory to add to each filename when
adding it to the archive. Default is none.</td>
<td valign="top" align="center">No</td>
</tr>
<tr>
<td valign="top">dir</td>
<td valign="top">The root of the directory tree of this FileSet.</td>
<td valign="top" align="center">Yes</td>
</tr>
<tr>
<td valign="top">defaultexcludes</td>
<td valign="top">indicates whether default excludes should be used or not
(&quot;yes&quot;/&quot;no&quot;). Default excludes are used when omitted.</td>
<td valign="top" align="center">No</td>
</tr>
<tr>
<td valign="top">includes</td>
<td valign="top">comma separated list of patterns of files that must be
included. All files are included when omitted.</td>
<td valign="top" align="center">No</td>
</tr>
<tr>
<td valign="top">includesfile</td>
<td valign="top">the name of a file. Each line of this file is
taken to be an include pattern</td>
<td valign="top" align="center">No</td>
</tr>
<tr>
<td valign="top">excludes</td>
<td valign="top">comma separated list of patterns of files that must be
excluded. No files (except default excludes) are excluded when omitted.</td>
<td valign="top" align="center">No</td>
</tr>
<tr>
<td valign="top">excludesfile</td>
<td valign="top">the name of a file. Each line of this file is
taken to be an exclude pattern</td>
<td valign="top" align="center">No</td>
</tr>
</table>
<h3>Examples</h3>
<p>Assume the following structure in the project's base directory:
<pre>
@@ -4941,7 +4892,7 @@ then the war file <code>myapp.war</code> created with
&lt;exclude name=&quot;jdbc1.jar&quot; /&gt;
&lt;/lib&gt;
&lt;classes dir=&quot;build/main&quot; /&gt;
&lt;prefixedfileset dir=&quot;src/graphics/images/gifs&quot;
&lt;fileset dir=&quot;src/graphics/images/gifs&quot;
prefix="images"/&gt;
&lt;/war&gt;
</pre>
@@ -4986,6 +4937,13 @@ if <code>basedir</code> is set. You may use any mixture of the implicit file set
and optional subelements like <code>&lt;include&gt;</code>); explicit nested
<code>&lt;fileset&gt;</code> elements so long as at least one fileset total is specified. The ZIP file will
only reflect the relative paths of files <em>within</em> each fileset.</p>
<p>Inside of <code>&lt;zip&gt;</code> elements, nested filesets may include one of two special attributes:
<i>prefix</i> or <i>fullpath</i>. These attributes modify the location of the files when they are placed
inside the archive. If the <i>prefix</i> attribute is set, all the files in the fileset are prefixed
with that path in the archive. If the <i>fullpath</i> attribute is set, the file described by the filset is placed at that
exact location in the archive. (The <i>fullpath</i> attribute can only be set for filesets that
represent a single file. The <i>prefix</i> and <i>fullpath</i> attributes cannot both be set on the
same fileset.)</p>
<p>The <code>whenempty</code> parameter controls what happens when no files match.
If <code>skip</code> (the default), the ZIP is not created and a warning is issued.
If <code>fail</code>, 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.</p>
<pre> &lt;zip zipfile=&quot;${dist}/manual.zip&quot;
basedir=&quot;htdocs/manual&quot;
/&gt;</pre>
<p>zips all files in the <code>htdocs/manual</code> directory in a file called <code>manual.zip</code>
<p>zips all files in the <code>htdocs/manual</code> directory into a file called <code>manual.zip</code>
in the <code>${dist}</code> directory.</p>
<pre> &lt;zip zipfile=&quot;${dist}/manual.zip&quot;
basedir=&quot;htdocs/manual&quot;
excludes=&quot;mydocs/**, **/todo.html&quot;
/&gt;</pre>
<p>zips all files in the <code>htdocs/manual</code> directory in a file called <code>manual.zip</code>
in the <code>${dist}</code> directory. Files in the directory <code>mydocs</code>,
<p>zips all files in the <code>htdocs/manual</code> directory. Files in the directory <code>mydocs</code>,
or files with the name <code>todo.html</code> are excluded.</p>
<pre> &lt;zip zipfile=&quot;${dist}/manual.zip&quot;
basedir=&quot;htdocs/manual&quot;
includes=&quot;api/**/*.html&quot;
excludes=&quot;**/todo.html&quot;
/&gt;</pre>
<p>zips all files in the <code>htdocs/manual</code> directory in a file called <code>manual.zip</code>
in the <code>${dist}</code> directory. Only html files under the directory <code>api</code>
<p>zips all files in the <code>htdocs/manual</code> directory. Only html files under the directory <code>api</code>
are zipped, and files with the name <code>todo.html</code> are excluded.</p>
<pre> &lt;zip zipfile=&quot;${dist}/manual.zip&quot;&gt;
&lt;fileset dir=&quot;htdocs/manual&quot;/&gt;
&lt;fileset dir=&quot;.&quot; includes=&quot;ChangeLog.txt&quot;/&gt;
&lt;/zip&gt;</pre>
<p>zips all files in the <code>htdocs/manual</code> directory in a file called <code>manual.zip</code>
in the <code>${dist}</code> directory, and also adds the file <code>ChangeLog.txt</code> in the
<p>zips all files in the <code>htdocs/manual</code> directory, and also adds the file <code>ChangeLog.txt</code> in the
current directory. <code>ChangeLog.txt</code> will be added to the top of the ZIP file, just as if
it had been located at <code>htdocs/manual/ChangeLog.txt</code>.</p>
<pre> &lt;zip zipfile=&quot;${dist}/manual.zip&quot;&gt;
&lt;fileset dir=&quot;htdocs/manual&quot; prefix=&quot;docs/user-guide&quot;/&gt;
&lt;fileset dir=&quot;.&quot; includes=&quot;ChangeLog27.txt&quot; fullpath=&quot;docs/ChangeLog.txt&quot;/&gt;
&lt;/zip&gt;</pre>
<p>zips all files in the <code>htdocs/manual</code> directory into the <code>docs/user-guide</code> directory
in the archive, and also adds the file <code>ChangeLog27.txt</code> in the
current directory as <code>docs/ChangeLog.txt</code>. For example, the archive might end up containing two files:
<code>docs/user-guide/html/index.html</code> and <code>docs/ChangeLog.txt</code></p>

<hr>
<h2><a name="optionaltasks">Optional tasks</a></h2>
@@ -5188,7 +5151,7 @@ supports all attributes of <code>&lt;fileset&gt;</code>
basedir=&quot;htdocs/manual&quot;
/&gt;
</pre></blockquote>
<p>cabs all files in the htdocs/manual directory in a file called
<p>cabs all files in the htdocs/manual directory into a file called
manual.cab in the ${dist} directory.</p>
<blockquote><pre>
&lt;cab cabfile=&quot;${dist}/manual.cab&quot;
@@ -5196,7 +5159,7 @@ manual.cab in the ${dist} directory.</p>
excludes=&quot;mydocs/**, **/todo.html&quot;
/&gt;
</pre></blockquote>
<p>cabs all files in the htdocs/manual directory in a file called
<p>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.</p>
<blockquote><pre>
@@ -5207,7 +5170,7 @@ or files with the name todo.html are excluded.</p>
verbose=&quot;yes&quot;
/&gt;
</pre></blockquote>
<p>cab all files in the htdocs/manual directory in a file called
<p>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


+ 36
- 52
src/main/org/apache/tools/ant/taskdefs/Jar.java View File

@@ -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 <fileset> 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);
}
}

}

+ 39
- 63
src/main/org/apache/tools/ant/taskdefs/War.java View File

@@ -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 <fileset> 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);
}
}
}
}

+ 52
- 51
src/main/org/apache/tools/ant/taskdefs/Zip.java View File

@@ -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; i<fileSets.size(); i++) {
FileSet fs = (FileSet) fileSets.elementAt(i);
scanners[startIndex+i] = fs.getDirectoryScanner(project);
}
}

/**
* Add all files of the given FileScanner to the ZipOutputStream
* prependig the given prefix to each filename.
@@ -244,11 +234,16 @@ public class Zip extends MatchingTask {
* <p>Ensure 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<v.size(); i++) {
FileSet fs = (FileSet) v.elementAt(i);
DirectoryScanner ds = fs.getDirectoryScanner(project);
addFiles(ds, zOut, prefix);
}
}

/**
* Iterate over the given Vector of prefixedfilesets and add
* all files to the ZipOutputStream using the given prefix.
*/
protected void addPrefixedFiles(Vector v, ZipOutputStream zOut)
protected void addFiles(Vector filesets, ZipOutputStream zOut)
throws IOException {
for (int i=0; i<v.size(); i++) {
PrefixedFileSet fs = (PrefixedFileSet) v.elementAt(i);
// Add each fileset in the Vector.
for (int i = 0; i<filesets.size(); i++) {
PrefixedFileSet fs = (PrefixedFileSet) filesets.elementAt(i);
DirectoryScanner ds = fs.getDirectoryScanner(project);
String prefix = fs.getPrefix();
if (prefix.length() > 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);
}
}
}

Loading…
Cancel
Save