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 &lt;sequential&gt; or &lt;parallel&gt;
  -      nested task as a template. Nested elements &lt;param&gt; and
  +      nested task as a template. Nested elements &lt;attribute&gt; and
         &lt;element&gt; are used to specify attributes and elements of
         the new task. These get substituted into the  &lt;sequential&gt;
         or &lt;parallel&gt; 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>
   &lt;macrodef name="testing"&gt;
  -   &lt;param name="v" default="NOT SET"/&gt;
  +   &lt;attribute name="v" default="NOT SET"/&gt;
      &lt;element name="some-tasks" optional="yes"/&gt;
      &lt;sequential&gt;
         &lt;echo&gt;v is ${v}&lt;/echo&gt;
  @@ -125,6 +141,23 @@
         </pre>
       </blockquote>
       <p>
  +      The following fragment sets the attribute style to "xpath"
  +      for the macro definition &lt;testing&gt; and calls the
  +      macro. The fragment should output "attribute is this is a test".
  +    </p>
  +    <blockquote>
  +      <pre>
  +&lt;macrodef name="testing" attributestyle="xpath"&gt;
  +   &lt;attribute name="abc"/&gt;
  +   &lt;sequential&gt;
  +      &lt;echo&gt;attribute is @abc&lt;/echo&gt;
  +   &lt;/sequential&gt;
  +&lt;/macrodef&gt;
  +
  +&lt;testing abc="this is a test"/&gt;
  +      </pre>
  +    </blockquote>
  +    <p>
         The following fragment defines a task called &lt;call-cc&gt; 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>
   &lt;macrodef name="call-cc"&gt;
  -   &lt;param name="target"/&gt;
  -   &lt;param name="link"/&gt;
  -   &lt;param name="target.dir"/&gt;
  +   &lt;attribute name="target"/&gt;
  +   &lt;attribute name="link"/&gt;
  +   &lt;attribute name="target.dir"/&gt;
      &lt;element name="cc-elements"/&gt;
      &lt;sequential&gt;
         &lt;mkdir dir="${obj.dir}/${target}"/&gt;
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to