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]