Hi,
I made a patch to add "deleteDestFiles" attribute to Copy task.
This is useful to clean up files made by a copy task with a nested
mapper element.
Without this patch, you must list up files to delete in filesets.
For example:
<target name="filter">
<filter filtersfile="some_filter.properties"/>
<copy todir="." filtering="true" overwrite="false">
<fileset dir=".">
<include name="**/*.tmpl"/>
</fileset>
<mapper type="glob" from="*.tmpl" to="*"/>
</copy>
</target>
<target name="clean_filter">
<delete>
<fileset dir=".">
<include name="foo.txt"/>
<include name="bar/baz.xml"/>
</fileset>
</delete>
</target>
It is tedious to maintain those file lists.
With this patch, you can write the "clean_filter" target like this:
<target name="clean_filter">
<copy todir="." deleteDestFiles="true">
<fileset dir=".">
<include name="**/*.tmpl"/>
</fileset>
<mapper type="glob" from="*.tmpl" to="*"/>
</copy>
</target>
Here I explain why I added this feature to the copy task, not the
delete task.
- To avoid complicating the delete task.
If the delete task has this feature, it must have the source
and destination directory attributes and a nested mapper
element. With those, it is not easy to understand the usage of
the delete task at glance.
- Easier to implement this feature in the copy task.
Since the copy task already have the logic on mapping source
and destination files, the modification is smaller.
I hope this patch is useful and applied in the future release.
---
)Hiroaki Nakamura) [EMAIL PROTECTED]
--- Copy.java.orig Thu Oct 11 13:58:30 2001
+++ Copy.java Sat Jan 19 18:59:21 2002
@@ -87,6 +87,7 @@
protected boolean flatten = false;
protected int verbosity = Project.MSG_VERBOSE;
protected boolean includeEmpty = true;
+ protected boolean deleteDestFiles = false;
protected Hashtable fileCopyMap = new Hashtable();
protected Hashtable dirCopyMap = new Hashtable();
@@ -162,6 +163,13 @@
}
/**
+ * Set deleteDestFiles flag.
+ */
+ public void setDeleteDestFiles(boolean deleteDestFiles) {
+ this.deleteDestFiles = deleteDestFiles;
+ }
+
+ /**
* When copying directory trees, the files can be "flattened"
* into a single directory. If there are multiple files with
* the same name in the source directory tree, only the first
@@ -223,7 +231,7 @@
destFile = new File(destDir, file.getName());
}
- if (forceOverwrite ||
+ if (forceOverwrite || deleteDestFiles ||
(file.lastModified() > destFile.lastModified())) {
fileCopyMap.put(file.getAbsolutePath(),
destFile.getAbsolutePath());
} else {
@@ -250,7 +258,7 @@
scan(fromDir, destDir, srcFiles, srcDirs);
}
- // do all the copy operations now...
+ // do all the copy or delete operations now...
doFileOperations();
// clean up destDir again - so this instance can be used a second
@@ -321,7 +329,7 @@
FileNameMapper mapper, Hashtable map) {
String[] toCopy = null;
- if (forceOverwrite) {
+ if (forceOverwrite || deleteDestFiles) {
Vector v = new Vector();
for (int i=0; i<names.length; i++) {
if (mapper.mapFileName(names[i]) != null) {
@@ -343,10 +351,22 @@
}
/**
- * Actually does the file (and possibly empty directory) copies.
+ * Actually does the file operation.
* This is a good method for subclasses to override.
*/
protected void doFileOperations() {
+ if (deleteDestFiles) {
+ doDeleteDestFiles();
+ } else {
+ doCopyFiles();
+ }
+ }
+
+ /**
+ * Actually does the file (and possibly empty directory) copies.
+ * This is a good method for subclasses to override.
+ */
+ protected void doCopyFiles() {
if (fileCopyMap.size() > 0) {
log("Copying " + fileCopyMap.size() +
" file" + (fileCopyMap.size() == 1 ? "" : "s") +
@@ -401,6 +421,43 @@
" empty director" +
(count==1?"y":"ies") +
" to " + destDir.getAbsolutePath());
+ }
+ }
+ }
+
+ /**
+ * Actually deletes the destination files.
+ * This is a good method for subclasses to override.
+ */
+ protected void doDeleteDestFiles() {
+ if (fileCopyMap.size() > 0) {
+ log("Deleting " + fileCopyMap.size() +
+ " file" + (fileCopyMap.size() == 1 ? "" : "s") );
+
+ Enumeration e = fileCopyMap.keys();
+ while (e.hasMoreElements()) {
+ String fromFile = (String) e.nextElement();
+ String toFile = (String) fileCopyMap.get(fromFile);
+
+ if( fromFile.equals( toFile ) ) {
+ log("Skipping delete of " + fromFile, verbosity);
+ continue;
+ }
+
+ try {
+ log("Deleting " + toFile, verbosity);
+ File toFileObj = new File(toFile);
+ if (toFileObj.exists()) {
+ boolean deleted = toFileObj.delete();
+ if (!deleted) {
+ throw new IOException("unknown reason delete
failure");
+ }
+ }
+ } catch (IOException ioe) {
+ String msg = "Failed to delete " + toFile
+ + " due to " + ioe.getMessage();
+ throw new BuildException(msg, ioe, location);
+ }
}
}
}
--
To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>