git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@708204 13f79535-47bb-0310-9956-ffa450edef68master
| @@ -270,6 +270,10 @@ Fixed bugs: | |||
| TaskContainers at the same time. | |||
| Bugzilla Report 41647. | |||
| * Tasks that implementes DynamicElemen or DynamicElementNS failed to | |||
| work as TaskContainers at the same time. | |||
| Bugzilla Report 41647. | |||
| Other changes: | |||
| -------------- | |||
| @@ -474,6 +474,21 @@ public final class IntrospectionHelper { | |||
| } | |||
| } | |||
| /** | |||
| * part of the error message created by {@link #throwNotSupported | |||
| * throwNotSupported}. | |||
| * @since Ant 1.8.0 | |||
| */ | |||
| protected static final String NOT_SUPPORTED_CHILD_PREFIX = | |||
| " doesn't support the nested \""; | |||
| /** | |||
| * part of the error message created by {@link #throwNotSupported | |||
| * throwNotSupported}. | |||
| * @since Ant 1.8.0 | |||
| */ | |||
| protected static final String NOT_SUPPORTED_CHILD_POSTFIX = "\" element."; | |||
| /** | |||
| * Utility method to throw a NotSupported exception | |||
| * | |||
| @@ -483,7 +498,8 @@ public final class IntrospectionHelper { | |||
| */ | |||
| public void throwNotSupported(Project project, Object parent, String elementName) { | |||
| String msg = project.getElementName(parent) | |||
| + " doesn't support the nested \"" + elementName + "\" element."; | |||
| + NOT_SUPPORTED_CHILD_PREFIX + elementName | |||
| + NOT_SUPPORTED_CHILD_POSTFIX; | |||
| throw new UnsupportedElementException(msg, elementName); | |||
| } | |||
| @@ -690,42 +706,26 @@ public final class IntrospectionHelper { | |||
| * Indicate if this element supports a nested element of the | |||
| * given name. | |||
| * | |||
| * <p>Note that this method will always return true if the | |||
| * introspected class is {@link #isDynamic dynamic}, so be | |||
| * prepared to catch an exception about unsupported children when | |||
| * calling {@link #getElementCreator getElementCreator}.</p> | |||
| * | |||
| * @param parentUri the uri of the parent | |||
| * @param elementName the name of the nested element being checked | |||
| * @param project currently executing project instance | |||
| * @param parent the parent element (an instance of the introspected class) | |||
| * @param childQName QName of the child element, may be null | |||
| * @param parent the parent element | |||
| * | |||
| * @return true if the given nested element is supported | |||
| * @since Ant 1.8.0. | |||
| */ | |||
| public boolean supportsNestedElement(String parentUri, String elementName, | |||
| Project project, Object parent, | |||
| String childQName) { | |||
| Project project, Object parent) { | |||
| if (addTypeMethods.size() > 0 | |||
| && createAddTypeCreator(project, parent, elementName) != null) { | |||
| return true; | |||
| } | |||
| if (isDynamic()) { | |||
| /* | |||
| breaks several tests, in particular EchoXML because it | |||
| creates additional empty child elements in XMLFragment | |||
| String localName = | |||
| ProjectHelper.extractNameFromComponentName(elementName); | |||
| String uri = ProjectHelper.extractUriFromComponentName(elementName); | |||
| if (uri.equals(ProjectHelper.ANT_CORE_URI)) { | |||
| uri = ""; | |||
| } | |||
| if (createDynamicElement(parent, uri, localName, | |||
| childQName == null ? localName : childQName) | |||
| != null) { | |||
| return true; | |||
| } | |||
| */ | |||
| return true; | |||
| } | |||
| return supportsReflectElement(parentUri, elementName); | |||
| return isDynamic() || supportsReflectElement(parentUri, elementName); | |||
| } | |||
| /** | |||
| @@ -542,11 +542,19 @@ public class UnknownElement extends Task { | |||
| RuntimeConfigurable childWrapper) { | |||
| String childName = ProjectHelper.genComponentName( | |||
| child.getNamespace(), child.getTag()); | |||
| if (ih.supportsNestedElement(parentUri, childName, | |||
| getProject(), parent, child.getQName())) { | |||
| IntrospectionHelper.Creator creator = | |||
| ih.getElementCreator( | |||
| getProject(), parentUri, parent, childName, child); | |||
| if (ih.supportsNestedElement(parentUri, childName, getProject(), | |||
| parent)) { | |||
| IntrospectionHelper.Creator creator = null; | |||
| try { | |||
| creator = ih.getElementCreator(getProject(), parentUri, | |||
| parent, childName, child); | |||
| } catch (UnsupportedElementException use) { | |||
| if (!ih.isDynamic()) { | |||
| throw use; | |||
| } | |||
| // can't trust supportsNestedElement for dynamic elements | |||
| return false; | |||
| } | |||
| creator.setPolyType(childWrapper.getPolyType()); | |||
| Object realChild = creator.create(); | |||
| if (realChild instanceof PreSetDef.PreSetDefinition) { | |||
| @@ -19,7 +19,7 @@ | |||
| <import file="../antunit-base.xml"/> | |||
| <target name="testConditionBaseAndTasContainer"> | |||
| <target name="testConditionBaseAndTaskContainer"> | |||
| <mkdir dir="${input}"/> | |||
| <mkdir dir="${output}"/> | |||
| <echo file="${input}/ConditionRun.java"> | |||
| @@ -51,4 +51,75 @@ public class ConditionRun extends ConditionBase implements TaskContainer { | |||
| </conditionrun> | |||
| <au:assertLogContains text="Hello"/> | |||
| </target> | |||
| <target name="testDynamicElementAndTaskContainer"> | |||
| <mkdir dir="${input}"/> | |||
| <mkdir dir="${output}"/> | |||
| <echo file="${input}/Dynamic.java"> | |||
| import org.apache.tools.ant.*; | |||
| import java.util.*; | |||
| public class Dynamic implements TaskContainer, DynamicElement { | |||
| private List tasks = new ArrayList(); | |||
| public void addTask(Task task) { | |||
| tasks.add(task); | |||
| } | |||
| public void execute() { | |||
| for (Iterator iter = tasks.iterator(); iter.hasNext(); ) { | |||
| Task t = (Task) iter.next(); | |||
| t.perform(); | |||
| } | |||
| } | |||
| public Object createDynamicElement(String name) { | |||
| return null; | |||
| } | |||
| } | |||
| </echo> | |||
| <javac destdir="${output}" | |||
| srcdir="${input}"/> | |||
| <taskdef name="dyn" classpath="${output}" | |||
| classname="Dynamic"/> | |||
| <dyn> | |||
| <echo>Hello</echo> | |||
| </dyn> | |||
| <au:assertLogContains text="Hello"/> | |||
| </target> | |||
| <target name="testDynamicElementNSAndTaskContainer"> | |||
| <mkdir dir="${input}"/> | |||
| <mkdir dir="${output}"/> | |||
| <echo file="${input}/Dynamic.java"> | |||
| import org.apache.tools.ant.*; | |||
| import java.util.*; | |||
| public class Dynamic implements TaskContainer, DynamicElementNS { | |||
| private List tasks = new ArrayList(); | |||
| public void addTask(Task task) { | |||
| tasks.add(task); | |||
| } | |||
| public void execute() { | |||
| for (Iterator iter = tasks.iterator(); iter.hasNext(); ) { | |||
| Task t = (Task) iter.next(); | |||
| t.perform(); | |||
| } | |||
| } | |||
| public Object createDynamicElement(String uri, String localName, | |||
| String qName) { | |||
| return null; | |||
| } | |||
| } | |||
| </echo> | |||
| <javac destdir="${output}" | |||
| srcdir="${input}"/> | |||
| <taskdef name="dyn" classpath="${output}" | |||
| classname="Dynamic"/> | |||
| <dyn> | |||
| <echo>Hello</echo> | |||
| </dyn> | |||
| <au:assertLogContains text="Hello"/> | |||
| </target> | |||
| </project> | |||