Submitted by: Craeg K. Strong <cstrong@arielpartners.com> git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@269479 13f79535-47bb-0310-9956-ffa450edef68master
@@ -39,7 +39,7 @@ Other changes: | |||
-------------- | |||
* New tasks: ear, p4counter, record, cvspass, vsscheckin, vsscheckout, | |||
typedef, sleep, mimemail, set of tasks for Continuus/Synergy | |||
typedef, sleep, mimemail, set of tasks for Continuus/Synergy, dependset | |||
* Ant now uses JAXP 1.1 | |||
@@ -0,0 +1,132 @@ | |||
<html> | |||
<head> | |||
<meta http-equiv="Content-Language" content="en-us"> | |||
<title>Ant User Manual</title> | |||
</head> | |||
<body> | |||
<h2>DependSet</h2> | |||
A task to manage arbitrary dependencies between files. | |||
<h3>Description</h3> | |||
<p> | |||
The dependset task compares a set of source files with a set of target | |||
files. If any of the source files is more recent than any of | |||
the target files, all of the target files are removed. | |||
</p> | |||
<p> | |||
Source files and target files are specified via nested <a | |||
href="../CoreTypes/fileset.html">FileSets</a> and/or nested <a | |||
href="../CoreTypes/filelist.html">FileLists</a>. Arbitrarily many | |||
source and target filesets/filelists may be specified, but at | |||
least one filelist/fileset is required for both sources and targets. | |||
</p> | |||
<p> | |||
Use a FileSet when you want to use wildcard include or exclude | |||
patterns and don't care about missing files. Use a FileList when you | |||
want to consider the non-existence of a file as if it were out of | |||
date. If there are any non-existing files in any source or target | |||
FileList, all target files will be removed. | |||
</p> | |||
<p> | |||
DependSet is useful to capture dependencies that are not or cannot be | |||
determined algorithmically. For example, the <style> task only | |||
compares the source XML file and XSLT stylesheet against the target | |||
file to determined whether to restyle the source. Using dependset you | |||
can extend this dependency checking to include a DTD or XSD file as | |||
well as other stylesheets imported by the main stylesheet. | |||
</p> | |||
<h3>Parameters</h3> | |||
<p> | |||
(none) | |||
</p> | |||
<h3>Parameters Specified as Nested Elements</h3> | |||
<h4>srcfileset</h4> | |||
<p> | |||
The nested <code>srcfileset</code> element specifies a <a | |||
href="../CoreTypes/fileset.html">FileSet</a>. All files included in | |||
this fileset will be compared against all files included in all of the | |||
<code>targetfileset</code> filesets and <code>targetfilelist</code> | |||
filelists. Multiple <code>srcfileset</code> filesets may be specified. | |||
</p> | |||
<h4>srcfilelist</h4> | |||
<p> | |||
The nested <code>srcfilelist</code> element specifies a <a | |||
href="../CoreTypes/filelist.html">FileList</a>. All files included in | |||
this filelist will be compared against all files included in all of the | |||
<code>targetfileset</code> filesets and <code>targetfilelist</code> | |||
filelists. Multiple <code>srcfilelist</code> filelists may be specified. | |||
</p> | |||
<h4>targetfileset</h4> | |||
<p> | |||
The nested <code>targetfileset</code> element specifies a <a | |||
href="../CoreTypes/fileset.html">FileSet</a>. All files included in | |||
this fileset will be compared against all files included in all of the | |||
<code>srcfileset</code> filesets and <code>sourcefilelist</code> | |||
filelists, and if any are older, they are all deleted. | |||
</p> | |||
<h4>targetfilelist</h4> | |||
<p> | |||
The nested <code>targetfilelist</code> element specifies a <a | |||
href="../CoreTypes/filelist.html">FileList</a>. All files included in | |||
this filelist will be compared against all files included in all of the | |||
<code>srcfileset</code> filesets and <code>sourcefilelist</code> | |||
filelists, and if any are older, they are all deleted. | |||
</p> | |||
<h3>Examples</h3> | |||
<blockquote> <pre> | |||
<dependset> | |||
<srcfilelist | |||
dir = "${dtd.dir}" | |||
files = "paper.dtd,common.dtd"/> | |||
<srcfilelist | |||
dir = "${xsl.dir}" | |||
files = "common.xsl"/> | |||
<srcfilelist | |||
dir = "${basedir}" | |||
files = "build.xml"/> | |||
<targetfileset | |||
dir = "${output.dir}" | |||
includes = "**/*.html"/> | |||
</dependset> </pre> | |||
</blockquote> | |||
<p> | |||
In this example derived HTML files in the ${output.dir} directory | |||
will be removed if any are out-of-date with respect to: | |||
<olist> | |||
<li>the DTD of their source XML files</li> | |||
<li>a common DTD (imported by the main DTD)</li> | |||
<li>a subordinate XSLT stylesheet (imported by the main stylesheet), or</li> | |||
<li>the buildfile</li> | |||
</olist> | |||
</p> | |||
<p> | |||
If any of the source files in the above example does not exist, all | |||
target files will also be removed. To ignore missing source files instead, | |||
use filesets instead of filelists for the source files. | |||
</p> | |||
<hr> | |||
<p align="center">Copyright © 2000,2001 Apache Software Foundation. | |||
All rights | |||
Reserved.</p> | |||
</body> | |||
</html> |
@@ -0,0 +1,65 @@ | |||
<html> | |||
<head> | |||
<meta http-equiv="Content-Language" content="en-us"> | |||
<title>Ant User Manual</title> | |||
</head> | |||
<body> | |||
<h2><a name="filelist">FileList</a></h2> | |||
<p>FileLists are explicitly named lists of files. Whereas FileSets | |||
act as filters, returning only those files that exist in the file | |||
system and match specified patterns, filelists are useful for | |||
specifying filenames that may or may not exist. Multiple files are | |||
specified via a comma-separated list, with no support for wildcards. | |||
FileLists can appear inside tasks that support this feature or at the | |||
same level as <code>target</code> - i.e., as children of | |||
<code>project</code>. | |||
</p> | |||
<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">dir</td> | |||
<td valign="top">the base directory of this FileList.</td> | |||
<td valign="top" align="center">Yes</td> | |||
</tr> | |||
<tr> | |||
<td valign="top">files</td> | |||
<td valign="top">Comma-separated list of file names.</td> | |||
<td valign="top" align="center">Yes</td> | |||
</tr> | |||
</tr> | |||
</table> | |||
<h4>Examples</h4> | |||
<blockquote><pre> | |||
<filelist | |||
id="docfiles" | |||
dir="${doc.src}" | |||
files="foo.xml,bar.xml"/> | |||
</pre></blockquote> | |||
<p>The files <code>${doc.src}/foo.xml</code> and | |||
<code>${doc.src}/bar.xml</code>. Note that these files may not (yet) | |||
actually exist. | |||
</p> | |||
<blockquote><pre> | |||
<filelist refid="docfiles"/> | |||
</pre></blockquote> | |||
<p>Same files as the example above.</p> | |||
<hr> | |||
<p align="center">Copyright © 2000,2001 Apache Software Foundation. All rights | |||
Reserved.</p> | |||
</body> | |||
</html> | |||
@@ -33,6 +33,7 @@ | |||
<a href="CoreTasks/cvspass.html">CVSPass</a><br> | |||
<a href="CoreTasks/delete.html">Delete</a><br> | |||
<a href="CoreTasks/deltree.html"><i>Deltree</i></a><br> | |||
<a href="CoreTasks/dependset.html">Dependset</a><br> | |||
<a href="CoreTasks/ear.html">Ear</a><br> | |||
<a href="CoreTasks/echo.html">Echo</a><br> | |||
<a href="CoreTasks/exec.html">Exec</a><br> | |||
@@ -0,0 +1,43 @@ | |||
<?xml version="1.0"?> | |||
<project name="dependset-test" basedir="." default="test1"> | |||
<target name="test1"> | |||
<dependset/> | |||
</target> | |||
<target name="test2"> | |||
<dependset> | |||
<srcfilelist dir="." includes="test2.tmp"/> | |||
</dependset> | |||
</target> | |||
<target name="test3"> | |||
<dependset> | |||
<targetfileset dir="." files="test3.tmp"/> | |||
</dependset> | |||
</target> | |||
<target name="test4"> | |||
<touch file="test4.tmp"/> | |||
<dependset> | |||
<srcfilelist dir="." files="test4.tmp"/> | |||
<targetfileset dir="." includes="i-do-not-exist"/> | |||
</dependset> | |||
</target> | |||
<target name="test5"> | |||
<touch millis="0" file="older.tmp"/> | |||
<touch file="newer.tmp"/> | |||
<dependset> | |||
<srcfilelist dir="." files="newer.tmp"/> | |||
<targetfilelist dir="." files="older.tmp"/> | |||
</dependset> | |||
</target> | |||
<target name="cleanup"> | |||
<delete file="test4.tmp"/> | |||
<delete file="older.tmp"/> | |||
<delete file="newer.tmp"/> | |||
</target> | |||
</project> |
@@ -0,0 +1,315 @@ | |||
/* | |||
* The Apache Software License, Version 1.1 | |||
* | |||
* Copyright (c) 2001 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", "Ant", 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 java.io.File; | |||
import java.util.Enumeration; | |||
import java.util.Vector; | |||
import java.util.Date; | |||
import org.apache.tools.ant.*; | |||
import org.apache.tools.ant.types.FileSet; | |||
import org.apache.tools.ant.types.FileList; | |||
/** | |||
* A Task to record explicit dependencies. If any of the target files | |||
* are out of date with respect to any of the source files, all target | |||
* files are removed. This is useful where dependencies cannot be | |||
* computed (for example, dynamically interpreted parameters or files | |||
* that need to stay in synch but are not directly linked) or where | |||
* the ant task in question could compute them but does not (for | |||
* example, the linked DTD for an XML file using the style task). | |||
* | |||
* nested arguments: | |||
* <ul> | |||
* <li>srcfileset (fileset describing the source files to examine) | |||
* <li>srcfilelist (filelist describing the source files to examine) | |||
* <li>targetfileset (fileset describing the target files to examine) | |||
* <li>targetfilelist (filelist describing the target files to examine) | |||
* </ul> | |||
* At least one instance of either a fileset or filelist for both source and target | |||
* are required. | |||
* <p> | |||
* This task will examine each of the source files against each of the target files. | |||
* If any target files are out of date with respect to any of the source files, all targets are removed. | |||
* If any files named in a (src or target) filelist do not exist, all targets are removed. | |||
* Hint: If missing files should be ignored, specify them as include patterns in filesets, | |||
* rather than using filelists. | |||
* </p><p> | |||
* This task attempts to optimize speed of dependency checking. It will stop after the first | |||
* out of date file is found and remove all targets, rather than exhaustively checking every | |||
* source vs target combination unnecessarily. | |||
* </p><p> | |||
* Example uses: | |||
* <ulist><li> | |||
* Record the fact that an XML file must be up to date | |||
* with respect to its XSD (Schema file), even though the XML file | |||
* itself includes no reference to its XSD. | |||
* </li><li> | |||
* Record the fact that an XSL stylesheet includes other | |||
* sub-stylesheets | |||
* </li><li> | |||
* Record the fact that java files must be recompiled if the ant build | |||
* file changes | |||
* </li></ulist> | |||
* | |||
* @author <a href="mailto:cstrong@arielpartners.com">Craeg Strong</a> | |||
* @version $Revision$ $Date$ | |||
*/ | |||
public class DependSet extends MatchingTask { | |||
private Vector sourceFileSets = new Vector(); | |||
private Vector sourceFileLists = new Vector(); | |||
private Vector targetFileSets = new Vector(); | |||
private Vector targetFileLists = new Vector(); | |||
/** | |||
* Creates a new DependSet Task. | |||
**/ | |||
public DependSet() { | |||
} //-- DependSet | |||
/** | |||
* Nested <srcfileset> element. | |||
*/ | |||
public void addSrcfileset(FileSet fs) { | |||
sourceFileSets.addElement(fs); | |||
} | |||
/** | |||
* Nested <srcfilelist> element. | |||
*/ | |||
public void addSrcfilelist(FileList fl) { | |||
sourceFileLists.addElement(fl); | |||
} | |||
/** | |||
* Nested <targetfileset> element. | |||
*/ | |||
public void addTargetfileset(FileSet fs) { | |||
targetFileSets.addElement(fs); | |||
} | |||
/** | |||
* Nested <targetfilelist> element. | |||
*/ | |||
public void addTargetfilelist(FileList fl) { | |||
targetFileLists.addElement(fl); | |||
} | |||
/** | |||
* Executes the task. | |||
*/ | |||
public void execute() throws BuildException { | |||
if ( (sourceFileSets.size() == 0) && (sourceFileLists.size() == 0) ) { | |||
throw new BuildException("At least one <srcfileset> or <srcfilelist> element must be set"); | |||
} | |||
if ( (targetFileSets.size() == 0) && (targetFileLists.size() == 0) ) { | |||
throw new BuildException("At least one <targetfileset> or <targetfilelist> element must be set"); | |||
} | |||
long now = (new Date()).getTime(); | |||
/* | |||
If we're on Windows, we have to munge the time up to 2 secs to | |||
be able to check file modification times. | |||
(Windows has a max resolution of two secs for modification times) | |||
*/ | |||
String osname = System.getProperty("os.name").toLowerCase(); | |||
if ( osname.indexOf("windows") >= 0 ) { | |||
now += 2000; | |||
} | |||
// | |||
// Grab all the target files specified via filesets | |||
// | |||
Vector allTargets = new Vector(); | |||
Enumeration enumTargetSets = targetFileSets.elements(); | |||
while (enumTargetSets.hasMoreElements()) { | |||
FileSet targetFS = (FileSet) enumTargetSets.nextElement(); | |||
DirectoryScanner targetDS = targetFS.getDirectoryScanner(project); | |||
String[] targetFiles = targetDS.getIncludedFiles(); | |||
for (int i = 0; i < targetFiles.length; i++) { | |||
File dest = new File(targetFS.getDir(project), targetFiles[i]); | |||
allTargets.add(dest); | |||
if (dest.lastModified() > now) { | |||
log("Warning: "+targetFiles[i]+" modified in the future.", | |||
Project.MSG_WARN); | |||
} | |||
} | |||
} | |||
// | |||
// Grab all the target files specified via filelists | |||
// | |||
boolean upToDate = true; | |||
Enumeration enumTargetLists = targetFileLists.elements(); | |||
while (enumTargetLists.hasMoreElements()) { | |||
FileList targetFL = (FileList) enumTargetLists.nextElement(); | |||
String[] targetFiles = targetFL.getFiles(project); | |||
for (int i = 0; i < targetFiles.length; i++) { | |||
File dest = new File(targetFL.getDir(project), targetFiles[i]); | |||
if (!dest.exists()) { | |||
log(targetFiles[i]+ " does not exist.", Project.MSG_VERBOSE); | |||
upToDate = false; | |||
continue; | |||
} | |||
else { | |||
allTargets.add(dest); | |||
} | |||
if (dest.lastModified() > now) { | |||
log("Warning: "+targetFiles[i]+" modified in the future.", | |||
Project.MSG_WARN); | |||
} | |||
} | |||
} | |||
// | |||
// Check targets vs source files specified via filesets | |||
// | |||
if (upToDate) { | |||
Enumeration enumSourceSets = sourceFileSets.elements(); | |||
while (upToDate && enumSourceSets.hasMoreElements()) { | |||
FileSet sourceFS = (FileSet) enumSourceSets.nextElement(); | |||
DirectoryScanner sourceDS = sourceFS.getDirectoryScanner(project); | |||
String[] sourceFiles = sourceDS.getIncludedFiles(); | |||
int i = 0; | |||
do { | |||
File src = new File(sourceFS.getDir(project), sourceFiles[i]); | |||
if (src.lastModified() > now) { | |||
log("Warning: "+sourceFiles[i]+" modified in the future.", | |||
Project.MSG_WARN); | |||
} | |||
Enumeration enumTargets = allTargets.elements(); | |||
while (upToDate && enumTargets.hasMoreElements()) { | |||
File dest = (File)enumTargets.nextElement(); | |||
if (src.lastModified() > dest.lastModified()) { | |||
log(dest.getPath() + " is out of date with respect to " + | |||
sourceFiles[i], Project.MSG_VERBOSE); | |||
upToDate = false; | |||
} | |||
} | |||
} while (upToDate && (++i < sourceFiles.length) ); | |||
} | |||
} | |||
// | |||
// Check targets vs source files specified via filelists | |||
// | |||
if (upToDate) { | |||
Enumeration enumSourceLists = sourceFileLists.elements(); | |||
while (upToDate && enumSourceLists.hasMoreElements()) { | |||
FileList sourceFL = (FileList) enumSourceLists.nextElement(); | |||
String[] sourceFiles = sourceFL.getFiles(project); | |||
int i = 0; | |||
do { | |||
File src = new File(sourceFL.getDir(project), sourceFiles[i]); | |||
if (src.lastModified() > now) { | |||
log("Warning: "+sourceFiles[i]+" modified in the future.", | |||
Project.MSG_WARN); | |||
} | |||
if (!src.exists()) { | |||
log(sourceFiles[i]+ " does not exist.", Project.MSG_VERBOSE); | |||
upToDate = false; | |||
break; | |||
} | |||
Enumeration enumTargets = allTargets.elements(); | |||
while (upToDate && enumTargets.hasMoreElements()) { | |||
File dest = (File)enumTargets.nextElement(); | |||
if (src.lastModified() > dest.lastModified()) { | |||
log(dest.getPath() + " is out of date with respect to " + | |||
sourceFiles[i], Project.MSG_VERBOSE); | |||
upToDate = false; | |||
} | |||
} | |||
} while (upToDate && (++i < sourceFiles.length) ); | |||
} | |||
} | |||
if (!upToDate) { | |||
log("Deleting all target files. ", Project.MSG_VERBOSE); | |||
for (Enumeration e = allTargets.elements(); e.hasMoreElements(); ) { | |||
File fileToRemove = (File)e.nextElement(); | |||
log("Deleting file " + fileToRemove.getAbsolutePath(), Project.MSG_VERBOSE); | |||
fileToRemove.delete(); | |||
} | |||
} | |||
} //-- execute | |||
} //-- DependSet.java |
@@ -52,6 +52,7 @@ ear=org.apache.tools.ant.taskdefs.Ear | |||
parallel=org.apache.tools.ant.taskdefs.Parallel | |||
sequential=org.apache.tools.ant.taskdefs.Sequential | |||
condition=org.apache.tools.ant.taskdefs.ConditionTask | |||
dependset=org.apache.tools.ant.taskdefs.DependSet | |||
# optional tasks | |||
script=org.apache.tools.ant.taskdefs.optional.Script | |||
@@ -0,0 +1,172 @@ | |||
/* | |||
* The Apache Software License, Version 1.1 | |||
* | |||
* Copyright (c) 2001 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", "Ant", 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.types; | |||
import org.apache.tools.ant.BuildException; | |||
import org.apache.tools.ant.Project; | |||
import java.io.File; | |||
import java.util.StringTokenizer; | |||
import java.util.Enumeration; | |||
import java.util.Stack; | |||
import java.util.Vector; | |||
/** | |||
* FileList represents an explicitly named list of files. FileLists | |||
* are useful when you want to capture a list of files regardless of | |||
* whether they currently exist. By contrast, FileSet operates as a | |||
* filter, only returning the name of a matched file if it currently | |||
* exists in the file system. | |||
* | |||
* @author <a href="mailto:cstrong@arielpartners.com">Craeg Strong</a> | |||
* @version $Revision$ $Date$ | |||
*/ | |||
public class FileList extends DataType { | |||
private Vector filenames = new Vector(); | |||
private File dir; | |||
public FileList() { | |||
super(); | |||
} | |||
protected FileList(FileList filelist) { | |||
this.dir = filelist.dir; | |||
this.filenames = filelist.filenames; | |||
} | |||
/** | |||
* Makes this instance in effect a reference to another FileList | |||
* instance. | |||
* | |||
* <p>You must not set another attribute or nest elements inside | |||
* this element if you make it a reference.</p> | |||
*/ | |||
public void setRefid(Reference r) throws BuildException { | |||
if ((dir != null) || (filenames.size() != 0)) { | |||
throw tooManyAttributes(); | |||
} | |||
super.setRefid(r); | |||
} | |||
public void setDir(File dir) throws BuildException { | |||
if (isReference()) { | |||
throw tooManyAttributes(); | |||
} | |||
this.dir = dir; | |||
} | |||
public File getDir(Project p) { | |||
if (isReference()) { | |||
return getRef(p).getDir(p); | |||
} | |||
return dir; | |||
} | |||
public void setFiles(String filenames) { | |||
if (isReference()) { | |||
throw tooManyAttributes(); | |||
} | |||
if (filenames != null && filenames.length() > 0) { | |||
StringTokenizer tok = new StringTokenizer(filenames, ", \t\n\r\f", false); | |||
while (tok.hasMoreTokens()) { | |||
this.filenames.addElement(tok.nextToken()); | |||
} | |||
} | |||
} | |||
/** | |||
* Returns the list of files represented by this FileList. | |||
*/ | |||
public String[] getFiles(Project p) { | |||
if (isReference()) { | |||
return getRef(p).getFiles(p); | |||
} | |||
if (dir == null) { | |||
throw new BuildException("No directory specified for filelist."); | |||
} | |||
if (filenames.size() == 0) { | |||
throw new BuildException("No files specified for filelist."); | |||
} | |||
String result[] = new String[filenames.size()]; | |||
filenames.copyInto(result); | |||
return result; | |||
} | |||
/** | |||
* Performs the check for circular references and returns the | |||
* referenced FileList. | |||
*/ | |||
protected FileList getRef(Project p) { | |||
if (!checked) { | |||
Stack stk = new Stack(); | |||
stk.push(this); | |||
dieOnCircularReference(stk, p); | |||
} | |||
Object o = ref.getReferencedObject(p); | |||
if (!(o instanceof FileList)) { | |||
String msg = ref.getRefId()+" doesn\'t denote a filelist"; | |||
throw new BuildException(msg); | |||
} else { | |||
return (FileList) o; | |||
} | |||
} | |||
} //-- FileList.java |
@@ -1,5 +1,6 @@ | |||
path=org.apache.tools.ant.types.Path | |||
fileset=org.apache.tools.ant.types.FileSet | |||
filelist=org.apache.tools.ant.types.FileList | |||
patternset=org.apache.tools.ant.types.PatternSet | |||
mapper=org.apache.tools.ant.types.Mapper | |||
filterset=org.apache.tools.ant.types.FilterSet | |||
@@ -0,0 +1,100 @@ | |||
/* | |||
* The Apache Software License, Version 1.1 | |||
* | |||
* Copyright (c) 2001 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", "Ant", 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; | |||
/** | |||
* Tests DependSet. | |||
* | |||
* @author <a href="mailto:cstrong@arielpartners.com">Craeg Strong</a> | |||
*/ | |||
public class DependSetTest extends TaskdefsTest { | |||
public DependSetTest(String name) { | |||
super(name); | |||
} | |||
public void setUp() { | |||
configureProject("src/etc/testcases/taskdefs/dependset.xml"); | |||
} | |||
public void test1() { | |||
expectBuildException("test1","At least one <srcfileset> or <srcfilelist> element must be set"); | |||
} | |||
public void tearDown() { | |||
executeTarget("cleanup"); | |||
} | |||
public void test2() { | |||
expectBuildException("test2","At least one <targetfileset> or <targetfilelist> element must be set"); | |||
} | |||
public void test3() { | |||
expectBuildException("test1","At least one <srcfileset> or <srcfilelist> element must be set"); | |||
} | |||
public void test4() { | |||
executeTarget("test4"); | |||
} | |||
public void test5() { | |||
executeTarget("test5"); | |||
java.io.File f = new java.io.File(getProjectDir(), "older.tmp"); | |||
if (f.exists()) { | |||
fail("dependset failed to remove out of date file " + f.toString()); | |||
} | |||
} | |||
} |
@@ -0,0 +1,184 @@ | |||
/* | |||
* The Apache Software License, Version 1.1 | |||
* | |||
* Copyright (c) 2001 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", "Ant", 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.types; | |||
import org.apache.tools.ant.BuildException; | |||
import org.apache.tools.ant.Project; | |||
import junit.framework.TestCase; | |||
import junit.framework.AssertionFailedError; | |||
import java.io.File; | |||
/** | |||
* JUnit 3 testcases for org.apache.tools.ant.types.FileList. | |||
* | |||
* <p>This doesn't actually test much, mainly reference handling. | |||
* Adapted from FileSetTest.</p> | |||
* | |||
* @author <a href="mailto:cstrong@arielpartners.com">Craeg Strong</a> | |||
*/ | |||
public class FileListTest extends TestCase { | |||
private Project project; | |||
public FileListTest(String name) { | |||
super(name); | |||
} | |||
public void setUp() { | |||
project = new Project(); | |||
project.setBasedir("."); | |||
} | |||
public void testEmptyElementIfIsReference() { | |||
FileList f = new FileList(); | |||
f.setDir(project.resolveFile(".")); | |||
try { | |||
f.setRefid(new Reference("dummyref")); | |||
fail("Can add reference to FileList with directory attribute set."); | |||
} catch (BuildException be) { | |||
assertEquals("You must not specify more than one attribute when using refid", | |||
be.getMessage()); | |||
} | |||
f = new FileList(); | |||
f.setFiles("foo.xml,c/d/bar.xml"); | |||
try { | |||
f.setRefid(new Reference("dummyref")); | |||
fail("Can add reference to FileList with file attribute set."); | |||
} catch (BuildException be) { | |||
assertEquals("You must not specify more than one attribute when using refid", | |||
be.getMessage()); | |||
} | |||
f = new FileList(); | |||
f.setRefid(new Reference("dummyref")); | |||
try { | |||
f.setFiles("a/b/foo.java"); | |||
fail("Can set files in FileList that is a reference."); | |||
} catch (BuildException be) { | |||
assertEquals("You must not specify more than one attribute when using refid", | |||
be.getMessage()); | |||
} | |||
try { | |||
f.setDir(project.resolveFile(".")); | |||
fail("Can set dir in FileList that is a reference."); | |||
} catch (BuildException be) { | |||
assertEquals("You must not specify more than one attribute when using refid", | |||
be.getMessage()); | |||
} | |||
} | |||
public void testCircularReferenceCheck() { | |||
FileList f = new FileList(); | |||
project.addReference("dummy", f); | |||
f.setRefid(new Reference("dummy")); | |||
try { | |||
f.getDir(project); | |||
fail("Can make FileList a Reference to itself."); | |||
} catch (BuildException be) { | |||
assertEquals("This data type contains a circular reference.", | |||
be.getMessage()); | |||
} | |||
try { | |||
f.getFiles(project); | |||
fail("Can make FileList a Reference to itself."); | |||
} catch (BuildException be) { | |||
assertEquals("This data type contains a circular reference.", | |||
be.getMessage()); | |||
} | |||
// dummy1 --> dummy2 --> dummy3 --> dummy1 | |||
FileList f1 = new FileList(); | |||
project.addReference("dummy1", f1); | |||
f1.setRefid(new Reference("dummy2")); | |||
FileList f2 = new FileList(); | |||
project.addReference("dummy2", f2); | |||
f2.setRefid(new Reference("dummy3")); | |||
FileList f3 = new FileList(); | |||
project.addReference("dummy3", f3); | |||
f3.setRefid(new Reference("dummy1")); | |||
try { | |||
f1.getDir(project); | |||
fail("Can make circular reference."); | |||
} catch (BuildException be) { | |||
assertEquals("This data type contains a circular reference.", | |||
be.getMessage()); | |||
} | |||
try { | |||
f1.getFiles(project); | |||
fail("Can make circular reference."); | |||
} catch (BuildException be) { | |||
assertEquals("This data type contains a circular reference.", | |||
be.getMessage()); | |||
} | |||
// dummy1 --> dummy2 --> dummy3 | |||
// (which has the Project's basedir as root). | |||
f1 = new FileList(); | |||
project.addReference("dummy1", f1); | |||
f1.setRefid(new Reference("dummy2")); | |||
f2 = new FileList(); | |||
project.addReference("dummy2", f2); | |||
f2.setRefid(new Reference("dummy3")); | |||
f3 = new FileList(); | |||
project.addReference("dummy3", f3); | |||
f3.setDir(project.resolveFile(".")); | |||
File dir = f1.getDir(project); | |||
assertEquals("Dir is basedir", dir, project.getBaseDir()); | |||
} | |||
} |