commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From wer...@apache.org
Subject cvs commit: jakarta-commons-sandbox/jelly/src/java/org/apache/commons/jelly/tags/werkz JellyBuildListener.java ProjectTag.java
Date Tue, 18 Jun 2002 18:36:43 GMT
werken      2002/06/18 11:36:43

  Modified:    jelly/src/java/org/apache/commons/jelly
                        DynaBeanTagSupport.java JellyContext.java
                        XMLOutput.java
               jelly/src/java/org/apache/commons/jelly/expression/jexl
                        JexlExpressionFactory.java
               jelly/src/java/org/apache/commons/jelly/impl
                        BeanTagScript.java DynaTagScript.java
                        TextScript.java
               jelly/src/java/org/apache/commons/jelly/tags/ant
                        AntTagLibrary.java DataTypeTag.java TaskTag.java
               jelly/src/java/org/apache/commons/jelly/tags/core
                        ForEachTag.java
               jelly/src/java/org/apache/commons/jelly/tags/jeez
                        JeezTagLibrary.java
               jelly/src/java/org/apache/commons/jelly/tags/werkz
                        JellyBuildListener.java ProjectTag.java
  Added:       jelly/src/java/org/apache/commons/jelly/tags/ant
                        AntTagSupport.java IntrospectionHelper.java
                        OtherAntTag.java
  Removed:     jelly/src/java/org/apache/commons/jelly/tags/ant
                        TaskPropertyTag.java
  Log:
  Mostly hackings to make all sorts of Ant tasks, datatypes, dynamically
  loaded taskdefs, wrapped javabean taskdefs, and other Ant muckage work
  much more smoothly with Jelly.
  
  Other superficial no-op changes while debugging.
  
  Revision  Changes    Path
  1.2       +3 -0      jakarta-commons-sandbox/jelly/src/java/org/apache/commons/jelly/DynaBeanTagSupport.java
  
  Index: DynaBeanTagSupport.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/jelly/src/java/org/apache/commons/jelly/DynaBeanTagSupport.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- DynaBeanTagSupport.java	30 May 2002 08:11:55 -0000	1.1
  +++ DynaBeanTagSupport.java	18 Jun 2002 18:36:42 -0000	1.2
  @@ -107,5 +107,8 @@
       public void setDynaBean(DynaBean dynaBean) {
           this.dynaBean = dynaBean;
       }
  +
  +    public void beforeSetAttributes() throws Exception {
  +    }
       
   }
  
  
  
  1.13      +10 -4     jakarta-commons-sandbox/jelly/src/java/org/apache/commons/jelly/JellyContext.java
  
  Index: JellyContext.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/jelly/src/java/org/apache/commons/jelly/JellyContext.java,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -u -r1.12 -r1.13
  --- JellyContext.java	14 Jun 2002 10:55:31 -0000	1.12
  +++ JellyContext.java	18 Jun 2002 18:36:42 -0000	1.13
  @@ -185,8 +185,10 @@
       }
   
       public void setScopedVariable(String name, Object value) {
  -        if ( getExport() ) {
  +        if ( getExport() && getParent() != null ) {
               getParent().setScopedVariable( name, value );
  +        } else {
  +            setVariable( name, value );
           }
       }
   
  @@ -209,11 +211,15 @@
           
       /** @return the value of the given variable name */
       public Object getVariable(String name) {
  -        if ( getInherit() ) {
  -            return getParent().findVariable( name );
  +        Object value = variables.get(name);
  +
  +        if ( value == null 
  +             &&
  +             getInherit() ) {
  +            value = getParent().findVariable( name );
           }
   
  -        return variables.get(name);
  +        return value;
       }
   
       /** Sets the value of the given variable name */
  
  
  
  1.5       +9 -5      jakarta-commons-sandbox/jelly/src/java/org/apache/commons/jelly/XMLOutput.java
  
  Index: XMLOutput.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/jelly/src/java/org/apache/commons/jelly/XMLOutput.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- XMLOutput.java	17 May 2002 15:18:12 -0000	1.4
  +++ XMLOutput.java	18 Jun 2002 18:36:42 -0000	1.5
  @@ -138,6 +138,10 @@
       public void close() throws IOException {
       }
   
  +    public void flush() throws IOException {
  +        ((XMLWriter)contentHandler).flush();
  +    }
  +
       // Static helper methods
       //-------------------------------------------------------------------------                    
   
  
  
  
  1.8       +14 -14    jakarta-commons-sandbox/jelly/src/java/org/apache/commons/jelly/expression/jexl/JexlExpressionFactory.java
  
  Index: JexlExpressionFactory.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/jelly/src/java/org/apache/commons/jelly/expression/jexl/JexlExpressionFactory.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- JexlExpressionFactory.java	13 Jun 2002 21:31:14 -0000	1.7
  +++ JexlExpressionFactory.java	18 Jun 2002 18:36:42 -0000	1.8
  @@ -88,20 +88,20 @@
   
           final Expression jexlExpression = new JexlExpression(
               org.apache.commons.jexl.ExpressionFactory.createExpression(text)
  -        );
  +            );
           
           if ( isSupportAntVariables() && isValidAntVariableName(text) ) {
               ExpressionSupport expr = new ExpressionSupport() {
  -                public Object evaluate(JellyContext context) {
  -                    Object answer = jexlExpression.evaluate(context);
  +                    public Object evaluate(JellyContext context) {
  +                        Object answer = jexlExpression.evaluate(context);
   
  -                    if ( answer == null ) {
  -                        answer = context.getScopedVariable(text);
  -                    }
  +                        if ( answer == null ) {
  +                            answer = context.getVariable(text);
  +                        }
   
  -                    return answer;
  -                }
  -            };
  +                        return answer;
  +                    }
  +                };
   
               return expr;
           }
  
  
  
  1.9       +7 -5      jakarta-commons-sandbox/jelly/src/java/org/apache/commons/jelly/impl/BeanTagScript.java
  
  Index: BeanTagScript.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/jelly/src/java/org/apache/commons/jelly/impl/BeanTagScript.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- BeanTagScript.java	28 May 2002 23:38:57 -0000	1.8
  +++ BeanTagScript.java	18 Jun 2002 18:36:42 -0000	1.9
  @@ -160,6 +160,8 @@
                   }
               }
           }
  +
  +        // System.err.println( "BeanTagScript::compile() " + this );
           
           // now create the arrays to avoid object allocation & casting when
           // running the script
  
  
  
  1.6       +12 -5     jakarta-commons-sandbox/jelly/src/java/org/apache/commons/jelly/impl/DynaTagScript.java
  
  Index: DynaTagScript.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/jelly/src/java/org/apache/commons/jelly/impl/DynaTagScript.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- DynaTagScript.java	14 Jun 2002 10:24:14 -0000	1.5
  +++ DynaTagScript.java	18 Jun 2002 18:36:42 -0000	1.6
  @@ -69,6 +69,7 @@
   import org.apache.commons.jelly.Script;
   import org.apache.commons.jelly.Tag;
   import org.apache.commons.jelly.DynaTag;
  +import org.apache.commons.jelly.DynaBeanTagSupport;
   import org.apache.commons.jelly.XMLOutput;
   import org.apache.commons.jelly.expression.Expression;
   import org.apache.commons.logging.Log;
  @@ -108,15 +109,21 @@
   
       /** Evaluates the body of a tag */
       public void run(JellyContext context, XMLOutput output) throws Exception {
  +
           tag.setContext(context);
           
           DynaTag dynaTag = (DynaTag) tag;
  +
  +        if (dynaTag instanceof DynaBeanTagSupport) {
  +            ((DynaBeanTagSupport)dynaTag).beforeSetAttributes();
  +        }
           
           // ### probably compiling this to 2 arrays might be quicker and smaller
           for (Iterator iter = attributes.entrySet().iterator(); iter.hasNext();) {
               Map.Entry entry = (Map.Entry) iter.next();
               String name = (String) entry.getKey();
               Expression expression = (Expression) entry.getValue();
  +
               Object value = expression.evaluate(context);
               dynaTag.setAttribute(name, value);
           }
  
  
  
  1.7       +5 -7      jakarta-commons-sandbox/jelly/src/java/org/apache/commons/jelly/impl/TextScript.java
  
  Index: TextScript.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/jelly/src/java/org/apache/commons/jelly/impl/TextScript.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- TextScript.java	14 Jun 2002 06:53:03 -0000	1.6
  +++ TextScript.java	18 Jun 2002 18:36:42 -0000	1.7
  @@ -148,6 +148,4 @@
       public void run(JellyContext context, XMLOutput output) throws Exception {
           output.write(text);
       }
  -
  -     
   }
  
  
  
  1.12      +68 -11    jakarta-commons-sandbox/jelly/src/java/org/apache/commons/jelly/tags/ant/AntTagLibrary.java
  
  Index: AntTagLibrary.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/jelly/src/java/org/apache/commons/jelly/tags/ant/AntTagLibrary.java,v
  retrieving revision 1.11
  retrieving revision 1.12
  diff -u -r1.11 -r1.12
  --- AntTagLibrary.java	14 Jun 2002 11:22:33 -0000	1.11
  +++ AntTagLibrary.java	18 Jun 2002 18:36:43 -0000	1.12
  @@ -79,11 +79,14 @@
   import org.apache.commons.logging.LogFactory;
   
   import org.apache.tools.ant.Project;
  +import org.apache.tools.ant.ProjectComponent;
   import org.apache.tools.ant.Task;
   import org.apache.tools.ant.BuildLogger;
   import org.apache.tools.ant.NoBannerLogger;
   import org.apache.tools.ant.types.DataType;
   import org.apache.tools.ant.types.Reference;
  +import org.apache.tools.ant.types.EnumeratedAttribute;
  +import org.apache.tools.ant.taskdefs.optional.junit.FormatterElement;
   
   import org.xml.sax.Attributes;
   
  @@ -91,6 +94,7 @@
    * A Jelly custom tag library that allows Ant tasks to be called from inside Jelly.
    *
    * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
  + * @author <a href="mailto:bob@eng.werken.com">bob mcwhirter</a>
    * @version $Revision$
    */
   public class AntTagLibrary extends TagLibrary {
  @@ -119,7 +123,7 @@
                   }
               },
               File.class
  -        );
  +            );
           
           ConvertUtils.register(
               new Converter() {
  @@ -135,8 +139,27 @@
                   }
               },
               Reference.class
  -        );
  -    }        
  +            );
  +        
  +        ConvertUtils.register(
  +            new Converter() {
  +                public Object convert(Class type, Object value) {
  +                    if ( value instanceof EnumeratedAttribute ) {
  +                        return (EnumeratedAttribute) value;
  +                    }
  +                    else if ( value instanceof String ) {
  +                        FormatterElement.TypeAttribute attr = new FormatterElement.TypeAttribute();
  +                        attr.setValue( (String) value );
  +                        return attr;
  +                    }
  +                    return null;
  +                }
  +                
  +            },
  +            FormatterElement.TypeAttribute.class
  +            );
  +    }
  +
           
       public AntTagLibrary() {
           this.project = createProject();
  @@ -185,6 +208,7 @@
   
       /** Creates a new script to execute the given tag name and attributes */
       public TagScript createTagScript(String name, Attributes attributes) throws Exception {
  +
           Project project = getProject();
           
           // custom Ant tags
  @@ -202,24 +226,57 @@
           }
           
           // an Ant DataType?
  -        Object dataType = null;
  +        DataType dataType = null;
           type = (Class) project.getDataTypeDefinitions().get(name);
  +        
           if ( type != null ) {            
  -            dataType = type.newInstance();
  -        }
  -        else {
  -            dataType = project.createDataType(name);
  +
  +            try {
  +                java.lang.reflect.Constructor ctor = null;
  +                boolean noArg = false;
  +                // DataType can have a "no arg" constructor or take a single 
  +                // Project argument.
  +                try {
  +                    ctor = type.getConstructor(new Class[0]);
  +                    noArg = true;
  +                } catch (NoSuchMethodException nse) {
  +                    ctor = type.getConstructor(new Class[] { Project.class });
  +                    noArg = false;
  +                }
  +                
  +                if (noArg) {
  +                    dataType = (DataType) ctor.newInstance(new Object[0]);
  +                } else {
  +                    dataType = (DataType) ctor.newInstance(new Object[] {project});
  +                }
  +                dataType.setProject( project );
  +
  +            } catch (Throwable t) {
  +                t.printStackTrace();
  +                // ignore 
  +            }
           }
           if ( dataType != null ) {
               DataTypeTag tag = new DataTypeTag( name, dataType );
  +            tag.setAntProject( getProject() );
               tag.getDynaBean().set( "project", project );
               return TagScript.newInstance(tag);
           }
           
  -        // assume its an Ant property object (classpath, arg etc).
  -        Tag tag = new TaskPropertyTag( name );
  -        return TagScript.newInstance(tag);
  +        // Since ant resolves so many dynamically loaded/created
  +        // things at run-time, we can make virtually no assumptions
  +        // as to what this tag might be.  
  +        Tag tag = new OtherAntTag( project,
  +                                   name );
  +
  +        return TagScript.newInstance( tag );
  +    }
  +
  +    public TagScript createRuntimeTaskTagScript(String taskName, Attributes attributes) throws Exception {
  +        TaskTag tag = new TaskTag( project, taskName );
  +        return TagScript.newInstance( tag );
       }
  +                                                
   
       
       // Properties
  
  
  
  1.8       +115 -41   jakarta-commons-sandbox/jelly/src/java/org/apache/commons/jelly/tags/ant/DataTypeTag.java
  
  Index: DataTypeTag.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/jelly/src/java/org/apache/commons/jelly/tags/ant/DataTypeTag.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- DataTypeTag.java	14 Jun 2002 17:19:20 -0000	1.7
  +++ DataTypeTag.java	18 Jun 2002 18:36:43 -0000	1.8
  @@ -73,9 +73,12 @@
   import org.apache.commons.jelly.JellyContext;
   import org.apache.commons.jelly.JellyException;
   import org.apache.commons.jelly.XMLOutput;
  +import org.apache.commons.jelly.Tag;
   
   import org.apache.tools.ant.Task;
   import org.apache.tools.ant.types.DataType;
  +import org.apache.tools.ant.types.Path;
  +import org.apache.tools.ant.types.Reference;
   
   /** 
    * A tag which manages a DataType used to configure a Task
  @@ -83,67 +86,115 @@
    * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
    * @version $Revision$
    */
  -public class DataTypeTag extends DynaBeanTagSupport {
  +public class DataTypeTag extends AntTagSupport {
   
       /** the name of the DataType */
       private String name;
       
       /** the Ant DataType */
  -    private Object dataType;
  +    private DataType dataType;
   
       public DataTypeTag() {
       }
   
  -    public DataTypeTag(String name, Object dataType) {
  +    public DataTypeTag(String name, DataType dataType) {
           this.name = name;
           this.dataType = dataType;
           setDynaBean( new ConvertingWrapDynaBean(dataType) );
       }
   
  +    public Object getObject() {
  +        return this.dataType;
  +    }
  +
       // Tag interface
       //------------------------------------------------------------------------- 
       public void doTag(XMLOutput output) throws Exception {
  -        TaskSource tag = (TaskSource) findAncestorWithClass( TaskSource.class );
  -        if ( tag == null ) {
  -            throw new JellyException( "You should only use Ant DataType tags within an Ant Task" );
  -        }        
  -        
  -        Object task = tag.getTaskObject();
  -        Object dataType = getDataType();
   
  -        // now we need to configure the task with the data type
  -        
  -        // first try setting a property on the DynaBean wrapper of the task
  -        DynaBean dynaBean = tag.getDynaBean();
  -        DynaClass dynaClass = dynaBean.getDynaClass();
  -        DynaProperty dynaProperty = dynaClass.getDynaProperty(name);
  -        if ( dynaProperty != null ) {
  -            // lets set the bean property
  -            dynaBean.set( name, dataType );
  -        }
  -        else {
  -            // lets invoke the addFoo() method instead
  -            String methodName = "add" + name.substring(0,1).toUpperCase() + name.substring(1);
  -            Class taskClass = task.getClass();
  -            Class[] parameterTypes = new Class[] { dataType.getClass() };
  -            Method method = MethodUtils.getAccessibleMethod(
  -                taskClass, methodName, parameterTypes 
  -            );
  -            if ( method == null ) {
  -                throw new JellyException( 
  -                    "Cannot add dataType: " + dataType + " to Ant task: " + task 
  -                    + " as no method called: " + methodName + " could be found" 
  -                );
  +        // run the body first to configure any nested DataType instances
  +        getBody().run(context, output);
  +
  +        AntTagSupport parentTag = (AntTagSupport) findAncestorWithClass( AntTagSupport.class);
  +
  +        if ( parentTag == null ) {
  +            // ignore, as all it can be is a top-level datatype with
  +            // an id which has -already- added it to the project thanks
  +            // to the setAttribute() call.
  +            return;
  +        }
  +
  +        Object   targetObj = parentTag.getObject();
  +        DataType dataType  = getDataType();
  +
  +        if ( targetObj == null ) {
  +            // ignore, as all it can be is a top-level datatype with
  +            // an id which has -already- added it to the project thanks
  +            // to the setAttribute() call.
  +            return;
  +        }
  +
  +        if( parentTag instanceof DynaBeanTagSupport ) {
  +            DynaBean dynaBean = ((DynaBeanTagSupport)parent).getDynaBean();
  +            DynaClass dynaClass = dynaBean.getDynaClass();
  +            DynaProperty dynaProperty = dynaClass.getDynaProperty(name);
  +
  +            if ( dynaProperty != null ) {
  +                // lets set the bean property
  +                try {
  +                    dynaBean.set( name, dataType );
  +                    return;
  +                } catch (Exception e) {
  +                    // ignore, maybe something else will work.
  +                }
               }
  -            
  -            Object[] parameters = new Object[] { dataType };
  -            method.invoke( task, parameters );
  +        }
  +
  +        if ( targetObj instanceof Path
  +             &&
  +             dataType instanceof Path ) {
  +            ((Path)targetObj).append( (Path)dataType );
  +            return;
           }
           
  +        IntrospectionHelper ih = IntrospectionHelper.getHelper( targetObj.getClass() );
           
  -                
  -        // run the body first to configure any nested DataType instances
  -        getBody().run(context, output);
  +        try
  +        {
  +            ih.storeElement( getAntProject(),
  +                             targetObj,
  +                             dataType,
  +                             getName() );
  +        }
  +        catch (Exception e) {
  +            String dataTypeName = dataType.getClass().getName();
  +            String baseName = dataTypeName.substring( dataTypeName.lastIndexOf( "." ) + 1 );
  +
  +            String methName = "add" + baseName;
  +
  +            Method m = MethodUtils.getAccessibleMethod( targetObj.getClass(),
  +                                                        methName,
  +                                                        dataType.getClass() );
  +
  +            if ( m == null ) {
  +                String lname = baseName.toLowerCase();
  +                methName = "add" + lname.substring( 0, 1 ).toUpperCase() + lname.substring( 1 );
  +
  +                m = MethodUtils.getAccessibleMethod( targetObj.getClass(),
  +                                                     methName,
  +                                                     dataType.getClass() );
  +            }
  +
  +            if ( m != null ) {
  +                try
  +                {
  +                    m.invoke( targetObj, new Object[] { dataType } );
  +                    return;
  +                }
  +                catch (Exception i) {
  +                    i.printStackTrace();
  +                }
  +            }
  +        }
       }
       
       // Properties
  @@ -166,16 +217,39 @@
       /** 
        * @return the Ant dataType
        */
  -    public Object getDataType() {
  +    public DataType getDataType() {
           return dataType;
       }
       
       /** 
        * Sets the Ant dataType
        */
  -    public void setDataType(Object dataType) {
  +    public void setDataType(DataType dataType) {
           this.dataType = dataType;
           setDynaBean( new ConvertingWrapDynaBean(dataType) );
  +    }
  +
  +    public void setAttribute(String name, Object value) {
  +        if ( "id".equals( name ) ) {
  +            getAntProject().addReference( (String) value, dataType );
  +            return;
  +        }
  +
  +        if ( "refid".equals( name ) ) {
  +
  +            Object refd = getAntProject().getReferences().get( value );
  +
  +
  +            this.dataType.setRefid( new Reference( (String) value ) );
  +            return;
  +        }
  +
  +        super.setAttribute( name, value );
  +    }
  +
  +    public String toString() {
  +        return "[DataTypeTag: name=" + getName()
  +            + "; dataType=" + getDataType() + "]";
       }
       
   }
  
  
  
  1.11      +73 -17    jakarta-commons-sandbox/jelly/src/java/org/apache/commons/jelly/tags/ant/TaskTag.java
  
  Index: TaskTag.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/jelly/src/java/org/apache/commons/jelly/tags/ant/TaskTag.java,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- TaskTag.java	14 Jun 2002 10:32:34 -0000	1.10
  +++ TaskTag.java	18 Jun 2002 18:36:43 -0000	1.11
  @@ -70,11 +70,14 @@
   import org.apache.commons.jelly.DynaBeanTagSupport;
   import org.apache.commons.jelly.JellyContext;
   import org.apache.commons.jelly.XMLOutput;
  +import org.apache.commons.jelly.CompilableTag;
   
   import org.apache.tools.ant.Task;
   import org.apache.tools.ant.Project;
   import org.apache.tools.ant.ProjectHelper;
  +import org.apache.tools.ant.BuildException;
   import org.apache.tools.ant.taskdefs.Echo;
  +import org.apache.tools.ant.types.DataType;
   
   /** 
    * A tag which invokes an Ant Task
  @@ -82,7 +85,7 @@
    * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
    * @version $Revision$
    */
  -public class TaskTag extends DynaBeanTagSupport implements TaskSource {
  +public class TaskTag extends AntTagSupport implements TaskSource { 
   
       /** argumment types */
       private static final Class[] addTaskParamTypes = { String.class };
  @@ -96,17 +99,31 @@
       /** the name of the Ant task */
       private String taskName;
   
  -    /** the current Ant project */
  -    private Project project;
  -
       public TaskTag() {
       }
   
       public TaskTag(Project project, Class taskType, String taskName) {
  -        this.project = project;
  +        super( project );
           this.taskType = taskType;
           this.taskName = taskName;
       }
  +
  +    public TaskTag(Project project, String taskName) {
  +        super( project );
  +        this.taskName = taskName;
  +    }
  +
  +    public String getTaskName() {
  +        return this.taskName;
  +    }
  +
  +    public Class getTaskType() {
  +        return this.taskType;
  +    }
  +
  +    public void setTaskType(Class taskType) {
  +        this.taskType = taskType;
  +    }
       
       /**
        * Override this method as it is called before the tag is configured with its attributes.
  @@ -124,26 +141,47 @@
       //------------------------------------------------------------------------- 
       public void doTag(XMLOutput output) throws Exception {
           Task task = getTask();                
  -
  -        String text = getBodyText();
  +        // setDynaBean( new ConvertingWrapDynaBean( task ) );
   
   		// if the task has an addText()
   		Method method = MethodUtils.getAccessibleMethod(
               taskType, "addText", addTaskParamTypes
           );            
  +
   		if (method != null) {
  +            String text = getBodyText();
  +
   			Object[] args = { text };
   			method.invoke(task, args);
  -		}
  +		} else {
  +            getBody().run(context, output);
  +        }
           
           task.perform();   
       }
  +
  +    // DataTypeCreator interface
  +    //------------------------------------------------------------------------- 
  +
  +    public DataType createDataType(String name) throws Exception {
  +
  +        IntrospectionHelper helper = IntrospectionHelper.getHelper( getTask().getClass() );
  +
  +        return (DataType) helper.createElement( getAntProject(),
  +                                                getTask(),
  +                                                name );
  +    }
  +
       
       // TaskSource interface
       //------------------------------------------------------------------------- 
       public Object getTaskObject() throws Exception {
           return getTask();
       }
  +
  +    public Object getObject() throws Exception {
  +        return getTask();
  +    }
       
       // Properties
       //-------------------------------------------------------------------------                
  @@ -152,22 +190,40 @@
        * @return the Ant task
        */
       public Task getTask() throws Exception {
  -        if ( task == null ) {
  -            task = (Task) taskType.newInstance();
  -            task.setProject(project);
  -            task.setTaskName(taskName);
  -            task.init();
  -            setDynaBean( new ConvertingWrapDynaBean(task) );
  +
  +        if ( this.task == null ) {
  +            if ( getTaskType() == null ) {
  +                setTaskType( (Class) getAntProject().getTaskDefinitions().get( getTaskName() ) );
  +            }
  +            
  +            this.task = createTask( getTaskName(),
  +                                    getTaskType() );
  +            setDynaBean( new ConvertingWrapDynaBean( this.task ) );
           }
  -        return task;
  +        return this.task;
       }
  -    
  +
       /** 
        * Sets the Ant task
        */
       public void setTask(Task task) {
           this.task = task;
  -        setDynaBean( new ConvertingWrapDynaBean(task) );
  +        setDynaBean( new ConvertingWrapDynaBean( this.task ) );
       }
       
  +
  +    public String toString() {
  +        try
  +        {
  +            return "[TaskTag: task=" + getTask().getClass().getName() + "]";
  +        }
  +        catch (Exception e) {
  +            return "[TaskTag: unknown: " + e.getLocalizedMessage() + " ]";
  +        }
  +    }
  +
  +    public void beforeSetAttributes() throws Exception {
  +        getTask();
  +    }
  +
   }
  
  
  
  1.1                  jakarta-commons-sandbox/jelly/src/java/org/apache/commons/jelly/tags/ant/AntTagSupport.java
  
  Index: AntTagSupport.java
  ===================================================================
  
  package org.apache.commons.jelly.tags.ant;
  
  import org.apache.commons.jelly.DynaBeanTagSupport;
  import org.apache.tools.ant.Project;
  import org.apache.tools.ant.Task;
  import org.apache.tools.ant.TaskAdapter;
  import org.apache.tools.ant.types.DataType;
  
  import org.apache.commons.beanutils.MethodUtils;
  
  import java.lang.reflect.Method;
  
  public abstract class AntTagSupport extends DynaBeanTagSupport {
  
      private Project project;
  
      public AntTagSupport() {
          
      }
      public AntTagSupport(Project project) {
          this.project = project;
      }
  
      public void setAntProject(Project project) {
          this.project = project;
      }
  
      public Project getAntProject() {
          return this.project;
      }
  
      public Object createNestedObject(String name) throws Exception {
  
          Object object = getObject();
  
          IntrospectionHelper ih = IntrospectionHelper.getHelper( object.getClass() );
  
          Object dataType = null;
  
          try {
              dataType = ih.createElement( getAntProject(), object, name );
          } catch (Exception e) {
              dataType = null;
              e.printStackTrace();
          }
  
          return dataType;
      }
  
      public Task createTask(String taskName) throws Exception {
          return createTask( taskName,
                             (Class) getAntProject().getTaskDefinitions().get( taskName ) );
      }
  
      public Task createTask(String taskName,
                             Class taskType) throws Exception {
          if (taskType == null) {
              return null;
          }
  
          Object o = taskType.newInstance();
          Task task = null;
          if( o instanceof Task ) {
              task=(Task)o;
          } else {
              TaskAdapter taskA=new TaskAdapter();
              taskA.setProxy( o );
              task=taskA;
          }
  
          task.setProject(getAntProject());
          task.setTaskName(taskName);
  
          return task;
      }
  
      public void setAttribute(String name, Object value) {
  
          Object obj = null;
  
          try {
              obj = getObject();
          } catch (Exception e) {
              e.printStackTrace();
              return;
          }
  
          if ( obj == null ) {
              return;
          }
          
          IntrospectionHelper ih = IntrospectionHelper.getHelper( obj.getClass() );
  
          if ( value instanceof String ) {
              try {
                  ih.setAttribute( getAntProject(), obj, name.toLowerCase(), (String) value );
                  return;
              } catch (Exception e) {
                  // e.printStackTrace();
              }
          }
  
          try {
              ih.storeElement( getAntProject(), obj, value, name );
          } catch (Exception e) {
              // e.printStackTrace();
  
              try
              {
                  super.setAttribute( name, value );
              }
              catch (Exception f) {
                  // f.printStackTrace();
              }
          }
      }
      
      public abstract Object getObject() throws Exception;
  }
  
  
  
  1.1                  jakarta-commons-sandbox/jelly/src/java/org/apache/commons/jelly/tags/ant/IntrospectionHelper.java
  
  Index: IntrospectionHelper.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2000 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 "The Jakarta Project", "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.commons.jelly.tags.ant;
  
  import org.apache.tools.ant.Project;
  import org.apache.tools.ant.BuildEvent;
  import org.apache.tools.ant.BuildListener;
  import org.apache.tools.ant.BuildException;
  import org.apache.tools.ant.types.Path;
  import org.apache.tools.ant.types.DataType;
  import org.apache.tools.ant.types.EnumeratedAttribute;
  
  import java.lang.reflect.*;
  import java.io.File;
  import java.util.*;
  
  /**
   * Helper class that collects the methods a task or nested element
   * holds to set attributes, create nested elements or hold PCDATA
   * elements.
   *
   * @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
   */
  public class IntrospectionHelper implements BuildListener {
  
      /**
       * holds the types of the attributes that could be set.
       */
      private Hashtable attributeTypes;
  
      /**
       * holds the attribute setter methods.
       */
      private Hashtable attributeSetters;
  
      /**
       * Holds the types of nested elements that could be created.
       */
      private Hashtable nestedTypes;
  
      /**
       * Holds methods to create nested elements.
       */
      private Hashtable nestedCreators;
  
      /**
       * Holds methods to store configured nested elements.
       */
      private Hashtable nestedStorers;
  
      /**
       * The method to add PCDATA stuff.
       */
      private Method addText = null;
  
      /**
       * The Class that's been introspected.
       */
      private Class bean;
  
      /**
       * instances we've already created
       */
      private static Hashtable helpers = new Hashtable();
  
      private IntrospectionHelper(final Class bean) {
          attributeTypes = new Hashtable();
          attributeSetters = new Hashtable();
          nestedTypes = new Hashtable();
          nestedCreators = new Hashtable();
          nestedStorers = new Hashtable();
          
          this.bean = bean;
  
          Method[] methods = bean.getMethods();
          for (int i=0; i<methods.length; i++) {
              final Method m = methods[i];
              final String name = m.getName();
              Class returnType = m.getReturnType();
              Class[] args = m.getParameterTypes();
  
              // not really user settable properties on tasks
              if (org.apache.tools.ant.Task.class.isAssignableFrom(bean) 
                  && args.length == 1 &&
                  (
                   (
                    "setLocation".equals(name) && org.apache.tools.ant.Location.class.equals(args[0])
                    ) || (
                     "setTaskType".equals(name) && java.lang.String.class.equals(args[0])
                    )
                   )) {
                  continue;
              }
              
              // hide addTask for TaskContainers
              if (org.apache.tools.ant.TaskContainer.class.isAssignableFrom(bean) 
                  && args.length == 1 && "addTask".equals(name) 
                  && org.apache.tools.ant.Task.class.equals(args[0])) {
                  continue;
              }
              
  
              if ("addText".equals(name)
                  && java.lang.Void.TYPE.equals(returnType)
                  && args.length == 1
                  && java.lang.String.class.equals(args[0])) {
  
                  addText = methods[i];
  
              } else if (name.startsWith("set")
                         && java.lang.Void.TYPE.equals(returnType)
                         && args.length == 1
                         && !args[0].isArray()) {
  
                  String propName = getPropertyName(name, "set");
                  AttributeSetter as = createAttributeSetter(m, args[0]);
                  if (as != null) {
                      attributeTypes.put(propName, args[0]);
                      attributeSetters.put(propName, as);
                  }
  
              } else if (name.startsWith("create")
                         && !returnType.isArray()
                         && !returnType.isPrimitive()
                         && args.length == 0) {
  
                  String propName = getPropertyName(name, "create");
                  nestedTypes.put(propName, returnType);
                  nestedCreators.put(propName, new NestedCreator() {
  
                          public Object create(Object parent) 
                              throws InvocationTargetException, 
                              IllegalAccessException {
  
                              return m.invoke(parent, new Object[] {});
                          }
  
                      });
                  
              } else if (name.startsWith("addConfigured")
                         && java.lang.Void.TYPE.equals(returnType)
                         && args.length == 1
                         && !java.lang.String.class.equals(args[0])
                         && !args[0].isArray()
                         && !args[0].isPrimitive()) {
                   
                  try {
                      final Constructor c = 
                          args[0].getConstructor(new Class[] {});
                      String propName = getPropertyName(name, "addConfigured");
                      nestedTypes.put(propName, args[0]);
                      nestedCreators.put(propName, new NestedCreator() {
  
                              public Object create(Object parent) 
                                  throws InvocationTargetException, IllegalAccessException, InstantiationException {
                                  
                                  Object o = c.newInstance(new Object[] {});
                                  return o;
                              }
  
                          });
                      nestedStorers.put(propName, new NestedStorer() {
  
                              public void store(Object parent, Object child) 
                                  throws InvocationTargetException, IllegalAccessException, InstantiationException {
                                  
                                  m.invoke(parent, new Object[] {child});
                              }
  
                          });
                  } catch (NoSuchMethodException nse) {
                  }
              } else if (name.startsWith("add")
                         && java.lang.Void.TYPE.equals(returnType)
                         && args.length == 1
                         && !java.lang.String.class.equals(args[0])
                         && !args[0].isArray()
                         && !args[0].isPrimitive()) {
                   
                  try {
                      final Constructor c = 
                          args[0].getConstructor(new Class[] {});
                      String propName = getPropertyName(name, "add");
                      nestedTypes.put(propName, args[0]);
                      nestedCreators.put(propName, new NestedCreator() {
  
                              public Object create(Object parent) 
                                  throws InvocationTargetException, IllegalAccessException, InstantiationException {
                                  
                                  Object o = c.newInstance(new Object[] {});
                                  m.invoke(parent, new Object[] {o});
                                  return o;
                              }
  
                          });
                  } catch (NoSuchMethodException nse) {
                  }
              }
          }
      }
      
      /**
       * Factory method for helper objects.
       */
      public synchronized static IntrospectionHelper getHelper(Class c) {
          IntrospectionHelper ih = (IntrospectionHelper) helpers.get(c);
          if (ih == null) {
              ih = new IntrospectionHelper(c);
              helpers.put(c, ih);
          }
          return ih;
      }
  
      /**
       * Sets the named attribute.
       */
      public void setAttribute(Project p, Object element, String attributeName, 
                               String value)
          throws BuildException {
          AttributeSetter as = (AttributeSetter) attributeSetters.get(attributeName);
          if (as == null) {
              String msg = getElementName(p, element) +
                  //String msg = "Class " + element.getClass().getName() +
                  " doesn't support the \"" + attributeName + "\" attribute.";
              throw new BuildException(msg);
          }
          try {
              as.set(p, element, value);
          } catch (IllegalAccessException ie) {
              // impossible as getMethods should only return public methods
              throw new BuildException(ie);
          } catch (InvocationTargetException ite) {
              Throwable t = ite.getTargetException();
              if (t instanceof BuildException) {
                  throw (BuildException) t;
              }
              throw new BuildException(t);
          }
      }
  
      /**
       * Adds PCDATA areas.
       */
      public void addText(Project project, Object element, String text) {
          if (addText == null) {
  	   String msg = getElementName(project, element) +
             //String msg = "Class " + element.getClass().getName() +
                  " doesn't support nested text data.";
              throw new BuildException(msg);
          }
          try {
              addText.invoke(element, new String[] {text});
          } catch (IllegalAccessException ie) {
              // impossible as getMethods should only return public methods
              throw new BuildException(ie);
          } catch (InvocationTargetException ite) {
              Throwable t = ite.getTargetException();
              if (t instanceof BuildException) {
                  throw (BuildException) t;
              }
              throw new BuildException(t);
          }
      }
  
      /**
       * Creates a named nested element.
       */
      public Object createElement(Project project, Object element, String elementName) 
          throws BuildException {
          NestedCreator nc = (NestedCreator) nestedCreators.get(elementName);
          if (nc == null) {
  	    String msg = getElementName(project, element) +
              //String msg = "Class " + element.getClass().getName() +
                  " doesn't support the nested \"" + elementName + "\" element.";
              throw new BuildException(msg);
          }
          try {
              Object nestedElement = nc.create(element);
              if (nestedElement instanceof DataType) {
                  ((DataType)nestedElement).setProject(project);
              }
              return nestedElement;
          } catch (IllegalAccessException ie) {
              // impossible as getMethods should only return public methods
              throw new BuildException(ie);
          } catch (InstantiationException ine) {
              // impossible as getMethods should only return public methods
              throw new BuildException(ine);
          } catch (InvocationTargetException ite) {
              Throwable t = ite.getTargetException();
              if (t instanceof BuildException) {
                  throw (BuildException) t;
              }
              throw new BuildException(t);
          }
      }
  
      /**
       * Creates a named nested element.
       */
      public void storeElement(Project project, Object element, Object child, String elementName) 
          throws BuildException {
  
          if (elementName == null) {
              throw new BuildException( "null elementName" );
              // return;
          }
          NestedStorer ns = (NestedStorer)nestedStorers.get(elementName);
          if (ns == null) {
              throw new BuildException( "null nested storer" );
              //return;
          }
          try {
              ns.store(element, child);
          } catch (IllegalAccessException ie) {
              // impossible as getMethods should only return public methods
              throw new BuildException(ie);
          } catch (InstantiationException ine) {
              // impossible as getMethods should only return public methods
              throw new BuildException(ine);
          } catch (InvocationTargetException ite) {
              Throwable t = ite.getTargetException();
              if (t instanceof BuildException) {
                  throw (BuildException) t;
              }
              throw new BuildException(t);
          }
      }
  
      /**
       * returns the type of a named nested element.
       */
      public Class getElementType(String elementName) 
          throws BuildException {
          Class nt = (Class) nestedTypes.get(elementName);
          if (nt == null) {
              String msg = "Class " + bean.getName() +
                  " doesn't support the nested \"" + elementName + "\" element.";
              throw new BuildException(msg);
          }
          return nt;
      }
  
      /**
       * returns the type of a named attribute.
       */
      public Class getAttributeType(String attributeName) 
          throws BuildException {
          Class at = (Class) attributeTypes.get(attributeName);
          if (at == null) {
              String msg = "Class " + bean.getName() +
                  " doesn't support the \"" + attributeName + "\" attribute.";
              throw new BuildException(msg);
          }
          return at;
      }
  
      /**
       * Does the introspected class support PCDATA?
       */
      public boolean supportsCharacters() {
          return addText != null;
      }
  
      /**
       * Return all attribues supported by the introspected class.
       */
      public Enumeration getAttributes() {
          return attributeSetters.keys();
      }
  
      /**
       * Return all nested elements supported by the introspected class.
       */
      public Enumeration getNestedElements() {
          return nestedTypes.keys();
      }
  
      /**
       * Create a proper implementation of AttributeSetter for the given
       * attribute type.  
       */
      private AttributeSetter createAttributeSetter(final Method m,
                                                    final Class arg) {
  
          // simplest case - setAttribute expects String
          if (java.lang.String.class.equals(arg)) {
              return new AttributeSetter() {
                      public void set(Project p, Object parent, String value) 
                          throws InvocationTargetException, IllegalAccessException {
                          m.invoke(parent, new String[] {value});
                      }
                  };
  
          // now for the primitive types, use their wrappers
          } else if (java.lang.Character.class.equals(arg)
                     || java.lang.Character.TYPE.equals(arg)) {
              return new AttributeSetter() {
                      public void set(Project p, Object parent, String value) 
                          throws InvocationTargetException, IllegalAccessException {
                          m.invoke(parent, new Character[] {new Character(value.charAt(0))});
                      }
  
                  };
          } else if (java.lang.Byte.TYPE.equals(arg)) {
              return new AttributeSetter() {
                      public void set(Project p, Object parent, String value) 
                          throws InvocationTargetException, IllegalAccessException {
                          m.invoke(parent, new Byte[] {new Byte(value)});
                      }
  
                  };
          } else if (java.lang.Short.TYPE.equals(arg)) {
              return new AttributeSetter() {
                      public void set(Project p, Object parent, String value) 
                          throws InvocationTargetException, IllegalAccessException {
                          m.invoke(parent, new Short[] {new Short(value)});
                      }
  
                  };
          } else if (java.lang.Integer.TYPE.equals(arg)) {
              return new AttributeSetter() {
                      public void set(Project p, Object parent, String value) 
                          throws InvocationTargetException, IllegalAccessException {
                          m.invoke(parent, new Integer[] {new Integer(value)});
                      }
  
                  };
          } else if (java.lang.Long.TYPE.equals(arg)) {
              return new AttributeSetter() {
                      public void set(Project p, Object parent, String value) 
                          throws InvocationTargetException, IllegalAccessException {
                          m.invoke(parent, new Long[] {new Long(value)});
                      }
  
                  };
          } else if (java.lang.Float.TYPE.equals(arg)) {
              return new AttributeSetter() {
                      public void set(Project p, Object parent, String value) 
                          throws InvocationTargetException, IllegalAccessException {
                          m.invoke(parent, new Float[] {new Float(value)});
                      }
  
                  };
          } else if (java.lang.Double.TYPE.equals(arg)) {
              return new AttributeSetter() {
                      public void set(Project p, Object parent, String value) 
                          throws InvocationTargetException, IllegalAccessException {
                          m.invoke(parent, new Double[] {new Double(value)});
                      }
  
                  };
  
          // boolean gets an extra treatment, because we have a nice method 
          // in Project
          } else if (java.lang.Boolean.class.equals(arg) 
                     || java.lang.Boolean.TYPE.equals(arg)) {
              return new AttributeSetter() {
                      public void set(Project p, Object parent, String value) 
                          throws InvocationTargetException, IllegalAccessException {
                          m.invoke(parent, 
                                   new Boolean[] {new Boolean(Project.toBoolean(value))});
                      }
  
                  };
  
          // Class doesn't have a String constructor but a decent factory method
          } else if (java.lang.Class.class.equals(arg)) {
              return new AttributeSetter() {
                      public void set(Project p, Object parent, String value) 
                          throws InvocationTargetException, IllegalAccessException, BuildException {
                          try {
                              m.invoke(parent, new Class[] {Class.forName(value)});
                          } catch (ClassNotFoundException ce) {
                              throw new BuildException(ce);
                          }
                      }
                  };
  
          // resolve relative paths through Project
          } else if (java.io.File.class.equals(arg)) {
              return new AttributeSetter() {
                      public void set(Project p, Object parent, String value) 
                          throws InvocationTargetException, IllegalAccessException {
                          m.invoke(parent, new File[] {p.resolveFile(value)});
                      }
  
                  };
  
          // resolve relative paths through Project
          } else if (org.apache.tools.ant.types.Path.class.equals(arg)) {
              return new AttributeSetter() {
                      public void set(Project p, Object parent, String value) 
                          throws InvocationTargetException, IllegalAccessException {
                          m.invoke(parent, new Path[] {new Path(p, value)});
                      }
  
                  };
  
          // EnumeratedAttributes have their own helper class
          } else if (org.apache.tools.ant.types.EnumeratedAttribute.class.isAssignableFrom(arg)) {
              return new AttributeSetter() {
                      public void set(Project p, Object parent, String value) 
                          throws InvocationTargetException, IllegalAccessException, BuildException {
                          try {
                              org.apache.tools.ant.types.EnumeratedAttribute ea = (org.apache.tools.ant.types.EnumeratedAttribute)arg.newInstance();
                              ea.setValue(value);
                              m.invoke(parent, new EnumeratedAttribute[] {ea});
                          } catch (InstantiationException ie) {
                              throw new BuildException(ie);
                          }
                      }
                  };
          
  
          // worst case. look for a public String constructor and use it
          } else {
  
              try {
                  final Constructor c = 
                      arg.getConstructor(new Class[] {java.lang.String.class});
  
                  return new AttributeSetter() {
                          public void set(Project p, Object parent, 
                                          String value) 
                              throws InvocationTargetException, IllegalAccessException, BuildException {
                              try {
                                  Object attribute = c.newInstance(new String[] {value});
                                  if (attribute instanceof DataType) {
                                      ((DataType)attribute).setProject(p);
                                  }
                                  m.invoke(parent, new Object[] {attribute});
                              } catch (InstantiationException ie) {
                                  throw new BuildException(ie);
                              }
                          }
                      };
                  
              } catch (NoSuchMethodException nme) {
              }
          }
          
          return null;
      }
  
      protected String getElementName(Project project, Object element)
      {
  	Hashtable elements = project.getTaskDefinitions();
  	String typeName = "task";
  	if (!elements.contains( element.getClass() ))
  	{
  	    elements = project.getDataTypeDefinitions();
  	    typeName = "data type";
  	    if (!elements.contains( element.getClass() ))
  	    {
  		elements = null;
  	    }
  	}
  
  	if (elements != null)
  	{
  	    Enumeration e = elements.keys();
  	    while (e.hasMoreElements())
  	    {
  		String elementName = (String) e.nextElement();
  		Class elementClass = (Class) elements.get( elementName );
  		if ( element.getClass().equals( elementClass ) )
  		{
  		    return "The <" + elementName + "> " + typeName;
  		}
  	    }
  	}
  	
  	return "Class " + element.getClass().getName();
      }
  
      /**
       * extract the name of a property from a method name - subtracting
       * a given prefix.  
       */
      private String getPropertyName(String methodName, String prefix) {
          int start = prefix.length();
          return methodName.substring(start).toLowerCase();
      }
  
      private interface NestedCreator {
          public Object create(Object parent) 
              throws InvocationTargetException, IllegalAccessException, InstantiationException;
      }
      
      private interface NestedStorer {
          public void store(Object parent, Object child) 
              throws InvocationTargetException, IllegalAccessException, InstantiationException;
      }
      
      private interface AttributeSetter {
          public void set(Project p, Object parent, String value)
              throws InvocationTargetException, IllegalAccessException, 
                     BuildException;
      }
  
      public void buildStarted(BuildEvent event) {}
      public void buildFinished(BuildEvent event) {
          attributeTypes.clear();
          attributeSetters.clear();
          nestedTypes.clear();
          nestedCreators.clear();
          addText = null;
          helpers.clear();
      }
  
      public void targetStarted(BuildEvent event) {}
      public void targetFinished(BuildEvent event) {}
      public void taskStarted(BuildEvent event) {}
      public void taskFinished(BuildEvent event) {}
      public void messageLogged(BuildEvent event) {}
  }
  
  
  
  1.1                  jakarta-commons-sandbox/jelly/src/java/org/apache/commons/jelly/tags/ant/OtherAntTag.java
  
  Index: OtherAntTag.java
  ===================================================================
  
  package org.apache.commons.jelly.tags.ant;
  
  import org.apache.commons.beanutils.ConvertingWrapDynaBean;
  
  import org.apache.commons.jelly.XMLOutput;
  import org.apache.commons.jelly.JellyContext;
  import org.apache.commons.jelly.DynaBeanTagSupport;
  import org.apache.commons.beanutils.MethodUtils;
  import org.apache.commons.beanutils.PropertyUtils;
  
  import org.apache.tools.ant.Project;
  import org.apache.tools.ant.Task;
  import org.apache.tools.ant.TaskAdapter;
  import org.apache.tools.ant.types.DataType;
  
  import java.lang.reflect.Method;
  
  /** Tag supporting ant's dynamic runtime behaviour for
   *  'unknown' tags.
   *
   *  <p>
   *  This tag duplicates much of the functionality from
   *  TaskTag and DataTypeTag and should probably be refactored.
   *  </p>
   *
   *  @author <a href="mailto:bob@eng.werken.com">bob mcwhirter</a>
   */
  public class OtherAntTag extends AntTagSupport {
  
      private static final Class[] addTaskParamTypes = { String.class };
  
      /** The general object underlying this tag. */
      protected Object object;
  
      /** The name of this tag. */
      protected String tagName;
  
      /** Task, if this tag represents a task. */
      protected Task task;
  
      /** Construct with a project and tag name.
       *
       *  @param project The Ant project.
       *  @param tagName The name on the tag.
       */
      public OtherAntTag(Project project,
                         String tagName) {
          super( project );
          this.tagName = tagName;
      }
  
      public void doTag(XMLOutput output) throws Exception {
  
          Object obj = getObject();
  
          if ( this.task != null ) {
              Method method = MethodUtils.getAccessibleMethod( this.task.getClass(),
                                                               "addText",
                                                               addTaskParamTypes );            
              
              if (method != null) {
                  String text = getBodyText();
                  
                  Object[] args = { text };
                  method.invoke(this.task, args);
              } else {
                  getBody().run(context, output);
              }
              
              this.task.perform(); 
          } else {
              getBody().run( context, output );
              AntTagSupport parent = (AntTagSupport) getParent();
              
              Object parentObj =  parent.getObject();
              
              IntrospectionHelper ih = IntrospectionHelper.getHelper( parentObj.getClass() );
  
              try
              {
                  ih.storeElement( getAntProject(),
                                   parentObj,
                                   getObject(),
                                   getTagName() );
              }
              catch (Exception e) {
  
              }
          }
      }
  
      public String getTagName() {
          return this.tagName;
      }
  
      /** Retrieve the general object underlying this tag.
       *
       *  @return The object underlying this tag.
       */
      public Object getObject() {
          return this.object;
      }
      
      /** Set the object underlying this tag.
       *
       *  @param object The object.
       */
      public void setObject(Object object) {
          this.object = object;
          setDynaBean( new ConvertingWrapDynaBean( object ) );
      }
  
      public void beforeSetAttributes() throws Exception {
  
          Project project = getAntProject();
          String  tagName = getTagName();
  
          if ( project.getTaskDefinitions().containsKey( tagName ) ) {
              Task task = createTask( tagName );
  
              if ( task instanceof TaskAdapter ) {
                  setObject( ((TaskAdapter)task).getProxy() );
              } else {
                  setObject( task );
              }
              this.task = task;
              return;
              
          } else {
              AntTagSupport ancestor = (AntTagSupport) findAncestorWithClass( AntTagSupport.class );
              
              if ( ancestor == null ) {
                  return;
              }
              
              Object nested = ancestor.createNestedObject( getTagName() );
              
              if ( nested != null ) {
                  setObject( nested );
  
                  try
                  {
                      PropertyUtils.setProperty( nested, "name", "goober" );
                  }
                  catch (Exception e) {
                  }
                  return;
              } 
          }
      }
  }
  
      
  
  
  
  1.13      +5 -6      jakarta-commons-sandbox/jelly/src/java/org/apache/commons/jelly/tags/core/ForEachTag.java
  
  Index: ForEachTag.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/jelly/src/java/org/apache/commons/jelly/tags/core/ForEachTag.java,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -u -r1.12 -r1.13
  --- ForEachTag.java	12 Jun 2002 19:28:08 -0000	1.12
  +++ ForEachTag.java	18 Jun 2002 18:36:43 -0000	1.13
  @@ -145,7 +145,6 @@
                   if (indexVar != null) {
                       context.setVariable(indexVar, new Integer(index));
                   }
  -                // System.err.println( "body=" + getBody() );
                   getBody().run(context, output);
                   
                   // now we need to move to next index
  
  
  
  1.3       +47 -15    jakarta-commons-sandbox/jelly/src/java/org/apache/commons/jelly/tags/jeez/JeezTagLibrary.java
  
  Index: JeezTagLibrary.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/jelly/src/java/org/apache/commons/jelly/tags/jeez/JeezTagLibrary.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- JeezTagLibrary.java	14 Jun 2002 14:13:48 -0000	1.2
  +++ JeezTagLibrary.java	18 Jun 2002 18:36:43 -0000	1.3
  @@ -63,6 +63,8 @@
   
   import java.util.Iterator;
   import java.util.List;
  +import java.util.Set;
  +import java.util.HashSet;
   
   import org.apache.commons.jelly.JellyContext;
   import org.apache.commons.jelly.JellyException;
  @@ -71,8 +73,8 @@
   import org.apache.commons.jelly.TagLibrary;
   import org.apache.commons.jelly.tags.werkz.WerkzTagLibrary;
   import org.apache.commons.jelly.tags.ant.AntTagLibrary;
  -import org.apache.commons.jelly.tags.core.CoreTagLibrary;
  -
  +// import org.apache.commons.jelly.tags.core.CoreTagLibrary;
  +import org.apache.tools.ant.Project;
   import org.apache.commons.logging.Log;
   import org.apache.commons.logging.LogFactory;
   
  @@ -90,22 +92,30 @@
       private Log log = LogFactory.getLog(JeezTagLibrary.class);
   
       /** jelly:core taglib. */
  -    private TagLibrary coreTagLib;
  +    // private TagLibrary coreTagLib;
   
       /** jelly:werkz taglib. */
       private TagLibrary werkzTagLib;
   
       /** jelly:ant taglib. */
  -    private TagLibrary antTagLib;
  +    private AntTagLibrary antTagLib;
  +
  +    private Set runtimeTasks;
  +
  +    private Project project;
       
       /** Construct.
        *
        *  @param antProject The ant Project.
        */
  -    public JeezTagLibrary(org.apache.tools.ant.Project antProject) {
  -        this.coreTagLib  = new CoreTagLibrary();
  -        this.antTagLib   = new AntTagLibrary( antProject );
  -        this.werkzTagLib = new WerkzTagLibrary();
  +    public JeezTagLibrary(Project antProject) {
  +
  +        this.project      = antProject;
  +        this.runtimeTasks = new HashSet();
  +
  +        // this.coreTagLib   = new CoreTagLibrary();
  +        this.antTagLib    = new AntTagLibrary( antProject );
  +        this.werkzTagLib  = new WerkzTagLibrary();
   
           registerTag( "target",
                        TargetTag.class );
  @@ -114,23 +124,45 @@
       public TagScript createTagScript(String name,
                                        Attributes attrs) throws Exception
       {
  -        
           TagScript script = super.createTagScript( name, attrs );
   
           if ( script == null ) {
   
  -            script = this.coreTagLib.createTagScript( name, attrs );
  +            // script = this.coreTagLib.createTagScript( name, attrs );
   
               if ( script == null ) {
                   
                   script = this.werkzTagLib.createTagScript( name, attrs );
                   
                   if ( script == null ) {
  -                    script = this.antTagLib.createTagScript( name, attrs );
  +
  +                    if ( isRuntimeTask( name ) ) {
  +                        if ( ! project.getTaskDefinitions().containsKey( name ) ) {
  +                            script = this.antTagLib.createRuntimeTaskTagScript( name, attrs );
  +                        } else {
  +                            this.runtimeTasks.remove( name );
  +                        }
  +                    }
  +
  +                    if ( script == null ) {
  +                        script = this.antTagLib.createTagScript( name, attrs );
  +                    }
  +
  +                    if ( name.equals( "taskdef" ) ) {
  +                        addRuntimeTask( attrs.getValue( "name" ) );
  +                    } 
                   }
               }
           }
   
           return script;
  +    }
  +
  +    protected void addRuntimeTask(String name) {
  +        this.runtimeTasks.add( name );
  +    }
  +
  +    protected boolean isRuntimeTask(String name) {
  +        return this.runtimeTasks.contains( name );
       }
   }
  
  
  
  1.3       +57 -13    jakarta-commons-sandbox/jelly/src/java/org/apache/commons/jelly/tags/werkz/JellyBuildListener.java
  
  Index: JellyBuildListener.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/jelly/src/java/org/apache/commons/jelly/tags/werkz/JellyBuildListener.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- JellyBuildListener.java	14 Jun 2002 04:04:12 -0000	1.2
  +++ JellyBuildListener.java	18 Jun 2002 18:36:43 -0000	1.3
  @@ -3,11 +3,14 @@
   
   import org.apache.commons.jelly.XMLOutput;
   
  +import org.apache.tools.ant.Project;
   import org.apache.tools.ant.BuildListener;
   import org.apache.tools.ant.BuildEvent;
  +import org.apache.tools.ant.taskdefs.optional.junit.JUnitTask;
   
   import org.xml.sax.SAXException;
   
  +import java.io.IOException;
   import java.util.Stack;
   
   public class JellyBuildListener implements BuildListener
  @@ -16,9 +19,20 @@
   
       private Stack taskStack;
   
  +    private boolean debug;
  +
       public JellyBuildListener(XMLOutput out) {
           this.taskStack = new Stack();
  -        this.out = out;
  +        this.out       = out;
  +        this.debug     = false;
  +    }
  +
  +    public boolean isDebug() {
  +        return this.debug;
  +    }
  +
  +    public void isDebug(boolean debug) {
  +        this.debug = debug;
       }
   
       public void buildFinished(BuildEvent event) {
  @@ -29,21 +43,52 @@
   
       public void messageLogged(BuildEvent event) {
   
  -        try
  -        {
  -            if ( this.taskStack.isEmpty() )
  -            {
  -                out.write( event.getMessage() + "\n" );
  +        // System.err.println( "messageLogged(" + event + ")" );
  +
  +        if ( event.getPriority() > Project.MSG_INFO
  +             &&
  +             ! isDebug() ) {
  +            return;
  +        }
  +
  +        try {
  +            if ( ! this.taskStack.isEmpty() ) {
  +                out.write( "    [" + this.taskStack.peek() + "] " );
               }
  -            else
  -            {
  -                out.write( "    [" + this.taskStack.peek() + "] " + event.getMessage() + "\n" );
  +
  +            switch ( event.getPriority() ) {
  +                case ( Project.MSG_ERR ): {
  +                    out.write( "[ERROR] ");
  +                    break;
  +                }
  +                case ( Project.MSG_WARN ): {
  +                    // out.write( "[WARN] ");
  +                    break;
  +                }
  +                case ( Project.MSG_INFO ): {
  +                    // normal, do nothing.
  +                    break;
  +                }
  +                case ( Project.MSG_VERBOSE ): {
  +                    out.write( "[VERBOSE] ");
  +                    break;
  +                }
  +                case ( Project.MSG_DEBUG ): {
  +                    out.write( "[DEBUG] ");
  +                    break;
  +                }
               }
  -        }
  -        catch (SAXException e)
  -        {
  +            
  +            out.write( event.getMessage() + "\n" );
  +            out.flush();
  +        } catch (SAXException e) {
  +            // fall-back to stderr.
  +            System.err.println( event.getMessage() );
  +            System.err.flush();
  +        } catch (IOException e) {
               // ignore
           }
  +            
       }
   
       public void targetFinished(BuildEvent event) {
  @@ -59,7 +104,6 @@
       public void taskStarted(BuildEvent event) {
           this.taskStack.push( event.getTask().getTaskName() );
       }
  -
   }
   
   
  
  
  
  1.10      +6 -0      jakarta-commons-sandbox/jelly/src/java/org/apache/commons/jelly/tags/werkz/ProjectTag.java
  
  Index: ProjectTag.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/jelly/src/java/org/apache/commons/jelly/tags/werkz/ProjectTag.java,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- ProjectTag.java	14 Jun 2002 11:22:33 -0000	1.9
  +++ ProjectTag.java	18 Jun 2002 18:36:43 -0000	1.10
  @@ -117,9 +117,15 @@
           // allow access to Ant methods via the project class
           context.setVariable( "project", antProject );
   
  +/*
           antProject.getBuildListeners().clear();
   
           antProject.addBuildListener( new JellyBuildListener( output ) );
  +        PrintStream demuxOut = new PrintStream(new DemuxOutputStream(antProject, false));
  +        PrintStream demuxErr = new PrintStream(new DemuxOutputStream(antProject, true));
  +        System.setOut( demuxOut );
  +        System.setErr( demuxErr );
  +*/
           
           getBody().run(context, output);
       }
  
  
  

--
To unsubscribe, e-mail:   <mailto:commons-dev-unsubscribe@jakarta.apache.org>
For additional commands, e-mail: <mailto:commons-dev-help@jakarta.apache.org>


Mime
View raw message