
Contents of /Public_Parser_JSON-0.2/module.pmod.in:
inherit .___JSON;
//! Holds a pike object and exposes its methods to JSON-RPC:
//!
//! Example:
//!
//! object wrap = Wrapper(my_pike_object);
//! mapping json_result = wrap->call ( json_request );
class Wrapper {
object o;
void create (object mo) {
/* master object */
if (mo)
o = mo;
else
return 0;
}
//! Will return an array with the names of the available methods.
mapping describe () {
string name = "";
array e = catch {
name = function_name(object_program(o));
};
array list = filter( map(indices(o), lambda(string m) {
if (functionp(o[m]) && m != "create" && m != "destroy")
return ([ "name" : m ]); } )
, lambda(mixed a) { return a != 0; } );
return ([ "name" : name,
"procs" : list ]);
}
//! The argument must be a mapping of a JSON-RPC request object.
//!
//! Any errror that occurs will be returned in the error component of the
//! JSON-RPC result object.
mapping call (mapping request) {
mapping response = ([]);
response->method = request->method;
mixed method = o[request->method];
if (!zero_type(method) && functionp(method)) {
array error = catch {
if (request->params && sizeof(request->params))
response->result = method(@request->params);
else
response->result = method();
};
if (error) {
response->error = ([]);
response->error->msg = error[0];
response->error->params = request->params;
// response->error->backtrace = describe_backtrace(error);
}
} else if (request->method == "system.describe") {
response->result = describe();
} else {
response->result = 0;
response->error = ({ "Unknown method " });
}
if (request->id)
response->id = request->id;
return response;
}
}
/* This would be used like this:
*
* object json-rpc = Proxy("http://my_url");
*
* mixed result = json-rpc->foreign_method(arguments);
*/
class ProxyMethod {
string name, id;
object proxy;
void create (string i, string n, Proxy p) {
name = n;
proxy = p;
id = i;
}
mixed `() (mixed ... args) {
mapping request = ([ "method" : name,
"params" : args,
"id" : id ]);
Protocols.HTTP.Session.Request r = proxy->session->post_url(proxy->url, encode(request));
/* do request */
/* return result part of response. If errors, throw error message */
}
}
class Proxy {
Protocols.HTTP.Session session;
object url;
mapping(string:object) ids;
void create (string u) {
session = Protocols.HTTP.Session();
url = Standards.URI(u);
}
/* Maybe preload the methods? */
ProxyMethod `-> (string arg) {
ProxyMethod o = ProxyMethod("0", arg, this_object());
}
}