Browse Source

add resource collection support to tar

git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@326643 13f79535-47bb-0310-9956-ffa450edef68
master
Stefan Bodewig 19 years ago
parent
commit
b5fcf10604
15 changed files with 980 additions and 283 deletions
  1. +7
    -0
      build.xml
  2. +27
    -57
      docs/manual/CoreTasks/tar.html
  3. +1
    -1
      docs/manual/CoreTypes/resources.html
  4. +146
    -0
      docs/manual/CoreTypes/tarfileset.html
  5. +14
    -34
      docs/manual/CoreTypes/zipfileset.html
  6. +1
    -1
      docs/manual/conceptstypeslist.html
  7. +75
    -0
      src/etc/testcases/taskdefs/tar.xml
  8. +1
    -1
      src/main/org/apache/tools/ant/taskdefs/Copy.java
  9. +386
    -165
      src/main/org/apache/tools/ant/taskdefs/Tar.java
  10. +30
    -5
      src/main/org/apache/tools/ant/types/ArchiveFileSet.java
  11. +154
    -2
      src/main/org/apache/tools/ant/types/TarFileSet.java
  12. +25
    -1
      src/main/org/apache/tools/ant/types/resources/ArchiveResource.java
  13. +56
    -6
      src/main/org/apache/tools/ant/types/resources/TarResource.java
  14. +14
    -7
      src/main/org/apache/tools/ant/types/resources/ZipResource.java
  15. +43
    -3
      src/testcases/org/apache/tools/ant/taskdefs/TarTest.java

+ 7
- 0
build.xml View File

@@ -1231,6 +1231,10 @@
</zip>
<tar longfile="gnu"
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">
<include name="${dist.name}/bin/ant"/>
<include name="${dist.name}/bin/antRun"/>
@@ -1296,6 +1300,9 @@
</zip>
<tar longfile="gnu"
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">
<include name="${dist.name}/bootstrap.sh"/>
<include name="${dist.name}/build.sh"/>


+ 27
- 57
docs/manual/CoreTasks/tar.html View File

@@ -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
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
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>
@@ -110,8 +111,11 @@ or "bzip2".</p>
</table>

<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

<table border="1" cellpadding="2" cellspacing="0">
@@ -120,59 +124,6 @@ attributes
<td valign="top"><b>Description</b></td>
<td valign="top" align="center"><b>Required</b></td>
</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>
<td valign="top">preserveLeadingSlashes</td>
<td valign="top">Indicates whether leading `/'s should
@@ -181,6 +132,13 @@ attributes
</tr>
</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>&lt;fileset&gt;</code> has been
supported as a nested element.</p>

<h3>Examples</h3>
<pre>
&lt;tar tarfile=&quot;${dist}/manual.tar&quot; basedir=&quot;htdocs/manual&quot;/&gt;
@@ -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
the executable files and include all others. </p>



<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>

<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
to <code>${dist.name}/..</code>.</p>

<pre>
&lt;tar dest="release.tar.gz" compress="gzip"&gt;
&lt;zipfileset src="release.zip"/&gt;
&lt;/tar&gt;
</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>
<p align="center">Copyright &copy; 2000-2002,2004-2005 The Apache Software Foundation. All rights
Reserved.</p>


+ 1
- 1
docs/manual/CoreTypes/resources.html View File

@@ -23,7 +23,7 @@ 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="#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="#gzipresource">gzipresource</a> - a GZip compressed resource.</li>
<li><a href="#bzip2resource">bzip2resource</a> - a BZip2 compressed resource.</li>


+ 146
- 0
docs/manual/CoreTypes/tarfileset.html View File

@@ -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>&lt;tarfileset&gt;</code> is a special form of a <code>&lt;<a
href="fileset.html">fileset</a>&gt;</code> which can behave in 2
different ways : <br>
</p>
<ul>
<li>When the <span style="font-style: italic;">src</span> attribute
is used - 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>&lt;tarfileset&gt;</code> supports all attributes of <code>&lt;<a
href="fileset.html">fileset</a>&gt;</code>
in addition to those listed below.<br>
</p>
<p>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>
&lt;copy todir="some-dir"&gt;
&lt;tarfileset includes="lib/**"&gt;
&lt;bzip2resource&gt;
&lt;url url="http://example.org/dist/some-archive.tar.bz2"/&gt;
&lt;/bzip2resource&gt;
&lt;/tarfileset&gt;
&lt;/copy&gt;
</pre></blockquote>

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

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

+ 14
- 34
docs/manual/CoreTypes/zipfileset.html View File

@@ -6,35 +6,31 @@
<title>ZipFileSet Type</title>
</head>
<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>&lt;zipfileset&gt;</code> and <code>&lt;tarfileset&gt;</code> are special forms of a <code>&lt;<a
<p>A <code>&lt;zipfileset&gt;</code> is a special form of a <code>&lt;<a
href="fileset.html">fileset</a>&gt;</code> which can behave in 2
different ways : <br>
</p>
<ul>
<li>When the <span style="font-style: italic;">src</span> attribute
is used - 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>
</li>
<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>
</li>
</ul>
<p><code>&lt;tar/zipfileset&gt;</code> supports all attributes of <code>&lt;<a
<p><code>&lt;zipfileset&gt;</code> supports all attributes of <code>&lt;<a
href="fileset.html">fileset</a>&gt;</code>
in addition to those listed below.<br>
</p>
<p>Since Ant 1.6, a zipfileset can be defined with the <span
style="font-style: italic;">id </span>attribute and referred to with
the <span style="font-style: italic;">refid</span> attribute. 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>
<h3>Parameters</h3>
<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
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>

<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>
<blockquote>
@@ -117,24 +115,6 @@ docs/ChangeLog.txt<br>
docs/examples/index.html<br>
</code></blockquote>

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

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


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


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

@@ -34,7 +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/tarfileset.html">TarFileSet</a><br>
<a href="CoreTypes/xmlcatalog.html">XMLCatalog</a><br>
<a href="CoreTypes/zipfileset.html">ZipFileSet</a><br>



+ 75
- 0
src/etc/testcases/taskdefs/tar.xml View File

@@ -44,6 +44,32 @@
<untar src="test7.tar" dest="."/>
</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">
<tar destfile="test8.tar">
<tarfileset dir="." fullpath="/test8.xml">
@@ -53,6 +79,45 @@
<untar src="test8.tar" dest="."/>
</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">
<tar destfile="blah" compression="Foo"/>
</target>
@@ -79,6 +144,7 @@
<delete file="test4.tar"/>
<delete file="test5.tar"/>
<delete file="asf-logo.gif.tar"/>
<delete dir="testout"/>
<delete dir="test5dir"/>
<delete dir="test7dir"/>
<delete dir="test7-prefix"/>
@@ -107,5 +173,14 @@
compression="bzip2" />
</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>

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

@@ -64,7 +64,7 @@ import org.apache.tools.ant.util.FlatFileNameMapper;
* @ant.task category="filesystem"
*/
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 destFile = null; // the destination file


+ 386
- 165
src/main/org/apache/tools/ant/taskdefs/Tar.java View File

@@ -19,18 +19,29 @@ package org.apache.tools.ant.taskdefs;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Vector;
import java.util.zip.GZIPOutputStream;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.DirectoryScanner;
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.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.SourceFileScanner;
import org.apache.tools.bzip2.CBZip2OutputStream;
@@ -79,7 +90,12 @@ public class Tar extends MatchingTask {

private TarLongFileMode longFileMode = new TarLongFileMode();

// need to keep the package private version for backwards compatibility
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();

/**
@@ -95,10 +111,19 @@ public class Tar extends MatchingTask {
*/
public TarFileSet createTarFileSet() {
TarFileSet fs = new TarFileSet();
fs.setProject(getProject());
filesets.addElement(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.
@@ -217,9 +242,10 @@ public class Tar extends MatchingTask {
filesets.addElement(mainFileSet);
}

if (filesets.size() == 0) {
if (filesets.size() == 0 && resourceCollections.size() == 0) {
throw new BuildException("You must supply either a basedir "
+ "attribute or some nested filesets.",
+ "attribute or some nested resource"
+ " collections.",
getLocation());
}

@@ -227,20 +253,11 @@ public class Tar extends MatchingTask {
// fileset
boolean upToDate = true;
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) {
@@ -271,19 +288,11 @@ public class Tar extends MatchingTask {
longWarningGiven = false;
for (Enumeration e = filesets.elements();
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) {
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,
TarFileSet tarFileSet)
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);
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
+ "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());
} 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);

if (!file.isDirectory()) {
fIn = new FileInputStream(file);
if (!r.isDirectory()) {
in = r.getInputStream();

byte[] buffer = new byte[8 * 1024];
int count = 0;
do {
tOut.write(buffer, 0, count);
count = fIn.read(buffer, 0, buffer.length);
count = in.read(buffer, 0, buffer.length);
} while (count != -1);
}

tOut.closeEntry();
} 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;
}

/**
* 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
* &lt;tar&gt;. 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
* and other attributes.
@@ -438,10 +733,6 @@ public class Tar extends MatchingTask {
extends org.apache.tools.ant.types.TarFileSet {
private String[] files = null;

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

/**
@@ -470,13 +761,7 @@ public class Tar extends MatchingTask {
*/
public String[] getFiles(Project p) {
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;
@@ -499,70 +784,6 @@ public class Tar extends MatchingTask {
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
* be preserved in the file names.


+ 30
- 5
src/main/org/apache/tools/ant/types/ArchiveFileSet.java View File

@@ -310,9 +310,22 @@ public abstract class ArchiveFileSet extends FileSet {
* @param octalString a <code>String</code> value
*/
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;
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
*/
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;
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
* @return the abstract fileset instance
*/
protected final void configureFileSet(ArchiveFileSet zfs) {
protected void configureFileSet(ArchiveFileSet zfs) {
zfs.setPrefix(prefix);
zfs.setFullpath(fullpath);
zfs.fileModeHasBeenSet = fileModeHasBeenSet;


+ 154
- 2
src/main/org/apache/tools/ant/types/TarFileSet.java View File

@@ -31,11 +31,19 @@ import org.apache.tools.zip.UnixStat;
* 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 {

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 */
public TarFileSet() {
super();
@@ -57,11 +65,138 @@ public class TarFileSet extends ArchiveFileSet {
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() {
TarScanner zs = new TarScanner();
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
* 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
* as this one.


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

@@ -33,6 +33,8 @@ public abstract class ArchiveResource extends Resource {

private Resource archive;
private boolean haveEntry = false;
private boolean modeSet = false;
private int mode = 0;

/**
* Default constructor.
@@ -80,6 +82,16 @@ public abstract class ArchiveResource extends Resource {
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
* collection.
@@ -155,12 +167,24 @@ public abstract class ArchiveResource extends Resource {
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.
* @param r the Reference to set.
*/
public void setRefid(Reference r) {
if (archive != null) {
if (archive != null || modeSet) {
throw tooManyAttributes();
}
super.setRefid(r);


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

@@ -36,6 +36,11 @@ import org.apache.tools.tar.TarInputStream;
*/
public class TarResource extends ArchiveResource {

private String userName = "";
private String groupName = "";
private int uid;
private int gid;

/**
* Default constructor.
*/
@@ -104,6 +109,46 @@ public class TarResource extends ArchiveResource {
"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.
*/
@@ -132,14 +177,19 @@ public class TarResource extends ArchiveResource {

private void setEntry(TarEntry e) {
if (e == null) {
super.setExists(false);
setExists(false);
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();
}

}

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

@@ -127,7 +127,13 @@ public class ZipResource extends ArchiveResource {
return ((Resource) getCheckedRef()).getInputStream();
}
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 {
FileUtils.close(in);
z.close();
@@ -182,14 +188,15 @@ public class ZipResource extends ArchiveResource {

private void setEntry(ZipEntry e) {
if (e == null) {
super.setExists(false);
setExists(false);
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());
}

}

+ 43
- 3
src/testcases/org/apache/tools/ant/taskdefs/TarTest.java View File

@@ -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");
* you may not use this file except in compliance with the License.
@@ -17,8 +17,10 @@

package org.apache.tools.ant.taskdefs;

import java.io.IOException;
import java.io.File;
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() {
executeTarget("test7");
test7("test7");
}

public void test7UsingPlainFileSet() {
test7("test7UsingPlainFileSet");
}

public void test7UsingFileList() {
test7("test7UsingFileList");
}

private void test7(String target) {
executeTarget(target);
File f1
= new File(System.getProperty("root"), "src/etc/testcases/taskdefs/test7-prefix");

@@ -80,7 +94,27 @@ public class TarTest extends BuildFileTest {
}

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
= new File(System.getProperty("root"), "src/etc/testcases/taskdefs/test8.xml");
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() {
executeTarget("cleanup");


Loading…
Cancel
Save