Index: docs/index.html
===================================================================
RCS file: /home/cvspublic/jakarta-ant/docs/index.html,v
retrieving revision 1.94
diff -u -r1.94 index.html
--- docs/index.html	2000/09/07 11:08:59	1.94
+++ docs/index.html	2000/09/08 21:08:34
@@ -828,6 +828,7 @@
   <li><a href="#antstructure">AntStructure</a></li>
   <li><a href="#available">Available</a></li>
   <li><a href="#chmod">Chmod</a></li>
+  <li><a href="#copy">Copy</a></li>
   <li><a href="#copydir">Copydir</a></li>
   <li><a href="#copyfile">Copyfile</a></li>
   <li><a href="#cvs">Cvs</a></li>
@@ -848,6 +849,7 @@
   <li><a href="#javac">Javac</a></li>
   <li><a href="#javadoc">Javadoc/Javadoc2</a></li>
   <li><a href="#mkdir">Mkdir</a></li>
+  <li><a href="#move">Move</a></li>
   <li><a href="#patch">Patch</a></li>
   <li><a href="#property">Property</a></li>
   <li><a href="#rename">Rename</a></li>
@@ -1097,6 +1099,88 @@
 with <code>id</code> <code>other.shared.sources</code> get the same
 permissions.</p>
 <hr>
+<h2><a name="copy">Copy</a></h2>
+<h3>Description</h3>
+<p>Copies a file or directory to a new file or directory.  Files are
+only copied if the source file is newer than the destination file,
+or when the destination file does not exist.  However, you can explicitly 
+overwrite files with the <var>overwrite</var> attribute.</p>
+<p><a href="#fileset">FileSet</a>s are used to select files to copy.  
+To use a fileset, the <var>todir</var> attribute must be set.</p>
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+  <tr>
+    <td valign="top"><b>Attribute</b></td>
+    <td valign="top"><b>Description</b></td>
+    <td align="center" valign="top"><b>Required</b></td>
+  </tr>
+  <tr>
+    <td valign="top">file</td>
+    <td valign="top">the file to copy</td>
+    <td valign="top" align="center" rowspan="2">One of <var>file</var> or 
+    <var>dir</var> are required, or a nested fileset element</td>
+  </tr>
+  <tr>
+    <td valign="top">dir</td>
+    <td valign="top">the directory to copy</td>
+  </tr>
+  <tr>
+    <td valign="top">tofile</td>
+    <td valign="top">the file to copy to</td>
+    <td valign="top" align="center" rowspan="2">With the <var>file</var> attribute, 
+    either <var>tofile</var> or <var>todir</var> can be used.  With the <var>dir</var>
+    attribute and nested filesets, only <var>todir</var> is allowed.</td>
+  </tr>
+  <tr>
+    <td valign="top">todir</td>
+    <td valign="top">the directory to copy to</td>
+  </tr>
+  <tr>
+    <td valign="top">overwrite</td>
+    <td valign="top">overwrite existing files even if the destination
+      files are newer (default is false)</td>
+    <td valign="top" align="center">No</td>
+  </tr>
+  <tr>
+    <td valign="top">filtering</td>
+    <td valign="top">indicates whether token filtering should take place during
+      the copy</td>
+    <td valign="top" align="center">No</td>
+  </tr>
+  <tr>
+    <td valign="top">flatten</td>
+    <td valign="top">ignore directory structure of source directory,
+      copy all files into a single directory, specified by the <var>todir</var>
+      attribute (default is false).</td>
+    <td valign="top" align="center">No</td>
+  </tr>
+</table>
+<h3>Examples</h3>
+<p><b>Copy a single file</b></p>
+<pre>
+  &lt;copy file=&quot;myfile.txt&quot; tofile=&quot;mycopy.txt&quot; /&gt;
+</pre>
+<p><b>Copy a file to a directory</b></p>
+<pre>
+  &lt;copy file=&quot;myfile.txt&quot; todir=&quot;../some/dir/tree&quot; /&gt;
+</pre>
+<p><b>Copy a directory to another directory</b></p>
+<pre>
+  &lt;copy dir=&quot;src_dir&quot; todir=&quot;../new/dir&quot; /&gt;
+</pre>
+<p><b>Copy a set of files to a directory</b></p>
+<pre>
+  &lt;copy todir=&quot;../dest/dir&quot; &gt;
+    &lt;fileset dir=&quot;src_dir&quot &gt;
+      &lt;exclude name=&quot;**/*.java&quot; /&gt;
+    &lt;/fileset&gt;
+  &lt;/copy&gt;
+
+  &lt;copy todir=&quot;../dest/dir&quot; &gt;
+    &lt;fileset dir=&quot;src_dir&quot excludes=&quot;**/*.java&quot; /&gt;
+  &lt;/copy&gt;
+</pre>
+<hr>
 <h2><a name="copydir">Copydir</a></h2>
 <h3>Description</h3>
 <p>Copies a directory tree from the source to the destination.</p>
@@ -1311,21 +1395,9 @@
 <hr>
 <h2><a name="delete">Delete</a></h2>
 <h3>Description</h3>
-<p>Deletes either a single file or
-all files in a specified directory and its sub-directories.</p>
-<p>It is possible to refine the set of files that are being deleted. This can be
-done with the <i>includes</i>, <i>includesfile</i>, <i>excludes</i>, <i>excludesfile</i> and <i>defaultexcludes</i>
-attributes. With the <i>includes</i> or <i>includesfile</i> attribute you specify the files you want to
-have included in the deletion process by using patterns. The <i>exclude</i> or <i>excludesfile</i> attribute is used to specify
-the files you want to have excluded from the deletion process. This is also done with patterns. And
-finally with the <i>defaultexcludes</i> attribute, you can specify whether you
-want to use default exclusions or not. See the section on <a
-href="#directorybasedtasks">directory based tasks</a>, on how the
-inclusion/exclusion of files works, and how to write patterns.</p>
-<p>This task forms an implicit <a href="#fileset">FileSet</a> and
-supports all attributes of <code>&lt;fileset&gt;</code> as well as the
-nested <code>&lt;include&gt;</code>, <code>&lt;exclude&gt;</code> and
-<code>&lt;patternset&gt;</code> elements.</p>
+<p>Deletes either a single file, all files in a specified directory and its 
+sub-directories, or a set of files specified by a <a href="#fileset">FileSet</a>.
+When specifying a set of files, empty directories are <em>not</em> removed.</p>
 <h3>Parameters</h3>
 <table border="1" cellpadding="2" cellspacing="0">
   <tr>
@@ -1335,58 +1407,38 @@
   </tr>
   <tr>
     <td valign="top">file</td>
-    <td valign="top">The file to delete.</td>
-    <td align="center" valign="middle" rowspan="2">at least one of the two</td>
+    <td valign="top">the file to delete</td>
+    <td align="center" valign="middle" rowspan="2">at least one of the two, or
+    at least one nested FileSet</td>
   </tr>
   <tr>
     <td valign="top">dir</td>
-    <td valign="top">The directory to delete files from.</td>
-  </tr>
-  <tr>
-    <td valign="top">includes</td>
-    <td valign="top">Comma separated list of patterns of files that must be
-      deleted. All files are in the current directory 
-      and any sub-directories are deleted when omitted.</td>
-    <td valign="top" align="center">No</td>
-  </tr>
-  <tr>
-    <td valign="top">includesfile</td>
-    <td valign="top">the name of a file. Each line of this file is
-      taken to be an include pattern</td>
-    <td valign="top" align="center">No</td>
+    <td valign="top">the directory to delete files from</td>
   </tr>
   <tr>
-    <td valign="top">excludes</td>
-    <td valign="top">Comma separated list of patterns of files that must be
-      excluded from the deletion list. No files (except default excludes) are excluded when omitted.</td>
-    <td valign="top" align="center">No</td>
-  </tr>
-  <tr>
-    <td valign="top">excludesfile</td>
-    <td valign="top">the name of a file. Each line of this file is
-      taken to be an exclude pattern</td>
-    <td valign="top" align="center">No</td>
-  </tr>
-  <tr>
-    <td valign="top">defaultexcludes</td>
-    <td valign="top">Indicates whether default excludes should be used or not
-      (&quot;yes&quot;/&quot;no&quot;). Default excludes are used when omitted.</td>
-    <td valign="top" align="center">No</td>
-  </tr>
-  <tr>
     <td valign="top">verbose</td>
-    <td valign="top">Show name of each deleted file (&quot;true&quot;/&quot;false&quot;). Default is "false" when omitted.</td>
+    <td valign="top">show the name of each deleted file (&quot;true&quot;/&quot;false&quot;). 
+    Default is "false".</td>
     <td align="center" valign="top">No</td>
   </tr>
 </table>
 <h3>Examples</h3>
-<pre>  &lt;delete file=&quot;/lib/ant.jar&quot; /&gt;</pre>
+<p><b>Delete a single file</b></p>
+<pre>
+  &lt;delete file=&quot;/lib/ant.jar&quot; /&gt;
+</pre>
 <p>deletes the file <code>/lib/ant.jar</code>.</p>
-<pre>  &lt;delete dir=&quot;lib&quot; /&gt;</pre>
-<p>deletes all files in the <code>/lib</code> directory.</p>
-<pre>  &lt;delete dir=&quot;.&quot;
-          includes=&quot;**/*.bak&quot;
-  /&gt;
+<p><b>Delete a directory</b></p>
+<pre>
+  &lt;delete dir=&quot;lib&quot; /&gt;
+</pre>
+<p>deletes all files in the <code>lib</code> directory, and the 
+directory itself.</p>
+<p><b>Delete a set of files</b></p>
+<pre>
+  &lt;delete &gt;
+    &lt;fileset dir=&quot;.&quot; includes=&quot;**/*.bak&quot; /&gt;
+  &lt;/delete&gt;
 </pre>
 <p>deletes all files with the extension &quot;<code>.bak</code>&quot from the current directory 
 and any sub-directories.</p>
@@ -2954,6 +3006,88 @@
 <p>creates a directory <code>${dist}</code>.</p>
 <pre>&lt;mkdir dir=&quot;${dist}/lib&quot; /&gt;</pre>
 <p>creates a directory <code>${dist}/lib</code>.</p>
+<hr>
+<h2><a name="move">Move</a></h2>
+<h3>Description</h3>
+<p>Moves a file or directory to a new file or directory, or sets of files to
+a new directory.  By default, the
+destination file is overwritten if it already exists.  When <var>overwrite</var> is
+turned off, then files are only moved if the source file is newer than
+the destination file, or when the destination file does not exist.</p>
+<p><a href="#fileset">FileSet</a>s are used to select sets of files
+to move to the <var>todir</var> directory.</p>
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+  <tr>
+    <td valign="top"><b>Attribute</b></td>
+    <td valign="top"><b>Description</b></td>
+    <td align="center" valign="top"><b>Required</b></td>
+  </tr>
+  <tr>
+    <td valign="top">file</td>
+    <td valign="top">the file to move</td>
+    <td valign="top" align="center" rowspan="2">One of <var>file</var> or 
+    <var>dir</var> are required, or at least one nested fileset element</td>
+  </tr>
+  <tr>
+    <td valign="top">dir</td>
+    <td valign="top">the directory to move</td>
+  </tr>
+  <tr>
+    <td valign="top">tofile</td>
+    <td valign="top">the file to move to</td>
+    <td valign="top" align="center" rowspan="2">With the <var>file</var> attribute, 
+    either <var>tofile</var> or <var>todir</var> can be used.  With the <var>dir</var>
+    attribute or a nested fileset, only <var>todir</var> is allowed.</td>
+  </tr>
+  <tr>
+    <td valign="top">todir</td>
+    <td valign="top">the directory to move to</td>
+  </tr>
+  <tr>
+    <td valign="top">overwrite</td>
+    <td valign="top">overwrite existing files even if the destination
+      files are newer (default is &quot;true&quot;)</td>
+    <td valign="top" align="center">No</td>
+  </tr>
+  <tr>
+    <td valign="top">filtering</td>
+    <td valign="top">indicates whether token filtering should take place during
+      the move.  See the <a href="#filter">filter</a> task for a description of
+      how filters work.</td>
+    <td valign="top" align="center">No</td>
+  </tr>
+  <tr>
+    <td valign="top">flatten</td>
+    <td valign="top">ignore directory structure of source directory,
+      copy all files into a single directory, specified by the <var>todir</var>
+      attribute (default is &quot;false&quot;).</td>
+    <td valign="top" align="center">No</td>
+  </tr>
+</table>
+<h3>Examples</h3>
+<p><b>Move a single file</b></p>
+<pre>
+  &lt;move file=&quot;file.orig&quot; tofile=&quot;file.moved&quot; /&gt;
+</pre>
+<p><b>Move a single file to a directory</b></p>
+<pre>
+  &lt;move file=&quot;file.orig&quot; todir=&quot;dir/to/move/to&quot; /&gt;
+</pre>
+<p><b>Move a directory to a new directory</b></p>
+<pre>
+  &lt;move dir=&quot;src/dir&quot; todir=&quot;new/dir/to/move/to&quot; /&gt;
+</pre>
+<p>Note that the directory src/dir will be removed.</p>
+<p><b>Move a set of files to a new directory</b></p>
+<pre>
+  &lt;move todir=&quot;some/new/dir&quot; &gt;
+    &lt;fileset dir=&quot;my/src/dir&quot; &gt;
+      &lt;include name=&quot;**/*.jar&quot; /&gt;
+      &lt;exclude name=&quot;**/ant.jar&quot; /&gt;
+    &lt;/fileset&gt;
+  &lt;/move&gt;
+</pre>
 <hr>
 <h2><a name="patch">Patch</a></h2>
 <h3>Description</h3>
Index: src/main/org/apache/tools/ant/taskdefs/Delete.java
===================================================================
RCS file: /home/cvspublic/jakarta-ant/src/main/org/apache/tools/ant/taskdefs/Delete.java,v
retrieving revision 1.6
diff -u -r1.6 Delete.java
--- src/main/org/apache/tools/ant/taskdefs/Delete.java	2000/07/06 16:48:14	1.6
+++ src/main/org/apache/tools/ant/taskdefs/Delete.java	2000/09/08 21:08:37
@@ -54,26 +54,35 @@
 package org.apache.tools.ant.taskdefs;
 
 import org.apache.tools.ant.*;
+import org.apache.tools.ant.types.*;
 import java.io.*;
+import java.util.*;
 
 /**
- * Deletes a single file or a set of files defined by a pattern.
+ * Deletes a file or directory, or set of files defined by a fileset.
+ * The original delete task would delete a file, or a set of files 
+ * using the include/exclude syntax.  The deltree task would delete a 
+ * directory tree.  This task combines the functionality of these two
+ * originally distinct tasks.
  * 
  * @author stefano@apache.org
  * @author Tom Dimock <a href="mailto:tad1@cornell.edu">tad1@cornell.edu</a>
+ * @author Glenn McAllister <a href="mailto:glennm@ca.ibm.com">glennm@ca.ibm.com</a>
  */
-public class Delete extends MatchingTask {
-    private File delDir = null;
+public class Delete extends Task {
+    protected File file = null;
+    protected File dir = null;
+    protected Vector filesets = new Vector();
+
     private int verbosity = Project.MSG_VERBOSE;
-    private File f = null;
 
     /**
      * Set the name of a single file to be removed.
      * 
      * @param file the file to be deleted
      */
-    public void setFile(String file) {
-        f = project.resolveFile(file);
+    public void setFile(File file) {
+        this.file = file;
     } 
 
     /**
@@ -81,8 +90,8 @@
      * 
      * @param dir the directory path.
      */
-    public void setDir(String dir) {
-        delDir = project.resolveFile(dir);
+    public void setDir(File dir) {
+        this.dir = dir;
     } 
 
     /**
@@ -90,67 +99,96 @@
      * 
      * @param verbose "true" or "on"
      */
-    public void setVerbose(String verbose) {
-        if ("true".equalsIgnoreCase(verbose.trim()) || "on".equalsIgnoreCase(verbose.trim())) {
+    public void setVerbose(boolean verbose) {
+        if (verbose) {
             this.verbosity = Project.MSG_INFO;
         } else {
             this.verbosity = Project.MSG_VERBOSE;
         } 
     } 
 
+    /**
+     * Adds a set of files (nested fileset attribute).
+     */
+    public void addFileset(FileSet set) {
+        filesets.addElement(set);
+    }
+
     /**
-     * Make it so.  Delete the file(s).
+     * Delete the file(s).
      * 
      * @throws BuildException
      */
     public void execute() throws BuildException {
-        if (f == null && delDir == null) {
-            throw new BuildException("<file> or <dir> attribute must be set!");
+        if (file == null && dir == null && filesets.size() == 0) {
+            throw new BuildException("At least one of the file or dir attributes, or a fileset element, must be set.");
         } 
 
-        // old <delete> functionality must still work
-        if (f != null) {
-            if (f.exists()) {
-                if (f.isDirectory()) {
-                    log("Directory: " + f.getAbsolutePath() + " cannot be removed with delete.  Use Deltree instead.");
+        // delete the single file
+        if (file != null) {
+            if (file.exists()) {
+                if (file.isDirectory()) {
+                    log("Directory " + file.getAbsolutePath() + " cannot be removed using the file attribute.  Use dir instead.");
                 } else {
-                    log("Deleting: " + f.getAbsolutePath());
+                    log("Deleting: " + file.getAbsolutePath());
 
-                    if (!f.delete()) {
-                        throw new BuildException("Unable to delete file " + f.getAbsolutePath());
+                    if (!file.delete()) {
+                        throw new BuildException("Unable to delete file " + file.getAbsolutePath());
                     } 
                 } 
-            } 
-        } 
-
-        // now we'll do the fancy pattern-driven deletes
-        if (delDir == null) {
-            return;
-        } 
-
-        if (!delDir.exists()) {
-            throw new BuildException("dir does not exist!");
-        } 
-
-        DirectoryScanner ds = super.getDirectoryScanner(delDir);
-        String[] files = ds.getIncludedFiles();
-
-        if (files.length > 0) {
-            log("Deleting " + files.length + " files from " + delDir.getAbsolutePath());
-
-            for (int i = 0; i < files.length; i++) {
-                File f = new File(delDir, files[i]);
-
-                if (f.exists()) {
-                    log("Deleting: " + f.getAbsolutePath(), verbosity);
-
+            } else {
+                log("Could not find file " + file.getAbsolutePath() + " to delete.");
+            }
+        }
+
+        // delete the directory
+        if (dir != null) {
+            log("Deleting directory " + dir.getAbsolutePath());
+            removeDir(dir);
+        }
+
+        // delete the files in the filesets
+        for (int i=0; i<filesets.size(); i++) {
+            FileSet fs = (FileSet) filesets.elementAt(i);
+            DirectoryScanner ds = fs.getDirectoryScanner(project);
+
+            String[] files = ds.getIncludedFiles();
+            if (files.length > 0) {
+                log("Deleting " + files.length + " files from " + fs.getDir(project));
+                for (int j=0; j<files.length; j++) {
+                    File f = new File(fs.getDir(project), files[j]);
+                    log("Deleting " + f.getAbsolutePath(), verbosity);
                     if (!f.delete()) {
-                        throw new BuildException("Unable to delete " + f.getAbsolutePath());
-                    } 
-                } 
-            } 
-        } 
+                        throw new BuildException("Unable to delete file " + f.getAbsolutePath());
+                    }
+                }
+            }
+        }
     } 
+
+//************************************************************************
+//  protected and private methods
+//************************************************************************
+
+    protected void removeDir(File d) {
+    	String[] list = d.list();
+        for (int i = 0; i < list.length; i++) {
+            String s = list[i];
+            File f = new File(d, s);
+            if (f.isDirectory()) {
+                removeDir(f);
+            } else {
+                log("Deleting " + f.getAbsolutePath(), verbosity);
+                if (!f.delete()) {
+                    throw new BuildException("Unable to delete file " + f.getAbsolutePath());
+                }
+            }
+        }
+        log("Deleting directory " + d.getAbsolutePath(), verbosity);
+        if (!d.delete()) {
+	       throw new BuildException("Unable to delete directory " + dir.getAbsolutePath());
+	   }
+    }
 
 }
 
Index: src/main/org/apache/tools/ant/taskdefs/defaults.properties
===================================================================
RCS file: /home/cvspublic/jakarta-ant/src/main/org/apache/tools/ant/taskdefs/defaults.properties,v
retrieving revision 1.37
diff -u -r1.37 defaults.properties
--- src/main/org/apache/tools/ant/taskdefs/defaults.properties	2000/09/07 11:09:03	1.37
+++ src/main/org/apache/tools/ant/taskdefs/defaults.properties	2000/09/08 21:08:37
@@ -4,6 +4,8 @@
 chmod=org.apache.tools.ant.taskdefs.Chmod
 deltree=org.apache.tools.ant.taskdefs.Deltree
 delete=org.apache.tools.ant.taskdefs.Delete
+copy=org.apache.tools.ant.taskdefs.Copy
+move=org.apache.tools.ant.taskdefs.Move
 jar=org.apache.tools.ant.taskdefs.Jar
 copydir=org.apache.tools.ant.taskdefs.Copydir
 copyfile=org.apache.tools.ant.taskdefs.Copyfile
