Home modules.gotpike.org
Username: Password: [Create Account]
[Forgot Password?]

Modules

ADT
Database
GTK2
GUI
IP
PiJAX
Public
Sql
Stdio
Subversion
System
Tools
Xosd
lua
v4l2
wx

Recent Changes

Public.ZeroMQ 1.1
Public.Template.Mustache 1.0
Public.Protocols.XMPP 1.4
Sql.Provider.jdbc 1.0
Public.Storage.Manta 1.0

Popular Downloads

Public.Parser.JSON2 1.0
Public.Parser.JSON 0.2
GTK2 2.23
Public.Web.FCGI 1.8
Public.Parser.XML2 1.48


Module Information
Public.Parser.JSON
Viewing 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());    
  }
}


gotpike.org | Copyright © 2004 - 2019 | Pike is a trademark of Department of Computer and Information Science, Linköping University