diff --git a/src/helma/framework/core/RequestEvaluator.java b/src/helma/framework/core/RequestEvaluator.java
index 5524f5d5..296a9d2c 100644
--- a/src/helma/framework/core/RequestEvaluator.java
+++ b/src/helma/framework/core/RequestEvaluator.java
@@ -329,7 +329,8 @@ public final class RequestEvaluator implements Runnable {
"onRequest")) {
scriptingEngine.invoke(currentElement,
"onRequest",
- new Object[0], false);
+ new Object[0],
+ ScriptingEngine.ARGS_WRAP_DEFAULT);
}
} catch (RedirectException redir) {
throw redir;
@@ -340,7 +341,8 @@ public final class RequestEvaluator implements Runnable {
// do the actual action invocation
scriptingEngine.invoke(currentElement, action,
- new Object[0], false);
+ new Object[0],
+ ScriptingEngine.ARGS_WRAP_DEFAULT);
} catch (RedirectException redirect) {
// res.redirect = redirect.getMessage ();
// if there is a message set, save it on the user object for the next request
@@ -482,7 +484,7 @@ public final class RequestEvaluator implements Runnable {
skinDepth = 0;
result = scriptingEngine.invoke(currentElement, method, args,
- true);
+ ScriptingEngine.ARGS_WRAP_XMLRPC);
commitTransaction();
} catch (Exception x) {
abortTransaction(false);
@@ -549,7 +551,7 @@ public final class RequestEvaluator implements Runnable {
skinDepth = 0;
result = scriptingEngine.invoke(thisObject, method, args,
- false);
+ ScriptingEngine.ARGS_WRAP_DEFAULT);
commitTransaction();
} catch (Exception x) {
abortTransaction(false);
@@ -785,7 +787,7 @@ public final class RequestEvaluator implements Runnable {
*/
public Object invokeDirectFunction(Object obj, String functionName, Object[] args)
throws Exception {
- return scriptingEngine.invoke(obj, functionName, args, false);
+ return scriptingEngine.invoke(obj, functionName, args, ScriptingEngine.ARGS_WRAP_DEFAULT);
}
/**
@@ -850,7 +852,8 @@ public final class RequestEvaluator implements Runnable {
private Object getChildElement(Object obj, String name) throws ScriptingException {
if (scriptingEngine.hasFunction(obj, "getChildElement")) {
- return scriptingEngine.invoke(obj, "getChildElement", new Object[] {name}, false);
+ return scriptingEngine.invoke(obj, "getChildElement", new Object[] {name},
+ ScriptingEngine.ARGS_WRAP_DEFAULT);
}
if (obj instanceof IPathElement) {
diff --git a/src/helma/scripting/ScriptingEngine.java b/src/helma/scripting/ScriptingEngine.java
index 0c325221..3e6de704 100644
--- a/src/helma/scripting/ScriptingEngine.java
+++ b/src/helma/scripting/ScriptingEngine.java
@@ -29,6 +29,25 @@ import java.util.*;
* to be usable by the Helma framework.
*/
public interface ScriptingEngine {
+
+ /**
+ * Argument wrapping mode that indicates arguments are wrapped already
+ * and should be passed along unchanged.
+ */
+ public final int ARGS_WRAP_NONE = 0;
+
+ /**
+ * Argument wrapping mode that indicates arguments may be arbitrary
+ * Java objects that may need to be wrapped.
+ */
+ public final int ARGS_WRAP_DEFAULT = 1;
+
+ /**
+ * Argument wrapping mode that indicates this is an XML-RPC call and
+ * arguments should be processed accordingly.
+ */
+ public final int ARGS_WRAP_XMLRPC = 2;
+
/**
* Init the scripting engine with an application and a request evaluator
*/
@@ -57,9 +76,23 @@ public interface ScriptingEngine {
/**
* Invoke a function on some object, using the given arguments and global vars.
* XML-RPC calls require special input and output parameter conversion.
+ *
+ * @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 args array of argument objects
+ * @param argsWrapMode indicated the way to process the arguments. Must be
+ * one of ARGS_WRAP_NONE
,
+ * ARGS_WRAP_DEFAULT
,
+ * ARGS_WRAP_XMLRPC
+ * @return the return value of the function
+ * @throws ScriptingException to indicate something went wrong
+ * with the invocation
*/
- public Object invoke(Object thisObject, String functionName, Object[] args,
- boolean xmlrpc) throws ScriptingException;
+ public Object invoke(Object thisObject, String functionName,
+ Object[] args, int argsWrapMode)
+ throws ScriptingException;
+
/**
* Let the evaluator know that the current evaluation has been aborted.
diff --git a/src/helma/scripting/rhino/HopObject.java b/src/helma/scripting/rhino/HopObject.java
index 9d99ffde..c09e9191 100644
--- a/src/helma/scripting/rhino/HopObject.java
+++ b/src/helma/scripting/rhino/HopObject.java
@@ -17,6 +17,7 @@
package helma.scripting.rhino;
import helma.scripting.ScriptingException;
+import helma.scripting.ScriptingEngine;
import helma.framework.core.*;
import helma.objectmodel.*;
import helma.objectmodel.db.*;
@@ -144,7 +145,7 @@ public class HopObject extends ScriptableObject implements Wrapper {
hobj.init(core, node);
if (proto != null) {
- engine.invoke(hobj, "constructor", args, false);
+ engine.invoke(hobj, "constructor", args, ScriptingEngine.ARGS_WRAP_NONE);
}
return hobj;
diff --git a/src/helma/scripting/rhino/PhantomEngine.java b/src/helma/scripting/rhino/PhantomEngine.java
index 7a7fea44..070798d3 100644
--- a/src/helma/scripting/rhino/PhantomEngine.java
+++ b/src/helma/scripting/rhino/PhantomEngine.java
@@ -32,7 +32,7 @@ public final class PhantomEngine extends RhinoEngine {
*
*/
public Object invoke(Object thisObject, String functionName, Object[] args,
- boolean xmlrpc) throws ScriptingException {
- return super.invoke(thisObject, functionName, args, xmlrpc);
+ int argsWrapMode) throws ScriptingException {
+ return super.invoke(thisObject, functionName, args, argsWrapMode);
}
}
diff --git a/src/helma/scripting/rhino/RhinoCore.java b/src/helma/scripting/rhino/RhinoCore.java
index 4ee33b3e..9397a15e 100644
--- a/src/helma/scripting/rhino/RhinoCore.java
+++ b/src/helma/scripting/rhino/RhinoCore.java
@@ -670,7 +670,8 @@ public final class RhinoCore {
try {
result = engine.invoke(handler, hrefFunction,
- new Object[] { basicHref }, false);
+ new Object[] { basicHref },
+ ScriptingEngine.ARGS_WRAP_DEFAULT);
} catch (ScriptingException x) {
throw new EvaluatorException("Error in hrefFunction: " + x);
}
diff --git a/src/helma/scripting/rhino/RhinoEngine.java b/src/helma/scripting/rhino/RhinoEngine.java
index 4be7060f..9b6260d6 100644
--- a/src/helma/scripting/rhino/RhinoEngine.java
+++ b/src/helma/scripting/rhino/RhinoEngine.java
@@ -236,7 +236,7 @@ public class RhinoEngine implements ScriptingEngine {
* Invoke a function on some object, using the given arguments and global vars.
*/
public Object invoke(Object thisObject, String functionName, Object[] args,
- boolean xmlrpc) throws ScriptingException {
+ int argsWrapMode) throws ScriptingException {
Scriptable eso = null;
if (thisObject == null) {
@@ -246,11 +246,19 @@ public class RhinoEngine implements ScriptingEngine {
}
try {
for (int i = 0; i < args.length; i++) {
- // XML-RPC requires special argument conversion
- if (xmlrpc) {
- args[i] = core.processXmlRpcArgument (args[i]);
- } else if (args[i] != null) {
- args[i] = Context.toObject(args[i], global);
+ switch (argsWrapMode) {
+ case ARGS_WRAP_DEFAULT:
+ // wrap vanilla java objects unless they represent primitives
+ if (args[i] != null && !(args[i] instanceof String)
+ && !(args[i] instanceof Double
+ && !(args[i] instanceof Boolean))) {
+ args[i] = Context.toObject(args[i], global);
+ }
+ break;
+ case ARGS_WRAP_XMLRPC:
+ // XML-RPC requires special argument conversion
+ args[i] = core.processXmlRpcArgument(args[i]);
+ break;
}
}
@@ -268,7 +276,7 @@ public class RhinoEngine implements ScriptingEngine {
if ((retval == null) || (retval == Undefined.instance)) {
return null;
- } else if (xmlrpc) {
+ } else if (argsWrapMode == ARGS_WRAP_XMLRPC) {
return core.processXmlRpcResponse (retval);
} else {
return retval;
@@ -392,7 +400,7 @@ public class RhinoEngine implements ScriptingEngine {
try {
Object prop = so.get(propname, so);
- if ((prop == null) || (prop == Undefined.instance)
+ if ((prop == null) || (prop == Undefined.instance)
|| (prop == ScriptableObject.NOT_FOUND)) {
return null;
} else if (prop instanceof Wrapper) {