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/07/23 14:06:04 UTC

cvs commit: ant/src/testcases/org/apache/tools/ant/types PolyTest.java

peterreilly    2003/07/23 05:06:04

  Modified:    src/main/org/apache/tools/ant IntrospectionHelper.java
                        RuntimeConfigurable.java UnknownElement.java
  Added:       src/etc/testcases/types poly.xml
               src/testcases/org/apache/tools/ant/types PolyTest.java
  Log:
  This commit implements:
      - addConfigured(Type) to introspection rules
      - ant-type magic polymorhic attribute
      - allow types that have Project as a constructor to
        be used in addName(Type) and addConfiguredName(Type) methods
      - allow addName and addConfiguredName methods to have higher
        presedence that createName() methods.
  
  PR: 19897
  
  Revision  Changes    Path
  1.61      +300 -84   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.60
  retrieving revision 1.61
  diff -u -r1.60 -r1.61
  --- IntrospectionHelper.java	18 Jul 2003 12:45:54 -0000	1.60
  +++ IntrospectionHelper.java	23 Jul 2003 12:06:03 -0000	1.61
  @@ -70,10 +70,12 @@
    * Helper class that collects the methods a task or nested element
    * holds to set attributes, create nested elements or hold PCDATA
    * elements.
  + * The class is final as it has a private constructor.
    *
    * @author Stefan Bodewig
  + * @author Peter Reilly
    */
  -public class IntrospectionHelper implements BuildListener {
  +public final class IntrospectionHelper implements BuildListener {
   
       /**
        * Map from attribute names to attribute types
  @@ -205,7 +207,6 @@
           attributeSetters = new Hashtable();
           nestedTypes = new Hashtable();
           nestedCreators = new Hashtable();
  -        nestedStorers = new Hashtable();
           addTypeMethods = new ArrayList();
   
           this.bean = bean;
  @@ -220,7 +221,7 @@
               // check of add[Configured](Class) pattern
               if (args.length == 1
                   && java.lang.Void.TYPE.equals(returnType)
  -                && (name.equals("add") /*|| name.equals("addConfigured")*/)) {
  +                && (name.equals("add") || name.equals("addConfigured"))) {
                   insertAddTypeMethod(m);
                   continue;
               }
  @@ -286,19 +287,31 @@
                          && args.length == 0) {
   
                   String propName = getPropertyName(name, "create");
  -                nestedTypes.put(propName, returnType);
  -                nestedCreators.put(propName, new NestedCreator() {
  +                // Check if a create of this property is already present
  +                // add takes preference over create for CB purposes
  +                if (nestedCreators.get(propName) == null) {
  +                    nestedTypes.put(propName, returnType);
  +                    nestedCreators.put(propName, new NestedCreator() {
  +
  +                        public boolean isPolyMorphic() {
  +                            return false;
  +                        }
  +
  +                        public Class getElementClass() {
  +                            return null;
  +                        }
   
  -                        public Object create(Object parent)
  +                        public Object create(
  +                            Project project, Object parent, Object ignore)
                               throws InvocationTargetException,
                               IllegalAccessException {
  -
                               return m.invoke(parent, new Object[] {});
                           }
   
  +                        public void store(Object parent, Object child) {
  +                        }
                       });
  -                nestedStorers.remove(propName);
  -
  +                }
               } else if (name.startsWith("addConfigured")
                          && java.lang.Void.TYPE.equals(returnType)
                          && args.length == 1
  @@ -307,24 +320,45 @@
                          && !args[0].isPrimitive()) {
   
                   try {
  -                    final Constructor c =
  -                        args[0].getConstructor(new Class[] {});
  +                    Constructor constructor = null;
  +                    try {
  +                        constructor =
  +                            args[0].getConstructor(new Class[] {});
  +                    } catch (NoSuchMethodException ex) {
  +                        constructor =
  +                            args[0].getConstructor(new Class[] {
  +                                Project.class});
  +                    }
  +                    final Constructor c = constructor;
                       String propName = getPropertyName(name, "addConfigured");
                       nestedTypes.put(propName, args[0]);
                       nestedCreators.put(propName, new NestedCreator() {
   
  -                            public Object create(Object parent)
  -                                throws InvocationTargetException, IllegalAccessException, InstantiationException {
  +                            public boolean isPolyMorphic() {
  +                                return true;
  +                            }
   
  -                                Object o = c.newInstance(new Object[] {});
  -                                return o;
  +                            public Class getElementClass() {
  +                                return c.getDeclaringClass();
                               }
   
  -                        });
  -                    nestedStorers.put(propName, new NestedStorer() {
  +                            public Object create(
  +                                Project project, Object parent, Object child)
  +                                throws InvocationTargetException,
  +                                IllegalAccessException, InstantiationException {
  +                                if (child != null) {
  +                                    return child;
  +                                } else if (c.getParameterTypes().length == 0) {
  +                                    return c.newInstance(new Object[] {});
  +                                } else {
  +                                    return c.newInstance(new Object[] {
  +                                        project});
  +                                }
  +                            }
   
                               public void store(Object parent, Object child)
  -                                throws InvocationTargetException, IllegalAccessException, InstantiationException {
  +                                throws InvocationTargetException,
  +                                IllegalAccessException, InstantiationException {
   
                                   m.invoke(parent, new Object[] {child});
                               }
  @@ -341,22 +375,50 @@
                          && !args[0].isPrimitive()) {
   
                   try {
  -                    final Constructor c =
  -                        args[0].getConstructor(new Class[] {});
  +                    Constructor constructor = null;
  +                    try {
  +                        constructor =
  +                            args[0].getConstructor(new Class[] {});
  +                    } catch (NoSuchMethodException ex) {
  +                        constructor =
  +                            args[0].getConstructor(new Class[] {
  +                                Project.class});
  +                    }
  +                    final Constructor c = constructor;
                       String propName = getPropertyName(name, "add");
                       nestedTypes.put(propName, args[0]);
                       nestedCreators.put(propName, new NestedCreator() {
   
  -                            public Object create(Object parent)
  -                                throws InvocationTargetException, IllegalAccessException, InstantiationException {
  +                            public boolean isPolyMorphic() {
  +                                return true;
  +                            }
  +
  +                            public Class getElementClass() {
  +                                return c.getDeclaringClass();
  +                            }
  +
  +                            public Object create(
  +                                Project project, Object parent, Object child)
  +                                throws InvocationTargetException,
  +                                       IllegalAccessException, InstantiationException {
  +                                if (child != null) {
  +                                    // ignore
  +                                } else if (c.getParameterTypes().length == 0) {
  +                                    child = c.newInstance(new Object[] {});
  +                                } else {
  +                                    child = c.newInstance(new Object[] {
  +                                        project});
  +                                }
  +                                m.invoke(parent, new Object[] {child});
  +                                return child;
  +                            }
  +                            public void store(Object parent, Object child)
  +                                throws InvocationTargetException,
  +                                       IllegalAccessException, InstantiationException {
   
  -                                Object o = c.newInstance(new Object[] {});
  -                                m.invoke(parent, new Object[] {o});
  -                                return o;
                               }
   
                           });
  -                    nestedStorers.remove(name);
                   } catch (NoSuchMethodException nse) {
                       // ignore
                   }
  @@ -535,6 +597,40 @@
           throw new BuildException(msg);
       }
   
  +    private NestedCreator getNestedCreator(Project project, Object parent,
  +        String elementName) throws BuildException {
  +
  +        NestedCreator nc = (NestedCreator) nestedCreators.get(elementName);
  +        if (nc == null) {
  +            nc = createAddTypeCreator(project, parent, elementName);
  +        }
  +        if (nc == null && parent instanceof DynamicConfigurator) {
  +            DynamicConfigurator dc = (DynamicConfigurator) parent;
  +            final Object nestedElement = dc.createDynamicElement(elementName);
  +            if (nestedElement != null) {
  +                nc = new NestedCreator() {
  +                    public boolean isPolyMorphic() {
  +                        return false;
  +                    }
  +                    public Class getElementClass() {
  +                        return null;
  +                    }
  +
  +                    public Object create(
  +                        Project project, Object parent, Object ignore) {
  +                        return nestedElement;
  +                    }
  +                    public void store(Object parent, Object child) {
  +                    }
  +                };
  +            }
  +        }
  +        if (nc == null) {
  +            throwNotSupported(project, parent, elementName);
  +        }
  +        return nc;
  +    }
  +
       /**
        * Creates a named nested element. Depending on the results of the
        * initial introspection, either a method in the given parent instance
  @@ -558,32 +654,9 @@
        */
       public Object createElement(Project project, Object parent,
           String elementName) throws BuildException {
  -        NestedCreator nc = (NestedCreator) nestedCreators.get(elementName);
  -        if (nc == null && addTypeMethods.size() > 0) {
  -            Object nestedElement = createAddTypeElement(
  -                project, parent, elementName);
  -            if (nestedElement != null) {
  -                if (project != null) {
  -                    project.setProjectReference(nestedElement);
  -                }
  -                return nestedElement;
  -            }
  -        }
  -        if (nc == null && parent instanceof DynamicConfigurator) {
  -            DynamicConfigurator dc = (DynamicConfigurator) parent;
  -            Object nestedElement = dc.createDynamicElement(elementName);
  -            if (nestedElement != null) {
  -                if (project != null) {
  -                    project.setProjectReference(nestedElement);
  -                }
  -                return nestedElement;
  -            }
  -        }
  -        if (nc == null) {
  -            throwNotSupported(project, parent, elementName);
  -        }
  +        NestedCreator nc = getNestedCreator(project, parent, elementName);
           try {
  -            Object nestedElement = nc.create(parent);
  +            Object nestedElement = nc.create(project, parent, null);
               if (project != null) {
                   project.setProjectReference(nestedElement);
               }
  @@ -604,6 +677,23 @@
       }
   
       /**
  +     * returns an object that creates and stores an object
  +     * for an element of a parent.
  +     *
  +     * @param project      Project to which the parent object belongs.
  +     * @param parent       Parent object used to create the creator object to
  +     *                     create and store and instance of a subelement.
  +     * @param elementName  Name of the element to create an instance of.
  +     * @return a creator object to create and store the element instance.
  +     */
  +
  +    public Creator getElementCreator(
  +        Project project, Object parent, String elementName) {
  +        NestedCreator nc = getNestedCreator(project, parent, elementName);
  +        return new Creator(project, parent, nc);
  +    }
  +
  +    /**
        * Indicate if this element supports a nested element of the
        * given name.
        *
  @@ -642,7 +732,7 @@
           if (elementName == null) {
               return;
           }
  -        NestedStorer ns = (NestedStorer) nestedStorers.get(elementName);
  +        NestedCreator ns = (NestedCreator) nestedCreators.get(elementName);
           if (ns == null) {
               return;
           }
  @@ -876,7 +966,8 @@
                   return new AttributeSetter() {
                           public void set(Project p, Object parent,
                                           String value)
  -                            throws InvocationTargetException, IllegalAccessException, BuildException {
  +                            throws InvocationTargetException,
  +                                   IllegalAccessException, BuildException {
                               try {
                                   Object attribute = c.newInstance(new String[] {value});
                                   if (p != null) {
  @@ -934,23 +1025,138 @@
       }
   
       /**
  -     * Internal interface used to create nested elements. Not documented
  -     * in detail for reasons of source code readability.
  -     */
  -    private interface NestedCreator {
  -        Object create(Object parent)
  -            throws InvocationTargetException, IllegalAccessException, InstantiationException;
  +     * creator - allows use of create/store external
  +     * to IntrospectionHelper.
  +     * The class is final as it has a private constructor.
  +     */
  +    public static final class Creator {
  +        private NestedCreator nestedCreator;
  +        private Object parent;
  +        private Project project;
  +        private Object nestedObject;
  +        private String polyType;
  +
  +        /**
  +         * Creates a new Creator instance.
  +         * This object is given to the UnknownElement to create
  +         * objects for sub-elements. UnknownElement calls
  +         * create to create an object, the object then gets
  +         * configured and then UnknownElement calls store.
  +         * SetPolyType may be used to override the type used
  +         * to create the object with. SetPolyType gets called
  +         * before create.
  +         *
  +         * @param project the current project
  +         * @param parent  the parent object to create the object in
  +         * @param nestedCreator the nested creator object to use
  +         */
  +        private Creator(
  +            Project project, Object parent, NestedCreator nestedCreator) {
  +            this.project = project;
  +            this.parent = parent;
  +            this.nestedCreator = nestedCreator;
  +        }
  +
  +        /**
  +         * Used to override the class used to create the object.
  +         *
  +         * @param polyType a ant component type name
  +         */
  +        public void setPolyType(String polyType) {
  +            this.polyType = polyType;
  +        }
  +
  +        /**
  +         * Create an object using this creator, which is determined
  +         * by introspection.
  +         *
  +         * @return the created object
  +         */
  +        public Object create() {
  +            if (polyType != null) {
  +                if (!nestedCreator.isPolyMorphic()) {
  +                    throw new BuildException(
  +                        "Not allowed to use the polymorhic form"
  +                        + " for this element");
  +                }
  +                Class elementClass = nestedCreator.getElementClass();
  +                ComponentHelper helper =
  +                    ComponentHelper.getComponentHelper(project);
  +                nestedObject = ComponentHelper.getComponentHelper(project)
  +                    .createComponent(polyType);
  +                if (nestedObject == null) {
  +                    throw new BuildException(
  +                        "Unable to create object of type " + polyType);
  +                }
  +            }
  +            try {
  +                nestedObject = nestedCreator.create(
  +                    project, parent, nestedObject);
  +                if (project != null) {
  +                    project.setProjectReference(nestedObject);
  +                }
  +                return nestedObject;
  +            } catch (IllegalAccessException ex) {
  +                throw new BuildException(ex);
  +            } catch (InstantiationException ex) {
  +                throw new BuildException(ex);
  +            } catch (IllegalArgumentException ex) {
  +                if (polyType != null) {
  +                    throw new BuildException(
  +                        "Invalid type used " + polyType);
  +                }
  +                throw ex;
  +            } catch (InvocationTargetException ex) {
  +                Throwable t = ex.getTargetException();
  +                if (t instanceof BuildException) {
  +                    throw (BuildException) t;
  +                }
  +                throw new BuildException(t);
  +            }
  +        }
  +
  +        /**
  +         * Stores the nested elemtnt object using a storage method
  +         * detimined by introspection.
  +         *
  +         */
  +        public void store() {
  +            try {
  +                nestedCreator.store(parent, nestedObject);
  +            } catch (IllegalAccessException ex) {
  +                throw new BuildException(ex);
  +            } catch (InstantiationException ex) {
  +                throw new BuildException(ex);
  +            } catch (IllegalArgumentException ex) {
  +                if (polyType != null) {
  +                    throw new BuildException(
  +                        "Invalid type used " + polyType);
  +                }
  +                throw ex;
  +            } catch (InvocationTargetException ex) {
  +                Throwable t = ex.getTargetException();
  +                if (t instanceof BuildException) {
  +                    throw (BuildException) t;
  +                }
  +                throw new BuildException(t);
  +            }
  +        }
       }
   
       /**
  -     * Internal interface used to storing nested elements. Not documented
  +     * Internal interface used to create nested elements. Not documented
        * in detail for reasons of source code readability.
        */
  -    private interface NestedStorer {
  +    private interface NestedCreator {
  +        boolean isPolyMorphic();
  +        Class getElementClass();
  +        Object create(Project project, Object parent, Object child)
  +            throws InvocationTargetException, IllegalAccessException, InstantiationException;
           void store(Object parent, Object child)
               throws InvocationTargetException, IllegalAccessException, InstantiationException;
       }
   
  +
       /**
        * Internal interface used to setting element attributes. Not documented
        * in detail for reasons of source code readability.
  @@ -1023,21 +1229,20 @@
       public void messageLogged(BuildEvent event) {
       }
   
  +
       /**
  -     * Check if the parent accepts a typed nested element
  -     * and if so, create the object, call the parents
  -     * addmethod.
  -     * This method is part of the initial support
  -     * for add(Type) and addConfigured(Type).
  -     * AddConfigured(Type) will be done later.
  +     *
        */
  -
  -    private Object createAddTypeElement(
  -        Project project, Object parent, String elementName) {
  +    private NestedCreator createAddTypeCreator(
  +        Project project, Object parent, String elementName)
  +        throws BuildException {
  +        if (addTypeMethods.size() == 0) {
  +            return null;
  +        }
           ComponentHelper helper = ComponentHelper.getComponentHelper(project);
  +
           Object addedObject = null;
           Method addMethod = null;
  -
           Class clazz = helper.getComponentClass(elementName);
           if (clazz == null) {
               return null;
  @@ -1050,21 +1255,32 @@
           if (addedObject == null) {
               return null;
           }
  +        final Method method = addMethod;
  +        final Object nestedObject = addedObject;
   
  -        try {
  -            addMethod.invoke(parent, new Object[] {addedObject});
  -        } catch (IllegalAccessException ex) {
  -            throw new BuildException(ex);
  -        } catch (InvocationTargetException ex) {
  -            Throwable t = ex.getTargetException();
  -            if (t instanceof BuildException) {
  -                throw (BuildException) t;
  +        return new NestedCreator() {
  +            public boolean isPolyMorphic() {
  +                return false;
               }
  -            throw new BuildException(t);
  -        } catch (Throwable t) {
  -            throw new BuildException(t);
  -        }
  -        return addedObject;
  +
  +            public Class getElementClass() {
  +                return null;
  +            }
  +            public Object create(Project project, Object parent, Object ignore)
  +                throws InvocationTargetException, IllegalAccessException {
  +                if (!method.getName().endsWith("Configured")) {
  +                    method.invoke(parent, new Object[]{nestedObject});
  +                }
  +                return nestedObject;
  +            }
  +            public void store(Object parent, Object child)
  +                throws InvocationTargetException, IllegalAccessException,
  +                InstantiationException {
  +                if (method.getName().endsWith("Configured")) {
  +                    method.invoke(parent, new Object[]{nestedObject});
  +                }
  +            }
  +        };
       }
   
       /**
  
  
  
  1.41      +42 -6     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.40
  retrieving revision 1.41
  diff -u -r1.40 -r1.41
  --- RuntimeConfigurable.java	18 Jul 2003 12:45:55 -0000	1.40
  +++ RuntimeConfigurable.java	23 Jul 2003 12:06:03 -0000	1.41
  @@ -77,6 +77,9 @@
    */
   public class RuntimeConfigurable implements Serializable {
   
  +    /** Polymorphic attribute (May be XML NS attribute later) */
  +    private static final String ANT_TYPE = "ant-type";
  +    
       /** Name of the element to configure. */
       private String elementTag = null;
   
  @@ -88,7 +91,10 @@
        */
       private transient Object wrappedObject = null;
   
  -    /**
  +    /** the creator used to make the wrapped object */
  +    private transient IntrospectionHelper.Creator creator;
  +
  +    /** 
        * @deprecated
        * XML attributes for the element.
        */
  @@ -112,6 +118,9 @@
       /** Indicates if the wrapped object has been configured */
       private boolean proxyConfigured = false;
   
  +    /** the polymorphic type */
  +    private String polyType = null;
  +    
       /**
        * Sole constructor creating a wrapper for the specified object.
        *
  @@ -140,6 +149,16 @@
       }
   
       /**
  +     * Sets the creator of the element to be configured
  +     * used to store the element in the parent;
  +     *
  +     * @param creator the creator object
  +     */
  +    void setCreator(IntrospectionHelper.Creator creator) {
  +        this.creator = creator;
  +    }
  +    
  +    /**
        * Get the object for which this RuntimeConfigurable holds the configuration
        * information
        *
  @@ -150,6 +169,13 @@
       }
   
       /**
  +     * get the polymorphic type for this element
  +     */
  +    public String getPolyType() {
  +        return polyType;
  +    }
  +
  +    /**
        * Sets the attributes for the wrapped element.
        *
        * @deprecated
  @@ -170,12 +196,16 @@
        * @param value the attribute's value.
        */
       public void setAttribute(String name, String value) {
  -        if (attributeNames == null) {
  -            attributeNames = new ArrayList();
  -            attributeMap = new HashMap();
  +        if (name.equalsIgnoreCase(ANT_TYPE)) {
  +            this.polyType = value;
  +        } else {
  +            if (attributeNames == null) {
  +                attributeNames = new ArrayList();
  +                attributeMap = new HashMap();
  +            }
  +            attributeNames.add(name);
  +            attributeMap.put(name, value);
           }
  -        attributeNames.add(name);
  -        attributeMap.put(name, value);
       }
   
       /** Return the attribute map.
  @@ -389,6 +419,12 @@
                   childTask.setRuntimeConfigurableWrapper(child);
               }
   
  + 
  +            if ((child.creator != null) && configureChildren) {
  +                child.maybeConfigure(p);
  +                child.creator.store();
  +                continue;
  +            }
               /*
                * backwards compatibility - element names of nested
                * elements have been all lower-case in Ant, except for
  
  
  
  1.58      +15 -12    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.57
  retrieving revision 1.58
  diff -u -r1.57 -r1.58
  --- UnknownElement.java	22 Jul 2003 11:58:55 -0000	1.57
  +++ UnknownElement.java	23 Jul 2003 12:06:03 -0000	1.58
  @@ -312,17 +312,13 @@
           Class parentClass = parent.getClass();
           IntrospectionHelper ih = IntrospectionHelper.getHelper(parentClass);
   
  +
           if (children != null) {
               Iterator it = children.iterator();
               for (int i = 0; it.hasNext(); i++) {
                   RuntimeConfigurable childWrapper = parentWrapper.getChild(i);
                   UnknownElement child = (UnknownElement) it.next();
  -
  -                // backwards compatibility - element names of nested
  -                // elements have been all lower-case in Ant, except for
  -                // TaskContainers
  -                if (!handleChild(ih, parent, child,
  -                                 child.getTag().toLowerCase(Locale.US),
  +                if (!handleChild(ih, parent, child, 
                                    childWrapper)) {
                       if (!(parent instanceof TaskContainer)) {
                           ih.throwNotSupported(getProject(), parent,
  @@ -475,17 +471,24 @@
        */
       private boolean handleChild(IntrospectionHelper ih,
                                   Object parent, UnknownElement child,
  -                                String childTag,
                                   RuntimeConfigurable childWrapper) {
  -        if (ih.supportsNestedElement(childTag)) {
  -            Object realChild
  -                = ih.createElement(getProject(), parent, childTag);
  +        // backwards compatibility - element names of nested
  +        // elements have been all lower-case in Ant, except for
  +        // TaskContainers
  +        String childName = child.getTag().toLowerCase(Locale.US);
  +        if (ih.supportsNestedElement(childName)) {
  +            IntrospectionHelper.Creator creator =
  +                ih.getElementCreator(getProject(), parent, childName);
  +            creator.setPolyType(childWrapper.getPolyType());
  +            Object realChild=creator.create();
  +            childWrapper.setCreator(creator);
               childWrapper.setProxy(realChild);
               if (realChild instanceof Task) {
                   Task childTask = (Task) realChild;
                   childTask.setRuntimeConfigurableWrapper(childWrapper);
  -                childTask.setTaskName(childTag);
  -                childTask.setTaskType(childTag);
  +                childTask.setTaskName(childName);
  +                childTask.setTaskType(childName);
  +                childTask.setLocation(child.getLocation());
               }
               child.handleChildren(realChild, childWrapper);
               return true;
  
  
  
  1.1                  ant/src/etc/testcases/types/poly.xml
  
  Index: poly.xml
  ===================================================================
  <project name="test" basedir=".">
    
    <property name="c" value="org.apache.tools.ant.types.PolyTest"/>
    
    <path id="test-c">
      <pathelement location="../../../../build/testcases" />
      <pathelement path="${java.class.path}" />
    </path>
  
    <target name="init">
      <typedef loaderref="poly"   classpathref="test-c"
               name = "myfileset" classname="${c}$MyFileSet"/>
  
      <typedef loaderref="poly" classpathref="test-c"
               name = "mypath"  classname="${c}$MyPath"/>
  
      <typedef loaderref="poly" classpathref="test-c"
               name = "mytask"  classname="${c}$MyTask"/>
    </target>
  
    <target name="fileset" depends="init">
      <mytask>
        <fileset dir="."/>
      </mytask>
    </target>
  
    <target name="fileset-ant-type" depends="init">
      <mytask>
        <fileset ant-type="myfileset" dir="."/>
      </mytask>
    </target>
  
    <target name="path" depends="init">
      <mytask>
        <path path="."/>
      </mytask>
    </target>
  
    <target name="path-ant-type" depends="init">
      <mytask>
        <path ant-type="mypath" path="."/>
      </mytask>
    </target>
  
  </project>
  
  
  
  1.1                  ant/src/testcases/org/apache/tools/ant/types/PolyTest.java
  
  Index: PolyTest.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "Ant" and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  package org.apache.tools.ant.types;
  
  import org.apache.tools.ant.BuildException;
  import org.apache.tools.ant.BuildFileTest;
  import org.apache.tools.ant.Project;
  import org.apache.tools.ant.Task;
  import org.apache.tools.ant.taskdefs.condition.Condition;
  
  public class PolyTest extends BuildFileTest {
  
      public PolyTest(String name) {
          super(name);
      }
  
      public void setUp() {
          configureProject("src/etc/testcases/types/poly.xml");
      }
  
      public void testFileSet() {
          expectLogContaining("fileset", "types.FileSet");
      }
      
      public void testFileSetAntType() {
          expectLogContaining("fileset-ant-type", "types.PolyTest$MyFileSet");
      }
  
      public void testPath() {
          expectLogContaining("path", "types.Path");
      }
      
      public void testPathAntType() {
          expectLogContaining("path-ant-type", "types.PolyTest$MyPath");
      }
  
      public static class MyFileSet extends FileSet {}
  
      public static class MyPath extends Path {
          public MyPath(Project project) {
              super(project);
          }
      }
  
      public static class MyTask extends Task {
          public void addPath(Path path) {
              log("class of path is " + path.getClass());
          }
          public void addFileset(FileSet fileset) {
              log("class of fileset is " + fileset.getClass());
          }
      }
  }
  
  
  

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