git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@326643 13f79535-47bb-0310-9956-ffa450edef68master
| @@ -1231,6 +1231,10 @@ | |||||
| </zip> | </zip> | ||||
| <tar longfile="gnu" | <tar longfile="gnu" | ||||
| destfile="${dist.base.binaries}/${dist.name}-bin.tar"> | destfile="${dist.base.binaries}/${dist.name}-bin.tar"> | ||||
| <!-- removes redundant definition of permissions, but seems to | |||||
| drop dirs (and to be slow) | |||||
| <zipfileset src="${dist.base.binaries}/${dist.name}-bin.zip"/> | |||||
| --> | |||||
| <tarfileset dir="${dist.name}/.." mode="755" username="ant" group="ant"> | <tarfileset dir="${dist.name}/.." mode="755" username="ant" group="ant"> | ||||
| <include name="${dist.name}/bin/ant"/> | <include name="${dist.name}/bin/ant"/> | ||||
| <include name="${dist.name}/bin/antRun"/> | <include name="${dist.name}/bin/antRun"/> | ||||
| @@ -1296,6 +1300,9 @@ | |||||
| </zip> | </zip> | ||||
| <tar longfile="gnu" | <tar longfile="gnu" | ||||
| destfile="${dist.base.source}/${dist.name}-src.tar"> | destfile="${dist.base.source}/${dist.name}-src.tar"> | ||||
| <!-- | |||||
| <zipfileset src="${dist.base.source}/${dist.name}-src.zip"/> | |||||
| --> | |||||
| <tarfileset dir="${dist.name}/.." mode="755" username="ant" group="ant"> | <tarfileset dir="${dist.name}/.." mode="755" username="ant" group="ant"> | ||||
| <include name="${dist.name}/bootstrap.sh"/> | <include name="${dist.name}/bootstrap.sh"/> | ||||
| <include name="${dist.name}/build.sh"/> | <include name="${dist.name}/build.sh"/> | ||||
| @@ -18,7 +18,8 @@ defines which files, relative to the <i>basedir</i>, will be included in the | |||||
| archive. The tar task supports all the attributes of Fileset to refine the | archive. The tar task supports all the attributes of Fileset to refine the | ||||
| set of files to be included in the implicit fileset.</p> | set of files to be included in the implicit fileset.</p> | ||||
| <p>In addition to the implicit fileset, the tar task supports nested filesets. These | |||||
| <p>In addition to the implicit fileset, the tar task supports nested | |||||
| resource collections and a special form of filesets. These | |||||
| filesets are extended to allow control over the access mode, username and groupname | filesets are extended to allow control over the access mode, username and groupname | ||||
| to be applied to the tar entries. This is useful, for example, when preparing archives for | to be applied to the tar entries. This is useful, for example, when preparing archives for | ||||
| Unix systems where some files need to have execute permission.</p> | Unix systems where some files need to have execute permission.</p> | ||||
| @@ -110,8 +111,11 @@ or "bzip2".</p> | |||||
| </table> | </table> | ||||
| <h3>Nested Elements</h3> | <h3>Nested Elements</h3> | ||||
| The tar task supports nested <a href="../CoreTypes/fileset.html">tarfileset</a> elements. These are | |||||
| extended Filesets which, in addition to the standard fileset elements, support three additional | |||||
| The tar task supports nested <a | |||||
| href="../CoreTypes/fileset.html">tarfileset</a> elements. These are | |||||
| extended <a href="../CoreTypes/tarfileset.html">TarFilesets</a> which, | |||||
| in addition to the standard elements, support one additional | |||||
| attributes | attributes | ||||
| <table border="1" cellpadding="2" cellspacing="0"> | <table border="1" cellpadding="2" cellspacing="0"> | ||||
| @@ -120,59 +124,6 @@ attributes | |||||
| <td valign="top"><b>Description</b></td> | <td valign="top"><b>Description</b></td> | ||||
| <td valign="top" align="center"><b>Required</b></td> | <td valign="top" align="center"><b>Required</b></td> | ||||
| </tr> | </tr> | ||||
| <tr> | |||||
| <td valign="top">mode</td> | |||||
| <td valign="top">A 3 digit octal string, specify the user, group | |||||
| and other modes in the standard Unix fashion. Only applies to | |||||
| plain files. Default is 644.</td> | |||||
| <td align="center" valign="top">No</td> | |||||
| </tr> | |||||
| <tr> | |||||
| <td valign="top">dirmode</td> | |||||
| <td valign="top">A 3 digit octal string, specify the user, group | |||||
| and other modes in the standard Unix fashion. Only applies to | |||||
| directories. Default is 755. <em>since Ant 1.6</em>.</td> | |||||
| <td align="center" valign="top">No</td> | |||||
| </tr> | |||||
| <tr> | |||||
| <td valign="top">username</td> | |||||
| <td valign="top">The username for the tar entry. This is not the same as the UID. | |||||
| </td> | |||||
| <td align="center" valign="top">No</td> | |||||
| </tr> | |||||
| <tr> | |||||
| <td valign="top">group</td> | |||||
| <td valign="top">The groupname for the tar entry. This is not the same as the GID. | |||||
| </td> | |||||
| <td align="center" valign="top">No</td> | |||||
| </tr> | |||||
| <tr> | |||||
| <td valign="top">uid</td> | |||||
| <td valign="top">The user identifier (UID) for the tar entry. This is an integer value | |||||
| and is not the same as the username. <em>since Ant 1.6.2</em>. | |||||
| </td> | |||||
| <td align="center" valign="top">No</td> | |||||
| </tr> | |||||
| <tr> | |||||
| <td valign="top">gid</td> | |||||
| <td valign="top">The group identifier (GID) for the tar entry. <em>since Ant 1.6.2</em>. | |||||
| </td> | |||||
| <td align="center" valign="top">No</td> | |||||
| </tr> | |||||
| <tr> | |||||
| <td valign="top">prefix</td> | |||||
| <td valign="top">If the prefix attribute is set, all files in the fileset | |||||
| are prefixed with that path in the archive.</td> | |||||
| <td align="center" valign="top">No</td> | |||||
| </tr> | |||||
| <tr> | |||||
| <td valign="top">fullpath</td> | |||||
| <td valign="top">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.</td> | |||||
| <td align="center" valign="top">No</td> | |||||
| </tr> | |||||
| <tr> | <tr> | ||||
| <td valign="top">preserveLeadingSlashes</td> | <td valign="top">preserveLeadingSlashes</td> | ||||
| <td valign="top">Indicates whether leading `/'s should | <td valign="top">Indicates whether leading `/'s should | ||||
| @@ -181,6 +132,13 @@ attributes | |||||
| </tr> | </tr> | ||||
| </table> | </table> | ||||
| <h4>any other resource collection</h4> | |||||
| <p><a href="../CoreTypes/resources.html#collection">Resource | |||||
| Collection</a>s are used to select groups of files to copy. To use a | |||||
| resource collection, the <code>todir</code> attribute must be set.</p> | |||||
| <p>Prior to Ant 1.7 only <code><fileset></code> has been | |||||
| supported as a nested element.</p> | |||||
| <h3>Examples</h3> | <h3>Examples</h3> | ||||
| <pre> | <pre> | ||||
| <tar tarfile="${dist}/manual.tar" basedir="htdocs/manual"/> | <tar tarfile="${dist}/manual.tar" basedir="htdocs/manual"/> | ||||
| @@ -242,8 +200,10 @@ and the rest are use the default mode (read-write by owner). The first | |||||
| fileset selects just the executable files. The second fileset must exclude | fileset selects just the executable files. The second fileset must exclude | ||||
| the executable files and include all others. </p> | the executable files and include all others. </p> | ||||
| <p><strong>Note: </strong> The tar task does not ensure that a file is only selected | <p><strong>Note: </strong> The tar task does not ensure that a file is only selected | ||||
| by one fileset. If the same file is selected by more than one fileset, it will be included in the | |||||
| by one resource collection. If the same file is selected by more than one collection, it will be included in the | |||||
| tar file twice, with the same path.</p> | tar file twice, with the same path.</p> | ||||
| <p><strong>Note:</strong> The patterns in the include and exclude | <p><strong>Note:</strong> The patterns in the include and exclude | ||||
| @@ -253,6 +213,16 @@ attribute as with all other filesets. In the example above, | |||||
| of a directory, so <code>${dist.name}</code> is a valid path relative | of a directory, so <code>${dist.name}</code> is a valid path relative | ||||
| to <code>${dist.name}/..</code>.</p> | to <code>${dist.name}/..</code>.</p> | ||||
| <pre> | |||||
| <tar dest="release.tar.gz" compress="gzip"> | |||||
| <zipfileset src="release.zip"/> | |||||
| </tar> | |||||
| </pre> | |||||
| <p>Re-packages a ZIP archive as a GZip compressed tar archive. If | |||||
| Unix file permissions have been stored as part of the ZIP file, they | |||||
| will be retained in the resulting tar archive.</p> | |||||
| <hr> | <hr> | ||||
| <p align="center">Copyright © 2000-2002,2004-2005 The Apache Software Foundation. All rights | <p align="center">Copyright © 2000-2002,2004-2005 The Apache Software Foundation. All rights | ||||
| Reserved.</p> | Reserved.</p> | ||||
| @@ -23,7 +23,7 @@ explicit use beginning in <b>Ant 1.7</b>. | |||||
| <ul> | <ul> | ||||
| <li><a href="#basic">resource</a> - a basic resource.</li> | <li><a href="#basic">resource</a> - a basic resource.</li> | ||||
| <li><a href="#file">file</a> - a file.</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="#tarentry">tarentry</a> - an entry in a tar file.</li> | |||||
| <li><a href="#zipentry">zipentry</a> - an entry in a zip 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="#gzipresource">gzipresource</a> - a GZip compressed resource.</li> | ||||
| <li><a href="#bzip2resource">bzip2resource</a> - a BZip2 compressed resource.</li> | <li><a href="#bzip2resource">bzip2resource</a> - a BZip2 compressed resource.</li> | ||||
| @@ -0,0 +1,146 @@ | |||||
| <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> | |||||
| <html> | |||||
| <head> | |||||
| <meta http-equiv="Content-Language" content="en-us"> | |||||
| <link rel="stylesheet" type="text/css" href="../stylesheets/style.css"> | |||||
| <title>TarFileSet Type</title> | |||||
| </head> | |||||
| <body> | |||||
| <h2><a name="fileset">TarFileSet</a></h2> | |||||
| <p><em>TarFileSet</em> has been added as a stand-alone type in Ant | |||||
| 1.7.</p> | |||||
| <p>A <code><tarfileset></code> is a special form 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 - or a nested resource collection has been specified, the | |||||
| tarfileset is populated with tar 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 tarfileset is populated with filesystem files found under <span | |||||
| style="font-style: italic;">dir</span>.<br> | |||||
| </li> | |||||
| </ul> | |||||
| <p><code><tarfileset></code> supports all attributes of <code><<a | |||||
| href="fileset.html">fileset</a>></code> | |||||
| in addition to those listed below.<br> | |||||
| </p> | |||||
| <p>A tarfileset 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. 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"> | |||||
| <tbody> | |||||
| <tr> | |||||
| <td valign="top"><b>Attribute</b></td> | |||||
| <td valign="top"><b>Description</b></td> | |||||
| <td valign="top" align="center"><b>Required</b></td> | |||||
| </tr> | |||||
| <tr> | |||||
| <td valign="top">prefix</td> | |||||
| <td valign="top">all files in the fileset are prefixed with that | |||||
| path in the archive.</td> | |||||
| <td align="center" valign="top">No</td> | |||||
| </tr> | |||||
| <tr> | |||||
| <td valign="top">fullpath</td> | |||||
| <td valign="top">the file described by the fileset is placed at | |||||
| that exact location in the archive.</td> | |||||
| <td align="center" valign="top">No</td> | |||||
| </tr> | |||||
| <tr> | |||||
| <td valign="top">src</td> | |||||
| <td valign="top">may be used in place of the <i>dir</i> attribute | |||||
| to specify a tar file whose contents will be extracted and included | |||||
| in the archive.</td> | |||||
| <td align="center" valign="top">No</td> | |||||
| </tr> | |||||
| <tr> | |||||
| <td valign="top">filemode</td> | |||||
| <td valign="top">A 3 digit octal string, specify the user, group | |||||
| and other modes in the standard Unix fashion. Only applies to | |||||
| plain files. Default is 644.</td> | |||||
| <td align="center" valign="top">No</td> | |||||
| </tr> | |||||
| <tr> | |||||
| <td valign="top">dirmode</td> | |||||
| <td valign="top">A 3 digit octal string, specify the user, group | |||||
| and other modes in the standard Unix fashion. Only applies to | |||||
| directories. Default is 755.</td> | |||||
| <td align="center" valign="top">No</td> | |||||
| </tr> | |||||
| <tr> | |||||
| <td valign="top">username</td> | |||||
| <td valign="top">The username for the tar entry. This is not the same as the UID. | |||||
| </td> | |||||
| <td align="center" valign="top">No</td> | |||||
| </tr> | |||||
| <tr> | |||||
| <td valign="top">group</td> | |||||
| <td valign="top">The groupname for the tar entry. This is not the same as the GID. | |||||
| </td> | |||||
| <td align="center" valign="top">No</td> | |||||
| </tr> | |||||
| <tr> | |||||
| <td valign="top">uid</td> | |||||
| <td valign="top">The user identifier (UID) for the tar entry. This is an integer value | |||||
| and is not the same as the username. | |||||
| </td> | |||||
| <td align="center" valign="top">No</td> | |||||
| </tr> | |||||
| <tr> | |||||
| <td valign="top">gid</td> | |||||
| <td valign="top">The group identifier (GID) for the tar entry. | |||||
| </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 archive for inclusion in the | |||||
| archive as with the <i>dir</i> attribute.</p> | |||||
| <p>Please note that currently only the <a | |||||
| href="../CoreTasks/tar.html">tar</a> task uses the permission and | |||||
| ownership attributes.</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.</p> | |||||
| <h4>Examples</h4> | |||||
| <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 © 2005 The Apache Software Foundation. All | |||||
| rights Reserved.</p> | |||||
| </body> | |||||
| </html> | |||||
| @@ -6,35 +6,31 @@ | |||||
| <title>ZipFileSet Type</title> | <title>ZipFileSet Type</title> | ||||
| </head> | </head> | ||||
| <body> | <body> | ||||
| <h2><a name="fileset">ZipFileSet/TarFileSet</a></h2> | |||||
| <h2><a name="fileset">ZipFileSet</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 | |||||
| <p>A <code><zipfileset></code> is a special form of a <code><<a | |||||
| href="fileset.html">fileset</a>></code> which can behave in 2 | href="fileset.html">fileset</a>></code> which can behave in 2 | ||||
| different ways : <br> | different ways : <br> | ||||
| </p> | </p> | ||||
| <ul> | <ul> | ||||
| <li>When the <span style="font-style: italic;">src</span> attribute | <li>When the <span style="font-style: italic;">src</span> attribute | ||||
| is used - or a nested resource collection has been specified | 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: | |||||
| (<em>since Ant 1.7</em>), the zipfileset is populated with | |||||
| zip entries found in the file <span style="font-style: | |||||
| italic;">src</span>.<br> | italic;">src</span>.<br> | ||||
| </li> | </li> | ||||
| <li>When the <span style="font-style: italic;">dir</span> attribute | <li>When the <span style="font-style: italic;">dir</span> attribute | ||||
| is used, the tar/zipfileset is populated with filesystem files found under <span | |||||
| is used, the zipfileset is populated with filesystem files found under <span | |||||
| style="font-style: italic;">dir</span>.<br> | style="font-style: italic;">dir</span>.<br> | ||||
| </li> | </li> | ||||
| </ul> | </ul> | ||||
| <p><code><tar/zipfileset></code> supports all attributes of <code><<a | |||||
| <p><code><zipfileset></code> supports all attributes of <code><<a | |||||
| href="fileset.html">fileset</a>></code> | href="fileset.html">fileset</a>></code> | ||||
| in addition to those listed below.<br> | in addition to those listed below.<br> | ||||
| </p> | </p> | ||||
| <p>Since Ant 1.6, a zipfileset can be defined with the <span | <p>Since Ant 1.6, a zipfileset can be defined with the <span | ||||
| style="font-style: italic;">id </span>attribute and referred to with | style="font-style: italic;">id </span>attribute and referred to with | ||||
| the <span style="font-style: italic;">refid</span> attribute. This is | |||||
| also true for tarfileset which has been added in Ant 1.7.<br> | |||||
| the <span style="font-style: italic;">refid</span> attribute.<br> | |||||
| </p> | </p> | ||||
| <h3>Parameters</h3> | <h3>Parameters</h3> | ||||
| <table border="1" cellpadding="2" cellspacing="0"> | <table border="1" cellpadding="2" cellspacing="0"> | ||||
| @@ -95,14 +91,16 @@ attributes cannot both be set on the same fileset.</p> | |||||
| may be used to specify a subset of the archive 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> | archive as with the <i>dir</i> attribute.</p> | ||||
| <p>Please note that currently only the <a | |||||
| href="../CoreTasks/tar.html">tar</a> and <a | |||||
| href="../CoreTaks/zip.html">zip</a> tasks use the permission.</p> | |||||
| <h3>Parameters specified as nested elements</h3> | <h3>Parameters specified as nested elements</h3> | ||||
| <h4>any <a href="resources.html">resource</a> or single element | |||||
| resource collection</h4> | |||||
| <h4>any file system based <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> | |||||
| <p>The specified resource will be used as src.</p> | |||||
| <h4>Examples</h4> | <h4>Examples</h4> | ||||
| <blockquote> | <blockquote> | ||||
| @@ -117,24 +115,6 @@ docs/ChangeLog.txt<br> | |||||
| docs/examples/index.html<br> | docs/examples/index.html<br> | ||||
| </code></blockquote> | </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> | <hr> | ||||
| <p align="center">Copyright © 2003-2005 The Apache Software Foundation. All | <p align="center">Copyright © 2003-2005 The Apache Software Foundation. All | ||||
| rights Reserved.</p> | rights Reserved.</p> | ||||
| @@ -34,7 +34,7 @@ | |||||
| <a href="CoreTypes/resources.html">Resources</a><br> | <a href="CoreTypes/resources.html">Resources</a><br> | ||||
| <a href="CoreTypes/resources.html#collection">Resource Collections</a><br> | <a href="CoreTypes/resources.html#collection">Resource Collections</a><br> | ||||
| <a href="CoreTypes/selectors.html">Selectors</a><br> | <a href="CoreTypes/selectors.html">Selectors</a><br> | ||||
| <a href="CoreTypes/zipfileset.html">TarFileSet</a><br> | |||||
| <a href="CoreTypes/tarfileset.html">TarFileSet</a><br> | |||||
| <a href="CoreTypes/xmlcatalog.html">XMLCatalog</a><br> | <a href="CoreTypes/xmlcatalog.html">XMLCatalog</a><br> | ||||
| <a href="CoreTypes/zipfileset.html">ZipFileSet</a><br> | <a href="CoreTypes/zipfileset.html">ZipFileSet</a><br> | ||||
| @@ -44,6 +44,32 @@ | |||||
| <untar src="test7.tar" dest="."/> | <untar src="test7.tar" dest="."/> | ||||
| </target> | </target> | ||||
| <target name="test7UsingPlainFileSet"> | |||||
| <mkdir dir="test7dir"/> | |||||
| <tar destfile="test7.tar"> | |||||
| <tarfileset dir="." prefix="test7-prefix/"> | |||||
| <include name="test7dir"/> | |||||
| </tarfileset> | |||||
| <fileset dir="."> | |||||
| <include name="test7dir"/> | |||||
| </fileset> | |||||
| </tar> | |||||
| <untar src="test7.tar" dest="."/> | |||||
| </target> | |||||
| <target name="test7UsingFileList"> | |||||
| <mkdir dir="test7dir"/> | |||||
| <tar destfile="test7.tar"> | |||||
| <tarfileset dir="." prefix="test7-prefix/"> | |||||
| <include name="test7dir"/> | |||||
| </tarfileset> | |||||
| <filelist dir="."> | |||||
| <file name="test7dir"/> | |||||
| </filelist> | |||||
| </tar> | |||||
| <untar src="test7.tar" dest="."/> | |||||
| </target> | |||||
| <target name="test8"> | <target name="test8"> | ||||
| <tar destfile="test8.tar"> | <tar destfile="test8.tar"> | ||||
| <tarfileset dir="." fullpath="/test8.xml"> | <tarfileset dir="." fullpath="/test8.xml"> | ||||
| @@ -53,6 +79,45 @@ | |||||
| <untar src="test8.tar" dest="."/> | <untar src="test8.tar" dest="."/> | ||||
| </target> | </target> | ||||
| <target name="test8UsingZipFileset"> | |||||
| <tar destfile="test8.tar"> | |||||
| <zipfileset dir="." fullpath="/test8.xml"> | |||||
| <include name="tar.xml"/> | |||||
| </zipfileset> | |||||
| </tar> | |||||
| <untar src="test8.tar" dest="."/> | |||||
| </target> | |||||
| <target name="test8UsingZipFilesetSrc"> | |||||
| <zip destfile="test7.tar" basedir="." includes="tar.xml"/> | |||||
| <tar destfile="test8.tar"> | |||||
| <zipfileset src="test7.tar" fullpath="/test8.xml"> | |||||
| <include name="tar.xml"/> | |||||
| </zipfileset> | |||||
| </tar> | |||||
| <untar src="test8.tar" dest="."/> | |||||
| </target> | |||||
| <target name="test8UsingTarFilesetSrc"> | |||||
| <tar destfile="test7.tar" basedir="." includes="tar.xml"/> | |||||
| <tar destfile="test8.tar"> | |||||
| <tarfileset src="test7.tar" fullpath="/test8.xml"> | |||||
| <include name="tar.xml"/> | |||||
| </tarfileset> | |||||
| </tar> | |||||
| <untar src="test8.tar" dest="."/> | |||||
| </target> | |||||
| <target name="test8UsingZipEntry"> | |||||
| <zip destfile="test7.tar"> | |||||
| <zipfileset dir="." includes="tar.xml" fullpath="/test8.xml"/> | |||||
| </zip> | |||||
| <tar destfile="test8.tar"> | |||||
| <zipentry archive="test7.tar" name="/test8.xml"/> | |||||
| </tar> | |||||
| <untar src="test8.tar" dest="."/> | |||||
| </target> | |||||
| <target name="test9"> | <target name="test9"> | ||||
| <tar destfile="blah" compression="Foo"/> | <tar destfile="blah" compression="Foo"/> | ||||
| </target> | </target> | ||||
| @@ -79,6 +144,7 @@ | |||||
| <delete file="test4.tar"/> | <delete file="test4.tar"/> | ||||
| <delete file="test5.tar"/> | <delete file="test5.tar"/> | ||||
| <delete file="asf-logo.gif.tar"/> | <delete file="asf-logo.gif.tar"/> | ||||
| <delete dir="testout"/> | |||||
| <delete dir="test5dir"/> | <delete dir="test5dir"/> | ||||
| <delete dir="test7dir"/> | <delete dir="test7dir"/> | ||||
| <delete dir="test7-prefix"/> | <delete dir="test7-prefix"/> | ||||
| @@ -107,5 +173,14 @@ | |||||
| compression="bzip2" /> | compression="bzip2" /> | ||||
| </target> | </target> | ||||
| <target name="testGZipResource"> | |||||
| <mkdir dir="testout"/> | |||||
| <tar destfile="testout/test.tar"> | |||||
| <gzipresource> | |||||
| <file file="expected/asf-logo.gif.gz"/> | |||||
| </gzipresource> | |||||
| </tar> | |||||
| <untar src="testout/test.tar" dest="testout"/> | |||||
| </target> | |||||
| </project> | </project> | ||||
| @@ -64,7 +64,7 @@ import org.apache.tools.ant.util.FlatFileNameMapper; | |||||
| * @ant.task category="filesystem" | * @ant.task category="filesystem" | ||||
| */ | */ | ||||
| public class Copy extends Task { | public class Copy extends Task { | ||||
| private static final File NULL_FILE_PLACEHOLDER = new File("/NULL_FILE"); | |||||
| static final File NULL_FILE_PLACEHOLDER = new File("/NULL_FILE"); | |||||
| protected File file = null; // the source file | protected File file = null; // the source file | ||||
| protected File destFile = null; // the destination file | protected File destFile = null; // the destination file | ||||
| @@ -19,18 +19,29 @@ package org.apache.tools.ant.taskdefs; | |||||
| import java.io.BufferedOutputStream; | import java.io.BufferedOutputStream; | ||||
| import java.io.File; | import java.io.File; | ||||
| import java.io.FileInputStream; | |||||
| import java.io.FileOutputStream; | import java.io.FileOutputStream; | ||||
| import java.io.IOException; | import java.io.IOException; | ||||
| import java.io.InputStream; | |||||
| import java.io.OutputStream; | import java.io.OutputStream; | ||||
| import java.util.Enumeration; | import java.util.Enumeration; | ||||
| import java.util.HashMap; | |||||
| import java.util.HashSet; | |||||
| import java.util.Iterator; | |||||
| import java.util.Vector; | import java.util.Vector; | ||||
| import java.util.zip.GZIPOutputStream; | import java.util.zip.GZIPOutputStream; | ||||
| import org.apache.tools.ant.BuildException; | import org.apache.tools.ant.BuildException; | ||||
| import org.apache.tools.ant.DirectoryScanner; | import org.apache.tools.ant.DirectoryScanner; | ||||
| import org.apache.tools.ant.Project; | import org.apache.tools.ant.Project; | ||||
| import org.apache.tools.ant.types.ArchiveFileSet; | |||||
| import org.apache.tools.ant.types.EnumeratedAttribute; | import org.apache.tools.ant.types.EnumeratedAttribute; | ||||
| import org.apache.tools.ant.types.FileSet; | import org.apache.tools.ant.types.FileSet; | ||||
| import org.apache.tools.ant.types.Resource; | |||||
| import org.apache.tools.ant.types.ResourceCollection; | |||||
| import org.apache.tools.ant.types.resources.ArchiveResource; | |||||
| import org.apache.tools.ant.types.resources.FileResource; | |||||
| import org.apache.tools.ant.types.selectors.SelectorUtils; | |||||
| import org.apache.tools.ant.types.resources.TarResource; | |||||
| import org.apache.tools.ant.util.FileUtils; | |||||
| import org.apache.tools.ant.util.MergingMapper; | import org.apache.tools.ant.util.MergingMapper; | ||||
| import org.apache.tools.ant.util.SourceFileScanner; | import org.apache.tools.ant.util.SourceFileScanner; | ||||
| import org.apache.tools.bzip2.CBZip2OutputStream; | import org.apache.tools.bzip2.CBZip2OutputStream; | ||||
| @@ -79,7 +90,12 @@ public class Tar extends MatchingTask { | |||||
| private TarLongFileMode longFileMode = new TarLongFileMode(); | private TarLongFileMode longFileMode = new TarLongFileMode(); | ||||
| // need to keep the package private version for backwards compatibility | |||||
| Vector filesets = new Vector(); | Vector filesets = new Vector(); | ||||
| // we must keep two lists since other classes may modify the | |||||
| // filesets Vector (it is package private) without us noticing | |||||
| private Vector resourceCollections = new Vector(); | |||||
| Vector fileSetFiles = new Vector(); | Vector fileSetFiles = new Vector(); | ||||
| /** | /** | ||||
| @@ -95,10 +111,19 @@ public class Tar extends MatchingTask { | |||||
| */ | */ | ||||
| public TarFileSet createTarFileSet() { | public TarFileSet createTarFileSet() { | ||||
| TarFileSet fs = new TarFileSet(); | TarFileSet fs = new TarFileSet(); | ||||
| fs.setProject(getProject()); | |||||
| filesets.addElement(fs); | filesets.addElement(fs); | ||||
| return fs; | return fs; | ||||
| } | } | ||||
| /** | |||||
| * Add a collection of resources to archive. | |||||
| * @param res a resource collection to archive. | |||||
| * @since Ant 1.7 | |||||
| */ | |||||
| public void add(ResourceCollection res) { | |||||
| resourceCollections.add(res); | |||||
| } | |||||
| /** | /** | ||||
| * Set is the name/location of where to create the tar file. | * Set is the name/location of where to create the tar file. | ||||
| @@ -217,9 +242,10 @@ public class Tar extends MatchingTask { | |||||
| filesets.addElement(mainFileSet); | filesets.addElement(mainFileSet); | ||||
| } | } | ||||
| if (filesets.size() == 0) { | |||||
| if (filesets.size() == 0 && resourceCollections.size() == 0) { | |||||
| throw new BuildException("You must supply either a basedir " | throw new BuildException("You must supply either a basedir " | ||||
| + "attribute or some nested filesets.", | |||||
| + "attribute or some nested resource" | |||||
| + " collections.", | |||||
| getLocation()); | getLocation()); | ||||
| } | } | ||||
| @@ -227,20 +253,11 @@ public class Tar extends MatchingTask { | |||||
| // fileset | // fileset | ||||
| boolean upToDate = true; | boolean upToDate = true; | ||||
| for (Enumeration e = filesets.elements(); e.hasMoreElements();) { | for (Enumeration e = filesets.elements(); e.hasMoreElements();) { | ||||
| TarFileSet fs = (TarFileSet) e.nextElement(); | |||||
| String[] files = fs.getFiles(getProject()); | |||||
| if (!archiveIsUpToDate(files, fs.getDir(getProject()))) { | |||||
| upToDate = false; | |||||
| } | |||||
| for (int i = 0; i < files.length; ++i) { | |||||
| if (tarFile.equals(new File(fs.getDir(getProject()), | |||||
| files[i]))) { | |||||
| throw new BuildException("A tar file cannot include " | |||||
| + "itself", getLocation()); | |||||
| } | |||||
| } | |||||
| upToDate &= check((TarFileSet) e.nextElement()); | |||||
| } | |||||
| for (Enumeration e = resourceCollections.elements(); | |||||
| e.hasMoreElements();) { | |||||
| upToDate &= check((ResourceCollection) e.nextElement()); | |||||
| } | } | ||||
| if (upToDate) { | if (upToDate) { | ||||
| @@ -271,19 +288,11 @@ public class Tar extends MatchingTask { | |||||
| longWarningGiven = false; | longWarningGiven = false; | ||||
| for (Enumeration e = filesets.elements(); | for (Enumeration e = filesets.elements(); | ||||
| e.hasMoreElements();) { | e.hasMoreElements();) { | ||||
| TarFileSet fs = (TarFileSet) e.nextElement(); | |||||
| String[] files = fs.getFiles(getProject()); | |||||
| if (files.length > 1 && fs.getFullpath().length() > 0) { | |||||
| throw new BuildException("fullpath attribute may only " | |||||
| + "be specified for " | |||||
| + "filesets that specify a " | |||||
| + "single file."); | |||||
| } | |||||
| for (int i = 0; i < files.length; i++) { | |||||
| File f = new File(fs.getDir(getProject()), files[i]); | |||||
| String name = files[i].replace(File.separatorChar, '/'); | |||||
| tarFile(f, tOut, name, fs); | |||||
| } | |||||
| tar((TarFileSet) e.nextElement(), tOut); | |||||
| } | |||||
| for (Enumeration e = resourceCollections.elements(); | |||||
| e.hasMoreElements();) { | |||||
| tar((ResourceCollection) e.nextElement(), tOut); | |||||
| } | } | ||||
| } catch (IOException ioe) { | } catch (IOException ioe) { | ||||
| String msg = "Problem creating TAR: " + ioe.getMessage(); | String msg = "Problem creating TAR: " + ioe.getMessage(); | ||||
| @@ -314,95 +323,144 @@ public class Tar extends MatchingTask { | |||||
| protected void tarFile(File file, TarOutputStream tOut, String vPath, | protected void tarFile(File file, TarOutputStream tOut, String vPath, | ||||
| TarFileSet tarFileSet) | TarFileSet tarFileSet) | ||||
| throws IOException { | throws IOException { | ||||
| FileInputStream fIn = null; | |||||
| tarResource(new FileResource(file), tOut, vPath, tarFileSet); | |||||
| } | |||||
| String fullpath = tarFileSet.getFullpath(); | |||||
| if (fullpath.length() > 0) { | |||||
| vPath = fullpath; | |||||
| } else { | |||||
| // don't add "" to the archive | |||||
| if (vPath.length() <= 0) { | |||||
| return; | |||||
| } | |||||
| /** | |||||
| * tar a resource | |||||
| * @param file the resource to tar | |||||
| * @param tOut the output stream | |||||
| * @param vPath the path name of the file to tar | |||||
| * @param tarFileSet the fileset that the file came from, may be null. | |||||
| * @throws IOException on error | |||||
| * @since Ant 1.7 | |||||
| */ | |||||
| protected void tarResource(Resource r, TarOutputStream tOut, String vPath, | |||||
| TarFileSet tarFileSet) | |||||
| throws IOException { | |||||
| if (!r.isExists()) { | |||||
| return; | |||||
| } | |||||
| if (file.isDirectory() && !vPath.endsWith("/")) { | |||||
| vPath += "/"; | |||||
| if (tarFileSet != null) { | |||||
| String fullpath = tarFileSet.getFullpath(); | |||||
| if (fullpath.length() > 0) { | |||||
| vPath = fullpath; | |||||
| } else { | |||||
| // don't add "" to the archive | |||||
| if (vPath.length() <= 0) { | |||||
| return; | |||||
| } | |||||
| String prefix = tarFileSet.getPrefix(); | |||||
| // '/' is appended for compatibility with the zip task. | |||||
| if (prefix.length() > 0 && !prefix.endsWith("/")) { | |||||
| prefix = prefix + "/"; | |||||
| } | |||||
| vPath = prefix + vPath; | |||||
| } | } | ||||
| String prefix = tarFileSet.getPrefix(); | |||||
| // '/' is appended for compatibility with the zip task. | |||||
| if (prefix.length() > 0 && !prefix.endsWith("/")) { | |||||
| prefix = prefix + "/"; | |||||
| if (vPath.startsWith("/") | |||||
| && !tarFileSet.getPreserveLeadingSlashes()) { | |||||
| int l = vPath.length(); | |||||
| if (l <= 1) { | |||||
| // we would end up adding "" to the archive | |||||
| return; | |||||
| } | |||||
| vPath = vPath.substring(1, l); | |||||
| } | } | ||||
| vPath = prefix + vPath; | |||||
| } | } | ||||
| if (vPath.startsWith("/") && !tarFileSet.getPreserveLeadingSlashes()) { | |||||
| int l = vPath.length(); | |||||
| if (l <= 1) { | |||||
| // we would end up adding "" to the archive | |||||
| return; | |||||
| } | |||||
| vPath = vPath.substring(1, l); | |||||
| if (r.isDirectory() && !vPath.endsWith("/")) { | |||||
| vPath += "/"; | |||||
| } | } | ||||
| try { | |||||
| if (vPath.length() >= TarConstants.NAMELEN) { | |||||
| if (longFileMode.isOmitMode()) { | |||||
| log("Omitting: " + vPath, Project.MSG_INFO); | |||||
| return; | |||||
| } else if (longFileMode.isWarnMode()) { | |||||
| log("Entry: " + vPath + " longer than " | |||||
| + TarConstants.NAMELEN + " characters.", | |||||
| if (vPath.length() >= TarConstants.NAMELEN) { | |||||
| if (longFileMode.isOmitMode()) { | |||||
| log("Omitting: " + vPath, Project.MSG_INFO); | |||||
| return; | |||||
| } else if (longFileMode.isWarnMode()) { | |||||
| log("Entry: " + vPath + " longer than " | |||||
| + TarConstants.NAMELEN + " characters.", | |||||
| Project.MSG_WARN); | |||||
| if (!longWarningGiven) { | |||||
| log("Resulting tar file can only be processed " | |||||
| + "successfully by GNU compatible tar commands", | |||||
| Project.MSG_WARN); | Project.MSG_WARN); | ||||
| if (!longWarningGiven) { | |||||
| log("Resulting tar file can only be processed " | |||||
| + "successfully by GNU compatible tar commands", | |||||
| Project.MSG_WARN); | |||||
| longWarningGiven = true; | |||||
| } | |||||
| } else if (longFileMode.isFailMode()) { | |||||
| throw new BuildException("Entry: " + vPath | |||||
| longWarningGiven = true; | |||||
| } | |||||
| } else if (longFileMode.isFailMode()) { | |||||
| throw new BuildException("Entry: " + vPath | |||||
| + " longer than " + TarConstants.NAMELEN | + " longer than " + TarConstants.NAMELEN | ||||
| + "characters.", getLocation()); | + "characters.", getLocation()); | ||||
| } | |||||
| } | } | ||||
| } | |||||
| TarEntry te = new TarEntry(vPath); | |||||
| te.setModTime(file.lastModified()); | |||||
| if (!file.isDirectory()) { | |||||
| if (file.length() > TarConstants.MAXSIZE) { | |||||
| throw new BuildException("File: " + file + " larger than " + | |||||
| TarConstants.MAXSIZE + " bytes."); | |||||
| } | |||||
| te.setSize(file.length()); | |||||
| TarEntry te = new TarEntry(vPath); | |||||
| te.setModTime(r.getLastModified()); | |||||
| // preserve permissions | |||||
| if (r instanceof ArchiveResource) { | |||||
| ArchiveResource ar = (ArchiveResource) r; | |||||
| te.setMode(ar.getMode()); | |||||
| if (r instanceof TarResource) { | |||||
| TarResource tr = (TarResource) r; | |||||
| te.setUserName(tr.getUserName()); | |||||
| te.setUserId(tr.getUid()); | |||||
| te.setGroupName(tr.getGroup()); | |||||
| te.setGroupId(tr.getGid()); | |||||
| } | |||||
| } | |||||
| if (!r.isDirectory()) { | |||||
| if (r.size() > TarConstants.MAXSIZE) { | |||||
| throw new BuildException("Resource: " + r + " larger than " + | |||||
| TarConstants.MAXSIZE + " bytes."); | |||||
| } | |||||
| te.setSize(r.getSize()); | |||||
| // override permissions if set explicitly | |||||
| if (tarFileSet != null && tarFileSet.hasFileModeBeenSet()) { | |||||
| te.setMode(tarFileSet.getMode()); | te.setMode(tarFileSet.getMode()); | ||||
| } else { | |||||
| te.setMode(tarFileSet.getDirMode()); | |||||
| } | } | ||||
| te.setUserName(tarFileSet.getUserName()); | |||||
| te.setGroupName(tarFileSet.getGroup()); | |||||
| te.setUserId(tarFileSet.getUid()); | |||||
| te.setGroupId(tarFileSet.getGid()); | |||||
| } else if (tarFileSet != null && tarFileSet.hasDirModeBeenSet()) { | |||||
| // override permissions if set explicitly | |||||
| te.setMode(tarFileSet.getDirMode()); | |||||
| } | |||||
| if (tarFileSet != null) { | |||||
| // only override permissions if set explicitly | |||||
| if (tarFileSet.hasUserNameBeenSet()) { | |||||
| te.setUserName(tarFileSet.getUserName()); | |||||
| } | |||||
| if (tarFileSet.hasGroupBeenSet()) { | |||||
| te.setGroupName(tarFileSet.getGroup()); | |||||
| } | |||||
| if (tarFileSet.hasUserIdBeenSet()) { | |||||
| te.setUserId(tarFileSet.getUid()); | |||||
| } | |||||
| if (tarFileSet.hasGroupIdBeenSet()) { | |||||
| te.setGroupId(tarFileSet.getGid()); | |||||
| } | |||||
| } | |||||
| InputStream in = null; | |||||
| try { | |||||
| tOut.putNextEntry(te); | tOut.putNextEntry(te); | ||||
| if (!file.isDirectory()) { | |||||
| fIn = new FileInputStream(file); | |||||
| if (!r.isDirectory()) { | |||||
| in = r.getInputStream(); | |||||
| byte[] buffer = new byte[8 * 1024]; | byte[] buffer = new byte[8 * 1024]; | ||||
| int count = 0; | int count = 0; | ||||
| do { | do { | ||||
| tOut.write(buffer, 0, count); | tOut.write(buffer, 0, count); | ||||
| count = fIn.read(buffer, 0, buffer.length); | |||||
| count = in.read(buffer, 0, buffer.length); | |||||
| } while (count != -1); | } while (count != -1); | ||||
| } | } | ||||
| tOut.closeEntry(); | tOut.closeEntry(); | ||||
| } finally { | } finally { | ||||
| if (fIn != null) { | |||||
| fIn.close(); | |||||
| } | |||||
| FileUtils.close(in); | |||||
| } | } | ||||
| } | } | ||||
| @@ -430,6 +488,243 @@ public class Tar extends MatchingTask { | |||||
| return sfs.restrict(files, dir, null, mm).length == 0; | return sfs.restrict(files, dir, null, mm).length == 0; | ||||
| } | } | ||||
| /** | |||||
| * Is the archive up to date in relationship to a list of files. | |||||
| * @param files the files to check | |||||
| * @return true if the archive is up to date. | |||||
| * @since Ant 1.7 | |||||
| */ | |||||
| protected boolean archiveIsUpToDate(Resource r) { | |||||
| return SelectorUtils.isOutOfDate(new FileResource(tarFile), r, | |||||
| FileUtils.getFileUtils() | |||||
| .getFileTimestampGranularity()); | |||||
| } | |||||
| /** | |||||
| * Whether this task can deal with non-file resources. | |||||
| * | |||||
| * <p>This implementation returns true only if this task is | |||||
| * <tar>. Any subclass of this class that also wants to | |||||
| * support non-file resources needs to override this method. We | |||||
| * need to do so for backwards compatibility reasons since we | |||||
| * can't expect subclasses to support resources.</p> | |||||
| * | |||||
| * @since Ant 1.7 | |||||
| */ | |||||
| protected boolean supportsNonFileResources() { | |||||
| return getClass().equals(Tar.class); | |||||
| } | |||||
| /** | |||||
| * Checks whether the archive is out-of-date with respect to the resources | |||||
| * of the given collection. | |||||
| * | |||||
| * <p>Also checks that either all collections only contain file | |||||
| * resources or this class supports non-file collections.</p> | |||||
| * | |||||
| * <p>And - in case of file-collections - ensures that the archive won't | |||||
| * contain itself.</p> | |||||
| * | |||||
| * @param rc the resource collection to check | |||||
| * @return whether the archive is up-to-date | |||||
| * @since Ant 1.7 | |||||
| */ | |||||
| protected boolean check(ResourceCollection rc) { | |||||
| boolean upToDate = true; | |||||
| if (isFileFileSet(rc)) { | |||||
| FileSet fs = (FileSet) rc; | |||||
| upToDate = check(fs.getDir(getProject()), getFileNames(fs)); | |||||
| } else if (!rc.isFilesystemOnly() && !supportsNonFileResources()) { | |||||
| throw new BuildException("only filesystem resources are supported"); | |||||
| } else if (rc.isFilesystemOnly()) { | |||||
| HashSet basedirs = new HashSet(); | |||||
| HashMap basedirToFilesMap = new HashMap(); | |||||
| Iterator iter = rc.iterator(); | |||||
| while (iter.hasNext()) { | |||||
| FileResource r = (FileResource) iter.next(); | |||||
| File base = r.getBaseDir(); | |||||
| if (base == null) { | |||||
| base = Copy.NULL_FILE_PLACEHOLDER; | |||||
| } | |||||
| basedirs.add(base); | |||||
| Vector files = (Vector) basedirToFilesMap.get(base); | |||||
| if (files == null) { | |||||
| files = new Vector(); | |||||
| basedirToFilesMap.put(base, new Vector()); | |||||
| } | |||||
| files.add(r.getName()); | |||||
| } | |||||
| iter = basedirs.iterator(); | |||||
| while (iter.hasNext()) { | |||||
| File base = (File) iter.next(); | |||||
| Vector f = (Vector) basedirToFilesMap.get(base); | |||||
| String[] files = (String[]) f.toArray(new String[f.size()]); | |||||
| upToDate &= | |||||
| check(base == Copy.NULL_FILE_PLACEHOLDER ? null : base, | |||||
| files); | |||||
| } | |||||
| } else { // non-file resources | |||||
| Iterator iter = rc.iterator(); | |||||
| while (upToDate && iter.hasNext()) { | |||||
| Resource r = (Resource) iter.next(); | |||||
| upToDate &= archiveIsUpToDate(r); | |||||
| } | |||||
| } | |||||
| return upToDate; | |||||
| } | |||||
| /** | |||||
| * Checks whether the archive is out-of-date with respect to the | |||||
| * given files, ensures that the archive won't contain itself.</p> | |||||
| * | |||||
| * @param basedir base directory for file names | |||||
| * @param files array of relative file names | |||||
| * @return whether the archive is up-to-date | |||||
| * @since Ant 1.7 | |||||
| */ | |||||
| protected boolean check(File basedir, String[] files) { | |||||
| boolean upToDate = true; | |||||
| if (!archiveIsUpToDate(files, basedir)) { | |||||
| upToDate = false; | |||||
| } | |||||
| for (int i = 0; i < files.length; ++i) { | |||||
| if (tarFile.equals(new File(basedir, files[i]))) { | |||||
| throw new BuildException("A tar file cannot include " | |||||
| + "itself", getLocation()); | |||||
| } | |||||
| } | |||||
| return upToDate; | |||||
| } | |||||
| /** | |||||
| * Adds the resources contained in this collection to the archive. | |||||
| * | |||||
| * <p>Uses the file based methods for file resources for backwards | |||||
| * compatibility.</p> | |||||
| * | |||||
| * @param rc the collection containing resources to add | |||||
| * @param tOut stream writing to the archive. | |||||
| * @since Ant 1.7 | |||||
| */ | |||||
| protected void tar(ResourceCollection rc, TarOutputStream tOut) | |||||
| throws IOException { | |||||
| ArchiveFileSet afs = null; | |||||
| if (rc instanceof ArchiveFileSet) { | |||||
| afs = (ArchiveFileSet) rc; | |||||
| } | |||||
| if (afs != null && afs.size() > 1 | |||||
| && afs.getFullpath().length() > 0) { | |||||
| throw new BuildException("fullpath attribute may only " | |||||
| + "be specified for " | |||||
| + "filesets that specify a " | |||||
| + "single file."); | |||||
| } | |||||
| TarFileSet tfs = asTarFileSet(afs); | |||||
| if (isFileFileSet(rc)) { | |||||
| FileSet fs = (FileSet) rc; | |||||
| String[] files = getFileNames(fs); | |||||
| for (int i = 0; i < files.length; i++) { | |||||
| File f = new File(fs.getDir(getProject()), files[i]); | |||||
| String name = files[i].replace(File.separatorChar, '/'); | |||||
| tarFile(f, tOut, name, tfs); | |||||
| } | |||||
| } else if (rc.isFilesystemOnly()) { | |||||
| Iterator iter = rc.iterator(); | |||||
| while (iter.hasNext()) { | |||||
| FileResource r = (FileResource) iter.next(); | |||||
| File f = r.getFile(); | |||||
| if (f == null) { | |||||
| f = new File(r.getBaseDir(), r.getName()); | |||||
| } | |||||
| tarFile(f, tOut, f.getName(), tfs); | |||||
| } | |||||
| } else { // non-file resources | |||||
| Iterator iter = rc.iterator(); | |||||
| while (iter.hasNext()) { | |||||
| Resource r = (Resource) iter.next(); | |||||
| tarResource(r, tOut, r.getName(), tfs); | |||||
| } | |||||
| } | |||||
| } | |||||
| /** | |||||
| * whether the given resource collection is a (subclass of) | |||||
| * FileSet that only contains file system resources. | |||||
| * @since Ant 1.7 | |||||
| */ | |||||
| protected static final boolean isFileFileSet(ResourceCollection rc) { | |||||
| return rc instanceof FileSet && rc.isFilesystemOnly(); | |||||
| } | |||||
| /** | |||||
| * Grabs all included files and directors from the FileSet and | |||||
| * returns them as an array of (relative) file names. | |||||
| * | |||||
| * @since Ant 1.7 | |||||
| */ | |||||
| protected static final String[] getFileNames(FileSet fs) { | |||||
| DirectoryScanner ds = fs.getDirectoryScanner(fs.getProject()); | |||||
| String[] directories = ds.getIncludedDirectories(); | |||||
| String[] filesPerSe = ds.getIncludedFiles(); | |||||
| String[] files = new String [directories.length + filesPerSe.length]; | |||||
| System.arraycopy(directories, 0, files, 0, directories.length); | |||||
| System.arraycopy(filesPerSe, 0, files, directories.length, | |||||
| filesPerSe.length); | |||||
| return files; | |||||
| } | |||||
| /** | |||||
| * Copies fullpath, prefix and permission attributes from the | |||||
| * ArchiveFileSet to a new TarFileSet (or returns it unchanged if | |||||
| * it already is a TarFileSet). | |||||
| * | |||||
| * @param archiveFileSet fileset to copy attributes from, may be null | |||||
| * @since Ant 1.7 | |||||
| */ | |||||
| protected TarFileSet asTarFileSet(ArchiveFileSet archiveFileSet) { | |||||
| TarFileSet tfs = null; | |||||
| if (archiveFileSet != null && archiveFileSet instanceof TarFileSet) { | |||||
| tfs = (TarFileSet) archiveFileSet; | |||||
| } else { | |||||
| tfs = new TarFileSet(); | |||||
| tfs.setProject(getProject()); | |||||
| if (archiveFileSet != null) { | |||||
| tfs.setPrefix(archiveFileSet.getPrefix(getProject())); | |||||
| tfs.setFullpath(archiveFileSet.getFullpath(getProject())); | |||||
| if (archiveFileSet.hasFileModeBeenSet()) { | |||||
| tfs.integerSetFileMode(archiveFileSet | |||||
| .getFileMode(getProject())); | |||||
| } | |||||
| if (archiveFileSet.hasDirModeBeenSet()) { | |||||
| tfs.integerSetDirMode(archiveFileSet | |||||
| .getDirMode(getProject())); | |||||
| } | |||||
| if (archiveFileSet instanceof | |||||
| org.apache.tools.ant.types.TarFileSet) { | |||||
| org.apache.tools.ant.types.TarFileSet t = | |||||
| (org.apache.tools.ant.types.TarFileSet) archiveFileSet; | |||||
| if (t.hasUserNameBeenSet()) { | |||||
| tfs.setUserName(t.getUserName()); | |||||
| } | |||||
| if (t.hasGroupBeenSet()) { | |||||
| tfs.setGroup(t.getGroup()); | |||||
| } | |||||
| if (t.hasUserIdBeenSet()) { | |||||
| tfs.setUid(t.getUid()); | |||||
| } | |||||
| if (t.hasGroupIdBeenSet()) { | |||||
| tfs.setGid(t.getGid()); | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| return tfs; | |||||
| } | |||||
| /** | /** | ||||
| * This is a FileSet with the option to specify permissions | * This is a FileSet with the option to specify permissions | ||||
| * and other attributes. | * and other attributes. | ||||
| @@ -438,10 +733,6 @@ public class Tar extends MatchingTask { | |||||
| extends org.apache.tools.ant.types.TarFileSet { | extends org.apache.tools.ant.types.TarFileSet { | ||||
| private String[] files = null; | private String[] files = null; | ||||
| private String userName = ""; | |||||
| private String groupName = ""; | |||||
| private int uid; | |||||
| private int gid; | |||||
| private boolean preserveLeadingSlashes = false; | private boolean preserveLeadingSlashes = false; | ||||
| /** | /** | ||||
| @@ -470,13 +761,7 @@ public class Tar extends MatchingTask { | |||||
| */ | */ | ||||
| public String[] getFiles(Project p) { | public String[] getFiles(Project p) { | ||||
| if (files == null) { | if (files == null) { | ||||
| DirectoryScanner ds = getDirectoryScanner(p); | |||||
| String[] directories = ds.getIncludedDirectories(); | |||||
| String[] filesPerSe = ds.getIncludedFiles(); | |||||
| files = new String [directories.length + filesPerSe.length]; | |||||
| System.arraycopy(directories, 0, files, 0, directories.length); | |||||
| System.arraycopy(filesPerSe, 0, files, directories.length, | |||||
| filesPerSe.length); | |||||
| files = getFileNames(this); | |||||
| } | } | ||||
| return files; | return files; | ||||
| @@ -499,70 +784,6 @@ public class Tar extends MatchingTask { | |||||
| return getFileMode(); | return getFileMode(); | ||||
| } | } | ||||
| /** | |||||
| * The username for the tar entry | |||||
| * This is not the same as the UID. | |||||
| * @param userName the user name for the tar entry. | |||||
| */ | |||||
| public void setUserName(String userName) { | |||||
| this.userName = userName; | |||||
| } | |||||
| /** | |||||
| * @return the user name for the tar entry | |||||
| */ | |||||
| public String getUserName() { | |||||
| return userName; | |||||
| } | |||||
| /** | |||||
| * The uid for the tar entry | |||||
| * This is not the same as the User name. | |||||
| * @param uid the id of the user for the tar entry. | |||||
| */ | |||||
| public void setUid(int uid) { | |||||
| this.uid = uid; | |||||
| } | |||||
| /** | |||||
| * @return the uid for the tar entry | |||||
| */ | |||||
| public int getUid() { | |||||
| return uid; | |||||
| } | |||||
| /** | |||||
| * The groupname for the tar entry; optional, default="" | |||||
| * This is not the same as the GID. | |||||
| * @param groupName the group name string. | |||||
| */ | |||||
| public void setGroup(String groupName) { | |||||
| this.groupName = groupName; | |||||
| } | |||||
| /** | |||||
| * @return the group name string. | |||||
| */ | |||||
| public String getGroup() { | |||||
| return groupName; | |||||
| } | |||||
| /** | |||||
| * The GID for the tar entry; optional, default="0" | |||||
| * This is not the same as the group name. | |||||
| * @param gid the group id. | |||||
| */ | |||||
| public void setGid(int gid) { | |||||
| this.gid = gid; | |||||
| } | |||||
| /** | |||||
| * @return the group identifier. | |||||
| */ | |||||
| public int getGid() { | |||||
| return gid; | |||||
| } | |||||
| /** | /** | ||||
| * Flag to indicates whether leading `/'s should | * Flag to indicates whether leading `/'s should | ||||
| * be preserved in the file names. | * be preserved in the file names. | ||||
| @@ -310,9 +310,22 @@ public abstract class ArchiveFileSet extends FileSet { | |||||
| * @param octalString a <code>String</code> value | * @param octalString a <code>String</code> value | ||||
| */ | */ | ||||
| public void setFileMode(String octalString) { | public void setFileMode(String octalString) { | ||||
| integerSetFileMode(Integer.parseInt(octalString, 8)); | |||||
| } | |||||
| /** | |||||
| * specify the user, group and | |||||
| * other modes in the standard Unix fashion; | |||||
| * optional, default=0644 | |||||
| * | |||||
| * <p>We use the strange name so this method doesn't appear in | |||||
| * IntrospectionHelpers list of attribute setters.</p> | |||||
| * @param mode a <code>int</code> value | |||||
| * @since Ant 1.7 | |||||
| */ | |||||
| public void integerSetFileMode(int mode) { | |||||
| fileModeHasBeenSet = true; | fileModeHasBeenSet = true; | ||||
| this.fileMode = | |||||
| UnixStat.FILE_FLAG | Integer.parseInt(octalString, 8); | |||||
| this.fileMode = UnixStat.FILE_FLAG | mode; | |||||
| } | } | ||||
| /** | /** | ||||
| @@ -353,9 +366,21 @@ public abstract class ArchiveFileSet extends FileSet { | |||||
| * @param octalString a <code>String</code> value | * @param octalString a <code>String</code> value | ||||
| */ | */ | ||||
| public void setDirMode(String octalString) { | public void setDirMode(String octalString) { | ||||
| integerSetDirMode(Integer.parseInt(octalString, 8)); | |||||
| } | |||||
| /** | |||||
| * specify the user, group and | |||||
| * other modes in the standard Unix fashion; | |||||
| * optional, default=0755 | |||||
| * <p>We use the strange name so this method doesn't appear in | |||||
| * IntrospectionHelpers list of attribute setters.</p> | |||||
| * @param mode a <code>int</code> value | |||||
| * @since Ant 1.7 | |||||
| */ | |||||
| public void integerSetDirMode(int mode) { | |||||
| dirModeHasBeenSet = true; | dirModeHasBeenSet = true; | ||||
| this.dirMode = | |||||
| UnixStat.DIR_FLAG | Integer.parseInt(octalString, 8); | |||||
| this.dirMode = UnixStat.DIR_FLAG | mode; | |||||
| } | } | ||||
| /** | /** | ||||
| @@ -395,7 +420,7 @@ public abstract class ArchiveFileSet extends FileSet { | |||||
| * @param p the project to use | * @param p the project to use | ||||
| * @return the abstract fileset instance | * @return the abstract fileset instance | ||||
| */ | */ | ||||
| protected final void configureFileSet(ArchiveFileSet zfs) { | |||||
| protected void configureFileSet(ArchiveFileSet zfs) { | |||||
| zfs.setPrefix(prefix); | zfs.setPrefix(prefix); | ||||
| zfs.setFullpath(fullpath); | zfs.setFullpath(fullpath); | ||||
| zfs.fileModeHasBeenSet = fileModeHasBeenSet; | zfs.fileModeHasBeenSet = fileModeHasBeenSet; | ||||
| @@ -31,11 +31,19 @@ import org.apache.tools.zip.UnixStat; | |||||
| * entries of a Tar file for inclusion in another Tar file. It also includes | * 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. | * 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 { | public class TarFileSet extends ArchiveFileSet { | ||||
| private boolean userNameSet; | |||||
| private boolean groupNameSet; | |||||
| private boolean userIdSet; | |||||
| private boolean groupIdSet; | |||||
| private String userName = ""; | |||||
| private String groupName = ""; | |||||
| private int uid; | |||||
| private int gid; | |||||
| /** Constructor for TarFileSet */ | /** Constructor for TarFileSet */ | ||||
| public TarFileSet() { | public TarFileSet() { | ||||
| super(); | super(); | ||||
| @@ -57,11 +65,138 @@ public class TarFileSet extends ArchiveFileSet { | |||||
| super(fileset); | super(fileset); | ||||
| } | } | ||||
| /** | |||||
| * The username for the tar entry | |||||
| * This is not the same as the UID. | |||||
| * @param userName the user name for the tar entry. | |||||
| */ | |||||
| public void setUserName(String userName) { | |||||
| checkAttributesAllowed(); | |||||
| userNameSet = true; | |||||
| this.userName = userName; | |||||
| } | |||||
| /** | |||||
| * @return the user name for the tar entry | |||||
| */ | |||||
| public String getUserName() { | |||||
| if (isReference()) { | |||||
| return ((TarFileSet) getCheckedRef()).getUserName(); | |||||
| } | |||||
| return userName; | |||||
| } | |||||
| /** | |||||
| * @return whether the user name has been explicitly set. | |||||
| */ | |||||
| public boolean hasUserNameBeenSet() { | |||||
| return userNameSet; | |||||
| } | |||||
| /** | |||||
| * The uid for the tar entry | |||||
| * This is not the same as the User name. | |||||
| * @param uid the id of the user for the tar entry. | |||||
| */ | |||||
| public void setUid(int uid) { | |||||
| checkAttributesAllowed(); | |||||
| userIdSet = true; | |||||
| this.uid = uid; | |||||
| } | |||||
| /** | |||||
| * @return the uid for the tar entry | |||||
| */ | |||||
| public int getUid() { | |||||
| if (isReference()) { | |||||
| return ((TarFileSet) getCheckedRef()).getUid(); | |||||
| } | |||||
| return uid; | |||||
| } | |||||
| /** | |||||
| * @return whether the user id has been explicitly set. | |||||
| */ | |||||
| public boolean hasUserIdBeenSet() { | |||||
| return userIdSet; | |||||
| } | |||||
| /** | |||||
| * The groupname for the tar entry; optional, default="" | |||||
| * This is not the same as the GID. | |||||
| * @param groupName the group name string. | |||||
| */ | |||||
| public void setGroup(String groupName) { | |||||
| checkAttributesAllowed(); | |||||
| groupNameSet = true; | |||||
| this.groupName = groupName; | |||||
| } | |||||
| /** | |||||
| * @return the group name string. | |||||
| */ | |||||
| public String getGroup() { | |||||
| if (isReference()) { | |||||
| return ((TarFileSet) getCheckedRef()).getGroup(); | |||||
| } | |||||
| return groupName; | |||||
| } | |||||
| /** | |||||
| * @return whether the group name has been explicitly set. | |||||
| */ | |||||
| public boolean hasGroupBeenSet() { | |||||
| return groupNameSet; | |||||
| } | |||||
| /** | |||||
| * The GID for the tar entry; optional, default="0" | |||||
| * This is not the same as the group name. | |||||
| * @param gid the group id. | |||||
| */ | |||||
| public void setGid(int gid) { | |||||
| checkAttributesAllowed(); | |||||
| groupIdSet = true; | |||||
| this.gid = gid; | |||||
| } | |||||
| /** | |||||
| * @return the group identifier. | |||||
| */ | |||||
| public int getGid() { | |||||
| if (isReference()) { | |||||
| return ((TarFileSet) getCheckedRef()).getGid(); | |||||
| } | |||||
| return gid; | |||||
| } | |||||
| /** | |||||
| * @return whether the group id has been explicitly set. | |||||
| */ | |||||
| public boolean hasGroupIdBeenSet() { | |||||
| return groupIdSet; | |||||
| } | |||||
| protected ArchiveScanner newArchiveScanner() { | protected ArchiveScanner newArchiveScanner() { | ||||
| TarScanner zs = new TarScanner(); | TarScanner zs = new TarScanner(); | ||||
| return zs; | return zs; | ||||
| } | } | ||||
| /** | |||||
| * Makes this instance in effect a reference to another instance. | |||||
| * | |||||
| * <p>You must not set another attribute or nest elements inside | |||||
| * this element if you make it a reference.</p> | |||||
| * @param r the <code>Reference</code> to use. | |||||
| * @throws BuildException on error | |||||
| */ | |||||
| public void setRefid(Reference r) throws BuildException { | |||||
| if (userNameSet || userIdSet || groupNameSet || groupIdSet) { | |||||
| throw tooManyAttributes(); | |||||
| } | |||||
| super.setRefid(r); | |||||
| } | |||||
| /** | /** | ||||
| * A TarFileset accepts another TarFileSet or a FileSet as reference | * A TarFileset accepts another TarFileSet or a FileSet as reference | ||||
| * FileSets are often used by the war task for the lib attribute | * FileSets are often used by the war task for the lib attribute | ||||
| @@ -83,6 +218,23 @@ public class TarFileSet extends ArchiveFileSet { | |||||
| } | } | ||||
| } | } | ||||
| /** | |||||
| * 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 void configureFileSet(ArchiveFileSet zfs) { | |||||
| super.configureFileSet(zfs); | |||||
| if (zfs instanceof TarFileSet) { | |||||
| TarFileSet tfs = (TarFileSet) zfs; | |||||
| tfs.setUserName(userName); | |||||
| tfs.setGroup(groupName); | |||||
| tfs.setUid(uid); | |||||
| tfs.setGid(gid); | |||||
| } | |||||
| } | |||||
| /** | /** | ||||
| * Return a TarFileSet that has the same properties | * Return a TarFileSet that has the same properties | ||||
| * as this one. | * as this one. | ||||
| @@ -33,6 +33,8 @@ public abstract class ArchiveResource extends Resource { | |||||
| private Resource archive; | private Resource archive; | ||||
| private boolean haveEntry = false; | private boolean haveEntry = false; | ||||
| private boolean modeSet = false; | |||||
| private int mode = 0; | |||||
| /** | /** | ||||
| * Default constructor. | * Default constructor. | ||||
| @@ -80,6 +82,16 @@ public abstract class ArchiveResource extends Resource { | |||||
| archive = new FileResource(a); | archive = new FileResource(a); | ||||
| } | } | ||||
| /** | |||||
| * Sets the file or dir mode for this resource. | |||||
| * @param integer representation of Unix permission mask. | |||||
| */ | |||||
| public void setMode(int mode) { | |||||
| checkAttributesAllowed(); | |||||
| this.mode = mode; | |||||
| modeSet = true; | |||||
| } | |||||
| /** | /** | ||||
| * Sets the archive that holds this as a single element Resource | * Sets the archive that holds this as a single element Resource | ||||
| * collection. | * collection. | ||||
| @@ -155,12 +167,24 @@ public abstract class ArchiveResource extends Resource { | |||||
| return super.isExists(); | return super.isExists(); | ||||
| } | } | ||||
| /** | |||||
| * Get the file or dir mode for this Resource. | |||||
| * @return integer representation of Unix permission mask. | |||||
| */ | |||||
| public int getMode() { | |||||
| if (isReference()) { | |||||
| return ((ArchiveResource) getCheckedRef()).getMode(); | |||||
| } | |||||
| checkEntry(); | |||||
| return mode; | |||||
| } | |||||
| /** | /** | ||||
| * Overrides the super version. | * Overrides the super version. | ||||
| * @param r the Reference to set. | * @param r the Reference to set. | ||||
| */ | */ | ||||
| public void setRefid(Reference r) { | public void setRefid(Reference r) { | ||||
| if (archive != null) { | |||||
| if (archive != null || modeSet) { | |||||
| throw tooManyAttributes(); | throw tooManyAttributes(); | ||||
| } | } | ||||
| super.setRefid(r); | super.setRefid(r); | ||||
| @@ -36,6 +36,11 @@ import org.apache.tools.tar.TarInputStream; | |||||
| */ | */ | ||||
| public class TarResource extends ArchiveResource { | public class TarResource extends ArchiveResource { | ||||
| private String userName = ""; | |||||
| private String groupName = ""; | |||||
| private int uid; | |||||
| private int gid; | |||||
| /** | /** | ||||
| * Default constructor. | * Default constructor. | ||||
| */ | */ | ||||
| @@ -104,6 +109,46 @@ public class TarResource extends ArchiveResource { | |||||
| "Use the tar task for tar output."); | "Use the tar task for tar output."); | ||||
| } | } | ||||
| /** | |||||
| * @return the user name for the tar entry | |||||
| */ | |||||
| public String getUserName() { | |||||
| if (isReference()) { | |||||
| return ((TarResource) getCheckedRef()).getUserName(); | |||||
| } | |||||
| return userName; | |||||
| } | |||||
| /** | |||||
| * @return the group name for the tar entry | |||||
| */ | |||||
| public String getGroup() { | |||||
| if (isReference()) { | |||||
| return ((TarResource) getCheckedRef()).getGroup(); | |||||
| } | |||||
| return groupName; | |||||
| } | |||||
| /** | |||||
| * @return the uid for the tar entry | |||||
| */ | |||||
| public int getUid() { | |||||
| if (isReference()) { | |||||
| return ((TarResource) getCheckedRef()).getUid(); | |||||
| } | |||||
| return uid; | |||||
| } | |||||
| /** | |||||
| * @return the uid for the tar entry | |||||
| */ | |||||
| public int getGid() { | |||||
| if (isReference()) { | |||||
| return ((TarResource) getCheckedRef()).getGid(); | |||||
| } | |||||
| return uid; | |||||
| } | |||||
| /** | /** | ||||
| * fetches information from the named entry inside the archive. | * fetches information from the named entry inside the archive. | ||||
| */ | */ | ||||
| @@ -132,14 +177,19 @@ public class TarResource extends ArchiveResource { | |||||
| private void setEntry(TarEntry e) { | private void setEntry(TarEntry e) { | ||||
| if (e == null) { | if (e == null) { | ||||
| super.setExists(false); | |||||
| setExists(false); | |||||
| return; | return; | ||||
| } | } | ||||
| super.setName(e.getName()); | |||||
| super.setExists(true); | |||||
| super.setLastModified(e.getModTime().getTime()); | |||||
| super.setDirectory(e.isDirectory()); | |||||
| super.setSize(e.getSize()); | |||||
| setName(e.getName()); | |||||
| setExists(true); | |||||
| setLastModified(e.getModTime().getTime()); | |||||
| setDirectory(e.isDirectory()); | |||||
| setSize(e.getSize()); | |||||
| setMode(e.getMode()); | |||||
| userName = e.getUserName(); | |||||
| groupName = e.getGroupName(); | |||||
| uid = e.getUserId(); | |||||
| gid = e.getGroupId(); | |||||
| } | } | ||||
| } | } | ||||
| @@ -127,7 +127,13 @@ public class ZipResource extends ArchiveResource { | |||||
| return ((Resource) getCheckedRef()).getInputStream(); | return ((Resource) getCheckedRef()).getInputStream(); | ||||
| } | } | ||||
| final ZipFile z = new ZipFile(getZipfile(), getEncoding()); | final ZipFile z = new ZipFile(getZipfile(), getEncoding()); | ||||
| return new FilterInputStream(z.getInputStream(z.getEntry(getName()))) { | |||||
| ZipEntry ze = z.getEntry(getName()); | |||||
| if (ze == null) { | |||||
| z.close(); | |||||
| throw new BuildException("no entry " + getName() + " in " | |||||
| + getArchive()); | |||||
| } | |||||
| return new FilterInputStream(z.getInputStream(ze)) { | |||||
| public void close() throws IOException { | public void close() throws IOException { | ||||
| FileUtils.close(in); | FileUtils.close(in); | ||||
| z.close(); | z.close(); | ||||
| @@ -182,14 +188,15 @@ public class ZipResource extends ArchiveResource { | |||||
| private void setEntry(ZipEntry e) { | private void setEntry(ZipEntry e) { | ||||
| if (e == null) { | if (e == null) { | ||||
| super.setExists(false); | |||||
| setExists(false); | |||||
| return; | return; | ||||
| } | } | ||||
| super.setName(e.getName()); | |||||
| super.setExists(true); | |||||
| super.setLastModified(e.getTime()); | |||||
| super.setDirectory(e.isDirectory()); | |||||
| super.setSize(e.getSize()); | |||||
| setName(e.getName()); | |||||
| setExists(true); | |||||
| setLastModified(e.getTime()); | |||||
| setDirectory(e.isDirectory()); | |||||
| setSize(e.getSize()); | |||||
| setMode(e.getUnixMode()); | |||||
| } | } | ||||
| } | } | ||||
| @@ -1,5 +1,5 @@ | |||||
| /* | /* | ||||
| * Copyright 2000-2002,2004 The Apache Software Foundation | |||||
| * Copyright 2000-2002,2004-2005 The Apache Software Foundation | |||||
| * | * | ||||
| * Licensed under the Apache License, Version 2.0 (the "License"); | * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
| * you may not use this file except in compliance with the License. | * you may not use this file except in compliance with the License. | ||||
| @@ -17,8 +17,10 @@ | |||||
| package org.apache.tools.ant.taskdefs; | package org.apache.tools.ant.taskdefs; | ||||
| import java.io.IOException; | |||||
| import java.io.File; | import java.io.File; | ||||
| import org.apache.tools.ant.BuildFileTest; | import org.apache.tools.ant.BuildFileTest; | ||||
| import org.apache.tools.ant.util.FileUtils; | |||||
| /** | /** | ||||
| */ | */ | ||||
| @@ -63,7 +65,19 @@ public class TarTest extends BuildFileTest { | |||||
| } | } | ||||
| public void test7() { | public void test7() { | ||||
| executeTarget("test7"); | |||||
| test7("test7"); | |||||
| } | |||||
| public void test7UsingPlainFileSet() { | |||||
| test7("test7UsingPlainFileSet"); | |||||
| } | |||||
| public void test7UsingFileList() { | |||||
| test7("test7UsingFileList"); | |||||
| } | |||||
| private void test7(String target) { | |||||
| executeTarget(target); | |||||
| File f1 | File f1 | ||||
| = new File(System.getProperty("root"), "src/etc/testcases/taskdefs/test7-prefix"); | = new File(System.getProperty("root"), "src/etc/testcases/taskdefs/test7-prefix"); | ||||
| @@ -80,7 +94,27 @@ public class TarTest extends BuildFileTest { | |||||
| } | } | ||||
| public void test8() { | public void test8() { | ||||
| executeTarget("test8"); | |||||
| test8("test8"); | |||||
| } | |||||
| public void test8UsingZipFileset() { | |||||
| test8("test8UsingZipFileset"); | |||||
| } | |||||
| public void test8UsingZipFilesetSrc() { | |||||
| test8("test8UsingZipFilesetSrc"); | |||||
| } | |||||
| public void test8UsingTarFilesetSrc() { | |||||
| test8("test8UsingTarFilesetSrc"); | |||||
| } | |||||
| public void test8UsingZipEntry() { | |||||
| test8("test8UsingZipEntry"); | |||||
| } | |||||
| private void test8(String target) { | |||||
| executeTarget(target); | |||||
| File f1 | File f1 | ||||
| = new File(System.getProperty("root"), "src/etc/testcases/taskdefs/test8.xml"); | = new File(System.getProperty("root"), "src/etc/testcases/taskdefs/test8.xml"); | ||||
| if (! f1.exists()) { | if (! f1.exists()) { | ||||
| @@ -110,6 +144,12 @@ public class TarTest extends BuildFileTest { | |||||
| } | } | ||||
| } | } | ||||
| public void testGZipResource() throws IOException { | |||||
| executeTarget("testGZipResource"); | |||||
| assertTrue(FileUtils.getFileUtils() | |||||
| .contentEquals(getProject().resolveFile("../asf-logo.gif"), | |||||
| getProject().resolveFile("testout/asf-logo.gif.gz"))); | |||||
| } | |||||
| public void tearDown() { | public void tearDown() { | ||||
| executeTarget("cleanup"); | executeTarget("cleanup"); | ||||