diff options
Diffstat (limited to 'includes/js/dojox/rpc/Service.js')
-rw-r--r-- | includes/js/dojox/rpc/Service.js | 293 |
1 files changed, 293 insertions, 0 deletions
diff --git a/includes/js/dojox/rpc/Service.js b/includes/js/dojox/rpc/Service.js new file mode 100644 index 0000000..438ee6f --- /dev/null +++ b/includes/js/dojox/rpc/Service.js @@ -0,0 +1,293 @@ +if(!dojo._hasResource["dojox.rpc.Service"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. +dojo._hasResource["dojox.rpc.Service"] = true; +dojo.provide("dojox.rpc.Service"); + +dojo.require("dojo.AdapterRegistry"); + +dojo.declare("dojox.rpc.Service", null, { + constructor: function(smd, options){ + //summary: + //Take a string as a url to retrieve an smd or an object that is an smd or partial smd to use + //as a definition for the service + // + // smd: object + // Takes a number of properties as kwArgs for defining the service. It also + // accepts a string. When passed a string, it is treated as a url from + // which it should synchronously retrieve an smd file. Otherwise it is a kwArgs + // object. It accepts serviceUrl, to manually define a url for the rpc service + // allowing the rpc system to be used without an smd definition. strictArgChecks + // forces the system to verify that the # of arguments provided in a call + // matches those defined in the smd. smdString allows a developer to pass + // a jsonString directly, which will be converted into an object or alternatively + // smdObject is accepts an smdObject directly. + // + var url; + var _this = this; + function processSmd(smd){ + smd._baseUrl = new dojo._Url(location.href,url || '.') + ''; + _this._smd = smd; + + //generate the methods + for(var serviceName in _this._smd.services){ + _this[serviceName]=_this._generateService(serviceName, _this._smd.services[serviceName]); + + } + } + if(smd){ + //if the arg is a string, we assume it is a url to retrieve an smd definition from + if( (dojo.isString(smd)) || (smd instanceof dojo._Url)){ + if (smd instanceof dojo._Url){ + url = smd + ""; + }else{ + url = smd; + } + + var text = dojo._getText(url); + if(!text){ + throw new Error("Unable to load SMD from " + smd) + }else{ + processSmd(dojo.fromJson(text)); + } + }else{ + processSmd(smd); + } + } + + if (options){this._options = options} + this._requestId=0; + }, + + _generateService: function(serviceName, method){ + if(this[method]){ + throw new Error("WARNING: "+ serviceName+ " already exists for service. Unable to generate function"); + } + method.name = serviceName; + var func = dojo.hitch(this, "_executeMethod",method); + var transport = dojox.rpc.transportRegistry.match(method.transport || this._smd.transport); + if (transport.getExecutor) + func = transport.getExecutor(func,method,this); + var schema = method.returns || (method._schema = {}); // define the schema + schema._idPrefix = serviceName +'/'; // schemas are minimally used to track the id prefixes for the different services + dojox.rpc.services[serviceName] = func; // register the service + schema._service = func; + func.serviceName = serviceName; + func._schema = schema; + + return func; + }, + + _executeMethod: function(method){ + var args = []; + var i; + for (i=1; i< arguments.length; i++){ + args.push(arguments[i]); + } + + var smd = this._smd; + if (method.parameters && method.parameters[0] && method.parameters[0].name && (args.length==1) && dojo.isObject(args[0])){ + // if it is the parameters are not named in the definition, then we should use ordered params, otherwise try to determine by parameters + args = args[0]; + // inherit root-level parameters + if (smd.parameters && smd.parameters[0]){ + for (i=0; i< smd.parameters.length; i++){ + if (smd.parameters[i]["name"] && smd.parameters[i]["default"]){ + args[smd.parameters[i]["name"]] = smd.parameters[i]["default"]; + } + } + } + } + if (dojo.isObject(this._options)){ + args = dojo.mixin(args, this._options); + } + + var envelope = method.envelope || smd.envelope || "NONE"; + var envDef = dojox.rpc.envelopeRegistry.match(envelope); + var schema = method._schema || method.returns; // serialize with the right schema for the context; + var request = envDef.serialize.apply(this, [smd, method, args]); + var contentType = (method.contentType || smd.contentType || request.contentType); + var isJson = (contentType + '').match(/application\/json/); + + // this allows to mandate synchronous behavior from elsewhere when necessary, this may need to be changed to be one-shot in FF3 new sync handling model + dojo.mixin(request,{sync : dojox.rpc._sync, + handleAs : isJson ? "json" : "text", + contentType : contentType, + target : request.target || dojox.rpc.getTarget(smd, method), + transport: method.transport || smd.transport || request.transport, + envelope: method.envelope || smd.envelope || request.envelope, + timeout: method.timeout || smd.timeout, + callbackParamName: method.callbackParamName || smd.callbackParamName, + preventCache: method.preventCache || smd.preventCache}); + + var deferred = (method.restMethod || dojox.rpc.transportRegistry.match(request.transport).fire).call(this,request); + deferred.addBoth(dojo.hitch(this,function(results){ + // if it is an application/json content type, than it should be handled as json + // we have to do conversion here instead of in XHR so that we can set the currentSchema before running it + results = envDef.deserialize.call(this,isJson ? dojox.rpc.resolveJson(results,schema) : results); + return results; + })); + return deferred; + } +}); + +dojox.rpc.getTarget = function(smd, method){ + + var dest=smd._baseUrl; + if (smd.target){ + dest = new dojo._Url(dest,smd.target) + ''; + } + if (method.target){ + dest = new dojo._Url(dest,method.target) + ''; + } + return dest; +} + +dojox.rpc.toNamed=function(method, args, strictParams){ + var i; + if (!dojo.isArray(args)){ + if (strictParams){ + //verify that all required parameters were supplied + for (i=0; i<method.parameters.length;i++){ + if ((!method.parameters[i].optional) && (!args[method.parameters[i].name])){ + throw new Error("Optional Parameter '" + method.parameters[i].name + "' not supplied to " + method.name); + } + } + + //remove any properties that were not defined + for (var x in args){ + var found=false; + for(i=0; i<method.parameters.length;i++){ + if (method.parameters[i].name==x){found=true;} + } + if(!found){ + delete args[x]; + } + } + } + return args; + } + + var data={}; + for(i=0;i<method.parameters.length;i++){ + data[method.parameters[i].name]=args[i] + } + return data; +} + +dojox.rpc.toOrdered=function(method, args){ + if (dojo.isArray(args)){return args;} + var data=[]; + for(var i=0;i<method.parameters.length;i++){ + data.push(args[method.parameters[i].name]); + } + return data; +} + +dojox.rpc.transportRegistry = new dojo.AdapterRegistry(true); +dojox.rpc.envelopeRegistry = new dojo.AdapterRegistry(true); +//Built In Envelopes + +dojox.rpc.envelopeRegistry.register( + "URL",function(str){return str == "URL"},{ + serialize:function(smd, method, data ){ + var d = dojo.objectToQuery(dojox.rpc.toNamed(method, data, method.strictParameters||smd.strictParameters)); + + return { + data: d, + transport:"POST" + } + }, + deserialize:function(results){ + return results; + } + } +); + +dojox.rpc.envelopeRegistry.register( + "JSON",function(str){return str == "JSON"},{ + serialize: function(smd, method, data){ + var d = dojox.rpc.toJson(dojox.rpc.toNamed(method, data, method.strictParameters||smd.strictParameters)); + + return { + data: d, + contentType : 'application/json' + } + }, + deserialize: function(results){ + return results; + } + } +); +dojox.rpc.envelopeRegistry.register( + "PATH",function(str){return str == "PATH"},{ + serialize:function(smd, method, data){ + var i; + var target = dojox.rpc.getTarget(smd, method); + if (dojo.isArray(data)){ + for (i = 0; i < data.length;i++) + target += '/' + data[i]; + } + else { + for (i in data) + target += '/' + i + '/' + data[i]; + } + + return { + data:'', + target: target + } + }, + deserialize:function(results){ + return results; + } + } +); + + + +//post is registered first because it is the default; +dojox.rpc.transportRegistry.register( + "POST",function(str){return str == "POST"},{ + fire:function(r){ + r.url = r.target; + r.postData = r.data; + return dojo.rawXhrPost(r); + } + } +); + +dojox.rpc.transportRegistry.register( + "GET",function(str){return str == "GET"},{ + fire: function(r){ + r.url= r.target + (r.data ? '?'+ r.data : ''); + r.preventCache = r.preventCache || true; + return dojo.xhrGet(r); + } + } +); + + +//only works if you include dojo.io.script +dojox.rpc.transportRegistry.register( + "JSONP",function(str){return str == "JSONP"},{ + fire:function(r){ + r.url = r.target + ((r.target.indexOf("?") == -1) ? '?' : '&') + r.data, + r.callbackParamName = r.callbackParamName || "callback"; + return dojo.io.script.get(r); + } + } +); +dojox.rpc.services={}; +// The RPC service can have it's own serializer. It needs to define this if they are not defined by JsonReferencing +if (!dojox.rpc.toJson){ + dojox.rpc.toJson = function(){ + return dojo.toJson.apply(dojo,arguments); + } + dojox.rpc.fromJson = function(){ + return dojo.fromJson.apply(dojo,arguments); + } + dojox.rpc.resolveJson = function(it){ + return it; + } +} + +} |