diff --git a/proposal/embed/src/java/org/apache/tools/ant/RuntimeConfigurable2.java b/proposal/embed/src/java/org/apache/tools/ant/RuntimeConfigurable2.java
index c16d0d1ec..8b4d6174b 100644
--- a/proposal/embed/src/java/org/apache/tools/ant/RuntimeConfigurable2.java
+++ b/proposal/embed/src/java/org/apache/tools/ant/RuntimeConfigurable2.java
@@ -65,8 +65,8 @@ import org.xml.sax.helpers.AttributeListImpl;
import org.xml.sax.helpers.AttributesImpl;
/**
- * Wrapper class that holds the attributes of an element, its children, and
- * any text within it. It then takes care of configuring that element at
+ * Wrapper class that holds the attributes of an element, its children, and
+ * any text within it. It then takes care of configuring that element at
* runtime.
*
* This uses SAX2 and a more flexible substitution mechansim, based on
@@ -87,13 +87,15 @@ public class RuntimeConfigurable2 extends RuntimeConfigurable {
private Attributes attributes;
/** Text appearing within the element. */
private StringBuffer characters = new StringBuffer();
+ /** Indicates if the wrapped object has been configured */
+ private boolean proxyConfigured = false;
Project project;
protected Location location = Location.UNKNOWN_LOCATION;
/**
* Sole constructor creating a wrapper for the specified object.
- *
+ *
* @param proxy The element to configure. Must not be null
.
* @param elementTag The tag name generating this element.
* Should not be null
.
@@ -101,12 +103,11 @@ public class RuntimeConfigurable2 extends RuntimeConfigurable {
public RuntimeConfigurable2(Project project, Location location, Object proxy, String elementTag) {
super( proxy, elementTag );
wrappedObject = proxy;
- this.location=location;
- this.project=project;
this.elementTag = elementTag;
// This should never happen - all objects are lazy
if( proxy instanceof Task )
((Task)proxy).setRuntimeConfigurableWrapper( this );
+ proxyConfigured=false;
}
Project getProject() {
@@ -117,13 +118,14 @@ public class RuntimeConfigurable2 extends RuntimeConfigurable {
return location;
}
/**
- * Sets the element to configure. This is used when the real type of
+ * Sets the element to configure. This is used when the real type of
* an element isn't known at the time of wrapper creation.
- *
+ *
* @param proxy The element to configure. Must not be null
.
*/
public void setProxy(Object proxy) {
wrappedObject = proxy;
+ proxyConfigured=false;
}
public Object getProxy() {
@@ -132,7 +134,7 @@ public class RuntimeConfigurable2 extends RuntimeConfigurable {
/**
* Sets the attributes for the wrapped element.
- *
+ *
* @param attributes List of attributes defined in the XML for this
* element. May be null
.
* @deprecated It shouldn't be called by anyone except ProjectHelper
@@ -250,8 +252,35 @@ public class RuntimeConfigurable2 extends RuntimeConfigurable {
* an element which doesn't accept it.
*/
public void maybeConfigure(Project p) throws BuildException {
+ maybeConfigure(p, true);
+ }
+
+ /**
+ * Configures the wrapped element. The attributes and text for
+ * the wrapped element are configured. Each time the wrapper is
+ * configured, the attributes and text for it are reset.
+ *
+ * If the element has an id
attribute, a reference
+ * is added to the project as well.
+ *
+ * @param p The project containing the wrapped element.
+ * Must not be null
.
+ *
+ * @param configureChildren Whether to configure child elements as
+ * well. if true, child elements will be configured after the
+ * wrapped element.
+ *
+ * @exception BuildException if the configuration fails, for instance due
+ * to invalid attributes or children, or text being added to
+ * an element which doesn't accept it.
+ */
+ public void maybeConfigure(Project p, boolean configureChildren)
+ throws BuildException {
String id = null;
+ if( proxyConfigured ) {
+ return;
+ }
PropertyHelper ph=PropertyHelper.getPropertyHelper(p);
if (attributes != null) {
@@ -259,14 +288,8 @@ public class RuntimeConfigurable2 extends RuntimeConfigurable {
id = attributes.getValue("id");
attributes = null;
}
-
if (characters.length() != 0) {
-// // First do substitution. This allows Message to work
-// // like . And it's more fun.
- String txt=characters.toString();
-// txt=ph.replaceProperties( txt );
- ProjectHelper.addText(p, wrappedObject, txt);
- characters.setLength(0);
+ ProjectHelper.addText(p, wrappedObject, characters.toString());
}
Enumeration enum = children.elements();
while (enum.hasMoreElements()) {
@@ -275,12 +298,19 @@ public class RuntimeConfigurable2 extends RuntimeConfigurable {
if (child.wrappedObject instanceof Task) {
Task childTask = (Task) child.wrappedObject;
childTask.setRuntimeConfigurableWrapper(child);
- childTask.maybeConfigure();
- } else {
- child.maybeConfigure(p);
}
- ProjectHelper.storeChild(p, wrappedObject, child.wrappedObject,
- child.getElementTag().toLowerCase(Locale.US));
+
+ if (configureChildren) {
+ if (child.wrappedObject instanceof Task) {
+ Task childTask = (Task) child.wrappedObject;
+ childTask.maybeConfigure();
+ } else {
+ child.maybeConfigure(p);
+ }
+ ProjectHelper.storeChild(p, wrappedObject, child.wrappedObject,
+ child.getElementTag()
+ .toLowerCase(Locale.US));
+ }
}
if (id != null) {
@@ -288,212 +318,10 @@ public class RuntimeConfigurable2 extends RuntimeConfigurable {
p.getReferences().put( id, wrappedObject );
//System.out.println("XXX updating reference " + this + " " + id + " " + wrappedObject );
}
- }
-
-
- // -------------------- Merged from UE
- RuntimeConfigurable getWrapper() {
- return this;
- }
-
-
- /**
- * Creates the real object instance and child elements, then configures
- * the attributes and text of the real object. This unknown element
- * is then replaced with the real object in the containing target's list
- * of children.
- *
- * @exception BuildException if the configuration fails
- */
- protected void maybeConfigureTask() throws BuildException {
-// wrappedObject = makeObject(this, getWrapper());
-// getWrapper().setProxy(wrappedObject);
-// if (wrappedObject instanceof Task) {
-// ((Task) wrappedObject).setRuntimeConfigurableWrapper(getWrapper());
-// }
+ proxyConfigured = true;
+ }
-// handleChildren(wrappedObject, getWrapper());
-// getWrapper().maybeConfigure(getProject());
- }
-
- /**
- * Creates child elements, creates children of the children
- * (recursively), and sets attributes of the child elements.
- *
- * @param parent The configured object for the parent.
- * Must not be null
.
- *
- * @param parentWrapper The wrapper containing child wrappers
- * to be configured. Must not be null
- * if there are any children.
- *
- * @exception BuildException if the children cannot be configured.
- */
- 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 < children.size(); i++) {
- RuntimeConfigurable childWrapper = parentWrapper.getChild(i);
- UnknownElement child = (UnknownElement) children.elementAt(i);
- Object realChild = null;
-
- if (parent instanceof TaskContainer) {
- realChild = makeTask(child, childWrapper, false);
- ((TaskContainer) parent).addTask((Task) realChild);
- } else {
- realChild = ih.createElement(getProject(), parent, child.getTag());
- }
-
- childWrapper.setProxy(realChild);
- if (parent instanceof TaskContainer) {
- ((Task) realChild).setRuntimeConfigurableWrapper(childWrapper);
- }
-
- child.handleChildren(realChild, childWrapper);
-
- if (parent instanceof TaskContainer) {
- ((Task) realChild).maybeConfigure();
- }
- }
- }
-
- /**
- * Creates a named task or data type. If the real object is a task,
- * it is configured up to the init() stage.
- *
- * @param ue The unknown element to create the real object for.
- * Must not be null
.
- * @param w Ignored in this implementation.
- *
- * @return the task or data type represented by the given unknown element.
- */
-// protected Object makeObject(UnknownElement ue, RuntimeConfigurable w) {
-// Object o = makeTask(ue, w, true);
-// if (o == null) {
-// o = getProject().createDataType(ue.getTag());
-// }
-// if (o == null) {
-// throw getNotFoundException("task or type", ue.getTag());
-// }
-// return o;
-// }
-
- /**
- * Creates a named task and configures it up to the init() stage.
- *
- * @param ue The UnknownElement to create the real task for.
- * Must not be null
.
- * @param w Ignored.
- * @param onTopLevel Whether or not this is definitely trying to create
- * a task. If this is true
and the
- * task name is not recognised, a BuildException
- * is thrown.
- *
- * @return the task specified by the given unknown element, or
- * null
if the task name is not recognised and
- * onTopLevel is false
.
- */
- protected Task makeTask(UnknownElement ue, RuntimeConfigurable w,
- boolean onTopLevel) {
- Task task = getProject().createTask(ue.getTag());
- if (task == null && !onTopLevel) {
- throw getNotFoundException("task", ue.getTag());
- }
-
- if (task != null) {
- task.setLocation(getLocation());
- // UnknownElement always has an associated target
-// task.setOwningTarget(getOwningTarget());
- task.init();
- }
- return task;
- }
- /**
- * Returns a very verbose exception for when a task/data type cannot
- * be found.
- *
- * @param what The kind of thing being created. For example, when
- * a task name could not be found, this would be
- * "task"
. Should not be null
.
- * @param elementName The name of the element which could not be found.
- * Should not be null
.
- *
- * @return a detailed description of what might have caused the problem.
- */
- protected BuildException getNotFoundException(String what,
- String elementName) {
- String lSep = System.getProperty("line.separator");
- String msg = "Could not create " + what + " of type: " + elementName
- + "." + lSep + lSep
- + "Ant could not find the task or a class this "
- + "task relies upon." + lSep + lSep
- + "This is common and has a number of causes; the usual " + lSep
- + "solutions are to read the manual pages then download and" + lSep
- + "install needed JAR files, or fix the build file: " + lSep
- + " - You have misspelt '" + elementName + "'." + lSep
- + " Fix: check your spelling." + lSep
- + " - The task needs an external JAR file to execute" + lSep
- + " and this is not found at the right place in the classpath." + lSep
- + " Fix: check the documentation for dependencies." + lSep
- + " Fix: declare the task." + lSep
- + " - The task is an Ant optional task and optional.jar is absent" + lSep
- + " Fix: look for optional.jar in ANT_HOME/lib, download if needed" + lSep
- + " - The task was not built into optional.jar as dependent" + lSep
- + " libraries were not found at build time." + lSep
- + " Fix: look in the JAR to verify, then rebuild with the needed" + lSep
- + " libraries, or download a release version from apache.org" + lSep
- + " - The build file was written for a later version of Ant" + lSep
- + " Fix: upgrade to at least the latest release version of Ant" + lSep
- + " - The task is not an Ant core or optional task " + lSep
- + " and needs to be declared using ." + lSep
- + lSep
- + "Remember that for JAR files to be visible to Ant tasks implemented" + lSep
- + "in ANT_HOME/lib, the files must be in the same directory or on the" + lSep
- + "classpath" + lSep
- + lSep
- + "Please neither file bug reports on this problem, nor email the" + lSep
- + "Ant mailing lists, until all of these causes have been explored," + lSep
- + "as this is not an Ant bug.";
-
-
- return new BuildException(msg, getLocation());
- }
-
- /**
- * Returns the name to use in logging messages.
- *
- * @return the name to use in logging messages.
- */
- public String getTaskName() {
-// return wrappedObject == null || !(wrappedObject instanceof Task) ?
-// super.getTaskName() : ((Task) wrappedObject).getTaskName();
- if( wrappedObject!=null && (wrappedObject instanceof Task))
- return ((Task) wrappedObject).getTaskName();
- else
- return elementTag;
- }
-
- /**
- * Returns the task instance after it has been created and if it is a task.
- *
- * @return a task instance or null
if the real object is not
- * a task.
- */
-// public Task getTask() {
-// if (wrappedObject instanceof Task) {
-// return (Task) wrappedObject;
-// }
-// return null;
-// }
}