📄 xmlrpc.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*/ /** 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 = "<struct>"; for(var attr in obj){ if(typeof obj[attr] != "function"){ s += "<member><name>" + attr + "</name><value>" + mod.marshall(obj[attr]) + "</value></member>"; } } s += "</struct>"; 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<node.childNodes.length;i++){ var child = node.childNodes.item(i); if (child.nodeType == 1){ switch (child.tagName){ case "fault": //a fault is thrown as an Exception throw parseFault(child); case "params": var params = parseParams(child); if(params.length == 1){//params should only have one param return params[0]; }else{ throw new mod.MalformedXmlRpc("'params' element inside 'methodResponse' must have exactly ONE 'param' child element.\nFound: " + params.length); } default: throw new mod.MalformedXmlRpc("'fault' or 'params' element expected.\nFound: '" + child.tagName + "'"); } } } //no child elements found throw new mod.MalformedXmlRpc("No child elements found."); }catch(e){ if(e instanceof mod.Fault){ throw e; }else{ throw new mod.MalformedXmlRpc("'methodResponse' element could not be parsed.",null,e); } } } /** Parses a methodCall element. @param node The methodCall element. @return Array [methodName,params]. */ var parseMethodCall = function(node){ try{ var methodName = null; var params = new Array();//default is no parameters for(var i=0;i<node.childNodes.length;i++){ var child = node.childNodes.item(i); if (child.nodeType == 1){ switch (child.tagName){ case "methodName": methodName = new String(child.firstChild.nodeValue); break; case "params": params = parseParams(child); break; default: throw new mod.MalformedXmlRpc("'methodName' or 'params' element expected.\nFound: '" + child.tagName + "'"); } } } if(methodName==null){ throw new mod.MalformedXmlRpc("'methodName' element expected."); }else{ return new Array(methodName, params); } }catch(e){ throw new mod.MalformedXmlRpc("'methodCall' element could not be parsed.",null,e); } } /** Parses a params element. @param node The params element. @return Array of params values. */ var parseParams = function(node){ try{ var params=new Array(); for(var i=0;i<node.childNodes.length;i++){ var child = node.childNodes.item(i); if (child.nodeType == 1){ switch (child.tagName){ case "param": params.push(parseParam(child)); break; default: throw new mod.MalformedXmlRpc("'param' element expected.\nFound: '" + child.tagName + "'"); } } } //the specs say a 'params' element can contain any number of 'param' elements. That includes 0 ?! return params; }catch(e){ throw new mod.MalformedXmlRpc("'params' element could not be parsed.",null,e); } } /** Parses a param element. @param node The param node. @return The value of the param. */ var parseParam = function(node){ try{ for(var i=0;i<node.childNodes.length;i++){ var child = node.childNodes.item(i); if (child.nodeType == 1){ switch (child.tagName){ case "value": return parseValue(child); default: throw new mod.MalformedXmlRpc("'value' element expected.\nFound: '" + child.tagName + "'"); } } } //no child elements found, that's an error throw new mod.MalformedXmlRpc("'value' element expected.But none found."); }catch(e){ throw new mod.MalformedXmlRpc("'param' element could not be parsed.",null,e); } } /** Parses a value element. @param node The value element. @return The value. */ var parseValue = function(node){ try{ for(var i=0;i<node.childNodes.length;i++){ var child = node.childNodes.item(i); if (child.nodeType == 1){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -