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 <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. <I>from</I> the archive. If no patternset is used, all files are extracted.
</p> </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. to perform unarchival upon.
</p> </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>File permissions will not be restored on extracted files.</p>
<p>The untar task recognizes the long pathname entries used by GNU tar.<p> <p>The untar task recognizes the long pathname entries used by GNU tar.<p>
<h3>Parameters</h3> <h3>Parameters</h3>
@@ -102,6 +105,16 @@ to perform unarchival upon.
&lt;/unzip&gt; &lt;/unzip&gt;
</pre></p> </pre></p>
</blockquote> </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> <hr>
<p align="center">Copyright &copy; 2000-2004 The Apache Software Foundation. All rights <p align="center">Copyright &copy; 2000-2004 The Apache Software Foundation. All rights
Reserved.</p> Reserved.</p>


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

@@ -93,4 +93,33 @@
<unzip src="unziptest.zip" dest="unziptestout" encoding="UnicodeBig"/> <unzip src="unziptest.zip" dest="unziptestout" encoding="UnicodeBig"/>
</target> </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> </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.Project;
import org.apache.tools.ant.Task; import org.apache.tools.ant.Task;
import org.apache.tools.ant.types.FileSet; 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.PatternSet;
import org.apache.tools.ant.types.selectors.SelectorUtils; 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.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.ZipEntry;
import org.apache.tools.zip.ZipFile; import org.apache.tools.zip.ZipFile;


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


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


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


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


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


log("expand complete", Project.MSG_VERBOSE); log("expand complete", Project.MSG_VERBOSE);
@@ -127,20 +138,40 @@ public class Expand extends Task {
throw new BuildException("Error while expanding " + srcF.getPath(), throw new BuildException("Error while expanding " + srcF.getPath(),
ioe); ioe);
} finally { } 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, protected void extractFile(FileUtils fileUtils, File srcF, File dir,
InputStream compressedInputStream, InputStream compressedInputStream,
String entryName,
Date entryDate, boolean isDirectory)
String entryName, Date entryDate,
boolean isDirectory, FileNameMapper mapper)
throws IOException { throws IOException {


if (patternsets != null && patternsets.size() > 0) { if (patternsets != null && patternsets.size() > 0) {
@@ -194,7 +225,11 @@ public class Expand extends Task {
return; 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 { try {
if (!overwrite && f.exists() if (!overwrite && f.exists()
&& f.lastModified() >= entryDate.getTime()) { && f.lastModified() >= entryDate.getTime()) {
@@ -286,6 +321,21 @@ public class Expand extends Task {
filesets.addElement(set); 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. * 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.BuildException;
import org.apache.tools.ant.Project; import org.apache.tools.ant.Project;
import org.apache.tools.ant.types.EnumeratedAttribute; 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.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.bzip2.CBZip2InputStream;
import org.apache.tools.tar.TarEntry; import org.apache.tools.tar.TarEntry;
import org.apache.tools.tar.TarInputStream; import org.apache.tools.tar.TarInputStream;
@@ -92,10 +95,11 @@ public class Untar extends Expand {
new BufferedInputStream( new BufferedInputStream(
new FileInputStream(srcF)))); new FileInputStream(srcF))));
TarEntry te = null; TarEntry te = null;
FileNameMapper mapper = getMapper();
while ((te = tis.getNextEntry()) != null) { while ((te = tis.getNextEntry()) != null) {
extractFile(fileUtils, srcF, dir, tis, extractFile(fileUtils, srcF, dir, tis,
te.getName(), te.getModTime(), te.isDirectory());
te.getName(), te.getModTime(),
te.isDirectory(), mapper);
} }
log("expand complete", Project.MSG_VERBOSE); log("expand complete", Project.MSG_VERBOSE);


@@ -103,13 +107,7 @@ public class Untar extends Expand {
throw new BuildException("Error while expanding " + srcF.getPath(), throw new BuildException("Error while expanding " + srcF.getPath(),
ioe, getLocation()); ioe, getLocation());
} finally { } 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(); 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. * Returns all entries.
* @return all entries as {@link ZipEntry} instances * @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.BuildFileTest;
import org.apache.tools.ant.util.FileUtils; import org.apache.tools.ant.util.FileUtils;


import java.io.IOException;

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




public void testRealTest() throws java.io.IOException { public void testRealTest() throws java.io.IOException {
FileUtils fileUtils = FileUtils.newFileUtils();
executeTarget("realTest"); 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"), assertTrue(fileUtils.contentEquals(project.resolveFile("../asf-logo.gif"),
project.resolveFile("asf-logo.gif"))); project.resolveFile("asf-logo.gif")));
} }


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


public void testTestUncompressedZipTask() throws java.io.IOException { public void testTestUncompressedZipTask() throws java.io.IOException {
FileUtils fileUtils = FileUtils.newFileUtils();
executeTarget("testUncompressedZipTask"); 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() { public void testPatternSetExcludeOnly() {
executeTarget("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() { public void testPatternSetIncludeOnly() {
executeTarget("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() { public void testPatternSetIncludeAndExclude() {
executeTarget("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() { public void testPatternSetSlashOnly() {
executeTarget("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 * PR 10504
*/ */
public void testEncoding() { public void testEncoding() {
executeTarget("encodingTest"); 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