RhinoTask

ネタがないので、なんとなく。
Java側でのJavaScriptの関数の定義はいい加減。


<?xml version="1.0" ?>
<project name="sql" default="all" basedir=".">

<taskdef name="rhino" classname="foo.RhinoTask">
<classpath path="${basedir}/bin;${basedir}/lib/js.jar" />
</taskdef>

<property name="foo" value="foofoo" />
<property name="bar" value="barbar" />

<target name="all">
<rhino>
print(foo);
print(bar);
property('hoge', 'hogehoge');
</rhino>
<echo message="${hoge}" />
</target>
</project>


package foo;

import java.util.Iterator;
import java.util.Map;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.Task;
import org.mozilla.javascript.BaseFunction;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.Function;
import org.mozilla.javascript.Script;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.ScriptableObject;
import org.mozilla.javascript.tools.shell.Global;
import org.mozilla.javascript.tools.shell.ShellContextFactory;

public class RhinoTask extends Task {

private String src = null;

public void addText(String source) {
this.src = source;
}

public void execute() throws BuildException {
Context cx = Context.enter();

try {
run(cx);
} finally {
Context.exit();
}
}

private void run(Context cx) {
Script script = cx.compileString(src, "", 1, null);
Global global = new Global();
ShellContextFactory factory = new ShellContextFactory();
global.init(factory);
final Project project = getProject();
Map props = project.getProperties();

for (Iterator ite = props.keySet().iterator(); ite.hasNext();) {
String name = (String) ite.next();
Object value = props.get(name);
putProperty(name, value, global);
}

putFunction("property", global, new BaseFunction() {
public Object call(Context cx, Scriptable scope, Scriptable thisObj, java.lang.Object[] args) {
String name = (String) args[0];
String value = (String) args[1];
project.setProperty(name, value);
return Context.getUndefinedValue();
}
});

Object result = script.exec(cx, global);

if (result != Context.getUndefinedValue())
System.err.println(Context.toString(result));
}

private void putProperty(String name, Object obj, Scriptable scope) {
Object jsObj = Context.javaToJS(obj, scope);
ScriptableObject.putProperty(scope, name, jsObj);
}

private void putFunction(String name, Scriptable scope, Function function) {
ScriptableObject.putProperty(scope, name, function);
}

}