Added Remote (XML-RPC client) object.

Fixes in XML-RPC argument encoding.
This commit is contained in:
hns 2003-06-18 16:11:02 +00:00
parent a758a479d7
commit 2f5c368124
3 changed files with 168 additions and 4 deletions

View file

@ -84,6 +84,7 @@ public final class RhinoCore {
ScriptableObject.defineClass(global, FileObject.class);
ScriptableObject.defineClass(global, FtpObject.class);
ImageObject.init(global);
XmlRpcObject.init(global);
MailObject.init(global, app.getProperties());
putPrototype("hopobject",
ScriptableObject.getClassPrototype(global, "HopObject"));
@ -378,15 +379,23 @@ public final class RhinoCore {
* representation.
*/
public Object processXmlRpcArgument (Object what, Context cx) throws Exception {
public Object processXmlRpcArgument (Object what) throws Exception {
if (what == null)
return null;
if (what instanceof Vector) {
Vector v = (Vector) what;
return Context.toObject(v.toArray(), global);
Object[] a = v.toArray();
for (int i=0; i<a.length; i++) {
a[i] = processXmlRpcArgument(a[i]);
}
return Context.toObject(a, global);
}
if (what instanceof Hashtable) {
Hashtable t = (Hashtable) what;
for (Enumeration e=t.keys(); e.hasMoreElements(); ) {
Object key = e.nextElement();
t.put(key, processXmlRpcArgument(t.get(key)));
}
return Context.toObject(new SystemMap(t), global);
}
if (what instanceof String)
@ -398,7 +407,7 @@ public final class RhinoCore {
if (what instanceof Date) {
Date d = (Date) what;
Object[] args = { new Long(d.getTime()) };
return cx.newObject(global, "Date", args);
return Context.getCurrentContext().newObject(global, "Date", args);
}
return Context.toObject(what, global);
}

View file

@ -288,7 +288,7 @@ public final class RhinoEngine implements ScriptingEngine {
esv[i] = ESLoader.normalizeValue (args[i], evaluator); */
// XML-RPC requires special argument conversion
if (xmlrpc) {
args[i] = core.processXmlRpcArgument (args[i], Context.getCurrentContext());
args[i] = core.processXmlRpcArgument (args[i]);
} else {
args[i] = context.toObject(args[i], global);
}

View file

@ -0,0 +1,155 @@
/*
* Helma License Notice
*
* The contents of this file are subject to the Helma License
* Version 2.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://adele.helma.org/download/helma/license.txt
*
* Copyright 1998-2003 Helma Software. All Rights Reserved.
*
* $RCSfile$
* $Author$
* $Revision$
* $Date$
*/
package helma.scripting.rhino;
import org.mozilla.javascript.*;
import org.apache.xmlrpc.*;
import java.io.*;
import java.net.*;
import java.util.*;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
/**
* An extension to transparently call and serve XML-RPC from Rhino.
* The extension adds constructors for XML-RPC clients and servers to the Global Object.
*
* All argument conversion is done automatically. Currently the following argument and return
* types are supported:
* <ul>
* <li> plain objects (with all properties returned by ESObject.getProperties ())
* <li> arrays
* <li> strings
* <li> date objects
* <li> booleans
* <li> integer and float numbers (long values are not supported!)
* </ul>
*
*/
public class XmlRpcObject extends BaseFunction {
String url = null;
String method = null;
XmlRpcObject(String url) {
this.url = url;
this.method = null;
}
XmlRpcObject(String url, String method) {
this.url = url;
this.method = method;
}
/**
* This method is used as HopObject constructor from JavaScript.
*/
public static Object xmlrpcObjectConstructor(Context cx, Object[] args,
Function ctorObj, boolean inNewExpr) {
if (args.length == 0 || args.length > 2) {
throw new IllegalArgumentException("Wrong number of arguments in constructor for XML-RPC client");
}
if (args.length == 1) {
String url = args[0].toString();
return new XmlRpcObject(url);
} else {
String url = args[0].toString();
String method = args[1].toString();
return new XmlRpcObject(url, method);
}
}
/**
* Called by the evaluator after the extension is loaded.
*/
public static void init(Scriptable scope) {
Method[] methods = XmlRpcObject.class.getDeclaredMethods();
Member ctorMember = null;
for (int i=0; i<methods.length; i++) {
if ("xmlrpcObjectConstructor".equals(methods[i].getName())) {
ctorMember = methods[i];
break;
}
}
FunctionObject ctor = new FunctionObject("Remote", ctorMember, scope);
((ScriptableObject)scope).defineProperty(scope, "Remote", ctor, ScriptableObject.DONTENUM);
// ctor.addAsConstructor(scope, proto);
}
public Object get(String name, Scriptable start) {
String m = method == null ? name : method+"."+name;
return new XmlRpcObject(url, m);
}
public Object call(Context cx,
Scriptable scope,
Scriptable thisObj,
Object[] args)
throws JavaScriptException {
if (method == null) {
throw new JavaScriptException("Invalid method name");
}
try {
RhinoEngine engine = (RhinoEngine) cx.getThreadLocal("engine");
RhinoCore c = engine.core;
XmlRpcClient client = new XmlRpcClient(url);
// long now = System.currentTimeMillis ();
Object retval = null;
int l = args.length;
Vector v = new Vector();
for (int i = 0; i < l; i++) {
Object arg = c.processXmlRpcResponse(args[i]);
v.addElement(arg);
}
retval = client.execute(method, v);
return c.processXmlRpcArgument(retval);
} catch (Exception x) {
String msg = x.getMessage();
if ((msg == null) || (msg.length() == 0)) {
msg = x.toString();
}
throw new JavaScriptException(msg);
}
}
public String getClassName() {
return "Remote";
}
public String toString() {
return "[Remote "+url+"]";
}
public Object getDefaultValue(Class hint) {
if (hint == null || hint == String.class) {
return toString();
}
return super.getDefaultValue(hint);
}
}