PR: 10755 git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@273986 13f79535-47bb-0310-9956-ffa450edef68master
@@ -25,6 +25,12 @@ Changes that could break older environments: | |||||
* XML namespaces are now enabled in the XML parser, meaning XML namespace | * XML namespaces are now enabled in the XML parser, meaning XML namespace | ||||
declarations no longer cause errors. | declarations no longer cause errors. | ||||
* The <zip> task and friends have been heavily modified, almost every | |||||
method signature of the Zip class has changed. If you have subclassed | |||||
Zip (or one of its subclasses), your class will most likely not | |||||
compile against the current code base. If it still compiles, it will | |||||
probably not work as in Ant 1.5.1. | |||||
Fixed bugs: | Fixed bugs: | ||||
----------- | ----------- | ||||
* <translate> was not ignoring comment lines. | * <translate> was not ignoring comment lines. | ||||
@@ -32,11 +32,16 @@ The extended fileset and groupfileset attributes from the zip task are | |||||
also available in the jar task. | also available in the jar task. | ||||
See the <a href="zip.html">Zip</a> task for more details and examples.</p> | See the <a href="zip.html">Zip</a> task for more details and examples.</p> | ||||
<p>If the manifest is omitted, a simple one will be supplied by Ant.</p> | <p>If the manifest is omitted, a simple one will be supplied by Ant.</p> | ||||
<p>The <code>update</code> parameter controls what happens if the | |||||
JAR file already exists. When set to <code>yes</code>, the JAR file is | |||||
<p>The <code>update</code> parameter controls what happens if the JAR | |||||
file already exists. When set to <code>yes</code>, the JAR file is | |||||
updated with the files specified. When set to <code>no</code> (the | updated with the files specified. When set to <code>no</code> (the | ||||
default) the JAR file is overwritten. An example use of this is | default) the JAR file is overwritten. An example use of this is | ||||
provided in the <a href="zip.html">Zip task documentation</a>.</p> | |||||
provided in the <a href="zip.html">Zip task documentation</a>. Please | |||||
note that ZIP files store file modification times with a granularity | |||||
of two seconds. If a file is less than two seconds newer than the | |||||
entry in the archive, Ant will not consider it newer.</p> | |||||
<p>(The Jar task is a shortcut for specifying the manifest file of a JAR file. | <p>(The Jar task is a shortcut for specifying the manifest file of a JAR file. | ||||
The same thing can be accomplished by using the <i>fullpath</i> | The same thing can be accomplished by using the <i>fullpath</i> | ||||
attribute of a zipfileset in a Zip task. The one difference is that if the | attribute of a zipfileset in a Zip task. The one difference is that if the | ||||
@@ -19,11 +19,12 @@ | |||||
</target> | </target> | ||||
<!-- Test when the zip file includes itself | <!-- Test when the zip file includes itself | ||||
when target file does not exist before the zip task is run --> | |||||
when target file does not exist before the zip task is run | |||||
<target name="test4"> | <target name="test4"> | ||||
<zip destFile="test4.zip" | <zip destFile="test4.zip" | ||||
basedir="."/> | basedir="."/> | ||||
</target> | </target> | ||||
--> | |||||
<target name="test5"> | <target name="test5"> | ||||
<zip zipfile="test5.zip" basedir="." > | <zip zipfile="test5.zip" basedir="." > | ||||
@@ -203,11 +203,6 @@ public class DirectoryScanner implements ResourceScanner, SelectorScanner { | |||||
*/ | */ | ||||
protected Vector filesIncluded; | protected Vector filesIncluded; | ||||
/** | |||||
* the same as filesIncluded, but in terms of Resource | |||||
*/ | |||||
private Vector filesIncludedR; | |||||
/** The files which did not match any includes or selectors. */ | /** The files which did not match any includes or selectors. */ | ||||
protected Vector filesNotIncluded; | protected Vector filesNotIncluded; | ||||
@@ -221,10 +216,6 @@ public class DirectoryScanner implements ResourceScanner, SelectorScanner { | |||||
* and were selected. | * and were selected. | ||||
*/ | */ | ||||
protected Vector dirsIncluded; | protected Vector dirsIncluded; | ||||
/** The directories which matched at least one include and no excludes | |||||
* and were selected, as resources | |||||
*/ | |||||
private Vector dirsIncludedR; | |||||
/** The directories which were found and did not match any includes. */ | /** The directories which were found and did not match any includes. */ | ||||
protected Vector dirsNotIncluded; | protected Vector dirsNotIncluded; | ||||
@@ -556,12 +547,10 @@ public class DirectoryScanner implements ResourceScanner, SelectorScanner { | |||||
} | } | ||||
filesIncluded = new Vector(); | filesIncluded = new Vector(); | ||||
filesIncludedR = new Vector(); | |||||
filesNotIncluded = new Vector(); | filesNotIncluded = new Vector(); | ||||
filesExcluded = new Vector(); | filesExcluded = new Vector(); | ||||
filesDeselected = new Vector(); | filesDeselected = new Vector(); | ||||
dirsIncluded = new Vector(); | dirsIncluded = new Vector(); | ||||
dirsIncludedR = new Vector(); | |||||
dirsNotIncluded = new Vector(); | dirsNotIncluded = new Vector(); | ||||
dirsExcluded = new Vector(); | dirsExcluded = new Vector(); | ||||
dirsDeselected = new Vector(); | dirsDeselected = new Vector(); | ||||
@@ -570,10 +559,6 @@ public class DirectoryScanner implements ResourceScanner, SelectorScanner { | |||||
if (!isExcluded("")) { | if (!isExcluded("")) { | ||||
if (isSelected("",basedir)) { | if (isSelected("",basedir)) { | ||||
dirsIncluded.addElement(""); | dirsIncluded.addElement(""); | ||||
dirsIncludedR.addElement(new Resource("", true, | |||||
basedir | |||||
.lastModified(), | |||||
true)); | |||||
} else { | } else { | ||||
dirsDeselected.addElement(""); | dirsDeselected.addElement(""); | ||||
} | } | ||||
@@ -692,11 +677,6 @@ public class DirectoryScanner implements ResourceScanner, SelectorScanner { | |||||
if (!isExcluded(name)) { | if (!isExcluded(name)) { | ||||
if (isSelected(name,file)) { | if (isSelected(name,file)) { | ||||
dirsIncluded.addElement(name); | dirsIncluded.addElement(name); | ||||
dirsIncludedR.addElement(new Resource(name, | |||||
true, | |||||
file | |||||
.lastModified(), | |||||
true)); | |||||
if (fast) { | if (fast) { | ||||
scandir(file, name + File.separator, fast); | scandir(file, name + File.separator, fast); | ||||
} | } | ||||
@@ -730,11 +710,6 @@ public class DirectoryScanner implements ResourceScanner, SelectorScanner { | |||||
if (!isExcluded(name)) { | if (!isExcluded(name)) { | ||||
if (isSelected(name,file)) { | if (isSelected(name,file)) { | ||||
filesIncluded.addElement(name); | filesIncluded.addElement(name); | ||||
filesIncludedR.addElement(new Resource(name, | |||||
true, | |||||
file | |||||
.lastModified(), | |||||
false)); | |||||
} else { | } else { | ||||
everythingIncluded = false; | everythingIncluded = false; | ||||
filesDeselected.addElement(name); | filesDeselected.addElement(name); | ||||
@@ -830,13 +805,11 @@ public class DirectoryScanner implements ResourceScanner, SelectorScanner { | |||||
* include patterns and none of the exclude patterns. | * include patterns and none of the exclude patterns. | ||||
*/ | */ | ||||
public String[] getIncludedFiles() { | public String[] getIncludedFiles() { | ||||
int count = filesIncluded.size(); | |||||
String[] files = new String[count]; | |||||
for (int i = 0; i < count; i++) { | |||||
files[i] = (String)filesIncluded.elementAt(i); | |||||
} | |||||
String[] files = new String[filesIncluded.size()]; | |||||
filesIncluded.copyInto(files); | |||||
return files; | return files; | ||||
} | } | ||||
/** | /** | ||||
* Returns the resources of the files which matched at least one | * Returns the resources of the files which matched at least one | ||||
* of the include patterns and none of the exclude patterns. The | * of the include patterns and none of the exclude patterns. The | ||||
@@ -849,11 +822,11 @@ public class DirectoryScanner implements ResourceScanner, SelectorScanner { | |||||
* @since Ant 1.5.2 | * @since Ant 1.5.2 | ||||
*/ | */ | ||||
public Resource[] getIncludedFileResources() { | public Resource[] getIncludedFileResources() { | ||||
int count = filesIncludedR.size(); | |||||
String[] names = getIncludedFiles(); | |||||
int count = names.length; | |||||
Resource[] resources = new Resource[count]; | Resource[] resources = new Resource[count]; | ||||
for (int i = 0; i < count; i++) { | for (int i = 0; i < count; i++) { | ||||
resources[i] = | |||||
(Resource) ((Resource) filesIncludedR.elementAt(i)).clone(); | |||||
resources[i] = getResource(names[i]); | |||||
} | } | ||||
return resources; | return resources; | ||||
} | } | ||||
@@ -870,11 +843,8 @@ public class DirectoryScanner implements ResourceScanner, SelectorScanner { | |||||
*/ | */ | ||||
public String[] getNotIncludedFiles() { | public String[] getNotIncludedFiles() { | ||||
slowScan(); | slowScan(); | ||||
int count = filesNotIncluded.size(); | |||||
String[] files = new String[count]; | |||||
for (int i = 0; i < count; i++) { | |||||
files[i] = (String)filesNotIncluded.elementAt(i); | |||||
} | |||||
String[] files = new String[filesNotIncluded.size()]; | |||||
filesNotIncluded.copyInto(files); | |||||
return files; | return files; | ||||
} | } | ||||
@@ -891,11 +861,8 @@ public class DirectoryScanner implements ResourceScanner, SelectorScanner { | |||||
*/ | */ | ||||
public String[] getExcludedFiles() { | public String[] getExcludedFiles() { | ||||
slowScan(); | slowScan(); | ||||
int count = filesExcluded.size(); | |||||
String[] files = new String[count]; | |||||
for (int i = 0; i < count; i++) { | |||||
files[i] = (String)filesExcluded.elementAt(i); | |||||
} | |||||
String[] files = new String[filesExcluded.size()]; | |||||
filesExcluded.copyInto(files); | |||||
return files; | return files; | ||||
} | } | ||||
@@ -912,11 +879,8 @@ public class DirectoryScanner implements ResourceScanner, SelectorScanner { | |||||
*/ | */ | ||||
public String[] getDeselectedFiles() { | public String[] getDeselectedFiles() { | ||||
slowScan(); | slowScan(); | ||||
int count = filesDeselected.size(); | |||||
String[] files = new String[count]; | |||||
for (int i = 0; i < count; i++) { | |||||
files[i] = (String)filesDeselected.elementAt(i); | |||||
} | |||||
String[] files = new String[filesDeselected.size()]; | |||||
filesDeselected.copyInto(files); | |||||
return files; | return files; | ||||
} | } | ||||
@@ -929,11 +893,8 @@ public class DirectoryScanner implements ResourceScanner, SelectorScanner { | |||||
* include patterns and none of the exclude patterns. | * include patterns and none of the exclude patterns. | ||||
*/ | */ | ||||
public String[] getIncludedDirectories() { | public String[] getIncludedDirectories() { | ||||
int count = dirsIncluded.size(); | |||||
String[] directories = new String[count]; | |||||
for (int i = 0; i < count; i++) { | |||||
directories[i] = (String)dirsIncluded.elementAt(i); | |||||
} | |||||
String[] directories = new String[dirsIncluded.size()]; | |||||
dirsIncluded.copyInto(directories); | |||||
return directories; | return directories; | ||||
} | } | ||||
@@ -947,15 +908,16 @@ public class DirectoryScanner implements ResourceScanner, SelectorScanner { | |||||
* | * | ||||
* @since Ant 1.5.2 | * @since Ant 1.5.2 | ||||
*/ | */ | ||||
public Resource[] getIncludedDirectoryResources() { | |||||
int count = dirsIncludedR.size(); | |||||
Resource[] directories = new Resource[count]; | |||||
for (int i = 0; i < count; i++) { | |||||
directories[i] = | |||||
(Resource) ((Resource) dirsIncludedR.elementAt(i)).clone(); | |||||
} | |||||
return directories; | |||||
} | |||||
public Resource[] getIncludedDirectoryResources() { | |||||
String[] names = getIncludedDirectories(); | |||||
int count = names.length; | |||||
Resource[] resources = new Resource[count]; | |||||
for (int i = 0; i < count; i++) { | |||||
resources[i] = getResource(names[i]); | |||||
} | |||||
return resources; | |||||
} | |||||
/** | /** | ||||
* Returns the names of the directories which matched none of the include | * Returns the names of the directories which matched none of the include | ||||
* patterns. The names are relative to the base directory. This involves | * patterns. The names are relative to the base directory. This involves | ||||
@@ -968,11 +930,8 @@ public class DirectoryScanner implements ResourceScanner, SelectorScanner { | |||||
*/ | */ | ||||
public String[] getNotIncludedDirectories() { | public String[] getNotIncludedDirectories() { | ||||
slowScan(); | slowScan(); | ||||
int count = dirsNotIncluded.size(); | |||||
String[] directories = new String[count]; | |||||
for (int i = 0; i < count; i++) { | |||||
directories[i] = (String)dirsNotIncluded.elementAt(i); | |||||
} | |||||
String[] directories = new String[dirsNotIncluded.size()]; | |||||
dirsNotIncluded.copyInto(directories); | |||||
return directories; | return directories; | ||||
} | } | ||||
@@ -989,11 +948,8 @@ public class DirectoryScanner implements ResourceScanner, SelectorScanner { | |||||
*/ | */ | ||||
public String[] getExcludedDirectories() { | public String[] getExcludedDirectories() { | ||||
slowScan(); | slowScan(); | ||||
int count = dirsExcluded.size(); | |||||
String[] directories = new String[count]; | |||||
for (int i = 0; i < count; i++) { | |||||
directories[i] = (String)dirsExcluded.elementAt(i); | |||||
} | |||||
String[] directories = new String[dirsExcluded.size()]; | |||||
dirsExcluded.copyInto(directories); | |||||
return directories; | return directories; | ||||
} | } | ||||
@@ -1010,11 +966,8 @@ public class DirectoryScanner implements ResourceScanner, SelectorScanner { | |||||
*/ | */ | ||||
public String[] getDeselectedDirectories() { | public String[] getDeselectedDirectories() { | ||||
slowScan(); | slowScan(); | ||||
int count = dirsDeselected.size(); | |||||
String[] directories = new String[count]; | |||||
for (int i = 0; i < count; i++) { | |||||
directories[i] = (String)dirsDeselected.elementAt(i); | |||||
} | |||||
String[] directories = new String[dirsDeselected.size()]; | |||||
dirsDeselected.copyInto(directories); | |||||
return directories; | return directories; | ||||
} | } | ||||
@@ -1,7 +1,7 @@ | |||||
/* | /* | ||||
* The Apache Software License, Version 1.1 | * The Apache Software License, Version 1.1 | ||||
* | * | ||||
* Copyright (c) 2001-2002 The Apache Software Foundation. All rights | |||||
* Copyright (c) 2001-2003 The Apache Software Foundation. All rights | |||||
* reserved. | * reserved. | ||||
* | * | ||||
* Redistribution and use in source and binary forms, with or without | * Redistribution and use in source and binary forms, with or without | ||||
@@ -104,8 +104,7 @@ public class Ear extends Jar { | |||||
// Create a ZipFileSet for this file, and pass it up. | // Create a ZipFileSet for this file, and pass it up. | ||||
ZipFileSet fs = new ZipFileSet(); | ZipFileSet fs = new ZipFileSet(); | ||||
fs.setDir(new File(deploymentDescriptor.getParent())); | |||||
fs.setIncludes(deploymentDescriptor.getName()); | |||||
fs.setFile(deploymentDescriptor); | |||||
fs.setFullpath("META-INF/application.xml"); | fs.setFullpath("META-INF/application.xml"); | ||||
super.addFileset(fs); | super.addFileset(fs); | ||||
} | } | ||||
@@ -134,7 +133,10 @@ public class Ear extends Jar { | |||||
super.initZipOutputStream(zOut); | super.initZipOutputStream(zOut); | ||||
} | } | ||||
protected void zipFile(File file, ZipOutputStream zOut, String vPath, | |||||
/** | |||||
* Overriden from Zip class to deal with application.xml | |||||
*/ | |||||
protected void zipFile(File file, ZipOutputStream zOut, String vPath, | |||||
int mode) | int mode) | ||||
throws IOException { | throws IOException { | ||||
// If the file being added is META-INF/application.xml, we | // If the file being added is META-INF/application.xml, we | ||||
@@ -72,6 +72,7 @@ import org.apache.tools.ant.Project; | |||||
import org.apache.tools.ant.ResourceScanner; | import org.apache.tools.ant.ResourceScanner; | ||||
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.ZipFileSet; | import org.apache.tools.ant.types.ZipFileSet; | ||||
import org.apache.tools.zip.ZipOutputStream; | import org.apache.tools.zip.ZipOutputStream; | ||||
@@ -190,7 +191,6 @@ public class Jar extends Zip { | |||||
} | } | ||||
} | } | ||||
} | } | ||||
} | } | ||||
} | } | ||||
@@ -374,7 +374,7 @@ public class Jar extends Zip { | |||||
ByteArrayInputStream bais = | ByteArrayInputStream bais = | ||||
new ByteArrayInputStream(baos.toByteArray()); | new ByteArrayInputStream(baos.toByteArray()); | ||||
super.zipFile(bais, zOut, "META-INF/MANIFEST.MF", | super.zipFile(bais, zOut, "META-INF/MANIFEST.MF", | ||||
System.currentTimeMillis(), null, | |||||
System.currentTimeMillis(), null, | |||||
ZipFileSet.DEFAULT_FILE_MODE); | ZipFileSet.DEFAULT_FILE_MODE); | ||||
super.initZipOutputStream(zOut); | super.initZipOutputStream(zOut); | ||||
} | } | ||||
@@ -442,33 +442,18 @@ public class Jar extends Zip { | |||||
ZipFileSet.DEFAULT_FILE_MODE); | ZipFileSet.DEFAULT_FILE_MODE); | ||||
} | } | ||||
/** | |||||
* Overriden from Zip class to deal with manifests | |||||
*/ | |||||
protected void zipFile(File file, ZipOutputStream zOut, String vPath, | |||||
int mode) | |||||
throws IOException { | |||||
if ("META-INF/MANIFEST.MF".equalsIgnoreCase(vPath)) { | |||||
if (! doubleFilePass || (doubleFilePass && skipWriting)) { | |||||
filesetManifest(file, null); | |||||
} | |||||
} else { | |||||
super.zipFile(file, zOut, vPath, mode); | |||||
} | |||||
} | |||||
/** | /** | ||||
* Overriden from Zip class to deal with manifests | * Overriden from Zip class to deal with manifests | ||||
*/ | */ | ||||
protected void zipFile(InputStream is, ZipOutputStream zOut, String vPath, | protected void zipFile(InputStream is, ZipOutputStream zOut, String vPath, | ||||
long lastModified, File file, int mode) | |||||
long lastModified, File fromArchive, int mode) | |||||
throws IOException { | throws IOException { | ||||
if ("META-INF/MANIFEST.MF".equalsIgnoreCase(vPath)) { | if ("META-INF/MANIFEST.MF".equalsIgnoreCase(vPath)) { | ||||
if (! doubleFilePass || (doubleFilePass && skipWriting)) { | if (! doubleFilePass || (doubleFilePass && skipWriting)) { | ||||
filesetManifest(file, is); | |||||
filesetManifest(fromArchive, is); | |||||
} | } | ||||
} else { | } else { | ||||
super.zipFile(is, zOut, vPath, lastModified, null, mode); | |||||
super.zipFile(is, zOut, vPath, lastModified, fromArchive, mode); | |||||
} | } | ||||
} | } | ||||
@@ -525,16 +510,31 @@ public class Jar extends Zip { | |||||
} | } | ||||
/** | /** | ||||
* Check whether the archive is up-to-date; | |||||
* @param scanners list of prepared scanners containing files to archive | |||||
* Collect the resources that are newer than the corresponding | |||||
* entries (or missing) in the original archive. | |||||
* | |||||
* <p>If we are going to recreate the archive instead of updating | |||||
* it, all resources should be considered as new, if a single one | |||||
* is. Because of this, subclasses overriding this method must | |||||
* call <code>super.getResourcesToAdd</code> and indicate with the | |||||
* third arg if they already know that the archive is | |||||
* out-of-date.</p> | |||||
* | |||||
* @param filesets The filesets to grab resources from | |||||
* @param zipFile intended archive file (may or may not exist) | * @param zipFile intended archive file (may or may not exist) | ||||
* @return true if nothing need be done (may have done something | |||||
* already); false if archive creation should proceed | |||||
* @param needsUpdate whether we already know that the archive is | |||||
* out-of-date. Subclasses overriding this method are supposed to | |||||
* set this value correctly in their call to | |||||
* super.getResourcesToAdd. | |||||
* @return an array of resources to add for each fileset passed in. | |||||
* | |||||
* @exception BuildException if it likes | * @exception BuildException if it likes | ||||
*/ | */ | ||||
protected boolean isUpToDate(ResourceScanner[] scanners, | |||||
FileSet[] fss, File zipFile) | |||||
protected Resource[][] getResourcesToAdd(FileSet[] filesets, | |||||
File zipFile, | |||||
boolean needsUpdate) | |||||
throws BuildException { | throws BuildException { | ||||
// need to handle manifest as a special check | // need to handle manifest as a special check | ||||
if (configuredManifest != null || manifestFile == null) { | if (configuredManifest != null || manifestFile == null) { | ||||
java.util.zip.ZipFile theZipFile = null; | java.util.zip.ZipFile theZipFile = null; | ||||
@@ -545,23 +545,24 @@ public class Jar extends Zip { | |||||
if (entry == null) { | if (entry == null) { | ||||
log("Updating jar since the current jar has no manifest", | log("Updating jar since the current jar has no manifest", | ||||
Project.MSG_VERBOSE); | Project.MSG_VERBOSE); | ||||
return false; | |||||
} | |||||
Manifest currentManifest = | |||||
new Manifest(new InputStreamReader(theZipFile | |||||
.getInputStream(entry))); | |||||
Manifest newManifest = createManifest(); | |||||
if (!currentManifest.equals(newManifest)) { | |||||
log("Updating jar since jar manifest has changed", | |||||
Project.MSG_VERBOSE); | |||||
return false; | |||||
needsUpdate = true; | |||||
} else { | |||||
Manifest currentManifest = | |||||
new Manifest(new InputStreamReader(theZipFile | |||||
.getInputStream(entry))); | |||||
Manifest newManifest = createManifest(); | |||||
if (!currentManifest.equals(newManifest)) { | |||||
log("Updating jar since jar manifest has changed", | |||||
Project.MSG_VERBOSE); | |||||
needsUpdate = true; | |||||
} | |||||
} | } | ||||
} catch (Exception e) { | } catch (Exception e) { | ||||
// any problems and we will rebuild | // any problems and we will rebuild | ||||
log("Updating jar since cannot read current jar manifest: " | log("Updating jar since cannot read current jar manifest: " | ||||
+ e.getClass().getName() + " - " + e.getMessage(), | + e.getClass().getName() + " - " + e.getMessage(), | ||||
Project.MSG_VERBOSE); | Project.MSG_VERBOSE); | ||||
return false; | |||||
needsUpdate = true; | |||||
} finally { | } finally { | ||||
if (theZipFile != null) { | if (theZipFile != null) { | ||||
try { | try { | ||||
@@ -572,9 +573,33 @@ public class Jar extends Zip { | |||||
} | } | ||||
} | } | ||||
} else if (manifestFile.lastModified() > zipFile.lastModified()) { | } else if (manifestFile.lastModified() > zipFile.lastModified()) { | ||||
return false; | |||||
log("Updating jar since manifestFile is newer than the archive", | |||||
Project.MSG_VERBOSE); | |||||
needsUpdate = true; | |||||
} | |||||
Resource[][] fromZip = | |||||
super.getResourcesToAdd(filesets, zipFile, needsUpdate); | |||||
if (needsUpdate && isEmpty(fromZip)) { | |||||
// archive doesn't have any content apart from the manifest | |||||
/* | |||||
* OK, this is a hack. | |||||
* | |||||
* Zip doesn't care if the array we return is longer than | |||||
* the array of filesets, so we can savely append an | |||||
* additional non-empty array. This will make Zip think | |||||
* that there are resources out-of-date and at the same | |||||
* time add nothing. | |||||
* | |||||
* The whole manifest handling happens in initZipOutputStream. | |||||
*/ | |||||
Resource[][] tmp = new Resource[fromZip.length + 1][]; | |||||
System.arraycopy(fromZip, 0, tmp, 0, fromZip.length); | |||||
tmp[fromZip.length] = new Resource[] {new Resource("")}; | |||||
fromZip = tmp; | |||||
} | } | ||||
return super.isUpToDate(scanners, fss, zipFile); | |||||
return fromZip; | |||||
} | } | ||||
protected boolean createEmptyZip(File zipFile) { | protected boolean createEmptyZip(File zipFile) { | ||||
@@ -1,7 +1,7 @@ | |||||
/* | /* | ||||
* The Apache Software License, Version 1.1 | * The Apache Software License, Version 1.1 | ||||
* | * | ||||
* Copyright (c) 2000-2002 The Apache Software Foundation. All rights | |||||
* Copyright (c) 2000-2003 The Apache Software Foundation. All rights | |||||
* reserved. | * reserved. | ||||
* | * | ||||
* Redistribution and use in source and binary forms, with or without | * Redistribution and use in source and binary forms, with or without | ||||
@@ -409,4 +409,13 @@ public abstract class MatchingTask extends Task implements SelectorContainer { | |||||
public void addDepend(DependSelector selector) { | public void addDepend(DependSelector selector) { | ||||
fileset.addDepend(selector); | fileset.addDepend(selector); | ||||
} | } | ||||
/** | |||||
* Accessor for the implict fileset. | |||||
* | |||||
* @since Ant 1.5.2 | |||||
*/ | |||||
protected final FileSet getImplicitFileSet() { | |||||
return fileset; | |||||
} | |||||
} | } |
@@ -1,7 +1,7 @@ | |||||
/* | /* | ||||
* The Apache Software License, Version 1.1 | * The Apache Software License, Version 1.1 | ||||
* | * | ||||
* Copyright (c) 2000-2002 The Apache Software Foundation. All rights | |||||
* Copyright (c) 2000-2003 The Apache Software Foundation. All rights | |||||
* reserved. | * reserved. | ||||
* | * | ||||
* Redistribution and use in source and binary forms, with or without | * Redistribution and use in source and binary forms, with or without | ||||
@@ -121,8 +121,7 @@ public class War extends Jar { | |||||
// Create a ZipFileSet for this file, and pass it up. | // Create a ZipFileSet for this file, and pass it up. | ||||
ZipFileSet fs = new ZipFileSet(); | ZipFileSet fs = new ZipFileSet(); | ||||
fs.setDir(new File(deploymentDescriptor.getParent())); | |||||
fs.setIncludes(deploymentDescriptor.getName()); | |||||
fs.setFile(deploymentDescriptor); | |||||
fs.setFullpath("WEB-INF/web.xml"); | fs.setFullpath("WEB-INF/web.xml"); | ||||
super.addFileset(fs); | super.addFileset(fs); | ||||
} | } | ||||
@@ -170,9 +169,9 @@ public class War extends Jar { | |||||
} | } | ||||
/** | /** | ||||
* add another file to the stream | |||||
* Overriden from Zip class to deal with web.xml | |||||
*/ | */ | ||||
protected void zipFile(File file, ZipOutputStream zOut, String vPath, | |||||
protected void zipFile(File file, ZipOutputStream zOut, String vPath, | |||||
int mode) | int mode) | ||||
throws IOException { | throws IOException { | ||||
// If the file being added is WEB-INF/web.xml, we warn if it's | // If the file being added is WEB-INF/web.xml, we warn if it's | ||||
@@ -66,6 +66,7 @@ import java.util.Hashtable; | |||||
import java.util.Stack; | import java.util.Stack; | ||||
import java.util.Vector; | import java.util.Vector; | ||||
import java.util.zip.CRC32; | import java.util.zip.CRC32; | ||||
import java.util.zip.ZipFile; | |||||
import java.util.zip.ZipInputStream; | import java.util.zip.ZipInputStream; | ||||
import org.apache.tools.ant.BuildException; | import org.apache.tools.ant.BuildException; | ||||
@@ -127,6 +128,7 @@ public class Zip extends MatchingTask { | |||||
protected boolean doubleFilePass = false; | protected boolean doubleFilePass = false; | ||||
protected boolean skipWriting = false; | protected boolean skipWriting = false; | ||||
private static FileUtils fileUtils = FileUtils.newFileUtils(); | |||||
/** | /** | ||||
* true when we are adding new files into the Zip file, as opposed | * true when we are adding new files into the Zip file, as opposed | ||||
@@ -338,35 +340,31 @@ public class Zip extends MatchingTask { | |||||
} | } | ||||
} | } | ||||
// Create the scanners to pass to isUpToDate(). | |||||
Vector dss = new Vector(); | |||||
// collect filesets to pass them to getResourcesToAdd | |||||
Vector vfss = new Vector(); | Vector vfss = new Vector(); | ||||
if (baseDir != null) { | if (baseDir != null) { | ||||
dss.addElement(getDirectoryScanner(baseDir)); | |||||
FileSet fs = new FileSet(); | |||||
FileSet fs = (FileSet) getImplicitFileSet().clone(); | |||||
fs.setDir(baseDir); | fs.setDir(baseDir); | ||||
vfss.addElement(fs); | vfss.addElement(fs); | ||||
} | } | ||||
for (int i = 0; i < filesets.size(); i++) { | for (int i = 0; i < filesets.size(); i++) { | ||||
FileSet fs = (FileSet) filesets.elementAt(i); | FileSet fs = (FileSet) filesets.elementAt(i); | ||||
dss.addElement (fs.getDirectoryScanner(getProject())); | |||||
vfss.addElement(fs); | vfss.addElement(fs); | ||||
} | } | ||||
int dssSize = dss.size(); | |||||
ResourceScanner[] scanners = new ResourceScanner[dssSize]; | |||||
dss.copyInto(scanners); | |||||
FileSet [] fss = new FileSet[dssSize]; | |||||
FileSet[] fss = new FileSet[vfss.size()]; | |||||
vfss.copyInto(fss); | vfss.copyInto(fss); | ||||
boolean success = false; | boolean success = false; | ||||
try { | try { | ||||
Resource[][] addThem = getResourcesToAdd(fss, zipFile, false); | |||||
// quick exit if the target is up to date | // quick exit if the target is up to date | ||||
// can also handle empty archives | // can also handle empty archives | ||||
if (isUpToDate(scanners, fss, zipFile)) { | |||||
if (isEmpty(addThem)) { | |||||
return; | return; | ||||
} | } | ||||
if (doUpdate) { | if (doUpdate) { | ||||
FileUtils fileUtils = FileUtils.newFileUtils(); | |||||
renamedFile = | renamedFile = | ||||
fileUtils.createTempFile("zip", ".tmp", | fileUtils.createTempFile("zip", ".tmp", | ||||
fileUtils.getParentFile(zipFile)); | fileUtils.getParentFile(zipFile)); | ||||
@@ -401,14 +399,13 @@ public class Zip extends MatchingTask { | |||||
} | } | ||||
initZipOutputStream(zOut); | initZipOutputStream(zOut); | ||||
// Add the implicit fileset to the archive. | |||||
if (baseDir != null) { | |||||
addFiles(getDirectoryScanner(baseDir), zOut, "", "", | |||||
ZipFileSet.DEFAULT_DIR_MODE, | |||||
ZipFileSet.DEFAULT_FILE_MODE); | |||||
} | |||||
// Add the explicit filesets to the archive. | // Add the explicit filesets to the archive. | ||||
addFiles(filesets, zOut); | |||||
for (int i = 0; i < fss.length; i++) { | |||||
if (addThem[i].length != 0) { | |||||
addResources(fss[i], addThem[i], zOut); | |||||
} | |||||
} | |||||
if (doUpdate) { | if (doUpdate) { | ||||
addingNewFiles = false; | addingNewFiles = false; | ||||
ZipFileSet oldFiles = new ZipFileSet(); | ZipFileSet oldFiles = new ZipFileSet(); | ||||
@@ -418,9 +415,10 @@ public class Zip extends MatchingTask { | |||||
PatternSet.NameEntry ne = oldFiles.createExclude(); | PatternSet.NameEntry ne = oldFiles.createExclude(); | ||||
ne.setName((String) addedFiles.elementAt(i)); | ne.setName((String) addedFiles.elementAt(i)); | ||||
} | } | ||||
Vector tmp = new Vector(1); | |||||
tmp.addElement(oldFiles); | |||||
addFiles(tmp, zOut); | |||||
addResources(oldFiles, | |||||
oldFiles.getDirectoryScanner(getProject()) | |||||
.getIncludedFileResources(), | |||||
zOut); | |||||
} | } | ||||
finalizeZipOutputStream(zOut); | finalizeZipOutputStream(zOut); | ||||
@@ -481,127 +479,101 @@ public class Zip extends MatchingTask { | |||||
* Indicates if the task is adding new files into the archive as opposed to | * Indicates if the task is adding new files into the archive as opposed to | ||||
* copying back unchanged files from the backup copy | * copying back unchanged files from the backup copy | ||||
*/ | */ | ||||
protected boolean isAddingNewFiles() { | |||||
protected final boolean isAddingNewFiles() { | |||||
return addingNewFiles; | return addingNewFiles; | ||||
} | } | ||||
/** | /** | ||||
* Add all files of the given FileScanner to the ZipOutputStream | |||||
* prependig the given prefix to each filename. | |||||
* | |||||
* <p>Ensure parent directories have been added as well. | |||||
* | |||||
* @deprecated use six-arg version instead. | |||||
*/ | |||||
protected void addFiles(FileScanner scanner, ZipOutputStream zOut, | |||||
String prefix, String fullpath) | |||||
throws IOException { | |||||
addFiles(scanner, zOut, prefix, fullpath, ZipFileSet.DEFAULT_DIR_MODE, | |||||
ZipFileSet.DEFAULT_FILE_MODE); | |||||
} | |||||
/** | |||||
* Add all files of the given FileScanner to the ZipOutputStream | |||||
* prependig the given prefix to each filename. | |||||
* Add the given resources. | |||||
* | * | ||||
* <p>Ensure parent directories have been added as well. | |||||
* @param fileset may give additional information like fullpath or | |||||
* permissions. | |||||
* @param resources the resources to add | |||||
* @param zOut the stream to write to | |||||
* | * | ||||
* @since Ant 1.6 | * @since Ant 1.6 | ||||
*/ | */ | ||||
protected void addFiles(FileScanner scanner, ZipOutputStream zOut, | |||||
String prefix, String fullpath, int dirMode, | |||||
int fileMode) | |||||
protected final void addResources(FileSet fileset, Resource[] resources, | |||||
ZipOutputStream zOut) | |||||
throws IOException { | throws IOException { | ||||
String prefix = ""; | |||||
String fullpath = ""; | |||||
int dirMode = ZipFileSet.DEFAULT_DIR_MODE; | |||||
int fileMode = ZipFileSet.DEFAULT_FILE_MODE; | |||||
ZipFileSet zfs = null; | |||||
if (fileset instanceof ZipFileSet) { | |||||
zfs = (ZipFileSet) fileset; | |||||
prefix = zfs.getPrefix(); | |||||
fullpath = zfs.getFullpath(); | |||||
dirMode = zfs.getDirMode(); | |||||
fileMode = zfs.getDirMode(); | |||||
} | |||||
if (prefix.length() > 0 && fullpath.length() > 0) { | if (prefix.length() > 0 && fullpath.length() > 0) { | ||||
throw new BuildException("Both prefix and fullpath attributes must" | throw new BuildException("Both prefix and fullpath attributes must" | ||||
+ " not be set on the same fileset."); | + " not be set on the same fileset."); | ||||
} | } | ||||
File thisBaseDir = scanner.getBasedir(); | |||||
// directories that matched include patterns | |||||
String[] dirs = scanner.getIncludedDirectories(); | |||||
if (dirs.length > 0 && fullpath.length() > 0) { | |||||
if (resources.length != 1 && fullpath.length() > 0) { | |||||
throw new BuildException("fullpath attribute may only be specified" | throw new BuildException("fullpath attribute may only be specified" | ||||
+ " for filesets that specify a single" | + " for filesets that specify a single" | ||||
+ " file."); | + " file."); | ||||
} | } | ||||
for (int i = 0; i < dirs.length; i++) { | |||||
if ("".equals(dirs[i])) { | |||||
continue; | |||||
} | |||||
String name = dirs[i].replace(File.separatorChar, '/'); | |||||
if (!name.endsWith("/")) { | |||||
name += "/"; | |||||
} | |||||
addParentDirs(thisBaseDir, name, zOut, prefix, dirMode); | |||||
} | |||||
// files that matched include patterns | |||||
String[] files = scanner.getIncludedFiles(); | |||||
if (files.length > 1 && fullpath.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(thisBaseDir, files[i]); | |||||
if (fullpath.length() > 0) { | |||||
// Add this file at the specified location. | |||||
addParentDirs(null, fullpath, zOut, "", dirMode); | |||||
zipFile(f, zOut, fullpath, fileMode); | |||||
} else { | |||||
// Add this file with the specified prefix. | |||||
String name = files[i].replace(File.separatorChar, '/'); | |||||
addParentDirs(thisBaseDir, name, zOut, prefix, dirMode); | |||||
zipFile(f, zOut, prefix + name, fileMode); | |||||
} | |||||
if (prefix.length() > 0 | |||||
&& !prefix.endsWith("/") | |||||
&& !prefix.endsWith("\\")) { | |||||
prefix += "/"; | |||||
} | } | ||||
} | |||||
protected void addZipEntries(ZipFileSet fs, DirectoryScanner ds, | |||||
ZipOutputStream zOut, String prefix, | |||||
String fullpath) | |||||
throws IOException { | |||||
log("adding zip entries: " + fullpath, Project.MSG_VERBOSE); | |||||
if (prefix.length() > 0 && fullpath.length() > 0) { | |||||
throw new BuildException("Both prefix and fullpath attributes must" | |||||
+ " not be set on the same fileset."); | |||||
} | |||||
ZipScanner zipScanner = (ZipScanner) ds; | |||||
File zipSrc = fs.getSrc(); | |||||
ZipEntry entry; | |||||
java.util.zip.ZipEntry origEntry; | |||||
ZipInputStream in = null; | |||||
ZipFile zf = null; | |||||
try { | try { | ||||
in = new ZipInputStream(new FileInputStream(zipSrc)); | |||||
while ((origEntry = in.getNextEntry()) != null) { | |||||
entry = new ZipEntry(origEntry); | |||||
String vPath = entry.getName(); | |||||
if (zipScanner.match(vPath)) { | |||||
if (fullpath.length() > 0) { | |||||
addParentDirs(null, fullpath, zOut, "", | |||||
fs.getDirMode()); | |||||
zipFile(in, zOut, fullpath, entry.getTime(), zipSrc, | |||||
fs.getFileMode()); | |||||
} else { | |||||
addParentDirs(null, vPath, zOut, prefix, | |||||
fs.getDirMode()); | |||||
if (!entry.isDirectory()) { | |||||
zipFile(in, zOut, prefix + vPath, entry.getTime(), | |||||
zipSrc, fs.getFileMode()); | |||||
} | |||||
boolean dealingWithFiles = false; | |||||
File base = null; | |||||
if (zfs == null || zfs.getSrc() == null) { | |||||
dealingWithFiles = true; | |||||
base = fileset.getDir(getProject()); | |||||
} else { | |||||
zf = new ZipFile(zfs.getSrc()); | |||||
} | |||||
for (int i = 0; i < resources.length; i++) { | |||||
String name = null; | |||||
if (fullpath.length() > 0) { | |||||
name = fullpath; | |||||
} else { | |||||
name = resources[i].getName(); | |||||
} | |||||
name = name.replace(File.separatorChar, '/'); | |||||
if ("".equals(name)) { | |||||
continue; | |||||
} | |||||
if (resources[i].isDirectory() && ! name.endsWith("/")) { | |||||
name = name + "/"; | |||||
} | |||||
addParentDirs(base, name, zOut, prefix, dirMode); | |||||
if (!resources[i].isDirectory() && dealingWithFiles) { | |||||
File f = fileUtils.resolveFile(base, | |||||
resources[i].getName()); | |||||
zipFile(f, zOut, prefix + name, fileMode); | |||||
} else if (!resources[i].isDirectory()) { | |||||
java.util.zip.ZipEntry ze = | |||||
zf.getEntry(resources[i].getName()); | |||||
if (ze != null) { | |||||
zipFile(zf.getInputStream(ze), zOut, prefix + name, | |||||
ze.getTime(), zfs.getSrc(), fileMode); | |||||
} | } | ||||
} | } | ||||
} | } | ||||
} finally { | } finally { | ||||
if (in != null) { | |||||
in.close(); | |||||
if (zf != null) { | |||||
zf.close(); | |||||
} | } | ||||
} | } | ||||
} | } | ||||
@@ -623,7 +595,7 @@ public class Zip extends MatchingTask { | |||||
/** | /** | ||||
* Create an empty zip file | * Create an empty zip file | ||||
* | * | ||||
* @return true if the file is then considered up to date. | |||||
* @return true for historic reasons | |||||
*/ | */ | ||||
protected boolean createEmptyZip(File zipFile) { | protected boolean createEmptyZip(File zipFile) { | ||||
// In this case using java.util.zip will not work | // In this case using java.util.zip will not work | ||||
@@ -657,9 +629,12 @@ public class Zip extends MatchingTask { | |||||
return true; | return true; | ||||
} | } | ||||
/** | |||||
* @since Ant 1.6 | |||||
*/ | |||||
private synchronized ZipScanner getZipScanner() { | private synchronized ZipScanner getZipScanner() { | ||||
if (zs == null) { | if (zs == null) { | ||||
zs=new ZipScanner(); | |||||
zs = new ZipScanner(); | |||||
// set the task of the zip scanner so that it can log properly | // set the task of the zip scanner so that it can log properly | ||||
zs.setTask(this); | zs.setTask(this); | ||||
zs.setSrc(zipFile); | zs.setSrc(zipFile); | ||||
@@ -668,144 +643,149 @@ public class Zip extends MatchingTask { | |||||
} | } | ||||
/** | /** | ||||
* Check whether the archive is up-to-date; and handle behavior | |||||
* for empty archives. | |||||
* @param scanners list of prepared scanners containing files to archive | |||||
* Collect the resources that are newer than the corresponding | |||||
* entries (or missing) in the original archive. | |||||
* | |||||
* <p>If we are going to recreate the archive instead of updating | |||||
* it, all resources should be considered as new, if a single one | |||||
* is. Because of this, subclasses overriding this method must | |||||
* call <code>super.getResourcesToAdd</code> and indicate with the | |||||
* third arg if they already know that the archive is | |||||
* out-of-date.</p> | |||||
* | |||||
* @param filesets The filesets to grab resources from | |||||
* @param zipFile intended archive file (may or may not exist) | * @param zipFile intended archive file (may or may not exist) | ||||
* @return true if nothing need be done (may have done something | |||||
* already); false if archive creation should proceed | |||||
* @param needsUpdate whether we already know that the archive is | |||||
* out-of-date. Subclasses overriding this method are supposed to | |||||
* set this value correctly in their call to | |||||
* super.getResourcesToAdd. | |||||
* @return an array of resources to add for each fileset passed in. | |||||
* | |||||
* @exception BuildException if it likes | * @exception BuildException if it likes | ||||
*/ | */ | ||||
protected boolean isUpToDate(ResourceScanner[] scanners, | |||||
FileSet[] fss, File zipFile) | |||||
protected Resource[][] getResourcesToAdd(FileSet[] filesets, | |||||
File zipFile, | |||||
boolean needsUpdate) | |||||
throws BuildException { | throws BuildException { | ||||
Resource[][] resourceNames = grabResources(scanners); | |||||
for (int counter = 0;counter < scanners.length; counter++){ | |||||
for (int j=0; j < resourceNames[counter].length;j++) { | |||||
log("resource from scanner " + counter + " " + j + " name : " | |||||
+ resourceNames[counter][j].getName(), Project.MSG_DEBUG); | |||||
} | |||||
} | |||||
String[][] fileNames = grabFileNames(scanners); | |||||
File[] files = grabFiles(scanners, fileNames); | |||||
if (files.length == 0) { | |||||
Resource[][] initialResources = grabResources(filesets); | |||||
if (isEmpty(initialResources)) { | |||||
if (emptyBehavior.equals("skip")) { | if (emptyBehavior.equals("skip")) { | ||||
log("Warning: skipping " + archiveType + " archive " + zipFile + | |||||
" because no files were included.", Project.MSG_WARN); | |||||
return true; | |||||
log("Warning: skipping " + archiveType + " archive " | |||||
+ zipFile + " because no files were included.", | |||||
Project.MSG_WARN); | |||||
} else if (emptyBehavior.equals("fail")) { | } else if (emptyBehavior.equals("fail")) { | ||||
throw new BuildException("Cannot create " + archiveType | throw new BuildException("Cannot create " + archiveType | ||||
+ " archive " + zipFile + | + " archive " + zipFile + | ||||
": no files were included.", getLocation()); | |||||
": no files were included.", | |||||
getLocation()); | |||||
} else { | } else { | ||||
// Create. | // Create. | ||||
return createEmptyZip(zipFile); | |||||
} | |||||
} else { | |||||
for (int i = 0; i < files.length; ++i) { | |||||
if (files[i].equals(zipFile)) { | |||||
throw new BuildException("A zip file cannot include " | |||||
+ "itself", getLocation()); | |||||
} | |||||
createEmptyZip(zipFile); | |||||
} | } | ||||
return initialResources; | |||||
} | |||||
if (!zipFile.exists()) { | |||||
return false; | |||||
} | |||||
if (!zipFile.exists()) { | |||||
return initialResources; | |||||
} | |||||
if (needsUpdate && !doUpdate) { | |||||
// we are recreating the archive, need all resources | |||||
return initialResources; | |||||
} | |||||
for (int i = 0; i < scanners.length; i++) { | |||||
boolean result=false; | |||||
FileNameMapper myMapper = new IdentityMapper(); | |||||
if (fss[i] instanceof ZipFileSet) { | |||||
ZipFileSet zfs = (ZipFileSet) fss[i]; | |||||
if (zfs.getFullpath() != null | |||||
&& !zfs.getFullpath().equals("") ) { | |||||
// in this case all files from origin map to | |||||
// the fullPath attribute of the zipfileset at | |||||
// destination | |||||
MergingMapper fm = new MergingMapper(); | |||||
fm.setTo(zfs.getFullpath()); | |||||
myMapper = fm; | |||||
} else if (zfs.getPrefix() != null | |||||
&& !zfs.getPrefix().equals("")) { | |||||
GlobPatternMapper gm=new GlobPatternMapper(); | |||||
gm.setFrom("*"); | |||||
gm.setTo(zfs.getPrefix() + "*"); | |||||
myMapper = gm; | |||||
Resource[][] newerResources = new Resource[filesets.length][]; | |||||
for (int i = 0; i < filesets.length; i++) { | |||||
if (!(fileset instanceof ZipFileSet) | |||||
|| ((ZipFileSet) fileset).getSrc() == null) { | |||||
File base = filesets[i].getDir(getProject()); | |||||
for (int j = 0; j < initialResources[i].length; j++) { | |||||
File resourceAsFile = | |||||
fileUtils.resolveFile(base, | |||||
initialResources[i][j].getName()); | |||||
if (resourceAsFile.equals(zipFile)) { | |||||
throw new BuildException("A zip file cannot include " | |||||
+ "itself", getLocation()); | |||||
} | } | ||||
} | } | ||||
Resource[] newerSources = | |||||
SourceSelector.selectOutOfDateSources(this, | |||||
resourceNames[i], | |||||
myMapper, | |||||
getZipScanner()); | |||||
result = (newerSources.length == 0); | |||||
if (!result) { | |||||
return result; | |||||
} | |||||
} | } | ||||
} | } | ||||
return true; | |||||
} | |||||
protected static File[] grabFiles(FileScanner[] scanners) { | |||||
return grabFiles(scanners, grabFileNames(scanners)); | |||||
} | |||||
protected static File[] grabFiles(FileScanner[] scanners, | |||||
String[][] fileNames) { | |||||
Vector files = new Vector(); | |||||
for (int i = 0; i < fileNames.length; i++) { | |||||
File thisBaseDir = scanners[i].getBasedir(); | |||||
for (int j = 0; j < fileNames[i].length; j++) { | |||||
files.addElement(new File(thisBaseDir, fileNames[i][j])); | |||||
for (int i = 0; i < filesets.length; i++) { | |||||
if (initialResources[i].length == 0) { | |||||
continue; | |||||
} | |||||
FileNameMapper myMapper = new IdentityMapper(); | |||||
if (filesets[i] instanceof ZipFileSet) { | |||||
ZipFileSet zfs = (ZipFileSet) filesets[i]; | |||||
if (zfs.getFullpath() != null | |||||
&& !zfs.getFullpath().equals("") ) { | |||||
// in this case all files from origin map to | |||||
// the fullPath attribute of the zipfileset at | |||||
// destination | |||||
MergingMapper fm = new MergingMapper(); | |||||
fm.setTo(zfs.getFullpath()); | |||||
myMapper = fm; | |||||
} else if (zfs.getPrefix() != null | |||||
&& !zfs.getPrefix().equals("")) { | |||||
GlobPatternMapper gm=new GlobPatternMapper(); | |||||
gm.setFrom("*"); | |||||
String prefix = zfs.getPrefix(); | |||||
if (!prefix.endsWith("/") && !prefix.endsWith("\\")) { | |||||
prefix += "/"; | |||||
} | |||||
gm.setTo(prefix + "*"); | |||||
myMapper = gm; | |||||
} | |||||
} | |||||
newerResources[i] = | |||||
SourceSelector.selectOutOfDateSources(this, | |||||
initialResources[i], | |||||
myMapper, | |||||
getZipScanner()); | |||||
needsUpdate = needsUpdate || (newerResources[i].length > 0); | |||||
if (needsUpdate && !doUpdate) { | |||||
// we will return initialResources anyway, no reason | |||||
// to scan further. | |||||
break; | |||||
} | } | ||||
} | } | ||||
File[] toret = new File[files.size()]; | |||||
files.copyInto(toret); | |||||
return toret; | |||||
} | |||||
protected static String[][] grabFileNames(FileScanner[] scanners) { | |||||
String[][] result = new String[scanners.length][]; | |||||
for (int i = 0; i < scanners.length; i++) { | |||||
String[] files = scanners[i].getIncludedFiles(); | |||||
String[] dirs = scanners[i].getIncludedDirectories(); | |||||
result[i] = new String[files.length + dirs.length]; | |||||
System.arraycopy(files, 0, result[i], 0, files.length); | |||||
System.arraycopy(dirs, 0, result[i], files.length, dirs.length); | |||||
if (needsUpdate && !doUpdate) { | |||||
// we are recreating the archive, need all resources | |||||
return initialResources; | |||||
} | } | ||||
return result; | |||||
return newerResources; | |||||
} | } | ||||
/** | /** | ||||
* Fetch all included and not excluded resources from the sets. | |||||
* | |||||
* <p>Included directories will preceede included files.</p> | |||||
* | * | ||||
* @param scanners here are expected ResourceScanner arguments | |||||
* @return double dimensional array of resources | |||||
* @since Ant 1.6 | |||||
*/ | */ | ||||
protected static Resource[][] grabResources(ResourceScanner[] scanners) { | |||||
Resource[][] result = new Resource[scanners.length][]; | |||||
for (int i = 0; i < scanners.length; i++) { | |||||
Resource[] files = scanners[i].getIncludedFileResources(); | |||||
Resource[] directories = | |||||
scanners[i].getIncludedDirectoryResources(); | |||||
protected Resource[][] grabResources(FileSet[] filesets) { | |||||
Resource[][] result = new Resource[filesets.length][]; | |||||
for (int i = 0; i < filesets.length; i++) { | |||||
ResourceScanner rs = filesets[i].getDirectoryScanner(getProject()); | |||||
Resource[] files = rs.getIncludedFileResources(); | |||||
Resource[] directories = rs.getIncludedDirectoryResources(); | |||||
result[i] = new Resource[files.length + directories.length]; | result[i] = new Resource[files.length + directories.length]; | ||||
System.arraycopy(files, 0, result[i], 0, files.length); | |||||
System.arraycopy(directories, 0, result[i], files.length, | |||||
directories.length); | |||||
System.arraycopy(directories, 0, result[i], 0, directories.length); | |||||
System.arraycopy(files, 0, result[i], directories.length, | |||||
files.length); | |||||
} | } | ||||
return result; | return result; | ||||
} | } | ||||
/** | |||||
* @deprecated use four-arg version instead. | |||||
*/ | |||||
protected void zipDir(File dir, ZipOutputStream zOut, String vPath) | |||||
throws IOException { | |||||
zipDir(dir, zOut, vPath, ZipFileSet.DEFAULT_DIR_MODE); | |||||
} | |||||
/** | /** | ||||
* @since Ant 1.6 | * @since Ant 1.6 | ||||
*/ | */ | ||||
@@ -841,20 +821,20 @@ public class Zip extends MatchingTask { | |||||
} | } | ||||
/** | /** | ||||
* @deprecated use six-arg version instead. | |||||
*/ | |||||
protected void zipFile(InputStream in, ZipOutputStream zOut, String vPath, | |||||
long lastModified, File file) | |||||
throws IOException { | |||||
zipFile(in, zOut, vPath, lastModified, file, | |||||
ZipFileSet.DEFAULT_FILE_MODE); | |||||
} | |||||
/** | |||||
* Adds a new entry to the archive, takes care of duplicates as well. | |||||
* | |||||
* @param in the stream to read data for the entry from. | |||||
* @param zOut the stream to write to. | |||||
* @param vPath the name this entry shall have in the archive. | |||||
* @param lastModified last modification time for the entry. | |||||
* @param fromArchive the original archive we are copying this | |||||
* entry from, will be null if we are not copying from an archive. | |||||
* @param mode the Unix permissions to set. | |||||
* | |||||
* @since Ant 1.6 | * @since Ant 1.6 | ||||
*/ | */ | ||||
protected void zipFile(InputStream in, ZipOutputStream zOut, String vPath, | protected void zipFile(InputStream in, ZipOutputStream zOut, String vPath, | ||||
long lastModified, File file, int mode) | |||||
long lastModified, File fromArchive, int mode) | |||||
throws IOException { | throws IOException { | ||||
if (entries.contains(vPath)) { | if (entries.contains(vPath)) { | ||||
@@ -939,17 +919,18 @@ public class Zip extends MatchingTask { | |||||
} | } | ||||
/** | /** | ||||
* @deprecated use six-arg version instead. | |||||
*/ | |||||
protected void zipFile(File file, ZipOutputStream zOut, String vPath) | |||||
throws IOException { | |||||
zipFile(file, zOut, vPath, ZipFileSet.DEFAULT_FILE_MODE); | |||||
} | |||||
/** | |||||
* Method that gets called when adding from java.io.File instances. | |||||
* | |||||
* <p>This implementation delegates to the six-arg version.</p> | |||||
* | |||||
* @param file the file to add to the archive | |||||
* @param zOut the stream to write to | |||||
* @param vPath the name this entry shall have in the archive | |||||
* @param mode the Unix permissions to set. | |||||
* | |||||
* @since Ant 1.6 | * @since Ant 1.6 | ||||
*/ | */ | ||||
protected void zipFile(File file, ZipOutputStream zOut, String vPath, | |||||
protected void zipFile(File file, ZipOutputStream zOut, String vPath, | |||||
int mode) | int mode) | ||||
throws IOException { | throws IOException { | ||||
if (file.equals(zipFile)) { | if (file.equals(zipFile)) { | ||||
@@ -966,24 +947,14 @@ public class Zip extends MatchingTask { | |||||
} | } | ||||
} | } | ||||
/** | |||||
* @deprecated use five-arg version instead. | |||||
*/ | |||||
protected void addParentDirs(File baseDir, String entry, | |||||
ZipOutputStream zOut, String prefix) | |||||
throws IOException { | |||||
addParentDirs(baseDir, entry, zOut, prefix, | |||||
ZipFileSet.DEFAULT_DIR_MODE); | |||||
} | |||||
/** | /** | ||||
* Ensure all parent dirs of a given entry have been added. | * Ensure all parent dirs of a given entry have been added. | ||||
* | * | ||||
* @since Ant 1.6 | * @since Ant 1.6 | ||||
*/ | */ | ||||
protected void addParentDirs(File baseDir, String entry, | |||||
ZipOutputStream zOut, String prefix, | |||||
int dirMode) | |||||
protected final void addParentDirs(File baseDir, String entry, | |||||
ZipOutputStream zOut, String prefix, | |||||
int dirMode) | |||||
throws IOException { | throws IOException { | ||||
if (!doFilesonly) { | if (!doFilesonly) { | ||||
Stack directories = new Stack(); | Stack directories = new Stack(); | ||||
@@ -1010,55 +981,6 @@ public class Zip extends MatchingTask { | |||||
} | } | ||||
} | } | ||||
/** | |||||
* Iterate over the given Vector of (zip)filesets and add | |||||
* all files to the ZipOutputStream using the given prefix | |||||
* or fullpath. | |||||
*/ | |||||
protected void addFiles(Vector filesets, ZipOutputStream zOut) | |||||
throws IOException { | |||||
// Add each fileset in the Vector. | |||||
for (int i = 0; i < filesets.size(); i++) { | |||||
FileSet fs = (FileSet) filesets.elementAt(i); | |||||
DirectoryScanner ds = fs.getDirectoryScanner(getProject()); | |||||
String prefix = ""; | |||||
String fullpath = ""; | |||||
int fileMode = ZipFileSet.DEFAULT_FILE_MODE; | |||||
int dirMode = ZipFileSet.DEFAULT_DIR_MODE; | |||||
if (fs instanceof ZipFileSet) { | |||||
ZipFileSet zfs = (ZipFileSet) fs; | |||||
prefix = zfs.getPrefix(); | |||||
fullpath = zfs.getFullpath(); | |||||
fileMode = zfs.getFileMode(); | |||||
dirMode = zfs.getDirMode(); | |||||
} | |||||
if (prefix.length() > 0 | |||||
&& !prefix.endsWith("/") | |||||
&& !prefix.endsWith("\\")) { | |||||
prefix += "/"; | |||||
} | |||||
// Need to manually add either fullpath's parent directory, or | |||||
// the prefix directory, to the archive. | |||||
if (prefix.length() > 0) { | |||||
addParentDirs(null, prefix, zOut, "", dirMode); | |||||
zipDir(null, zOut, prefix, dirMode); | |||||
} else if (fullpath.length() > 0) { | |||||
addParentDirs(null, fullpath, zOut, "", dirMode); | |||||
} | |||||
if (fs instanceof ZipFileSet | |||||
&& ((ZipFileSet) fs).getSrc() != null) { | |||||
addZipEntries((ZipFileSet) fs, ds, zOut, prefix, fullpath); | |||||
} else { | |||||
// Add the fileset. | |||||
addFiles(ds, zOut, prefix, fullpath, dirMode, fileMode); | |||||
} | |||||
} | |||||
} | |||||
/** | /** | ||||
* Do any clean up necessary to allow this instance to be used again. | * Do any clean up necessary to allow this instance to be used again. | ||||
* | * | ||||
@@ -1109,6 +1031,20 @@ public class Zip extends MatchingTask { | |||||
encoding = null; | encoding = null; | ||||
} | } | ||||
/** | |||||
* @return true if all individual arrays are empty | |||||
* | |||||
* @since Ant 1.6 | |||||
*/ | |||||
protected final static boolean isEmpty(Resource[][] r) { | |||||
for (int i = 0; i < r.length; i++) { | |||||
if (r[i].length > 0) { | |||||
return false; | |||||
} | |||||
} | |||||
return true; | |||||
} | |||||
/** | /** | ||||
* Possible behaviors when a duplicate file is added: | * Possible behaviors when a duplicate file is added: | ||||
* "add", "preserve" or "fail" | * "add", "preserve" or "fail" | ||||
@@ -127,18 +127,22 @@ public class ZipScanner extends DirectoryScanner { | |||||
* include patterns and none of the exclude patterns. | * include patterns and none of the exclude patterns. | ||||
*/ | */ | ||||
public String[] getIncludedFiles() { | public String[] getIncludedFiles() { | ||||
Vector myvector = new Vector(); | |||||
// first check if the archive needs to be scanned again | |||||
scanme(); | |||||
for (Enumeration e = myentries.elements() ; e.hasMoreElements() ;) { | |||||
Resource myresource= (Resource) e.nextElement(); | |||||
if (!myresource.isDirectory() && match(myresource.getName())) { | |||||
myvector.addElement(myresource.getName()); | |||||
if (srcFile != null) { | |||||
Vector myvector = new Vector(); | |||||
// first check if the archive needs to be scanned again | |||||
scanme(); | |||||
for (Enumeration e = myentries.elements(); e.hasMoreElements() ;) { | |||||
Resource myresource= (Resource) e.nextElement(); | |||||
if (!myresource.isDirectory() && match(myresource.getName())) { | |||||
myvector.addElement(myresource.getName()); | |||||
} | |||||
} | } | ||||
String[] files = new String[myvector.size()]; | |||||
myvector.copyInto(files); | |||||
return files; | |||||
} else { | |||||
return super.getIncludedFiles(); | |||||
} | } | ||||
String[] files = new String[myvector.size()]; | |||||
myvector.copyInto(files); | |||||
return files; | |||||
} | } | ||||
/** | /** | ||||
@@ -150,18 +154,22 @@ public class ZipScanner extends DirectoryScanner { | |||||
* include patterns and none of the exclude patterns. | * include patterns and none of the exclude patterns. | ||||
*/ | */ | ||||
public String[] getIncludedDirectories() { | public String[] getIncludedDirectories() { | ||||
Vector myvector=new Vector(); | |||||
// first check if the archive needs to be scanned again | |||||
scanme(); | |||||
for (Enumeration e = myentries.elements() ; e.hasMoreElements() ;) { | |||||
Resource myresource= (Resource) e.nextElement(); | |||||
if (myresource.isDirectory() && match(myresource.getName())) { | |||||
myvector.addElement(myresource.getName()); | |||||
if (srcFile != null) { | |||||
Vector myvector=new Vector(); | |||||
// first check if the archive needs to be scanned again | |||||
scanme(); | |||||
for (Enumeration e = myentries.elements(); e.hasMoreElements() ;) { | |||||
Resource myresource= (Resource) e.nextElement(); | |||||
if (myresource.isDirectory() && match(myresource.getName())) { | |||||
myvector.addElement(myresource.getName()); | |||||
} | |||||
} | } | ||||
String[] files = new String[myvector.size()]; | |||||
myvector.copyInto(files); | |||||
return files; | |||||
} else { | |||||
return super.getIncludedDirectories(); | |||||
} | } | ||||
String[] files = new String[myvector.size()]; | |||||
myvector.copyInto(files); | |||||
return files; | |||||
} | } | ||||
/** | /** | ||||
@@ -205,18 +213,22 @@ public class ZipScanner extends DirectoryScanner { | |||||
* @since Ant 1.5.2 | * @since Ant 1.5.2 | ||||
*/ | */ | ||||
public Resource[] getIncludedFileResources() { | public Resource[] getIncludedFileResources() { | ||||
Vector myvector = new Vector(); | |||||
// first check if the archive needs to be scanned again | |||||
scanme(); | |||||
for (Enumeration e = myentries.elements() ; e.hasMoreElements() ;) { | |||||
Resource myresource= (Resource) e.nextElement(); | |||||
if (!myresource.isDirectory() && match(myresource.getName())) { | |||||
myvector.addElement(myresource.clone()); | |||||
if (srcFile != null) { | |||||
Vector myvector = new Vector(); | |||||
// first check if the archive needs to be scanned again | |||||
scanme(); | |||||
for (Enumeration e = myentries.elements(); e.hasMoreElements() ;) { | |||||
Resource myresource= (Resource) e.nextElement(); | |||||
if (!myresource.isDirectory() && match(myresource.getName())) { | |||||
myvector.addElement(myresource.clone()); | |||||
} | |||||
} | } | ||||
Resource[] resources = new Resource[myvector.size()]; | |||||
myvector.copyInto(resources); | |||||
return resources; | |||||
} else { | |||||
return super.getIncludedFileResources(); | |||||
} | } | ||||
Resource[] resources = new Resource[myvector.size()]; | |||||
myvector.copyInto(resources); | |||||
return resources; | |||||
} | } | ||||
/** | /** | ||||
@@ -231,18 +243,22 @@ public class ZipScanner extends DirectoryScanner { | |||||
* @since Ant 1.5.2 | * @since Ant 1.5.2 | ||||
*/ | */ | ||||
public Resource[] getIncludedDirectoryResources() { | public Resource[] getIncludedDirectoryResources() { | ||||
Vector myvector = new Vector(); | |||||
// first check if the archive needs to be scanned again | |||||
scanme(); | |||||
for (Enumeration e = myentries.elements() ; e.hasMoreElements() ;) { | |||||
Resource myresource= (Resource) e.nextElement(); | |||||
if (myresource.isDirectory() && match(myresource.getName())) { | |||||
myvector.addElement(myresource.clone()); | |||||
if (srcFile != null) { | |||||
Vector myvector = new Vector(); | |||||
// first check if the archive needs to be scanned again | |||||
scanme(); | |||||
for (Enumeration e = myentries.elements(); e.hasMoreElements() ;) { | |||||
Resource myresource= (Resource) e.nextElement(); | |||||
if (myresource.isDirectory() && match(myresource.getName())) { | |||||
myvector.addElement(myresource.clone()); | |||||
} | |||||
} | } | ||||
Resource[] resources = new Resource[myvector.size()]; | |||||
myvector.copyInto(resources); | |||||
return resources; | |||||
} else { | |||||
return super.getIncludedDirectoryResources(); | |||||
} | } | ||||
Resource[] resources = new Resource[myvector.size()]; | |||||
myvector.copyInto(resources); | |||||
return resources; | |||||
} | } | ||||
/** | /** | ||||
@@ -1,7 +1,7 @@ | |||||
/* | /* | ||||
* The Apache Software License, Version 1.1 | * The Apache Software License, Version 1.1 | ||||
* | * | ||||
* Copyright (c) 2001-2002 The Apache Software Foundation. All rights | |||||
* Copyright (c) 2001-2003 The Apache Software Foundation. All rights | |||||
* reserved. | * reserved. | ||||
* | * | ||||
* Redistribution and use in source and binary forms, with or without | * Redistribution and use in source and binary forms, with or without | ||||
@@ -55,6 +55,7 @@ | |||||
package org.apache.tools.ant; | package org.apache.tools.ant; | ||||
import org.apache.tools.ant.taskdefs.condition.Os; | import org.apache.tools.ant.taskdefs.condition.Os; | ||||
import org.apache.tools.ant.types.Resource; | |||||
import org.apache.tools.ant.util.JavaEnvUtils; | import org.apache.tools.ant.util.JavaEnvUtils; | ||||
import junit.framework.TestCase; | import junit.framework.TestCase; | ||||
@@ -186,6 +187,20 @@ public class DirectoryScannerTest extends TestCase { | |||||
assertTrue("(1) zip package included", haveZipPackage); | assertTrue("(1) zip package included", haveZipPackage); | ||||
assertTrue("(1) taskdefs package not included", !haveTaskdefsPackage); | assertTrue("(1) taskdefs package not included", !haveTaskdefsPackage); | ||||
haveZipPackage = false; | |||||
Resource[] includedResources = ds.getIncludedDirectoryResources(); | |||||
for (int i=0; i<includedResources.length; i++) { | |||||
if (includedResources[i].getName().equals("zip")) { | |||||
haveZipPackage = true; | |||||
} else if (includedResources[i].getName().equals("ant" | |||||
+ File.separator | |||||
+ "taskdefs")) { | |||||
haveTaskdefsPackage = true; | |||||
} | |||||
} | |||||
assertTrue("(1b) zip package included", haveZipPackage); | |||||
assertTrue("(1b) taskdefs package not included", !haveTaskdefsPackage); | |||||
ds = new DirectoryScanner(); | ds = new DirectoryScanner(); | ||||
ds.setBasedir(dir); | ds.setBasedir(dir); | ||||
ds.setExcludes(new String[] {"ant"}); | ds.setExcludes(new String[] {"ant"}); | ||||
@@ -202,6 +217,21 @@ public class DirectoryScannerTest extends TestCase { | |||||
assertTrue("(2) zip package included", haveZipPackage); | assertTrue("(2) zip package included", haveZipPackage); | ||||
assertTrue("(2) taskdefs package included", haveTaskdefsPackage); | assertTrue("(2) taskdefs package included", haveTaskdefsPackage); | ||||
haveZipPackage = false; | |||||
haveTaskdefsPackage = false; | |||||
includedResources = ds.getIncludedDirectoryResources(); | |||||
for (int i=0; i<includedResources.length; i++) { | |||||
if (includedResources[i].getName().equals("zip")) { | |||||
haveZipPackage = true; | |||||
} else if (includedResources[i].getName().equals("ant" | |||||
+ File.separator | |||||
+ "taskdefs")) { | |||||
haveTaskdefsPackage = true; | |||||
} | |||||
} | |||||
assertTrue("(2b) zip package included", haveZipPackage); | |||||
assertTrue("(2b) taskdefs package included", haveTaskdefsPackage); | |||||
} | } | ||||
} | } |
@@ -1,7 +1,7 @@ | |||||
/* | /* | ||||
* The Apache Software License, Version 1.1 | * The Apache Software License, Version 1.1 | ||||
* | * | ||||
* Copyright (c) 2000-2002 The Apache Software Foundation. All rights | |||||
* Copyright (c) 2000-2003 The Apache Software Foundation. All rights | |||||
* reserved. | * reserved. | ||||
* | * | ||||
* Redistribution and use in source and binary forms, with or without | * Redistribution and use in source and binary forms, with or without | ||||
@@ -85,9 +85,9 @@ public class ZipTest extends BuildFileTest { | |||||
expectBuildException("test3", "zip cannot include itself"); | expectBuildException("test3", "zip cannot include itself"); | ||||
} | } | ||||
public void test4() { | |||||
expectBuildException("test4", "zip cannot include itself"); | |||||
} | |||||
// public void test4() { | |||||
// expectBuildException("test4", "zip cannot include itself"); | |||||
// } | |||||
public void tearDown() { | public void tearDown() { | ||||
executeTarget("cleanup"); | executeTarget("cleanup"); | ||||