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