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 @@