You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
333 lines
9.8 KiB
333 lines
9.8 KiB
2 years ago
|
/*
|
||
|
DynAPI Distribution
|
||
|
IOElement SODA add-on
|
||
|
|
||
|
The DynAPI Distribution is distributed under the terms of the GNU LGPL license.
|
||
|
|
||
|
requires: Math, IOElement
|
||
|
*/
|
||
|
|
||
|
IOElementSoda={}; // used by dynapi.library
|
||
|
IOElement.SODA=true;
|
||
|
|
||
|
var p=IOElement.prototype;
|
||
|
|
||
|
p.createWebService = function(name,url,fn,useSync,uid,pwd,method){
|
||
|
var o,IOE=IOElement;
|
||
|
if(typeof(fn)!='function') {
|
||
|
alert('Missing or invalid Callback Function');
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
useSync=(IOElement.SYNC)? useSync:false;
|
||
|
o=this[name]={};
|
||
|
method=(method+'').toLowerCase();
|
||
|
o.sid=dynapi.functions.getGUID();
|
||
|
o._callback=fn;
|
||
|
o._name=name;
|
||
|
o._useSync=useSync;
|
||
|
o._method=(method=='post'||method=='get')? method:'post';
|
||
|
o._src=this; o._url=url; o._uid=uid; o._pwd=pwd;
|
||
|
o._iSysCall=IOE.ws_iSysCall;
|
||
|
o._iSysManager=IOE.ws_iSysManager;
|
||
|
o._iSysConnect=IOE.ws_iSysConnect;
|
||
|
|
||
|
o.isConnected=false;
|
||
|
o.call=IOE.ws_callSrv;
|
||
|
o.getWebName=IOE.ws_getWebName;
|
||
|
o.getWebComment=IOE.ws_getWebComment;
|
||
|
o.importWebMethods=IOE.ws_importWebMethods;
|
||
|
|
||
|
if(!useSync || (useSync && this.isSync)) o._iSysManager("connect");
|
||
|
else this.activateSyncMode(this+'.'+name+'._iSysManager("connect")');
|
||
|
};
|
||
|
p.disconnectWebService = function(name,fn){
|
||
|
var o=this[name];
|
||
|
if(o && o._src==this && o.isConnected==true){
|
||
|
o._callback=fn;
|
||
|
o._iSysManager("disconnect");
|
||
|
};
|
||
|
};
|
||
|
p.getResponse = function(){
|
||
|
var cargo=this.getCargo(true);
|
||
|
var retry=(this._retryID==this._cargoID)?true:false;
|
||
|
var response=IOElement.ws_SODAParser(this.getVariable('wsSODAResponse'));
|
||
|
if(retry) response.error={code:0,text:'Request Timeout'};
|
||
|
if(response.error) this._retryID=this._cargoID;
|
||
|
if(cargo) response.serviceName=cargo.DynAPIWSName;
|
||
|
return response;
|
||
|
};
|
||
|
|
||
|
// WS Object Functions
|
||
|
IOElement.wsError='Error occurred while parsing SODA Envelope';
|
||
|
IOElement.ws_iSysManager = function(sys){
|
||
|
var s,r;
|
||
|
|
||
|
this.isSync = (this._useSync && this._src.isSync)? true:false;;
|
||
|
|
||
|
if(sys=='connect') mn='SYS:WebServiceConnect';
|
||
|
else if(sys=='disconnect') mn='SYS:WebServiceDisconnect';
|
||
|
|
||
|
if(this.isSync) {
|
||
|
// use sync login/logout
|
||
|
r=this._iSysCall(mn);
|
||
|
o=r.value;
|
||
|
if(o && typeof(o)=='object' && o.SYSCall==true) {
|
||
|
o.error=r.error;
|
||
|
r=o;s=true;
|
||
|
};
|
||
|
this._iSysConnect(r,s);
|
||
|
}else {
|
||
|
// use async login/logout
|
||
|
var cargo={wsObject:this,DynAPIWSName:this._name}
|
||
|
this._iSysCall(mn,null,this._iSysConnect,cargo);
|
||
|
}
|
||
|
};
|
||
|
IOElement.ws_iSysConnect = function(e,s){
|
||
|
var o,r,c,ws,et;
|
||
|
|
||
|
if(!e||(e && e.constructor!=DynEvent)) {
|
||
|
// sync
|
||
|
o=ws=this;
|
||
|
if(!e.error) c=e;
|
||
|
else if(e.error) et= ((e.error.code)? e.error.code+':':'')+e.error.text;
|
||
|
else if(!s) et='Connection Failed';
|
||
|
}else{
|
||
|
// async
|
||
|
o=e.getSource();
|
||
|
r=o.getResponse();
|
||
|
c=o.getCargo(!s||!r.value);
|
||
|
o=ws=c.wsObject;
|
||
|
c=r.value;
|
||
|
if(r.error) et=r.error.text;
|
||
|
}
|
||
|
o.isConnected=false;
|
||
|
if(!et && c && (c.logout||c.login)=='failed') et='Login failed';
|
||
|
s=(!et && c && (c.logout||c.login)=='ok')? true:false; // web service must return a login/logout state
|
||
|
if(s && c.logout) {
|
||
|
delete o._src[o._name];
|
||
|
o.call=dynapi.functions.Null;
|
||
|
}else if(s && c.login){
|
||
|
o._iWSName = c.name;
|
||
|
o._iWSComment = c.comment;
|
||
|
o._iWSMethodNames = (c.methodNames)? c.methodNames:'';
|
||
|
o.isConnected=s;
|
||
|
}
|
||
|
if (o._callback) o._callback(ws,s,et);
|
||
|
};
|
||
|
|
||
|
IOElement.ws_iSysCall=function(name,params,fn,cargo){ // used to make async/sync system call to the service
|
||
|
var r,o,data={};
|
||
|
if(this.isSync) fn=false;
|
||
|
data.IOResponse=(fn)? 'text/html':'text/xml';
|
||
|
data.IOEnvelope=IOElement.ws_createSODAEnvelope(name,params,null,null,this.sid,this._uid,this._pwd);
|
||
|
if(this._method=='get') r=this._src.get(this._url,data,fn,cargo);
|
||
|
else r=this._src.post(this._url,data,fn,cargo);
|
||
|
if(this.isSync) {
|
||
|
// convert SODA text returned from get() or post() into response object
|
||
|
if(!r.error) r=IOElement.ws_SODAParser(r.value);
|
||
|
}
|
||
|
return r;
|
||
|
};
|
||
|
|
||
|
IOElement.ws_callSrv=function(name,params,fn,cargo){
|
||
|
var rt,data={IOResponse:'text/html'},cargo=(cargo)? cargo:{};
|
||
|
var mod=this._method;
|
||
|
var sync=(fn==false && this.isSync);
|
||
|
if(typeof(name)!='string'){
|
||
|
var i,o=name;
|
||
|
var na=[],pa=[];
|
||
|
for(i in o){
|
||
|
na[na.length]=i;
|
||
|
pa[pa.length]=o[i];
|
||
|
}
|
||
|
name=na.join(',');
|
||
|
params=pa;
|
||
|
}
|
||
|
if(typeof(params)!='object'||params==null) params=[params];
|
||
|
else if((params.constructor+'')!= (Array+'')) params=[params];
|
||
|
IOElement.ws_setStringEncFormat('xml');
|
||
|
cargo.DynAPIWSName=this._name;
|
||
|
data.IOEnvelope=IOElement.ws_createSODAEnvelope(name,params,null,null,this.sid);
|
||
|
if(sync) data.IOResponse = 'text/xml'; // Returned Content Format
|
||
|
if (mod=='get') rt=this._src.get(this._url,data,fn,cargo);
|
||
|
else rt=this._src.post(this._url,data,fn,cargo);
|
||
|
if(sync) {
|
||
|
// convert SODA text returned from get() or post() into response object
|
||
|
if(!rt.error) rt = IOElement.ws_SODAParser(rt.value);
|
||
|
rt.serviceName=this._name;
|
||
|
}
|
||
|
return rt;
|
||
|
};
|
||
|
IOElement.ws_createSODAEnvelope = function(method,body,ecode,etext,sid,uid,pwd){
|
||
|
return '<envelope>'
|
||
|
+((sid)? '<sid>'+ sid +'</sid>':'')
|
||
|
+((ecode||etext)? '<err>'+ IOElement.ws_SODAStringEncode(ecode+'|'+etext) +'</err>':'')
|
||
|
+((uid)? '<uid>'+uid+'</uid>':'')
|
||
|
+((pwd)? '<pwd>'+pwd+'</pwd>':'')
|
||
|
+'<method>'+ IOElement.ws_SODAStringEncode(method) +'</method>'
|
||
|
+'<body>'+ IOElement.ws_Var2SODA(body) +'</body>'
|
||
|
+'</envelope>';
|
||
|
};
|
||
|
IOElement.ws_getWebName= function(){
|
||
|
return this._iWSName;
|
||
|
};
|
||
|
IOElement.ws_getWebComment= function(){
|
||
|
return this._iWSComment;
|
||
|
};
|
||
|
IOElement.ws_importWebMethods = function(){
|
||
|
if(!this.isSync) return false;
|
||
|
var fn,rt=this._iWSMethodNames;
|
||
|
if(rt) {
|
||
|
rt=rt.split(',');
|
||
|
for(var i=0;i<rt.length;i++){
|
||
|
fn=rt[i];
|
||
|
s = 'var mthd="'+fn+'";'
|
||
|
+'var i,params=(arguments.length)?[]:null;'
|
||
|
+'for(i=0;i<arguments.length;i++){params[i]=arguments[i]};'
|
||
|
+'return this.call(mthd,params,false);';
|
||
|
this[fn]=new Function('',s);
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
// SODA Internal Data types: U=undefined/null, I=integer, F=float, B=boolean, D=date/time, S=string, A=array, O=Object (Associative Array)
|
||
|
IOElement._strEncFormat='xml'; // String Encode Format: html or xml
|
||
|
IOElement.ws_Var2SODA=function(v,lvl){
|
||
|
var ot,ct,i,c,data,vtype=typeof(v);
|
||
|
|
||
|
if (lvl>=0) lvl++;
|
||
|
else lvl=0;
|
||
|
|
||
|
if(vtype=="number") {
|
||
|
if((v+'').indexOf('.')>=0) data='<f'+lvl+'>'+v+'</f'+lvl+'>';
|
||
|
else data='<i'+lvl+'>'+v+'</i'+lvl+'>';
|
||
|
}else if(vtype=="boolean") {
|
||
|
if(v==true) data='<b'+lvl+'>true</b'+lvl+'>';
|
||
|
else data='<b'+lvl+'>false</b'+lvl+'>';
|
||
|
}else if(vtype=="string") {
|
||
|
data='<s'+lvl+'>'+this.ws_SODAStringEncode(v)+'</s'+lvl+'>';
|
||
|
}else if(vtype=="object" && v!=null) {
|
||
|
if((v.constructor+'')==(Array+'')){
|
||
|
data='<a'+lvl+'>';
|
||
|
for (i=0;i<v.length;i++){
|
||
|
data+=(i>0)? '<r'+lvl+'/>'+this.ws_Var2SODA(v[i],lvl):this.ws_Var2SODA(v[i],lvl);
|
||
|
}
|
||
|
data+='</a'+lvl+'>';
|
||
|
}else if((v.constructor+'')==(Date+'')){
|
||
|
//Date format: mm/dd/yyyy hh:nn:ss
|
||
|
v=((v.getMonth()+1)+'/'+v.getDate()+'/'+v.getFullYear()+' '+v.getHours()+':'+v.getMinutes()+':'+v.getSeconds());
|
||
|
data='<d'+lvl+'>'+v+'</d'+lvl+'>';
|
||
|
}else {
|
||
|
var keys=[],values=[];
|
||
|
for(var key in v){
|
||
|
values[values.length]=v[key];
|
||
|
if (key.indexOf('|')>=0) key=key.replace(/\|/g,'&s;');
|
||
|
keys[keys.length]=key;
|
||
|
}
|
||
|
v=[keys.join('|'),values];
|
||
|
data='<o'+lvl+'>'+this.ws_Var2SODA(v,lvl)+'</o'+lvl+'>';
|
||
|
};
|
||
|
}else data='<u'+lvl+'>0</u'+lvl+'>';
|
||
|
if (lvl==0) data='<soda>'+data+'</soda>';
|
||
|
return data;
|
||
|
};
|
||
|
IOElement.ws_SODA2Var=function(t,lvl){
|
||
|
var i,tag,data,elms;
|
||
|
var tagType,tagIndex;
|
||
|
|
||
|
if (lvl>=0)lvl++;
|
||
|
else lvl=0;
|
||
|
|
||
|
if(lvl==0) {
|
||
|
if((t+'').substr(0,6)!='<soda>') return t;
|
||
|
tag=IOElement.ws_getSODATag(t,'soda');
|
||
|
t=tag.content;
|
||
|
}
|
||
|
|
||
|
tag=this.ws_getSODATag(t);
|
||
|
tagType=tag.name.substr(0,1);
|
||
|
tagIndex=tag.name.substr(1);
|
||
|
if(tagType=='i') data=parseInt(tag.content);
|
||
|
else if(tagType=='f') data=parseFloat(tag.content);
|
||
|
else if(tagType=='b') data=(tag.content=='true')?true:false;
|
||
|
else if(tagType=='s') data=IOElement.ws_SODAStringDecode(tag.content+'');
|
||
|
else if(tagType=='d') data= new Date(tag.content);
|
||
|
else if(tagType=='a') {
|
||
|
data=[];
|
||
|
if(tag.content){
|
||
|
elms=tag.content.split('<r'+tagIndex+'/>');
|
||
|
for (i=0;i<elms.length;i++){
|
||
|
data[i]=this.ws_SODA2Var(elms[i],lvl);
|
||
|
}
|
||
|
}
|
||
|
}else if(tagType=='o') {
|
||
|
data={};
|
||
|
elms=this.ws_SODA2Var(tag.content,lvl);
|
||
|
if(!elms) elms=[];
|
||
|
var key,keys=(elms[0]+'').split('|');
|
||
|
var values=elms[1];
|
||
|
for (i=0;i<keys.length;i++) {
|
||
|
key=keys[i];
|
||
|
if(key.indexOf('&s;')>=0) key=key.replace(/\&s\;/g,'|');
|
||
|
data[key]=values[i];
|
||
|
}
|
||
|
}else if(tagType=='u') data=null;
|
||
|
return data;
|
||
|
};
|
||
|
IOElement.ws_SODAStringEncode=function (text){
|
||
|
if (!text) return '';
|
||
|
// encode string for use with html/javascript
|
||
|
if(this._strEncFormat=='html'){
|
||
|
text=text.replace(/\\/g,"\\\\"); // \ -> \\
|
||
|
text=text.replace(/\'/g,"\\'"); // ' -> \' "
|
||
|
text=text.replace(/\n/g,"\\n");
|
||
|
text=text.replace(/\r/g,"\\r");
|
||
|
}
|
||
|
// encode string for use with xml/html
|
||
|
text=text.replace(/\&/g,"&");
|
||
|
text=text.replace(/</g,"<");
|
||
|
text=text.replace(/>/g,">");
|
||
|
return text;
|
||
|
};
|
||
|
IOElement.ws_SODAStringDecode=function (text){
|
||
|
if (!text) return '';
|
||
|
text=text.replace(/\&\;/g,"&");
|
||
|
text=text.replace(/\<\;/g,"<");
|
||
|
text=text.replace(/\>\;/g,">");
|
||
|
return text;
|
||
|
};
|
||
|
IOElement.ws_setStringEncFormat = function(t){
|
||
|
this._strEncFormat=(t=='xml')? 'xml':'html';
|
||
|
};
|
||
|
IOElement.ws_getSODATag=function(t,n){
|
||
|
var st,et,tag,con;
|
||
|
if(!t) return {};
|
||
|
n=(n)?n:'';
|
||
|
st=t.indexOf('<'+n);
|
||
|
et=t.indexOf('>',st);
|
||
|
if(st || et) {
|
||
|
tag=t.substr(st+1,(et-1)-st);
|
||
|
st=et+1;
|
||
|
et=t.indexOf('</'+tag+'>');
|
||
|
con=t.substr(st,et-st);
|
||
|
|
||
|
}
|
||
|
return {name:tag,content:con};
|
||
|
};
|
||
|
IOElement.ws_SODAParser=function(envelope){
|
||
|
var r={
|
||
|
error:IOElement.ws_SODAStringDecode(IOElement.ws_getSODATag(envelope,'err').content),
|
||
|
methodName:IOElement.ws_SODAStringDecode(IOElement.ws_getSODATag(envelope,'method').content),
|
||
|
value:IOElement.ws_SODA2Var(IOElement.ws_getSODATag(envelope,'body').content)
|
||
|
};
|
||
|
if(r.error) {
|
||
|
var ea=r.error.split('|');
|
||
|
r.error={code:ea[0],text:ea[1]};
|
||
|
}else if((envelope+'').indexOf('<envelope>')!=0){
|
||
|
r.error={code:'E3',text:IOElement.wsError+':\n\n'+envelope};
|
||
|
};
|
||
|
return r;
|
||
|
};
|