From 5a381558aef54280f925781bed3d4c9ba7ced360 Mon Sep 17 00:00:00 2001
From: Stefan Bodewig overwrite
attribute.
Resource
-Collections are used to select a group of files to copy. Only
-file system based resource collections are supported, this includes filesets, filelist and path. To use a resource collection, the
-todir
attribute must be set.
todir
attribute must be set.
Note: If you employ filters in your copy operation, you should @@ -144,7 +140,7 @@ operation as filtersets
Resource
Collections are used to select groups of files to copy. To use a
resource collection, the todir
attribute must be set.
Synchronize a target directory from the files defined in one or -more filesystem based Resource Collections.
+more Resource Collections.Any file in the target directory that has not been matched by at -least one of the nested resource collection gets removed. I.e. if you exclude a +least one of the nested resource collections gets removed. I.e. if you exclude a file in your sources and a file of that name is present in the target dir, it will get removed from the target.
@@ -72,7 +72,7 @@ dir, it will get removed from the target.Resource
Collections are used to select groups of files to copy. To use a
resource collection, the todir
attribute must be set.
FileNameMapper
value.
+ * @return a map of source resource to array of destination files.
+ * @since Ant 1.7
+ */
+ protected Map buildMap(Resource[] fromResources, final File toDir,
+ FileNameMapper mapper) {
+ HashMap map = new HashMap();
+ Resource[] toCopy = null;
+ if (forceOverwrite) {
+ Vector v = new Vector();
+ for (int i = 0; i < fromResources.length; i++) {
+ if (mapper.mapFileName(fromResources[i].getName()) != null) {
+ v.addElement(fromResources[i]);
+ }
+ }
+ toCopy = new Resource[v.size()];
+ v.copyInto(toCopy);
+ } else {
+ toCopy =
+ ResourceUtils.selectOutOfDateSources(this, fromResources,
+ mapper,
+ new ResourceFactory() {
+ public Resource getResource(String name) {
+ return new FileResource(toDir, name);
+ }
+ },
+ granularity);
+ }
+ for (int i = 0; i < toCopy.length; i++) {
+ String[] mappedFiles = mapper.mapFileName(toCopy[i].getName());
+
+ if (!enableMultipleMappings) {
+ map.put(toCopy[i],
+ new String[] {new File(toDir, mappedFiles[0]).getAbsolutePath()});
+ } else {
+ // reuse the array created by the mapper
+ for (int k = 0; k < mappedFiles.length; k++) {
+ mappedFiles[k] = new File(toDir, mappedFiles[k]).getAbsolutePath();
+ }
+ map.put(toCopy[i], mappedFiles);
+ }
+ }
+ return map;
+ }
+
/**
* Actually does the file (and possibly empty directory) copies.
* This is a good method for subclasses to override.
@@ -738,6 +833,84 @@ public class Copy extends Task {
}
}
+ /**
+ * Actually does the resource copies.
+ * This is a good method for subclasses to override.
+ * @param map a map of source resource to array of destination files.
+ * @since Ant 1.7
+ */
+ protected void doResourceOperations(Map map) {
+ if (map.size() > 0) {
+ log("Copying " + map.size()
+ + " resource" + (map.size() == 1 ? "" : "s")
+ + " to " + destDir.getAbsolutePath());
+
+ Iterator iter = map.keySet().iterator();
+ while (iter.hasNext()) {
+ Resource fromResource = (Resource) iter.next();
+ String[] toFiles = (String[]) map.get(fromResource);
+
+ for (int i = 0; i < toFiles.length; i++) {
+ String toFile = toFiles[i];
+
+ try {
+ log("Copying " + fromResource + " to " + toFile,
+ verbosity);
+
+ FilterSetCollection executionFilters =
+ new FilterSetCollection();
+ if (filtering) {
+ executionFilters
+ .addFilterSet(getProject().getGlobalFilterSet());
+ }
+ for (Enumeration filterEnum = filterSets.elements();
+ filterEnum.hasMoreElements();) {
+ executionFilters
+ .addFilterSet((FilterSet) filterEnum.nextElement());
+ }
+ ResourceUtils.copyResource(fromResource,
+ new FileResource(destDir,
+ toFile),
+ executionFilters,
+ filterChains,
+ forceOverwrite,
+ preserveLastModified,
+ inputEncoding,
+ outputEncoding,
+ getProject());
+ } catch (IOException ioe) {
+ String msg = "Failed to copy " + fromResource
+ + " to " + toFile
+ + " due to " + ioe.getMessage();
+ File targetFile = new File(toFile);
+ if (targetFile.exists() && !targetFile.delete()) {
+ msg += " and I couldn't delete the corrupt " + toFile;
+ }
+ throw new BuildException(msg, ioe, getLocation());
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Whether this task can deal with non-file resources.
+ *
+ * <copy> can while <move> can't since we don't + * know how to remove non-file resources.
+ * + *This implementation returns true only if this task is + * <copy>. Any subclass of this class that also wants to + * support non-file resources needs to override this method. We + * need to do so for backwards compatibility reasons since we + * can't expect subclasses to support resources.
+ * + * @since Ant 1.7 + */ + protected boolean supportsNonFileResources() { + return getClass().equals(Copy.class); + } + /** * Adds the given strings to a list contained in the given map. * The file is the key into the map. @@ -770,4 +943,21 @@ public class Copy extends Task { private static File getKeyFile(File f) { return f == null ? NULL_FILE_PLACEHOLDER : f; } + + /** + * returns the mapper to use based on nested elements or the + * flatten attribute. + */ + private FileNameMapper getMapper() { + FileNameMapper mapper = null; + if (mapperElement != null) { + mapper = mapperElement.getImplementation(); + } else if (flatten) { + mapper = new FlatFileNameMapper(); + } else { + mapper = new IdentityMapper(); + } + return mapper; + } + } diff --git a/src/main/org/apache/tools/ant/taskdefs/Sync.java b/src/main/org/apache/tools/ant/taskdefs/Sync.java index 17cc14836..15e3b87c7 100644 --- a/src/main/org/apache/tools/ant/taskdefs/Sync.java +++ b/src/main/org/apache/tools/ant/taskdefs/Sync.java @@ -26,6 +26,8 @@ package org.apache.tools.ant.taskdefs; import java.io.File; import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; import java.util.Set; import org.apache.tools.ant.BuildException; @@ -35,6 +37,7 @@ import org.apache.tools.ant.Task; import org.apache.tools.ant.types.AbstractFileSet; import org.apache.tools.ant.types.FileSet; import org.apache.tools.ant.types.PatternSet; +import org.apache.tools.ant.types.Resource; import org.apache.tools.ant.types.ResourceCollection; import org.apache.tools.ant.types.selectors.FileSelector; import org.apache.tools.ant.types.selectors.NoneSelector; @@ -384,6 +387,21 @@ public class Sync extends Task { } } + /** + * @see Copy#scan(Resource[], File) + */ + protected Map scan(Resource[] resources, File toDir) { + assertTrue("No mapper", mapperElement == null); + + Map m = super.scan(resources, toDir); + + Iterator iter = m.keySet().iterator(); + while (iter.hasNext()) { + nonOrphans.add(((Resource) iter.next()).getName()); + } + return m; + } + /** * Get the destination directory. * @return the destination directory @@ -400,6 +418,13 @@ public class Sync extends Task { return includeEmpty; } + /** + * Yes, we can. + * @since Ant 1.7 + */ + protected boolean supportsNonFileResources() { + return true; + } } /** diff --git a/src/testcases/org/apache/tools/ant/taskdefs/CopyTest.java b/src/testcases/org/apache/tools/ant/taskdefs/CopyTest.java index 16e648a96..687fe6a38 100644 --- a/src/testcases/org/apache/tools/ant/taskdefs/CopyTest.java +++ b/src/testcases/org/apache/tools/ant/taskdefs/CopyTest.java @@ -197,6 +197,16 @@ public class CopyTest extends BuildFileTest { assertTrue(file3.exists()); } + public void testZipfileset() { + executeTarget("testZipfileset"); + File file1 = new File(getProjectDir(), getProject().getProperty("to.dir")+"/file1.txt"); + File file2 = new File(getProjectDir(), getProject().getProperty("to.dir")+"/file2.txt"); + File file3 = new File(getProjectDir(), getProject().getProperty("to.dir")+"/file3.txt"); + assertTrue(file1.exists()); + assertTrue(file2.exists()); + assertTrue(file3.exists()); + } + public void _testResourcePlain() { executeTarget("testResourcePlain"); } diff --git a/src/testcases/org/apache/tools/ant/taskdefs/SyncTest.java b/src/testcases/org/apache/tools/ant/taskdefs/SyncTest.java index 30aa99b20..5fffdacc2 100644 --- a/src/testcases/org/apache/tools/ant/taskdefs/SyncTest.java +++ b/src/testcases/org/apache/tools/ant/taskdefs/SyncTest.java @@ -67,6 +67,10 @@ public class SyncTest extends BuildFileTest { testCopyAndRemove("copyandremove-with-filelist"); } + public void testCopyAndRemoveWithZipfileset() { + testCopyAndRemove("copyandremove-with-zipfileset"); + } + private void testCopyAndRemove(String target) { executeTarget(target); String d = getProject().getProperty("dest") + "/a/b/c/d";