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, FileObject.class);
|
||||||
ScriptableObject.defineClass(global, FtpObject.class);
|
ScriptableObject.defineClass(global, FtpObject.class);
|
||||||
ImageObject.init(global);
|
ImageObject.init(global);
|
||||||
|
XmlRpcObject.init(global);
|
||||||
MailObject.init(global, app.getProperties());
|
MailObject.init(global, app.getProperties());
|
||||||
putPrototype("hopobject",
|
putPrototype("hopobject",
|
||||||
ScriptableObject.getClassPrototype(global, "HopObject"));
|
ScriptableObject.getClassPrototype(global, "HopObject"));
|
||||||
|
@ -378,15 +379,23 @@ public final class RhinoCore {
|
||||||
* representation.
|
* representation.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public Object processXmlRpcArgument (Object what, Context cx) throws Exception {
|
public Object processXmlRpcArgument (Object what) throws Exception {
|
||||||
if (what == null)
|
if (what == null)
|
||||||
return null;
|
return null;
|
||||||
if (what instanceof Vector) {
|
if (what instanceof Vector) {
|
||||||
Vector v = (Vector) what;
|
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) {
|
if (what instanceof Hashtable) {
|
||||||
Hashtable t = (Hashtable) what;
|
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);
|
return Context.toObject(new SystemMap(t), global);
|
||||||
}
|
}
|
||||||
if (what instanceof String)
|
if (what instanceof String)
|
||||||
|
@ -398,7 +407,7 @@ public final class RhinoCore {
|
||||||
if (what instanceof Date) {
|
if (what instanceof Date) {
|
||||||
Date d = (Date) what;
|
Date d = (Date) what;
|
||||||
Object[] args = { new Long(d.getTime()) };
|
Object[] args = { new Long(d.getTime()) };
|
||||||
return cx.newObject(global, "Date", args);
|
return Context.getCurrentContext().newObject(global, "Date", args);
|
||||||
}
|
}
|
||||||
return Context.toObject(what, global);
|
return Context.toObject(what, global);
|
||||||
}
|
}
|
||||||
|
|
|
@ -288,7 +288,7 @@ public final class RhinoEngine implements ScriptingEngine {
|
||||||
esv[i] = ESLoader.normalizeValue (args[i], evaluator); */
|
esv[i] = ESLoader.normalizeValue (args[i], evaluator); */
|
||||||
// XML-RPC requires special argument conversion
|
// XML-RPC requires special argument conversion
|
||||||
if (xmlrpc) {
|
if (xmlrpc) {
|
||||||
args[i] = core.processXmlRpcArgument (args[i], Context.getCurrentContext());
|
args[i] = core.processXmlRpcArgument (args[i]);
|
||||||
} else {
|
} else {
|
||||||
args[i] = context.toObject(args[i], global);
|
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