From a4c986354481641bc4b9811854fefaf2fec7f86a Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Wed, 15 Jul 2009 13:09:00 +0000 Subject: [PATCH] don't compare timestamps on directories but add missing dirs git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@794255 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/tools/ant/taskdefs/Zip.java | 115 +++++++++++++++--- .../apache/tools/ant/util/ResourceUtils.java | 56 +++++++-- src/tests/antunit/taskdefs/zip-test.xml | 3 +- 3 files changed, 144 insertions(+), 30 deletions(-) diff --git a/src/main/org/apache/tools/ant/taskdefs/Zip.java b/src/main/org/apache/tools/ant/taskdefs/Zip.java index 348c581f1..c05303f21 100644 --- a/src/main/org/apache/tools/ant/taskdefs/Zip.java +++ b/src/main/org/apache/tools/ant/taskdefs/Zip.java @@ -26,6 +26,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.Enumeration; @@ -52,7 +53,9 @@ import org.apache.tools.ant.types.ZipScanner; import org.apache.tools.ant.types.resources.ArchiveResource; import org.apache.tools.ant.types.resources.FileProvider; import org.apache.tools.ant.types.resources.FileResource; +import org.apache.tools.ant.types.resources.Union; import org.apache.tools.ant.types.resources.ZipResource; +import org.apache.tools.ant.types.resources.selectors.ResourceSelector; import org.apache.tools.ant.util.FileNameMapper; import org.apache.tools.ant.util.FileUtils; import org.apache.tools.ant.util.GlobPatternMapper; @@ -99,6 +102,21 @@ public class Zip extends MatchingTask { protected Hashtable addedDirs = new Hashtable(); private Vector addedFiles = new Vector(); + private static final ResourceSelector MISSING_SELECTOR = + new ResourceSelector() { + public boolean isSelected(Resource target) { + return !target.isExists(); + } + }; + + private static final ResourceUtils.ResourceSelectorProvider + MISSING_DIR_PROVIDER = new ResourceUtils.ResourceSelectorProvider() { + public ResourceSelector + getTargetSelectorForSource(Resource sr) { + return MISSING_SELECTOR; + } + }; + /** * If this flag is true, execute() will run most operations twice, * the first time with {@link #skipWriting skipWriting} set to @@ -1353,15 +1371,29 @@ public class Zip extends MatchingTask { } } - Resource[] resources = initialResources[i]; - if (doFilesonly) { - resources = selectFileResources(resources); - } + Resource[] resources = selectFileResources(initialResources[i]); newerResources[i] = ResourceUtils.selectOutOfDateSources(this, resources, myMapper, getZipScanner()); + if (!doFilesonly) { + Union u = new Union(); + u.addAll(Arrays + .asList(selectDirectoryResources(initialResources[i]))); + ResourceCollection rc = + ResourceUtils.selectSources(this, u, + myMapper, + getZipScanner(), + MISSING_DIR_PROVIDER); + if (rc.size() > 0) { + ArrayList newer = new ArrayList(); + newer.addAll(Arrays.asList(((Union) rc).listResources())); + newer.addAll(Arrays.asList(newerResources[i])); + newerResources[i] = + (Resource[]) newer.toArray(newerResources[i]); + } + } needsUpdate = needsUpdate || (newerResources[i].length > 0); if (needsUpdate && !doUpdate) { @@ -1445,15 +1477,29 @@ public class Zip extends MatchingTask { } } - Resource[] rs = initialResources[i]; - if (doFilesonly) { - rs = selectFileResources(rs); - } + Resource[] rs = selectFileResources(initialResources[i]); newerResources[i] = ResourceUtils.selectOutOfDateSources(this, rs, new IdentityMapper(), getZipScanner()); + if (!doFilesonly) { + Union u = new Union(); + u.addAll(Arrays + .asList(selectDirectoryResources(initialResources[i]))); + ResourceCollection rc = + ResourceUtils.selectSources(this, u, + new IdentityMapper(), + getZipScanner(), + MISSING_DIR_PROVIDER); + if (rc.size() > 0) { + ArrayList newer = new ArrayList(); + newer.addAll(Arrays.asList(((Union) rc).listResources())); + newer.addAll(Arrays.asList(newerResources[i])); + newerResources[i] = + (Resource[]) newer.toArray(newerResources[i]); + } + } needsUpdate = needsUpdate || (newerResources[i].length > 0); if (needsUpdate && !doUpdate) { @@ -1912,25 +1958,60 @@ public class Zip extends MatchingTask { * @since Ant 1.6 */ protected Resource[] selectFileResources(Resource[] orig) { + return selectResources(orig, + new ResourceSelector() { + public boolean isSelected(Resource r) { + if (!r.isDirectory()) { + return true; + } else if (doFilesonly) { + logOnFirstPass("Ignoring directory " + + r.getName() + + " as only files will" + + " be added.", + Project.MSG_VERBOSE); + } + return false; + } + }); + } + + /** + * Drops all non-directory resources from the given array. + * @param orig the resources to filter + * @return the filters resources + * @since Ant 1.8.0 + */ + protected Resource[] selectDirectoryResources(Resource[] orig) { + return selectResources(orig, + new ResourceSelector() { + public boolean isSelected(Resource r) { + return r.isDirectory(); + } + }); + } + + /** + * Drops all resources from the given array that are not selected + * @param orig the resources to filter + * @return the filters resources + * @since Ant 1.8.0 + */ + protected Resource[] selectResources(Resource[] orig, + ResourceSelector selector) { if (orig.length == 0) { return orig; } - Vector v = new Vector(orig.length); + ArrayList v = new ArrayList(orig.length); for (int i = 0; i < orig.length; i++) { - if (!orig[i].isDirectory()) { - v.addElement(orig[i]); - } else { - logOnFirstPass("Ignoring directory " + orig[i].getName() - + " as only files will be added.", - Project.MSG_VERBOSE); + if (selector.isSelected(orig[i])) { + v.add(orig[i]); } } if (v.size() != orig.length) { Resource[] r = new Resource[v.size()]; - v.copyInto(r); - return r; + return (Resource[]) v.toArray(r); } return orig; } diff --git a/src/main/org/apache/tools/ant/util/ResourceUtils.java b/src/main/org/apache/tools/ant/util/ResourceUtils.java index 8d5d1583d..7f821a2f6 100644 --- a/src/main/org/apache/tools/ant/util/ResourceUtils.java +++ b/src/main/org/apache/tools/ant/util/ResourceUtils.java @@ -130,12 +130,51 @@ public class ResourceUtils { FileNameMapper mapper, ResourceFactory targets, final long granularity) { + logFuture(logTo, source, granularity); + ResourceSelectorProvider p = + new ResourceSelectorProvider() { + public ResourceSelector + getTargetSelectorForSource(final Resource sr) { + return new ResourceSelector() { + public boolean isSelected(Resource target) { + /* Extra I/O, probably wasted: + if (target.isDirectory()) { + return false; + } + */ + return SelectorUtils.isOutOfDate(sr, target, + granularity); + } + }; + } + }; + return selectSources(logTo, source, mapper, targets, p); + } + + /** + * Tells which sources should be reprocessed because the given + * selector selects at least one target. + * + * @param logTo where to send (more or less) interesting output. + * @param source ResourceCollection. + * @param mapper filename mapper indicating how to find the target Resources. + * @param targets object able to map a relative path as a Resource. + * @param selector returns a selector that is applied to target + * files. If it selects at least one target the source will be + * added to the returned collection. + * @return ResourceCollection. + * @since Ant 1.8.0 + */ + public static ResourceCollection selectSources(ProjectComponent logTo, + ResourceCollection source, + FileNameMapper mapper, + ResourceFactory targets, + ResourceSelectorProvider selector) { if (source.size() == 0) { logTo.log("No sources found.", Project.MSG_VERBOSE); return Resources.NONE; } source = Union.getInstance(source); - logFuture(logTo, source, granularity); Union result = new Union(); for (Iterator iter = source.iterator(); iter.hasNext();) { @@ -168,16 +207,7 @@ public class ResourceUtils { } //find the out-of-date targets: Restrict r = new Restrict(); - r.add(new ResourceSelector() { - public boolean isSelected(Resource target) { - /* Extra I/O, probably wasted: - if (target.isDirectory()) { - return false; - } - */ - return SelectorUtils.isOutOfDate(sr, target, granularity); - } - }); + r.add(selector.getTargetSelectorForSource(sr)); r.add(targetColl); if (r.size() > 0) { result.add(sr); @@ -639,4 +669,8 @@ public class ResourceUtils { } return resource.getOutputStream(); } + + public static interface ResourceSelectorProvider { + ResourceSelector getTargetSelectorForSource(Resource source); + } } diff --git a/src/tests/antunit/taskdefs/zip-test.xml b/src/tests/antunit/taskdefs/zip-test.xml index 7edcaf640..6f0d77c0e 100644 --- a/src/tests/antunit/taskdefs/zip-test.xml +++ b/src/tests/antunit/taskdefs/zip-test.xml @@ -86,9 +86,8 @@ - -