/*
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' + mod.marshall(args[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" + mod.marshall(this[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));
}
})