Added Remote (XML-RPC client) object.
Fixes in XML-RPC argument encoding.
This commit is contained in:
parent
a758a479d7
commit
2f5c368124
3 changed files with 168 additions and 4 deletions
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
155
src/helma/scripting/rhino/XmlRpcObject.java
Normal file
155
src/helma/scripting/rhino/XmlRpcObject.java
Normal 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);
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Reference in a new issue