Re: Extension of <scriptdef>

peter reilly <[email protected]>
Newsgroups gmane.comp.java.beanshell.devel,gmane.text.xml.cocoon.devel
Organization corvil
Message-ID <200310100944.40197.peter.reilly__7599.02069480649$1065775533@corvil.com>
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:[email protected]]
> > 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



-------------------------------------------------------
This SF.net email is sponsored by: SF.net Giveback Program.
SourceForge.net hosts over 70,000 Open Source Projects.
See the people who have HELPED US provide better services:
Click here: http://sourceforge.net/supporters.php
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.