diff --git a/docs/manual/CoreTypes/antlib.html b/docs/manual/CoreTypes/antlib.html
index 9d626a395..6bdbd87f5 100644
--- a/docs/manual/CoreTypes/antlib.html
+++ b/docs/manual/CoreTypes/antlib.html
@@ -133,9 +133,9 @@
<sequential>
<current:if>
<current:isallowed test="${action}"/>
- <then>
- <do/>
- </then>
+ <current:then>
+ <current:do/>
+ </current:then>
</current:if>
</sequential>
</macrodef>
diff --git a/src/main/org/apache/tools/ant/IntrospectionHelper.java b/src/main/org/apache/tools/ant/IntrospectionHelper.java
index c7301d00d..a89d38835 100644
--- a/src/main/org/apache/tools/ant/IntrospectionHelper.java
+++ b/src/main/org/apache/tools/ant/IntrospectionHelper.java
@@ -642,6 +642,52 @@ public final class IntrospectionHelper implements BuildListener {
return nc;
}
+ private NestedCreator getNestedCreator(
+ Project project, String parentUri, Object parent,
+ String elementName) throws BuildException {
+
+ String uri = ProjectHelper.extractUriFromComponentName(elementName);
+ String name = ProjectHelper.extractNameFromComponentName(elementName);
+
+ NestedCreator nc = null;
+ if (uri.equals(parentUri)) { // || uri.equals("")) {
+ nc = (NestedCreator) nestedCreators.get(
+ name.toLowerCase(Locale.US));
+ }
+ if (nc == null) {
+ nc = createAddTypeCreator(project, parent, elementName);
+ }
+ if (nc == null && parent instanceof DynamicConfigurator) {
+ DynamicConfigurator dc = (DynamicConfigurator) parent;
+ final Object nestedElement = dc.createDynamicElement(elementName);
+ if (nestedElement != null) {
+ nc = new NestedCreator() {
+ public boolean isPolyMorphic() {
+ return false;
+ }
+ public Class getElementClass() {
+ return null;
+ }
+
+ public Object getRealObject() {
+ return null;
+ }
+
+ public Object create(
+ Project project, Object parent, Object ignore) {
+ return nestedElement;
+ }
+ public void store(Object parent, Object child) {
+ }
+ };
+ }
+ }
+ if (nc == null) {
+ throwNotSupported(project, parent, elementName);
+ }
+ return nc;
+ }
+
/**
* Creates a named nested element. Depending on the results of the
* initial introspection, either a method in the given parent instance
@@ -692,6 +738,7 @@ public final class IntrospectionHelper implements BuildListener {
* for an element of a parent.
*
* @param project Project to which the parent object belongs.
+ * @param parentUri The namespace uri of the parent object.
* @param parent Parent object used to create the creator object to
* create and store and instance of a subelement.
* @param elementName Name of the element to create an instance of.
@@ -699,8 +746,9 @@ public final class IntrospectionHelper implements BuildListener {
*/
public Creator getElementCreator(
- Project project, Object parent, String elementName) {
- NestedCreator nc = getNestedCreator(project, parent, elementName);
+ Project project, String parentUri, Object parent, String elementName) {
+ NestedCreator nc = getNestedCreator(
+ project, parentUri, parent, elementName);
return new Creator(project, parent, nc);
}
@@ -718,6 +766,26 @@ public final class IntrospectionHelper implements BuildListener {
|| addTypeMethods.size() != 0;
}
+ /**
+ * Indicate if this element supports a nested element of the
+ * given name.
+ *
+ * @param parentUri the uri of the parent
+ * @param elementName the name of the nested element being checked
+ *
+ * @return true if the given nested element is supported
+ */
+ public boolean supportsNestedElement(String parentUri, String elementName) {
+ String uri = ProjectHelper.extractUriFromComponentName(elementName);
+ String name = ProjectHelper.extractNameFromComponentName(elementName);
+
+ return (
+ nestedCreators.containsKey(name.toLowerCase(Locale.US))
+ && (uri.equals(parentUri))) // || uri.equals("")))
+ || DynamicConfigurator.class.isAssignableFrom(bean)
+ || addTypeMethods.size() != 0;
+ }
+
/**
* Stores a named nested element using a storage method determined
* by the initial introspection. If no appropriate storage method
diff --git a/src/main/org/apache/tools/ant/ProjectHelper.java b/src/main/org/apache/tools/ant/ProjectHelper.java
index 92765e5b8..f00ad9fcb 100644
--- a/src/main/org/apache/tools/ant/ProjectHelper.java
+++ b/src/main/org/apache/tools/ant/ProjectHelper.java
@@ -525,12 +525,29 @@ public class ProjectHelper {
* @return The uri or "" if not present
*/
public static String extractUriFromComponentName(String componentName) {
+ if (componentName == null) {
+ return "";
+ }
int index = componentName.lastIndexOf(':');
if (index == -1) {
return "";
}
return componentName.substring(0, index);
}
+
+ /**
+ * extract the element name from a component name
+ *
+ * @param componentName The stringified form for {uri, name}
+ * @return The element name of the component
+ */
+ public static String extractNameFromComponentName(String componentName) {
+ int index = componentName.lastIndexOf(':');
+ if (index == -1) {
+ return componentName;
+ }
+ return componentName.substring(index+1);
+ }
/**
* Add location to build exception.
diff --git a/src/main/org/apache/tools/ant/Task.java b/src/main/org/apache/tools/ant/Task.java
index d1409c4ca..a437cb02e 100644
--- a/src/main/org/apache/tools/ant/Task.java
+++ b/src/main/org/apache/tools/ant/Task.java
@@ -493,7 +493,7 @@ public abstract class Task extends ProjectComponent {
*
* @return the type of task
*/
- protected String getTaskType() {
+ public String getTaskType() {
return taskType;
}
diff --git a/src/main/org/apache/tools/ant/UnknownElement.java b/src/main/org/apache/tools/ant/UnknownElement.java
index 3e7cf8cd3..6dc3aaa33 100644
--- a/src/main/org/apache/tools/ant/UnknownElement.java
+++ b/src/main/org/apache/tools/ant/UnknownElement.java
@@ -336,13 +336,15 @@ public class UnknownElement extends Task {
*
* @exception BuildException if the children cannot be configured.
*/
- protected void handleChildren(Object parent,
- RuntimeConfigurable parentWrapper)
+ protected void handleChildren(
+ Object parent,
+ RuntimeConfigurable parentWrapper)
throws BuildException {
if (parent instanceof TypeAdapter) {
parent = ((TypeAdapter) parent).getProxy();
}
+ String parentUri = getNamespace();
Class parentClass = parent.getClass();
IntrospectionHelper ih = IntrospectionHelper.getHelper(parentClass);
@@ -352,8 +354,8 @@ public class UnknownElement extends Task {
for (int i = 0; it.hasNext(); i++) {
RuntimeConfigurable childWrapper = parentWrapper.getChild(i);
UnknownElement child = (UnknownElement) it.next();
- if (!handleChild(ih, parent, child,
- childWrapper)) {
+ if (!handleChild(
+ parentUri, ih, parent, child, childWrapper)) {
if (!(parent instanceof TaskContainer)) {
ih.throwNotSupported(getProject(), parent,
child.getTag());
@@ -548,14 +550,16 @@ public class UnknownElement extends Task {
*
* @return whether the creation has been successful
*/
- private boolean handleChild(IntrospectionHelper ih,
- Object parent, UnknownElement child,
- RuntimeConfigurable childWrapper) {
+ private boolean handleChild(
+ String parentUri,
+ IntrospectionHelper ih,
+ Object parent, UnknownElement child,
+ RuntimeConfigurable childWrapper) {
String childName = ProjectHelper.genComponentName(
child.getNamespace(), child.getTag());
- if (ih.supportsNestedElement(childName)) {
+ if (ih.supportsNestedElement(parentUri, childName)) {
IntrospectionHelper.Creator creator =
- ih.getElementCreator(getProject(), parent, childName);
+ ih.getElementCreator(getProject(), parentUri, parent, childName);
creator.setPolyType(childWrapper.getPolyType());
Object realChild = creator.create();
if (realChild instanceof PreSetDef.PreSetDefinition) {
diff --git a/src/main/org/apache/tools/ant/helper/ProjectHelper2.java b/src/main/org/apache/tools/ant/helper/ProjectHelper2.java
index 5b5a498a9..1d8c5ce11 100644
--- a/src/main/org/apache/tools/ant/helper/ProjectHelper2.java
+++ b/src/main/org/apache/tools/ant/helper/ProjectHelper2.java
@@ -939,8 +939,9 @@ public class ProjectHelper2 extends ProjectHelper {
UnknownElement task = new UnknownElement(tag);
task.setProject(context.getProject());
task.setNamespace(uri);
- //XXX task.setTaskType(qname);
task.setQName(qname);
+ task.setTaskType(
+ ProjectHelper.genComponentName(task.getNamespace(), tag));
task.setTaskName(qname);
Location location = new Location(context.getLocator().getSystemId(),
diff --git a/src/main/org/apache/tools/ant/taskdefs/MacroInstance.java b/src/main/org/apache/tools/ant/taskdefs/MacroInstance.java
index f5c8337ab..cdab476b0 100644
--- a/src/main/org/apache/tools/ant/taskdefs/MacroInstance.java
+++ b/src/main/org/apache/tools/ant/taskdefs/MacroInstance.java
@@ -84,8 +84,10 @@ import org.apache.tools.ant.UnknownElement;
public class MacroInstance extends Task implements DynamicConfigurator {
private MacroDef macroDef;
private Map map = new HashMap();
- private Map elements = new HashMap();
+ private Map nsElements = null;
+ private Map presentElements = new HashMap();
private Hashtable localProperties = new Hashtable();
+
/**
* Called from MacroDef.MyAntTypeDefinition#create()
@@ -114,17 +116,33 @@ public class MacroInstance extends Task implements DynamicConfigurator {
* has already been seen
*/
public Object createDynamicElement(String name) throws BuildException {
- if (macroDef.getElements().get(name) == null) {
+ if (getNsElements().get(name) == null) {
throw new BuildException("unsupported element " + name);
}
- if (elements.get(name) != null) {
+ if (presentElements.get(name) != null) {
throw new BuildException("Element " + name + " already present");
}
Element ret = new Element();
- elements.put(name, ret);
+ presentElements.put(name, ret);
return ret;
}
+ private Map getNsElements() {
+ if (nsElements == null) {
+ nsElements = new HashMap();
+ String myUri = ProjectHelper.extractUriFromComponentName(
+ getTaskType());
+ for (Iterator i = macroDef.getElements().entrySet().iterator();
+ i.hasNext();) {
+ Map.Entry entry = (Map.Entry) i.next();
+ nsElements.put(ProjectHelper.genComponentName(
+ myUri, (String) entry.getKey()),
+ entry.getValue());
+ }
+ }
+ return nsElements;
+ }
+
/**
* Embedded element in macro instance
*/
@@ -148,18 +166,38 @@ public class MacroInstance extends Task implements DynamicConfigurator {
}
}
+ private static final int STATE_NORMAL = 0;
+ private static final int STATE_EXPECT_BRACKET = 1;
+ private static final int STATE_EXPECT_NAME = 2;
+
private String macroSubs(String s, Map macroMapping) {
StringBuffer ret = new StringBuffer();
- StringBuffer macroName = new StringBuffer();
+ StringBuffer macroName = null;
boolean inMacro = false;
+ int state = STATE_NORMAL;
for (int i = 0; i < s.length(); ++i) {
- if (s.charAt(i) == '$') {
- inMacro = true;
- } else {
- if (inMacro) {
- if (s.charAt(i) == '{') {
- continue;
- } else if (s.charAt(i) == '}') {
+ char ch = s.charAt(i);
+ switch (state) {
+ case STATE_NORMAL:
+ if (ch == '$') {
+ state = 1;
+ } else {
+ ret.append(ch);
+ }
+ break;
+ case STATE_EXPECT_BRACKET:
+ if (ch == '{') {
+ state = 2;
+ macroName = new StringBuffer();
+ } else {
+ state = 0;
+ ret.append('$');
+ ret.append(ch);
+ }
+ break;
+ case STATE_EXPECT_NAME:
+ if (ch == '}') {
+ state = 0;
String name = macroName.toString();
String value = (String) macroMapping.get(name);
if (value == null) {
@@ -167,16 +205,23 @@ public class MacroInstance extends Task implements DynamicConfigurator {
} else {
ret.append(value);
}
- macroName = new StringBuffer();
- inMacro = false;
+ macroName = null;
} else {
macroName.append(s.charAt(i));
}
- } else {
- ret.append(s.charAt(i));
- }
}
}
+ switch (state) {
+ case STATE_NORMAL:
+ break;
+ case STATE_EXPECT_BRACKET:
+ ret.append('$');
+ break;
+ case STATE_EXPECT_NAME:
+ ret.append("${");
+ ret.append(macroName.toString());
+ break;
+ }
return ret.toString();
}
@@ -212,15 +257,15 @@ public class MacroInstance extends Task implements DynamicConfigurator {
while (e.hasMoreElements()) {
RuntimeConfigurable r = (RuntimeConfigurable) e.nextElement();
UnknownElement unknownElement = (UnknownElement) r.getProxy();
- String tag = unknownElement.getTag();
+ String tag = unknownElement.getTaskType();
MacroDef.TemplateElement templateElement =
- (MacroDef.TemplateElement) macroDef.getElements().get(tag);
+ (MacroDef.TemplateElement) getNsElements().get(tag);
if (templateElement == null) {
UnknownElement child = copy(unknownElement);
rc.addChild(child.getWrapper());
ret.addChild(child);
} else {
- Element element = (Element) elements.get(tag);
+ Element element = (Element) presentElements.get(tag);
if (element == null) {
if (!templateElement.isOptional()) {
throw new BuildException(