Created
August 10, 2020 10:10
-
-
Save kohav/54b7dcf606e0347491ddab6452e330d9 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function SOAPClientParameters() | |
{ | |
var _pl = new Array(); | |
this.add = function(name, value) | |
{ | |
_pl[name] = value; | |
return this; | |
} | |
this.toXml = function() | |
{ | |
var xml = ""; | |
for(var p in _pl) | |
xml += "<" + p + ">" + SOAPClientParameters._serialize(_pl[p]) + "</" + p + ">"; | |
return xml; | |
} | |
} | |
SOAPClientParameters._serialize = function(o) | |
{ | |
var s = ""; | |
switch(typeof(o)) | |
{ | |
case "string": | |
s += o.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">"); break; | |
case "number": | |
case "boolean": | |
s += o.toString(); break; | |
case "object": | |
// Date | |
if(o.constructor.toString().indexOf("function Date()") > -1) | |
{ | |
var year = o.getFullYear().toString(); | |
var month = (o.getMonth() + 1).toString(); month = (month.length == 1) ? "0" + month : month; | |
var date = o.getDate().toString(); date = (date.length == 1) ? "0" + date : date; | |
var hours = o.getHours().toString(); hours = (hours.length == 1) ? "0" + hours : hours; | |
var minutes = o.getMinutes().toString(); minutes = (minutes.length == 1) ? "0" + minutes : minutes; | |
var seconds = o.getSeconds().toString(); seconds = (seconds.length == 1) ? "0" + seconds : seconds; | |
var milliseconds = o.getMilliseconds().toString(); | |
var tzminutes = Math.abs(o.getTimezoneOffset()); | |
var tzhours = 0; | |
while(tzminutes >= 60) | |
{ | |
tzhours++; | |
tzminutes -= 60; | |
} | |
tzminutes = (tzminutes.toString().length == 1) ? "0" + tzminutes.toString() : tzminutes.toString(); | |
tzhours = (tzhours.toString().length == 1) ? "0" + tzhours.toString() : tzhours.toString(); | |
var timezone = ((o.getTimezoneOffset() < 0) ? "+" : "-") + tzhours + ":" + tzminutes; | |
s += year + "-" + month + "-" + date + "T" + hours + ":" + minutes + ":" + seconds + "." + milliseconds + timezone; | |
} | |
// Array | |
else if(o.constructor.toString().indexOf("function Array()") > -1) | |
{ | |
for(var p in o) | |
{ | |
if(!isNaN(p)) // linear array | |
{ | |
(/function\s+(\w*)\s*\(/ig).exec(o[p].constructor.toString()); | |
var type = RegExp.$1; | |
switch(type) | |
{ | |
case "": | |
type = typeof(o[p]); | |
case "String": | |
type = "string"; break; | |
case "Number": | |
type = "int"; break; | |
case "Boolean": | |
type = "bool"; break; | |
case "Date": | |
type = "DateTime"; break; | |
} | |
s += "<" + type + ">" + SOAPClientParameters._serialize(o[p]) + "</" + type + ">" | |
} | |
else // associative array | |
s += "<" + p + ">" + SOAPClientParameters._serialize(o[p]) + "</" + p + ">" | |
} | |
} | |
// Object or custom function | |
else | |
for(var p in o) | |
s += "<" + p + ">" + SOAPClientParameters._serialize(o[p]) + "</" + p + ">"; | |
break; | |
default: | |
throw new Error(500, "SOAPClientParameters: type '" + typeof(o) + "' is not supported"); | |
} | |
return s; | |
} | |
function SOAPClient() {} | |
SOAPClient.invoke = function(url, method, parameters, async, callback) | |
{ | |
if(async) | |
SOAPClient._loadWsdl(url, method, parameters, async, callback); | |
else | |
return SOAPClient._loadWsdl(url, method, parameters, async, callback); | |
} | |
// private: wsdl cache | |
SOAPClient_cacheWsdl = new Array(); | |
// private: invoke async | |
SOAPClient._loadWsdl = function(url, method, parameters, async, callback) | |
{ | |
// load from cache? | |
var wsdl = SOAPClient_cacheWsdl[url]; | |
if(wsdl + "" != "" && wsdl + "" != "undefined") | |
return SOAPClient._sendSoapRequest(url, method, parameters, async, callback, wsdl); | |
// get wsdl | |
var xmlHttp = SOAPClient._getXmlHttp(); | |
xmlHttp.open("GET", url + "?wsdl", async); | |
if(async) | |
{ | |
xmlHttp.onreadystatechange = function() | |
{ | |
if(xmlHttp.readyState == 4) | |
SOAPClient._onLoadWsdl(url, method, parameters, async, callback, xmlHttp); | |
} | |
} | |
xmlHttp.send(null); | |
if (!async) | |
return SOAPClient._onLoadWsdl(url, method, parameters, async, callback, xmlHttp); | |
} | |
SOAPClient._onLoadWsdl = function(url, method, parameters, async, callback, req) | |
{ | |
var wsdl = req.responseXML; | |
SOAPClient_cacheWsdl[url] = wsdl; // save a copy in cache | |
return SOAPClient._sendSoapRequest(url, method, parameters, async, callback, wsdl); | |
} | |
SOAPClient._sendSoapRequest = function(url, method, parameters, async, callback, wsdl) | |
{ | |
// get namespace | |
var ns = (wsdl.documentElement.attributes["targetNamespace"] + "" == "undefined") ? wsdl.documentElement.attributes.getNamedItem("targetNamespace").nodeValue : wsdl.documentElement.attributes["targetNamespace"].value; | |
// build SOAP request | |
var sr = | |
"<?xml version=\"1.0\" encoding=\"utf-8\"?>" + | |
"<soap:Envelope " + | |
"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " + | |
"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" " + | |
"xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">" + | |
"<soap:Body>" + | |
"<" + method + " xmlns=\"" + ns + "\">" + | |
parameters.toXml() + | |
"</" + method + "></soap:Body></soap:Envelope>"; | |
// send request | |
var xmlHttp = SOAPClient._getXmlHttp(); | |
xmlHttp.open("POST", url, async); | |
var soapaction = ((ns.lastIndexOf("/") != ns.length - 1) ? ns + "/" : ns) + method; | |
xmlHttp.setRequestHeader("SOAPAction", soapaction); | |
xmlHttp.setRequestHeader("Content-Type", "text/xml; charset=utf-8"); | |
if(async) | |
{ | |
xmlHttp.onreadystatechange = function() | |
{ | |
if(xmlHttp.readyState == 4) | |
SOAPClient._onSendSoapRequest(method, async, callback, wsdl, xmlHttp); | |
} | |
} | |
xmlHttp.send(sr); | |
if (!async) | |
return SOAPClient._onSendSoapRequest(method, async, callback, wsdl, xmlHttp); | |
} | |
SOAPClient._onSendSoapRequest = function(method, async, callback, wsdl, req) | |
{ | |
var o = null; | |
var nd = SOAPClient._getElementsByTagName(req.responseXML, method + "Result"); | |
if(nd.length == 0) | |
{ | |
if(req.responseXML.getElementsByTagName("faultcode").length > 0) | |
{ | |
if(async || callback) | |
o = new Error(500, req.responseXML.getElementsByTagName("faultstring")[0].childNodes[0].nodeValue); | |
else | |
throw new Error(500, req.responseXML.getElementsByTagName("faultstring")[0].childNodes[0].nodeValue); | |
} | |
} | |
else | |
o = SOAPClient._soapresult2object(nd[0], wsdl); | |
if(callback) | |
callback(o, req.responseXML); | |
if(!async) | |
return o; | |
} | |
SOAPClient._soapresult2object = function(node, wsdl) | |
{ | |
var wsdlTypes = SOAPClient._getTypesFromWsdl(wsdl); | |
return SOAPClient._node2object(node, wsdlTypes); | |
} | |
SOAPClient._node2object = function(node, wsdlTypes) | |
{ | |
// null node | |
if(node == null) | |
return null; | |
// text node | |
if(node.nodeType == 3 || node.nodeType == 4) | |
return SOAPClient._extractValue(node, wsdlTypes); | |
// leaf node | |
if (node.childNodes.length == 1 && (node.childNodes[0].nodeType == 3 || node.childNodes[0].nodeType == 4)) | |
return SOAPClient._node2object(node.childNodes[0], wsdlTypes); | |
var isarray = SOAPClient._getTypeFromWsdl(node.nodeName, wsdlTypes).toLowerCase().indexOf("arrayof") != -1; | |
// object node | |
if(!isarray) | |
{ | |
var obj = null; | |
if(node.hasChildNodes()) | |
obj = new Object(); | |
for(var i = 0; i < node.childNodes.length; i++) | |
{ | |
var p = SOAPClient._node2object(node.childNodes[i], wsdlTypes); | |
obj[node.childNodes[i].nodeName] = p; | |
} | |
return obj; | |
} | |
// list node | |
else | |
{ | |
// create node ref | |
var l = new Array(); | |
for(var i = 0; i < node.childNodes.length; i++) | |
l[l.length] = SOAPClient._node2object(node.childNodes[i], wsdlTypes); | |
return l; | |
} | |
return null; | |
} | |
SOAPClient._extractValue = function(node, wsdlTypes) | |
{ | |
var value = node.nodeValue; | |
switch(SOAPClient._getTypeFromWsdl(node.parentNode.nodeName, wsdlTypes).toLowerCase()) | |
{ | |
default: | |
case "s:string": | |
return (value != null) ? value + "" : ""; | |
case "s:boolean": | |
return value + "" == "true"; | |
case "s:int": | |
case "s:long": | |
return (value != null) ? parseInt(value + "", 10) : 0; | |
case "s:double": | |
return (value != null) ? parseFloat(value + "") : 0; | |
case "s:datetime": | |
if(value == null) | |
return null; | |
else | |
{ | |
value = value + ""; | |
value = value.substring(0, (value.lastIndexOf(".") == -1 ? value.length : value.lastIndexOf("."))); | |
value = value.replace(/T/gi," "); | |
value = value.replace(/-/gi,"/"); | |
var d = new Date(); | |
d.setTime(Date.parse(value)); | |
return d; | |
} | |
} | |
} | |
SOAPClient._getTypesFromWsdl = function(wsdl) | |
{ | |
var wsdlTypes = new Array(); | |
// IE | |
var ell = wsdl.getElementsByTagName("s:element"); | |
var useNamedItem = true; | |
// MOZ | |
if(ell.length == 0) | |
{ | |
ell = wsdl.getElementsByTagName("element"); | |
useNamedItem = false; | |
} | |
for(var i = 0; i < ell.length; i++) | |
{ | |
if(useNamedItem) | |
{ | |
if(ell[i].attributes.getNamedItem("name") != null && ell[i].attributes.getNamedItem("type") != null) | |
wsdlTypes[ell[i].attributes.getNamedItem("name").nodeValue] = ell[i].attributes.getNamedItem("type").nodeValue; | |
} | |
else | |
{ | |
if(ell[i].attributes["name"] != null && ell[i].attributes["type"] != null) | |
wsdlTypes[ell[i].attributes["name"].value] = ell[i].attributes["type"].value; | |
} | |
} | |
return wsdlTypes; | |
} | |
SOAPClient._getTypeFromWsdl = function(elementname, wsdlTypes) | |
{ | |
var type = wsdlTypes[elementname] + ""; | |
return (type == "undefined") ? "" : type; | |
} | |
// private: utils | |
SOAPClient._getElementsByTagName = function(document, tagName) | |
{ | |
try | |
{ | |
// trying to get node omitting any namespaces (latest versions of MSXML.XMLDocument) | |
return document.selectNodes(".//*[local-name()=\""+ tagName +"\"]"); | |
} | |
catch (ex) {} | |
// old XML parser support | |
return document.getElementsByTagName(tagName); | |
} | |
// private: xmlhttp factory | |
SOAPClient._getXmlHttp = function() | |
{ | |
try | |
{ | |
if(window.XMLHttpRequest) | |
{ | |
var req = new XMLHttpRequest(); | |
// some versions of Moz do not support the readyState property and the onreadystate event so we patch it! | |
if(req.readyState == null) | |
{ | |
req.readyState = 1; | |
req.addEventListener("load", | |
function() | |
{ | |
req.readyState = 4; | |
if(typeof req.onreadystatechange == "function") | |
req.onreadystatechange(); | |
}, | |
false); | |
} | |
return req; | |
} | |
if(window.ActiveXObject) | |
return new ActiveXObject(SOAPClient._getXmlHttpProgID()); | |
} | |
catch (ex) {} | |
throw new Error("Your browser does not support XmlHttp objects"); | |
} | |
SOAPClient._getXmlHttpProgID = function() | |
{ | |
if(SOAPClient._getXmlHttpProgID.progid) | |
return SOAPClient._getXmlHttpProgID.progid; | |
var progids = ["Msxml2.XMLHTTP.5.0", "Msxml2.XMLHTTP.4.0", "MSXML2.XMLHTTP.3.0", "MSXML2.XMLHTTP", "Microsoft.XMLHTTP"]; | |
var o; | |
for(var i = 0; i < progids.length; i++) | |
{ | |
try | |
{ | |
o = new ActiveXObject(progids[i]); | |
return SOAPClient._getXmlHttpProgID.progid = progids[i]; | |
} | |
catch (ex) {}; | |
} | |
throw new Error("Could not find an installed XML parser"); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment