Invoke Functions with the Invocable Interface
Invocation is a close cousin to compilation. When supported by a script engine, invocation lets you execute the intermediate code of a script's global functions and object member functions. The script would have been previously parsed (using one of ScriptEngine's eval() methods) and its intermediate code stored in the script engine's state.
Script engines that support this invocation feature implement the Invocable interface. Because not every engine will support invocation, it is important to test for this support before casting the engine to an Invocable, as follows:
ScriptEngine engine = … Invocable invocable = null; if (engine instanceof Invocable) invocable = (Invocable) engine;
After casting the engine to an Invocable, you can call Invocable's Object invokeFunction(String name, Object... args) method to invoke a global member function. Pass the function's name as name and the function's arguments as args. This method throws a NoSuchMethodException if it cannot find the function, or ScriptException if there is a problem with the function's invocation, or NullPointerException if name is null.
In a similar manner, you can invoke an object's member functions by calling Invocable's Object invokeMethod(Object thiz, String name, Object... args) method. Argument thiz is a reference to the member function's class: This reference is returned via a previous script evaluation or invocation. Also, name identifies the object member function, and args identifies the function's arguments. In addition to the same exceptions that are thrown by invokeFunction(), invokeMethod() throws IllegalArgumentException if null is passed to thiz or the Object reference passed to thiz does not represent a script object.
Listing 7 uses the invokeFunction() and invokeMethod() methods to create an initialized employee object and then use this object to print the employee name and salary.
Listing 7: ScriptDemo7.java
// ScriptDemo7.java import javax.script.*; public class ScriptDemo7 { public static void main (String [] args) throws Exception { // Create a ScriptEngineManager that discovers all script engine // factories (and their associated script engines) that are visible to // the current thread's classloader. ScriptEngineManager manager = new ScriptEngineManager (); // Obtain a ScriptEngine that supports the JavaScript short name. ScriptEngine engine = manager.getEngineByName ("JavaScript"); // Evaluate a script that defines a global function and an object. String script = "function makeEmployee(name, salary)"+ "{"+ " var obj = new Object();"+ " obj.name = name;"+ " obj.salary = salary;"+ " obj.print = function()"+ " {"+ " println (\"name = \"+obj.name);"+ " println (\"salary = \"+obj.salary);"+ " };"+ " return obj;"+ "}"; engine.eval (script); Invocable invocable = null; if (engine instanceof Invocable) { invocable = (Invocable) engine; // Invoke the makeEmployee() function to make an object. Object emp = invocable.invokeFunction ("makeEmployee", "John Doe", 40000.0); // Print the employee via the object's print() member function. invocable.invokeMethod (emp, "print"); } } }
ScriptDemo7 creates the following output:
name = John Doe salary = 40000