Browse Source

Now that resources become available in more tasks, throw in a couple of new resources, including tarfileset

git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@314776 13f79535-47bb-0310-9956-ffa450edef68
master
Stefan Bodewig 19 years ago
parent
commit
a96627738d
21 changed files with 2041 additions and 777 deletions
  1. +53
    -3
      docs/manual/CoreTypes/resources.html
  2. +53
    -8
      docs/manual/CoreTypes/zipfileset.html
  3. +1
    -0
      docs/manual/conceptstypeslist.html
  4. +26
    -0
      src/etc/testcases/types/resources/tarentry.xml
  5. +4
    -65
      src/main/org/apache/tools/ant/taskdefs/Tar.java
  6. +1
    -1
      src/main/org/apache/tools/ant/taskdefs/Untar.java
  7. +420
    -0
      src/main/org/apache/tools/ant/types/ArchiveFileSet.java
  8. +329
    -0
      src/main/org/apache/tools/ant/types/ArchiveScanner.java
  9. +98
    -0
      src/main/org/apache/tools/ant/types/TarFileSet.java
  10. +90
    -0
      src/main/org/apache/tools/ant/types/TarScanner.java
  11. +3
    -322
      src/main/org/apache/tools/ant/types/ZipFileSet.java
  12. +28
    -249
      src/main/org/apache/tools/ant/types/ZipScanner.java
  13. +4
    -0
      src/main/org/apache/tools/ant/types/defaults.properties
  14. +244
    -0
      src/main/org/apache/tools/ant/types/resources/ArchiveResource.java
  15. +61
    -0
      src/main/org/apache/tools/ant/types/resources/BZip2Resource.java
  16. +244
    -0
      src/main/org/apache/tools/ant/types/resources/CompressedResource.java
  17. +51
    -0
      src/main/org/apache/tools/ant/types/resources/GZipResource.java
  18. +145
    -0
      src/main/org/apache/tools/ant/types/resources/TarResource.java
  19. +25
    -129
      src/main/org/apache/tools/ant/types/resources/ZipResource.java
  20. +118
    -0
      src/testcases/org/apache/tools/ant/types/TarFileSetTest.java
  21. +43
    -0
      src/testcases/org/apache/tools/ant/types/resources/TarResourceTest.java

+ 53
- 3
docs/manual/CoreTypes/resources.html View File

@@ -23,7 +23,10 @@ explicit use beginning in <b>Ant 1.7</b>.
<ul>
<li><a href="#basic">resource</a> - a basic resource.</li>
<li><a href="#file">file</a> - a file.</li>
<li><a href="#tarentry">zipentry</a> - an entry in a tar file.</li>
<li><a href="#zipentry">zipentry</a> - an entry in a zip file.</li>
<li><a href="#gzipresource">gzipresource</a> - a GZip compressed resource.</li>
<li><a href="#bzip2resource">bzip2resource</a> - a BZip2 compressed resource.</li>
<li><a href="#url">url</a> - a URL.</li>
<li><a href="#string">string</a> - a text string.</li>
<li><a href="#property">property</a> - an Ant property.</li>
@@ -97,7 +100,10 @@ implementations are also usable as single-element

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

<p>Represents an entry in a ZIP archive.</p>
<p>Represents an entry in a ZIP archive. The archive can be specified
using the archive attribute or a nested single-element resource
collection. <code>zipentry</code> only supports file system resources
as nested elements.</p>

<table border="1" cellpadding="2" cellspacing="0">
<tr>
@@ -106,9 +112,10 @@ implementations are also usable as single-element
<td align="center" valign="top"><b>Required</b></td>
</tr>
<tr>
<td valign="top">zipfile</td>
<td valign="top">zipfile or its alias name archive</td>
<td valign="top">The zip file containing this resource</td>
<td align="center" valign="top">Yes</td>
<td align="center" valign="top">Yes, unless a nested resource
collection has been specified.</td>
</tr>
<tr>
<td valign="top">name</td>
@@ -123,6 +130,45 @@ implementations are also usable as single-element
</tr>
</table>

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

<p>Represents an entry in a TAR archive. The archive can be specified
using the archive attribute or a nested single-element resource
collection.</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">archive</td>
<td valign="top">The tar archive containing this resource</td>
<td align="center" valign="top">Yes, unless a nested resource
collection has been specified.</td>
</tr>
<tr>
<td valign="top">name</td>
<td valign="top">The name of the archived resource</td>
<td align="center" valign="top">Yes</td>
</tr>
</table>

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

<p>This is not a stand-alone reource, but a wrapper around another
resource providing compression of the resource's contents on the fly.
A single element resource collection must be specified as a nested
element.</p>

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

<p>This is not a stand-alone reource, but a wrapper around another
resource providing compression of the resource's contents on the fly.
A single element resource collection must be specified as a nested
element.</p>

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

<p>Represents a URL.</p>
@@ -205,6 +251,10 @@ Ant's "legacy" datatypes have been modified to behave as Resource Collections:
<a href="../using.html#path">path</a>
(and derivative types) expose <a href="#file">file</a> resources
</li>
<li><a href="zipfileset.html">tarfileset</a>
can expose <a href="#file">file</a> or <a href="#tarentry">tarentry</a>
resources depending on configuration
</li>
<li><a href="zipfileset.html">zipfileset</a>
can expose <a href="#file">file</a> or <a href="#zipentry">zipentry</a>
resources depending on configuration


+ 53
- 8
docs/manual/CoreTypes/zipfileset.html View File

@@ -6,28 +6,35 @@
<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
<h2><a name="fileset">ZipFileSet/TarFileSet</a></h2>

<p><em>TarFileSet</em> has been added as a stand-alone type in Ant
1.7.</p>

<p>A <code>&lt;zipfileset&gt;</code> and <code>&lt;tarfileset&gt;</code> are special forms 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>
is used - or a nested resource collection has been specified
(<em>since Ant 1.7</em>), the tar/zipfileset is populated with tar
or 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
is used, the tar/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
<p><code>&lt;tar/zipfileset&gt;</code> supports all attributes of <code>&lt;<a
href="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>
the <span style="font-style: italic;">refid</span> attribute. This is
also true for tarfileset which has been added in Ant 1.7.<br>
</p>
<h3>Parameters</h3>
<table border="1" cellpadding="2" cellspacing="0">
@@ -70,14 +77,33 @@ 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>
<tr>
<td valign="top">encoding</td>
<td valign="top">The character encoding to use for filenames
inside the zip file. For a list of possible values see <a
href="http://java.sun.com/j2se/1.5.0/docs/guide/intl/encoding.doc.html">http://java.sun.com/j2se/1.5.0/docs/guide/intl/encoding.doc.html</a>.
Defaults to the platform's default character encoding.
<b>Only supported by zipfileset.</b></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
may be used to specify a subset of the archive for inclusion in the
archive as with the <i>dir</i> attribute.</p>

<h3>Parameters specified as nested elements</h3>

<h4>any <a href="resources.html">resource</a> or single element
resource collection</h4>

<p>The specified resource will be used as src. zipfileset can only
support filesystem based resources while tarfileset can operate on
arbitrary resources.</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>
@@ -90,6 +116,25 @@ The archive might end up containing the files:</p>
docs/ChangeLog.txt<br>
docs/examples/index.html<br>
</code></blockquote>

<blockquote>
<pre>
&lt;copy todir="some-dir"&gt;
&lt;tarfileset includes="lib/**"&gt;
&lt;bzip2resource&gt;
&lt;url url="http://example.org/dist/some-archive.tar.bz2"/&gt;
&lt;/bzip2resource&gt;
&lt;/tarfileset&gt;
&lt;/copy&gt;
</pre></blockquote>

<p>downloads the archive some-archive.tar.bz2, uncompresses and
extracts it on the fly, copies the contents of the lib directory into
some-dir and discards the rest of the archive. File timestamps will
be compared between the archive's entries and files inside the target
directory, no files get overwritten unless they are out-of-date.</p>


<hr>
<p align="center">Copyright &copy; 2003-2005 The Apache Software Foundation. All
rights Reserved.</p>


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

@@ -34,6 +34,7 @@
<a href="CoreTypes/resources.html">Resources</a><br>
<a href="CoreTypes/resources.html#collection">Resource Collections</a><br>
<a href="CoreTypes/selectors.html">Selectors</a><br>
<a href="CoreTypes/zipfileset.html">TarFileSet</a><br>
<a href="CoreTypes/xmlcatalog.html">XMLCatalog</a><br>
<a href="CoreTypes/zipfileset.html">ZipFileSet</a><br>



+ 26
- 0
src/etc/testcases/types/resources/tarentry.xml View File

@@ -0,0 +1,26 @@
<project default="not me">
<target name="not me">
<fail>only use from within unit tests</fail>
</target>

<property name="testout" location="testout"/>
<target name="setUp">
<mkdir dir="${testout}"/>
</target>

<target name="uncompressSource" depends="setUp">
<ant antfile="../../taskdefs/tar.xml" target="feather" />
<copy todir="${testout}">
<tarentry name="asf-logo.gif">
<gzipresource>
<file file="../../taskdefs/expected/asf-logo.gif.tar.gz"/>
</gzipresource>
</tarentry>
</copy>
</target>

<target name="tearDown">
<delete dir="${testout}"/>
<ant antfile="../../taskdefs/tar.xml" target="cleanup" />
</target>
</project>

+ 4
- 65
src/main/org/apache/tools/ant/taskdefs/Tar.java View File

@@ -434,18 +434,14 @@ public class Tar extends MatchingTask {
* This is a FileSet with the option to specify permissions
* and other attributes.
*/
public static class TarFileSet extends FileSet {
public static class TarFileSet
extends org.apache.tools.ant.types.TarFileSet {
private String[] files = null;

private int fileMode = UnixStat.FILE_FLAG | UnixStat.DEFAULT_FILE_PERM;
private int dirMode = UnixStat.DIR_FLAG | UnixStat.DEFAULT_DIR_PERM;

private String userName = "";
private String groupName = "";
private int uid;
private int gid;
private String prefix = "";
private String fullpath = "";
private boolean preserveLeadingSlashes = false;

/**
@@ -493,36 +489,14 @@ public class Tar extends MatchingTask {
* @param octalString a 3 digit octal string.
*/
public void setMode(String octalString) {
this.fileMode =
UnixStat.FILE_FLAG | Integer.parseInt(octalString, 8);
setFileMode(octalString);
}

/**
* @return the current mode.
*/
public int getMode() {
return fileMode;
}

/**
* A 3 digit octal string, specify the user, group and
* other modes in the standard Unix fashion;
* optional, default=0755
*
* @param octalString a 3 digit octal string.
* @since Ant 1.6
*/
public void setDirMode(String octalString) {
this.dirMode =
UnixStat.DIR_FLAG | Integer.parseInt(octalString, 8);
}

/**
* @return the current directory mode
* @since Ant 1.6
*/
public int getDirMode() {
return dirMode;
return getFileMode();
}

/**
@@ -589,41 +563,6 @@ public class Tar extends MatchingTask {
return gid;
}

/**
* If the prefix attribute is set, all files in the fileset
* are prefixed with that path in the archive.
* optional.
* @param prefix the path prefix.
*/
public void setPrefix(String prefix) {
this.prefix = prefix;
}

/**
* @return the path prefix for the files in the fileset.
*/
public String getPrefix() {
return prefix;
}

/**
* If the fullpath attribute is set, the file in the fileset
* is written with that path in the archive. The prefix attribute,
* if specified, is ignored. It is an error to have more than one file specified in
* such a fileset.
* @param fullpath the path to use for the file in a fileset.
*/
public void setFullpath(String fullpath) {
this.fullpath = fullpath;
}

/**
* @return the path to use for a single file fileset.
*/
public String getFullpath() {
return fullpath;
}

/**
* Flag to indicates whether leading `/'s should
* be preserved in the file names.


+ 1
- 1
src/main/org/apache/tools/ant/taskdefs/Untar.java View File

@@ -197,7 +197,7 @@ public class Untar extends Expand {
* @exception BuildException thrown if bzip stream does not
* start with expected magic values
*/
private InputStream decompress(final String name,
public InputStream decompress(final String name,
final InputStream istream)
throws IOException, BuildException {
final String v = getValue();


+ 420
- 0
src/main/org/apache/tools/ant/types/ArchiveFileSet.java View File

@@ -0,0 +1,420 @@
/*
* Copyright 2005 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.apache.tools.ant.types;

import java.io.File;
import java.util.Iterator;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.DirectoryScanner;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.types.resources.FileResource;
import org.apache.tools.zip.UnixStat;

/**
* A ArchiveFileSet is a FileSet with extra attributes useful in the
* context of archiving tasks.
*
* It includes a prefix attribute which is prepended to each entry in
* the output archive file as well as a fullpath ttribute. It also
* supports Unix file permissions for files and directories.
*
* @since Ant 1.7
*/
public abstract class ArchiveFileSet extends FileSet {

/**
* Default value for the dirmode attribute.
*
* @since Ant 1.5.2
*/
public static final int DEFAULT_DIR_MODE =
UnixStat.DIR_FLAG | UnixStat.DEFAULT_DIR_PERM;

/**
* Default value for the filemode attribute.
*
* @since Ant 1.5.2
*/
public static final int DEFAULT_FILE_MODE =
UnixStat.FILE_FLAG | UnixStat.DEFAULT_FILE_PERM;

private Resource src = null;
private String prefix = "";
private String fullpath = "";
private boolean hasDir = false;
private int fileMode = DEFAULT_FILE_MODE;
private int dirMode = DEFAULT_DIR_MODE;

private boolean fileModeHasBeenSet = false;
private boolean dirModeHasBeenSet = false;

/** Constructor for ArchiveFileSet */
public ArchiveFileSet() {
super();
}

/**
* Constructor using a fileset arguement.
* @param fileset the fileset to use
*/
protected ArchiveFileSet(FileSet fileset) {
super(fileset);
}

/**
* Constructor using a archive fileset arguement.
* @param fileset the archivefileset to use
*/
protected ArchiveFileSet(ArchiveFileSet fileset) {
super(fileset);
src = fileset.src;
prefix = fileset.prefix;
fullpath = fileset.fullpath;
hasDir = fileset.hasDir;
fileMode = fileset.fileMode;
dirMode = fileset.dirMode;
fileModeHasBeenSet = fileset.fileModeHasBeenSet;
dirModeHasBeenSet = fileset.dirModeHasBeenSet;
}

/**
* Set the directory for the fileset.
* @param dir the directory for the fileset
* @throws BuildException on error
*/
public void setDir(File dir) throws BuildException {
checkAttributesAllowed();
if (src != null) {
throw new BuildException("Cannot set both dir and src attributes");
} else {
super.setDir(dir);
hasDir = true;
}
}

/**
* Set the source Archive file for the archivefileset. Prevents both
* "dir" and "src" from being specified.
* @param a the archive as a single element Resource collection.
*/
public void addConfigured(ResourceCollection a) {
checkChildrenAllowed();
if (a.size() != 1) {
throw new BuildException("only single argument resource collections"
+ " are supported as archives");
}
setSrc((Resource) a.iterator().next());
}

/**
* Set the source Archive file for the archivefileset. Prevents both
* "dir" and "src" from being specified.
*
* @param srcFile The archive from which to extract entries.
*/
public void setSrc(File srcFile) {
setSrc(new FileResource(srcFile));
}

/**
* Set the source Archive file for the archivefileset. Prevents both
* "dir" and "src" from being specified.
*
* @param srcFile The archive from which to extract entries.
*/
public void setSrc(Resource src) {
checkAttributesAllowed();
if (hasDir) {
throw new BuildException("Cannot set both dir and src attributes");
}
this.src = src;
}

/**
* Get the archive from which entries will be extracted.
* @param p the project to use
* @return the source file
*/
public File getSrc(Project p) {
if (isReference()) {
return ((ArchiveFileSet) getRef(p)).getSrc(p);
}
return getSrc();
}

/**
* Get the archive file from which entries will be extracted.
*/
public File getSrc() {
if (src instanceof FileResource) {
return ((FileResource) src).getFile();
}
return null;
}
/**
* Prepend this prefix to the path for each archive entry.
* Prevents both prefix and fullpath from being specified
*
* @param prefix The prefix to prepend to entries in the archive file.
*/
public void setPrefix(String prefix) {
if (!prefix.equals("") && !fullpath.equals("")) {
throw new BuildException("Cannot set both fullpath and prefix attributes");
}
this.prefix = prefix;
}

/**
* Return the prefix prepended to entries in the archive file.
* @param p the project to use
* @return the prefix
*/
public String getPrefix(Project p) {
if (isReference()) {
return ((ArchiveFileSet) getRef(p)).getPrefix(p);
}
return prefix;
}

/**
* Return the prefix prepended to entries in the archive file.
* @deprecated
*/
public String getPrefix() {
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 (!prefix.equals("") && !fullpath.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.
* @param p the project to use
* @return the full path
*/
public String getFullpath(Project p) {
if (isReference()) {
return ((ArchiveFileSet) getRef(p)).getFullpath(p);
}
return fullpath;
}
/**
* Return the full pathname of the single entry in this fileset.
* @deprecated
*/
public String getFullpath() {
return fullpath;
}

/**
* Creates a scanner for this type of archive.
*/
protected abstract ArchiveScanner newArchiveScanner();

/**
* Return the DirectoryScanner associated with this FileSet.
* If the ArchiveFileSet defines a source Archive file, then a ArchiveScanner
* is returned instead.
* @param p the project to use
* @return a directory scanner
*/
public DirectoryScanner getDirectoryScanner(Project p) {
if (isReference()) {
return getRef(p).getDirectoryScanner(p);
}
if (src == null) {
return super.getDirectoryScanner(p);
}
ArchiveScanner as = newArchiveScanner();
as.setSrc(src);
super.setDir(p.getBaseDir());
setupDirectoryScanner(as, p);
as.init();
return as;
}

/**
* Fulfill the ResourceCollection contract.
* @return Iterator of Resources.
* @since Ant 1.7
*/
public Iterator iterator() {
if (isReference()) {
return ((ResourceCollection) (getRef(getProject()))).iterator();
}
if (src == null) {
return super.iterator();
}
ArchiveScanner as = (ArchiveScanner) getDirectoryScanner(getProject());
return as.getResourceFiles();
}

/**
* Fulfill the ResourceCollection contract.
* @return size of the collection as int.
* @since Ant 1.7
*/
public int size() {
if (isReference()) {
return ((ResourceCollection) (getRef(getProject()))).size();
}
if (src == null) {
return super.size();
}
ArchiveScanner as = (ArchiveScanner) getDirectoryScanner(getProject());
return as.getIncludedFilesCount();
}

/**
* Indicate whether this ResourceCollection is composed entirely of
* Resources accessible via local filesystem conventions. If true,
* all Resources returned from this ResourceCollection should be
* instances of FileResource.
* @return whether this is a filesystem-only resource collection.
* @since Ant 1.7
*/
public boolean isFilesystemOnly() {
return src == null;
}

/**
* A 3 digit octal string, specify the user, group and
* other modes in the standard Unix fashion;
* optional, default=0644
* @param octalString a <code>String</code> value
*/
public void setFileMode(String octalString) {
fileModeHasBeenSet = true;
this.fileMode =
UnixStat.FILE_FLAG | Integer.parseInt(octalString, 8);
}

/**
* Get the mode of the archive fileset
* @param p the project to use
* @return the mode
*/
public int getFileMode(Project p) {
if (isReference()) {
return ((ArchiveFileSet) getRef(p)).getFileMode(p);
}
return fileMode;
}
/**
* @deprecated
*/
public int getFileMode() {
return fileMode;
}


/**
* Whether the user has specified the mode explicitly.
* @return true if it has been set
*/
public boolean hasFileModeBeenSet() {
if (isReference()) {
return ((ArchiveFileSet) getRef(getProject())).hasFileModeBeenSet();
}
return fileModeHasBeenSet;
}

/**
* A 3 digit octal string, specify the user, group and
* other modes in the standard Unix fashion;
* optional, default=0755
* @param octalString a <code>String</code> value
*/
public void setDirMode(String octalString) {
dirModeHasBeenSet = true;
this.dirMode =
UnixStat.DIR_FLAG | Integer.parseInt(octalString, 8);
}

/**
* Get the dir mode of the archive fileset
* @param p the project to use
* @return the mode
*/
public int getDirMode(Project p) {
if (isReference()) {
return ((ArchiveFileSet) getRef(p)).getDirMode(p);
}
return dirMode;
}
/**
* @deprecated
*/
public int getDirMode() {
return dirMode;
}

/**
* Whether the user has specified the mode explicitly.
*
* @return true if it has been set
*/
public boolean hasDirModeBeenSet() {
if (isReference()) {
return ((ArchiveFileSet) getRef(getProject())).hasDirModeBeenSet();
}
return dirModeHasBeenSet;
}

/**
* A ArchiveFileset accepts another ArchiveFileSet or a FileSet as reference
* FileSets are often used by the war task for the lib attribute
* @param p the project to use
* @return the abstract fileset instance
*/
protected final void configureFileSet(ArchiveFileSet zfs) {
zfs.setPrefix(prefix);
zfs.setFullpath(fullpath);
zfs.fileModeHasBeenSet = fileModeHasBeenSet;
zfs.fileMode = fileMode;
zfs.dirModeHasBeenSet = dirModeHasBeenSet;
zfs.dirMode = dirMode;
}

/**
* Return a ArchiveFileSet that has the same properties
* as this one.
* @return the cloned archiveFileSet
* @since Ant 1.6
*/
public Object clone() {
if (isReference()) {
return ((ArchiveFileSet) getRef(getProject())).clone();
} else {
return super.clone();
}
}
}

+ 329
- 0
src/main/org/apache/tools/ant/types/ArchiveScanner.java View File

@@ -0,0 +1,329 @@
/*
* Copyright 2005 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

package org.apache.tools.ant.types;

import java.io.File;
import java.io.IOException;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.Iterator;
import java.util.Enumeration;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.DirectoryScanner;
import org.apache.tools.ant.types.resources.FileResource;
import org.apache.tools.ant.types.resources.FileResourceIterator;

/**
* ArchiveScanner 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
* the matching archive entries.
*
* @since Ant 1.7
*/
public abstract class ArchiveScanner extends DirectoryScanner {

/**
* The archive file which should be scanned.
*/
protected File srcFile;

/**
* The archive resource which should be scanned.
*/
private Resource src;

/**
* to record the last scanned zip file with its modification date
*/
private Resource lastScannedResource;

/**
* record list of all file zip entries
*/
private TreeMap fileEntries = new TreeMap();

/**
* record list of all directory zip entries
*/
private TreeMap dirEntries = new TreeMap();

/**
* record list of matching file zip entries
*/
private TreeMap matchFileEntries = new TreeMap();

/**
* record list of matching directory zip entries
*/
private TreeMap matchDirEntries = new TreeMap();

/**
* encoding of file names.
*
* @since Ant 1.6
*/
private String encoding;

/**
* Don't scan when we have no zipfile.
* @since Ant 1.7
*/
public void scan() {
if (src == null) {
return;
}
super.scan();
}

/**
* Sets the srcFile for scanning. This is the jar or zip file that
* is scanned for matching entries.
*
* @param srcFile the (non-null) archive file name for scanning
*/
public void setSrc(File srcFile) {
setSrc(new FileResource(srcFile));
}

/**
* Sets the src for scanning. This is the jar or zip file that
* is scanned for matching entries.
*
* @param src the (non-null) archive resource
*/
public void setSrc(Resource src) {
this.src = src;
if (src instanceof FileResource) {
srcFile = ((FileResource) src).getFile();
}
}

/**
* Sets encoding of file names.
* @param encoding the encoding format
* @since Ant 1.6
*/
public void setEncoding(String encoding) {
this.encoding = encoding;
}

/**
* Returns the names of the files which matched at least one of the
* include patterns and none of the exclude patterns.
* The names are relative to the base directory.
*
* @return the names of the files which matched at least one of the
* include patterns and none of the exclude patterns.
*/
public String[] getIncludedFiles() {
if (src == null) {
return super.getIncludedFiles();
}
scanme();
Set s = matchFileEntries.keySet();
return (String[]) (s.toArray(new String[s.size()]));
}

/**
* Override parent implementation.
* @return count of included files.
* @since Ant 1.7
*/
public int getIncludedFilesCount() {
if (src == null) {
return super.getIncludedFilesCount();
}
scanme();
return matchFileEntries.size();
}

/**
* Returns the names of the directories which matched at least one of the
* include patterns and none of the exclude patterns.
* The names are relative to the base directory.
*
* @return the names of the directories which matched at least one of the
* include patterns and none of the exclude patterns.
*/
public String[] getIncludedDirectories() {
if (src == null) {
return super.getIncludedDirectories();
}
scanme();
Set s = matchDirEntries.keySet();
return (String[]) (s.toArray(new String[s.size()]));
}

/**
* Override parent implementation.
* @return count of included directories.
* @since Ant 1.7
*/
public int getIncludedDirsCount() {
if (src == null) {
return super.getIncludedDirsCount();
}
scanme();
return matchDirEntries.size();
}

/**
* Get the set of Resources that represent files.
* @return an Iterator of Resources.
* @since Ant 1.7
*/
/* package-private for now */ Iterator getResourceFiles() {
if (src == null) {
return new FileResourceIterator(getBasedir(), getIncludedFiles());
}
scanme();
return matchFileEntries.values().iterator();
}

/**
* Get the set of Resources that represent directories.
* @return an Iterator of Resources.
* @since Ant 1.7
*/
/* package-private for now */ Iterator getResourceDirectories() {
if (src == null) {
return new FileResourceIterator(getBasedir(), getIncludedDirectories());
}
scanme();
return matchDirEntries.values().iterator();
}

/**
* 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 <code>true</code> if the path should be included
* <code>false</code> otherwise.
*/
public boolean match(String path) {
String vpath = path.replace('/', File.separatorChar).
replace('\\', File.separatorChar);
return isIncluded(vpath) && !isExcluded(vpath);
}

/**
* Get the named Resource.
* @param name path name of the file sought in the archive
* @return the resource
* @since Ant 1.5.2
*/
public Resource getResource(String name) {
if (src == null) {
return super.getResource(name);
}
if (name.equals("")) {
// special case in ZIPs, we do not want this thing included
return new Resource("", true, Long.MAX_VALUE, true);
}
// first check if the archive needs to be scanned again
scanme();
if (fileEntries.containsKey(name)) {
return (Resource) fileEntries.get(name);
}
name = trimSeparator(name);

if (dirEntries.containsKey(name)) {
return (Resource) dirEntries.get(name);
}
return new Resource(name);
}

/**
* Fills the file and directory maps with resources read from the archive.
*
* @param archive the archive to scan.
* @param encoding encoding used to encode file names inside the archive.
* @param fileEntries Map (name to resource) of non-directory
* resources found inside the archive.
* @param matchFileEntries Map (name to resource) of non-directory
* resources found inside the archive that matched all include
* patterns and didn't match any exclude patterns.
* @param dirEntries Map (name to resource) of directory
* resources found inside the archive.
* @param matchDirEntries Map (name to resource) of directory
* resources found inside the archive that matched all include
* patterns and didn't match any exclude patterns.
*/
protected abstract void fillMapsFromArchive(Resource archive,
String encoding,
Map fileEntries,
Map matchFileEntries,
Map dirEntries,
Map matchDirEntries);

/**
* if the datetime of the archive did not change since
* lastScannedResource was initialized returns immediately else if
* the archive has not been scanned yet, then all the zip entries
* are put into the appropriate tables.
*/
private void scanme() {
//do not use a FileResource b/c it pulls File info from the filesystem:
Resource thisresource = new Resource(src.getName(),
src.isExists(),
src.getLastModified());
// spare scanning again and again
if (lastScannedResource != null
&& lastScannedResource.getName().equals(thisresource.getName())
&& lastScannedResource.getLastModified()
== thisresource.getLastModified()) {
return;
}
init();

fileEntries.clear();
dirEntries.clear();
matchFileEntries.clear();
matchDirEntries.clear();
fillMapsFromArchive(src, encoding, fileEntries, matchFileEntries,
dirEntries, matchDirEntries);

// record data about the last scanned resource
lastScannedResource = thisresource;
}

protected static final String trimSeparator(String s) {
return s.endsWith("/") ? s.substring(0, s.length() - 1) : s;
}

}

+ 98
- 0
src/main/org/apache/tools/ant/types/TarFileSet.java View File

@@ -0,0 +1,98 @@
/*
* Copyright 2005 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.apache.tools.ant.types;

import java.io.File;
import java.util.Iterator;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.DirectoryScanner;
import org.apache.tools.ant.Project;
import org.apache.tools.zip.UnixStat;

/**
* A TarFileSet is a FileSet with extra attributes useful in the context of
* Tar/Jar tasks.
*
* A TarFileSet extends FileSets with the ability to extract a subset of the
* entries of a Tar file for inclusion in another Tar file. It also includes
* a prefix attribute which is prepended to each entry in the output Tar file.
*
* Since ant 1.6 TarFileSet can be defined with an id and referenced in packaging tasks
*
*/
public class TarFileSet extends ArchiveFileSet {

/** Constructor for TarFileSet */
public TarFileSet() {
super();
}

/**
* Constructor using a fileset arguement.
* @param fileset the fileset to use
*/
protected TarFileSet(FileSet fileset) {
super(fileset);
}

/**
* Constructor using a tarfileset arguement.
* @param fileset the tarfileset to use
*/
protected TarFileSet(TarFileSet fileset) {
super(fileset);
}

protected ArchiveScanner newArchiveScanner() {
TarScanner zs = new TarScanner();
return zs;
}

/**
* A TarFileset accepts another TarFileSet or a FileSet as reference
* FileSets are often used by the war task for the lib attribute
* @param p the project to use
* @return the abstract fileset instance
*/
protected AbstractFileSet getRef(Project p) {
dieOnCircularReference(p);
Object o = getRefid().getReferencedObject(p);
if (o instanceof TarFileSet) {
return (AbstractFileSet) o;
} else if (o instanceof FileSet) {
TarFileSet zfs = new TarFileSet((FileSet) o);
configureFileSet(zfs);
return zfs;
} else {
String msg = getRefid().getRefId() + " doesn\'t denote a tarfileset or a fileset";
throw new BuildException(msg);
}
}

/**
* Return a TarFileSet that has the same properties
* as this one.
* @return the cloned tarFileSet
*/
public Object clone() {
if (isReference()) {
return ((TarFileSet) getRef(getProject())).clone();
} else {
return super.clone();
}
}
}

+ 90
- 0
src/main/org/apache/tools/ant/types/TarScanner.java View File

@@ -0,0 +1,90 @@
/*
* Copyright 2005 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

package org.apache.tools.ant.types;

import java.io.IOException;
import java.util.Map;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.types.resources.TarResource;
import org.apache.tools.tar.TarEntry;
import org.apache.tools.tar.TarInputStream;

/**
* Scans tar archives for resources.
*/
public class TarScanner extends ArchiveScanner {

/**
* Fills the file and directory maps with resources read from the
* archive.
*
* @param src the archive to scan.
* @param encoding encoding used to encode file names inside the archive.
* @param fileEntries Map (name to resource) of non-directory
* resources found inside the archive.
* @param matchFileEntries Map (name to resource) of non-directory
* resources found inside the archive that matched all include
* patterns and didn't match any exclude patterns.
* @param dirEntries Map (name to resource) of directory
* resources found inside the archive.
* @param matchDirEntries Map (name to resource) of directory
* resources found inside the archive that matched all include
* patterns and didn't match any exclude patterns.
*/
protected void fillMapsFromArchive(Resource src, String encoding,
Map fileEntries, Map matchFileEntries,
Map dirEntries, Map matchDirEntries) {
TarEntry entry = null;
TarInputStream ti = null;

try {
try {
ti = new TarInputStream(src.getInputStream());
} catch (IOException ex) {
throw new BuildException("problem opening " + srcFile, ex);
}
while ((entry = ti.getNextEntry()) != null) {
Resource r = new TarResource(src, entry);
String name = entry.getName();
if (entry.isDirectory()) {
name = trimSeparator(name);
dirEntries.put(name, r);
if (match(name)) {
matchDirEntries.put(name, r);
}
} else {
fileEntries.put(name, r);
if (match(name)) {
matchFileEntries.put(name, r);
}
}
}
} catch (IOException ex) {
throw new BuildException("problem reading " + srcFile, ex);
} finally {
if (ti != null) {
try {
ti.close();
} catch (IOException ex) {
// swallow
}
}
}
}
}

+ 3
- 322
src/main/org/apache/tools/ant/types/ZipFileSet.java View File

@@ -34,33 +34,7 @@ import org.apache.tools.zip.UnixStat;
* Since ant 1.6 ZipFileSet can be defined with an id and referenced in packaging tasks
*
*/
public class ZipFileSet extends FileSet {

/**
* Default value for the dirmode attribute.
*
* @since Ant 1.5.2
*/
public static final int DEFAULT_DIR_MODE =
UnixStat.DIR_FLAG | UnixStat.DEFAULT_DIR_PERM;

/**
* Default value for the filemode attribute.
*
* @since Ant 1.5.2
*/
public static final int DEFAULT_FILE_MODE =
UnixStat.FILE_FLAG | UnixStat.DEFAULT_FILE_PERM;

private File srcFile = null;
private String prefix = "";
private String fullpath = "";
private boolean hasDir = false;
private int fileMode = DEFAULT_FILE_MODE;
private int dirMode = DEFAULT_DIR_MODE;

private boolean fileModeHasBeenSet = false;
private boolean dirModeHasBeenSet = false;
public class ZipFileSet extends ArchiveFileSet {

private String encoding = null;

@@ -83,140 +57,9 @@ public class ZipFileSet extends FileSet {
*/
protected ZipFileSet(ZipFileSet fileset) {
super(fileset);
srcFile = fileset.srcFile;
prefix = fileset.prefix;
fullpath = fileset.fullpath;
hasDir = fileset.hasDir;
fileMode = fileset.fileMode;
dirMode = fileset.dirMode;
fileModeHasBeenSet = fileset.fileModeHasBeenSet;
dirModeHasBeenSet = fileset.dirModeHasBeenSet;
encoding = fileset.encoding;
}

/**
* Set the directory for the fileset. Prevents both "dir" and "src"
* from being specified.
* @param dir the directory for the fileset
* @throws BuildException on error
*/
public void setDir(File dir) throws BuildException {
checkAttributesAllowed();
if (srcFile != 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 srcFile The zip file from which to extract entries.
*/
public void setSrc(File srcFile) {
checkAttributesAllowed();
if (hasDir) {
throw new BuildException("Cannot set both dir and src attributes");
}
this.srcFile = srcFile;
}

/**
* 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.
* @param p the project to use
* @return the source file
* @since Ant 1.6
*/
public File getSrc(Project p) {
if (isReference()) {
return ((ZipFileSet) getRef(p)).getSrc(p);
}
return srcFile;
}

/**
* 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.
* @deprecated
*/
public File getSrc() {
return srcFile;
}
/**
* Prepend this prefix to the path for each zip entry.
* 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 (!prefix.equals("") && !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.
* @param p the project to use
* @return the prefix
* @since Ant 1.6
*/
public String getPrefix(Project p) {
if (isReference()) {
return ((ZipFileSet) getRef(p)).getPrefix(p);
}
return prefix;
}

/**
* Return the prefix prepended to entries in the zip file.
* @deprecated
*/
public String getPrefix() {
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 (!prefix.equals("") && !fullpath.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.
* @param p the project to use
* @return the full path
* @since Ant 1.6
*/
public String getFullpath(Project p) {
if (isReference()) {
return ((ZipFileSet) getRef(p)).getFullpath(p);
}
return fullpath;
}
/**
* Return the full pathname of the single entry in this fileset.
* @deprecated
*/
public String getFullpath() {
return fullpath;
}

/**
* Set the encoding used for this ZipFileSet.
* @param enc encoding as String.
@@ -235,168 +78,12 @@ public class ZipFileSet extends FileSet {
return encoding;
}

/**
* Return the DirectoryScanner associated with this FileSet.
* If the ZipFileSet defines a source Zip file, then a ZipScanner
* is returned instead.
* @param p the project to use
* @return a directory scanner
*/
public DirectoryScanner getDirectoryScanner(Project p) {
if (isReference()) {
return getRef(p).getDirectoryScanner(p);
}
if (srcFile == null) {
return super.getDirectoryScanner(p);
}
protected ArchiveScanner newArchiveScanner() {
ZipScanner zs = new ZipScanner();
zs.setSrc(srcFile);
super.setDir(p.getBaseDir());
setupDirectoryScanner(zs, p);
zs.init();
zs.setEncoding(encoding);
return zs;
}

/**
* Fulfill the ResourceCollection contract.
* @return Iterator of Resources.
* @since Ant 1.7
*/
public Iterator iterator() {
if (isReference()) {
return ((ResourceCollection) (getRef(getProject()))).iterator();
}
if (srcFile == null) {
return super.iterator();
}
ZipScanner zs = (ZipScanner) getDirectoryScanner(getProject());
return zs.getResourceFiles();
}

/**
* Fulfill the ResourceCollection contract.
* @return size of the collection as int.
* @since Ant 1.7
*/
public int size() {
if (isReference()) {
return ((ResourceCollection) (getRef(getProject()))).size();
}
if (srcFile == null) {
return super.size();
}
ZipScanner zs = (ZipScanner) getDirectoryScanner(getProject());
return zs.getIncludedFilesCount();
}

/**
* Indicate whether this ResourceCollection is composed entirely of
* Resources accessible via local filesystem conventions. If true,
* all Resources returned from this ResourceCollection should be
* instances of FileResource.
* @return whether this is a filesystem-only resource collection.
* @since Ant 1.7
*/
public boolean isFilesystemOnly() {
return srcFile == null;
}

/**
* A 3 digit octal string, specify the user, group and
* other modes in the standard Unix fashion;
* optional, default=0644
* @param octalString a <code>String</code> value
* @since Ant 1.5.2
*/
public void setFileMode(String octalString) {
fileModeHasBeenSet = true;
this.fileMode =
UnixStat.FILE_FLAG | Integer.parseInt(octalString, 8);
}

/**
* Get the mode of the zip fileset
* @param p the project to use
* @return the mode
* @since Ant 1.6
*/
public int getFileMode(Project p) {
if (isReference()) {
return ((ZipFileSet) getRef(p)).getFileMode(p);
}
return fileMode;
}
/**
* @since Ant 1.5.2
* @deprecated
*/
public int getFileMode() {
return fileMode;
}


/**
* Whether the user has specified the mode explicitly.
* @return true if it has been set
* @since Ant 1.6
*/
public boolean hasFileModeBeenSet() {
if (isReference()) {
return ((ZipFileSet) getRef(getProject())).hasFileModeBeenSet();
}
return fileModeHasBeenSet;
}

/**
* A 3 digit octal string, specify the user, group and
* other modes in the standard Unix fashion;
* optional, default=0755
* @param octalString a <code>String</code> value
*
* @since Ant 1.5.2
*/
public void setDirMode(String octalString) {
dirModeHasBeenSet = true;
this.dirMode =
UnixStat.DIR_FLAG | Integer.parseInt(octalString, 8);
}

/**
* Get the dir mode of the zip fileset
* @param p the project to use
* @return the mode
* @since Ant 1.6
*/
public int getDirMode(Project p) {
if (isReference()) {
return ((ZipFileSet) getRef(p)).getDirMode(p);
}
return dirMode;
}
/**
* @since Ant 1.5.2
* @deprecated
*/
public int getDirMode() {
return dirMode;
}

/**
* Whether the user has specified the mode explicitly.
*
* @return true if it has been set
* @since Ant 1.6
*/
public boolean hasDirModeBeenSet() {
if (isReference()) {
return ((ZipFileSet) getRef(getProject())).hasDirModeBeenSet();
}
return dirModeHasBeenSet;
}

/**
* A ZipFileset accepts another ZipFileSet or a FileSet as reference
* FileSets are often used by the war task for the lib attribute
@@ -410,12 +97,7 @@ public class ZipFileSet extends FileSet {
return (AbstractFileSet) o;
} else if (o instanceof FileSet) {
ZipFileSet zfs = new ZipFileSet((FileSet) o);
zfs.setPrefix(prefix);
zfs.setFullpath(fullpath);
zfs.fileModeHasBeenSet = fileModeHasBeenSet;
zfs.fileMode = fileMode;
zfs.dirModeHasBeenSet = dirModeHasBeenSet;
zfs.dirMode = dirMode;
configureFileSet(zfs);
return zfs;
} else {
String msg = getRefid().getRefId() + " doesn\'t denote a zipfileset or a fileset";
@@ -427,7 +109,6 @@ public class ZipFileSet extends FileSet {
* Return a ZipFileSet that has the same properties
* as this one.
* @return the cloned zipFileSet
* @since Ant 1.6
*/
public Object clone() {
if (isReference()) {


+ 28
- 249
src/main/org/apache/tools/ant/types/ZipScanner.java View File

@@ -19,264 +19,50 @@ package org.apache.tools.ant.types;

import java.io.File;
import java.io.IOException;
import java.util.Set;
import java.util.TreeMap;
import java.util.Iterator;
import java.util.Enumeration;
import java.util.Map;
import java.util.zip.ZipException;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.DirectoryScanner;
import org.apache.tools.ant.types.resources.FileResource;
import org.apache.tools.ant.types.resources.ZipResource;
import org.apache.tools.ant.types.resources.FileResourceIterator;
import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipFile;

/**
* 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
* the matching Zip entries.
*
* Scans zip archives for resources.
*/
public class ZipScanner extends DirectoryScanner {

/**
* The zip file which should be scanned.
*/
protected File srcFile;

/**
* to record the last scanned zip file with its modification date
*/
private Resource lastScannedResource;

/**
* record list of all file zip entries
*/
private TreeMap fileEntries = new TreeMap();

/**
* record list of all directory zip entries
*/
private TreeMap dirEntries = new TreeMap();

/**
* record list of matching file zip entries
*/
private TreeMap matchFileEntries = new TreeMap();

/**
* record list of matching directory zip entries
*/
private TreeMap matchDirEntries = new TreeMap();

/**
* encoding of file names.
*
* @since Ant 1.6
*/
private String encoding;

/**
* Don't scan when we have no zipfile.
* @since Ant 1.7
*/
public void scan() {
if (srcFile == null) {
return;
}
super.scan();
}

/**
* 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(File srcFile) {
this.srcFile = srcFile;
}

/**
* Sets encoding of file names.
* @param encoding the encoding format
* @since Ant 1.6
*/
public void setEncoding(String encoding) {
this.encoding = encoding;
}

/**
* Returns the names of the files which matched at least one of the
* include patterns and none of the exclude patterns.
* The names are relative to the base directory.
*
* @return the names of the files which matched at least one of the
* include patterns and none of the exclude patterns.
*/
public String[] getIncludedFiles() {
if (srcFile == null) {
return super.getIncludedFiles();
}
scanme();
Set s = matchFileEntries.keySet();
return (String[]) (s.toArray(new String[s.size()]));
}

/**
* Override parent implementation.
* @return count of included files.
* @since Ant 1.7
*/
public int getIncludedFilesCount() {
if (srcFile == null) {
return super.getIncludedFilesCount();
}
scanme();
return matchFileEntries.size();
}

/**
* Returns the names of the directories which matched at least one of the
* include patterns and none of the exclude patterns.
* The names are relative to the base directory.
*
* @return the names of the directories which matched at least one of the
* include patterns and none of the exclude patterns.
*/
public String[] getIncludedDirectories() {
if (srcFile == null) {
return super.getIncludedDirectories();
}
scanme();
Set s = matchDirEntries.keySet();
return (String[]) (s.toArray(new String[s.size()]));
}

/**
* Override parent implementation.
* @return count of included directories.
* @since Ant 1.7
*/
public int getIncludedDirsCount() {
if (srcFile == null) {
return super.getIncludedDirsCount();
}
scanme();
return matchDirEntries.size();
}

/**
* Get the set of Resources that represent files.
* @return an Iterator of Resources.
* @since Ant 1.7
*/
/* package-private for now */ Iterator getResourceFiles() {
if (srcFile == null) {
return new FileResourceIterator(getBasedir(), getIncludedFiles());
}
scanme();
return matchFileEntries.values().iterator();
}

/**
* Get the set of Resources that represent directories.
* @return an Iterator of Resources.
* @since Ant 1.7
*/
/* package-private for now */ Iterator getResourceDirectories() {
if (srcFile == null) {
return new FileResourceIterator(getBasedir(), getIncludedDirectories());
}
scanme();
return matchDirEntries.values().iterator();
}

/**
* 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];
}
}
public class ZipScanner extends ArchiveScanner {

/**
* Matches a jar entry against the includes/excludes list,
* normalizing the path separator.
*
* @param path the (non-null) path name to test for inclusion
* Fills the file and directory maps with resources read from the
* archive.
*
* @return <code>true</code> if the path should be included
* <code>false</code> otherwise.
*/
public boolean match(String path) {
String vpath = path.replace('/', File.separatorChar).
replace('\\', File.separatorChar);
return isIncluded(vpath) && !isExcluded(vpath);
}

/**
* Get the named Resource.
* @param name path name of the file sought in the archive
* @return the resource
* @since Ant 1.5.2
*/
public Resource getResource(String name) {
if (srcFile == null) {
return super.getResource(name);
}
if (name.equals("")) {
// special case in ZIPs, we do not want this thing included
return new Resource("", true, Long.MAX_VALUE, true);
}
// first check if the archive needs to be scanned again
scanme();
if (fileEntries.containsKey(name)) {
return (Resource) fileEntries.get(name);
}
name = trimSeparator(name);

if (dirEntries.containsKey(name)) {
return (Resource) dirEntries.get(name);
}
return new Resource(name);
}

/**
* if the datetime of the archive did not change since
* lastScannedResource was initialized returns immediately else if
* the archive has not been scanned yet, then all the zip entries
* are put into the appropriate tables.
*/
private void scanme() {
//do not use a FileResource b/c it pulls File info from the filesystem:
Resource thisresource = new Resource(srcFile.getAbsolutePath(),
srcFile.exists(),
srcFile.lastModified());
// spare scanning again and again
if (lastScannedResource != null
&& lastScannedResource.getName().equals(thisresource.getName())
&& lastScannedResource.getLastModified()
== thisresource.getLastModified()) {
return;
}
init();
* @param src the archive to scan.
* @param encoding encoding used to encode file names inside the archive.
* @param fileEntries Map (name to resource) of non-directory
* resources found inside the archive.
* @param matchFileEntries Map (name to resource) of non-directory
* resources found inside the archive that matched all include
* patterns and didn't match any exclude patterns.
* @param dirEntries Map (name to resource) of directory
* resources found inside the archive.
* @param matchDirEntries Map (name to resource) of directory
* resources found inside the archive that matched all include
* patterns and didn't match any exclude patterns.
*/
protected void fillMapsFromArchive(Resource src, String encoding,
Map fileEntries, Map matchFileEntries,
Map dirEntries, Map matchDirEntries) {
ZipEntry entry = null;
ZipFile zf = null;

fileEntries.clear();
dirEntries.clear();
matchFileEntries.clear();
matchDirEntries.clear();
File srcFile = null;
if (src instanceof FileResource) {
srcFile = ((FileResource) src).getFile();
} else {
throw new BuildException("only file resources are supported");
}

try {
try {
@@ -313,12 +99,5 @@ public class ZipScanner extends DirectoryScanner {
}
}
}
// record data about the last scanned resource
lastScannedResource = thisresource;
}

private static String trimSeparator(String s) {
return s.endsWith("/") ? s.substring(0, s.length() - 1) : s;
}

}

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

@@ -55,6 +55,7 @@ intersect=org.apache.tools.ant.types.resources.Intersect
sort=org.apache.tools.ant.types.resources.Sort
resources=org.apache.tools.ant.types.resources.Resources
first=org.apache.tools.ant.types.resources.First
tarfileset=org.apache.tools.ant.types.TarFileSet

#Resources (single-element ResourceCollections):
resource=org.apache.tools.ant.types.Resource
@@ -63,3 +64,6 @@ url=org.apache.tools.ant.types.resources.URLResource
string=org.apache.tools.ant.types.resources.StringResource
zipentry=org.apache.tools.ant.types.resources.ZipResource
propertyresource=org.apache.tools.ant.types.resources.PropertyResource
tarentry=org.apache.tools.ant.types.resources.TarResource
gzipresource=org.apache.tools.ant.types.resources.GZipResource
bzip2resource=org.apache.tools.ant.types.resources.BZip2Resource

+ 244
- 0
src/main/org/apache/tools/ant/types/resources/ArchiveResource.java View File

@@ -0,0 +1,244 @@
/*
* Copyright 2005 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.apache.tools.ant.types.resources;

import java.io.File;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.types.Resource;
import org.apache.tools.ant.types.ResourceCollection;
import org.apache.tools.ant.types.Reference;

/**
* A Resource representation of an entry inside an archive.
* @since Ant 1.7
*/
public abstract class ArchiveResource extends Resource {
private static final int NULL_ARCHIVE
= Resource.getMagicNumber("null archive".getBytes());

private Resource archive;
private boolean haveEntry = false;

/**
* Default constructor.
*/
public ArchiveResource() {
}

/**
* Construct a ArchiveResource representing the specified
* entry in the specified archive.
* @param a the archive as File.
*/
public ArchiveResource(File a) {
this(a, false);
}

/**
* Construct a ArchiveResource representing the specified
* entry in the specified archive.
* @param a the archive as File.
* @param withEntry if the entry has been specified.
*/
public ArchiveResource(File a, boolean withEntry) {
setArchive(a);
haveEntry = withEntry;
}

/**
* Construct a ArchiveResource representing the specified
* entry in the specified archive.
* @param a the archive as Resource.
* @param withEntry if the entry has been specified.
*/
public ArchiveResource(Resource a, boolean withEntry) {
addConfigured(a);
haveEntry = withEntry;
}

/**
* Set the archive that holds this Resource.
* @param a the archive as a File.
*/
public void setArchive(File a) {
checkAttributesAllowed();
archive = new FileResource(a);
}

/**
* Sets the archive that holds this as a single element Resource
* collection.
* @param a the archive as a single element Resource collection.
*/
public void addConfigured(ResourceCollection a) {
checkChildrenAllowed();
if (archive != null) {
throw new BuildException("you must not specify more than one"
+ " archive");
}
if (a.size() != 1) {
throw new BuildException("only single argument resource collections"
+ " are supported as archives");
}
archive = (Resource) a.iterator().next();
}

/**
* Get the archive that holds this Resource.
* @return the archive as a Resource.
*/
public Resource getArchive() {
return isReference()
? ((ArchiveResource) getCheckedRef()).getArchive() : archive;
}

/**
* Get the last modified date of this Resource.
* @return the last modification date.
*/
public long getLastModified() {
if (isReference()) {
return ((Resource) getCheckedRef()).getLastModified();
}
checkEntry();
return super.getLastModified();
}

/**
* Get the size of this Resource.
* @return the long size of this Resource.
*/
public long getSize() {
if (isReference()) {
return ((Resource) getCheckedRef()).getSize();
}
checkEntry();
return super.getSize();
}

/**
* Learn whether this Resource represents a directory.
* @return boolean flag indicating whether the entry is a directory.
*/
public boolean isDirectory() {
if (isReference()) {
return ((Resource) getCheckedRef()).isDirectory();
}
checkEntry();
return super.isDirectory();
}

/**
* Find out whether this Resource represents an existing Resource.
* @return boolean existence flag.
*/
public boolean isExists() {
if (isReference()) {
return ((Resource) getCheckedRef()).isExists();
}
checkEntry();
return super.isExists();
}

/**
* Overrides the super version.
* @param r the Reference to set.
*/
public void setRefid(Reference r) {
if (archive != null) {
throw tooManyAttributes();
}
super.setRefid(r);
}

/**
* Compare this ArchiveResource to another Resource.
* @param another the other Resource against which to compare.
* @return a negative integer, zero, or a positive integer as this Resource
* is less than, equal to, or greater than the specified Resource.
*/
public int compareTo(Object another) {
return this.equals(another) ? 0 : super.compareTo(another);
}

/**
* Compare another Object to this ArchiveResource for equality.
* @param another the other Object to compare.
* @return true if another is a Resource representing
* the same entry in the same archive.
*/
public boolean equals(Object another) {
if (this == another) {
return true;
}
if (isReference()) {
return getCheckedRef().equals(another);
}
if (!(another.getClass().equals(getClass()))) {
return false;
}
ArchiveResource r = (ArchiveResource) another;
return getArchive().equals(r.getArchive())
&& getName().equals(r.getName());
}

/**
* Get the hash code for this Resource.
* @return hash code as int.
*/
public int hashCode() {
return super.hashCode()
* (getArchive() == null ? NULL_ARCHIVE : getArchive().hashCode());
}

/**
* Format this Resource as a String.
* @return String representatation of this Resource.
*/
public String toString() {
return isReference() ? getCheckedRef().toString()
: getArchive().toString() + ':' + getName();
}

private synchronized void checkEntry() throws BuildException {
if (haveEntry) {
return;
}
String name = getName();
if (name == null) {
throw new BuildException("entry name not set");
}
Resource r = getArchive();
if (r == null) {
throw new BuildException("archive attribute not set");
}
if (!r.isExists()) {
throw new BuildException(r.toString() + " does not exist.");
}
if (r.isDirectory()) {
throw new BuildException(r + " denotes a directory.");
}
fetchEntry();
haveEntry = true;
}

/**
* fetches information from the named entry inside the archive.
*/
protected abstract void fetchEntry();
}

+ 61
- 0
src/main/org/apache/tools/ant/types/resources/BZip2Resource.java View File

@@ -0,0 +1,61 @@
/*
* Copyright 2005 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.apache.tools.ant.types.resources;

import java.io.InputStream;
import java.io.IOException;
import java.io.OutputStream;

import org.apache.tools.bzip2.CBZip2InputStream;
import org.apache.tools.bzip2.CBZip2OutputStream;

/**
* A Bzip2 compressed resource.
*
* <p>Wraps around another resource, delegates all quries to that
* other resource but uncompresses/compresses streams on the fly.</p>
*
* @since Ant 1.7
*/
public class BZip2Resource extends CompressedResource {
private static final char[] MAGIC = new char[] {'B', 'Z'};

public BZip2Resource() {
}

public BZip2Resource(org.apache.tools.ant.types.ResourceCollection other) {
super(other);
}

protected InputStream wrapStream(InputStream in) throws IOException {
for (int i = 0; i < MAGIC.length; i++) {
if (in.read() != MAGIC[i]) {
throw new IOException("Invalid bz2 stream.");
}
}
return new CBZip2InputStream(in);
}
protected OutputStream wrapStream(OutputStream out) throws IOException {
for (int i = 0; i < MAGIC.length; i++) {
out.write(MAGIC[i]);
}
return new CBZip2OutputStream(out);
}
protected String getCompressionName() {
return "Bzip2";
}
}

+ 244
- 0
src/main/org/apache/tools/ant/types/resources/CompressedResource.java View File

@@ -0,0 +1,244 @@
/*
* Copyright 2005 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.apache.tools.ant.types.resources;

import java.io.InputStream;
import java.io.IOException;
import java.io.OutputStream;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.types.DataType;
import org.apache.tools.ant.types.Resource;
import org.apache.tools.ant.types.Reference;
import org.apache.tools.ant.types.ResourceCollection;

/**
* A compressed resource.
*
* <p>Wraps around another resource, delegates all queries to that
* other resource but uncompresses/compresses streams on the fly.</p>
*
* @since Ant 1.7
*/
public abstract class CompressedResource extends Resource
implements ResourceCollection {

private Resource resource;

public CompressedResource() {
}

public CompressedResource(ResourceCollection other) {
addConfigured(other);
}

/**
* Sets the resource to wrap using a single-element collection.
* @param a the resource to wrap as a single element Resource collection.
*/
public void addConfigured(ResourceCollection a) {
checkChildrenAllowed();
if (resource != null) {
throw new BuildException("you must not specify more than one"
+ " resource");
}
if (a.size() != 1) {
throw new BuildException("only single argument resource collections"
+ " are supported");
}
resource = (Resource) a.iterator().next();
}

public String getName() {
return getResource().getName();
}


public void setName(String name) {
throw new BuildException("you can't change the name of a compressed"
+ " resource");
}

/**
* The exists attribute tells whether a file exists.
* @return true if this resource exists.
*/
public boolean isExists() {
return getResource().isExists();
}

/**
* Set the exists attribute.
* @param exists if true, this resource exists.
*/
public void setExists(boolean exists) {
throw new BuildException("you can't change the exists state of a "
+ " compressed resource");
}

/**
* Tells the modification time in milliseconds since 01.01.1970 .
*
* @return 0 if the resource does not exist to mirror the behavior
* of {@link java.io.File File}.
*/
public long getLastModified() {
return getResource().getLastModified();
}

public void setLastModified(long lastmodified) {
throw new BuildException("you can't change the timestamp of a "
+ " compressed resource");
}

/**
* Tells if the resource is a directory.
* @return boolean flag indicating if the resource is a directory.
*/
public boolean isDirectory() {
return getResource().isDirectory();
}

public void setDirectory(boolean directory) {
throw new BuildException("you can't change the directory state of a "
+ " compressed resource");
}

/**
* Get the size of this Resource.
* @return the size, as a long, 0 if the Resource does not exist (for
* compatibility with java.io.File), or UNKNOWN_SIZE if not known.
*/
public long getSize() {
return getResource().getSize();
}

public void setSize(long size) {
throw new BuildException("you can't change the size of a "
+ " compressed resource");
}

/**
* Delegates to a comparison of names.
* @param other the object to compare to.
* @return a negative integer, zero, or a positive integer as this Resource
* is less than, equal to, or greater than the specified Resource.
*/
public int compareTo(Object other) {
return getResource().compareTo(other);
}

/**
* Get the hash code for this Resource.
* @return hash code as int.
*/
public int hashCode() {
return getResource().hashCode();
}

/**
* Get an InputStream for the Resource.
* @return an InputStream containing this Resource's content.
* @throws IOException if unable to provide the content of this
* Resource as a stream.
* @throws UnsupportedOperationException if InputStreams are not
* supported for this Resource type.
*/
public InputStream getInputStream() throws IOException {
InputStream in = getResource().getInputStream();
if (in != null) {
in = wrapStream(in);
}
return in;
}

/**
* Get an OutputStream for the Resource.
* @return an OutputStream to which content can be written.
* @throws IOException if unable to provide the content of this
* Resource as a stream.
* @throws UnsupportedOperationException if OutputStreams are not
* supported for this Resource type.
*/
public OutputStream getOutputStream() throws IOException {
OutputStream out = getResource().getOutputStream();
if (out != null) {
out = wrapStream(out);
}
return out;
}

/**
* Fulfill the ResourceCollection contract.
* @return whether this Resource is a FileResource.
*/
public boolean isFilesystemOnly() {
return false;
}

/**
* Get the string representation of this Resource.
* @return this Resource formatted as a String.
* @since Ant 1.7
*/
public String toString() {
return getCompressionName() + " compressed "
+ getResource().toString();
}

/**
* Overrides the base version.
* @param r the Reference to set.
*/
public void setRefid(Reference r) {
if (resource != null) {
throw noChildrenAllowed();
}
super.setRefid(r);
}

/**
* Is supposed to wrap the stream to allow decompression on the fly.
*
* @param in InputStream to wrap, will never be null.
*/
protected abstract InputStream wrapStream(InputStream in)
throws IOException;

/**
* Is supposed to wrap the stream to allow compression on the fly.
*
* @param out OutputStream to wrap, will never be null.
*/
protected abstract OutputStream wrapStream(OutputStream out)
throws IOException;

/**
* @return the name of the compression method.
*/
protected abstract String getCompressionName();

private Resource getResource() {
if (isReference()) {
return (Resource) getCheckedRef();
} else if (resource == null) {
throw new BuildException("no resource specified");
}
return resource;
}

}

+ 51
- 0
src/main/org/apache/tools/ant/types/resources/GZipResource.java View File

@@ -0,0 +1,51 @@
/*
* Copyright 2005 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.apache.tools.ant.types.resources;

import java.io.InputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

/**
* A GZip compressed resource.
*
* <p>Wraps around another resource, delegates all quries to that
* other resource but uncompresses/compresses streams on the fly.</p>
*
* @since Ant 1.7
*/
public class GZipResource extends CompressedResource {

public GZipResource() {
}

public GZipResource(org.apache.tools.ant.types.ResourceCollection other) {
super(other);
}

protected InputStream wrapStream(InputStream in) throws IOException {
return new GZIPInputStream(in);
}
protected OutputStream wrapStream(OutputStream out) throws IOException {
return new GZIPOutputStream(out);
}
protected String getCompressionName() {
return "GZip";
}
}

+ 145
- 0
src/main/org/apache/tools/ant/types/resources/TarResource.java View File

@@ -0,0 +1,145 @@
/*
* Copyright 2005 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.apache.tools.ant.types.resources;

import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;
import java.io.FilterInputStream;

import org.apache.tools.ant.Project;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.types.Resource;
import org.apache.tools.ant.types.Reference;
import org.apache.tools.ant.util.FileUtils;
import org.apache.tools.tar.TarEntry;
import org.apache.tools.tar.TarInputStream;

/**
* A Resource representation of an entry in a tar archive.
* @since Ant 1.7
*/
public class TarResource extends ArchiveResource {

/**
* Default constructor.
*/
public TarResource() {
}

/**
* Construct a TarResource representing the specified
* entry in the specified archive.
* @param a the archive as File.
* @param e the TarEntry.
*/
public TarResource(File a, TarEntry e) {
super(a, true);
setEntry(e);
}

/**
* Construct a TarResource representing the specified
* entry in the specified archive.
* @param a the archive as Resource.
* @param e the TarEntry.
*/
public TarResource(Resource a, TarEntry e) {
super(a, true);
setEntry(e);
}

/**
* Return an InputStream for reading the contents of this Resource.
* @return an InputStream object.
* @throws IOException if the tar file cannot be opened,
* or the entry cannot be read.
*/
public InputStream getInputStream() throws IOException {
if (isReference()) {
return ((Resource) getCheckedRef()).getInputStream();
}
Resource archive = getArchive();
final TarInputStream i = new TarInputStream(archive.getInputStream());
TarEntry te = null;
while ((te = i.getNextEntry()) != null) {
if (te.getName().equals(getName())) {
return i;
}
}
FileUtils.close(i);
throw new BuildException("no entry " + getName() + " in "
+ getArchive());
}

/**
* Get an OutputStream for the Resource.
* @return an OutputStream to which content can be written.
* @throws IOException if unable to provide the content of this
* Resource as a stream.
* @throws UnsupportedOperationException if OutputStreams are not
* supported for this Resource type.
*/
public OutputStream getOutputStream() throws IOException {
if (isReference()) {
return ((Resource) getCheckedRef()).getOutputStream();
}
throw new UnsupportedOperationException(
"Use the tar task for tar output.");
}

/**
* fetches information from the named entry inside the archive.
*/
protected void fetchEntry() {
Resource archive = getArchive();
TarInputStream i = null;
try {
i = new TarInputStream(archive.getInputStream());
TarEntry te = null;
while ((te = i.getNextEntry()) != null) {
if (te.getName().equals(getName())) {
setEntry(te);
return;
}
}
} catch (IOException e) {
log(e.getMessage(), Project.MSG_DEBUG);
throw new BuildException(e);
} finally {
if (i != null) {
FileUtils.close(i);
}
}
setEntry(null);
}

private void setEntry(TarEntry e) {
if (e == null) {
super.setExists(false);
return;
}
super.setName(e.getName());
super.setExists(true);
super.setLastModified(e.getModTime().getTime());
super.setDirectory(e.isDirectory());
super.setSize(e.getSize());
}

}

+ 25
- 129
src/main/org/apache/tools/ant/types/resources/ZipResource.java View File

@@ -25,6 +25,7 @@ import java.io.FilterInputStream;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.types.Resource;
import org.apache.tools.ant.types.ResourceCollection;
import org.apache.tools.ant.types.Reference;
import org.apache.tools.ant.util.FileUtils;
import org.apache.tools.zip.ZipFile;
@@ -34,13 +35,9 @@ import org.apache.tools.zip.ZipEntry;
* A Resource representation of an entry in a zipfile.
* @since Ant 1.7
*/
public class ZipResource extends Resource {
private static final int NULL_ZIPFILE
= Resource.getMagicNumber("null zipfile".getBytes());
public class ZipResource extends ArchiveResource {

private String encoding;
private File zipfile;
private boolean haveEntry = false;

/**
* Default constructor.
@@ -56,9 +53,9 @@ public class ZipResource extends Resource {
* @param e the ZipEntry.
*/
public ZipResource(File z, String enc, ZipEntry e) {
setEntry(e);
setZipfile(z);
super(z, true);
setEncoding(enc);
setEntry(e);
}

/**
@@ -66,8 +63,7 @@ public class ZipResource extends Resource {
* @param z the zipfile as a File.
*/
public void setZipfile(File z) {
checkAttributesAllowed();
zipfile = z;
setArchive(z);
}

/**
@@ -75,8 +71,20 @@ public class ZipResource extends Resource {
* @return the zipfile as a File.
*/
public File getZipfile() {
return isReference()
? ((ZipResource) getCheckedRef()).getZipfile() : zipfile;
FileResource r = (FileResource) getArchive();
return r.getFile();
}

/**
* Sets the archive that holds this as a single element Resource
* collection.
* @param a the archive as a single element Resource collection.
*/
public void addConfigured(ResourceCollection a) {
super.addConfigured(a);
if (!a.isFilesystemOnly()) {
throw new BuildException("only filesystem resources are supported");
}
}

/**
@@ -97,60 +105,12 @@ public class ZipResource extends Resource {
? ((ZipResource) getCheckedRef()).getEncoding() : encoding;
}

/**
* Get the last modified date of this ZipResource.
* @return the last modification date.
*/
public long getLastModified() {
if (isReference()) {
return ((Resource) getCheckedRef()).getLastModified();
}
checkEntry();
return super.getLastModified();
}

/**
* Get the size of this ZipResource.
* @return the long size of this ZipResource.
*/
public long getSize() {
if (isReference()) {
return ((Resource) getCheckedRef()).getSize();
}
checkEntry();
return super.getSize();
}

/**
* Learn whether this ZipResource represents a directory.
* @return boolean flag indicating whether the zip entry is a directory.
*/
public boolean isDirectory() {
if (isReference()) {
return ((Resource) getCheckedRef()).isDirectory();
}
checkEntry();
return super.isDirectory();
}

/**
* Find out whether this ZipResource represents an existing Resource.
* @return boolean existence flag.
*/
public boolean isExists() {
if (isReference()) {
return ((Resource) getCheckedRef()).isExists();
}
checkEntry();
return super.isExists();
}

/**
* Overrides the super version.
* @param r the Reference to set.
*/
public void setRefid(Reference r) {
if (encoding != null || zipfile != null) {
if (encoding != null) {
throw tooManyAttributes();
}
super.setRefid(r);
@@ -199,76 +159,13 @@ public class ZipResource extends Resource {
}

/**
* Compare this ZipResource to another Resource.
* @param another the other Resource against which to compare.
* @return a negative integer, zero, or a positive integer as this ZipResource
* is less than, equal to, or greater than the specified Resource.
*/
public int compareTo(Object another) {
return this.equals(another) ? 0 : super.compareTo(another);
}

/**
* Compare another Object to this ZipResource for equality.
* @param another the other Object to compare.
* @return true if another is a ZipResource representing
* the same entry in the same zipfile.
*/
public boolean equals(Object another) {
if (this == another) {
return true;
}
if (isReference()) {
return getCheckedRef().equals(another);
}
if (!(another.getClass().equals(getClass()))) {
return false;
}
ZipResource r = (ZipResource) another;
return getZipfile().equals(r.getZipfile())
&& getName().equals(r.getName());
}

/**
* Get the hash code for this Resource.
* @return hash code as int.
* fetches information from the named entry inside the archive.
*/
public int hashCode() {
return super.hashCode()
* (getZipfile() == null ? NULL_ZIPFILE : getZipfile().hashCode());
}

/**
* Format this ZipResource as a String.
* @return String representatation of this ZipResource.
*/
public String toString() {
return isReference() ? getCheckedRef().toString()
: getZipfile().toString() + ':' + getName();
}

private synchronized void checkEntry() throws BuildException {
if (haveEntry) {
return;
}
String name = getName();
if (name == null) {
throw new BuildException("zip entry name not set");
}
File f = getZipfile();
if (f == null) {
throw new BuildException("zipfile attribute not set");
}
if (!f.exists()) {
throw new BuildException(f.getAbsolutePath() + " does not exist.");
}
if (f.isDirectory()) {
throw new BuildException(f + " denotes a directory.");
}
protected void fetchEntry() {
ZipFile z = null;
try {
z = new ZipFile(f, getEncoding());
setEntry(z.getEntry(name));
z = new ZipFile(getZipfile(), getEncoding());
setEntry(z.getEntry(getName()));
} catch (IOException e) {
log(e.getMessage(), Project.MSG_DEBUG);
throw new BuildException(e);
@@ -283,8 +180,7 @@ public class ZipResource extends Resource {
}
}

private synchronized void setEntry(ZipEntry e) {
haveEntry = true;
private void setEntry(ZipEntry e) {
if (e == null) {
super.setExists(false);
return;


+ 118
- 0
src/testcases/org/apache/tools/ant/types/TarFileSetTest.java View File

@@ -0,0 +1,118 @@
/*
* Copyright 2005 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

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.TarFileSet.
*
* <p>This doesn't actually test much, mainly reference handling.
*
*/

public class TarFileSetTest extends AbstractFileSetTest {

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

protected AbstractFileSet getInstance() {
return new TarFileSet();
}
public final void testAttributes() {
TarFileSet f = (TarFileSet)getInstance();
//check that dir and src are incompatible
f.setSrc(new File("example.tar"));
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 = (TarFileSet)getInstance();
//check that dir and src are incompatible
f.setDir(new File("examples"));
try {
f.setSrc(new File("example.tar"));
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 = (TarFileSet)getInstance();
f.setSrc(new File("example.tar"));
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 = (TarFileSet)getInstance();
f.setSrc(new File("example.tar"));
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 tarfilesets cannot have specific attributes
f = (TarFileSet)getInstance();
f.setRefid(new Reference("test"));
try {
f.setSrc(new File("example.tar"));
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 tarfileset gets the same attributes as the original
f = (TarFileSet)getInstance();
f.setSrc(new File("example.tar"));
f.setPrefix("/examples");
f.setFileMode("600");
f.setDirMode("530");
getProject().addReference("test",f);
TarFileSet zid=(TarFileSet)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()));
}


}

+ 43
- 0
src/testcases/org/apache/tools/ant/types/resources/TarResourceTest.java View File

@@ -0,0 +1,43 @@
/*
* Copyright 2005 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.apache.tools.ant.types.resources;

import org.apache.tools.ant.BuildFileTest;
import org.apache.tools.ant.util.FileUtils;

public class TarResourceTest extends BuildFileTest {

private static final FileUtils FU = FileUtils.getFileUtils();

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

protected void setUp() throws Exception {
configureProject("src/etc/testcases/types/resources/tarentry.xml");
}

protected void tearDown() throws Exception {
executeTarget("tearDown");
}

public void testUncompressSource() throws java.io.IOException {
executeTarget("uncompressSource");
assertTrue(FU.contentEquals(project.resolveFile("../../asf-logo.gif"),
project.resolveFile("testout/asf-logo.gif")));
}
}

Loading…
Cancel
Save