3 Modification information for LGPL compliance
5 r56990 - 2010-06-16 13:05:36 -0700 (Wed, 16 Jun 2010) - kjing - snapshot "Mango" svn branch to a new one for GitHub sync
7 r56989 - 2010-06-16 13:01:33 -0700 (Wed, 16 Jun 2010) - kjing - defunt "Mango" svn dev branch before github cutover
9 r55980 - 2010-04-19 13:31:28 -0700 (Mon, 19 Apr 2010) - kjing - create Mango (6.1) based on windex
11 r51719 - 2009-10-22 10:18:00 -0700 (Thu, 22 Oct 2009) - mitani - Converted to Build 3 tags and updated the build system
13 r51634 - 2009-10-19 13:32:22 -0700 (Mon, 19 Oct 2009) - mitani - Windex is the branch for Sugar Sales 1.0 development
15 r50375 - 2009-08-24 18:07:43 -0700 (Mon, 24 Aug 2009) - dwong - branch kobe2 from tokyo r50372
17 r42807 - 2008-12-29 11:16:59 -0800 (Mon, 29 Dec 2008) - dwong - Branch from trunk/sugarcrm r42806 to branches/tokyo/sugarcrm
19 r21575 - 2007-04-09 16:28:53 -0700 (Mon, 09 Apr 2007) - chris - Bug 12274 - SECURITY: CSRF (cross-site request forgery) fix.
30 ./include/jsclass_async.js
31 ./include/jsclass_base.js
32 ./include/javascript/yui/connection.js
33 ./include/jsolait/lib/jsonrpc.js
34 ./include/jsolait/lib/jsonrpclite.js
37 ./modules/Emails/Email.js
39 r10487 - 2005-12-12 03:57:07 -0800 (Mon, 12 Dec 2005) - robert - fixed: 3478
40 also changed jsonrpc on the client side so that javascript classes
41 will no longer get the toJSON method added to it.
47 Copyright (c) 2003-2004 Jan-Klaas Kollhof
49 This file is part of the JavaScript o lait library(jsolait).
51 jsolait is free software; you can redistribute it and/or modify
52 it under the terms of the GNU Lesser General Public License as published by
53 the Free Software Foundation; either version 2.1 of the License, or
54 (at your option) any later version.
56 This software is distributed in the hope that it will be useful,
57 but WITHOUT ANY WARRANTY; without even the implied warranty of
58 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
59 GNU Lesser General Public License for more details.
61 You should have received a copy of the GNU Lesser General Public License
62 along with this software; if not, write to the Free Software
63 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
68 // USES the langlite.php instead of lang.php
69 Provides an JSON-RPC imlementation.
71 Module("jsonrpclite", "0.3.2", function(mod){
74 var lang = importModule("langlite");
76 var tokens = lang.tokens;
78 var ObjectBuffer=Class("ObjectBuffer", function(publ, supr){
82 publ.getObjects=function(data){
84 var t = new lang.Tokenizer(this.data);
88 while(! t.finished()){
90 if(n.type != tokens.ERR){
93 }else if(n.value == "}"){
96 var s = this.data.slice(readCnt, n.pos+1);
105 this.data = this.data.slice(readCnt);
110 var nameAllowed=function(name){
111 return name.match(/^[a-zA-Z]\w*$/) != null;
114 var getMethodByName=function(obj, name){
115 try{//to get a method by asking the service
116 obj = obj._getMethodByName(name)
118 var names = name.split(".");
119 for(var i=0;i<names.length;i++){
121 if(nameAllowed(name)){
129 var Response=Class("Response", function(publ, supr){
130 publ.init=function(id, result, error){
132 this.result = result;
135 publ._toJSON=function(){
136 var p = [lang.objToJson(this.id), lang.objToJson(this.result),lang.objToJson(this.error)];
137 return '{"id":' + p[0] + ', "result":' + p[1] + ', "error":' + p[2] + "}";
141 var Request=Class("Request", function(publ, supr){
142 publ.init=function(id, method, params){
144 this.method = method;
145 this.params = params;
148 for(hello in this.params)
150 str += "var:"+hello+":"+this.params[hello]+":\n";
155 publ._toJSON=function(){
156 var p = [lang.objToJson(this.id), lang.objToJson(this.method),lang.objToJson(this.params)];
157 return '{"id":' + p[0] + ', "method":' + p[1] + ', "params":' + p[2] + "}";
161 var Notification=Class("Notification", function(publ, supr){
162 publ.init=function(method, params){
163 this.method = method;
164 this.params = params;
166 publ._toJSON=function(){
167 var p = [lang.objToJson(this.method),lang.objToJson(this.params)];
168 return '{"method":' + p[0] + ', "params":' + p[1] + "}";
172 var ResponseHandler=Class("ResponseHandler", function(publ, supr){
173 publ.init=function(callback){
174 this.callback=callback;
176 publ.handleResponse=function(resp){
177 this.callback(resp.result, resp.error);
181 var RPCLib = Class("RPCLib", function(publ, supr){
185 var BaseConnectionHandler = Class("BaseConnectionHandler", function(publ, supr){
186 publ.init=function(service){
187 this.service = service;
188 this.jsonParser = new lang.JSONParser();
189 this.jsonParser.addLib(new RPCLib(), "rpc", []);
190 this.respHandlers = [];
191 this.objBuffer = new ObjectBuffer();
194 publ.addResponseHandler=function(cb){
196 while(this.respHandlers[""+id] ){
200 this.respHandlers[id] = new ResponseHandler(cb);
204 publ.send = function(data){
207 publ.sendNotify = function(name, args){
208 var n = new Notification(name, args);
209 n = this.jsonParser.objToJson(n);
213 publ.sendRequest = function(name, args, callback){
214 var id = this.addResponseHandler(callback);
215 var r = new Request(id, name, args);
216 r = this.jsonParser.objToJson(r);
220 publ.sendResponse = function(id, result, error){
221 var r = new Response(id, result, error);
222 r = this.jsonParser.objToJson(r);
226 publ.handleRequest = function(req){
227 var name = req.method;
228 var params = req.params;
230 if(this.service[name]){
232 var rslt = this.service[name].apply(this.service,params);
233 this.sendResponse(id, rslt, null)
235 this.sendResponse(id, null, new ApplicationError("" + e))
238 this.sendResponse(id, null, new MethodNotFound());
242 publ.handleNotification = function(notif){
243 if(this.service[notif.method]){
245 this.service[notif.method].apply(this.service, notif.params);
251 publ.handleResponse = function(resp){
253 var h = this.respHandlers[id];
254 h.handleResponse(resp)
255 delete this.respHandlers[id]
258 publ.handleData = function(data){
259 var objs = this.objBuffer.getObjects(data);
260 for(var i=0;i<objs.length;i++){
262 var obj = this.jsonParser.jsonToObj(objs[i]);
264 throw "Not well formed";
266 if(obj.method != null){
268 this.handleRequest(new Request(obj.id, obj.method, obj.params));
270 this.handleNotification(new Notification(obj.method, obj.params));
272 }else if(obj.id != null){
273 this.handleResponse(new Response(obj.id, obj.result, obj.error));
275 throw "Unknown Data";
281 var SocketConnectionHandler = Class("SocketConnectionHandler", BaseConnectionHandler, function(publ, supr){
282 publ.init=function(socket, localService){
283 this.socket = socket;
284 socket.addEventListener("connectionData", this, false);
285 supr(this).init( localService);
288 publ.handleEvent=function(evt){
289 this.handleData(evt.data);
292 publ.send=function(data){
293 this.socket.send(data);
296 publ.close=function(data){
301 var HTTPConnectionHandler = Class("HTTPConnectionHandler", BaseConnectionHandler, function(publ, supr){
304 publ.init=function(url, localService){
305 urllib=importModule("urllib");
307 supr(this).init( localService);
310 publ.handleData = function(data){
313 var obj = JSON.parse(data);
315 throw " Not well formed\n\n" + e + "\n\nResponse from server:\n\n " + data;
320 throw "Unknown Data (No id property found)";
324 publ.sendRequest = function(name, args, callback){
326 if(typeof callback != "function"){//see if it is sync
330 var data = new Request(this.request_id++, name, args);
331 // cn: bug 12274 - defend against CSRF
332 data = JSON.stringify(data); // creates security envelope wrapped JSON object
335 var rsp = urllib.postURL(this.url, data, [["Content-Type", "text/plain"]]);
336 rsp = this.handleData(rsp.responseText);
342 }else{//async connection uses the respHandler to handle the repsonse
344 var request_id = this.request_id;
345 urllib.postURL(this.url, data, [["Content-Type", "text/plain"]], function(rsp){
347 rsp = self.handleData(rsp.responseText);
350 callback(request_id,null,e);
353 callback(request_id,rsp.result, rsp.error);
354 //callback(this.request_id,rsp.result, rsp.error);
355 //callback(rsp.result, rsp.error);
360 publ.sendNotify = function(name, args){
361 var data = new Notification(name, args);
362 data = this.jsonParser.objToJson(data);
363 urllib.postURL(this.url, data, [["Content-Type", "text/plain"]], function(rsp){});
367 var PeerObject=Class("PeerObject", function(publ, supr){
368 publ.init=function(name, conn){
371 for(var i=0;i<arguments.length;i++){
372 args[i] = arguments[i];
375 return conn.sendRequest(name, args, cb);
381 var PeerNotifyObject=Class("PeerNotifyObject", function(publ, supr){
382 publ.init=function(name, conn){
385 for(var i=0;i<arguments.length;i++){
386 args[i] = arguments[i];
388 conn.sendNotify(name, args);
394 var BasePeer = Class("BasePeer", function(publ, supr){
395 publ.init=function(conn, methodNames){
397 this.notify = new PeerObject("notify", conn);
398 this._add(methodNames);
401 var setupPeerMethod=function(root, methodName, conn, MethClass){
402 var names = methodName.split(".");
404 for(var n=0;n<names.length-1;n++){
409 obj[name] = new Object();
413 var name = names[names.length-1];
416 var mth = new MethClass(methodName, conn);
421 publ._add = function(methodNames){
422 for(var i=0;i<methodNames.length;i++){
423 setupPeerMethod(this, methodNames[i], this._conn, PeerObject);
424 setupPeerMethod(this.notify, methodNames[i], this._conn, PeerNotifyObject);
430 mod.ServiceProxy = Class("ServiceProxy", BasePeer, function(publ, supr){
431 publ.init = function(url, methodNames, localService){
433 var n = url.match(/^jsonrpc:\/\/(.*:\d*)$/);
434 if(n!=null){//is it json-rpc over TCP protocoll
437 var socket = createConnection();
439 throw "Can't create a socket connection."
441 socket.connect(hostaddr);
442 supr(this).init( new SocketConnectionHandler(socket, localService), methodNames);
443 }else{//or is it json-rpc over http
444 this.httpConn = new HTTPConnectionHandler(url, localService);
445 supr(this).init( this.httpConn, methodNames);