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, | * 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 | * 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/cvspass.html">CVSPass</a><br> | ||||
<a href="CoreTasks/delete.html">Delete</a><br> | <a href="CoreTasks/delete.html">Delete</a><br> | ||||
<a href="CoreTasks/deltree.html"><i>Deltree</i></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/ear.html">Ear</a><br> | ||||
<a href="CoreTasks/echo.html">Echo</a><br> | <a href="CoreTasks/echo.html">Echo</a><br> | ||||
<a href="CoreTasks/exec.html">Exec</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 | parallel=org.apache.tools.ant.taskdefs.Parallel | ||||
sequential=org.apache.tools.ant.taskdefs.Sequential | sequential=org.apache.tools.ant.taskdefs.Sequential | ||||
condition=org.apache.tools.ant.taskdefs.ConditionTask | condition=org.apache.tools.ant.taskdefs.ConditionTask | ||||
dependset=org.apache.tools.ant.taskdefs.DependSet | |||||
# optional tasks | # optional tasks | ||||
script=org.apache.tools.ant.taskdefs.optional.Script | 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 | path=org.apache.tools.ant.types.Path | ||||
fileset=org.apache.tools.ant.types.FileSet | fileset=org.apache.tools.ant.types.FileSet | ||||
filelist=org.apache.tools.ant.types.FileList | |||||
patternset=org.apache.tools.ant.types.PatternSet | patternset=org.apache.tools.ant.types.PatternSet | ||||
mapper=org.apache.tools.ant.types.Mapper | mapper=org.apache.tools.ant.types.Mapper | ||||
filterset=org.apache.tools.ant.types.FilterSet | 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()); | |||||
} | |||||
} |