Browse Source

Consolidation of Copyfile, Copydir, Delete, Deltree, and Rename into

Copy, Move, and Delete tasks.


git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@268051 13f79535-47bb-0310-9956-ffa450edef68
master
glennm 24 years ago
parent
commit
38c1cabaac
9 changed files with 813 additions and 79 deletions
  1. +191
    -29
      docs/index.html
  2. +285
    -0
      src/main/org/apache/tools/ant/taskdefs/Copy.java
  3. +2
    -0
      src/main/org/apache/tools/ant/taskdefs/Copydir.java
  4. +2
    -0
      src/main/org/apache/tools/ant/taskdefs/Copyfile.java
  5. +181
    -50
      src/main/org/apache/tools/ant/taskdefs/Delete.java
  6. +2
    -0
      src/main/org/apache/tools/ant/taskdefs/Deltree.java
  7. +146
    -0
      src/main/org/apache/tools/ant/taskdefs/Move.java
  8. +2
    -0
      src/main/org/apache/tools/ant/taskdefs/Rename.java
  9. +2
    -0
      src/main/org/apache/tools/ant/taskdefs/defaults.properties

+ 191
- 29
docs/index.html View File

@@ -846,6 +846,7 @@ same patterns as the example before.</p>
<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>
@@ -867,6 +868,7 @@ same patterns as the example before.</p>
<li><a href="#javadoc">Javadoc/Javadoc2</a></li>
<li><a href="#mail">Mail</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>
@@ -1172,7 +1174,91 @@ group on a UNIX system. In addition all files belonging to a FileSet
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 at least one 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 no)</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 (default is no)</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><i>Deprecated</i></h3>
<p><i>This task has been deprecated. Use the Copy task instead.</i></p>
<h3>Description</h3>
<p>Copies a directory tree from the source to the destination.</p>
<p>It is possible to refine the set of files that are being copied. This can be
@@ -1277,6 +1363,8 @@ recursively. All java files are copied, except for the files under the <code>myp
directory.</p>
<hr>
<h2><a name="copyfile">Copyfile</a></h2>
<h3><i>Deprecated</i></h3>
<p><i>This task has been deprecated. Use the Copy task instead.</i></p>
<h3>Description</h3>
<p>Copies a file from the source to the destination. The file is only copied if
the source file is newer than the destination file, or when the destination file
@@ -1396,21 +1484,9 @@ repository pointed to by the cvsRoot attribute, and stores the files in &quot;${
<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 one or more <a href="#fileset">FileSet</a>s.
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>
@@ -1427,57 +1503,59 @@ nested <code>&lt;include&gt;</code>, <code>&lt;exclude&gt;</code> and
<td valign="top">dir</td>
<td valign="top">The directory to delete files from.</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 &quot;false&quot; when omitted.</td>
<td align="center" valign="top">No</td>
</tr>
<tr>
<td valign="top">includes</td>
<td valign="top">Comma separated list of patterns of files that must be
<td valign="top"><i>Deprecated.</i> 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
<td valign="top"><i>Deprecated.</i> 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>
</tr>
<tr>
<td valign="top">excludes</td>
<td valign="top">Comma separated list of patterns of files that must be
<td valign="top"><i>Deprecated.</i> 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
<td valign="top"><i>Deprecated.</i> 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
<td valign="top"><i>Deprecated.</i> 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 &quot;false&quot; when omitted.</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>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;
<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>
<hr>
<h2><a name="deltree">Deltree</a></h2>
<h3><i>Deprecated</i></h3>
<p><i>This task has been deprecated. Use the Delete task instead.</i></p>
<h3>Description</h3>
<p>Deletes a directory with all its files and subdirectories.</p>
<h3>Parameters</h3>
@@ -3135,6 +3213,88 @@ necessary.</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 (rename a 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>
<p>Applies a diff file to originals.
@@ -3272,6 +3432,8 @@ JVM that I tested, the home directory on Windows is &quot;C:\&quot;. Different
implementations may use other values for the home directory on Windows.
<hr>
<h2><a name="rename">Rename</a></h2>
<h3><i>Deprecated</i></h3>
<p><i>This task has been deprecated. Use the Move task instead.</i></p>
<h3>Description</h3>
<p>Renames a given file.</p>
<h3>Parameters</h3>


+ 285
- 0
src/main/org/apache/tools/ant/taskdefs/Copy.java View File

@@ -0,0 +1,285 @@
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/

package org.apache.tools.ant.taskdefs;

import org.apache.tools.ant.*;
import org.apache.tools.ant.types.*;

import java.io.*;
import java.util.*;

/**
* A consolidated copy task. 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. It is possible to explicitly overwrite existing files.</p>
*
* <p>This implementation is based on Arnout Kuiper's initial design
* document, the following mailing list discussions, and the
* copyfile/copydir tasks.</p>
*
* @author Glenn McAllister <a href="mailto:glennm@ca.ibm.com">glennm@ca.ibm.com</a>
*/
public class Copy extends Task {
protected File file = null; // the source file
protected File dir = null; // the source directory
protected File destFile = null; // the destination file
protected File destDir = null; // the destination directory
protected Vector filesets = new Vector();

protected boolean filtering = false;
protected boolean forceOverwrite = false;
protected boolean flatten = false;
protected int verbosity = Project.MSG_VERBOSE;

protected Hashtable fileCopyMap = new Hashtable();

/**
* Sets a single source file to copy.
*/
public void setFile(File file) {
this.file = file;
}

/**
* Sets a directory to copy.
*/
public void setDir(File dir) {
this.dir = dir;
}

/**
* Sets the destination file.
*/
public void setTofile(File destFile) {
this.destFile = destFile;
}

/**
* Sets the destination directory.
*/
public void setTodir(File destDir) {
this.destDir = destDir;
}

/**
* Sets filtering.
*/
public void setFiltering(boolean filtering) {
this.filtering = filtering;
}

/**
* Overwrite any existing destination file(s).
*/
public void setOverwrite(boolean overwrite) {
this.forceOverwrite = overwrite;
}

/**
* 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
* file will be copied into the "flattened" directory, unless
* the forceoverwrite attribute is true.
*/
public void setFlatten(boolean flatten) {
this.flatten = flatten;
}

/**
* Used to force listing of all names of copied files.
*/
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);
}

/**
* Performs the copy operation.
*/
public void execute() throws BuildException {
// make sure we don't have an illegal set of options
validateAttributes();

// deal with the single file
if (file != null) {
if (destFile == null) {
destFile = new File(destDir, file.getName());
}

if (forceOverwrite ||
(file.lastModified() > destFile.lastModified())) {
fileCopyMap.put(file.getAbsolutePath(), destFile.getAbsolutePath());
}
}

// deal with the directory
if (dir != null) {
DirectoryScanner ds = new DirectoryScanner();
ds.setBasedir(dir);
ds.scan(); // include EVERYTHING

String[] srcFiles = ds.getIncludedFiles();
scan(dir, destDir, srcFiles); // add to fileCopyMap
}

// deal with the filesets
for (int i=0; i<filesets.size(); i++) {
FileSet fs = (FileSet) filesets.elementAt(i);
DirectoryScanner ds = fs.getDirectoryScanner(project);

String[] srcFiles = ds.getIncludedFiles();
scan(fs.getDir(project), destDir, srcFiles); // add to fileCopyMap
}

// do all the copy operations now...
doFileOperations();
}

//************************************************************************
// protected and private methods
//************************************************************************

/**
* Ensure we have a consistent and legal set of attributes, and set
* any internal flags necessary based on different combinations
* of attributes.
*/
protected void validateAttributes() throws BuildException {
if (file == null && dir == null && filesets.size() == 0) {
throw new BuildException("Specify at least one source - a file, a dir, or a fileset.");
}

if (destFile != null && destDir != null) {
throw new BuildException("Only one of destfile and destdir may be set.");
}

if (destFile == null && destDir == null) {
throw new BuildException("One of destfile or destdir must be set.");
}

if (dir != null && destFile != null) {
throw new BuildException("Cannot copy a directory into a file.");
}

if (destFile != null && filesets.size() > 0) {
throw new BuildException("Cannot concatenate multple files into a single file.");
}

if (destFile != null) {
destDir = new File(destFile.getParent()); // be 1.1 friendly
}

}

/**
* Compares source files to destination files to see if they should be
* copied.
*/
protected void scan(File fromDir, File toDir, String[] files) {
for (int i = 0; i < files.length; i++) {
String filename = files[i];
File src = new File(fromDir, filename);
File dest;
if (flatten) {
dest = new File(toDir, new File(filename).getName());
} else {
dest = new File(toDir, filename);
}
if (forceOverwrite ||
(src.lastModified() > dest.lastModified())) {
fileCopyMap.put(src.getAbsolutePath(),
dest.getAbsolutePath());
}
}
}

protected void doFileOperations() {
if (fileCopyMap.size() > 0) {
log("Copying " + fileCopyMap.size() + " files to " +
destDir.getAbsolutePath() );

Enumeration e = fileCopyMap.keys();
while (e.hasMoreElements()) {
String fromFile = (String) e.nextElement();
String toFile = (String) fileCopyMap.get(fromFile);

try {
log("Copying " + fromFile + " to " + toFile, verbosity);
project.copyFile(fromFile,
toFile,
filtering,
forceOverwrite);
} catch (IOException ioe) {
String msg = "Failed to copy " + fromFile + " to " + toFile
+ " due to " + ioe.getMessage();
throw new BuildException(msg, ioe, location);
}
}
}
}

}

+ 2
- 0
src/main/org/apache/tools/ant/taskdefs/Copydir.java View File

@@ -95,6 +95,8 @@ public class Copydir extends MatchingTask {
}

public void execute() throws BuildException {
log("DEPRECATED - The copydir task is deprecated. Use copy instead.");

if (srcDir == null) {
throw new BuildException("src attribute must be set!",
location);


+ 2
- 0
src/main/org/apache/tools/ant/taskdefs/Copyfile.java View File

@@ -89,6 +89,8 @@ public class Copyfile extends Task {
}

public void execute() throws BuildException {
log("DEPRECATED - The copyfile task is deprecated. Use copy instead.");

if (srcFile == null) {
throw new BuildException("The src attribute must be present.", location);
}


+ 181
- 50
src/main/org/apache/tools/ant/taskdefs/Delete.java View File

@@ -54,26 +54,39 @@
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.
* <p>Currently Delete extends MatchingTask. This is intend <i>only</i>
* to provide backwards compatibility for a release. The future position
* is to use nested filesets exclusively.</p>
*
* @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;
protected File file = null;
protected File dir = null;
protected Vector filesets = new Vector();
protected boolean usedMatchingTask = false;

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 +94,8 @@ public class Delete extends MatchingTask {
*
* @param dir the directory path.
*/
public void setDir(String dir) {
delDir = project.resolveFile(dir);
public void setDir(File dir) {
this.dir = dir;
}

/**
@@ -90,8 +103,8 @@ public class Delete extends MatchingTask {
*
* @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;
@@ -99,60 +112,178 @@ public class Delete extends MatchingTask {
}

/**
* Make it so. Delete the file(s).
*
* @throws BuildException
* Adds a set of files (nested fileset attribute).
*/
public void execute() throws BuildException {
if (f == null && delDir == null) {
throw new BuildException("<file> or <dir> attribute must be set!");
}
public void addFileset(FileSet set) {
filesets.addElement(set);
}
/**
* add a name entry on the include list
*/
public PatternSet.NameEntry createInclude() {
usedMatchingTask = true;
return super.createInclude();
}
/**
* add a name entry on the exclude list
*/
public PatternSet.NameEntry createExclude() {
usedMatchingTask = true;
return super.createExclude();
}

// 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.");
} else {
log("Deleting: " + f.getAbsolutePath());
/**
* add a set of patterns
*/
public PatternSet createPatternSet() {
usedMatchingTask = true;
return super.createPatternSet();
}

if (!f.delete()) {
throw new BuildException("Unable to delete file " + f.getAbsolutePath());
}
}
}
}
/**
* Sets the set of include patterns. Patterns may be separated by a comma
* or a space.
*
* @param includes the string containing the include patterns
*/
public void setIncludes(String includes) {
usedMatchingTask = true;
super.setIncludes(includes);
}

// now we'll do the fancy pattern-driven deletes
if (delDir == null) {
return;
}
/**
* Sets the set of exclude patterns. Patterns may be separated by a comma
* or a space.
*
* @param excludes the string containing the exclude patterns
*/
public void setExcludes(String excludes) {
usedMatchingTask = true;
super.setExcludes(excludes);
}

if (!delDir.exists()) {
throw new BuildException("dir does not exist!");
}
/**
* Sets whether default exclusions should be used or not.
*
* @param useDefaultExcludes "true"|"on"|"yes" when default exclusions
* should be used, "false"|"off"|"no" when they
* shouldn't be used.
*/
public void setDefaultexcludes(boolean useDefaultExcludes) {
usedMatchingTask = true;
super.setDefaultexcludes(useDefaultExcludes);
}

DirectoryScanner ds = super.getDirectoryScanner(delDir);
String[] files = ds.getIncludedFiles();
/**
* Sets the name of the file containing the includes patterns.
*
* @param includesfile A string containing the filename to fetch
* the include patterns from.
*/
public void setIncludesfile(File includesfile) {
usedMatchingTask = true;
super.setIncludesfile(includesfile);
}

if (files.length > 0) {
log("Deleting " + files.length + " file"
+ (files.length == 1 ? "" : "s")
+ " from " + delDir.getAbsolutePath());
/**
* Sets the name of the file containing the includes patterns.
*
* @param excludesfile A string containing the filename to fetch
* the include patterns from.
*/
public void setExcludesfile(File excludesfile) {
usedMatchingTask = true;
super.setExcludesfile(excludesfile);
}

for (int i = 0; i < files.length; i++) {
File f = new File(delDir, files[i]);
/**
* Delete the file(s).
*/
public void execute() throws BuildException {
if (usedMatchingTask) {
log("DEPRECATED - Use of the implicit FileSet is deprecated. Use a nested fileset element instead.");
}

if (f.exists()) {
log("Deleting: " + f.getAbsolutePath(), verbosity);
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.");
}

if (!f.delete()) {
throw new BuildException("Unable to delete " + f.getAbsolutePath());
// 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: " + file.getAbsolutePath());
if (!file.delete()) {
throw new BuildException("Unable to delete file " + file.getAbsolutePath());
}
}
}
}
} else {
log("Could not find file " + file.getAbsolutePath() + " to delete.");
}
}

// delete the directory
if (dir != null && !usedMatchingTask) {
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();
removeFiles(fs.getDir(project), files);
}

// delete the files from the default fileset
if (usedMatchingTask && dir != null) {
DirectoryScanner ds = super.getDirectoryScanner(dir);
String [] files = ds.getIncludedFiles();
removeFiles(dir, files);
}
}

//************************************************************************
// 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());
}
}

protected void removeFiles(File d, String[] files) {
if (files.length > 0) {
log("Deleting " + files.length + " files from " + d.getAbsolutePath());
for (int j=0; j<files.length; j++) {
File f = new File(d, files[j]);
log("Deleting " + f.getAbsolutePath(), verbosity);
if (!f.delete()) {
throw new BuildException("Unable to delete file " + f.getAbsolutePath());
}
}
}
}
}


+ 2
- 0
src/main/org/apache/tools/ant/taskdefs/Deltree.java View File

@@ -72,6 +72,8 @@ public class Deltree extends Task {
}
public void execute() throws BuildException {
log("DEPRECATED - The deltree task is deprecated. Use delete instead.");

if (dir == null) {
throw new BuildException("dir attribute must be set!", location);
}


+ 146
- 0
src/main/org/apache/tools/ant/taskdefs/Move.java View File

@@ -0,0 +1,146 @@
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/

package org.apache.tools.ant.taskdefs;

import org.apache.tools.ant.*;
import org.apache.tools.ant.types.*;

import java.io.*;
import java.util.*;

/**
* Moves a file or directory to a new file or directory. By default,
* the destination is overwriten when existing. When overwrite 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>Source files and directories are only deleted when the file or
* directory has been copied to the destination successfully. Filtering
* also works.</p>
*
* <p>This implementation is based on Arnout Kuiper's initial design
* document, the following mailing list discussions, and the
* copyfile/copydir tasks.</p>
*
* @author Glenn McAllister <a href="mailto:glennm@ca.ibm.com">glennm@ca.ibm.com</a>
*/
public class Move extends Copy {

public Move() {
super();
forceOverwrite = true;
}

public void execute() throws BuildException {
super.execute();

// take care of the source directory
if (dir != null && dir.exists()) {
deleteDir(dir);
}
}

//************************************************************************
// protected and private methods
//************************************************************************

protected void doFileOperations() {
if (fileCopyMap.size() > 0) {
log("Moving " + fileCopyMap.size() + " files to " +
destDir.getAbsolutePath() );

Enumeration e = fileCopyMap.keys();
while (e.hasMoreElements()) {
String fromFile = (String) e.nextElement();
String toFile = (String) fileCopyMap.get(fromFile);

try {
log("Moving " + fromFile + " to " + toFile, verbosity);
project.copyFile(fromFile,
toFile,
filtering,
forceOverwrite);
File f = new File(fromFile);
if (!f.delete()) {
throw new BuildException("Unable to delete file " + f.getAbsolutePath());
}
} catch (IOException ioe) {
String msg = "Failed to copy " + fromFile + " to " + toFile
+ " due to " + ioe.getMessage();
throw new BuildException(msg, ioe, location);
}
}
}
}

protected void deleteDir(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()) {
deleteDir(f);
} else {
throw new BuildException("UNEXPECTED ERROR - The file " + f.getAbsolutePath() + " should not exist!");
}
}
log("Deleting directory " + d.getAbsolutePath(), verbosity);
if (!d.delete()) {
throw new BuildException("Unable to delete directory " + dir.getAbsolutePath());
}
}

}

+ 2
- 0
src/main/org/apache/tools/ant/taskdefs/Rename.java View File

@@ -102,6 +102,8 @@ public class Rename extends Task {
* thrown, if the rename operation fails.
*/
public void execute() throws BuildException {
log("DEPRECATED - The rename task is deprecated. Use move instead.");

if (dest == null) {
throw new BuildException("dest attribute is required", location);
}


+ 2
- 0
src/main/org/apache/tools/ant/taskdefs/defaults.properties View File

@@ -4,6 +4,8 @@ javac=org.apache.tools.ant.taskdefs.Javac
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


Loading…
Cancel
Save