From 28447bc7c09eb2a7210a267ca7a6fb2e54ee488f Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Mon, 27 Oct 2008 14:49:00 +0000 Subject: [PATCH] allow TaskContainer and DynamicElement(NS) to coexist. Hijacked PR 41647 for this. git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@708204 13f79535-47bb-0310-9956-ffa450edef68 --- WHATSNEW | 4 + .../apache/tools/ant/IntrospectionHelper.java | 50 ++++++------- .../org/apache/tools/ant/UnknownElement.java | 18 +++-- .../antunit/core/nested-elements-test.xml | 73 ++++++++++++++++++- 4 files changed, 114 insertions(+), 31 deletions(-) diff --git a/WHATSNEW b/WHATSNEW index dc909adc7..aad6c2f64 100644 --- a/WHATSNEW +++ b/WHATSNEW @@ -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: -------------- diff --git a/src/main/org/apache/tools/ant/IntrospectionHelper.java b/src/main/org/apache/tools/ant/IntrospectionHelper.java index 696c6675a..1204d98e1 100644 --- a/src/main/org/apache/tools/ant/IntrospectionHelper.java +++ b/src/main/org/apache/tools/ant/IntrospectionHelper.java @@ -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. * + *

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}.

+ * * @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); } /** diff --git a/src/main/org/apache/tools/ant/UnknownElement.java b/src/main/org/apache/tools/ant/UnknownElement.java index e78b5ac1a..739d57081 100644 --- a/src/main/org/apache/tools/ant/UnknownElement.java +++ b/src/main/org/apache/tools/ant/UnknownElement.java @@ -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) { diff --git a/src/tests/antunit/core/nested-elements-test.xml b/src/tests/antunit/core/nested-elements-test.xml index 955b8ba6e..e031c41b4 100644 --- a/src/tests/antunit/core/nested-elements-test.xml +++ b/src/tests/antunit/core/nested-elements-test.xml @@ -19,7 +19,7 @@ - + @@ -51,4 +51,75 @@ public class ConditionRun extends ConditionBase implements TaskContainer { + + + + + +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; + } +} + + + + + Hello + + + + + + + + +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; + } +} + + + + + Hello + + +