You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by js...@apache.org on 2002/06/27 16:16:24 UTC

cvs commit: jakarta-commons-sandbox/jelly/src/java/org/apache/commons/jelly/tags/ant AntTag.java AntTagLibrary.java

jstrachan    2002/06/27 07:16:24

  Modified:    jelly/src/test/org/apache/commons/jelly/ant
                        example_tasks.jelly
               jelly    .cvsignore build.xml
               jelly/src/java/org/apache/commons/jelly/tags/ant
                        AntTagLibrary.java
  Added:       jelly/src/java/org/apache/commons/jelly/tags/ant AntTag.java
  Log:
  Patched the Ant Tag adapter to follow more closely the task lifecycle document, kindly outlined by Stefan.
  This new AntTag should replace the old stuff: TaskTag, OtherAntTag, DataTypeTag and AntTagScript.
  We should delete those once we've checked that AntTag works properly.
  
  There does appear to be still a problem with references; this checkin is hopefully so that bob can take a once-over and spot any schoolboy errors.
  I think the logic is fine for Tasks though we may need some more work on nested properties/elements and data types.
  We're nealy there now...
  
  Revision  Changes    Path
  1.4       +24 -22    jakarta-commons-sandbox/jelly/src/test/org/apache/commons/jelly/ant/example_tasks.jelly
  
  Index: example_tasks.jelly
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/jelly/src/test/org/apache/commons/jelly/ant/example_tasks.jelly,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- example_tasks.jelly	14 Jun 2002 10:24:14 -0000	1.3
  +++ example_tasks.jelly	27 Jun 2002 14:16:24 -0000	1.4
  @@ -1,22 +1,24 @@
  -<?xml version="1.0"?>
  -<j:jelly xmlns:j="jelly:core" xmlns="jelly:ant">
  -  Lets start by calling the echo task
  -    
  -  <!-- this example attempts to invoke some Ant tasks -->
  -  <echo message="Invoking the echo task from inside Jelly; the Maven repository is ${lib.repo}"/>          
  -
  -  <echo>
  -  	Maven home is ${maven.home}
  -  </echo>
  -
  -  <!-- lets try invoke a program -->
  -  <java classname="org.apache.commons.jelly.Jelly" fork="yes">
  -    <classpath refid="test.classpath"/>
  -    <arg value="src/test/org/apache/commons/jelly/show_args.jelly"/> 
  -    <arg value="one"/> 
  -    <arg value="two"/> 
  -    <arg value="three"/> 
  -  </java>
  -
  -  We should be back to the Jelly script again now...    
  -</j:jelly>
  +<?xml version="1.0"?>
  +<j:jelly xmlns:j="jelly:core" xmlns="jelly:ant">
  +  Lets start by calling the echo task
  +    
  +  <!-- this example attempts to invoke some Ant tasks -->
  +  <echo message="Invoking the echo task from inside Jelly; the Maven repository is ${lib.repo}"/>          
  +
  +  <echo>
  +  	Maven home is ${maven.home}
  +  </echo>
  +
  +  classpath: ${project.getReference('test.classpath')}
  +
  +  <!-- lets try invoke a program -->
  +  <java classname="org.apache.commons.jelly.Jelly" fork="yes">
  +    <classpath refid="test.classpath"/>
  +    <arg value="src/test/org/apache/commons/jelly/show_args.jelly"/> 
  +    <arg value="one"/> 
  +    <arg value="two"/> 
  +    <arg value="three"/> 
  +  </java>
  +
  +  We should be back to the Jelly script again now...    
  +</j:jelly>
  
  
  
  1.7       +1 -0      jakarta-commons-sandbox/jelly/.cvsignore
  
  Index: .cvsignore
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/jelly/.cvsignore,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- .cvsignore	22 Jun 2002 23:55:18 -0000	1.6
  +++ .cvsignore	27 Jun 2002 14:16:24 -0000	1.7
  @@ -6,3 +6,4 @@
   maven.log
   .project
   commons-jelly-1.0-dev-site.tar.gz
  +snapshot.bat
  
  
  
  1.59      +2 -0      jakarta-commons-sandbox/jelly/build.xml
  
  Index: build.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/jelly/build.xml,v
  retrieving revision 1.58
  retrieving revision 1.59
  diff -u -r1.58 -r1.59
  --- build.xml	26 Jun 2002 14:50:43 -0000	1.58
  +++ build.xml	27 Jun 2002 14:16:24 -0000	1.59
  @@ -23,6 +23,8 @@
       <pathelement location="${lib.repo}/xercesImpl-2.0.0.jar"/>
     </path>
   	  
  +	  
  +	  
     <!-- maven:start -->
     
     <!-- ================================================================== -->
  
  
  
  1.16      +9 -2      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.15
  retrieving revision 1.16
  diff -u -r1.15 -r1.16
  --- AntTagLibrary.java	26 Jun 2002 13:09:09 -0000	1.15
  +++ AntTagLibrary.java	27 Jun 2002 14:16:24 -0000	1.16
  @@ -216,6 +216,14 @@
               Tag tag = new FileScannerTag(new FileScanner(project));
               return TagScript.newInstance(tag);
           }
  +
  +        AntTag tag = new AntTag( getProject(), name );
  +        if ( name.equals( "echo" ) ) {
  +            tag.setTrim(false);
  +        }
  +        return TagScript.newInstance(tag);
  +
  +        /*
           
           // is it an Ant task?
           Class type = (Class) project.getTaskDefinitions().get(name);
  @@ -229,7 +237,6 @@
               return new AntTagScript(tag);
           }
           
  -        /*
           // an Ant DataType?
           DataType dataType = null;
           type = (Class) project.getDataTypeDefinitions().get(name);
  @@ -267,7 +274,6 @@
               tag.getDynaBean().set( "project", project );
               return TagScript.newInstance(tag);
           }
  -        */
           
           // Since ant resolves so many dynamically loaded/created
           // things at run-time, we can make virtually no assumptions
  @@ -276,6 +282,7 @@
                                      name );
   
           return new AntTagScript( tag );
  +        */
       }
   
       public TagScript createRuntimeTaskTagScript(String taskName, Attributes attributes) throws Exception {
  
  
  
  1.1                  jakarta-commons-sandbox/jelly/src/java/org/apache/commons/jelly/tags/ant/AntTag.java
  
  Index: AntTag.java
  ===================================================================
  /*
   * $Header: /home/cvs/jakarta-commons-sandbox/jelly/src/java/org/apache/commons/jelly/tags/ant/AntTagSupport.java,v 1.4 2002/06/25 20:43:30 werken Exp $
   * $Revision: 1.4 $
   * $Date: 2002/06/25 20:43:30 $
   *
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-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 "The Jakarta Project", "Commons", 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/>.
   * 
   * $Id: AntTagSupport.java,v 1.4 2002/06/25 20:43:30 werken Exp $
   */
  
  
  package org.apache.commons.jelly.tags.ant;
  
  import java.lang.reflect.Constructor;
  import java.lang.reflect.Method;
  import java.util.Iterator;
  import java.util.Map;
  
  import org.apache.commons.jelly.JellyContext;
  import org.apache.commons.jelly.XMLOutput;
  import org.apache.commons.jelly.MapTagSupport;
  
  import org.apache.commons.beanutils.BeanUtils;
  import org.apache.commons.beanutils.MethodUtils;
  import org.apache.commons.beanutils.PropertyUtils;
  
  import org.apache.commons.logging.Log;
  import org.apache.commons.logging.LogFactory;
  
  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.tools.ant.types.Reference;
  
  /** 
   * Tag supporting ant's Tasks as well as 
   * dynamic runtime behaviour for 'unknown' tags.
   *
   *  @author <a href="mailto:bob@eng.werken.com">bob mcwhirter</a>
   * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
   */
  public class AntTag extends MapTagSupport {
  
      /** The Log to which logging calls will be made. */
      private static final Log log = LogFactory.getLog(AntTag.class);
  
      private static final Class[] addTaskParamTypes = { String.class };
  
      /** The Ant project */
      private Project project;
      
      /** The name of this tag. */
      protected String tagName;
  
      /** The general object underlying this tag. */
      protected Object object;
  
      /** 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 AntTag(Project project, String tagName) {
          this.project = project;
          this.tagName = tagName;
      }
  
      public String toString() {
          return "[AntTag: name=" + getTagName() + "]";
      }
      
  
      // Tag interface
      //------------------------------------------------------------------------- 
      public void doTag(XMLOutput output) throws Exception {
  
          Project project = getAntProject();
          String tagName = getTagName();
  
          if ( project.getTaskDefinitions().containsKey( tagName ) ) {
              
              // the following algorithm follows the lifetime of a tag
              // http://jakarta.apache.org/ant/manual/develop.html#writingowntask
              // kindly recommended by Stefan Bodewig
              
              // create and set its project reference
              task = createTask( tagName );
              if ( task instanceof TaskAdapter ) {
                  setObject( ((TaskAdapter)task).getProxy() );
              } 
              else {
                  setObject( task );
              }
              
              // set the task ID if one is given
              Object id = getAttributes().remove( "id" );
              if ( id != null ) {
                  project.addReference( (String) id, task );
              }
              
              // ### we might want to spoof a Target setting here
              
              // now lets initialize 
              task.init();
  
              // now lets invoke the body to call all the createXXX() or addXXX() methods
              String body = getBodyText();
  
              // now lets set any attributes of this tag...
              setBeanProperties();
              
              // now lets set the addText() of the body content, if its applicaable
              Method method = MethodUtils.getAccessibleMethod( task.getClass(),
                                                               "addText",
                                                               addTaskParamTypes );            
              if (method != null) {
                  String text = getBodyText();
                  
                  Object[] args = { text };
                  method.invoke(this.task, args);
              } 
              
              // now lets set all the attributes of the child elements
              // XXXX: to do!
              
              
              // now we're ready to invoke the task
              // XXX: should we call execute() or perform()?
              task.perform(); 
          } 
          else {
              
              //log.info( "Setting datatype/nested object of name: " + tagName );
              
              // must be a datatype.
              AntTag ancestor = (AntTag) findAncestorWithClass( AntTag.class );
  
              Object nested = null;
              
              if ( ancestor != null ) {
                  nested = ancestor.createNestedObject( tagName );
              }
              
              if ( nested == null ) {
                  nested = createDataType( tagName );
              }
  
              if ( nested != null ) {
                  setObject( nested );
  
                  // set the task ID if one is given
                  Object id = getAttributes().remove( "id" );
                  if ( id != null ) {
                      project.addReference( (String) id, nested );
                  }
              
                  try{
                      PropertyUtils.setProperty( nested, "name", tagName );
                  }
                  catch (Exception e) {
                  }
              } 
  
              // now lets invoke the body 
              String body = getBodyText();
  
              // now lets set any attributes of this tag...
              setBeanProperties();
  
              // now lets add it to its parent
              if ( ancestor != null ) {
                  Object parentObj =  ancestor.getObject();                
                  if ( parentObj != null ) {
                      IntrospectionHelper ih = IntrospectionHelper.getHelper( parentObj.getClass() );                    
                      try {
                          ih.storeElement( project, parentObj, nested, tagName );
                      }
                      catch (Exception e) {
                          //log.warn( "Caught exception setting nested: " + tagName, e );
                      }
                  }
              }
          }
      }
      
  
      // Properties
      //------------------------------------------------------------------------- 
      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;
      }
  
      public void setAntProject(Project project) {
          this.project = project;
      }
  
      public Project getAntProject() {
          return this.project;
      }
  
      // Implementation methods
      //------------------------------------------------------------------------- 
  
      /** 
       * Sets the properties on the Ant task
       */
      public void setBeanProperties() throws Exception {
          Object object = getObject();
          if ( object != null ) {
  		    Map map = getAttributes();
  		    for ( Iterator iter = map.entrySet().iterator(); iter.hasNext(); ) {
  		        Map.Entry entry = (Map.Entry) iter.next();
  		        String name = (String) entry.getKey();
  		        Object value = entry.getValue();
  		        setBeanProperty( object, name, value );
  		    }
          }
      }
      
      public void setBeanProperty(Object object, String name, Object value) throws Exception {
          //log.info( "Setting bean property on: "+  object + " name: " + name + " value: " + value );
          
          IntrospectionHelper ih = IntrospectionHelper.getHelper( object.getClass() );
  
          if ( value instanceof String ) {
              try {
                  ih.setAttribute( getAntProject(), object, name.toLowerCase(), (String) value );
                  return;
              } 
              catch (Exception e) {
                  log.error( "Caught: " + e, e );
              }
          }
  
          try {
              
              ih.storeElement( getAntProject(), object, value, name );
          } 
          catch (Exception e) {
  
              // let any exceptions bubble up from here
              BeanUtils.setProperty( object, name, value );
          }
      }
  
  
      public Object createNestedObject(String name) throws Exception {
          Object dataType = null;
  
          Object object = getObject();
          if ( object != null ) {
              IntrospectionHelper ih = IntrospectionHelper.getHelper( object.getClass() );
              
              if ( ih != null ) {
                  try {
                      dataType = ih.createElement( getAntProject(), object, name );
                  } 
                  catch (Exception e) {
                      log.error(e);
                  }
              }
          }
  
          if ( dataType == null ) {
              dataType = createDataType( name );
          }
  
          return dataType;
      }
  
      public Object createDataType(String name) throws Exception {
          
          Object dataType = null;
  
          Class type = (Class) getAntProject().getDataTypeDefinitions().get(name);
  
          if ( type != null ) {            
              
              try {
                  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)dataType).setProject( project );
                  
              } 
              catch (Throwable t) {
                  // ignore 
                  log.error(t);
              }
          }
  
          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;
      }
  }
  
  

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>