New file |
0,0 → 1,172 |
if(!dojo._hasResource["dojo.rpc.RpcService"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. |
dojo._hasResource["dojo.rpc.RpcService"] = true; |
dojo.provide("dojo.rpc.RpcService"); |
|
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(new Error(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. |
|
var tf = 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)); |
} |
} |
); |
return tf; |
}, |
|
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.debug("RpcService: Failed to create", m.name, "()");*/ |
} |
} |
}, this); |
} |
|
this.serviceUrl = object.serviceUrl||object.serviceURL; |
this.required = object.required; |
this.smd = object; |
} |
}); |
|
} |