git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@314776 13f79535-47bb-0310-9956-ffa450edef68master
| @@ -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 | |||
| @@ -6,28 +6,35 @@ | |||
| <title>ZipFileSet Type</title> | |||
| </head> | |||
| <body> | |||
| <h2><a name="fileset">ZipFileSet</a></h2> | |||
| <p>A <code><zipfileset></code> is a special form of a <code><<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><zipfileset></code> and <code><tarfileset></code> are special forms of a <code><<a | |||
| href="fileset.html">fileset</a>></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><zipfileset></code> supports all attributes of <code><<a | |||
| <p><code><tar/zipfileset></code> supports all attributes of <code><<a | |||
| href="fileset.html">fileset</a>></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> <zip destfile="${dist}/manual.zip"><br> <zipfileset dir="htdocs/manual" prefix="docs/user-guide"/><br> <zipfileset dir="." includes="ChangeLog27.txt" fullpath="docs/ChangeLog.txt"/><br> <zipfileset src="examples.zip" includes="**/*.html" prefix="docs/examples"/><br> </zip><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> | |||
| <copy todir="some-dir"> | |||
| <tarfileset includes="lib/**"> | |||
| <bzip2resource> | |||
| <url url="http://example.org/dist/some-archive.tar.bz2"/> | |||
| </bzip2resource> | |||
| </tarfileset> | |||
| </copy> | |||
| </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 © 2003-2005 The Apache Software Foundation. All | |||
| rights Reserved.</p> | |||
| @@ -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> | |||
| @@ -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> | |||
| @@ -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. | |||
| @@ -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(); | |||
| @@ -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(); | |||
| } | |||
| } | |||
| } | |||
| @@ -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; | |||
| } | |||
| } | |||
| @@ -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(); | |||
| } | |||
| } | |||
| } | |||
| @@ -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 | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| @@ -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()) { | |||
| @@ -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; | |||
| } | |||
| } | |||
| @@ -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 | |||
| @@ -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(); | |||
| } | |||
| @@ -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"; | |||
| } | |||
| } | |||
| @@ -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; | |||
| } | |||
| } | |||
| @@ -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"; | |||
| } | |||
| } | |||
| @@ -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,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; | |||
| @@ -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())); | |||
| } | |||
| } | |||
| @@ -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"))); | |||
| } | |||
| } | |||