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