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"); | ||||