priv/server_root/htdocs/jsonrpc.js
author Tom Parker <palfrey@lshift.net>
Wed Mar 10 14:30:27 2010 +0000 (22 hours ago)
changeset 252 25255b7139e3
parent 1012e6223986a83
permissions -rw-r--r--
metadata: Hand back NullTags if we find a file we don't know how to get the tags for
     1 JsonRpcRequestId = 1;
     2 
     3 JsonRpcTransaction = Class.create();
     4 Object.extend(JsonRpcTransaction.prototype,
     5 {
     6     initialize: function(serviceUrl, methodName, params, options) {
     7 	this.options = {
     8 	    debug: false,
     9 	    timeout: 0 /* milliseconds; zero means "do not specify" */
    10 	};
    11 	Object.extend(this.options, options || {});
    12 	this.serviceUrl = serviceUrl;
    13 	this.methodName = methodName;
    14 	this.params = params;
    15 	this.error = null;
    16 	this.reply = null;
    17 	this.replyReady = 0;
    18 	this.callbacks = [];
    19 	this.errorCallbacks = [];
    20 	this.sendRequest();
    21     },
    22 
    23     buildRequest: function() {
    24 	return { version: "1.1",
    25 		 id: JsonRpcRequestId++,
    26 		 method: this.methodName,
    27 		 params: this.params };
    28     },
    29 
    30     sendRequest: function() {
    31 	var headers = ['Content-type', 'application/json',
    32 		       'Accept', 'application/json'];
    33 	if (this.options.timeout) {
    34 	    headers.push('X-JSON-RPC-Timeout', this.options.timeout);
    35 	}
    36 	this.request =
    37 	    new Ajax.Request(this.serviceUrl,
    38 			     { method: 'post',
    39 			       requestHeaders: headers,
    40 			       postBody: JSON.stringify(this.buildRequest()),
    41 			       onComplete: this.receiveReply.bind(this) });
    42     },
    43 
    44     receiveReply: function(ajaxRequest) {
    45 	var response = JSON.parse(ajaxRequest.responseText);
    46 	if (response.error) {
    47 	    if (this.options.debug) {
    48 		alert("JsonRPC error:\n" +
    49 		      "Service: " + JSON.stringify(this.serviceUrl) + "\n" +
    50 		      "Method: " + JSON.stringify(this.methodName) + "\n" +
    51 		      "Params: " + JSON.stringify(this.params) + "\n" +
    52 		      "Response: " + JSON.stringify(response) + "\n");
    53 	    }
    54 	    this.error = response.error;
    55 	    this.errorCallbacks.each(function (cb) {
    56 					 try { cb(response.error, true); }
    57 					 catch (err) {}
    58 				     });
    59 	} else {
    60 	    var reply = response.result;
    61 	    this.reply = reply;
    62 	    this.replyReady = 1;
    63 	    this.callbacks.each(function (cb) {
    64 				    try { cb(reply, false); }
    65 				    catch (err) {}
    66 				});
    67 	}
    68     },
    69 
    70     addCallback: function(cb) {
    71 	this.callbacks.push(cb);
    72 	if (this.replyReady) {
    73 	    try { cb(this.reply, false); }
    74 	    catch (err) {}
    75 	}
    76 	return this;
    77     },
    78 
    79     addErrorCallback: function(cb) {
    80 	this.errorCallbacks.push(cb);
    81 	if (this.error) {
    82 	    try { cb(this.error, true); }
    83 	    catch (err) {}
    84 	}
    85 	return this;
    86     }
    87 });
    88 
    89 JsonRpcService = Class.create();
    90 Object.extend(JsonRpcService.prototype,
    91 {
    92     initialize: function(serviceUrl, onReady, options) {
    93 	this.options = {
    94 	    transactionClass: JsonRpcTransaction,
    95 	    timeout: 0, /* milliseconds; zero means "do not specify" */
    96 	    debug: false
    97 	};
    98 	Object.extend(this.options, options || {});
    99 	this.serviceUrl = serviceUrl;
   100 	var svc = this;
   101 	var txn = new (this.options.transactionClass)(serviceUrl,
   102 						      "system.describe",
   103 						      [],
   104 						      {debug: this.options.debug});
   105 	txn.addCallback(receiveServiceDescription);
   106 	function receiveServiceDescription(sd) {
   107 	    svc.serviceDescription = sd;
   108 	    svc.serviceDescription.procs.each(svc.installGenericProxy.bind(svc));
   109 	    onReady();
   110 	}
   111     },
   112 
   113     installGenericProxy: function(desc) {
   114 	this[desc.name] = function () {
   115 	    var actuals = $A(arguments);
   116 	    return new (this.options.transactionClass)(this.serviceUrl,
   117 						       desc.name,
   118 						       actuals,
   119 						       {
   120 							   debug: this.options.debug,
   121 							   timeout: this.options.timeout
   122 						       });
   123 	};
   124     }
   125 });