ant-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From peter reilly <peter.rei...@corvil.com>
Subject Re: Extension of <scriptdef>
Date Fri, 10 Oct 2003 08:44:40 GMT
Ok,
I have had a look at beanshell 2.0. It is amazing. It
now understands normal java syntax and creates normal
java classes.

Based on Dawid's idea, I made a small definition task using beanshell
which can be used as follows:

    <typedef name="beanshelldef"
             classname="task.BeanShellDef"
             classpath="classes"/>
    <beanshelldef name="test1" classname="AList">
      import org.apache.tools.ant.Task;
      public class AList extends Task {
         String message = null;
         public void setMessage(String message) {
             this.message = message;
         }
         public void execute() {
            System.out.println("message is " + message);
         }
     }
    </beanshelldef>
    <test1 message="hello world"/>

It can also be used to define conditions etc.
    <beanshelldef name="bool.condition" classname="test.BoolCondition"
                  file="BoolCondition.bsh"/>
    <antcontrib:if>
      <bool.condition>
        <innerclass value="value"/>
        <path path="build.xml"/>
      </bool.condition>
      <then>
        <echo>Condition is true</echo>
      </then>
      <else>
        <echo>Condition is false</echo>
      </else>
    </antcontrib:if>

Where BoolCondition.bsh is:

package test;
import org.apache.tools.ant.taskdefs.condition.Condition;
import org.apache.tools.ant.types.Path;
public class BoolCondition implements Condition {
    static public class InnerClass {
        String value;
        public void setValue(String value) {
            this.value = value;
        }
    }
    String string;
    InnerClass innerClass;
    public void setString(String string) {
        this.string = string;
    }
    public void addInnerClass(InnerClass innerClass) {
        this.innerClass = innerClass;
    }
    public void add(Path path) {
    }
    public boolean eval() {
        if ("true".equals(string)) {
            return true;
        }
        if (innerClass != null) {
            return true;
        }
        return false;
    }
}

BeanShellDef.java:
import java.io.File;

import bsh.EvalError;
import bsh.Interpreter;

import org.apache.tools.ant.AntTypeDefinition;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.ComponentHelper;
import org.apache.tools.ant.ProjectHelper;
import org.apache.tools.ant.taskdefs.AntlibDefinition;

/**
 * Class to define an ant definition using a beanshell script.
 * The beanshell interpreter must be 2.0 or higher.
 * The beanshell script must contain the class specified
 * by the "classname" attribute.
 * <p>
 * Note that if there is anything incorrect with the script
 * the warning message is quite cryptic.
 * </p>
 *
 * @author  Peter Reilly
 * @since   Ant 1.7
 * @see AntlibDefinition
 */
public class BeanShellDef extends AntlibDefinition {

    private String name;
    private String definitionString;
    private File   definitionFile;
    private String classname;
    
    /**
     * Name of the definition
     * @param name the name of the definition
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * Name of the classname that the bean shell
     * definition contains.
     * @param classname the name of the class defined in the beanshell script
     */
    public void setClassname(String classname) {
        this.classname = classname;
    }

    /**
     * Set the definition file.
     * @param definitionFile a file containing beanshell script
     */
    public void setFile(File definitionFile) {
        this.definitionFile = definitionFile;
    }
    
    /**
     * Set the definition string.
     *
     * @param text a bean shell 2.0 string containing the definition
     *             of the classname
     */
    public void addText(String text) {
        this.definitionString = getProject().replaceProperties(text);
    }
    
    /**
     * define the beanshell definition.
     * check the attributes, get the class been defined and
     * set the definition.
     */
    public void execute() {
        if (classname == null) {
            throw new BuildException("Missing attribute classname");
        }
        if (name == null) {
            throw new BuildException("Missing attribute name");
        }
        if (definitionString == null && definitionFile == null) {
            throw new BuildException("Missing beanshell script or file");
        }
        Interpreter i = new Interpreter();  // Construct an interpreter
        if (definitionFile != null) {
            try {
                i.source(definitionFile.getAbsolutePath());
            } catch (Throwable t) {
                throw new BuildException(t);
            }
        }
        try {
            if (definitionString != null) {
                i.eval(definitionString);
            }
            Object o = i.eval("new " + classname + "()");
            Class cl = o.getClass();
            AntTypeDefinition def = new AntTypeDefinition();
            def.setName(ProjectHelper.genComponentName(getURI(), name));
            def.setClassName(classname);
            def.setClass(cl);
            ComponentHelper.getComponentHelper(getProject())
                .addDataTypeDefinition(def);
        } catch (BuildException ex) {
            throw ex;
        } catch (Throwable t) {
            throw new BuildException(t);
        }
    }
}

Peter

On Thursday 09 October 2003 17:38, Dominique Devienne wrote:
> Cool and thanks for the link. I saw it, but it slipped my mind and I didn't
> fully comprehend the possibilities. I also was made recently aware of
> BeanShell 2.0b, and again there I don't grasp the new possibilities.
>
> Please keep me appraise with anything you learn on this front, if you don't
> mind. There's something just outside our reach here that would be
> tremendously powerful. --DD
>
> > -----Original Message-----
> > From: peter reilly [mailto:peter.reilly@corvil.com]
> > Sent: Thursday, October 09, 2003 11:31 AM
> > To: Dominique Devienne
> > Subject: Re: Extension of <scriptdef>
> >
> > No, it is not too easy. One would
> > need to mess around with dynamic proxies.
> >
> > However using BeanShell 2.0 with a mod to Dawid's code it
> > should be very easy.
> >
> > See
> > http://marc.theaimsgroup.com/?l=ant-user&m=105523577505707&w=2
> >
> > Peter
> >
> > On Thursday 09 October 2003 16:48, you wrote:
> > > Hi Peter,
> > >
> > > I haven't looked at <scriptdef> in details, but I'm wondering if it
> >
> > could
> >
> > > be adapted to implement arbitrary interfaces instead of just a task?
> > >
> > > With such a facility, a COBOL filename case changing mapper could be
> > > implemented on the fly (and easily posted to the ML), and have to code
> >
> > in
> >
> > > Java a bunch of tiny classes, and suffer from the overhead associated
> >
> > for
> >
> > > most users (compiling and packaging and declaring it the build file).
> > >
> > > Scripted Mappers, FilterReaders, Selectors, property manipulators,
> >
> > etc...
> >
> > > would simply things tremendously, and give unlimited power to Ant the
> >
> > world
> >
> > > ;-) --DD


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


Mime
View raw message