* Extend ScriptingEngine.invoke() to directly accept JavaScript function objects.
* Make RequestEvaluator.invokeInternal() and RequestEvaluator.invokeDirectFunction() accept Javascript function objects as arguments.
This commit is contained in:
parent
900d16654a
commit
05a978e901
3 changed files with 63 additions and 40 deletions
|
@ -62,9 +62,12 @@ public final class RequestEvaluator implements Runnable {
|
|||
// the object on which to invoke a function, if specified
|
||||
private volatile Object thisObject;
|
||||
|
||||
// the method to be executed
|
||||
// the function to be executed
|
||||
private volatile String functionName;
|
||||
|
||||
// the function or function name to be executed
|
||||
private volatile Object function;
|
||||
|
||||
// the session object associated with the current request
|
||||
private volatile Session session;
|
||||
|
||||
|
@ -165,7 +168,7 @@ public final class RequestEvaluator implements Runnable {
|
|||
// avoid going into transaction if called function doesn't exist.
|
||||
// this only works for the (common) case that method is a plain
|
||||
// method name, not an obj.method path
|
||||
if (reqtype == INTERNAL) {
|
||||
if (reqtype == INTERNAL && functionName != null) {
|
||||
// if object is an instance of NodeHandle, get the node object itself.
|
||||
if (thisObject instanceof NodeHandle) {
|
||||
thisObject = ((NodeHandle) thisObject).getNode(app.nmgr.safe);
|
||||
|
@ -482,12 +485,12 @@ public final class RequestEvaluator implements Runnable {
|
|||
// reset skin recursion detection counter
|
||||
skinDepth = 0;
|
||||
|
||||
if (!scriptingEngine.hasFunction(thisObject, functionName)) {
|
||||
if (functionName != null && !scriptingEngine.hasFunction(thisObject, functionName)) {
|
||||
throw new FrameworkException(missingFunctionMessage(thisObject, functionName));
|
||||
}
|
||||
|
||||
result = scriptingEngine.invoke(thisObject,
|
||||
functionName,
|
||||
function,
|
||||
args,
|
||||
ScriptingEngine.ARGS_WRAP_DEFAULT,
|
||||
true);
|
||||
|
@ -850,14 +853,14 @@ public final class RequestEvaluator implements Runnable {
|
|||
* Invoke a function internally and directly, using the thread we're running on.
|
||||
*
|
||||
* @param obj the object to invoke the function on
|
||||
* @param functionName the name of the function to invoke
|
||||
* @param function the function or name of the function to invoke
|
||||
* @param args the arguments
|
||||
* @return the result returned by the invocation
|
||||
* @throws Exception any exception thrown by the invocation
|
||||
*/
|
||||
public Object invokeDirectFunction(Object obj, String functionName, Object[] args)
|
||||
public Object invokeDirectFunction(Object obj, Object function, Object[] args)
|
||||
throws Exception {
|
||||
return scriptingEngine.invoke(obj, functionName, args,
|
||||
return scriptingEngine.invoke(obj, function, args,
|
||||
ScriptingEngine.ARGS_WRAP_DEFAULT, false);
|
||||
}
|
||||
|
||||
|
@ -866,16 +869,16 @@ public final class RequestEvaluator implements Runnable {
|
|||
* and waits for it to finish.
|
||||
*
|
||||
* @param object the object to invoke the function on
|
||||
* @param functionName the name of the function to invoke
|
||||
* @param function the function or name of the function to invoke
|
||||
* @param args the arguments
|
||||
* @return the result returned by the invocation
|
||||
* @throws Exception any exception thrown by the invocation
|
||||
*/
|
||||
public synchronized Object invokeInternal(Object object, String functionName,
|
||||
public synchronized Object invokeInternal(Object object, Object function,
|
||||
Object[] args)
|
||||
throws Exception {
|
||||
// give internal call more time (15 minutes) to complete
|
||||
return invokeInternal(object, functionName, args, 60000L * 15);
|
||||
return invokeInternal(object, function, args, 60000L * 15);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -883,21 +886,27 @@ public final class RequestEvaluator implements Runnable {
|
|||
* and waits for it to finish.
|
||||
*
|
||||
* @param object the object to invoke the function on
|
||||
* @param functionName the name of the function to invoke
|
||||
* @param function the function or name of the function to invoke
|
||||
* @param args the arguments
|
||||
* @param timeout the time in milliseconds to wait for the function to return
|
||||
* @param timeout the time in milliseconds to wait for the function to return, or
|
||||
* -1 to wait indefinitely
|
||||
* @return the result returned by the invocation
|
||||
* @throws Exception any exception thrown by the invocation
|
||||
*/
|
||||
public synchronized Object invokeInternal(Object object, String functionName,
|
||||
public synchronized Object invokeInternal(Object object, Object function,
|
||||
Object[] args, long timeout)
|
||||
throws Exception {
|
||||
initObjects(functionName, INTERNAL, RequestTrans.INTERNAL);
|
||||
thisObject = object;
|
||||
this.functionName = functionName;
|
||||
if (function instanceof String)
|
||||
this.functionName = (String) function;
|
||||
this.function = function;
|
||||
this.args = args;
|
||||
|
||||
startTransactor();
|
||||
if (timeout < 0)
|
||||
wait();
|
||||
else
|
||||
wait(timeout);
|
||||
|
||||
if (reqtype != NONE && stopTransactor()) {
|
||||
|
@ -997,6 +1006,8 @@ public final class RequestEvaluator implements Runnable {
|
|||
res = null;
|
||||
req = null;
|
||||
session = null;
|
||||
functionName = null;
|
||||
function = null;
|
||||
args = null;
|
||||
result = null;
|
||||
exception = null;
|
||||
|
|
|
@ -85,7 +85,7 @@ public interface ScriptingEngine {
|
|||
*
|
||||
* @param thisObject the object to invoke the function on, or null for
|
||||
* global functions
|
||||
* @param functionName the name of the function to be invoked
|
||||
* @param function the name of the function to be invoked
|
||||
* @param args array of argument objects
|
||||
* @param argsWrapMode indicated the way to process the arguments. Must be
|
||||
* one of <code>ARGS_WRAP_NONE</code>,
|
||||
|
@ -97,7 +97,7 @@ public interface ScriptingEngine {
|
|||
* @throws ScriptingException to indicate something went wrong
|
||||
* with the invocation
|
||||
*/
|
||||
public Object invoke(Object thisObject, String functionName,
|
||||
public Object invoke(Object thisObject, Object function,
|
||||
Object[] args, int argsWrapMode, boolean resolve)
|
||||
throws ScriptingException;
|
||||
|
||||
|
|
|
@ -217,7 +217,7 @@ public class RhinoEngine implements ScriptingEngine {
|
|||
*
|
||||
* @param thisObject the object to invoke the function on, or null for
|
||||
* global functions
|
||||
* @param functionName the name of the function to be invoked
|
||||
* @param function the function or name of the function to be invoked
|
||||
* @param args array of argument objects
|
||||
* @param argsWrapMode indicated the way to process the arguments. Must be
|
||||
* one of <code>ARGS_WRAP_NONE</code>,
|
||||
|
@ -229,15 +229,18 @@ public class RhinoEngine implements ScriptingEngine {
|
|||
* @throws ScriptingException to indicate something went wrong
|
||||
* with the invocation
|
||||
*/
|
||||
public Object invoke(Object thisObject, String functionName, Object[] args,
|
||||
public Object invoke(Object thisObject, Object function, Object[] args,
|
||||
int argsWrapMode, boolean resolve) throws ScriptingException {
|
||||
try {
|
||||
Scriptable obj = thisObject == null ? global : Context.toObject(thisObject, global);
|
||||
Function func;
|
||||
if (function instanceof String) {
|
||||
String funcName = (String) function;
|
||||
// if function name should be resolved interpret it as member expression,
|
||||
// otherwise replace dots with underscores.
|
||||
if (resolve) {
|
||||
if (functionName.indexOf('.') > 0) {
|
||||
StringTokenizer st = new StringTokenizer(functionName, ".");
|
||||
if (funcName.indexOf('.') > 0) {
|
||||
StringTokenizer st = new StringTokenizer(funcName, ".");
|
||||
for (int i=0; i<st.countTokens()-1; i++) {
|
||||
String propName = st.nextToken();
|
||||
Object propValue = ScriptableObject.getProperty(obj, propName);
|
||||
|
@ -245,20 +248,29 @@ public class RhinoEngine implements ScriptingEngine {
|
|||
obj = (Scriptable) propValue;
|
||||
} else {
|
||||
throw new RuntimeException("Can't resolve function name " +
|
||||
functionName + " in " + thisObject);
|
||||
funcName + " in " + thisObject);
|
||||
}
|
||||
}
|
||||
functionName = st.nextToken();
|
||||
funcName = st.nextToken();
|
||||
}
|
||||
} else {
|
||||
functionName = functionName.replace('.', '_');
|
||||
funcName = funcName.replace('.', '_');
|
||||
}
|
||||
Object f = ScriptableObject.getProperty(obj, functionName);
|
||||
Object funcvalue = ScriptableObject.getProperty(obj, funcName);
|
||||
|
||||
if (!(f instanceof Function)) {
|
||||
if (!(funcvalue instanceof Function))
|
||||
return null;
|
||||
func = (Function) funcvalue;
|
||||
|
||||
} else {
|
||||
if (function instanceof Wrapper)
|
||||
function = ((Wrapper) function).unwrap();
|
||||
if (!(function instanceof Function))
|
||||
throw new IllegalArgumentException("Not a function or function name: " + function);
|
||||
func = (Function) function;
|
||||
}
|
||||
|
||||
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
switch (argsWrapMode) {
|
||||
case ARGS_WRAP_DEFAULT:
|
||||
|
@ -275,7 +287,7 @@ public class RhinoEngine implements ScriptingEngine {
|
|||
}
|
||||
|
||||
// use Context.call() in order to set the context's factory
|
||||
Object retval = Context.call(core.contextFactory, (Function) f, global, obj, args);
|
||||
Object retval = Context.call(core.contextFactory, func, global, obj, args);
|
||||
|
||||
if (retval instanceof Wrapper) {
|
||||
retval = ((Wrapper) retval).unwrap();
|
||||
|
|
Loading…
Add table
Reference in a new issue