/* Modification information for LGPL compliance r56990 - 2010-06-16 13:05:36 -0700 (Wed, 16 Jun 2010) - kjing - snapshot "Mango" svn branch to a new one for GitHub sync r56989 - 2010-06-16 13:01:33 -0700 (Wed, 16 Jun 2010) - kjing - defunt "Mango" svn dev branch before github cutover r55980 - 2010-04-19 13:31:28 -0700 (Mon, 19 Apr 2010) - kjing - create Mango (6.1) based on windex r51719 - 2009-10-22 10:18:00 -0700 (Thu, 22 Oct 2009) - mitani - Converted to Build 3 tags and updated the build system r51634 - 2009-10-19 13:32:22 -0700 (Mon, 19 Oct 2009) - mitani - Windex is the branch for Sugar Sales 1.0 development r50375 - 2009-08-24 18:07:43 -0700 (Mon, 24 Aug 2009) - dwong - branch kobe2 from tokyo r50372 r42807 - 2008-12-29 11:16:59 -0800 (Mon, 29 Dec 2008) - dwong - Branch from trunk/sugarcrm r42806 to branches/tokyo/sugarcrm r4085 - 2005-04-13 17:30:42 -0700 (Wed, 13 Apr 2005) - robert - adding meeting scheduler and accept/decline */ /* 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 */ /** Provides an XML-RPC imlementation. It is similar to python's xmlrpclib module. */ Module("xmlrpc","1.3.3", function(mod){ var xmlext = importModule("xml"); var urllib = importModule("urllib"); /** Thrown if a server did not respond with response status 200 (OK). */ mod.InvalidServerResponse = Class("InvalidServerResponse", mod.Exception, function(publ, supr){ /** Initializes the Exception. @param status The status returned by the server. */ publ.init= function(status){ supr(this).init("The server did not respond with a status 200 (OK) but with: " + status); this.status = status; } ///The status returned by the server. publ.status; }) /** Thrown if an XML-RPC response is not well formed. */ mod.MalformedXmlRpc = Class("MalformedXmlRpc", mod.Exception, function(publ, supr){ /** Initializes the Exception. @param msg The error message of the user. @param xml The xml document's source. @param trace=null The error causing this Exception */ publ.init= function(msg, xml, trace){ supr(this).init(msg,trace); this.xml = xml; } ///The xml source which was mal formed. publ.xml; }) /** Thrown if the RPC response is a Fault. */ mod.Fault = Class("Fault", mod.Exception, function(publ, supr){ /** Initializes the Exception. @param faultCode The fault code returned by the rpc call. @param faultString The fault string returned by the rpc call. */ publ.init= function(faultCode, faultString){ supr(this).init("XML-RPC Fault: " + faultCode + "\n\n" + faultString); this.faultCode = faultCode; this.faultString = faultString; } ///The fault code returned from the rpc call. publ.faultCode; ///The fault string returned from the rpc call. publ.faultString; }) /** Marshalls an object to XML-RPC.(Converts an object into XML-RPC conforming xml.) It just calls the toXmlRpc function of the objcect. So, to customize serialization of objects one just needs to specify/override the toXmlRpc method which should return an xml string conforming with XML-RPC spec. @param obj The object to marshall @return An xml representation of the object. */ mod.marshall = function(obj){ if(obj.toXmlRpc){ return obj.toXmlRpc(); }else{ var s = ""; for(var attr in obj){ if(typeof obj[attr] != "function"){ s += "" + attr + "" + mod.marshall(obj[attr]) + ""; } } s += ""; return s; } } /** Unmarshalls an XML document to a JavaScript object. (Converts xml to JavaScript object.) It parses the xml source and creates a JavaScript object. @param xml The xml document source to unmarshall. @return The JavaScript object created from the XML. */ mod.unmarshall = function(xml){ try {//try to parse xml ... this will throw an Exception if failed var doc = xmlext.parseXML(xml); }catch(e){ throw new mod.MalformedXmlRpc("The server's response could not be parsed.", xml, e); } var rslt = mod.unmarshallDoc(doc, xml); doc=null; return rslt; } /** Unmarshalls an XML document to a JavaScript object like unmarshall but expects a DOM document as parameter. It parses the xml source and creates a JavaScript object. @param doc The xml document(DOM compatible) to unmarshall. @return The JavaScript object created from the XML. */ mod.unmarshallDoc = function(doc, xml){ try{ var node = doc.documentElement; if(node==null){//just in case parse xml didn't throw an Exception but returned nothing usefull. throw new mod.MalformedXmlRpc("No documentElement found.", xml); } switch(node.tagName){ case "methodResponse": return parseMethodResponse(node); case "methodCall": return parseMethodCall(node); default://nothing usefull returned by parseXML. throw new mod.MalformedXmlRpc("'methodCall' or 'methodResponse' element expected.\nFound: '" + node.tagName + "'", xml); } }catch(e){ if(e instanceof mod.Fault){//just rethrow the fault. throw e; }else { throw new mod.MalformedXmlRpc("Unmarshalling of XML failed.", xml, e); } } } /** Parses a methodeResponse element. @param node The methodResponse element. @return The return value of the XML-RPC. */ var parseMethodResponse=function(node){ try{ for(var i=0;i'; if (args.length>0){ data += ""; for(var i=0;i'; } data += ''; } data += ''; return data; } /** Initializes the XML-RPC method. @param url The URL of the service providing the method. @param methodName The name of the method to invoke. @param user=null The user name to use for HTTP authentication. @param pass=null The password to use for HTTP authentication. */ publ.init = function(url, methodName, user, pass){ //this is pretty much a hack. //we create a function which mimics this class and return it instead of really instanciating an object. var fn=function(){ //sync or async call if(typeof arguments[arguments.length-1] != "function"){ var data=getXML(fn.methodName,arguments); var resp = postData(fn.url, fn.user, fn.password, data); return handleResponse(resp); }else{ var args=new Array(); for(var i=0;i 0){ var tryIntrospection=false; }else{ var tryIntrospection=true; } }else{ pass=user; user=methodNames; methodNames=[]; var tryIntrospection=true; } this._url = url; this._user = user; this._password = pass; this._addMethodNames(methodNames); if(tryIntrospection){ try{//it's ok if it fails. this._introspect(); }catch(e){ } } } /** Adds new XMLRPCMethods to the proxy server which can then be invoked. @param methodNames Array of names of methods that can be called on the server. */ publ._addMethodNames = function(methodNames){ for(var i=0;i" + this.replace(/&/g, "&").replace(/"; } /** XML-RPC representation of a number. @return A string containing the Number's representation in XML. */ Number.prototype.toXmlRpc = function(){ if(this == parseInt(this)){ return "" + this + ""; }else if(this == parseFloat(this)){ return "" + this + ""; }else{ return false.toXmlRpc(); } } /** XML-RPC representation of a boolean. @return A string containing the Boolean's representation in XML. */ Boolean.prototype.toXmlRpc = function(){ if(this == true) { return "1"; }else{ return "0"; } } /** XML-RPC representation of a date(iso 8601). @return A string containing the Date's representation in XML. */ Date.prototype.toXmlRpc = function(){ var padd=function(s, p){ s=p+s return s.substring(s.length - p.length) } var y = padd(this.getUTCFullYear(), "0000"); var m = padd(this.getUTCMonth() + 1, "00"); var d = padd(this.getUTCDate(), "00"); var h = padd(this.getUTCHours(), "00"); var min = padd(this.getUTCMinutes(), "00"); var s = padd(this.getUTCSeconds(), "00"); var isodate = y + m + d + "T" + h + ":" + min + ":" + s return "" + isodate + ""; } /** XML-RPC representation of an array. Each entry in the array is a value in the XML-RPC. @return A string containing the Array's representation in XML. */ Array.prototype.toXmlRpc = function(){ var retstr = ""; for(var i=0;i"; } return retstr + ""; } mod.test = function(){ print("creating ServiceProxy object using introspection for method construction...\n"); var s = new mod.ServiceProxy("http://localhost/testx.py"); print("%s created\n".format(s)); print("creating and marshalling test data:\n"); var o = [1.234, 5, {a:"Hello & < ", b:new Date()}]; print(mod.marshall(o)); print("\ncalling echo() on remote service...\n"); var r = s.echo(o); print("service returned data(marshalled again):\n") print(mod.marshall(r)); } })