I'm currently attempting to declare functions dynamically in my Rhino JavaScript context. I have gotten to the point where I can declare variables/properties dynamically, but can't figure out how to pass a function as the value for a property. Here's how far I have gotten:
import java.lang.reflect.Member;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.FunctionObject;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.ScriptableObject;
public class Main {
public static void main(String[] args) {
Context jsContext = Context.enter();
try {
Scriptable scope = jsContext.initStandardObjects();
ScriptableObject fooObject = new ScriptableObject() {
@Override
public String getClassName() {
return "MyFoo";
}
};
scope.put("foo", scope, fooObject);
fooObject.putProperty(fooObject, "oneProperty", "This is the value of oneProperty");
Member myFunction = /* What goes here? */ null;
fooObject.putProperty(fooObject, "doStuff", new FunctionObject("doStuff", myFunction, fooObject));
Object resultProp = jsContext.evaluateString(scope, "foo.oneProperty", "<cmd>", 1, null);
Object resultFunc = jsContext.evaluateString(scope, "foo.doStuff()", "<cmd>", 2, null);
System.out.println("Property value: " + Context.toString(resultProp));
System.out.println("Function value: " + Context.toString(resultFunc));
}
finally {
jsContext.exit();
}
}
}
I think I am correctly defining the "foo" object within the global scope and setting the property oneProperty
on it, but I can't figure out how to give that set method a function. Am I doing this correctly? How can I do it for a function?
UPDATE
It looks like one can create a new class that implements the Function
interface, implement the "call" method, and ignore the other methods that are required for that interface (just return null). That can then be given to the putProperty
call. This seems to work, however it's painful to see in code and it is not clear from reading it what it does. I am still looking for a better solution, if one exists.