--- src/tests/antunit/taskdefs/macrodef-element-test.xml (revision 0)
+++ src/tests/antunit/taskdefs/macrodef-element-test.xml (revision 0)
@@ -0,0 +1,41 @@
+null
.
*
- * @param parentWrapper The wrapper containing child wrappers
- * to be configured. Must not be null
- * if there are any children.
+ * @param notUsed Not used.(kept for BC reasons)
*
* @exception BuildException if the children cannot be configured.
*/
protected void handleChildren(
Object parent,
- RuntimeConfigurable parentWrapper)
+ RuntimeConfigurable notUsed)
throws BuildException {
+ if (children == null) {
+ return;
+ }
+
+ ComponentHelper helper = ComponentHelper.getComponentHelper(
+ getProject());
+
if (parent instanceof TypeAdapter) {
parent = ((TypeAdapter) parent).getProxy();
}
- String parentUri = getNamespace();
- Class parentClass = parent.getClass();
- IntrospectionHelper ih = IntrospectionHelper.getHelper(getProject(), parentClass);
-
-
- if (children != null) {
- Iterator it = children.iterator();
- for (int i = 0; it.hasNext(); i++) {
- RuntimeConfigurable childWrapper = parentWrapper.getChild(i);
- UnknownElement child = (UnknownElement) it.next();
- try {
- if (!handleChild(
- parentUri, ih, parent, child, childWrapper)) {
- if (!(parent instanceof TaskContainer)) {
- ih.throwNotSupported(getProject(), parent,
- child.getTag());
- } else {
- // a task container - anything could happen - just add the
- // child to the container
- TaskContainer container = (TaskContainer) parent;
- container.addTask(child);
- }
- }
- } catch (UnsupportedElementException ex) {
- throw new BuildException(
- parentWrapper.getElementTag()
- + " doesn't support the nested \"" + ex.getElement()
- + "\" element.", ex);
- }
- }
+ for (Iterator i = children.iterator(); i.hasNext();) {
+ recurHandleChild(helper, parent, (UnknownElement) i.next());
}
}
@@ -535,10 +553,12 @@
private boolean handleChild(
String parentUri,
IntrospectionHelper ih,
- Object parent, UnknownElement child,
- RuntimeConfigurable childWrapper) {
+ Object parent, UnknownElement child) {
+ RuntimeConfigurable childWrapper = child.getWrapper();
+
String childName = ProjectHelper.genComponentName(
child.getNamespace(), child.getTag());
+
if (ih.supportsNestedElement(parentUri, childName)) {
IntrospectionHelper.Creator creator =
ih.getElementCreator(
@@ -563,7 +583,7 @@
((ProjectComponent) realChild).setLocation(child.getLocation());
}
childWrapper.maybeConfigure(getProject());
- child.handleChildren(realChild, childWrapper);
+ child.handleChildren(realChild, null);
creator.store();
return true;
}
--- src/main/org/apache/tools/ant/MacroFragment.java (revision 0)
+++ src/main/org/apache/tools/ant/MacroFragment.java (revision 0)
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant;
+
+import java.util.List;
+
+/**
+ * An interface for a task/type that can be used to
+ * inject a list of unknown elements into a build file.
+ */
+public interface MacroFragment {
+ /**
+ * Convert the unknown element into a list of ues.
+ * @param el the unknown element to convert.
+ * @return the list of unknown elements.
+ */
+ List getUnknownElements(UnknownElement el);
+}
--- src/main/org/apache/tools/ant/taskdefs/MacroInstance.java (revision 575729)
+++ src/main/org/apache/tools/ant/taskdefs/MacroInstance.java (working copy)
@@ -32,6 +32,7 @@
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.DynamicAttribute;
import org.apache.tools.ant.ProjectHelper;
+import org.apache.tools.ant.MacroFragment;
import org.apache.tools.ant.RuntimeConfigurable;
import org.apache.tools.ant.Target;
import org.apache.tools.ant.Task;
@@ -45,7 +46,8 @@
* the parameter values in attributes and text.
* @since Ant 1.6
*/
-public class MacroInstance extends Task implements DynamicAttribute, TaskContainer {
+public class MacroInstance extends Task
+ implements DynamicAttribute, TaskContainer, MacroFragment {
private MacroDef macroDef;
private Map map = new HashMap();
private Map nsElements = null;
@@ -72,6 +74,20 @@
}
/**
+ * Get the unknown elements to inject into the build document.
+ * @param el the unknown element this is this fragment.
+ * @return the replacement list of unknown elements.
+ */
+ public List getUnknownElements(UnknownElement el) {
+ try {
+ doParams();
+ return copy(getMacroDef().getNestedTask(), false).getChildren();
+ } finally {
+ clearParams();
+ }
+ }
+
+ /**
* A parameter name value pair as a xml attribute.
*
* @param name the name of the attribute
@@ -93,21 +109,22 @@
}
private Map getNsElements() {
- if (nsElements == null) {
- nsElements = new HashMap();
- for (Iterator i = macroDef.getElements().entrySet().iterator();
- i.hasNext();) {
- Map.Entry entry = (Map.Entry) i.next();
- nsElements.put((String) entry.getKey(),
- entry.getValue());
- MacroDef.TemplateElement te = (MacroDef.TemplateElement)
- entry.getValue();
- if (te.isImplicit()) {
- implicitTag = te.getName();
- }
+ return nsElements;
+ }
+
+ private void doNsElements() {
+ nsElements = new HashMap();
+ for (Iterator i = macroDef.getElements().entrySet().iterator();
+ i.hasNext();) {
+ Map.Entry entry = (Map.Entry) i.next();
+ nsElements.put((String) entry.getKey(),
+ entry.getValue());
+ MacroDef.TemplateElement te = (MacroDef.TemplateElement)
+ entry.getValue();
+ if (te.isImplicit()) {
+ implicitTag = te.getName();
}
}
- return nsElements;
}
/**
@@ -119,7 +136,14 @@
unknownElements.add(nestedTask);
}
- private void processTasks() {
+ /**
+ * process the nested elements of this macro instance.
+ * Ensure that the correspond to the elements definitions
+ * in the macrodef.
+ * If the there is one nested elemtent of implicit type, then
+ * there is no processsing.
+ */
+ private void processNestedElements() {
if (implicitTag != null) {
return;
}
@@ -242,7 +266,12 @@
this.text = text;
}
- private UnknownElement copy(UnknownElement ue, boolean nested) {
+ /**
+ * Copy an unknown element, substituting in macro attributes.
+ * @param ue the unknown element to replace.
+ * @return the copied unknown element.
+ */
+ private UnknownElement copy(UnknownElement ue, boolean nested) {
UnknownElement ret = new UnknownElement(ue.getTag());
ret.setNamespace(ue.getNamespace());
ret.setProject(getProject());
@@ -329,16 +358,11 @@
return ret;
}
- /**
- * Execute the templates instance.
- * Copies the unknown element, substitutes the attributes,
- * and calls perform on the unknown element.
- *
- */
- public void execute() {
+ /** setup parameters */
+ private void doParams() {
presentElements = new HashMap();
- getNsElements();
- processTasks();
+ doNsElements();
+ processNestedElements();
localAttributes = new Hashtable();
Set copyKeys = new HashSet(map.keySet());
for (Iterator i = macroDef.getAttributes().iterator(); i.hasNext();) {
@@ -386,7 +410,22 @@
"Unknown attribute" + (copyKeys.size() > 1 ? "s " : " ")
+ copyKeys);
}
+ }
+ /** Clear the parameters */
+ private void clearParams() {
+ presentElements = null;
+ localAttributes = null;
+ }
+
+ /**
+ * Execute the templates instance.
+ * Copies the unknown element, substitutes the attributes,
+ * and calls perform on the unknown element.
+ *
+ */
+ public void execute() {
+ doParams();
// need to set the project on unknown element
UnknownElement c = copy(macroDef.getNestedTask(), false);
c.init();
@@ -401,8 +440,7 @@
throw ex;
}
} finally {
- presentElements = null;
- localAttributes = null;
+ clearParams();
}
}
}
--- src/etc/checkstyle/checkstyle-config (revision 575729)
+++ src/etc/checkstyle/checkstyle-config (working copy)
@@ -80,8 +80,8 @@
- This defines a new task using a <sequential>
- nested task as a template. Nested elements <attribute>
and
- <element>
are used to specify attributes and elements of
- the new task. These get substituted into the <sequential>
- task when the new task is run.
+ Since Ant 1.6.
+ This defines a new element that may be used to replace a sequence
+ of elements and thus allow reuse of the elements in other
+ parts of the build document.
+
+ This defines a new element tag using a <sequential>
+ nested task as a template.
+ Nested elements <attribute>
and
+ <element>
are used to specify attributes
+ and elements of the new task. These get substituted into the
+ <sequential>
+ task when the new element tag is evalulated.
- You can also use prior defined attributes for default-values in - other attributes. See the examples. -
-- since Ant 1.6 -
+Note: | ++ You can also use prior defined attributes for default-values + in other attributes. See the examples. + | +
Note: | ++ Since Ant 1.8, macrodef defined elements can replace + arbitary nested elements and not just tasks. + | +