Added support for encoding and decoding XML-RPC parameters.
This commit is contained in:
parent
3c561e4003
commit
7c759d694f
4 changed files with 108 additions and 12 deletions
|
@ -233,7 +233,7 @@ public final class RequestEvaluator implements Runnable {
|
||||||
// try calling onRequest() function on object before
|
// try calling onRequest() function on object before
|
||||||
// calling the actual action
|
// calling the actual action
|
||||||
try {
|
try {
|
||||||
scriptingEngine.invoke (currentElement, "onRequest", new Object[0]);
|
scriptingEngine.invoke (currentElement, "onRequest", new Object[0], false);
|
||||||
} catch (RedirectException redir) {
|
} catch (RedirectException redir) {
|
||||||
throw redir;
|
throw redir;
|
||||||
} catch (Exception ignore) {
|
} catch (Exception ignore) {
|
||||||
|
@ -241,7 +241,7 @@ public final class RequestEvaluator implements Runnable {
|
||||||
}
|
}
|
||||||
|
|
||||||
// do the actual action invocation
|
// do the actual action invocation
|
||||||
scriptingEngine.invoke (currentElement, action, new Object[0]);
|
scriptingEngine.invoke (currentElement, action, new Object[0], false);
|
||||||
|
|
||||||
localrtx.timer.endEvent (txname+" execute");
|
localrtx.timer.endEvent (txname+" execute");
|
||||||
} catch (RedirectException redirect) {
|
} catch (RedirectException redirect) {
|
||||||
|
@ -347,7 +347,7 @@ public final class RequestEvaluator implements Runnable {
|
||||||
String proto = app.getPrototypeName (currentElement);
|
String proto = app.getPrototypeName (currentElement);
|
||||||
app.checkXmlRpcAccess (proto, method);
|
app.checkXmlRpcAccess (proto, method);
|
||||||
|
|
||||||
result = scriptingEngine.invoke (currentElement, method, args);
|
result = scriptingEngine.invoke (currentElement, method, args, true);
|
||||||
commitTransaction ();
|
commitTransaction ();
|
||||||
|
|
||||||
} catch (Exception wrong) {
|
} catch (Exception wrong) {
|
||||||
|
@ -397,7 +397,7 @@ public final class RequestEvaluator implements Runnable {
|
||||||
|
|
||||||
scriptingEngine.enterContext (globals);
|
scriptingEngine.enterContext (globals);
|
||||||
|
|
||||||
result = scriptingEngine.invoke (thisObject, method, args);
|
result = scriptingEngine.invoke (thisObject, method, args, false);
|
||||||
commitTransaction ();
|
commitTransaction ();
|
||||||
|
|
||||||
} catch (Exception wrong) {
|
} catch (Exception wrong) {
|
||||||
|
@ -538,7 +538,7 @@ public final class RequestEvaluator implements Runnable {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object invokeDirectFunction (Object obj, String functionName, Object[] args) throws Exception {
|
public Object invokeDirectFunction (Object obj, String functionName, Object[] args) throws Exception {
|
||||||
return scriptingEngine.invoke (obj, functionName, args);
|
return scriptingEngine.invoke (obj, functionName, args, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized Object invokeFunction (Object object, String functionName, Object[] args)
|
public synchronized Object invokeFunction (Object object, String functionName, Object[] args)
|
||||||
|
|
|
@ -322,7 +322,7 @@ public final class Skin {
|
||||||
int oldLength = reval.res.getBufferLength ();
|
int oldLength = reval.res.getBufferLength ();
|
||||||
if (reval.scriptingEngine.hasFunction (handlerObject, name+"_macro")) {
|
if (reval.scriptingEngine.hasFunction (handlerObject, name+"_macro")) {
|
||||||
// System.err.println ("Getting macro from function");
|
// System.err.println ("Getting macro from function");
|
||||||
v = reval.scriptingEngine.invoke (handlerObject, name+"_macro", arguments);
|
v = reval.scriptingEngine.invoke (handlerObject, name+"_macro", arguments, false);
|
||||||
} else {
|
} else {
|
||||||
// System.err.println ("Getting macro from property");
|
// System.err.println ("Getting macro from property");
|
||||||
v = reval.scriptingEngine.get (handlerObject, name);
|
v = reval.scriptingEngine.get (handlerObject, name);
|
||||||
|
@ -353,7 +353,7 @@ public final class Skin {
|
||||||
throw timeout;
|
throw timeout;
|
||||||
} catch (Exception x) {
|
} catch (Exception x) {
|
||||||
x.printStackTrace();
|
x.printStackTrace();
|
||||||
String msg = "[HopMacro error: "+x+"]";
|
String msg = "[HopMacro error in "+this+": "+x+"]";
|
||||||
reval.res.write (" "+msg+" ");
|
reval.res.write (" "+msg+" ");
|
||||||
app.logEvent (msg);
|
app.logEvent (msg);
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,9 +37,10 @@ public interface ScriptingEngine {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invoke a function on some object, using the given arguments and global vars.
|
* Invoke a function on some object, using the given arguments and global vars.
|
||||||
|
* XML-RPC calls require special input and output parameter conversion.
|
||||||
*/
|
*/
|
||||||
public Object invoke (Object thisObject, String functionName, Object[] args)
|
public Object invoke (Object thisObject, String functionName, Object[] args, boolean xmlrpc)
|
||||||
throws ScriptingException;
|
throws ScriptingException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -373,7 +373,7 @@ public final class FesiEvaluator implements ScriptingEngine {
|
||||||
/**
|
/**
|
||||||
* Invoke a function on some object, using the given arguments and global vars.
|
* Invoke a function on some object, using the given arguments and global vars.
|
||||||
*/
|
*/
|
||||||
public Object invoke (Object thisObject, String functionName, Object[] args) throws ScriptingException {
|
public Object invoke (Object thisObject, String functionName, Object[] args, boolean xmlrpc) throws ScriptingException {
|
||||||
ESObject eso = null;
|
ESObject eso = null;
|
||||||
if (thisObject == null)
|
if (thisObject == null)
|
||||||
eso = global;
|
eso = global;
|
||||||
|
@ -382,15 +382,23 @@ public final class FesiEvaluator implements ScriptingEngine {
|
||||||
try {
|
try {
|
||||||
ESValue[] esv = args == null ? new ESValue[0] : new ESValue[args.length];
|
ESValue[] esv = args == null ? new ESValue[0] : new ESValue[args.length];
|
||||||
for (int i=0; i<esv.length; i++) {
|
for (int i=0; i<esv.length; i++) {
|
||||||
|
// XML-RPC requires special argument conversion
|
||||||
|
if (xmlrpc)
|
||||||
|
esv[i] = processXmlRpcArgument (args[i]);
|
||||||
// for java.util.Map objects, we use the special "tight" wrapper
|
// for java.util.Map objects, we use the special "tight" wrapper
|
||||||
// that makes the Map look like a native object
|
// that makes the Map look like a native object
|
||||||
if (args[i] instanceof Map)
|
else if (args[i] instanceof Map)
|
||||||
esv[i] = new ESMapWrapper (this, (Map) args[i]);
|
esv[i] = new ESMapWrapper (this, (Map) args[i]);
|
||||||
else
|
else
|
||||||
esv[i] = ESLoader.normalizeValue (args[i], evaluator);
|
esv[i] = ESLoader.normalizeValue (args[i], evaluator);
|
||||||
}
|
}
|
||||||
ESValue retval = eso.doIndirectCall (evaluator, eso, functionName, esv);
|
ESValue retval = eso.doIndirectCall (evaluator, eso, functionName, esv);
|
||||||
return retval == null ? null : retval.toJavaObject ();
|
if (xmlrpc)
|
||||||
|
return processXmlRpcResponse (retval);
|
||||||
|
else if (retval == null)
|
||||||
|
return null;
|
||||||
|
else
|
||||||
|
return retval.toJavaObject ();
|
||||||
} catch (Exception x) {
|
} catch (Exception x) {
|
||||||
// check if this is a redirect exception, which has been converted by fesi
|
// check if this is a redirect exception, which has been converted by fesi
|
||||||
// into an EcmaScript exception, which is why we can't explicitly catch it
|
// into an EcmaScript exception, which is why we can't explicitly catch it
|
||||||
|
@ -485,6 +493,93 @@ public final class FesiEvaluator implements ScriptingEngine {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert an input argument from Java to the scripting runtime
|
||||||
|
* representation.
|
||||||
|
*/
|
||||||
|
private ESValue processXmlRpcArgument (Object what) throws Exception {
|
||||||
|
if (what == null)
|
||||||
|
return ESNull.theNull;
|
||||||
|
if (what instanceof Vector) {
|
||||||
|
Vector v = (Vector) what;
|
||||||
|
ArrayPrototype retval = new ArrayPrototype (evaluator.getArrayPrototype (), evaluator);
|
||||||
|
int l = v.size ();
|
||||||
|
for (int i=0; i<l; i++)
|
||||||
|
retval.putProperty (i, processXmlRpcArgument (v.elementAt (i)));
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
if (what instanceof Hashtable) {
|
||||||
|
Hashtable t = (Hashtable) what;
|
||||||
|
ESObject retval = new ObjectPrototype (evaluator.getObjectPrototype (), evaluator);
|
||||||
|
for (Enumeration e=t.keys(); e.hasMoreElements(); ) {
|
||||||
|
String next = (String) e.nextElement ();
|
||||||
|
retval.putProperty (next, processXmlRpcArgument (t.get (next)), next.hashCode ());
|
||||||
|
}
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
if (what instanceof String)
|
||||||
|
return new ESString (what.toString ());
|
||||||
|
if (what instanceof Number)
|
||||||
|
return new ESNumber (new Double (what.toString ()).doubleValue ());
|
||||||
|
if (what instanceof Boolean)
|
||||||
|
return ESBoolean.makeBoolean (((Boolean) what).booleanValue ());
|
||||||
|
if (what instanceof Date)
|
||||||
|
return new DatePrototype (evaluator, (Date) what);
|
||||||
|
return ESLoader.normalizeValue (what, evaluator);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* convert a JavaScript Object object to a generic Java object stucture.
|
||||||
|
*/
|
||||||
|
public Object processXmlRpcResponse (ESValue what) throws EcmaScriptException {
|
||||||
|
if (what == null || what instanceof ESNull)
|
||||||
|
return null;
|
||||||
|
if (what instanceof ArrayPrototype) {
|
||||||
|
ArrayPrototype a = (ArrayPrototype) what;
|
||||||
|
int l = a.size ();
|
||||||
|
Vector v = new Vector ();
|
||||||
|
for (int i=0; i<l; i++) {
|
||||||
|
Object nj = processXmlRpcResponse (a.getProperty (i));
|
||||||
|
v.addElement (nj);
|
||||||
|
}
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
if (what instanceof ObjectPrototype) {
|
||||||
|
ObjectPrototype o = (ObjectPrototype) what;
|
||||||
|
Hashtable t = new Hashtable ();
|
||||||
|
for (Enumeration e=o.getProperties (); e.hasMoreElements (); ) {
|
||||||
|
String next = (String) e.nextElement ();
|
||||||
|
// We don't do deep serialization of HopObjects to avoid
|
||||||
|
// that the whole web site structure is sucked out with one
|
||||||
|
// object. Instead we return some kind of "proxy" objects
|
||||||
|
// that only contain the prototype and id of the HopObject property.
|
||||||
|
Object nj = null;
|
||||||
|
ESValue esv = o.getProperty (next, next.hashCode ());
|
||||||
|
if (esv instanceof ESNode) {
|
||||||
|
INode node = ((ESNode) esv).getNode ();
|
||||||
|
if (node != null) {
|
||||||
|
Hashtable nt = new Hashtable ();
|
||||||
|
nt.put ("id", node.getID());
|
||||||
|
if (node.getPrototype() != null)
|
||||||
|
nt.put ("prototype", node.getPrototype ());
|
||||||
|
nj = nt;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
nj = processXmlRpcResponse (esv);
|
||||||
|
if (nj != null) // can't put null as value in hashtable
|
||||||
|
t.put (next, nj);
|
||||||
|
}
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
if (what instanceof ESUndefined || what instanceof ESNull)
|
||||||
|
return null;
|
||||||
|
Object jval = what.toJavaObject ();
|
||||||
|
if (jval instanceof Byte || jval instanceof Short)
|
||||||
|
jval = new Integer (jval.toString ());
|
||||||
|
return jval;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the FESI Evaluator object wrapped by this object.
|
* Return the FESI Evaluator object wrapped by this object.
|
||||||
|
|
Loading…
Add table
Reference in a new issue