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. | TaskContainers at the same time. | ||||
| Bugzilla Report 41647. | Bugzilla Report 41647. | ||||
| * Tasks that implementes DynamicElemen or DynamicElementNS failed to | |||||
| work as TaskContainers at the same time. | |||||
| Bugzilla Report 41647. | |||||
| Other changes: | 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 | * Utility method to throw a NotSupported exception | ||||
| * | * | ||||
| @@ -483,7 +498,8 @@ public final class IntrospectionHelper { | |||||
| */ | */ | ||||
| public void throwNotSupported(Project project, Object parent, String elementName) { | public void throwNotSupported(Project project, Object parent, String elementName) { | ||||
| String msg = project.getElementName(parent) | 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); | throw new UnsupportedElementException(msg, elementName); | ||||
| } | } | ||||
| @@ -690,42 +706,26 @@ public final class IntrospectionHelper { | |||||
| * Indicate if this element supports a nested element of the | * Indicate if this element supports a nested element of the | ||||
| * given name. | * 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 parentUri the uri of the parent | ||||
| * @param elementName the name of the nested element being checked | * @param elementName the name of the nested element being checked | ||||
| * @param project currently executing project instance | * @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 | * @return true if the given nested element is supported | ||||
| * @since Ant 1.8.0. | * @since Ant 1.8.0. | ||||
| */ | */ | ||||
| public boolean supportsNestedElement(String parentUri, String elementName, | public boolean supportsNestedElement(String parentUri, String elementName, | ||||
| Project project, Object parent, | |||||
| String childQName) { | |||||
| Project project, Object parent) { | |||||
| if (addTypeMethods.size() > 0 | if (addTypeMethods.size() > 0 | ||||
| && createAddTypeCreator(project, parent, elementName) != null) { | && createAddTypeCreator(project, parent, elementName) != null) { | ||||
| return true; | 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) { | RuntimeConfigurable childWrapper) { | ||||
| String childName = ProjectHelper.genComponentName( | String childName = ProjectHelper.genComponentName( | ||||
| child.getNamespace(), child.getTag()); | 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()); | creator.setPolyType(childWrapper.getPolyType()); | ||||
| Object realChild = creator.create(); | Object realChild = creator.create(); | ||||
| if (realChild instanceof PreSetDef.PreSetDefinition) { | if (realChild instanceof PreSetDef.PreSetDefinition) { | ||||
| @@ -19,7 +19,7 @@ | |||||
| <import file="../antunit-base.xml"/> | <import file="../antunit-base.xml"/> | ||||
| <target name="testConditionBaseAndTasContainer"> | |||||
| <target name="testConditionBaseAndTaskContainer"> | |||||
| <mkdir dir="${input}"/> | <mkdir dir="${input}"/> | ||||
| <mkdir dir="${output}"/> | <mkdir dir="${output}"/> | ||||
| <echo file="${input}/ConditionRun.java"> | <echo file="${input}/ConditionRun.java"> | ||||
| @@ -51,4 +51,75 @@ public class ConditionRun extends ConditionBase implements TaskContainer { | |||||
| </conditionrun> | </conditionrun> | ||||
| <au:assertLogContains text="Hello"/> | <au:assertLogContains text="Hello"/> | ||||
| </target> | </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> | </project> | ||||