// ...
public Object run(String script) {
return rhinoContext.evaluateString(sharedJsScope, script, "A label here", 1, null);
}
public Object invokeFn(Scriptable o, String fn, Object... args) {
Function function = (Function) ScriptableObject.getProperty(o, fn);
return function.call(this.rhinoContext, this.sharedJsScope, o, args);
}
public Date jsToDate(Object o) {
return (Date) this.rhinoContext.jsToJava(o, Date.class);
}
// ...
// Create a reference to the car object with all its protoypes and state
// Note that by assigning it to an object (without "var") it's returning the object
// as a scriptable, otherwise it would return undefined.
Scriptable car = (Scriptable) jsEngine.run("car = new Car()", "");
// Invoke an instance method on car
double numDoors = (double) jsEngine.invokeFn(car, "getDoors");
// Get a property on the car
Date created = jsEngine.jsToDate(car.get("created", car));
System.out.println("Number of doors: " + numDoors);
System.out.println("Car was created: " + created);
function Car() {
this.created = new Date();
}
Car.prototype.getDoors = function() {
return 4;
}
@joelso big thanks!
Now I see where problem is in our code.
From beginning I was not thinking about need to save states and get direct access to js objects, but instead made everything JSON-based and stateless. We have Java native JSON-based representations of js models,
When running script, we have logics like:
The last
returnkills all referencing, and we have just String representation (type JSON) for the object we got from javascript.And I had methods like:
I continue digging into code, how to make it support real classes, and vital question for me if
ScriptableorScriptableObjectsupport serialisation somehow. As when we implement "Flow", we need to transfer ourScriptableobject from one flow view to another, as it should bemutableon any step (e.g. when user wants to change any property on it or invoke any method).