123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605 |
- // Fix an IE problem (another one)
- var HAS_ACTIVEX = false;
- try {
- new ActiveXObject('MSXML2.DOMDocument');
- HAS_ACTIVEX = true;
- } catch(e) {}
- /**
- * XML-RPC communication service.
- */
- angular.module('xml-rpc', [])
- .factory('js2xml', ['helperXmlRpc', function(helperXmlRpc){
- /**
- * Convert Null to XmlRpc valid value (as xml element)
- */
- function null2xml_(doc, input) {
- return helperXmlRpc.createNode(doc, 'nil');
- };
- var js2xmlMethod_ = {};
- /**
- * Convert a string to a valid xmlrpc value (as xml element).
- */
- function string2xml_(doc, input) {
- return helperXmlRpc.createNode(doc, 'string', input);
- };
- js2xmlMethod_['string'] = string2xml_;
- /**
- * Convert a number to a valid xmlrpc value (as xml element).
- */
- function number2xml_(doc, input) {
- var type = 'int',
- value = parseInt(input),
- f = parseFloat(input);
- if (value != f) {
- type = 'double';
- value = f;
- }
- return helperXmlRpc.createNode(doc, type, value.toString());
- };
- js2xmlMethod_['number'] = number2xml_;
-
- /**
- * Convert a boolean to a valid xmlrpc value (as xml element).
- */
- function boolean2xml_(doc, input) {
- return helperXmlRpc.createNode(doc, 'boolean', (input ? '1' : '0'));
- };
- js2xmlMethod_['boolean'] = boolean2xml_;
-
- /**
- * Convert an Array object to a valid xmlrpc value (as xml element).
- */
- function array2xml_(doc, input) {
- var elements = [];
- for (var i=0; i < input.length; i++) {
- elements.push(js2xml_(doc, input[i]));
- }
- return helperXmlRpc.createNode(doc, 'array',
- helperXmlRpc.createNode(doc, 'data', elements)
- );
- };
- /**
- * Convert an object to a valid xmlrpc value (as xml element).
- */
- function struct2xml_(doc, input) {
- var elements = [];
- for (var name in input) {
- elements.push(helperXmlRpc.createNode(doc, 'member',
- helperXmlRpc.createNode(doc, 'name', name),
- js2xml_(doc, input[name])
- ));
- }
- return helperXmlRpc.createNode(doc, 'struct', elements);
- };
- /**
- * Convert a DateTime object to a valid xmlrpc value (as xml element).
- */
- function date2xml_(doc, input) {
- var str = [
- input.getFullYear(),
- (input.getMonth() + 1 < 10)? '0' + (input.getMonth() + 1):input.getMonth() + 1,
- (input.getDate() < 10)? '0' + (input.getDate()):input.getDate(),
- 'T',
- (input.getHours() < 10)? '0' + (input.getHours()):input.getHours(), ':',
- (input.getMinutes() < 10)? '0' + (input.getMinutes()):input.getMinutes(), ':',
- (input.getSeconds() < 10)? '0' + (input.getSeconds()):input.getSeconds(),
- ];
- return helperXmlRpc.createNode(doc, 'dateTime.iso8601', str.join(''));
- };
- /**
- * Convert an object to a valid xmlrpc value (as xml element).
- */
- function object2xml_(doc, input) {
- if (input instanceof Date) {
- return date2xml_(doc, input);
- }
- //else
- if (input instanceof Array)
- return array2xml_(doc, input);
- //else
- return struct2xml_(doc, input);
- };
- js2xmlMethod_['object'] = object2xml_;
- /**
- * Converts a javascript object to a valid xmlrpc value (as xml element).
- */
- function js2xml_(doc, input) {
- var type = typeof(input);
- var method = js2xmlMethod_[type];
- if (input === null) {
- method = null2xml_;
- } else if (method == undefined) {
- method = string2xml_;
- }
- return helperXmlRpc.createNode(doc, 'value', method(doc, input));
- };
- return {
- js2xml:js2xml_
- };
- }])
- .factory('xml2js', ['helperXmlRpc', function(helperXmlRpc){
- var isTrue_ = {
- '1': true,
- 'true': true
- };
- var xml2jsMethod_ = {};
- /**
- * Convert an xmlrpc string value (as an xml tree) to a javascript string.
- */
- function xml2null_(input) {
- return null;
- };
- xml2jsMethod_['nil'] = xml2null_;
-
- /**
- * Convert an xmlrpc string value (as an xml tree) to a javascript string.
- *
- * @param {!Element} input Xmlrpc string to convert.
- * @return {string} Javascript conversion of input.
- * @protected
- */
- function xml2string_(input) {
- var buf = [];
- helperXmlRpc.getTextContent(input, buf, false);
- return buf.join('');
- };
- xml2jsMethod_['string'] = xml2string_;
- /**
- * Convert an xmlrpc number (int or double) value to a javascript number.
- */
- function xml2number_(input) {
- return parseFloat(helperXmlRpc.getTextContent(input, []));
- };
- xml2jsMethod_['int'] = xml2number_;
- xml2jsMethod_['i4'] = xml2number_;
- xml2jsMethod_['double'] = xml2number_;
-
- /**
- * Convert an xmlrpc boolean value to a javascript boolean.
- */
- function xml2boolean_(input) {
- var value = helperXmlRpc.getTextContent(input, []).toLowerCase();
- return isTrue_[value] || false;
- };
- xml2jsMethod_['boolean'] = xml2boolean_;
- /**
- * Convert an xmlrpc struct value to a javascript object.
- */
- function xml2struct_(input) {
- var memberNodes = helperXmlRpc.selectNodes(input, 'member') || [];
- var obj = {};
- for (var i=0; i < memberNodes.length; i++) {
- var node = helperXmlRpc.selectSingleNode(memberNodes[i], 'name');
- // If no name found, member is ignored
- if (node) {
- var label = helperXmlRpc.getTextContent(node, []);
- node = helperXmlRpc.selectSingleNode(memberNodes[i], 'value');
- obj[label] = xml2js_(node);
- }
- }
- return obj;
- };
- xml2jsMethod_['struct'] = xml2struct_;
- /**
- * Convert an xmlrpc array value to a javascript array.
- */
- function xml2array_(input) {
- var valueNodes = helperXmlRpc.selectNodes(input, 'data/value');
- if (!valueNodes.length) {
- valueNodes = helperXmlRpc.selectNodes(input, './value');
- }
- if (!valueNodes.length)
- return [];
- //else
- var map_ = (Array.prototype.map) ?
- function(arr, f, opt_obj) {
- return Array.prototype.map.call(arr, f, opt_obj);
- } :
- function(arr, f, opt_obj) {
- var l = arr.length; // must be fixed during loop... see docs
- var res = new Array(l);
- var arr2 = (typeof arr == 'string') ? arr.split('') : arr;
- for (var i = 0; i < l; i++) {
- if (i in arr2) {
- res[i] = f.call(opt_obj, arr2[i], i, arr);
- }
- }
- return res;
- };
- return map_(valueNodes, xml2js_);
- };
- xml2jsMethod_['array'] = xml2array_;
- /**
- * Convert an xmlrpc dateTime value to an itrust.date.DateTime.
- */
- function xml2datetime_(input) {
- var value = helperXmlRpc.getTextContent(input, []);
- if (!value) {
- return new Date();
- }
- if (value[value.length-1]=='T') {
- value = value.substring(0, value.length-1);
- }
- var parts = value.match(/\d+/g);
- if(value.indexOf('-') == -1){
- var toSplit = parts[0];
- parts[0] = toSplit.substring(0,4);
- parts.splice(1, 0, toSplit.substring(4,6));
- parts.splice(2, 0, toSplit.substring(6));
- }
- return new Date(parts[0], parts[1] - 1, parts[2], parts[3], parts[4], parts[5]);
- };
- xml2jsMethod_['datetime'] = xml2datetime_;
- xml2jsMethod_['datetime.iso8601'] = xml2datetime_;
-
- /**
- * Convert an xmlrpc value (as an xml tree) to a javascript object.
- */
- function xml2js_(input) {
- var elt = helperXmlRpc.selectSingleNode(input, './*');
- if (!elt)
- return null;
- //else
- var method = xml2jsMethod_[elt.nodeName.toLowerCase()];
- if (method == undefined) {
- method = xml2struct_;
- }
- return method(elt);
- };
- return {
- xml2js:xml2js_,
- };
- }])
- .factory('xmlrpc', ['$http', 'helperXmlRpc', 'js2xml', 'xml2js', function($http, helperXmlRpc, js2xml, xml2js){
- var configuration = {};
- /**
- * Serialize a XML document to string.
- */
- function serialize(xml){
- var text = xml.xml;
- if (text) {
- return text;
- }
- if (typeof XMLSerializer != 'undefined') {
- return new XMLSerializer().serializeToString(xml);
- }
- throw Error('Your browser does not support serializing XML documents');
- };
- /**
- * Creates a xmlrpc call of the given method with given params.
- */
- function createCall(method, params){
- var doc = helperXmlRpc.createDocument('methodCall');
- doc.firstChild.appendChild(
- helperXmlRpc.createNode(doc, 'methodName', method)
- );
- if (arguments.length > 2) {
- params = helperXmlRpc.cloneArray(arguments);
- params.shift();
- }
- if (params && params.length > 0) {
- var paramsNode = helperXmlRpc.createNode(doc, 'params');
- for (var i=0; i < params.length; i++) {
- paramsNode.appendChild(helperXmlRpc.createNode(doc, 'param',
- js2xml.js2xml(doc, params[i])
- ));
- }
- doc.firstChild.appendChild(paramsNode);
- }
- return (serialize(doc)).replace(/[\s\xa0]+$/, '');
- };
- // Use the promise system from angular.
- // This method return a promise with the response
- function callMethod(method, params){
- var xmlstr = createCall(method, params);
- var targetAddr = configuration.hostName + "" + configuration.pathName;
- return $http.post(targetAddr, xmlstr, {headers: {'Content-Type': 'text/xml'}})
- .then(function(responseFromServer) {
- var responseText = responseFromServer.data;
- var response = null;
- try {
- response = parseResponse(responseText);
- } catch (err) {
- response = err;
- }
- return response;
- }, function(responseFromServer){
- if(responseFromServer.status in configuration){
- if(typeof configuration[responseFromServer.status] == "function"){
- return configuration[responseFromServer.status].call();
- }
- }
- });
- };
- /**
- * Parse an xmlrpc response and return the js object.
- */
- function parseResponse(response){
- var doc = helperXmlRpc.loadXml(response);
- var rootNode = doc.firstChild;
- if (!rootNode)
- return undefined;
- //else
- var node = helperXmlRpc.selectSingleNode(rootNode, '//fault');
- var isFault = (node != undefined);
- node = helperXmlRpc.selectSingleNode(rootNode, '//value');
- var value = xml2js.xml2js(node);
- if (isFault) {
- throw value;
- }
- //else
- return value;
- };
- /**
- * Configure the service (Host name and service path).
- * Actually, 401, 404 and 500 server errors are originally defined, but any error code can be added
- */
- function config(conf) {
- angular.extend(configuration, {
- hostName:"",
- pathName:"/rpc2",
- 500:function(){},
- 401:function(){},
- 404:function(){}
- }, conf);
- };
- config();
- return {
- callMethod : callMethod,
- config : config
- };
- }])
- .factory('helperXmlRpc', function(){
- /**
- * Clones an array object
- */
- function cloneArray_(object){
- var length = object.length;
- if (length > 0) {
- var rv = new Array(length);
- for (var i = 0; i < length; i++) {
- rv[i] = object[i];
- }
- return rv;
- }
- return [];
- };
-
- /**
- * Creates a XML document for IEs browsers
- */
- function createMsXmlDocument_(){
- var doc = new ActiveXObject('MSXML2.DOMDocument');
- if (doc) {
- doc.resolveExternals = false;
- doc.validateOnParse = false;
- try {
- doc.setProperty('ProhibitDTD', true);
- doc.setProperty('MaxXMLSize', 2 * 1024);
- doc.setProperty('MaxElementDepth', 256);
- } catch (e) {
- // No-op.
- }
- }
- return doc;
- };
-
- /**
- * Creates a XML document
- */
- function createDocument(opt_rootTagName, opt_namespaceUri){
- if (opt_namespaceUri && !opt_rootTagName) {
- throw Error("Can't create document with namespace and no root tag");
- }
- if (HAS_ACTIVEX) {
- var doc = createMsXmlDocument_();
- if (doc) {
- if (opt_rootTagName) {
- doc.appendChild(doc.createNode(1,
- opt_rootTagName,
- opt_namespaceUri || ''));
- }
- return doc;
- }
- }
- else if (document.implementation && document.implementation.createDocument) {
- return document.implementation.createDocument(opt_namespaceUri || '',
- opt_rootTagName || '',
- null);
- }
- throw Error('Your browser does not support creating new documents');
- };
-
- /**
- * Creates a XML node and set the child(ren) node(s)
- */
- function createNode(doc, nodeName, children){
- var elt = doc.createElement(nodeName);
- var appendChild = function(child) {
- if(typeof child == 'object' && child.nodeType !== 1){
- for(var i in child){
- elt.appendChild(
- (typeof child == 'string') ? doc.createTextNode(child[i]) : child[i]
- );
- }
- } else {
- elt.appendChild(
- (typeof child == 'string') ? doc.createTextNode(child) : child
- );
- }
- }
- if (arguments.length > 3) {
- children = cloneArray_(arguments);
- children.shift(); //shift doc
- children.shift(); //shift nodeName
- }
- if (typeof children == 'array') {
- angular.forEach(children, appendChild);
- } else if (children) {
- appendChild(children);
- }
- return elt;
- };
- /**
- * Generate an ID for XMLRPC request
- */
- function generateId(){
- return 'xmlrpc-'+(new Date().getTime())+'-'+Math.floor(Math.random()*1000);
- };
-
- /**
- * Creates an XML document from a string
- */
- function loadXml_(xml) {
- if (HAS_ACTIVEX) {
- var doc = createMsXmlDocument_();
- doc.loadXML(xml);
- return doc;
- }
- else if (typeof DOMParser != 'undefined') {
- return new DOMParser().parseFromString(xml, 'application/xml');
- }
- throw Error('Your browser does not support loading xml documents');
- };
- /**
- * Returns the document in which the node is.
- */
- function getOwnerDocument_(node) {
- return (
- node.nodeType == 9 ? node :
- node.ownerDocument || node.document);
- };
-
- /**
- * Return a single node with the given name in the given node
- */
- function selectSingleNode_(node, path) {
- if (typeof node.selectSingleNode != 'undefined') {
- var doc = getOwnerDocument_(node);
- if (typeof doc.setProperty != 'undefined') {
- doc.setProperty('SelectionLanguage', 'XPath');
- }
- return node.selectSingleNode(path);
- } else if (document.implementation.hasFeature('XPath', '3.0')) {
- var doc = getOwnerDocument_(node);
- var resolver = doc.createNSResolver(doc.documentElement);
- var result = doc.evaluate(path, node, resolver,
- XPathResult.FIRST_ORDERED_NODE_TYPE, null);
- return result.singleNodeValue;
- }
- return null;
- };
- /**
- * Returns the string content of a node
- */
- function getTextContent_(node, buf, normalizedWhitespace){
- var PREDEFINED_TAG_VALUES_ = {'IMG': ' ', 'BR': '\n'};
- if (node.nodeName in ['SCRIPT', 'STYLE', 'HEAD', 'IFRAME', 'OBJECT']) {
- // ignore certain tags
- } else if (node.nodeType == 3) {
- if (normalizedWhitespace) {
- buf.push(String(node.nodeValue).replace(/(\r\n|\r|\n)/g, ''));
- } else {
-
- buf.push(node.nodeValue);
- }
- } else if (node.nodeName in PREDEFINED_TAG_VALUES_) {
- buf.push(PREDEFINED_TAG_VALUES_[node.nodeName]);
- } else {
- var child = node.firstChild;
- while (child) {
- getTextContent_(child, buf, normalizedWhitespace);
- child = child.nextSibling;
- }
- }
- return buf.join('');
- };
- /**
- * Returns all the nodes in a array that are inside the given node with the given path
- */
- function selectNodes_(node, path) {
- if (typeof node.selectNodes != 'undefined') {
- var doc = getOwnerDocument_(node);
- if (typeof doc.setProperty != 'undefined') {
- doc.setProperty('SelectionLanguage', 'XPath');
- }
- return node.selectNodes(path);
- } else if (document.implementation.hasFeature('XPath', '3.0')) {
- var doc = getOwnerDocument_(node);
- var resolver = doc.createNSResolver(doc.documentElement);
- var nodes = doc.evaluate(path, node, resolver,
- XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
- var results = [];
- var count = nodes.snapshotLength;
- for (var i = 0; i < count; i++) {
- results.push(nodes.snapshotItem(i));
- }
- return results;
- } else {
- return [];
- }
- };
- return {
- cloneArray:cloneArray_,
- createDocument: createDocument,
- createNode: createNode,
- generateId: generateId,
- loadXml: loadXml_,
- getOwnerDocument:getOwnerDocument_,
- selectNodes: selectNodes_,
- getTextContent : getTextContent_,
- selectSingleNode: selectSingleNode_
- };
- });
|