peterreilly 2003/08/15 02:33:45
Modified: src/main/org/apache/tools/ant/taskdefs MacroDef.java
MacroInstance.java
src/etc/testcases/taskdefs macrodef.xml
src/testcases/org/apache/tools/ant/taskdefs
MacroDefTest.java
docs/manual/CoreTasks macrodef.html
Log:
macrodef changes:
* change nested element name from param to attribute
(now the same as scriptdef)
* expermintal testing for @attribute notation - controlled
by an attributeStyle attribute
* checking if correct attribute/element names are used
* samedefinition method overloaded
Revision Changes Path
1.3 +108 -15 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.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- MacroDef.java 14 Aug 2003 13:22:24 -0000 1.2
+++ MacroDef.java 15 Aug 2003 09:33:45 -0000 1.3
@@ -68,6 +68,8 @@
import org.apache.tools.ant.TaskContainer;
import org.apache.tools.ant.UnknownElement;
+import org.apache.tools.ant.types.EnumeratedAttribute;
+
/**
* Describe class <code>MacroDef</code> here.
*
@@ -78,9 +80,10 @@
private UnknownElement nestedTask;
private String name;
private String componentName;
- private List params = new ArrayList();
+ private List attributes = new ArrayList();
private Map elements = new HashMap();
- private String uri;
+ private String uri;
+ private int attributeStyle = AttributeStyle.ANT;
/**
* Name of the definition
@@ -106,6 +109,46 @@
}
/**
+ * Enumerated type for attributeStyle attribute
+ *
+ * @see EnumeratedAttribute
+ */
+ public static class AttributeStyle extends EnumeratedAttribute {
+ /** Enumerated values */
+ public static final int ANT = 0, XPATH = 1;
+
+ /**
+ * get the values
+ * @return an array of the allowed values for this attribute.
+ */
+ public String[] getValues() {
+ return new String[] {"ant", "xpath"};
+ }
+ }
+
+ /**
+ * <em>Expermential</em>
+ * I am uncertain at the moment how to encode attributes
+ * using ant style ${attribute} or xpath style @attribute.
+ * The first may get mixed up with ant properties and
+ * the second may get mixed up with xpath.
+ * The default at the moment is ant s
+ *
+ * @param style an <code>AttributeStyle</code> value
+ */
+ public void setAttributeStyle(AttributeStyle style) {
+ attributeStyle = style.getIndex();
+ }
+
+ /**
+ * <em>Expermential</em>
+ * @return the attribute style
+ */
+ public int getAttributeStyle() {
+ return attributeStyle;
+ }
+
+ /**
* Set the class loader.
* Not used
* @param classLoader a <code>ClassLoader</code> value
@@ -139,10 +182,10 @@
}
/**
- * @return the nested Params
+ * @return the nested Attributes
*/
- public List getParams() {
- return params;
+ public List getAttributes() {
+ return attributes;
}
/**
@@ -153,16 +196,46 @@
}
/**
- * Add a param element.
+ * Check if a character is a valid character for an element or
+ * attribute name
+ * @param c the character to check
+ * @return true if the character is a letter or digit or '.' or '-'
+ * attribute name
+ */
+ public static boolean isValidNameCharacter(char c) {
+ // ? is there an xml api for this ?
+ return Character.isLetterOrDigit(c) || c == '.' || c == '-';
+ }
+
+ /**
+ * Check if a string is a valid name for an element or
+ * attribute
+ * @param name the string to check
+ * @return true if the name consists of valid name characters
+ */
+ private static boolean isValidName(String name) {
+ if (name.length() == 0) {
+ return false;
+ }
+ for (int i = 0; i < name.length(); ++i) {
+ if (!isValidNameCharacter(name.charAt(i))) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Add an attribute element.
*
- * @param param a param nested element.
+ * @param attribute an attribute nested element.
*/
- public void addConfiguredParam(Param param) {
- if (param.getName() == null) {
+ public void addConfiguredAttribute(Attribute attribute) {
+ if (attribute.getName() == null) {
throw new BuildException(
- "the param nested element needed a \"name\" attribute");
+ "the attribute nested element needed a \"name\" attribute");
}
- params.add(param);
+ attributes.add(attribute);
}
/**
@@ -207,20 +280,24 @@
* A nested element for the MacroDef task.
*
*/
- public static class Param {
+ public static class Attribute {
private String name;
private String defaultValue;
/**
- * The name of the parameter.
+ * The name of the attribute.
*
- * @param name the name of the parameter
+ * @param name the name of the attribute
*/
public void setName(String name) {
+ if (!isValidName(name)) {
+ throw new BuildException(
+ "Illegal name [" + name + "] for attribute");
+ }
this.name = name;
}
/**
- * @return the name of the parameter.
+ * @return the name of the attribute
*/
public String getName() {
return name;
@@ -257,6 +334,10 @@
* @param name the name of the element.
*/
public void setName(String name) {
+ if (!isValidName(name)) {
+ throw new BuildException(
+ "Illegal name [" + name + "] for attribute");
+ }
this.name = name;
}
@@ -315,6 +396,18 @@
}
((MacroInstance) o).setTemplate(template);
return o;
+ }
+
+ /**
+ * Equality method for this definition
+ * This only checks for pointer equality.
+ *
+ * @param other another definition
+ * @param project the current project
+ * @return true if the definitions are the same
+ */
+ public boolean sameDefinition(AntTypeDefinition other, Project
project) {
+ return this == other;
}
}
}
1.3 +63 -9
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.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- MacroInstance.java 14 Aug 2003 13:22:24 -0000 1.2
+++ MacroInstance.java 15 Aug 2003 09:33:45 -0000 1.3
@@ -146,7 +146,7 @@
}
}
- private static String macroSubs(String s, Map macroMapping) {
+ private String macroSubsAnt(String s, Map macroMapping) {
StringBuffer ret = new StringBuffer();
StringBuffer macroName = new StringBuffer();
boolean inMacro = false;
@@ -179,6 +179,59 @@
return ret.toString();
}
+ private String macroSubsXPath(String s, Map macroMapping) {
+ StringBuffer ret = new StringBuffer();
+ StringBuffer macroName = new StringBuffer();
+ boolean inMacro = false;
+ for (int i = 0; i < s.length(); ++i) {
+ char c = s.charAt(i);
+ if (!inMacro) {
+ if (c == '@') {
+ inMacro = true;
+ } else {
+ ret.append(c);
+ }
+ } else {
+ if (MacroDef.isValidNameCharacter(c)) {
+ macroName.append(c);
+ } else {
+ inMacro = false;
+ String name = macroName.toString();
+ String value = (String) macroMapping.get(name);
+ if (value == null) {
+ ret.append("@" + name);
+ } else {
+ ret.append(value);
+ }
+ if (c == '@') {
+ inMacro = true;
+ } else {
+ ret.append(c);
+ }
+ macroName = new StringBuffer();
+ }
+ }
+ }
+ if (inMacro) {
+ String name = macroName.toString();
+ String value = (String) macroMapping.get(name);
+ if (value == null) {
+ ret.append("@" + name);
+ } else {
+ ret.append(value);
+ }
+ }
+ return ret.toString();
+ }
+
+ private String macroSubs(String s, Map macroMapping) {
+ if (template.getAttributeStyle() == MacroDef.AttributeStyle.ANT) {
+ return macroSubsAnt(s, macroMapping);
+ } else {
+ return macroSubsXPath(s, macroMapping);
+ }
+ }
+
private UnknownElement copy(UnknownElement ue) {
UnknownElement ret = new UnknownElement(ue.getTag());
ret.setNamespace(ue.getNamespace());
@@ -234,25 +287,26 @@
/**
* Execute the templates instance.
- * Copies the unknown element, substitutes the parameters,
+ * Copies the unknown element, substitutes the attributes,
* and calls perform on the unknown element.
*
*/
public void execute() {
localProperties = new Hashtable();
Set copyKeys = new HashSet(map.keySet());
- for (int i = 0; i < template.getParams().size(); ++i) {
- MacroDef.Param param = (MacroDef.Param)
template.getParams().get(i);
- String value = (String) map.get(param.getName());
+ for (int i = 0; i < template.getAttributes().size(); ++i) {
+ MacroDef.Attribute attribute =
+ (MacroDef.Attribute) template.getAttributes().get(i);
+ String value = (String) map.get(attribute.getName());
if (value == null) {
- value = param.getDefault();
+ value = attribute.getDefault();
}
if (value == null) {
throw new BuildException(
- "required parameter " + param.getName() + " not set");
+ "required attribute " + attribute.getName() + " not
set");
}
- localProperties.put(param.getName(), value);
- copyKeys.remove(param.getName());
+ localProperties.put(attribute.getName(), value);
+ copyKeys.remove(attribute.getName());
}
if (copyKeys.size() != 0) {
throw new BuildException(
1.2 +14 -3 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.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- macrodef.xml 14 Aug 2003 13:17:25 -0000 1.1
+++ macrodef.xml 15 Aug 2003 09:33:45 -0000 1.2
@@ -2,7 +2,7 @@
<target name="simple">
<macrodef name="my.echo">
- <param name="text"/>
+ <attribute name="text"/>
<sequential>
<echo message="${text}"/>
</sequential>
@@ -12,7 +12,7 @@
<target name="text">
<macrodef name="my.echo">
- <param name="text"/>
+ <attribute name="text"/>
<sequential>
<echo>${text}</echo>
</sequential>
@@ -22,7 +22,7 @@
<target name="uri">
<macrodef name="echo" uri="abc">
- <param name="text"/>
+ <attribute name="text"/>
<sequential>
<echo message="${text}"/>
</sequential>
@@ -43,5 +43,16 @@
<echo>A nested element</echo>
</nested>
</nested>
+ </target>
+
+ <target name="xpathstyle">
+ <macrodef name="testing" attributestyle="xpath">
+ <attribute name="abc"/>
+ <sequential>
+ <echo>attribute is @[EMAIL PROTECTED]</echo>
+ </sequential>
+ </macrodef>
+
+ <testing abc="this is a test"/>
</target>
</project>
1.2 +4 -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.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- MacroDefTest.java 14 Aug 2003 13:17:26 -0000 1.1
+++ MacroDefTest.java 15 Aug 2003 09:33:45 -0000 1.2
@@ -85,5 +85,9 @@
public void testNested() {
expectLog("nested", "A nested element");
}
+
+ public void testXPathStyle() {
+ expectLog("xpathstyle", "attribute is this is a testthis is a test");
+ }
}
1.2 +44 -11 ant/docs/manual/CoreTasks/macrodef.html
Index: macrodef.html
===================================================================
RCS file: /home/cvs/ant/docs/manual/CoreTasks/macrodef.html,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- macrodef.html 14 Aug 2003 12:48:10 -0000 1.1
+++ macrodef.html 15 Aug 2003 09:33:45 -0000 1.2
@@ -11,7 +11,7 @@
<h3>Description</h3>
<p>
This defines a new task using a <sequential> or <parallel>
- nested task as a template. Nested elements <param> and
+ 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>
or <parallel> task when the new task is run.
@@ -28,7 +28,7 @@
</tr>
<tr>
<td valign="top">name</td>
- <td valign="top">the name of the new definition</td>
+ <td valign="top">The name of the new definition</td>
<td valign="top" align="center">Yes</td>
</tr>
<tr>
@@ -38,9 +38,20 @@
</td>
<td valign="top" align="center">No</td>
</tr>
+ <tr>
+ <td valign="top">attributestyle</td>
+ <td valign="top">
+ <em>Temporary</em>
+ this attribute specifies if the attribute is in ant style
+ (i.e. ${attributeName}) or xpath style (i.e @attributeName).
+ Valid values are "ant" and "xpath". The default value
+ is "ant".
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
</table>
<h3>Parameters specified as nested elements</h3>
- <h4>param</h4>
+ <h4>attribute</h4>
<p>
This is used to specify attributes of the new task. The values
of the attributes get substituted into the templated task.
@@ -52,6 +63,11 @@
task using the ant property notation - ${attribute name}.
Note that is not an actual ant property.
</p>
+ <p>
+ If the attribute style is set to "xpath", the attribute is
+ specified in the body of the template task by prefixing the
+ name with a "@".
+ </p>
<h3>Parameters</h3>
<table border="1" cellpadding="2" cellspacing="0">
<tr>
@@ -61,13 +77,13 @@
</tr>
<tr>
<td valign="top">name</td>
- <td valign="top">the name of the new attribute</td>
+ <td valign="top">The name of the new attribute</td>
<td valign="top" align="center">Yes</td>
</tr>
<tr>
<td valign="top">default</td>
<td valign="top">
- the default value of the attribute.
+ The default value of the attribute.
</td>
<td valign="top" align="center">No</td>
</tr>
@@ -87,13 +103,13 @@
</tr>
<tr>
<td valign="top">name</td>
- <td valign="top">the name of the new attribute</td>
+ <td valign="top">The name of the new attribute</td>
<td valign="top" align="center">Yes</td>
</tr>
<tr>
<td valign="top">optional</td>
<td valign="top">
- if true this nested element is optional. Default is
+ If true this nested element is optional. Default is
false - i.e the nested element is required in
the new task.
</td>
@@ -109,7 +125,7 @@
<blockquote>
<pre>
<macrodef name="testing">
- <param name="v" default="NOT SET"/>
+ <attribute name="v" default="NOT SET"/>
<element name="some-tasks" optional="yes"/>
<sequential>
<echo>v is ${v}</echo>
@@ -125,6 +141,23 @@
</pre>
</blockquote>
<p>
+ The following fragment sets the attribute style to "xpath"
+ for the macro definition <testing> and calls the
+ macro. The fragment should output "attribute is this is a test".
+ </p>
+ <blockquote>
+ <pre>
+<macrodef name="testing" attributestyle="xpath">
+ <attribute name="abc"/>
+ <sequential>
+ <echo>attribute is @abc</echo>
+ </sequential>
+</macrodef>
+
+<testing abc="this is a test"/>
+ </pre>
+ </blockquote>
+ <p>
The following fragment defines a task called <call-cc> which
take the attributes "target", "link" and "target.dir" and the
nested element "cc-elements". The body of the task
@@ -134,9 +167,9 @@
<blockquote>
<pre>
<macrodef name="call-cc">
- <param name="target"/>
- <param name="link"/>
- <param name="target.dir"/>
+ <attribute name="target"/>
+ <attribute name="link"/>
+ <attribute name="target.dir"/>
<element name="cc-elements"/>
<sequential>
<mkdir dir="${obj.dir}/${target}"/>
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]