0) {
+ if (delimiter==null) {
+ // only the first
+ rv = (String)foundFiles.elementAt(0);
+ } else {
+ // create list
+ StringBuffer list = new StringBuffer();
+ for(Iterator it=foundFiles.iterator(); it.hasNext(); ) {
+ list.append(it.next());
+ if (it.hasNext()) list.append(delimiter);
+ }
+ rv = list.toString();
+ }
+ }
+
+
+ if (rv!=null)
+ getProject().setNewProperty(location, rv);
+ }
+
+}
diff --git a/src/tutorial/tasks-filesets-properties/04-lists/src/FindTest.java b/src/tutorial/tasks-filesets-properties/04-lists/src/FindTest.java
new file mode 100644
index 000000000..54c7fc2b3
--- /dev/null
+++ b/src/tutorial/tasks-filesets-properties/04-lists/src/FindTest.java
@@ -0,0 +1,78 @@
+import org.apache.tools.ant.BuildFileTest;
+import org.apache.tools.ant.types.FileSet;
+import org.apache.tools.ant.taskdefs.Property;
+import java.io.File;
+
+public class FindTest extends BuildFileTest {
+
+ public FindTest(String name) {
+ super(name);
+ }
+
+ public void setUp() {
+ configureProject("build.xml");
+ }
+
+ public void testMissingFile() {
+ Find find = new Find();
+ try {
+ find.execute();
+ fail("No 'no-file'-exception thrown.");
+ } catch (Exception e) {
+ // exception expected
+ String expected = "file not set";
+ assertEquals("Wrong exception message.", expected, e.getMessage());
+ }
+ }
+
+ public void testMissingLocation() {
+ Find find = new Find();
+ find.setFile("ant.jar");
+ try {
+ find.execute();
+ fail("No 'no-location'-exception thrown.");
+ } catch (Exception e) {
+ // exception expected
+ String expected = "location not set";
+ assertEquals("Wrong exception message.", expected, e.getMessage());
+ }
+ }
+
+ public void testMissingPath() {
+ Find find = new Find();
+ find.setFile("ant.jar");
+ find.setLocation("location.ant-jar");
+ try {
+ find.execute();
+ fail("No 'no-fileset'-exception thrown.");
+ } catch (Exception e) {
+ // exception expected
+ String expected = "path not set";
+ assertEquals("Wrong exception message.", expected, e.getMessage());
+ }
+ }
+
+ public void testFileNotPresent() {
+ executeTarget("testFileNotPresent");
+ String result = getProject().getProperty("location.ant-jar");
+ assertNull("Property set to wrong value.", result);
+ }
+
+ public void testFilePresent() {
+ executeTarget("testFilePresent");
+ String result = getProject().getProperty("location.ant-jar");
+ assertNotNull("Property not set.", result);
+ assertTrue("Wrong file found.", result.endsWith("ant.jar"));
+ }
+
+
+ public void testMultipleFiles() {
+ executeTarget("testMultipleFiles");
+ String result = getProject().getProperty("location.test");
+ assertNotNull("Property not set.", result);
+ assertTrue("Only one file found.", result.indexOf(";") > -1);
+ //assertTrue("Wrong file found.", result.endsWith("ant.jar"));
+ }
+
+
+}
diff --git a/src/tutorial/tasks-filesets-properties/final/build.xml b/src/tutorial/tasks-filesets-properties/final/build.xml
new file mode 100644
index 000000000..39c18a2d6
--- /dev/null
+++ b/src/tutorial/tasks-filesets-properties/final/build.xml
@@ -0,0 +1,162 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ant.jar found on ${location.ant-jar}
+
+
+
+
+
+
+
+
+
+ ant.jar found on ${location.ant-jar}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/tutorial/tasks-filesets-properties/final/find.html b/src/tutorial/tasks-filesets-properties/final/find.html
new file mode 100644
index 000000000..7f781a618
--- /dev/null
+++ b/src/tutorial/tasks-filesets-properties/final/find.html
@@ -0,0 +1,68 @@
+
+
+
+
+ Find Task
+
+
+
+
+
+Description
+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.
+
+Parameters
+
+
+ Attribute |
+ Description |
+ Required |
+
+
+ file |
+ The name of the file to search. |
+ yes |
+
+
+ location |
+ The name of the property where to store the location |
+ yes |
+
+
+ delimiter |
+ A delimiter to use when returning the list |
+ only if the list is required |
+
+
+
+Parameters specified as nested elements
+
+path
+The path where to search the file.
+
+Examples
+
+ <find file="ant.jar" location="loc">
+ <path>
+ <fileset dir="${ant.home}"/>
+ <path>
+ </find>
+
+Searches in Ants home directory for a file ant.jar and stores its location in
+property loc (should be ANT_HOME/bin/ant.jar).
+
+
+ <find file="ant.jar" location="loc" delimiter=";">
+ <path>
+ <fileset dir="C:/"/>
+ <path>
+ </find>
+ <echo>ant.jar found in: ${loc}</echo>
+
+Searches in Windows C: drive for all ant.jar and stores their locations in
+property loc delimited with ';'. (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).
+
+
+
diff --git a/src/tutorial/tasks-filesets-properties/final/src/Find.java b/src/tutorial/tasks-filesets-properties/final/src/Find.java
new file mode 100644
index 000000000..96fc06f02
--- /dev/null
+++ b/src/tutorial/tasks-filesets-properties/final/src/Find.java
@@ -0,0 +1,141 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2000-2003 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 "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
+ * .
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.DirectoryScanner;
+
+import java.util.Vector;
+import java.util.Iterator;
+import java.io.File;
+
+public class Find extends Task {
+
+ // ===== internal attributes =====
+
+ private Vector foundFiles = new Vector();
+
+ // ===== attribute support =====
+
+ private String file;
+ private String location;
+ private Vector paths = new Vector();
+ private String delimiter = null;
+
+ public void setFile(String file) {
+ this.file = file;
+ }
+
+ public void setLocation(String location) {
+ this.location = location;
+ }
+
+ public void addPath(Path path) {
+ paths.add(path);
+ }
+
+ public void setDelimiter(String delim) {
+ delimiter = delim;
+ }
+
+ // ===== the tasks work =====
+
+ protected void validate() {
+ if (file==null) throw new BuildException("file not set");
+ if (location==null) throw new BuildException("location not set");
+ if (paths.size()<1) throw new BuildException("path not set");
+ }
+
+ public void execute() {
+ validate();
+ // find all files
+ for(Iterator itPaths = paths.iterator(); itPaths.hasNext(); ) {
+ Path path = (Path)itPaths.next();
+ String[] includedFiles = path.list();
+ for(int i=0; i 0) {
+ if (delimiter==null) {
+ // only the first
+ rv = (String)foundFiles.elementAt(0);
+ } else {
+ // create list
+ StringBuffer list = new StringBuffer();
+ for(Iterator it=foundFiles.iterator(); it.hasNext(); ) {
+ list.append(it.next());
+ if (it.hasNext()) list.append(delimiter);
+ }
+ rv = list.toString();
+ }
+ }
+
+ // create the property
+ if (rv!=null)
+ getProject().setNewProperty(location, rv);
+ }
+
+}
diff --git a/src/tutorial/tasks-filesets-properties/final/src/FindTest.java b/src/tutorial/tasks-filesets-properties/final/src/FindTest.java
new file mode 100644
index 000000000..117505347
--- /dev/null
+++ b/src/tutorial/tasks-filesets-properties/final/src/FindTest.java
@@ -0,0 +1,134 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2000-2003 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 "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
+ * .
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+
+import org.apache.tools.ant.BuildFileTest;
+import org.apache.tools.ant.types.FileSet;
+import org.apache.tools.ant.taskdefs.Property;
+import java.io.File;
+
+public class FindTest extends BuildFileTest {
+
+ public FindTest(String name) {
+ super(name);
+ }
+
+ public void setUp() {
+ configureProject("build.xml");
+ }
+
+ public void testMissingFile() {
+ Find find = new Find();
+ try {
+ find.execute();
+ fail("No 'no-file'-exception thrown.");
+ } catch (Exception e) {
+ // exception expected
+ String expected = "file not set";
+ assertEquals("Wrong exception message.", expected, e.getMessage());
+ }
+ }
+
+ public void testMissingLocation() {
+ Find find = new Find();
+ find.setFile("ant.jar");
+ try {
+ find.execute();
+ fail("No 'no-location'-exception thrown.");
+ } catch (Exception e) {
+ // exception expected
+ String expected = "location not set";
+ assertEquals("Wrong exception message.", expected, e.getMessage());
+ }
+ }
+
+ public void testMissingPath() {
+ Find find = new Find();
+ find.setFile("ant.jar");
+ find.setLocation("location.ant-jar");
+ try {
+ find.execute();
+ fail("No 'no-fileset'-exception thrown.");
+ } catch (Exception e) {
+ // exception expected
+ String expected = "path not set";
+ assertEquals("Wrong exception message.", expected, e.getMessage());
+ }
+ }
+
+ public void testFileNotPresent() {
+ executeTarget("testFileNotPresent");
+ String result = getProject().getProperty("location.ant-jar");
+ assertNull("Property set to wrong value.", result);
+ }
+
+ public void testFilePresent() {
+ executeTarget("testFilePresent");
+ String result = getProject().getProperty("location.ant-jar");
+ assertNotNull("Property not set.", result);
+ assertTrue("Wrong file found.", result.endsWith("ant.jar"));
+ }
+
+
+ public void testMultipleFiles() {
+ executeTarget("testMultipleFiles");
+ String result = getProject().getProperty("location.test");
+ assertNotNull("Property not set.", result);
+ assertTrue("Only one file found.", result.indexOf(";") > -1);
+ }
+
+
+}
diff --git a/src/tutorial/tasks-start-writing/build.xml b/src/tutorial/tasks-start-writing/build.xml
new file mode 100644
index 000000000..8e502c1b6
--- /dev/null
+++ b/src/tutorial/tasks-start-writing/build.xml
@@ -0,0 +1,103 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ nested-text
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/tutorial/tasks-start-writing/src/HelloWorld.java b/src/tutorial/tasks-start-writing/src/HelloWorld.java
new file mode 100644
index 000000000..eaa42d6ad
--- /dev/null
+++ b/src/tutorial/tasks-start-writing/src/HelloWorld.java
@@ -0,0 +1,70 @@
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.BuildException;
+import java.util.Vector;
+import java.util.Iterator;
+
+/**
+ * The task of the tutorial.
+ * Prints a message or let the build fail.
+ * @author Jan Matérne
+ * @since 2003-08-19
+ */
+public class HelloWorld extends Task {
+
+
+ /** The message to print. As attribute. */
+ String message;
+ public void setMessage(String msg) {
+ message = msg;
+ }
+
+ /** Should the build fail? Defaults to false. As attribute. */
+ boolean fail = false;
+ public void setFail(boolean b) {
+ fail = b;
+ }
+
+ /** Support for nested text. */
+ public void addText(String text) {
+ message = text;
+ }
+
+
+ /** Do the work. */
+ public void execute() {
+ // handle attribute 'fail'
+ if (fail) throw new BuildException("Fail requested.");
+
+ // handle attribute 'message' and nested text
+ if (message!=null) log(message);
+
+ // handle nested elements
+ for (Iterator it=messages.iterator(); it.hasNext(); ) {
+ Message msg = (Message)it.next();
+ log(msg.getMsg());
+ }
+ }
+
+
+ /** Store nested 'message's. */
+ Vector messages = new Vector();
+
+ /** Factory method for creating nested 'message's. */
+ public Message createMessage() {
+ Message msg = new Message();
+ messages.add(msg);
+ return msg;
+ }
+
+ /** A nested 'message'. */
+ public class Message {
+ // Bean constructor
+ public Message() {}
+
+ /** Message to print. */
+ String msg;
+ public void setMsg(String msg) { this.msg = msg; }
+ public String getMsg() { return msg; }
+ }
+
+}
\ No newline at end of file
diff --git a/src/tutorial/tasks-start-writing/src/HelloWorldTest.java b/src/tutorial/tasks-start-writing/src/HelloWorldTest.java
new file mode 100644
index 000000000..87a7e3142
--- /dev/null
+++ b/src/tutorial/tasks-start-writing/src/HelloWorldTest.java
@@ -0,0 +1,40 @@
+import org.apache.tools.ant.BuildFileTest;
+
+public class HelloWorldTest extends BuildFileTest {
+
+ public HelloWorldTest(String s) {
+ super(s);
+ }
+
+ public void setUp() {
+ // initialize Ant
+ configureProject("build.xml");
+ }
+
+ public void testWithout() {
+ executeTarget("use.without");
+ assertEquals("Message was logged but should not.", getLog(), "");
+ }
+
+ public void testMessage() {
+ // execute target 'use.nestedText' and expect a message
+ // 'attribute-text' in the log
+ expectLog("use.message", "attribute-text");
+ }
+
+ public void testFail() {
+ // execute target 'use.fail' and expect a BuildException
+ // with text 'Fail requested.'
+ expectBuildException("use.fail", "Fail requested.");
+ }
+
+ public void testNestedText() {
+ expectLog("use.nestedText", "nested-text");
+ }
+
+ public void testNestedElement() {
+ executeTarget("use.nestedElement");
+ assertLogContaining("Nested Element 1");
+ assertLogContaining("Nested Element 2");
+ }
+}