Browse Source

Patch in PR# 21996

add a flatten to unzip.
I actually only patched in the mapper nested element support; with that the flatten attribute can only introduce inconsistency (what if you spec a mapper and flatten=true).
And the patch was modified to keep the attributes private, with a getMapper() operation for subclasses (like untar) to get when needed.
Did a bit of cleanup -especially of the unzip tests- while at it.


git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@276981 13f79535-47bb-0310-9956-ffa450edef68
master
Steve Loughran 20 years ago
parent
commit
fdc903238f
6 changed files with 193 additions and 47 deletions
  1. +14
    -1
      docs/manual/CoreTasks/unzip.html
  2. +29
    -0
      src/etc/testcases/taskdefs/unzip.xml
  3. +62
    -12
      src/main/org/apache/tools/ant/taskdefs/Expand.java
  4. +7
    -9
      src/main/org/apache/tools/ant/taskdefs/Untar.java
  5. +15
    -0
      src/main/org/apache/tools/zip/ZipFile.java
  6. +66
    -25
      src/testcases/org/apache/tools/ant/taskdefs/UnzipTest.java

+ 14
- 1
docs/manual/CoreTasks/unzip.html View File

@@ -15,9 +15,12 @@ carried from the archive file.</p>
<p><a href="../CoreTypes/patternset.html">PatternSet</a>s are used to select files to extract
<I>from</I> the archive. If no patternset is used, all files are extracted.
</p>
<p><a href="../CoreTypes/fileset.html">FileSet</a>s may be used used to select archived files
<p><a href="../CoreTypes/fileset.html">FileSet</a>s may be used to select archived files
to perform unarchival upon.
</p>
<p>You can define filename transformations by using a nested <a href="../CoreTypes/mapper.html">mapper</a> element. The default mapper is the
<a href="../CoreTypes/mapper.html#identity-mapper">identity mapper</a>.
</p>
<p>File permissions will not be restored on extracted files.</p>
<p>The untar task recognizes the long pathname entries used by GNU tar.<p>
<h3>Parameters</h3>
@@ -102,6 +105,16 @@ to perform unarchival upon.
&lt;/unzip&gt;
</pre></p>
</blockquote>
<blockquote>
<p><pre>
&lt;unzip src=&quot;apache-ant-bin.zip&quot; dest=&quot;${tools.home}&quot;&gt;
&lt;patternset&gt;
&lt;include name=&quot;apache-ant/lib/ant.jar&quot;/&gt;
&lt;/patternset&gt;
&lt;mapper type=&quot;flatten&quot;/&gt;
&lt;/unzip&gt;
</pre></p>
</blockquote>
<hr>
<p align="center">Copyright &copy; 2000-2004 The Apache Software Foundation. All rights
Reserved.</p>


+ 29
- 0
src/etc/testcases/taskdefs/unzip.xml View File

@@ -93,4 +93,33 @@
<unzip src="unziptest.zip" dest="unziptestout" encoding="UnicodeBig"/>
</target>

<!-- Bugzilla Report 21996 -->
<target name="testFlattenMapper" depends="prepareTestZip">
<unzip dest="unziptestout" src="unziptest.zip">
<patternset>
<include name="1/**"/>
</patternset>
<mapper type="flatten"/>
</unzip>
</target>

<!-- Bugzilla Report 21996 -->
<target name="testGlobMapper" depends="prepareTestZip">
<unzip dest="unziptestout" src="unziptest.zip">
<patternset>
<include name="1/**"/>
</patternset>
<mapper type="glob" from="*" to="*.txt"/>
</unzip>
</target>

<target name="testTwoMappers" depends="prepareTestZip">
<unzip dest="unziptestout" src="unziptest.zip">
<patternset>
<include name="1/**"/>
</patternset>
<mapper type="glob" from="*" to="*.txt"/>
<mapper type="flatten"/>
</unzip>
</target>
</project>

+ 62
- 12
src/main/org/apache/tools/ant/taskdefs/Expand.java View File

@@ -30,9 +30,13 @@ import org.apache.tools.ant.DirectoryScanner;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.types.FileSet;
import org.apache.tools.ant.types.Mapper;
import org.apache.tools.ant.types.PatternSet;
import org.apache.tools.ant.types.selectors.SelectorUtils;
import org.apache.tools.ant.util.FileNameMapper;
import org.apache.tools.ant.util.FileUtils;
import org.apache.tools.ant.util.FlatFileNameMapper;
import org.apache.tools.ant.util.IdentityMapper;
import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipFile;

@@ -50,12 +54,14 @@ public class Expand extends Task {
private File dest; //req
private File source; // req
private boolean overwrite = true;
private Mapper mapperElement = null;
private Vector patternsets = new Vector();
private Vector filesets = new Vector();

private static final String NATIVE_ENCODING = "native-encoding";

private String encoding = "UTF8";
public static final String ERROR_MULTIPLE_MAPPERS = "Cannot define more than one mapper";

/**
* Do the work.
@@ -106,12 +112,17 @@ public class Expand extends Task {
}
}

/*
/**
* This method is to be overridden by extending unarchival tasks.
*
* @param fileUtils
* @param srcF
* @param dir
*/
protected void expandFile(FileUtils fileUtils, File srcF, File dir) {
log("Expanding: " + srcF + " into " + dir, Project.MSG_INFO);
ZipFile zf = null;
FileNameMapper mapper = getMapper();
try {
zf = new ZipFile(srcF, encoding);
Enumeration e = zf.getEntries();
@@ -119,7 +130,7 @@ public class Expand extends Task {
ZipEntry ze = (ZipEntry) e.nextElement();
extractFile(fileUtils, srcF, dir, zf.getInputStream(ze),
ze.getName(), new Date(ze.getTime()),
ze.isDirectory());
ze.isDirectory(), mapper);
}

log("expand complete", Project.MSG_VERBOSE);
@@ -127,20 +138,40 @@ public class Expand extends Task {
throw new BuildException("Error while expanding " + srcF.getPath(),
ioe);
} finally {
if (zf != null) {
try {
zf.close();
} catch (IOException e) {
//ignore
}
}
ZipFile.closeQuietly(zf);
}
}

/**
* get a mapper for a file
* @return
*/
protected FileNameMapper getMapper() {
FileNameMapper mapper = null;
if (mapperElement != null) {
mapper = mapperElement.getImplementation();
} else {
mapper = new IdentityMapper();
}
return mapper;
}

/**
* extract a file to a directory
* @param fileUtils
* @param srcF
* @param dir
* @param compressedInputStream
* @param entryName
* @param entryDate
* @param isDirectory
* @param mapper
* @throws IOException
*/
protected void extractFile(FileUtils fileUtils, File srcF, File dir,
InputStream compressedInputStream,
String entryName,
Date entryDate, boolean isDirectory)
String entryName, Date entryDate,
boolean isDirectory, FileNameMapper mapper)
throws IOException {

if (patternsets != null && patternsets.size() > 0) {
@@ -194,7 +225,11 @@ public class Expand extends Task {
return;
}
}
File f = fileUtils.resolveFile(dir, entryName);
String[] mappedNames = mapper.mapFileName(entryName);
if (mappedNames == null || mappedNames.length == 0) {
mappedNames = new String[] { entryName };
}
File f = fileUtils.resolveFile(dir, mappedNames[0]);
try {
if (!overwrite && f.exists()
&& f.lastModified() >= entryDate.getTime()) {
@@ -286,6 +321,21 @@ public class Expand extends Task {
filesets.addElement(set);
}

/**
* Defines the mapper to map source entries to destination files.
* @return a mapper to be configured
* @exception BuildException if more than one mapper is defined
* @since Ant1.7
*/
public Mapper createMapper() throws BuildException {
if (mapperElement != null) {
throw new BuildException(ERROR_MULTIPLE_MAPPERS,
getLocation());
}
mapperElement = new Mapper(getProject());
return mapperElement;
}

/**
* Sets the encoding to assume for file names and comments.
*


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

@@ -26,7 +26,10 @@ import java.util.zip.GZIPInputStream;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.types.EnumeratedAttribute;
import org.apache.tools.ant.util.FileNameMapper;
import org.apache.tools.ant.util.FileUtils;
import org.apache.tools.ant.util.FlatFileNameMapper;
import org.apache.tools.ant.util.IdentityMapper;
import org.apache.tools.bzip2.CBZip2InputStream;
import org.apache.tools.tar.TarEntry;
import org.apache.tools.tar.TarInputStream;
@@ -92,10 +95,11 @@ public class Untar extends Expand {
new BufferedInputStream(
new FileInputStream(srcF))));
TarEntry te = null;
FileNameMapper mapper = getMapper();
while ((te = tis.getNextEntry()) != null) {
extractFile(fileUtils, srcF, dir, tis,
te.getName(), te.getModTime(), te.isDirectory());
te.getName(), te.getModTime(),
te.isDirectory(), mapper);
}
log("expand complete", Project.MSG_VERBOSE);

@@ -103,13 +107,7 @@ public class Untar extends Expand {
throw new BuildException("Error while expanding " + srcF.getPath(),
ioe, getLocation());
} finally {
if (tis != null) {
try {
tis.close();
} catch (IOException e) {
// ignore
}
}
FileUtils.close(tis);
}
}



+ 15
- 0
src/main/org/apache/tools/zip/ZipFile.java View File

@@ -160,6 +160,21 @@ public class ZipFile {
archive.close();
}

/**
* close a zipfile quietly; throw no io fault, do nothing
* on a null parameter
* @param zipfile file to close, can be null
*/
public static void closeQuietly(ZipFile zipfile) {
if (zipfile != null) {
try {
zipfile.close();
} catch (IOException e) {
//ignore
}
}
}

/**
* Returns all entries.
* @return all entries as {@link ZipEntry} instances


+ 66
- 25
src/testcases/org/apache/tools/ant/taskdefs/UnzipTest.java View File

@@ -19,6 +19,8 @@ package org.apache.tools.ant.taskdefs;
import org.apache.tools.ant.BuildFileTest;
import org.apache.tools.ant.util.FileUtils;

import java.io.IOException;

/**
*/
public class UnzipTest extends BuildFileTest {
@@ -49,24 +51,28 @@ public class UnzipTest extends BuildFileTest {


public void testRealTest() throws java.io.IOException {
FileUtils fileUtils = FileUtils.newFileUtils();
executeTarget("realTest");
assertLogoUncorrupted();
}

/**
* test that the logo gif file has not been corrupted
* @throws IOException
*/
private void assertLogoUncorrupted() throws IOException {
FileUtils fileUtils = FileUtils.newFileUtils();
assertTrue(fileUtils.contentEquals(project.resolveFile("../asf-logo.gif"),
project.resolveFile("asf-logo.gif")));
}

public void testTestZipTask() throws java.io.IOException {
FileUtils fileUtils = FileUtils.newFileUtils();
executeTarget("testZipTask");
assertTrue(fileUtils.contentEquals(project.resolveFile("../asf-logo.gif"),
project.resolveFile("asf-logo.gif")));
assertLogoUncorrupted();
}

public void testTestUncompressedZipTask() throws java.io.IOException {
FileUtils fileUtils = FileUtils.newFileUtils();
executeTarget("testUncompressedZipTask");
assertTrue(fileUtils.contentEquals(project.resolveFile("../asf-logo.gif"),
project.resolveFile("asf-logo.gif")));
assertLogoUncorrupted();
}

/*
@@ -74,10 +80,8 @@ public class UnzipTest extends BuildFileTest {
*/
public void testPatternSetExcludeOnly() {
executeTarget("testPatternSetExcludeOnly");
assertTrue("1/foo is excluded",
!getProject().resolveFile("unziptestout/1/foo").exists());
assertTrue("2/bar is not excluded",
getProject().resolveFile("unziptestout/2/bar").exists());
assertFileMissing("1/foo is excluded", "unziptestout/1/foo");
assertFileExists("2/bar is not excluded", "unziptestout/2/bar");
}

/*
@@ -85,10 +89,8 @@ public class UnzipTest extends BuildFileTest {
*/
public void testPatternSetIncludeOnly() {
executeTarget("testPatternSetIncludeOnly");
assertTrue("1/foo is not included",
!getProject().resolveFile("unziptestout/1/foo").exists());
assertTrue("2/bar is included",
getProject().resolveFile("unziptestout/2/bar").exists());
assertFileMissing("1/foo is not included", "unziptestout/1/foo");
assertFileExists("2/bar is included", "unziptestout/2/bar");
}

/*
@@ -96,10 +98,8 @@ public class UnzipTest extends BuildFileTest {
*/
public void testPatternSetIncludeAndExclude() {
executeTarget("testPatternSetIncludeAndExclude");
assertTrue("1/foo is not included",
!getProject().resolveFile("unziptestout/1/foo").exists());
assertTrue("2/bar is excluded",
!getProject().resolveFile("unziptestout/2/bar").exists());
assertFileMissing("1/foo is not included", "unziptestout/1/foo");
assertFileMissing("2/bar is excluded", "unziptestout/2/bar");
}

/*
@@ -115,19 +115,60 @@ public class UnzipTest extends BuildFileTest {
*/
public void testPatternSetSlashOnly() {
executeTarget("testPatternSetSlashOnly");
assertTrue("1/foo is not included",
!getProject().resolveFile("unziptestout/1/foo").exists());
assertTrue("2/bar is included",
getProject().resolveFile("unziptestout/2/bar").exists());
assertFileMissing("1/foo is not included", "unziptestout/1/foo");
assertFileExists("\"2/bar is included", "unziptestout/2/bar");
}


/*
* PR 10504
*/
public void testEncoding() {
executeTarget("encodingTest");
assertTrue("foo has been properly named",
getProject().resolveFile("unziptestout/foo").exists());
assertFileExists("foo has been properly named", "unziptestout/foo");
}

/*
* PR 21996
*/
public void testFlattenMapper() {
executeTarget("testFlattenMapper");
assertFileMissing("1/foo is not flattened", "unziptestout/1/foo");
assertFileExists("foo is flattened", "unziptestout/foo");
}

/**
* assert that a file exists, relative to the project
* @param message message if there is no mpatch
* @param filename filename to resolve against the project
*/
private void assertFileExists(String message, String filename) {
assertTrue(message,
getProject().resolveFile(filename).exists());
}

/**
* assert that a file doesnt exist, relative to the project
*
* @param message message if there is no mpatch
* @param filename filename to resolve against the project
*/
private void assertFileMissing(String message, String filename) {
assertTrue(message,
!getProject().resolveFile(filename).exists());
}

/**
* PR 21996
*/
public void testGlobMapper() {
executeTarget("testGlobMapper");
assertFileMissing("1/foo is not mapped", "unziptestout/1/foo");
assertFileExists("1/foo is mapped", "unziptestout/1/foo.txt");
}

public void testTwoMappers() {
expectBuildException("testTwoMappers",Expand.ERROR_MULTIPLE_MAPPERS);
}

}

Loading…
Cancel
Save