You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ant.apache.org by pe...@apache.org on 2003/11/06 10:04:08 UTC

cvs commit: ant/src/testcases/org/apache/tools/ant/taskdefs PreSetDefTest.java

peterreilly    2003/11/06 01:04:08

  Modified:    docs/manual/CoreTasks presetdef.html
               src/etc/testcases/taskdefs presetdef.xml
               src/main/org/apache/tools/ant IntrospectionHelper.java
                        RuntimeConfigurable.java UnknownElement.java
               src/main/org/apache/tools/ant/taskdefs PreSetDef.java
               src/testcases/org/apache/tools/ant/taskdefs
                        PreSetDefTest.java
  Log:
  fixes for presetdef's handling of attributes
  PR: 24411
  
  Revision  Changes    Path
  1.3       +56 -19    ant/docs/manual/CoreTasks/presetdef.html
  
  Index: presetdef.html
  ===================================================================
  RCS file: /home/cvs/ant/docs/manual/CoreTasks/presetdef.html,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- presetdef.html	14 Oct 2003 09:59:19 -0000	1.2
  +++ presetdef.html	6 Nov 2003 09:04:08 -0000	1.3
  @@ -3,10 +3,15 @@
     <head>
       <meta http-equiv="Content-Language" content="en-us"></meta>
       <title>PreSetDef Task</title>
  +    <style type="text/css">
  +      <!--
  +           .code { background: #EFEFEF; margin-top: }
  +           -->
  +    </style>
     </head>
     
     <body>
  -
  +    
       <h2><a name="presetdef">PreSetDef</a></h2>
       <h3>Description</h3>
       <p>
  @@ -43,35 +48,67 @@
         This nested element can be any other type or task. The attributes
         and elements that need to be preset are placed here.
       </p>
  -
  +    
       <h3>Examples</h3>
  -    <p>
  -      The following fragment defines a javac task with the debug and deprecation
  +      The following fragment defines a javac task with the debug, deprecation
  +      srcdir and destdir
         attributes set. It also has a src element to source files from a generated
         directory.
  -    </p>
       <blockquote>
  -      <pre>
  +<pre class="code">
   &lt;presetdef name="my.javac"&gt;
  -   &lt;javac debug="${debug}" deprecation="${deprecation}"&gt;
  +   &lt;javac debug="${debug}" deprecation="${deprecation}"
  +          srcdir="${src.dir}" destdir="${classes.dir}"&gt;
         &lt;src path="${gen.dir}"/&gt;
      &lt;/javac&gt;
   &lt;/presetdef&gt;
  -      </pre>
  +</pre>
       </blockquote>
  -    <p>
         This can be used as a normal javac task - example:
  -    </p>
       <blockquote>
  -      <pre>
  -&lt;my.javac src="${src.dir}" destdir="${classes.dir}"/&gt;
  -      </pre>
  +<pre class="code">
  +&lt;my.javac/&gt;
  +</pre>
  +    </blockquote>
  +      The attributes specified in the preset task may be overridden - i.e.
  +      they may be seen as optional attributes - example:
  +    <blockquote>
  +<pre class="code">
  +&lt;my.javac srcdir="${test.src}" deprecation="no"/&gt;
  +</pre>
  +    </blockquote>
  +      One may put a presetdef definition in an antlib.
  +      For example suppose the jar file antgoodies.jar has
  +      the antlib.xml as follows:
  +    <blockquote>
  +<pre class="code">
  +&lt;antlib&gt;
  +   &lt;taskdef resource="com/acme/antgoodies/tasks.properties"/&gt;
  +   &lt;!-- Implement the common use of the javac command --&gt;
  +   &lt;presetdef name="javac"&gt;
  +      &lt;javac deprecation="${deprecation}" debug="${debug}"
  +             srcdir="src" destdir="classes"/&gt;
  +   &lt;/presetdef&gt;
  +&lt;/antlib&gt;
  +</pre>
  +    </blockquote>
  +      One may then use this in a build file as follows:
  +    <blockquote>
  +<pre class="code">
  +&lt;project default="example" xmlns:antgoodies="antlib:com.acme.antgoodies"&gt;
  +   &lt;target name="example"&gt;
  +      &lt;!-- Compile source --&gt;
  +      &lt;antgoodies:javac srcdir="src/main"/&gt;
  +      &lt;!-- Compile test code --&gt;
  +      &lt;antgoodies:javac srcdir="src/test"/&gt;
  +   &lt;/target&gt;
  +&lt;/project&gt;
  +</pre>
       </blockquote>
  -
  -<hr>
  -<p align="center">Copyright &copy; 2003 Apache Software
  -Foundation. All rights Reserved.</p>
  -
  -</body>
  +    <hr></hr>
  +    <p align="center">Copyright &copy; 2003 Apache Software
  +      Foundation. All rights Reserved.</p>
  +    
  +  </body>
   </html>
   
  
  
  
  1.2       +67 -0     ant/src/etc/testcases/taskdefs/presetdef.xml
  
  Index: presetdef.xml
  ===================================================================
  RCS file: /home/cvs/ant/src/etc/testcases/taskdefs/presetdef.xml,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- presetdef.xml	14 Aug 2003 13:17:25 -0000	1.1
  +++ presetdef.xml	6 Nov 2003 09:04:08 -0000	1.2
  @@ -1,20 +1,87 @@
   <project>
  +  <path id="test-classes">
  +    <pathelement location="../../../../build/testcases" />
  +    <pathelement path="${java.class.path}" />
  +  </path>
  +  
     <target name="simple">
       <presetdef name="my.echo">
         <echo message="Hello world"/>
       </presetdef>
       <my.echo/>
     </target>
  +
     <target name="text">
       <presetdef name="my.echo">
         <echo>Inner Text</echo>
       </presetdef>
       <my.echo/>
     </target>
  +
     <target name="uri">
       <presetdef name="echo" uri="abc">
         <echo message="Hello world"/>
       </presetdef>
       <x:echo xmlns:x="abc"/>
     </target>
  +
  +  <target name="defaulttest">
  +    <taskdef name="defaulttest"
  +             classname="org.apache.tools.ant.taskdefs.PreSetDefTest$DefaultTest"
  +             classpathref="test-classes"/>
  +    <presetdef name="d">
  +      <defaulttest attribute="true"/>
  +    </presetdef>
  +    <d attribute="false"/>
  +  </target>
  +
  +  <target name="doubledefault">
  +    <taskdef name="defaulttest"
  +             classname="org.apache.tools.ant.taskdefs.PreSetDefTest$DefaultTest"
  +             classpathref="test-classes"/>
  +    <presetdef name="d">
  +      <defaulttest attribute="true"/>
  +    </presetdef>
  +    <presetdef name="dd">
  +      <d attribute="false"/>
  +    </presetdef>
  +    <dd/>
  +    <dd attribute="true"/>
  +  </target>
  +
  +  <target name="text.optional">
  +    <presetdef name="echo.mytext">
  +      <echo>MyText</echo>
  +    </presetdef>
  +    <echo.mytext/>
  +    <echo.mytext>override text</echo.mytext>
  +  </target>
  +
  +  <target name="element.order">
  +    <presetdef name="el.order">
  +      <sequential>
  +        <echo>Line 1</echo>
  +      </sequential>
  +    </presetdef>
  +    <el.order>
  +      <echo>Line 2</echo>
  +    </el.order>
  +  </target>
  +
  +  <target name="element.order2">
  +    <presetdef name="el.order">
  +      <sequential>
  +        <echo>Line 1</echo>
  +      </sequential>
  +    </presetdef>
  +    <presetdef name="el.order2">
  +      <el.order>
  +        <echo>Line 2</echo>
  +      </el.order>
  +    </presetdef>
  +    <el.order2>
  +      <echo>Line 3</echo>
  +    </el.order2>
  +  </target>
  +
   </project>
  
  
  
  1.67      +39 -3     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.66
  retrieving revision 1.67
  diff -u -r1.66 -r1.67
  --- IntrospectionHelper.java	15 Oct 2003 15:35:31 -0000	1.66
  +++ IntrospectionHelper.java	6 Nov 2003 09:04:08 -0000	1.67
  @@ -65,6 +65,7 @@
   import java.util.Locale;
   import org.apache.tools.ant.types.EnumeratedAttribute;
   import org.apache.tools.ant.types.Path;
  +import org.apache.tools.ant.taskdefs.PreSetDef;
   
   /**
    * Helper class that collects the methods a task or nested element
  @@ -286,11 +287,14 @@
                   if (nestedCreators.get(propName) == null) {
                       nestedTypes.put(propName, returnType);
                       nestedCreators.put(propName, new NestedCreator() {
  -
                           public boolean isPolyMorphic() {
                               return false;
                           }
   
  +                        public Object getRealObject() {
  +                            return null;
  +                        }
  +
                           public Class getElementClass() {
                               return null;
                           }
  @@ -332,6 +336,10 @@
                                   return true;
                               }
   
  +                            public Object getRealObject() {
  +                                return null;
  +                            }
  +
                               public Class getElementClass() {
                                   return c.getDeclaringClass();
                               }
  @@ -387,6 +395,10 @@
                                   return true;
                               }
   
  +                            public Object getRealObject() {
  +                                return null;
  +                            }
  +
                               public Class getElementClass() {
                                   return c.getDeclaringClass();
                               }
  @@ -611,6 +623,10 @@
                           return null;
                       }
   
  +                    public Object getRealObject() {
  +                        return null;
  +                    }
  +
                       public Object create(
                           Project project, Object parent, Object ignore) {
                           return nestedElement;
  @@ -1113,6 +1129,14 @@
           }
   
           /**
  +         * @return the real object (used currently only
  +         *         for preset def)
  +         */
  +        public Object getRealObject() {
  +            return nestedCreator.getRealObject();
  +        }
  +
  +        /**
            * Stores the nested element object using a storage method
            * determined by introspection.
            *
  @@ -1147,6 +1171,7 @@
       private interface NestedCreator {
           boolean isPolyMorphic();
           Class getElementClass();
  +        Object getRealObject();
           Object create(Project project, Object parent, Object child)
               throws InvocationTargetException, IllegalAccessException, InstantiationException;
           void store(Object parent, Object child)
  @@ -1252,8 +1277,14 @@
           if (addedObject == null) {
               return null;
           }
  +        Object rObject = addedObject;
  +        if (addedObject instanceof PreSetDef.PreSetDefinition) {
  +            rObject = ((PreSetDef.PreSetDefinition) addedObject).createObject(
  +                project);
  +        }
           final Method method = addMethod;
           final Object nestedObject = addedObject;
  +        final Object realObject = rObject;
   
           return new NestedCreator() {
               public boolean isPolyMorphic() {
  @@ -1266,15 +1297,20 @@
               public Object create(Project project, Object parent, Object ignore)
                   throws InvocationTargetException, IllegalAccessException {
                   if (!method.getName().endsWith("Configured")) {
  -                    method.invoke(parent, new Object[]{nestedObject});
  +                    method.invoke(parent, new Object[]{realObject});
                   }
                   return nestedObject;
               }
  +
  +            public Object getRealObject() {
  +                return realObject;
  +            }
  +
               public void store(Object parent, Object child)
                   throws InvocationTargetException, IllegalAccessException,
                   InstantiationException {
                   if (method.getName().endsWith("Configured")) {
  -                    method.invoke(parent, new Object[]{nestedObject});
  +                    method.invoke(parent, new Object[]{realObject});
                   }
               }
           };
  
  
  
  1.46      +43 -1     ant/src/main/org/apache/tools/ant/RuntimeConfigurable.java
  
  Index: RuntimeConfigurable.java
  ===================================================================
  RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/RuntimeConfigurable.java,v
  retrieving revision 1.45
  retrieving revision 1.46
  diff -u -r1.45 -r1.46
  --- RuntimeConfigurable.java	12 Sep 2003 20:56:45 -0000	1.45
  +++ RuntimeConfigurable.java	6 Nov 2003 09:04:08 -0000	1.46
  @@ -63,6 +63,7 @@
   import java.util.List;
   import java.util.Locale;
   import java.util.Map;
  +import java.util.Iterator;
   
   import org.apache.tools.ant.util.CollectionUtils;
   import org.xml.sax.AttributeList;
  @@ -222,7 +223,6 @@
        * @return Attribute name to attribute value map
        */
       public Hashtable getAttributeMap() {
  -        // Nobody calls this method, maybe it could just be deleted?
           if (attributeMap != null) {
               return new Hashtable(attributeMap);
           } else {
  @@ -463,5 +463,47 @@
       public void reconfigure(Project p) {
           proxyConfigured = false;
           maybeConfigure(p);
  +    }
  +
  +
  +    /**
  +     * Apply presets, attributes and text are set if not currently set.
  +     * nested elements are prepended.
  +     *
  +     * @param r a <code>RuntimeConfigurable</code> value
  +     */
  +    public void applyPreSet(RuntimeConfigurable r) {
  +        // Attributes
  +        if (r.attributeMap != null) {
  +            for (Iterator i = r.attributeMap.keySet().iterator(); i.hasNext();) {
  +                String name = (String) i.next();
  +                if (attributeMap == null || attributeMap.get(name) == null) {
  +                    setAttribute(name, (String) r.attributeMap.get(name));
  +                }
  +            }
  +        }
  +        // poly type
  +        if (r.polyType != null && polyType == null) {
  +            polyType = r.polyType;
  +        }
  +
  +        // Children (this is a shadow of unknownElement#children)
  +        if (r.children != null) {
  +            List newChildren = new ArrayList();
  +            newChildren.addAll(r.children);
  +            if (children != null) {
  +                newChildren.addAll(children);
  +            }
  +            children = newChildren;
  +        }
  +
  +        // Text
  +        if (r.characters != null) {
  +            if (characters == null
  +                || characters.toString().trim().length() == 0) {
  +                characters =
  +                    new StringBuffer(r.characters.toString());
  +            }
  +        }
       }
   }
  
  
  
  1.68      +43 -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.67
  retrieving revision 1.68
  diff -u -r1.67 -r1.68
  --- UnknownElement.java	15 Oct 2003 15:35:31 -0000	1.67
  +++ UnknownElement.java	6 Nov 2003 09:04:08 -0000	1.68
  @@ -58,6 +58,7 @@
   import java.util.Iterator;
   import java.util.List;
   import java.io.IOException;
  +import org.apache.tools.ant.taskdefs.PreSetDef;
   
   /**
    * Wrapper class that holds all the information necessary to create a task
  @@ -95,6 +96,9 @@
        */
       private List/*<UnknownElement>*/ children = null;
   
  +    /** Specifies if a predefined definition has been done */
  +    private boolean presetDefed = false;
  +
       /**
        * Creates an UnknownElement for the given element name.
        *
  @@ -372,6 +376,31 @@
       }
   
       /**
  +     * This is used then the realobject of the UE is a PreSetDefinition.
  +     * This is also used when a presetdef is used on a presetdef
  +     * The attributes, elements and text are applied to this
  +     * UE.
  +     *
  +     * @param u an UnknownElement containing the attributes, elements and text
  +     */
  +    public void applyPreSet(UnknownElement u) {
  +        if (presetDefed) {
  +            return;
  +        }
  +        // Do the runtime
  +        getWrapper().applyPreSet(u.getWrapper());
  +        if (u.children != null) {
  +            List newChildren = new ArrayList();
  +            newChildren.addAll(u.children);
  +            if (children != null) {
  +                newChildren.addAll(children);
  +            }
  +            children = newChildren;
  +        }
  +        presetDefed = true;
  +    }
  +
  +    /**
        * Creates a named task or data type. If the real object is a task,
        * it is configured up to the init() stage.
        *
  @@ -386,9 +415,17 @@
               getProject());
           String name = ue.getComponentName();
           Object o = helper.createComponent(ue, ue.getNamespace(), name);
  +
           if (o == null) {
               throw getNotFoundException("task or type", name);
           }
  +
  +        if (o instanceof PreSetDef.PreSetDefinition) {
  +            PreSetDef.PreSetDefinition def = (PreSetDef.PreSetDefinition) o;
  +            o = def.createObject(ue.getProject());
  +            ue.applyPreSet(def.getPreSets());
  +        }
  +
           if (o instanceof Task) {
               Task task = (Task) o;
               task.setOwningTarget(getOwningTarget());
  @@ -521,6 +558,12 @@
                   ih.getElementCreator(getProject(), parent, childName);
               creator.setPolyType(childWrapper.getPolyType());
               Object realChild = creator.create();
  +            if (realChild instanceof PreSetDef.PreSetDefinition) {
  +                PreSetDef.PreSetDefinition def =
  +                    (PreSetDef.PreSetDefinition) realChild;
  +                realChild = creator.getRealObject();
  +                child.applyPreSet(def.getPreSets());
  +            }
               childWrapper.setCreator(creator);
               childWrapper.setProxy(realChild);
               if (realChild instanceof Task) {
  
  
  
  1.9       +53 -7     ant/src/main/org/apache/tools/ant/taskdefs/PreSetDef.java
  
  Index: PreSetDef.java
  ===================================================================
  RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/taskdefs/PreSetDef.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- PreSetDef.java	23 Sep 2003 05:59:04 -0000	1.8
  +++ PreSetDef.java	6 Nov 2003 09:04:08 -0000	1.9
  @@ -130,26 +130,52 @@
                   "Unable to find typedef " + componentName);
           }
   
  -        MyAntTypeDefinition newDef = new MyAntTypeDefinition(def, nestedTask);
  +        PreSetDefinition newDef = new PreSetDefinition(def, nestedTask);
   
           newDef.setName(name);
   
           helper.addDataTypeDefinition(newDef);
       }
   
  -    private static class MyAntTypeDefinition extends AntTypeDefinition {
  +    /**
  +     * This class contains the unknown element and the object
  +     * that is predefined.
  +     * @see AntTypeDefinition
  +     */
  +    public static class PreSetDefinition extends AntTypeDefinition {
           private AntTypeDefinition parent;
           private UnknownElement    element;
   
  -        public MyAntTypeDefinition(AntTypeDefinition parent, UnknownElement el) {
  +        /**
  +         * Creates a new <code>PresetDefinition</code> instance.
  +         *
  +         * @param parent The parent of this predefintion.
  +         * @param el     The predefined attributes, nested elements and text.
  +         */
  +        public PreSetDefinition(AntTypeDefinition parent, UnknownElement el) {
  +            if (parent instanceof PreSetDefinition) {
  +                PreSetDefinition p = (PreSetDefinition) parent;
  +                el.applyPreSet(p.element);
  +                parent = p.parent;
  +            }
               this.parent = parent;
               this.element = el;
           }
   
  +        /**
  +         * Override so that it is not allowed
  +         *
  +         * @param clazz a <code>Class</code> value
  +         */
           public void setClass(Class clazz) {
               throw new BuildException("Not supported");
           }
   
  +        /**
  +         * Override so that it is not allowed
  +         *
  +         * @param className a <code>String</code> value
  +         */
           public void setClassName(String className) {
               throw new BuildException("Not supported");
           }
  @@ -200,6 +226,7 @@
   
           /**
            * get the exposed class for this definition.
  +         * @param project the current project
            * @return the exposed class
            */
           public Class getExposedClass(Project project) {
  @@ -227,19 +254,38 @@
           /**
            * create an instance of the definition.
            * The instance may be wrapped in a proxy class.
  +         * This is a special version of create for IH and UE.
            * @param project the current project
            * @return the created object
            */
  -        public Object create(Project project) {
  +        public Object createObject(Project project) {
               Object o = parent.create(project);
               if (o == null) {
                   return null;
               }
  -            element.configure(o);
               return o;
           }
   
           /**
  +         * @return the predefined attributes, elements and text as
  +         *         a UnknownElement
  +         */
  +        public UnknownElement getPreSets() {
  +            return element;
  +        }
  +
  +        /**
  +         * Fake create an object, used by IH and UE to see that
  +         * this is a predefined object.
  +         *
  +         * @param project the current project
  +         * @return this object
  +         */
  +        public Object create(Project project) {
  +            return this;
  +        }
  +
  +        /**
            * Equality method for this definition
            *
            * @param other another definition
  @@ -253,7 +299,7 @@
               if (other.getClass() != getClass()) {
                   return false;
               }
  -            MyAntTypeDefinition otherDef = (MyAntTypeDefinition) other;
  +            PreSetDefinition otherDef = (PreSetDefinition) other;
               if (!parent.sameDefinition(otherDef.parent, project)) {
                   return false;
               }
  @@ -278,7 +324,7 @@
               if (!other.getClass().getName().equals(getClass().getName())) {
                   return false;
               }
  -            MyAntTypeDefinition otherDef = (MyAntTypeDefinition) other;
  +            PreSetDefinition otherDef = (PreSetDefinition) other;
               if (!parent.similarDefinition(otherDef.parent, project)) {
                   return false;
               }
  
  
  
  1.2       +39 -0     ant/src/testcases/org/apache/tools/ant/taskdefs/PreSetDefTest.java
  
  Index: PreSetDefTest.java
  ===================================================================
  RCS file: /home/cvs/ant/src/testcases/org/apache/tools/ant/taskdefs/PreSetDefTest.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- PreSetDefTest.java	14 Aug 2003 13:17:26 -0000	1.1
  +++ PreSetDefTest.java	6 Nov 2003 09:04:08 -0000	1.2
  @@ -55,6 +55,7 @@
   package org.apache.tools.ant.taskdefs;
   
   import org.apache.tools.ant.BuildFileTest;
  +import org.apache.tools.ant.BuildException;
   import org.apache.tools.ant.Project;
   import org.apache.tools.ant.Task;
   
  @@ -82,5 +83,43 @@
           expectLog("uri", "Hello world");
       }
   
  +    public void testDefaultTest() {
  +        expectLog("defaulttest", "attribute is false");
  +    }
  +
  +    public void testDoubleDefault() {
  +        expectLog("doubledefault", "attribute is falseattribute is true");
  +    }
  +
  +    public void testTextOptional() {
  +        expectLog("text.optional", "MyTextoverride text");
  +    }
  +
  +    public void testElementOrder() {
  +        expectLog("element.order", "Line 1Line 2");
  +    }
  +
  +    public void testElementOrder2() {
  +        expectLog("element.order2", "Line 1Line 2Line 3");
  +    }
  +    
  +    /**
  +     * A test class to check default properties
  +     */
  +    public static class DefaultTest extends Task {
  +        boolean isSet = false;
  +        boolean attribute = false;
  +        public void setAttribute(boolean b) {
  +            if (isSet) {
  +                throw new BuildException("Attribute Already set");
  +            }
  +            attribute = b;
  +            isSet = true;
  +        }
  +
  +        public void execute() {
  +            getProject().log("attribute is " + attribute);
  +        }
  +    }
   }
   
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@ant.apache.org
For additional commands, e-mail: dev-help@ant.apache.org