Browse Source

allow to define ZipFileSet(s) outside of Zip task bugrep 17007

git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@274481 13f79535-47bb-0310-9956-ffa450edef68
master
Antoine Levy-Lambert 22 years ago
parent
commit
bddaffe76d
7 changed files with 338 additions and 92 deletions
  1. +5
    -56
      docs/manual/CoreTasks/zip.html
  2. +96
    -0
      docs/manual/CoreTypes/zipfileset.html
  3. +1
    -0
      docs/manual/conceptstypeslist.html
  4. +14
    -15
      src/main/org/apache/tools/ant/taskdefs/Zip.java
  5. +65
    -20
      src/main/org/apache/tools/ant/types/ZipFileSet.java
  6. +1
    -1
      src/main/org/apache/tools/ant/types/defaults.properties
  7. +156
    -0
      src/testcases/org/apache/tools/ant/types/ZipFileSetTest.java

+ 5
- 56
docs/manual/CoreTasks/zip.html View File

@@ -60,7 +60,7 @@ Java.</p>

<p>Starting with Ant 1.5.2, &lt;zip&gt; can store Unix permissions
inside the archive (see description of the filemode and dirmode
attributes for <a href="#zipfileset">&lt;zipfileset&gt;</a>).
attributes for <a href="../CoreTypes/zipfileset.html">&lt;zipfileset&gt;</a>).
Unfortunately there is no portable way to store these permissions.
Ant uses the algorithm used by <a href="http://www.info-zip.org">Info-Zip's</a>
implementation of the zip and unzip commands - these are the default
@@ -158,62 +158,11 @@ versions of zip and unzip for many Unix and Unix-like systems.</p>
href="../CoreTypes/fileset.html"><code>&lt;fileset&gt;</code></a> elements to specify
the files to be included in the archive.</p>

<h4><a name="zipfileset">zipfileset</a></h4>
<h4>zipfileset</h4>

<p>A <code>&lt;zipfileset&gt;</code> is a special form of a
<code>&lt;fileset&gt;</code> that adds some extra functionality. It
supports all attributes of <code>&lt;fileset&gt;</code> in addition to
those listed below.</p>

<h3>Parameters</h3>
<table border="1" cellpadding="2" cellspacing="0">
<tr>
<td valign="top"><b>Attribute</b></td>
<td valign="top"><b>Description</b></td>
<td valign="top" align="center"><b>Required</b></td>
</tr>
<tr>
<td valign="top">prefix</td>
<td valign="top">all files in the fileset are prefixed with that
path in the archive.</td>
<td align="center" valign="top">No</td>
</tr>
<tr>
<td valign="top">fullpath</td>
<td valign="top">the file described by the fileset is placed at
that exact location in the archive.</td>
<td align="center" valign="top">No</td>
</tr>
<tr>
<td valign="top">src</td>
<td valign="top">may be used in place of the <i>dir</i> attribute
to specify a zip file whose contents will be extracted and
included in the archive.</td>
<td align="center" valign="top">No</td>
</tr>
<tr>
<td valign="top">filemode</td>
<td valign="top">A 3 digit octal string, specify the user, group
and other modes in the standard Unix fashion. Only applies to
plain files. Default is 644. <em>since Ant 1.5.2</em>.</td>
<td align="center" valign="top">No</td>
</tr>
<tr>
<td valign="top">dirmode</td>
<td valign="top">A 3 digit octal string, specify the user, group
and other modes in the standard Unix fashion. Only applies to
directories. Default is 755. <em>since Ant 1.5.2</em>.</td>
<td align="center" valign="top">No</td>
</tr>
</table>

<p>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>When using the <i>src</i> attribute, include and exclude patterns
may be used to specify a subset of the zip file for inclusion in the
archive as with the <i>dir</i> attribute.</p>
<p>The zip task supports any number of nested <a
href="../CoreTypes/zipfileset.html"><code>&lt;zipfileset&gt;</code></a> elements to specify
the files to be included in the archive.</p>

<h4>zipgroupfileset</h4>
<p>A <code>&lt;zipgroupfileset&gt;</code> allows for multiple zip files to be


+ 96
- 0
docs/manual/CoreTypes/zipfileset.html View File

@@ -0,0 +1,96 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Language" content="en-us">
<title>ZipFileSet Type</title>
</head>
<body>
<h2><a name="fileset">ZipFileSet</a></h2>
<p>A <code>&lt;zipfileset&gt;</code> is a special form of a <code>&lt;<a
href="fileset.html">fileset</a>&gt;</code> which can behave in 2
different ways : <br>
</p>
<ul>
<li>When the <span style="font-style: italic;">src</span> attribute
is used, the zipfileset is populated with zip entries found in the file <span
style="font-style: italic;">src</span>.<br>
</li>
<li>When the <span style="font-style: italic;">dir</span> attribute
is used, the zipfileset is populated with filesystem files found under <span
style="font-style: italic;">dir</span>.<br>
</li>
</ul>
<p><code>&lt;zipfileset&gt;</code> supports all attributes of <code>&lt;<a
href="file:///C:/dev/gnu/ant/docs/manual/CoreTypes/fileset.html">fileset</a>&gt;</code>
in addition to those listed below.<br>
</p>
<p>Since Ant 1.6, a zipfileset can be defined with the <span
style="font-style: italic;">id </span>attribute and referred to with
the <span style="font-style: italic;">refid</span> attribute.<br>
</p>
<h3>Parameters</h3>
<table border="1" cellpadding="2" cellspacing="0">
<tbody>
<tr>
<td valign="top"><b>Attribute</b></td>
<td valign="top"><b>Description</b></td>
<td valign="top" align="center"><b>Required</b></td>
</tr>
<tr>
<td valign="top">prefix</td>
<td valign="top">all files in the fileset are prefixed with that
path in the archive.</td>
<td align="center" valign="top">No</td>
</tr>
<tr>
<td valign="top">fullpath</td>
<td valign="top">the file described by the fileset is placed at
that exact location in the archive.</td>
<td align="center" valign="top">No</td>
</tr>
<tr>
<td valign="top">src</td>
<td valign="top">may be used in place of the <i>dir</i> attribute
to specify a zip file whose contents will be extracted and included
in the archive.</td>
<td align="center" valign="top">No</td>
</tr>
<tr>
<td valign="top">filemode</td>
<td valign="top">A 3 digit octal string, specify the user, group
and other modes in the standard Unix fashion. Only applies to
plain files. Default is 644. <em>since Ant 1.5.2</em>.</td>
<td align="center" valign="top">No</td>
</tr>
<tr>
<td valign="top">dirmode</td>
<td valign="top">A 3 digit octal string, specify the user, group
and other modes in the standard Unix fashion. Only applies to
directories. Default is 755. <em>since Ant 1.5.2</em>.</td>
<td align="center" valign="top">No</td>
</tr>
</tbody>
</table>
<p>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>When using the <i>src</i> attribute, include and exclude patterns
may be used to specify a subset of the zip file for inclusion in the
archive as with the <i>dir</i> attribute.</p>
<h4>Examples</h4>
<blockquote>
<pre> &lt;zip destfile="${dist}/manual.zip"&gt;<br> &lt;zipfileset dir="htdocs/manual" prefix="docs/user-guide"/&gt;<br> &lt;zipfileset dir="." includes="ChangeLog27.txt" fullpath="docs/ChangeLog.txt"/&gt;<br> &lt;zipfileset src="examples.zip" includes="**/*.html" prefix="docs/examples"/&gt;<br> &lt;/zip&gt;<br></pre>
<p>zips all files in the <code>htdocs/manual</code> directory into
the <code>docs/user-guide</code> directory in the archive, adds the
file <code>ChangeLog27.txt</code> in the current directory as <code>docs/ChangeLog.txt</code>,
and includes all the html files in <code>examples.zip</code> under <code>docs/examples</code>.
The archive might end up containing the files:</p>
<code> docs/user-guide/html/index.html<br>
docs/ChangeLog.txt<br>
docs/examples/index.html<br>
</code></blockquote>
<hr>
<p align="center">Copyright &copy; 2003 Apache Software Foundation. All
rights Reserved.</p>
</body>
</html>

+ 1
- 0
docs/manual/conceptstypeslist.html View File

@@ -27,6 +27,7 @@
<a href="using.html#path">Path-like Structures</a><br>
<a href="CoreTypes/selectors.html">Selectors</a><br>
<a href="CoreTypes/xmlcatalog.html">XMLCatalog</a><br>
<a href="CoreTypes/zipfileset.html">ZipFileSet</a><br>

<h3>Optional Types</h3>
<a href="OptionalTypes/classfileset.html">Class Fileset</a><br>


+ 14
- 15
src/main/org/apache/tools/ant/taskdefs/Zip.java View File

@@ -67,7 +67,6 @@ import java.util.Stack;
import java.util.Vector;
import java.util.zip.CRC32;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.DirectoryScanner;
@@ -541,10 +540,10 @@ public class Zip extends MatchingTask {
ZipFileSet zfs = null;
if (fileset instanceof ZipFileSet) {
zfs = (ZipFileSet) fileset;
prefix = zfs.getPrefix();
fullpath = zfs.getFullpath();
dirMode = zfs.getDirMode();
fileMode = zfs.getFileMode();
prefix = zfs.getPrefix(getProject());
fullpath = zfs.getFullpath(getProject());
dirMode = zfs.getDirMode(getProject());
fileMode = zfs.getFileMode(getProject());
}

if (prefix.length() > 0 && fullpath.length() > 0) {
@@ -570,11 +569,11 @@ public class Zip extends MatchingTask {
boolean dealingWithFiles = false;
File base = null;

if (zfs == null || zfs.getSrc() == null) {
if (zfs == null || zfs.getSrc(getProject()) == null) {
dealingWithFiles = true;
base = fileset.getDir(getProject());
} else {
zf = new ZipFile(zfs.getSrc());
zf = new ZipFile(zfs.getSrc(getProject()));
}
for (int i = 0; i < resources.length; i++) {
@@ -604,7 +603,7 @@ public class Zip extends MatchingTask {
zf.getEntry(resources[i].getName());
if (ze != null) {
zipFile(zf.getInputStream(ze), zOut, prefix + name,
ze.getTime(), zfs.getSrc(), fileMode);
ze.getTime(), zfs.getSrc(getProject()), fileMode);
}
}
}
@@ -763,7 +762,7 @@ public class Zip extends MatchingTask {

for (int i = 0; i < filesets.length; i++) {
if (!(fileset instanceof ZipFileSet)
|| ((ZipFileSet) fileset).getSrc() == null) {
|| ((ZipFileSet) fileset).getSrc(getProject()) == null) {
File base = filesets[i].getDir(getProject());
for (int j = 0; j < initialResources[i].length; j++) {
@@ -787,20 +786,20 @@ public class Zip extends MatchingTask {
FileNameMapper myMapper = new IdentityMapper();
if (filesets[i] instanceof ZipFileSet) {
ZipFileSet zfs = (ZipFileSet) filesets[i];
if (zfs.getFullpath() != null
&& !zfs.getFullpath().equals("") ) {
if (zfs.getFullpath(getProject()) != null
&& !zfs.getFullpath(getProject()).equals("") ) {
// in this case all files from origin map to
// the fullPath attribute of the zipfileset at
// destination
MergingMapper fm = new MergingMapper();
fm.setTo(zfs.getFullpath());
fm.setTo(zfs.getFullpath(getProject()));
myMapper = fm;

} else if (zfs.getPrefix() != null
&& !zfs.getPrefix().equals("")) {
} else if (zfs.getPrefix(getProject()) != null
&& !zfs.getPrefix(getProject()).equals("")) {
GlobPatternMapper gm=new GlobPatternMapper();
gm.setFrom("*");
String prefix = zfs.getPrefix();
String prefix = zfs.getPrefix(getProject());
if (!prefix.endsWith("/") && !prefix.endsWith("\\")) {
prefix += "/";
}


+ 65
- 20
src/main/org/apache/tools/ant/types/ZipFileSet.java View File

@@ -68,15 +68,10 @@ import org.apache.tools.zip.UnixStat;
* 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.
* Since ant 1.6 ZipFileSet can be defined with an id and referenced in packaging tasks
*
* @author Don Ferguson <a href="mailto:don@bea.com">don@bea.com</a>
* @author <a href="mailto:levylambert@tiscali-dsl.de">Antoine Levy-Lambert</a>
*/
public class ZipFileSet extends FileSet {

@@ -126,6 +121,9 @@ public class ZipFileSet extends FileSet {
* from being specified.
*/
public void setDir(File dir) throws BuildException {
if (isReference()) {
throw tooManyAttributes();
}
if (srcFile != null) {
throw new BuildException("Cannot set both dir and src attributes");
} else {
@@ -141,6 +139,9 @@ public class ZipFileSet extends FileSet {
* @param srcFile The zip file from which to extract entries.
*/
public void setSrc(File srcFile) {
if (isReference()) {
throw tooManyAttributes();
}
if (hasDir) {
throw new BuildException("Cannot set both dir and src attributes");
}
@@ -152,41 +153,62 @@ public class ZipFileSet extends FileSet {
* References are not followed, since it is not possible
* to have a reference to a ZipFileSet, only to a FileSet.
*/
public File getSrc() {
public File getSrc(Project p) {
if (isReference()) {
return ((ZipFileSet)getRef(p)).getSrc(p);
}
return srcFile;
}

/**
* 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.
* Prevents both prefix and fullpath from being specified
*
* @param prefix The prefix to prepend to entries in the zip file.
*/
public void setPrefix(String prefix) {
if (isReference()) {
throw tooManyAttributes();
}
if (!fullpath.equals("")) {
throw new BuildException("Cannot set both fullpath and prefix attributes");
}
this.prefix = prefix;
}

/**
* Return the prefix prepended to entries in the zip file.
*/
public String getPrefix() {
public String getPrefix(Project p) {
if (isReference()) {
return ((ZipFileSet)getRef(p)).getPrefix(p);
}
return prefix;
}

/**
* Set the full pathname of the single entry in this fileset.
* Prevents both prefix and fullpath from being specified
*
* @param fullpath the full pathname of the single entry in this fileset.
*/
public void setFullpath(String fullpath) {
if (isReference()) {
throw tooManyAttributes();
}
if (!prefix.equals("")) {
throw new BuildException("Cannot set both fullpath and prefix attributes");
}
this.fullpath = fullpath;
}

/**
* Return the full pathname of the single entry in this fileset.
*/
public String getFullpath() {
public String getFullpath(Project p) {
if (isReference()) {
return ((ZipFileSet)getRef(p)).getFullpath(p);
}
return fullpath;
}

@@ -219,14 +241,20 @@ public class ZipFileSet extends FileSet {
* @since Ant 1.5.2
*/
public void setFileMode(String octalString) {
this.fileMode =
if (isReference()) {
throw tooManyAttributes();
}
this.fileMode =
UnixStat.FILE_FLAG | Integer.parseInt(octalString, 8);
}
/**
* @since Ant 1.5.2
*/
public int getFileMode() {
public int getFileMode(Project p) {
if (isReference()) {
return ((ZipFileSet)getRef(p)).getFileMode(p);
}
return fileMode;
}
@@ -238,20 +266,25 @@ public class ZipFileSet extends FileSet {
* @since Ant 1.6
*/
public void setDirMode(String octalString) {
this.dirMode =
if (isReference()) {
throw tooManyAttributes();
}
this.dirMode =
UnixStat.DIR_FLAG | Integer.parseInt(octalString, 8);
}
/**
* @since Ant 1.6
*/
public int getDirMode() {
public int getDirMode(Project p) {
if (isReference()) {
return ((ZipFileSet)getRef(p)).getDirMode(p);
}
return dirMode;
}

/**
* A ZipFileset can accept any fileset as a reference as it just uses the
* standard directory scanner.
* A ZipFileset accepts only another ZipFileSet as reference
*/
protected AbstractFileSet getRef(Project p) {
if (!isChecked()) {
@@ -261,11 +294,23 @@ public class ZipFileSet extends FileSet {
}

Object o = getRefid().getReferencedObject(p);
if (!(o instanceof FileSet)) {
String msg = getRefid().getRefId() + " doesn\'t denote a fileset";
if (!(o instanceof ZipFileSet)) {
String msg = getRefid().getRefId() + " doesn\'t denote a zipfileset";
throw new BuildException(msg);
} else {
return (AbstractFileSet) o;
}
}
/**
* Return a ZipFileSet that has the same properties
* as this one.
* @since Ant 1.6
*/
public Object clone() {
if (isReference()) {
return new ZipFileSet((ZipFileSet) getRef(getProject()));
} else {
return new ZipFileSet(this);
}
}
}

+ 1
- 1
src/main/org/apache/tools/ant/types/defaults.properties View File

@@ -16,5 +16,5 @@ extensionSet=org.apache.tools.ant.taskdefs.optional.extension.ExtensionSet
extension=org.apache.tools.ant.taskdefs.optional.extension.ExtensionAdapter
libfileset=org.apache.tools.ant.taskdefs.optional.extension.LibFileSet
selector=org.apache.tools.ant.types.selectors.SelectSelector
zipfileset=org.apache.tools.ant.types.ZipFileSet
scriptfilter=org.apache.tools.ant.types.optional.ScriptFilter


+ 156
- 0
src/testcases/org/apache/tools/ant/types/ZipFileSetTest.java View File

@@ -0,0 +1,156 @@
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2003 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 "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
* <http://www.apache.org/>.
*/

package org.apache.tools.ant.types;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;

import junit.framework.TestCase;
import junit.framework.AssertionFailedError;

import java.io.File;

/**
* JUnit 3 testcases for org.apache.tools.ant.types.ZipFileSet.
*
* <p>This doesn't actually test much, mainly reference handling.
*
* @author Antoine Levy-Lambert
*/

public class ZipFileSetTest extends AbstractFileSetTest {

public ZipFileSetTest(String name) {
super(name);
}

protected AbstractFileSet getInstance() {
return new ZipFileSet();
}
public final void testAttributes() {
ZipFileSet f = (ZipFileSet)getInstance();
//check that dir and src are incompatible
f.setSrc(new File("example.zip"));
try {
f.setDir(new File("examples"));
fail("can add dir to "
+ f.getDataTypeName()
+ " when a src is already present");
} catch (BuildException be) {
assertEquals("Cannot set both dir and src attributes",be.getMessage());
}
f = (ZipFileSet)getInstance();
//check that dir and src are incompatible
f.setDir(new File("examples"));
try {
f.setSrc(new File("example.zip"));
fail("can add src to "
+ f.getDataTypeName()
+ " when a dir is already present");
} catch (BuildException be) {
assertEquals("Cannot set both dir and src attributes",be.getMessage());
}
//check that fullpath and prefix are incompatible
f = (ZipFileSet)getInstance();
f.setSrc(new File("example.zip"));
f.setPrefix("/examples");
try {
f.setFullpath("/doc/manual/index.html");
fail("Can add fullpath to "
+ f.getDataTypeName()
+ " when a prefix is already present");
} catch (BuildException be) {
assertEquals("Cannot set both fullpath and prefix attributes", be.getMessage());
}
f = (ZipFileSet)getInstance();
f.setSrc(new File("example.zip"));
f.setFullpath("/doc/manual/index.html");
try {
f.setPrefix("/examples");
fail("Can add prefix to "
+ f.getDataTypeName()
+ " when a fullpath is already present");
} catch (BuildException be) {
assertEquals("Cannot set both fullpath and prefix attributes", be.getMessage());
}
// check that reference zipfilesets cannot have specific attributes
f = (ZipFileSet)getInstance();
f.setRefid(new Reference("test"));
try {
f.setSrc(new File("example.zip"));
fail("Can add src to "
+ f.getDataTypeName()
+ " when a refid is already present");
} catch (BuildException be) {
assertEquals("You must not specify more than one "
+ "attribute when using refid", be.getMessage());
}
// check that a reference zipfileset gets the same attributes as the original
f = (ZipFileSet)getInstance();
f.setSrc(new File("example.zip"));
f.setPrefix("/examples");
f.setFileMode("600");
f.setDirMode("530");
getProject().addReference("test",f);
ZipFileSet zid=(ZipFileSet)getInstance();
zid.setRefid(new Reference("test"));
assertTrue("src attribute copied by copy constructor",zid.getSrc(getProject()).equals(f.getSrc(getProject())));
assertTrue("prefix attribute copied by copy constructor",f.getPrefix(getProject()).equals(zid.getPrefix(getProject())));
assertTrue("file mode attribute copied by copy constructor",f.getFileMode(getProject())==zid.getFileMode(getProject()));
assertTrue("dir mode attribute copied by copy constructor",f.getDirMode(getProject())==zid.getDirMode(getProject()));
}


}

Loading…
Cancel
Save