diff --git a/src/helma/framework/core/RequestEvaluator.java b/src/helma/framework/core/RequestEvaluator.java
index af2a3014..09795ec5 100644
--- a/src/helma/framework/core/RequestEvaluator.java
+++ b/src/helma/framework/core/RequestEvaluator.java
@@ -330,8 +330,6 @@ public final class RequestEvaluator implements Runnable {
// set the req.action property, cutting off the _action suffix
req.setAction(action);
- // make sure we have a valid function name by replacing dots with underscores
- action = action.replace('.', '_');
// reset skin recursion detection counter
skinDepth = 0;
@@ -344,7 +342,8 @@ public final class RequestEvaluator implements Runnable {
scriptingEngine.invoke(currentElement,
"onRequest",
new Object[0],
- ScriptingEngine.ARGS_WRAP_DEFAULT);
+ ScriptingEngine.ARGS_WRAP_DEFAULT,
+ false);
}
} catch (RedirectException redir) {
throw redir;
@@ -360,13 +359,18 @@ public final class RequestEvaluator implements Runnable {
.getInputStream());
Vector args = xreq.getParameters();
args.add(0, xreq.getMethodName());
- result = scriptingEngine.invoke(currentElement, action,
- args.toArray(), ScriptingEngine.ARGS_WRAP_XMLRPC);
+ result = scriptingEngine.invoke(currentElement,
+ action,
+ args.toArray(),
+ ScriptingEngine.ARGS_WRAP_XMLRPC,
+ false);
res.writeXmlRpcResponse(result);
} else {
- scriptingEngine.invoke(currentElement, action,
- new Object[0],
- ScriptingEngine.ARGS_WRAP_DEFAULT);
+ scriptingEngine.invoke(currentElement,
+ action,
+ new Object[0],
+ ScriptingEngine.ARGS_WRAP_DEFAULT,
+ false);
}
} catch (RedirectException redirect) {
// if there is a message set, save it on the user object for the next request
@@ -420,8 +424,10 @@ public final class RequestEvaluator implements Runnable {
// reset skin recursion detection counter
skinDepth = 0;
- result = scriptingEngine.invoke(currentElement, functionName, args,
- ScriptingEngine.ARGS_WRAP_XMLRPC);
+ result = scriptingEngine.invoke(currentElement,
+ functionName, args,
+ ScriptingEngine.ARGS_WRAP_XMLRPC,
+ false);
commitTransaction();
} catch (Exception x) {
abortTransaction();
@@ -475,8 +481,11 @@ public final class RequestEvaluator implements Runnable {
// reset skin recursion detection counter
skinDepth = 0;
- result = scriptingEngine.invoke(thisObject, functionName, args,
- ScriptingEngine.ARGS_WRAP_DEFAULT);
+ result = scriptingEngine.invoke(thisObject,
+ functionName,
+ args,
+ ScriptingEngine.ARGS_WRAP_DEFAULT,
+ true);
commitTransaction();
} catch (Exception x) {
abortTransaction();
@@ -836,7 +845,8 @@ public final class RequestEvaluator implements Runnable {
*/
public Object invokeDirectFunction(Object obj, String functionName, Object[] args)
throws Exception {
- return scriptingEngine.invoke(obj, functionName, args, ScriptingEngine.ARGS_WRAP_DEFAULT);
+ return scriptingEngine.invoke(obj, functionName, args,
+ ScriptingEngine.ARGS_WRAP_DEFAULT, false);
}
/**
@@ -961,7 +971,7 @@ 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},
- ScriptingEngine.ARGS_WRAP_DEFAULT);
+ ScriptingEngine.ARGS_WRAP_DEFAULT, false);
}
if (obj instanceof IPathElement) {
diff --git a/src/helma/scripting/ScriptingEngine.java b/src/helma/scripting/ScriptingEngine.java
index a1503f84..39c2a644 100644
--- a/src/helma/scripting/ScriptingEngine.java
+++ b/src/helma/scripting/ScriptingEngine.java
@@ -88,12 +88,14 @@ public interface ScriptingEngine {
* one of ARGS_WRAP_NONE
,
* ARGS_WRAP_DEFAULT
,
* ARGS_WRAP_XMLRPC
+ * @param resolve indicates whether functionName may contain an object path
+ * or just the plain function name
* @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, int argsWrapMode)
+ Object[] args, int argsWrapMode, boolean resolve)
throws ScriptingException;
diff --git a/src/helma/scripting/rhino/HopObject.java b/src/helma/scripting/rhino/HopObject.java
index a75987de..bacb2f16 100644
--- a/src/helma/scripting/rhino/HopObject.java
+++ b/src/helma/scripting/rhino/HopObject.java
@@ -147,7 +147,10 @@ public class HopObject extends ScriptableObject implements Wrapper, PropertyReco
hobj.init(core, node);
if (proto != null) {
- engine.invoke(hobj, "__constructor__", args, ScriptingEngine.ARGS_WRAP_NONE);
+ engine.invoke(hobj,
+ "__constructor__",
+ args, ScriptingEngine.ARGS_WRAP_NONE,
+ false);
}
return hobj;
diff --git a/src/helma/scripting/rhino/PhantomEngine.java b/src/helma/scripting/rhino/PhantomEngine.java
index 070798d3..8127e310 100644
--- a/src/helma/scripting/rhino/PhantomEngine.java
+++ b/src/helma/scripting/rhino/PhantomEngine.java
@@ -28,11 +28,27 @@ import helma.scripting.ScriptingException;
* @see helma.main.launcher.FilteredClassLoader
*/
public final class PhantomEngine extends RhinoEngine {
+
/**
+ * 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
+ * @param resolve indicates whether functionName may contain an object path
+ * or just the plain function name
+ * @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,
- int argsWrapMode) throws ScriptingException {
- return super.invoke(thisObject, functionName, args, argsWrapMode);
+ int argsWrapMode, boolean resolve) throws ScriptingException {
+ return super.invoke(thisObject, functionName, args, argsWrapMode, resolve);
}
}
diff --git a/src/helma/scripting/rhino/RhinoCore.java b/src/helma/scripting/rhino/RhinoCore.java
index 72b62153..be864b46 100644
--- a/src/helma/scripting/rhino/RhinoCore.java
+++ b/src/helma/scripting/rhino/RhinoCore.java
@@ -678,7 +678,8 @@ public final class RhinoCore implements ScopeProvider {
try {
result = engine.invoke(handler, hrefFunction,
new Object[] { basicHref },
- ScriptingEngine.ARGS_WRAP_DEFAULT);
+ ScriptingEngine.ARGS_WRAP_DEFAULT,
+ false);
} 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 e1d4d8ff..00316fc6 100644
--- a/src/helma/scripting/rhino/RhinoEngine.java
+++ b/src/helma/scripting/rhino/RhinoEngine.java
@@ -255,16 +255,24 @@ public class RhinoEngine implements 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
+ * @param resolve indicates whether functionName may contain an object path
+ * or just the plain function name
+ * @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,
- int argsWrapMode) throws ScriptingException {
- Scriptable eso = null;
-
- if (thisObject == null) {
- eso = global;
- } else {
- eso = Context.toObject(thisObject, global);
- }
+ int argsWrapMode, boolean resolve) throws ScriptingException {
try {
for (int i = 0; i < args.length; i++) {
switch (argsWrapMode) {
@@ -279,15 +287,37 @@ public class RhinoEngine implements ScriptingEngine {
args[i] = core.processXmlRpcArgument(args[i]);
break;
}
- }
- Object f = ScriptableObject.getProperty(eso, functionName.replace('.', '_'));
+ }
+ 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