diff --git a/build.xml b/build.xml index d4afee9f7..4d0b40dde 100644 --- a/build.xml +++ b/build.xml @@ -12,7 +12,7 @@ - + @@ -178,6 +178,8 @@ + + @@ -185,6 +187,7 @@ + @@ -302,11 +305,6 @@ - - - - - + + - + + +Bla + + diff --git a/docs/index.html b/docs/index.html index 3cbb80678..65e6d406f 100644 --- a/docs/index.html +++ b/docs/index.html @@ -1002,7 +1002,17 @@ execution depending on system parameters.

file the file to look for. + + classpath the classpath to + use when looking up classname. No + +

Parameters specified as nested elements

+

classpath

+

Available's classpath attribute is a PATH like structure and can also be set via a nested +classpath element.

Examples

  <available classname="org.whatever.Myclass" property="Myclass.present" />

sets the property Myclass.present to the value "true" @@ -3650,7 +3660,17 @@ href="#writingowntask">Writing your own task".

the full class name implementing the task Yes + + classpath the classpath to + use when looking up classname. No + +

Parameters specified as nested elements

+

classpath

+

Taskdef's classpath attribute is a PATH like structure and can also be set via a nested +classpath element.

Examples

  <taskdef name="myjavadoc" classname="com.mydomain.JavadocTask" />

makes a task called myjavadoc available to Ant. The class com.mydomain.JavadocTask diff --git a/src/main/org/apache/tools/ant/Project.java b/src/main/org/apache/tools/ant/Project.java index bfbf6e10d..6f7bd5c2e 100644 --- a/src/main/org/apache/tools/ant/Project.java +++ b/src/main/org/apache/tools/ant/Project.java @@ -429,9 +429,7 @@ public class Project { Class c = (Class) taskClassDefinitions.get(taskType); if (c == null) - throw new BuildException("Could not create task of type: "+taskType+ - " because I can't find it in the list of task"+ - " class definitions"); + return null; try { Object o = c.newInstance(); Task task = null; diff --git a/src/main/org/apache/tools/ant/ProjectHelper.java b/src/main/org/apache/tools/ant/ProjectHelper.java index c25c170c0..a6616c57e 100644 --- a/src/main/org/apache/tools/ant/ProjectHelper.java +++ b/src/main/org/apache/tools/ant/ProjectHelper.java @@ -363,7 +363,17 @@ public class ProjectHelper { } public void init(String tag, AttributeList attrs) throws SAXParseException { - task = project.createTask(tag); + try { + task = project.createTask(tag); + } catch (BuildException e) { + // swallow here, will be thrown again in + // UnknownElement.maybeConfigure if the problem persists. + } + + if (task == null) { + task = new UnknownElement(tag); + task.setProject(project); + } task.setLocation(new Location(buildFile.toString(), locator.getLineNumber(), locator.getColumnNumber())); configureId(task, attrs); @@ -422,7 +432,13 @@ public class ProjectHelper { IntrospectionHelper.getHelper(targetClass); try { - child = ih.createElement(target, propType.toLowerCase()); + if (target instanceof UnknownElement) { + child = new UnknownElement(propType.toLowerCase()); + ((UnknownElement) target).addChild((UnknownElement) child); + } else { + child = ih.createElement(target, propType.toLowerCase()); + } + configureId(child, attrs); if (parentWrapper != null) { diff --git a/src/main/org/apache/tools/ant/RuntimeConfigurable.java b/src/main/org/apache/tools/ant/RuntimeConfigurable.java index 1c271cb4b..a2c705f84 100644 --- a/src/main/org/apache/tools/ant/RuntimeConfigurable.java +++ b/src/main/org/apache/tools/ant/RuntimeConfigurable.java @@ -80,6 +80,10 @@ public class RuntimeConfigurable { wrappedObject = proxy; } + void setProxy(Object proxy) { + wrappedObject = proxy; + } + /** * Set's the attributes for the wrapped element. */ @@ -87,6 +91,13 @@ public class RuntimeConfigurable { this.attributes = new AttributeListImpl(attributes); } + /** + * Returns the AttributeList of the wrapped element. + */ + public AttributeList getAttributes() { + return attributes; + } + /** * Adds child elements to the wrapped element. */ @@ -94,6 +105,13 @@ public class RuntimeConfigurable { children.addElement(child); } + /** + * Returns the child with index index. + */ + RuntimeConfigurable getChild(int index) { + return (RuntimeConfigurable) children.elementAt(index); + } + /** * Add characters from #PCDATA areas to the wrapped element. */ diff --git a/src/main/org/apache/tools/ant/Target.java b/src/main/org/apache/tools/ant/Target.java index 390d31781..4d8c9ecf3 100644 --- a/src/main/org/apache/tools/ant/Target.java +++ b/src/main/org/apache/tools/ant/Target.java @@ -159,6 +159,13 @@ public class Target { } } + void replaceTask(UnknownElement el, Task t) { + int index = -1; + while ((index = tasks.indexOf(el)) >= 0) { + tasks.setElementAt(t, index); + } + } + private boolean testIfCondition() { return "".equals(ifCondition) || project.getProperty(ifCondition) != null; diff --git a/src/main/org/apache/tools/ant/Task.java b/src/main/org/apache/tools/ant/Task.java index f2e497a28..e7e5eaa45 100644 --- a/src/main/org/apache/tools/ant/Task.java +++ b/src/main/org/apache/tools/ant/Task.java @@ -205,6 +205,10 @@ public abstract class Task { return wrapper; } + protected void setRuntimeConfigurableWrapper(RuntimeConfigurable wrapper) { + this.wrapper = wrapper; + } + /** * Configure this task - if it hasn't been done already. */ diff --git a/src/main/org/apache/tools/ant/UnknownElement.java b/src/main/org/apache/tools/ant/UnknownElement.java new file mode 100644 index 000000000..e515de025 --- /dev/null +++ b/src/main/org/apache/tools/ant/UnknownElement.java @@ -0,0 +1,145 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2000 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", "Tomcat", 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; + +import java.util.Vector; + +/** + * Wrapper class that holds all information necessary to create a task + * that did not exist when Ant started. + * + * @author Stefan Bodewig + */ +public class UnknownElement extends Task { + + private String elementName; + private Task realTask; + private Vector children = new Vector(); + + public UnknownElement (String elementName) { + this.elementName = elementName; + } + + /** + * return the corresponding XML tag. + */ + public String getTag() { + return elementName; + } + + public void maybeConfigure() throws BuildException { + realTask = project.createTask(elementName); + if (realTask == null) { + throw new BuildException("Could not create task of type: "+elementName+ + " because I can\'t find it in the list of task"+ + " class definitions", location); + } + + realTask.setLocation(location); + String id = wrapper.getAttributes().getValue("id"); + if (id != null) { + project.addReference(id, realTask); + } + realTask.init(); + + // UnknownElement always has an associated target + realTask.setOwningTarget(target); + + wrapper.setProxy(realTask); + realTask.setRuntimeConfigurableWrapper(wrapper); + + handleChildren(realTask, wrapper); + + realTask.maybeConfigure(); + target.replaceTask(this, realTask); + } + + /** + * Called when the real task has been configured for the first time. + */ + public void execute() { + if (realTask == null) { + // plain impossible to get here, maybeConfigure should + // have thrown an exception. + throw new BuildException("Could not create task of type: " + + elementName, location); + } + realTask.execute(); + } + + public void addChild(UnknownElement child) { + children.addElement(child); + } + + protected void handleChildren(Object parent, + RuntimeConfigurable parentWrapper) + throws BuildException { + + if (parent instanceof TaskAdapter) { + parent = ((TaskAdapter) parent).getProxy(); + } + Class parentClass = parent.getClass(); + IntrospectionHelper ih = IntrospectionHelper.getHelper(parentClass); + + for (int i=0; i