diff --git a/build.xml b/build.xml
index 0548f277d..cf01d3c06 100644
--- a/build.xml
+++ b/build.xml
@@ -205,6 +205,7 @@
+
@@ -1517,6 +1518,8 @@
unless="bsf.present"/>
+
+
+
+ This build-file is intended to be run from the test cases
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/org/apache/tools/ant/MagicNames.java b/src/main/org/apache/tools/ant/MagicNames.java
new file mode 100644
index 000000000..378de29d5
--- /dev/null
+++ b/src/main/org/apache/tools/ant/MagicNames.java
@@ -0,0 +1,68 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 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;
+
+/**
+ * Magic names used within Ant.
+ *
+ * Not all magic names are here yet.
+ *
+ * @author Conor MacNeill
+ * @since Ant 1.6
+ */
+public class MagicNames {
+ /** The name of the script repository used by the script repo task */
+ public static final String SCRIPT_REPOSITORY = "org.apache.ant.scriptrepo";
+}
+
diff --git a/src/main/org/apache/tools/ant/Project.java b/src/main/org/apache/tools/ant/Project.java
index bf4f13f1b..c77d51e7b 100644
--- a/src/main/org/apache/tools/ant/Project.java
+++ b/src/main/org/apache/tools/ant/Project.java
@@ -1014,7 +1014,7 @@ public class Project {
* creation fails.
*/
public Task createTask(String taskType) throws BuildException {
- return ComponentHelper.getComponentHelper(this).createTask( taskType );
+ return ComponentHelper.getComponentHelper(this).createTask(taskType);
}
/**
diff --git a/src/main/org/apache/tools/ant/RuntimeConfigurable.java b/src/main/org/apache/tools/ant/RuntimeConfigurable.java
index 19a69a6dd..958c1069f 100644
--- a/src/main/org/apache/tools/ant/RuntimeConfigurable.java
+++ b/src/main/org/apache/tools/ant/RuntimeConfigurable.java
@@ -128,7 +128,7 @@ public class RuntimeConfigurable implements Serializable {
*
* @param proxy The element to configure. Must not be null
.
*/
- void setProxy(Object proxy) {
+ public void setProxy(Object proxy) {
wrappedObject = proxy;
proxyConfigured = false;
}
diff --git a/src/main/org/apache/tools/ant/UnknownElement.java b/src/main/org/apache/tools/ant/UnknownElement.java
index 66030d9f6..3831dcda5 100644
--- a/src/main/org/apache/tools/ant/UnknownElement.java
+++ b/src/main/org/apache/tools/ant/UnknownElement.java
@@ -150,11 +150,22 @@ public class UnknownElement extends Task {
//realThing = helper.createProjectComponent( this, getProject(), null,
// this.getTag());
- realThing = makeObject(this, getWrapper());
+ configure(makeObject(this, getWrapper()));
+ }
+ /**
+ * Configure the given object from this UnknownElement
+ *
+ * @param realObject the real object this UnknownElement is representing.
+ *
+ */
+ public void configure(Object realObject) {
+ realThing = realObject;
+
getWrapper().setProxy(realThing);
+ Task task = null;
if (realThing instanceof Task) {
- Task task = (Task) realThing;
+ task = (Task) realThing;
task.setRuntimeConfigurableWrapper(getWrapper());
@@ -168,7 +179,12 @@ public class UnknownElement extends Task {
// configure attributes of the object and it's children. If it is
// a task container, defer the configuration till the task container
// attempts to use the task
- getWrapper().maybeConfigure(getProject());
+
+ if (task != null) {
+ task.maybeConfigure();
+ } else {
+ getWrapper().maybeConfigure(getProject());
+ }
}
/**
@@ -294,7 +310,6 @@ public class UnknownElement extends Task {
for (int i = 0; i < children.size(); i++) {
RuntimeConfigurable childWrapper = parentWrapper.getChild(i);
UnknownElement child = (UnknownElement) children.elementAt(i);
- Object realChild = null;
// backwards compatibility - element names of nested
// elements have been all lower-case in Ant, except for
diff --git a/src/main/org/apache/tools/ant/taskdefs/defaults.properties b/src/main/org/apache/tools/ant/taskdefs/defaults.properties
index a9d792320..e9d06114e 100644
--- a/src/main/org/apache/tools/ant/taskdefs/defaults.properties
+++ b/src/main/org/apache/tools/ant/taskdefs/defaults.properties
@@ -191,6 +191,7 @@ scp=org.apache.tools.ant.taskdefs.optional.ssh.Scp
sshexec=org.apache.tools.ant.taskdefs.optional.ssh.SSHExec
jsharpc=org.apache.tools.ant.taskdefs.optional.dotnet.JSharp
rexec=org.apache.tools.ant.taskdefs.optional.net.RExecTask
+scriptdef=org.apache.tools.ant.taskdefs.optional.script.ScriptDef
# deprecated ant tasks (kept for back compatibility)
starteam=org.apache.tools.ant.taskdefs.optional.scm.AntStarTeamCheckOut
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/script/ScriptDef.java b/src/main/org/apache/tools/ant/taskdefs/optional/script/ScriptDef.java
new file mode 100644
index 000000000..d3398b4c2
--- /dev/null
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/script/ScriptDef.java
@@ -0,0 +1,397 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 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 "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
+ * .
+ */
+package org.apache.tools.ant.taskdefs.optional.script;
+
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.MagicNames;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.RuntimeConfigurable;
+import org.apache.tools.ant.UnknownElement;
+
+import java.util.Map;
+import java.util.HashMap;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Locale;
+
+import org.apache.bsf.BSFException;
+import org.apache.bsf.BSFManager;
+
+/**
+ * Define a task using a script
+ *
+ * @author Conor MacNeill
+ * @since Ant 1.6
+ */
+public class ScriptDef extends Task {
+ /** the name by which this script will be activated */
+ private String name;
+
+ /** the scripting language used by the script */
+ private String language;
+
+ /** the script itself */
+ private String script = "";
+
+ /** Attributes definitions of this script */
+ private List attributes = new ArrayList();
+
+ /** Nested Element definitions of this script */
+ private List nestedElements = new ArrayList();
+
+ /** The attribute names as a set */
+ private Set attributeSet;
+
+ /** The nested element definitions indexed by their names */
+ private Map nestedElementMap;
+
+ /**
+ * set the name under which this script will be activated in a build
+ * file
+ *
+ * @param name the name of the script
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ /**
+ * Set the scripting language used by this script
+ *
+ * @param language the scripting language used by this script.
+ */
+ public void setLanguage(String language) {
+ this.language = language;
+ }
+
+ /**
+ * Class representing an attribute definition
+ */
+ public static class Attribute {
+ /** The attribute name */
+ private String name;
+
+ /**
+ * Set the attribute name
+ *
+ * @param name the attribute name
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+ }
+
+ /**
+ * Add an attribute definition to this script.
+ *
+ * @param attribute the attribute definition.
+ */
+ public void addAttribute(Attribute attribute) {
+ attributes.add(attribute);
+ }
+
+ /**
+ * Class to represent a nested element definition
+ */
+ public static class NestedElement {
+ /** The name of the neseted element */
+ private String name;
+
+ /** The Ant type to which this nested element corresponds. */
+ private String type;
+
+ /** The class to be created for this nested element */
+ private String className;
+
+ /**
+ * set the tag name for this nested element
+ *
+ * @param name the name of this nested element
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ /**
+ * Set the type of this element. This is the name of an
+ * Ant task or type which is to be used when this element is to be
+ * created. This is an alternative to specifying the class name directly
+ *
+ * @param type the name of an Ant type, or task, to use for this nested
+ * element.
+ */
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ /**
+ * Set the classname of the class to be used for the nested element.
+ * This specifies the class directly and is an alternative to specifying
+ * the Ant type name.
+ *
+ * @param className the name of the class to use for this nested
+ * element.
+ */
+ public void setClassName(String className) {
+ this.className = className;
+ }
+ }
+
+ /**
+ * Add a nested element definition.
+ *
+ * @param nestedElement the nested element definition.
+ */
+ public void addElement(NestedElement nestedElement) {
+ nestedElements.add(nestedElement);
+ }
+
+ /**
+ * Define the script.
+ */
+ public void execute() {
+ if (name == null) {
+ throw new BuildException("scriptdef requires a name attribute to "
+ + "name the script");
+ }
+
+ if (language == null) {
+ throw new BuildException("scriptdef requires a language attribute "
+ + "to specify the script language");
+ }
+
+ attributeSet = new HashSet();
+ for (Iterator i = attributes.iterator(); i.hasNext();) {
+ Attribute attribute = (Attribute) i.next();
+ if (attribute.name == null) {
+ throw new BuildException("scriptdef elements "
+ + "must specify an attribute name");
+ }
+
+ if (attributeSet.contains(attribute.name)) {
+ throw new BuildException("scriptdef <" + name + "> declares "
+ + "the " + attribute.name + " attribute more than once");
+ }
+ attributeSet.add(attribute.name);
+ }
+
+ nestedElementMap = new HashMap();
+ for (Iterator i = nestedElements.iterator(); i.hasNext();) {
+ NestedElement nestedElement = (NestedElement) i.next();
+ if (nestedElement.name == null) {
+ throw new BuildException("scriptdef elements "
+ + "must specify an element name");
+ }
+ if (nestedElementMap.containsKey(nestedElement.name)) {
+ throw new BuildException("scriptdef <" + name + "> declares "
+ + "the " + nestedElement.name + " nested element more "
+ + "than once");
+ }
+
+ if (nestedElement.className == null
+ && nestedElement.type == null) {
+ throw new BuildException("scriptdef elements "
+ + "must specify either a classname or type attribute");
+ }
+ if (nestedElement.className != null
+ && nestedElement.type != null) {
+ throw new BuildException("scriptdef elements "
+ + "must specify only one of the classname and type "
+ + "attributes");
+ }
+
+
+ nestedElementMap.put(nestedElement.name, nestedElement);
+ }
+
+ // find the script repository - it is stored in the project
+ Map scriptRepository = null;
+ Project project = getProject();
+ synchronized (project) {
+ scriptRepository =
+ (Map) project.getReference(MagicNames.SCRIPT_REPOSITORY);
+ if (scriptRepository == null) {
+ scriptRepository = new HashMap();
+ project.addReference(MagicNames.SCRIPT_REPOSITORY,
+ scriptRepository);
+ }
+ }
+
+ scriptRepository.put(name, this);
+ project.addTaskDefinition(name, ScriptDefBase.class);
+ }
+
+ /**
+ * Execute the script.
+ *
+ * @param scriptConfig the RuntimeConfigurable which contains the attribute
+ * definitions for the script task instance.
+ *
+ * @param elements a list of UnknownElements which contain the configuration
+ * of the nested elements of the script instance.
+ */
+ public void executeScript(RuntimeConfigurable scriptConfig, List elements) {
+
+ Map configAttributes = scriptConfig.getAttributeMap();
+ for (Iterator i = configAttributes.keySet().iterator(); i.hasNext();) {
+ String attributeName = (String) i.next();
+ if (!attributeSet.contains(attributeName)) {
+ throw new BuildException("<" + name + "> does not support "
+ + "the \"" + attributeName + "\" attribute");
+ }
+ }
+
+ // handle nested elements
+ Map elementInstances = new HashMap();
+ for (Iterator i = elements.iterator(); i.hasNext();) {
+ UnknownElement element = (UnknownElement) i.next();
+ String elementTag = element.getTag().toLowerCase(Locale.US);
+
+ NestedElement definition
+ = (NestedElement) nestedElementMap.get(elementTag);
+ if (definition == null) {
+ throw new BuildException("<" + name + "> does not support "
+ + "the <" + elementTag + "> nested element");
+ }
+
+ // what is the type of the object to be created
+ Object instance = null;
+ String classname = definition.className;
+ if (classname == null) {
+ instance = getProject().createTask(definition.type);
+ if (instance == null) {
+ instance = getProject().createDataType(definition.type);
+ }
+ } else {
+ // try the context classloader
+ ClassLoader loader
+ = Thread.currentThread().getContextClassLoader();
+
+ Class instanceClass = null;
+ try {
+ instanceClass = Class.forName(classname, true, loader);
+ } catch (Throwable e) {
+ // try normal method
+ try {
+ instanceClass = Class.forName(classname);
+ } catch (Throwable e2) {
+ throw new BuildException("scriptdef: Unable to load "
+ + "class " + classname + " for nested element <"
+ + elementTag + ">", e2);
+ }
+ }
+
+ try {
+ instance = instanceClass.newInstance();
+ } catch (Throwable e) {
+ throw new BuildException("scriptdef: Unable to create "
+ + "element of class " + classname + " for nested "
+ + "element <" + elementTag + ">", e);
+ }
+ getProject().setProjectReference(instance);
+ }
+
+ if (instance == null) {
+ throw new BuildException("<" + name + "> is unable to create "
+ + "the <" + elementTag + "> nested element");
+ }
+
+ element.configure(instance);
+
+ // find the appropriate list
+ List instanceList = (List) elementInstances.get(elementTag);
+ if (instanceList == null) {
+ instanceList = new ArrayList();
+ elementInstances.put(elementTag, instanceList);
+ }
+ instanceList.add(instance);
+ }
+
+ try {
+ BSFManager manager = new BSFManager();
+ // execute the script
+ manager.declareBean("attributes", configAttributes,
+ configAttributes.getClass());
+ manager.declareBean("elements", elementInstances,
+ elementInstances.getClass());
+ manager.declareBean("project", getProject(), Project.class);
+ manager.exec(language, "scriptdef <" + name + ">", 0, 0, script);
+ } catch (BSFException e) {
+ Throwable t = e;
+ Throwable te = e.getTargetException();
+ if (te != null) {
+ if (te instanceof BuildException) {
+ throw (BuildException) te;
+ } else {
+ t = te;
+ }
+ }
+ throw new BuildException(t);
+ }
+ }
+
+ /**
+ * Ass the scipt text.
+ *
+ * @param text appended to the script text.
+ */
+ public void addText(String text) {
+ this.script += text;
+ }
+}
+
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/script/ScriptDefBase.java b/src/main/org/apache/tools/ant/taskdefs/optional/script/ScriptDefBase.java
new file mode 100644
index 000000000..6f313b566
--- /dev/null
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/script/ScriptDefBase.java
@@ -0,0 +1,115 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 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 "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
+ * .
+ */
+package org.apache.tools.ant.taskdefs.optional.script;
+
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.TaskContainer;
+import org.apache.tools.ant.MagicNames;
+import org.apache.tools.ant.BuildException;
+
+import java.util.Map;
+import java.util.List;
+import java.util.ArrayList;
+
+/**
+ * The script execution class. This class finds the defining script task
+ * and passes control to that task's executeScript method. This class
+ * implements the TaskCOntainer interface primarily to stop Ant's core from
+ * configuring the nested elements - this is done by the script task itself.
+ *
+ * @author Conor MacNeill
+ * @since Ant 1.6
+ */
+public class ScriptDefBase extends Task implements TaskContainer {
+
+ /** Nested elements - UnknownElements passed by Ant */
+ private List nestedElements = new ArrayList();
+
+ /**
+ * Locate the script defining task and execute the script by passing
+ * control to it
+ */
+ public void execute() {
+ String name = getTaskType();
+ Map scriptRepository
+ = (Map) getProject().getReference(MagicNames.SCRIPT_REPOSITORY);
+ if (scriptRepository == null) {
+ throw new BuildException("Script repository not found for " + name);
+ }
+
+ ScriptDef definition = (ScriptDef) scriptRepository.get(getTaskType());
+ if (definition == null) {
+ throw new BuildException("Script definition not found for " + name);
+ }
+ definition.executeScript(getWrapper(), nestedElements);
+ }
+
+ /**
+ * Method overridden to prevent configuration of this task by the core
+ */
+ public void maybeConfigure() {
+ // don't configure now - do it at script execute time
+ }
+
+ /**
+ * TaskContainer method implemented to prevent processing of the task
+ * instance by the Ant Core.
+ *
+ * @param nestedElement the nestedElement as an UnknownElement.
+ */
+ public void addTask(Task nestedElement) {
+ nestedElements.add(nestedElement);
+ }
+}
+
diff --git a/src/testcases/org/apache/tools/ant/BuildFileTest.java b/src/testcases/org/apache/tools/ant/BuildFileTest.java
index fba4ea981..883834b79 100644
--- a/src/testcases/org/apache/tools/ant/BuildFileTest.java
+++ b/src/testcases/org/apache/tools/ant/BuildFileTest.java
@@ -163,7 +163,7 @@ public abstract class BuildFileTest extends TestCase {
protected void expectOutput(String target, String output) {
executeTarget(target);
String realOutput = getOutput();
- assertEquals(output, realOutput);
+ assertEquals(output, realOutput.trim());
}
/**
diff --git a/src/testcases/org/apache/tools/ant/taskdefs/optional/script/ScriptDefTest.java b/src/testcases/org/apache/tools/ant/taskdefs/optional/script/ScriptDefTest.java
new file mode 100644
index 000000000..95d69bfec
--- /dev/null
+++ b/src/testcases/org/apache/tools/ant/taskdefs/optional/script/ScriptDefTest.java
@@ -0,0 +1,144 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2002 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.optional.script;
+
+import org.apache.tools.ant.BuildFileTest;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.FileSet;
+import java.io.File;
+
+/**
+ * Tests the examples of the <scriptdef> task.
+ *
+ * @author Conor MacNeill
+ * @since Ant 1.6
+ */
+public class ScriptDefTest extends BuildFileTest {
+
+ public ScriptDefTest(String name) {
+ super(name);
+ }
+
+ /**
+ * The JUnit setup method
+ */
+ public void setUp() {
+ configureProject("src/etc/testcases/taskdefs/optional/script/scriptdef.xml");
+ }
+
+ public void testSimple() {
+ executeTarget("simple");
+ // get the fileset and its basedir
+ Project project = getProject();
+ FileSet fileset = (FileSet) project.getReference("testfileset");
+ File baseDir = fileset.getDir(project);
+ String log = getLog();
+ assertTrue("Expecting attribute value printed",
+ log.indexOf("Attribute attr1 = test") != -1);
+
+ assertTrue("Expecting nested element value printed",
+ log.indexOf("Fileset basedir = " + baseDir.getAbsolutePath()) != -1);
+ }
+
+ public void testNoLang() {
+ expectBuildExceptionContaining("nolang",
+ "Absence of language attribute not detected",
+ "requires a language attribute");
+ }
+
+ public void testNoName() {
+ expectBuildExceptionContaining("noname",
+ "Absence of name attribute not detected",
+ "scriptdef requires a name attribute");
+ }
+
+ public void testNestedByClassName() {
+ executeTarget("nestedbyclassname");
+ // get the fileset and its basedir
+ Project project = getProject();
+ FileSet fileset = (FileSet) project.getReference("testfileset");
+ File baseDir = fileset.getDir(project);
+ String log = getLog();
+ assertTrue("Expecting attribute value to be printed",
+ log.indexOf("Attribute attr1 = test") != -1);
+
+ assertTrue("Expecting nested element value to be printed",
+ log.indexOf("Fileset basedir = " + baseDir.getAbsolutePath()) != -1);
+ }
+
+ public void testNoElement() {
+ expectOutput("noelement", "Attribute attr1 = test");
+ }
+
+ public void testException() {
+ expectBuildExceptionContaining("exception",
+ "Should have thrown an exception in the script",
+ "TypeError");
+ }
+
+ public void testDoubleDef() {
+ executeTarget("doubledef");
+ String log = getLog();
+ assertTrue("Task1 did not execute",
+ log.indexOf("Task1") != -1);
+ assertTrue("Task2 did not execute",
+ log.indexOf("Task2") != -1);
+ }
+
+ public void testDoubleAttribute() {
+ expectBuildExceptionContaining("doubleAttributeDef",
+ "Should have detected duplicate attribute definition",
+ "attr1 attribute more than once");
+ }
+}