From 05a978e901d503ea9b854ce9caa50ae4d2a782d4 Mon Sep 17 00:00:00 2001 From: hns Date: Wed, 28 Mar 2007 14:32:46 +0000 Subject: [PATCH] * Extend ScriptingEngine.invoke() to directly accept JavaScript function objects. * Make RequestEvaluator.invokeInternal() and RequestEvaluator.invokeDirectFunction() accept Javascript function objects as arguments. --- .../framework/core/RequestEvaluator.java | 41 ++++++++----- src/helma/scripting/ScriptingEngine.java | 4 +- src/helma/scripting/rhino/RhinoEngine.java | 58 +++++++++++-------- 3 files changed, 63 insertions(+), 40 deletions(-) diff --git a/src/helma/framework/core/RequestEvaluator.java b/src/helma/framework/core/RequestEvaluator.java index 8d872e98..ebe72deb 100644 --- a/src/helma/framework/core/RequestEvaluator.java +++ b/src/helma/framework/core/RequestEvaluator.java @@ -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,22 +886,28 @@ 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(); - wait(timeout); + if (timeout < 0) + wait(); + else + wait(timeout); if (reqtype != NONE && stopTransactor()) { exception = new RuntimeException("Request timed out"); @@ -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; diff --git a/src/helma/scripting/ScriptingEngine.java b/src/helma/scripting/ScriptingEngine.java index 46cd5e98..6eb56e88 100644 --- a/src/helma/scripting/ScriptingEngine.java +++ b/src/helma/scripting/ScriptingEngine.java @@ -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 ARGS_WRAP_NONE, @@ -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; diff --git a/src/helma/scripting/rhino/RhinoEngine.java b/src/helma/scripting/rhino/RhinoEngine.java index e9ba5eab..f59843c2 100644 --- a/src/helma/scripting/rhino/RhinoEngine.java +++ b/src/helma/scripting/rhino/RhinoEngine.java @@ -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 ARGS_WRAP_NONE, @@ -229,36 +229,48 @@ 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); - // 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, "."); - for (int i=0; i 0) { + StringTokenizer st = new StringTokenizer(funcName, "."); + for (int i=0; i