@@ -41,16 +41,16 @@ location of that file in a property.</p>
<p>We can use the buildfile from the other tutorial and modify it a little bit.
That´s the advantage of using properties - we can reuse nearly the whole script. :-)</p>
<pre class="code">
<?xml version="1.0" encoding="ISO-8859-1"?>
<project name="<b>FindTask</b>" basedir="." default="test">
<?xml version="1.0" encoding="ISO-8859-1"?>
<project name="<b>FindTask</b>" basedir="." default="test">
...
<target name="use.init" description="Taskdef´ the <b>Find</b>-Task" depends="jar">
<taskdef name="<b>find</b>" classname="<b>Find</b>" classpath="${ant.project.name}.jar"/>
</target>
<target name="use.init" description="Taskdef´ the <b>Find</b>-Task" depends="jar">
<taskdef name="<b>find</b>" classname="<b>Find</b>" classpath="${ant.project.name}.jar"/>
</target>
<b><!-- the other use.* targets are deleted --></b>
...
</project>
</project>
</pre>
<p>The buildfile is in the archive <a href="tutorial-tasks-filesets-properties.zip">
@@ -63,13 +63,13 @@ tutorial-tasks-filesets-properties.zip [2]</a> in <tt>/build.xml.01-propertyacce
<p>Our first step is to set a property to a value and print the value of that property.
So our scenario would be
<pre class="code">
<find property="test" value="test-value"/>
<find print="test"/>
<find property="test" value="test-value"/>
<find print="test"/>
</pre>
ok, can be rewritten with the core tasks
<pre class="code">
<property name="test" value="test-value"/>
<echo message="${test}"/>
<property name="test" value="test-value"/>
<echo message="${test}"/>
</pre>
but I have to start on known ground :-)</p>
<p>So what to do? Handling three attributes (property, value, print) and an execute method.
@@ -117,7 +117,7 @@ name. Otherwise a message is logged.</p>
<p><i>(by the way: a short word to ants "namespaces" (don´t
be confused with xml namespaces which will be also introduces in the future (1.6 or 1.7):
an <antcall> creates a new space for property names. All properties from the caller
an <antcall> creates a new space for property names. All properties from the caller
are passed to the callee, but the callee can set its own properties without notice by the
caller.)</i></p>
@@ -158,9 +158,9 @@ their usage in buildfiles. Our goal is to search a file in path. And on this ste
path is simply a fileset (or more precise: a collection of filesets). So our usage
would be
<pre class="code">
<find file="ant.jar" location="location.ant-jar">
<fileset dir="${ant.home}" includes="**/*.jar"/>
</find>
<find file="ant.jar" location="location.ant-jar">
<fileset dir="${ant.home}" includes="**/*.jar"/>
</find>
</pre>
</p>
@@ -315,30 +315,30 @@ whithout being complex :-)</p>
environment we have to set that value for our own. And we use the <junit> task in fork-mode.
Therefore we have do modify our buildfile:
<pre class="code">
<target name="junit" description="Runs the unit tests" depends="jar">
<delete dir="${junit.out.dir.xml}" />
<mkdir dir="${junit.out.dir.xml}" />
<junit printsummary="yes" haltonfailure="no">
<classpath refid="classpath.test"/>
<b><sysproperty key="ant.home" value="${ant.home}"/> </b>
<formatter type="xml"/>
<batchtest fork="yes" todir="${junit.out.dir.xml}">
<fileset dir="${src.dir}" includes="**/*Test.java"/>
</batchtest>
</junit>
</target>
<target name="junit" description="Runs the unit tests" depends="jar">
<delete dir="${junit.out.dir.xml}"/>
<mkdir dir="${junit.out.dir.xml}"/>
<junit printsummary="yes" haltonfailure="no">
<classpath refid="classpath.test"/>
<b><sysproperty key="ant.home" value="${ant.home}"/> </b>
<formatter type="xml"/>
<batchtest fork="yes" todir="${junit.out.dir.xml}">
<fileset dir="${src.dir}" includes="**/*Test.java"/>
</batchtest>
</junit>
</target>
</pre>
<a name="path"/>
<h2>Using nested paths</h2>
<p>A task providing support for filesets is a very comfortable one. But there is another
possibility of bundling files: the <path> . Fileset are easy if the files are all under
possibility of bundling files: the <path> . Fileset are easy if the files are all under
a common base directory. But if this is not the case you have a problem. Another disadvantage
is its speed: if you have only a few files in a huge directory structure, why not use a
<filelist> instead? <path> s combines these datatypes in that way that a path contains
<filelist> instead? <path> s combines these datatypes in that way that a path contains
other paths, filesets, dirsets and filelists. This is why <a href="http://ant-contrib.sourceforge.net/">
Ant-Contribs [4]</a> <foreach> task is modified to support paths instead of filesets. So we want that,
Ant-Contribs [4]</a> <foreach> task is modified to support paths instead of filesets. So we want that,
too.</p>
<p>Changing from fileset to path support is very easy:</p>
@@ -354,15 +354,15 @@ too.</p>
paths.add(path);
}
<i><b>and build file from:</b></i>
<find file="ant.jar" location="location.ant-jar">
<fileset dir="${ant.home}" includes="**/*.jar"/>
</find>
<find file="ant.jar" location="location.ant-jar">
<fileset dir="${ant.home}" includes="**/*.jar"/>
</find>
<i><b>to:</b></i>
<find file="ant.jar" location="location.ant-jar">
<b><path> </b> *3
<fileset dir="${ant.home}" includes="**/*.jar"/>
</path>
</find>
<find file="ant.jar" location="location.ant-jar">
<b><path> </b> *3
<fileset dir="${ant.home}" includes="**/*.jar"/>
</path>
</find>
</pre>
<p>On <b>*1</b> we rename only the vector. It´s just for better reading the source. On <b>*2</b>
we have to provide the right method: an add<i>Name</i>(<i>Type</i> t). Therefore replace the
@@ -414,13 +414,13 @@ And would it be good to get all of them? - It depends on ...<p>
<p>In this section we will extend that task to support returning a list of all files.
Lists as property values are not supported by Ant natively. So we have to see how other
tasks use lists. The most famous task using lists is Ant-Contribs <foreach> . All list
tasks use lists. The most famous task using lists is Ant-Contribs <foreach> . All list
elements are concatenated and separated with a customizable separator (default ',').</p>
<p>So we do the following:</p>
<pre class="code">
<find ... <b>delimiter=""</b>/> ... </find>
<find ... <b>delimiter=""</b>/> ... </find>
</pre>
<p>If the delimiter is set we will return all found files as list with that delimiter.</p>
@@ -436,35 +436,35 @@ elements are concatenated and separated with a customizable separator (default '
<p>So we add as testcase:</p>
<pre class="code">
<b><i>in the buildfile:</i></b>
<target name="test.init">
<mkdir dir="test1/dir11/dir111"/> *1
<mkdir dir="test1/dir11/dir112"/>
<target name="test.init">
<mkdir dir="test1/dir11/dir111"/> *1
<mkdir dir="test1/dir11/dir112"/>
...
<touch file="test1/dir11/dir111/test"/>
<touch file="test1/dir11/dir111/not"/>
<touch file="test1/dir11/dir111/test"/>
<touch file="test1/dir11/dir111/not"/>
...
<touch file="test1/dir13/dir131/not2"/>
<touch file="test1/dir13/dir132/test"/>
<touch file="test1/dir13/dir132/not"/>
<touch file="test1/dir13/dir132/not2"/>
<mkdir dir="test2"/>
<copy todir="test2"> *2
<fileset dir="test1"/>
</copy>
</target>
<target name="testMultipleFiles" depends="use.init,<b>test.init</b>"> *3
<find file="test" location="location.test" <b>delimiter=";"</b>>
<path>
<fileset dir="test1"/>
<fileset dir="test2"/>
</path>
</find>
<delete> *4
<fileset dir="test1"/>
<fileset dir="test2"/>
</delete>
</target>
<touch file="test1/dir13/dir131/not2"/>
<touch file="test1/dir13/dir132/test"/>
<touch file="test1/dir13/dir132/not"/>
<touch file="test1/dir13/dir132/not2"/>
<mkdir dir="test2"/>
<copy todir="test2"> *2
<fileset dir="test1"/>
</copy>
</target>
<target name="testMultipleFiles" depends="use.init,<b>test.init</b>"> *3
<find file="test" location="location.test" <b>delimiter=";"</b>>
<path>
<fileset dir="test1"/>
<fileset dir="test2"/>
</path>
</find>
<delete> *4
<fileset dir="test1"/>
<fileset dir="test2"/>
</delete>
</target>
<b><i>in the test class:</i></b>
public void testMultipleFiles() {
@@ -563,123 +563,123 @@ important :-) examples</li>
As a template we have:
<pre class="code">
<html>
<html>
<head>
<meta http-equiv="Content-Language" content="en-us">
<title> <b>Taskname</b> Task</title>
</head>
<head>
<meta http-equiv="Content-Language" content="en-us">
<title> <b>Taskname</b> Task</title>
</head>
<body>
<body>
<h2><a name="<i>taskname</i>"><b>Taskname</b></a></h2>
<h3>Description</h3>
<p> <b>Describe the task.</b></p>
<h2><a name="<i>taskname</i>"><b>Taskname</b></a></h2>
<h3>Description</h3>
<p> <b>Describe the task.</b></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>
<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>
<b>do this html row for each attribute (including inherited attributes)</b>
<tr>
<td valign="top">classname</td>
<td valign="top">the Java class to execute.</td>
<td align="center" valign="top">Either jar or classname</td>
</tr>
<tr>
<td valign="top">classname</td>
<td valign="top">the Java class to execute.</td>
<td align="center" valign="top">Either jar or classname</td>
</tr>
</table>
</table>
<h3>Parameters specified as nested elements</h3>
<h3>Parameters specified as nested elements</h3>
<b>Describe each nested element (including inherited)</b>
<h4><b>your nested element</b></h4>
<p> <b>description</b> </p>
<p><em>since Ant 1.6</em>.</p>
<h4>your nested element</b></h4>
<p> <b>description</b> </p>
<p><em>since Ant 1.6</em>.</p>
<h3>Examples</h3>
<pre>
<h3>Examples</h3>
<pre>
<b>A code sample; don´t forget to escape the < of the tags with &lt;</b>
</pre>
</pre>
<b>what should that example do?</b>
</body>
</html>
</body>
</html>
</pre>
<p>For our task we have <a href="CoreTasks/find.html">that [6]</a>:</p>
<pre class="code">
<html>
<head>
<meta http-equiv="Content-Language" content="en-us">
<title> Find Task</title>
</head>
<body>
<h2><a name="find">Find</a></h2>
<h3>Description</h3>
<p> Searchs in a given path for a file and returns the absolute to it as property.
If delimiter is set this task returns all found locations.</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 name of the file to search.</td>
<td align="center" valign="top">yes</td>
</tr>
<tr>
<td valign="top">location</td>
<td valign="top">The name of the property where to store the location</td>
<td align="center" valign="top">yes</td>
</tr>
<tr>
<td valign="top">delimiter</td>
<td valign="top">A delimiter to use when returning the list</td>
<td align="center" valign="top">only if the list is required</td>
</tr>
</table>
<h3>Parameters specified as nested elements</h3>
<h4>path</h4>
<p>The path where to search the file.</p>
<h3>Examples</h3>
<pre>
<find file="ant.jar" location="loc">
<path>
<fileset dir="${ant.home}"/>
<path>
</find>
</pre>
Searches in Ants home directory for a file <i>ant.jar</i> and stores its location in
property <i>loc</i> (should be ANT_HOME/bin/ant.jar).
<pre>
<find file="ant.jar" location="loc" delimiter=";">
<path>
<fileset dir="C:/"/>
<path>
</find>
<echo>ant.jar found in: ${loc}</echo>
</pre>
Searches in Windows C: drive for all <i>ant.jar</i> and stores their locations in
property <i>loc</i> delimited with <i>';'</i> . (should need a long time :-)
<html>
<head>
<meta http-equiv="Content-Language" content="en-us">
<title> Find Task</title>
</head>
<body>
<h2><a name="find">Find</a></h2>
<h3>Description</h3>
<p> Searchs in a given path for a file and returns the absolute to it as property.
If delimiter is set this task returns all found locations.</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 name of the file to search.</td>
<td align="center" valign="top">yes</td>
</tr>
<tr>
<td valign="top">location</td>
<td valign="top">The name of the property where to store the location</td>
<td align="center" valign="top">yes</td>
</tr>
<tr>
<td valign="top">delimiter</td>
<td valign="top">A delimiter to use when returning the list</td>
<td align="center" valign="top">only if the list is required</td>
</tr>
</table>
<h3>Parameters specified as nested elements</h3>
<h4>path</h4>
<p>The path where to search the file.</p>
<h3>Examples</h3>
<pre>
<find file="ant.jar" location="loc">
<path>
<fileset dir="${ant.home}"/>
<path>
</find>
</pre>
Searches in Ants home directory for a file <i>ant.jar</i> and stores its location in
property <i>loc</i> (should be ANT_HOME/bin/ant.jar).
<pre>
<find file="ant.jar" location="loc" delimiter=";">
<path>
<fileset dir="C:/"/>
<path>
</find>
<echo>ant.jar found in: ${loc}</echo>
</pre>
Searches in Windows C: drive for all <i>ant.jar</i> and stores their locations in
property <i>loc</i> delimited with <i>';'</i> . (should need a long time :-)
After that it prints out the result (e.g. C:/ant-1.5.4/bin/ant.jar;C:/ant-1.6/bin/ant.jar).
</body>
</html>
</body>
</html>
</pre>
@@ -755,9 +755,9 @@ on <b>//4</b>.</p>
are any tests failing on our machine. (We can ignore these failing tests on later
steps; windows syntax used here- translate to xNIX if needed):
<pre class="output">
ANTHOME> build // 1
ANTHOME> set ANT_HOME=%CD%\dist // 2
ANTHOME> ant test -Dtest.haltonfailure=false // 3
ANTHOME> build // 1
ANTHOME> set ANT_HOME=%CD%\dist // 2
ANTHOME> ant test -Dtest.haltonfailure=false // 3
</pre>
First we have to build our Ant distribution (<b>//1</b>). On <b>//2</b> we set the ANT_HOME
@@ -782,14 +782,14 @@ necessary and saves a lot of work if you modify existing source :-)</i>.
<li>in FindTest.java change the line <tt>configureProject("build.xml");</tt> to
<tt>configureProject("src/etc/testcases/taskdefs/find.xml");</tt> </li>
<li>move the find.html to ANTHOME/docs/manual/CoreTasks/find.html </li>
<li>add a <tt><a href="CoreTasks/find.html">Find</a><br> </tt>
<li>add a <tt><a href="CoreTasks/find.html">Find</a><br> </tt>
in the ANTHOME/docs/manual/coretasklist.html </li>
</ul>
Now our modifications are done and we will retest it:
<pre class="output">
ANTHOME> build
ANTHOME> ant run-single-test // 1
ANTHOME> build
ANTHOME> ant run-single-test // 1
-Dtestcase=org.apache.tools.ant.taskdefs.FindTest // 2
-Dtest.haltonfailure=false
</pre>
@@ -799,15 +799,15 @@ failures of our own test (<b>//1 + 2</b>).</p>
<p>And ... oh, all tests fail: <i>Ant could not find the task or a class this task relies upon.</i></p>
<p>Ok: in the earlier steps we told Ant to use the Find class for the <find> task (remember the
<taskdef> statement in the "use.init" target). But now we want to introduce that task as
<p>Ok: in the earlier steps we told Ant to use the Find class for the <find> task (remember the
<taskdef> statement in the "use.init" target). But now we want to introduce that task as
a core task. And nobody wants to taskdef the javac, echo, ... So what to do? The answer is the
src/main/.../taskdefs/default.properties. Here is the mapping between taskname and implementing
class done. So we add a <tt>find=org.apache.tools.ant.taskdefs.Find</tt> as the last core
task (just before the <tt># optional tasks</tt> line). Now a second try:
<pre class="output">
ANTHOME> build // 1
ANTHOME> ant run-single-test
ANTHOME> build // 1
ANTHOME> ant run-single-test
-Dtestcase=org.apache.tools.ant.taskdefs.FindTest
-Dtest.haltonfailure=false
</pre>
@@ -816,7 +816,7 @@ We have to rebuild (<b>//1</b>) Ant because the test look in the %ANT_HOME%\lib\
source path. So we have to rebuild that jar. But now all tests pass and we check whether our class
breaks some other tests.
<pre class="output">
ANTHOME> ant test -Dtest.haltonfailure=false
ANTHOME> ant test -Dtest.haltonfailure=false
</pre>
Because there are a lot of tests this step requires a little bit of time. So use the <i>run-single-test</i>
during development and do the <i>test</i> only at the end (maybe sometimes during development too).
@@ -863,7 +863,7 @@ directory (this feature was added with Ant 1.6).</p>
<p>So we will run the tests with
<pre class="output">
ANTHOME> ant -f check.xml checkstyle htmlreport
ANTHOME> ant -f check.xml checkstyle htmlreport
</pre>
I prefer the HTML report because there are lots of messages and we can navigate faster.
Open the ANTHOME/build/reports/checkstyle/html/index.html and navigate to the Find.java. Now we
@@ -900,7 +900,7 @@ entry. For both we need some information:</p>
<tr>
<th>body</th>
<td><i>more details about the path</i></td>
<td>This new task looks inside a nested <path/> for occurrences of a file and stores
<td>This new task looks inside a nested <path/> for occurrences of a file and stores
all locations as a property. See the included manual for details.</td>
</tr>
<tr>