From b28f2604755c621fa63bda2c71deefb29aaca9b9 Mon Sep 17 00:00:00 2001 From: Costin Manolache Date: Fri, 11 Oct 2002 18:06:26 +0000 Subject: [PATCH] Various fixes and changes to support more lazy creation of tasks and the other changes. git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@273435 13f79535-47bb-0310-9956-ffa450edef68 --- .../tools/ant/RuntimeConfigurable2.java | 245 +++++++++++++++++- 1 file changed, 237 insertions(+), 8 deletions(-) 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 648883f1e..f05f853af 100644 --- a/proposal/embed/src/java/org/apache/tools/ant/RuntimeConfigurable2.java +++ b/proposal/embed/src/java/org/apache/tools/ant/RuntimeConfigurable2.java @@ -77,17 +77,20 @@ import org.xml.sax.helpers.AttributesImpl; */ public class RuntimeConfigurable2 extends RuntimeConfigurable { - /** Name of the element to configure. */ - private String elementTag = null; - /** List of child element wrappers. */ + /** Name of the element to configure. elementName in UE */ + private String elementTag = null; + /** List of child element wrappers. */ private Vector children = new Vector(); - /** The element to configure. */ + /** The element to configure. realThing in UE */ private Object wrappedObject = null; /** XML attributes for the element. */ private Attributes attributes; /** Text appearing within the element. */ private StringBuffer characters = new StringBuffer(); + Project project; + protected Location location = Location.UNKNOWN_LOCATION; + /** * Sole constructor creating a wrapper for the specified object. * @@ -95,14 +98,24 @@ public class RuntimeConfigurable2 extends RuntimeConfigurable { * @param elementTag The tag name generating this element. * Should not be null. */ - public RuntimeConfigurable2(Object proxy, String elementTag) { + 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 ); } + Project getProject() { + return project; + } + + Location getLocation() { + return location; + } /** * Sets the element to configure. This is used when the real type of * an element isn't known at the time of wrapper creation. @@ -169,6 +182,7 @@ public class RuntimeConfigurable2 extends RuntimeConfigurable { * Must not be null. */ public void addChild(RuntimeConfigurable child) { + // addChild( UnknownElement ) in UE children.addElement(child); } @@ -214,6 +228,7 @@ public class RuntimeConfigurable2 extends RuntimeConfigurable { * to be null, but may be. */ public String getElementTag() { + // getTag in UE return elementTag; } @@ -237,15 +252,20 @@ public class RuntimeConfigurable2 extends RuntimeConfigurable { public void maybeConfigure(Project p) throws BuildException { String id = null; + PropertyHelper ph=PropertyHelper.getPropertyHelper(p); + if (attributes != null) { - PropertyHelper ph=PropertyHelper.getPropertyHelper(p); ph.configure(wrappedObject, attributes, p); id = attributes.getValue("id"); attributes = null; } if (characters.length() != 0) { - ProjectHelper.addText(p, wrappedObject, characters.toString()); + // 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); } Enumeration enum = children.elements(); @@ -264,7 +284,216 @@ public class RuntimeConfigurable2 extends RuntimeConfigurable { } if (id != null) { - p.addReference(id, wrappedObject); + // p.addReference(id, wrappedObject); + 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()); +// } + +// 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; +// } + }