peterreilly 2004/05/27 07:38:46
Modified: docs/manual/CoreTasks macrodef.html
src/etc/testcases/taskdefs macrodef.xml
src/main/org/apache/tools/ant IntrospectionHelper.java
UnknownElement.java
src/main/org/apache/tools/ant/taskdefs MacroDef.java
MacroInstance.java
src/testcases/org/apache/tools/ant/taskdefs
MacroDefTest.java
Added: src/main/org/apache/tools/ant DynamicAttribute.java
DynamicAttributeNS.java DynamicElement.java
DynamicElementNS.java
Log:
add implicit element to macrodef
PR: 25633
Revision Changes Path
1.21 +50 -0 ant/docs/manual/CoreTasks/macrodef.html
Index: macrodef.html
===================================================================
RCS file: /home/cvs/ant/docs/manual/CoreTasks/macrodef.html,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -r1.20 -r1.21
--- macrodef.html 26 May 2004 12:25:20 -0000 1.20
+++ macrodef.html 27 May 2004 14:38:45 -0000 1.21
@@ -132,6 +132,17 @@
<td valign="top" align="center">No</td>
</tr>
<tr>
+ <td valign="top">implicit</td>
+ <td valign="top">
+ If true this nested element is implicit. This means that
+ any nested elements of the macrodef instance will be placed
+ in the element indicated by the name of this element.
+ There can only be one element if an element is implicit.
+ The default value is false. <em>since ant 1.6.2</em>
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
<td valign="top">description</td>
<td valign="top">
This contains a description
@@ -253,6 +264,45 @@
<fileset dir="${gen.dir}" includes = "*.cpp"/>
<linker refid="linker-libs"/>
</cc-elements>
+</call-cc>
+</pre>
+ </blockquote>
+ <p>
+ The following fragment shows <call-cc>, but this time
+ using an implicit element and with the link and target.dir arguments
+ having default values.
+ </p>
+ <blockquote>
+<pre class="code">
+<macrodef name="call-cc">
+ <attribute name="target"/>
+ <attribute name="link" default="executable"/>
+ <attribute name="target.dir" default="${build.bin.dir}"/>
+ <element name="cc-elements" implicit="yes"/>
+ <sequential>
+ <mkdir dir="${obj.dir}/@{target}"/>
+ <mkdir dir="@{target.dir}"/>
+ <cc link="@{link}" objdir="${obj.dir}/@{target}"
+ outfile="@{target.dir}/@{target}">
+ <compiler refid="compiler.options"/>
+ <cc-elements/>
+ </cc>
+ </sequential>
+</macrodef>
+</pre>
+ </blockquote>
+ <p>
+ This then can be used as follows, note that <cc-elements>
+ is not specified.
+ </p>
+ <blockquote>
+<pre class="code">
+<call-cc target="unittests"/>
+ <includepath location="${gen.dir}"/>
+ <includepath location="test"/>
+ <fileset dir="test/unittest" includes = "**/*.cpp"/>
+ <fileset dir="${gen.dir}" includes = "*.cpp"/>
+ <linker refid="linker-libs"/>
</call-cc>
</pre>
</blockquote>
1.12 +55 -0 ant/src/etc/testcases/taskdefs/macrodef.xml
Index: macrodef.xml
===================================================================
RCS file: /home/cvs/ant/src/etc/testcases/taskdefs/macrodef.xml,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- macrodef.xml 24 Feb 2004 09:30:30 -0000 1.11
+++ macrodef.xml 27 May 2004 14:38:46 -0000 1.12
@@ -168,4 +168,59 @@
<d description="hello world"/>
</target>
+ <target name="implicit">
+ <macrodef name="implicit">
+ <element name="implicit" implicit="yes"/>
+ <sequential>
+ <echo>Before implicit</echo>
+ <implicit/>
+ <echo>After implicit</echo>
+ </sequential>
+ </macrodef>
+
+ <implicit>
+ <echo>In implicit</echo>
+ </implicit>
+ </target>
+
+ <target name="implicit.notoptional">
+ <macrodef name="implicit">
+ <element name="implicit" implicit="yes"/>
+ <sequential>
+ <echo>Before implicit</echo>
+ <implicit/>
+ <echo>After implicit</echo>
+ </sequential>
+ </macrodef>
+
+ <implicit>
+ </implicit>
+ </target>
+
+ <target name="implicit.optional">
+ <macrodef name="implicit">
+ <element name="implicit" optional="yes" implicit="yes"/>
+ <sequential>
+ <echo>Before implicit</echo>
+ <implicit/>
+ <echo>After implicit</echo>
+ </sequential>
+ </macrodef>
+
+ <implicit>
+ </implicit>
+ </target>
+
+ <target name="implicit.explicit">
+ <macrodef name="implicit">
+ <element name="explicit" optional="yes"/>
+ <element name="implicit" optional="yes" implicit="yes"/>
+ <sequential>
+ <implicit/>
+ <explicit/>
+ </sequential>
+ </macrodef>
+
+ </target>
+
</project>
1.84 +12 -12
ant/src/main/org/apache/tools/ant/IntrospectionHelper.java
Index: IntrospectionHelper.java
===================================================================
RCS file:
/home/cvs/ant/src/main/org/apache/tools/ant/IntrospectionHelper.java,v
retrieving revision 1.83
retrieving revision 1.84
diff -u -r1.83 -r1.84
--- IntrospectionHelper.java 25 May 2004 08:25:00 -0000 1.83
+++ IntrospectionHelper.java 27 May 2004 14:38:46 -0000 1.84
@@ -489,8 +489,8 @@
= (AttributeSetter) attributeSetters.get(
attributeName.toLowerCase(Locale.US));
if (as == null) {
- if (element instanceof DynamicConfiguratorNS) {
- DynamicConfiguratorNS dc = (DynamicConfiguratorNS) element;
+ if (element instanceof DynamicAttributeNS) {
+ DynamicAttributeNS dc = (DynamicAttributeNS) element;
String uriPlusPrefix =
ProjectHelper.extractUriFromComponentName(attributeName);
String uri =
@@ -502,8 +502,8 @@
dc.setDynamicAttribute(uri, localName, qName, value);
return;
- } else if (element instanceof DynamicConfigurator) {
- DynamicConfigurator dc = (DynamicConfigurator) element;
+ } else if (element instanceof DynamicAttribute) {
+ DynamicAttribute dc = (DynamicAttribute) element;
dc.setDynamicAttribute(attributeName.toLowerCase(Locale.US),
value);
return;
} else {
@@ -611,8 +611,8 @@
if (nc == null) {
nc = createAddTypeCreator(project, parent, elementName);
}
- if (nc == null && parent instanceof DynamicConfiguratorNS) {
- DynamicConfiguratorNS dc = (DynamicConfiguratorNS) parent;
+ if (nc == null && parent instanceof DynamicElementNS) {
+ DynamicElementNS dc = (DynamicElementNS) parent;
String qName = (child == null ? name : child.getQName());
final Object nestedElement =
dc.createDynamicElement(
@@ -640,8 +640,8 @@
};
}
}
- if (nc == null && parent instanceof DynamicConfigurator) {
- DynamicConfigurator dc = (DynamicConfigurator) parent;
+ if (nc == null && parent instanceof DynamicElement) {
+ DynamicElement dc = (DynamicElement) parent;
final Object nestedElement =
dc.createDynamicElement(name.toLowerCase(Locale.US));
if (nestedElement != null) {
@@ -749,8 +749,8 @@
*/
public boolean supportsNestedElement(String elementName) {
return nestedCreators.containsKey(elementName.toLowerCase(Locale.US))
- || DynamicConfigurator.class.isAssignableFrom(bean)
- || DynamicConfiguratorNS.class.isAssignableFrom(bean)
+ || DynamicElement.class.isAssignableFrom(bean)
+ || DynamicElementNS.class.isAssignableFrom(bean)
|| addTypeMethods.size() != 0;
}
@@ -776,8 +776,8 @@
return (
nestedCreators.containsKey(name.toLowerCase(Locale.US))
&& (uri.equals(parentUri))) // || uri.equals("")))
- || DynamicConfigurator.class.isAssignableFrom(bean)
- || DynamicConfiguratorNS.class.isAssignableFrom(bean)
+ || DynamicElement.class.isAssignableFrom(bean)
+ || DynamicElementNS.class.isAssignableFrom(bean)
|| addTypeMethods.size() != 0;
}
1.80 +7 -0 ant/src/main/org/apache/tools/ant/UnknownElement.java
Index: UnknownElement.java
===================================================================
RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/UnknownElement.java,v
retrieving revision 1.79
retrieving revision 1.80
diff -u -r1.79 -r1.80
--- UnknownElement.java 7 Apr 2004 12:11:17 -0000 1.79
+++ UnknownElement.java 27 May 2004 14:38:46 -0000 1.80
@@ -72,6 +72,13 @@
}
/**
+ * @return the list of nested UnknownElements for this UnknownElement.
+ */
+ public List getChildren() {
+ return children;
+ }
+
+ /**
* Returns the name of the XML element which generated this unknown
* element.
*
1.1 ant/src/main/org/apache/tools/ant/DynamicAttribute.java
Index: DynamicAttribute.java
===================================================================
/*
* Copyright 2002-2004 The Apache Software Foundation
*
* Licensed 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;
/**
* Enables a task to control unknown attributes
*
* @since Ant 1.5
*/
public interface DynamicAttribute {
/**
* Set a named attribute to the given value
*
* @param name the name of the attribute
* @param value the new value of the attribute
* @throws BuildException when any error occurs
*/
void setDynamicAttribute(String name, String value)
throws BuildException;
}
1.1 ant/src/main/org/apache/tools/ant/DynamicAttributeNS.java
Index: DynamicAttributeNS.java
===================================================================
/*
* Copyright 2004 The Apache Software Foundation
*
* Licensed 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;
/**
* Enables a task to control unknown attributes.
*
* @since Ant 1.7
*/
public interface DynamicAttributeNS {
/**
* Set a named attribute to the given value
*
* @param uri The namespace uri for this attribute, "" is
* used if there is no namespace uri.
* @param localName The localname of this attribute.
* @param qName The qualified name for this attribute
* @param value The value of this attribute.
* @throws BuildException when any error occurs
*/
void setDynamicAttribute(
String uri, String localName, String qName, String value)
throws BuildException;
}
1.1 ant/src/main/org/apache/tools/ant/DynamicElement.java
Index: DynamicElement.java
===================================================================
/*
* Copyright 2002-2004 The Apache Software Foundation
*
* Licensed 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;
/**
* Enables a task to control unknown elements.
*
* @since Ant 1.5
*/
public interface DynamicElement {
/**
* Create an element with the given name
*
* @param name the element nbame
* @throws BuildException when any error occurs
* @return the element created
*/
Object createDynamicElement(String name) throws BuildException;
}
1.1 ant/src/main/org/apache/tools/ant/DynamicElementNS.java
Index: DynamicElementNS.java
===================================================================
/*
* Copyright 2004 The Apache Software Foundation
*
* Licensed 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;
/**
* Enables a task to control unknown elements.
*
* @since Ant 1.7
*/
public interface DynamicElementNS {
/**
* Create an element with the given name
*
* @param uri The namespace uri for this attribute.
* @param localName The localname of this attribute.
* @param qName The qualified name for this element.
* @throws BuildException when any error occurs
* @return the element created for this element.
*/
Object createDynamicElement(
String uri, String localName, String qName) throws BuildException;
}
1.26 +28 -2 ant/src/main/org/apache/tools/ant/taskdefs/MacroDef.java
Index: MacroDef.java
===================================================================
RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/taskdefs/MacroDef.java,v
retrieving revision 1.25
retrieving revision 1.26
diff -u -r1.25 -r1.26
--- MacroDef.java 17 May 2004 13:30:17 -0000 1.25
+++ MacroDef.java 27 May 2004 14:38:46 -0000 1.26
@@ -46,6 +46,7 @@
private Map elements = new HashMap();
private String textName = null;
private Text text = null;
+ private boolean hasImplicitElement = false;
/**
* Name of the definition
@@ -254,6 +255,12 @@
"the element " + element.getName()
+ " has already been specified");
}
+ if (hasImplicitElement
+ || (element.isImplicit() && elements.size() != 0)) {
+ throw new BuildException(
+ "Only one element allowed when using implicit elements");
+ }
+ hasImplicitElement = element.isImplicit();
elements.put(element.getName(), element);
}
@@ -507,6 +514,7 @@
public static class TemplateElement {
private String name;
private boolean optional = false;
+ private boolean implicit = false;
private String description;
/**
@@ -547,6 +555,23 @@
}
/**
+ * is this element implicit ?
+ *
+ * @param implicit if true this element may be left out, default
+ * is false.
+ */
+ public void setImplicit(boolean implicit) {
+ this.implicit = implicit;
+ }
+
+ /**
+ * @return the implicit attribute
+ */
+ public boolean isImplicit() {
+ return implicit;
+ }
+
+ /**
* @param desc Description of the element.
* @since ant 1.6.1
*/
@@ -584,14 +609,15 @@
} else if (!name.equals(other.name)) {
return false;
}
- return optional == other.optional;
+ return optional == other.optional && implicit == other.implicit;
}
/**
* @return a hash code value for this object.
*/
public int hashCode() {
- return objectHashCode(name) + (optional ? 1 : 0);
+ return objectHashCode(name)
+ + (optional ? 1 : 0) + (implicit ? 1 : 0);
}
}
1.27 +59 -19
ant/src/main/org/apache/tools/ant/taskdefs/MacroInstance.java
Index: MacroInstance.java
===================================================================
RCS file:
/home/cvs/ant/src/main/org/apache/tools/ant/taskdefs/MacroInstance.java,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -r1.26 -r1.27
--- MacroInstance.java 7 Apr 2004 12:39:12 -0000 1.26
+++ MacroInstance.java 27 May 2004 14:38:46 -0000 1.27
@@ -29,7 +29,7 @@
import java.util.Enumeration;
import org.apache.tools.ant.BuildException;
-import org.apache.tools.ant.DynamicConfigurator;
+import org.apache.tools.ant.DynamicAttribute;
import org.apache.tools.ant.ProjectHelper;
import org.apache.tools.ant.RuntimeConfigurable;
import org.apache.tools.ant.Target;
@@ -44,13 +44,15 @@
* the parameter values in attributes and text.
* @since Ant 1.6
*/
-public class MacroInstance extends Task implements DynamicConfigurator {
+public class MacroInstance extends Task implements DynamicAttribute,
TaskContainer {
private MacroDef macroDef;
private Map map = new HashMap();
private Map nsElements = null;
private Map presentElements = new HashMap();
private Hashtable localProperties = new Hashtable();
private String text = null;
+ private String implicitTag = null;
+ private List unknownElements = new ArrayList();
/**
* Called from MacroDef.MyAntTypeDefinition#create()
@@ -79,22 +81,14 @@
}
/**
- * Add an element.
- * @param name the name of the element
- * @return an inner Element type
- * @throws BuildException if the name is not known or if this element
- * has already been seen
+ * Method present for BC purposes.
+ * @param name not used
+ * @return nothing
+ * @deprecated
+ * @throws BuildException always
*/
public Object createDynamicElement(String name) throws BuildException {
- if (getNsElements().get(name) == null) {
- throw new BuildException("unsupported element " + name);
- }
- if (presentElements.get(name) != null) {
- throw new BuildException("Element " + name + " already present");
- }
- Element ret = new Element();
- presentElements.put(name, ret);
- return ret;
+ throw new BuildException("Not implemented any more");
}
private Map getNsElements() {
@@ -105,12 +99,44 @@
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;
}
/**
+ * Add a unknownElement for the macro instances nested elements.
+ *
+ * @param nestedTask a nested element.
+ */
+ public void addTask(Task nestedTask) {
+ unknownElements.add(nestedTask);
+ }
+
+ private void processTasks() {
+ if (implicitTag != null) {
+ return;
+ }
+ for (Iterator i = unknownElements.iterator(); i.hasNext();) {
+ UnknownElement ue = (UnknownElement) i.next();
+ String name = ProjectHelper.extractNameFromComponentName(
+ ue.getTag()).toLowerCase(Locale.US);
+ if (getNsElements().get(name) == null) {
+ throw new BuildException("unsupported element " + name);
+ }
+ if (presentElements.get(name) != null) {
+ throw new BuildException("Element " + name + " already
present");
+ }
+ presentElements.put(name, ue.getChildren());
+ }
+ }
+
+ /**
* Embedded element in macro instance
*/
public static class Element implements TaskContainer {
@@ -255,9 +281,21 @@
UnknownElement child = copy(unknownElement);
rc.addChild(child.getWrapper());
ret.addChild(child);
+ } else if (templateElement.isImplicit()) {
+ if (unknownElements.size() == 0 &&
!templateElement.isOptional()) {
+ throw new BuildException(
+ "Missing nested elements for implicit element "
+ + templateElement.getName());
+ }
+ for (Iterator i = unknownElements.iterator();
+ i.hasNext();) {
+ UnknownElement child = (UnknownElement) i.next();
+ rc.addChild(child.getWrapper());
+ ret.addChild(child);
+ }
} else {
- Element element = (Element) presentElements.get(tag);
- if (element == null) {
+ List list = (List) presentElements.get(tag);
+ if (list == null) {
if (!templateElement.isOptional()) {
throw new BuildException(
"Required nested element "
@@ -265,7 +303,7 @@
}
continue;
}
- for (Iterator i = element.getUnknownElements().iterator();
+ for (Iterator i = list.iterator();
i.hasNext();) {
UnknownElement child = (UnknownElement) i.next();
rc.addChild(child.getWrapper());
@@ -283,6 +321,8 @@
*
*/
public void execute() {
+ getNsElements();
+ processTasks();
localProperties = new Hashtable();
Set copyKeys = new HashSet(map.keySet());
for (Iterator i = macroDef.getAttributes().iterator(); i.hasNext();)
{
1.17 +20 -0
ant/src/testcases/org/apache/tools/ant/taskdefs/MacroDefTest.java
Index: MacroDefTest.java
===================================================================
RCS file:
/home/cvs/ant/src/testcases/org/apache/tools/ant/taskdefs/MacroDefTest.java,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -r1.16 -r1.17
--- MacroDefTest.java 9 Mar 2004 16:48:57 -0000 1.16
+++ MacroDefTest.java 27 May 2004 14:38:46 -0000 1.17
@@ -108,5 +108,25 @@
"attribute.description",
"description is hello world");
}
+ public void testImplicit() {
+ expectLog(
+ "implicit", "Before implicitIn implicitAfter implicit");
+ }
+ public void testImplicitNotOptional() {
+ expectSpecificBuildException(
+ "implicit.notoptional",
+ "Missing nested elements for implicit element implicit",
+ "Missing nested elements for implicit element implicit");
+ }
+ public void testImplicitOptional() {
+ expectLog(
+ "implicit.optional", "Before implicitAfter implicit");
+ }
+ public void testImplicitExplicit() {
+ expectSpecificBuildException(
+ "implicit.explicit",
+ "Only one element allowed when using implicit elements",
+ "Only one element allowed when using implicit elements");
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]