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
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]