define("dojo/rpc/RpcService", ["../main", "../_base/url"], function(dojo) { // module: // dojo/rpc/RpcService // summary: // TODOC dojo.declare("dojo.rpc.RpcService", null, { constructor: function(args){ //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 // // args: 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. // if(args){ //if the arg is a string, we assume it is a url to retrieve an smd definition from if( (dojo.isString(args)) || (args instanceof dojo._Url)){ if (args instanceof dojo._Url){ var url = args + ""; }else{ url = args; } var def = dojo.xhrGet({ url: url, handleAs: "json-comment-optional", sync: true }); def.addCallback(this, "processSmd"); def.addErrback(function() { throw new Error("Unable to load SMD from " + args); }); }else if(args.smdStr){ this.processSmd(dojo.eval("("+args.smdStr+")")); }else{ // otherwise we assume it's an arguments object with the following // (optional) properties: // - serviceUrl // - strictArgChecks // - smdStr // - smdObj if(args.serviceUrl){ this.serviceUrl = args.serviceUrl; } this.timeout = args.timeout || 3000; if("strictArgChecks" in args){ this.strictArgChecks = args.strictArgChecks; } this.processSmd(args); } } }, strictArgChecks: true, serviceUrl: "", parseResults: function(obj){ // summary: // parse the results coming back from an rpc request. this // base implementation, just returns the full object // subclasses should parse and only return the actual results // obj: Object // Object that is the return results from an rpc request return obj; }, errorCallback: function(/* dojo.Deferred */ deferredRequestHandler){ // summary: // create callback that calls the Deferres errback method // deferredRequestHandler: Deferred // The deferred object handling a request. return function(data){ deferredRequestHandler.errback(data.message); }; }, resultCallback: function(/* dojo.Deferred */ deferredRequestHandler){ // summary: // create callback that calls the Deferred's callback method // deferredRequestHandler: Deferred // The deferred object handling a request. return dojo.hitch(this, function(obj){ if(obj.error!=null){ var err; if(typeof obj.error == 'object'){ err = new Error(obj.error.message); err.code = obj.error.code; err.error = obj.error.error; }else{ err = new Error(obj.error); } err.id = obj.id; err.errorObject = obj; deferredRequestHandler.errback(err); }else{ deferredRequestHandler.callback(this.parseResults(obj)); } } ); }, generateMethod: function(/*string*/ method, /*array*/ parameters, /*string*/ url){ // summary: // generate the local bind methods for the remote object // method: string // The name of the method we are generating // parameters: array // the array of parameters for this call. // url: string // the service url for this call return dojo.hitch(this, function(){ var deferredRequestHandler = new dojo.Deferred(); // if params weren't specified, then we can assume it's varargs if( (this.strictArgChecks) && (parameters != null) && (arguments.length != parameters.length) ){ // put error stuff here, no enough params throw new Error("Invalid number of parameters for remote method."); }else{ this.bind(method, dojo._toArray(arguments), deferredRequestHandler, url); } return deferredRequestHandler; }); }, processSmd: function(object){ // summary: // callback method for reciept of a smd object. Parse the smd // and generate functions based on the description // object: // smd object defining this service. if(object.methods){ dojo.forEach(object.methods, function(m){ if(m && m.name){ this[m.name] = this.generateMethod( m.name, m.parameters, m.url||m.serviceUrl||m.serviceURL); if(!dojo.isFunction(this[m.name])){ throw new Error("RpcService: Failed to create" + m.name + "()"); /*console.log("RpcService: Failed to create", m.name, "()");*/ } } }, this); } this.serviceUrl = object.serviceUrl||object.serviceURL; this.required = object.required; this.smd = object; } }); return dojo.rpc.RpcService; });