📄 jsonrpclite.js
字号:
/* Copyright (c) 2003-2004 Jan-Klaas Kollhof This file is part of the JavaScript o lait library(jsolait). jsolait is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this software; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA*//** // SUGARCRM: // USES the langlite.php instead of lang.php Provides an JSON-RPC imlementation.*/Module("jsonrpclite", "0.3.2", function(mod){ // SUGARCRM: var lang = importModule("langlite"); // END SUGARCRM var tokens = lang.tokens; var ObjectBuffer=Class("ObjectBuffer", function(publ, supr){ publ.init=function(){ this.data=""; } publ.getObjects=function(data){ this.data += data; var t = new lang.Tokenizer(this.data); var brCnt= 0; var objects = []; var readCnt = 0 while(! t.finished()){ var n = t.next(); if(n.type != tokens.ERR){ if(n.value == "{"){ brCnt+=1; }else if(n.value == "}"){ brCnt-=1; if(brCnt==0){ var s = this.data.slice(readCnt, n.pos+1); readCnt += s.length; objects.push(s); } } }else{ break; } } this.data = this.data.slice(readCnt); return objects; } }) var nameAllowed=function(name){ return name.match(/^[a-zA-Z]\w*$/) != null; } var getMethodByName=function(obj, name){ try{//to get a method by asking the service obj = obj._getMethodByName(name) }catch(e){ var names = name.split("."); for(var i=0;i<names.length;i++){ name = names[i]; if(nameAllowed(name)){ obj = obj[name]; } } } return obj; } var Response=Class("Response", function(publ, supr){ publ.init=function(id, result, error){ this.id=id; this.result = result; this.error = error; } publ._toJSON=function(){ var p = [lang.objToJson(this.id), lang.objToJson(this.result),lang.objToJson(this.error)]; return '{"id":' + p[0] + ', "result":' + p[1] + ', "error":' + p[2] + "}"; } }) var Request=Class("Request", function(publ, supr){ publ.init=function(id, method, params){ this.id=id; this.method = method; this.params = params;/* var str = '';for(hello in this.params){ str += "var:"+hello+":"+this.params[hello]+":\n";}alert(str);*/ } publ._toJSON=function(){ var p = [lang.objToJson(this.id), lang.objToJson(this.method),lang.objToJson(this.params)]; return '{"id":' + p[0] + ', "method":' + p[1] + ', "params":' + p[2] + "}"; } }) var Notification=Class("Notification", function(publ, supr){ publ.init=function(method, params){ this.method = method; this.params = params; } publ._toJSON=function(){ var p = [lang.objToJson(this.method),lang.objToJson(this.params)]; return '{"method":' + p[0] + ', "params":' + p[1] + "}"; } }) var ResponseHandler=Class("ResponseHandler", function(publ, supr){ publ.init=function(callback){ this.callback=callback; } publ.handleResponse=function(resp){ this.callback(resp.result, resp.error); } }) var RPCLib = Class("RPCLib", function(publ, supr){ }) var BaseConnectionHandler = Class("BaseConnectionHandler", function(publ, supr){ publ.init=function(service){ this.service = service; this.jsonParser = new lang.JSONParser(); this.jsonParser.addLib(new RPCLib(), "rpc", []); this.respHandlers = []; this.objBuffer = new ObjectBuffer(); } publ.addResponseHandler=function(cb){ var id=1; while(this.respHandlers[""+id] ){ id+=1; } id="" + id; this.respHandlers[id] = new ResponseHandler(cb); return id; } publ.send = function(data){ } publ.sendNotify = function(name, args){ var n = new Notification(name, args); n = this.jsonParser.objToJson(n); this.send(n) } publ.sendRequest = function(name, args, callback){ var id = this.addResponseHandler(callback); var r = new Request(id, name, args); r = this.jsonParser.objToJson(r); this.send(r); } publ.sendResponse = function(id, result, error){ var r = new Response(id, result, error); r = this.jsonParser.objToJson(r); this.send(r); } publ.handleRequest = function(req){ var name = req.method; var params = req.params; var id=req.id; if(this.service[name]){ try{ var rslt = this.service[name].apply(this.service,params); this.sendResponse(id, rslt, null) }catch(e){ this.sendResponse(id, null, new ApplicationError("" + e)) } }else{ this.sendResponse(id, null, new MethodNotFound()); } } publ.handleNotification = function(notif){ if(this.service[notif.method]){ try{ this.service[notif.method].apply(this.service, notif.params); }catch(e){ } } } publ.handleResponse = function(resp){ var id=resp.id; var h = this.respHandlers[id]; h.handleResponse(resp) delete this.respHandlers[id] } publ.handleData = function(data){ var objs = this.objBuffer.getObjects(data); for(var i=0;i<objs.length;i++){ try{ var obj = this.jsonParser.jsonToObj(objs[i]); }catch(e){ throw "Not well formed"; } if(obj.method != null){ if(obj.id != null){ this.handleRequest(new Request(obj.id, obj.method, obj.params)); }else{ this.handleNotification(new Notification(obj.method, obj.params)); } }else if(obj.id != null){ this.handleResponse(new Response(obj.id, obj.result, obj.error)); }else{ throw "Unknown Data"; } } } }) var SocketConnectionHandler = Class("SocketConnectionHandler", BaseConnectionHandler, function(publ, supr){ publ.init=function(socket, localService){ this.socket = socket; socket.addEventListener("connectionData", this, false); supr(this).init( localService); } publ.handleEvent=function(evt){ this.handleData(evt.data); } publ.send=function(data){ this.socket.send(data); } publ.close=function(data){ this.socket.close(); } }) var HTTPConnectionHandler = Class("HTTPConnectionHandler", BaseConnectionHandler, function(publ, supr){ var urllib; publ.request_id = 1; publ.init=function(url, localService){ urllib=importModule("urllib"); this.url = url; supr(this).init( localService); } publ.handleData = function(data){ try{ var obj = JSON.parse(data); }catch(e){; throw " Not well formed\n\n" + e + "\n\nResponse from server:\n\n " + data; } if(obj.id != null){ return obj; }else{ throw "Unknown Data (No id property found)"; } } publ.sendRequest = function(name, args, callback){ var sync = false; if(typeof callback != "function"){//see if it is sync args.push(callback); sync=true; } var data = new Request(this.request_id++, name, args); // cn: bug 12274 - defend against CSRF data = JSON.stringify(data); // creates security envelope wrapped JSON object if(sync){ var rsp = urllib.postURL(this.url, data, [["Content-Type", "text/plain"]]); rsp = this.handleData(rsp.responseText); if(rsp.error){ throw rsp.error; }else{ return rsp.result; } }else{//async connection uses the respHandler to handle the repsonse var self = this; var request_id = this.request_id; urllib.postURL(this.url, data, [["Content-Type", "text/plain"]], function(rsp){ try{ rsp = self.handleData(rsp.responseText); }catch(e){ //callback(null,e); callback(request_id,null,e); return; } callback(request_id,rsp.result, rsp.error); //callback(this.request_id,rsp.result, rsp.error); //callback(rsp.result, rsp.error); }); } } publ.sendNotify = function(name, args){ var data = new Notification(name, args); data = this.jsonParser.objToJson(data); urllib.postURL(this.url, data, [["Content-Type", "text/plain"]], function(rsp){}); } }) var PeerObject=Class("PeerObject", function(publ, supr){ publ.init=function(name, conn){ var fn=function(){ var args=[]; for(var i=0;i<arguments.length;i++){ args[i] = arguments[i]; } var cb=args.pop(); return conn.sendRequest(name, args, cb); } return fn; } }) var PeerNotifyObject=Class("PeerNotifyObject", function(publ, supr){ publ.init=function(name, conn){ var fn=function(){ var args=[]; for(var i=0;i<arguments.length;i++){ args[i] = arguments[i]; } conn.sendNotify(name, args); } return fn; } }) var BasePeer = Class("BasePeer", function(publ, supr){ publ.init=function(conn, methodNames){ this._conn = conn; this.notify = new PeerObject("notify", conn); this._add(methodNames); } var setupPeerMethod=function(root, methodName, conn, MethClass){ var names = methodName.split("."); var obj = root; for(var n=0;n<names.length-1;n++){ var name = names[n]; if(obj[name]){ obj = obj[name]; }else{ obj[name] = new Object(); obj = obj[name]; } } var name = names[names.length-1]; if(obj[name]){ }else{ var mth = new MethClass(methodName, conn); obj[name] = mth; } } publ._add = function(methodNames){ for(var i=0;i<methodNames.length;i++){ setupPeerMethod(this, methodNames[i], this._conn, PeerObject); setupPeerMethod(this.notify, methodNames[i], this._conn, PeerNotifyObject); } } }) mod.ServiceProxy = Class("ServiceProxy", BasePeer, function(publ, supr){ publ.init = function(url, methodNames, localService){ var n = url.match(/^jsonrpc:\/\/(.*:\d*)$/); if(n!=null){//is it json-rpc over TCP protocoll var hostaddr = n[1]; try{ var socket = createConnection(); }catch(e){ throw "Can't create a socket connection." } socket.connect(hostaddr); supr(this).init( new SocketConnectionHandler(socket, localService), methodNames); }else{//or is it json-rpc over http this.httpConn = new HTTPConnectionHandler(url, localService); supr(this).init( this.httpConn, methodNames); } } })})
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -