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