src/pyams_skin/resources/js/ext/jquery-jsonrpc.js
changeset 566 a1707c607eec
parent 565 318533413200
child 567 bca1726b1d85
equal deleted inserted replaced
565:318533413200 566:a1707c607eec
     1 (function($, undefined) {
       
     2   $.extend({
       
     3     jsonRPC: {
       
     4       // RPC Version Number
       
     5       version: '2.0',
       
     6 
       
     7       // End point URL, sets default in requests if not
       
     8       // specified with the request call
       
     9       endPoint: null,
       
    10 
       
    11       // Default namespace for methods
       
    12       namespace: null,
       
    13 
       
    14       /*
       
    15        * Provides the RPC client with an optional default endpoint and namespace
       
    16        *
       
    17        * @param {object} The params object which can contain
       
    18        *   endPoint {string} The default endpoint for RPC requests
       
    19        *   namespace {string} The default namespace for RPC requests
       
    20        *   cache {boolean} If set to false, it will force requested
       
    21        *       pages not to be cached by the browser. Setting cache
       
    22        *       to false also appends a query string parameter,
       
    23        *       "_=[TIMESTAMP]", to the URL. (Default: true)
       
    24        */
       
    25       setup: function(params) {
       
    26         this._validateConfigParams(params);
       
    27         this.endPoint = params.endPoint;
       
    28         this.namespace = params.namespace;
       
    29         this.cache = params.cache !== undefined ? params.cache : true;
       
    30         return this;
       
    31       },
       
    32 
       
    33       /*
       
    34        * Convenience wrapper method to allow you to temporarily set a config parameter
       
    35        * (endPoint or namespace) and ensure it gets set back to what it was before
       
    36        *
       
    37        * @param {object} The params object which can contains
       
    38        *   endPoint {string} The default endpoint for RPC requests
       
    39        *   namespace {string} The default namespace for RPC requests
       
    40        * @param {function} callback The function to call with the new params in place
       
    41        */
       
    42       withOptions: function(params, callback) {
       
    43         this._validateConfigParams(params);
       
    44         // No point in running if there isn't a callback received to run
       
    45         if(callback === undefined) throw("No callback specified");
       
    46 
       
    47         origParams = {endPoint: this.endPoint, namespace: this.namespace};
       
    48         this.setup(params);
       
    49         callback.call(this);
       
    50         this.setup(origParams);
       
    51       },
       
    52 
       
    53       /*
       
    54        * Performas a single RPC request
       
    55        *
       
    56        * @param {string} method The name of the rpc method to be called
       
    57        * @param {object} options A collection of object which can contains
       
    58        *  params {array} the params array to send along with the request
       
    59        *  success {function} a function that will be executed if the request succeeds
       
    60        *  error {function} a function that will be executed if the request fails
       
    61        *  url {string} the url to send the request to
       
    62        *  id {string} the provenance id for this request (defaults to 1)
       
    63        *  cache {boolean} If set to false, it will force requested
       
    64        *       pages not to be cached by the browser. Setting cache
       
    65        *       to false also appends a query string parameter,
       
    66        *       "_=[TIMESTAMP]", to the URL. (Default: cache value
       
    67        *       set with the setup method)
       
    68        * @return {undefined}
       
    69        */
       
    70       request: function(method, options) {
       
    71         if(options === undefined) {
       
    72           options = { id: 1 };
       
    73         }
       
    74         if (options.id === undefined) {
       
    75           options.id = 1;
       
    76         }
       
    77         if (options.cache === undefined) {
       
    78           options.cache = this.cache;
       
    79         }
       
    80 
       
    81         // Validate method arguments
       
    82         this._validateRequestMethod(method);
       
    83         this._validateRequestParams(options.params);
       
    84         this._validateRequestCallbacks(options.success, options.error);
       
    85 
       
    86         // Perform the actual request
       
    87         this._doRequest(JSON.stringify(this._requestDataObj(method, options.params, options.id)), options);
       
    88 
       
    89         return true;
       
    90       },
       
    91 
       
    92       /*
       
    93        * Submits multiple requests
       
    94        * Takes an array of objects that contain a method and params
       
    95        *
       
    96        * @params {array} requests an array of request object which can contain
       
    97        *  method {string} the name of the method
       
    98        *  param {object} the params object to be sent with the request
       
    99        *  id {string} the provenance id for the request (defaults to an incrementer starting at 1)
       
   100        * @param {object} options A collection of object which can contains
       
   101        *  success {function} a function that will be executed if the request succeeds
       
   102        *  error {function} a function that will be executed if the request fails
       
   103        *  url {string} the url to send the request to
       
   104        * @return {undefined}
       
   105        */
       
   106       batchRequest: function(requests, options) {
       
   107         if(options === undefined) {
       
   108           options = {};
       
   109         }
       
   110 
       
   111         // Ensure our requests come in as an array
       
   112         if(!$.isArray(requests) || requests.length === 0) throw("Invalid requests supplied for jsonRPC batchRequest. Must be an array object that contain at least a method attribute");
       
   113 
       
   114         // Make sure each of our request objects are valid
       
   115         var _that = this;
       
   116         $.each(requests, function(i, req) {
       
   117           _that._validateRequestMethod(req.method);
       
   118           _that._validateRequestParams(req.params);
       
   119           if (req.id === undefined) {
       
   120             req.id = i + 1;
       
   121           }
       
   122         });
       
   123         this._validateRequestCallbacks(options.success, options.error);
       
   124 
       
   125         var data = [],
       
   126             request;
       
   127 
       
   128         // Prepare our request object
       
   129         for(var i = 0; i<requests.length; i++) {
       
   130           request = requests[i];
       
   131           data.push(this._requestDataObj(request.method, request.params, request.id));
       
   132         }
       
   133 
       
   134         this._doRequest(JSON.stringify(data), options);
       
   135       },
       
   136 
       
   137       // Validate a params hash
       
   138       _validateConfigParams: function(params) {
       
   139         if(params === undefined) {
       
   140           throw("No params specified");
       
   141         }
       
   142         else {
       
   143           if(params.endPoint && typeof(params.endPoint) !== 'string'){
       
   144             throw("endPoint must be a string");
       
   145           }
       
   146           if(params.namespace && typeof(params.namespace) !== 'string'){
       
   147             throw("namespace must be a string");
       
   148           }
       
   149         }
       
   150       },
       
   151 
       
   152       // Request method must be a string
       
   153       _validateRequestMethod: function(method) {
       
   154         if(typeof(method) !== 'string') throw("Invalid method supplied for jsonRPC request")
       
   155         return true;
       
   156       },
       
   157 
       
   158       // Validate request params.  Must be a) empty, b) an object (e.g. {}), or c) an array
       
   159       _validateRequestParams: function(params) {
       
   160         if(!(params === null ||
       
   161              params === undefined ||
       
   162              typeof(params) === 'object' ||
       
   163              $.isArray(params))) {
       
   164           throw("Invalid params supplied for jsonRPC request. It must be empty, an object or an array.");
       
   165         }
       
   166         return true;
       
   167       },
       
   168 
       
   169       _validateRequestCallbacks: function(success, error) {
       
   170         // Make sure callbacks are either empty or a function
       
   171         if(success !== undefined &&
       
   172            typeof(success) !== 'function') throw("Invalid success callback supplied for jsonRPC request");
       
   173         if(error !== undefined &&
       
   174          typeof(error) !== 'function') throw("Invalid error callback supplied for jsonRPC request");
       
   175         return true;
       
   176       },
       
   177 
       
   178       // Internal method used for generic ajax requests
       
   179       _doRequest: function(data, options) {
       
   180         var _that = this;
       
   181         $.ajax({
       
   182           type: 'POST',
       
   183           async: false !== options.async,
       
   184           dataType: 'json',
       
   185           contentType: 'application/json',
       
   186           url: this._requestUrl((options.endPoint || options.url), options.cache),
       
   187           data: data,
       
   188           cache: options.cache,
       
   189           processData: false,
       
   190           error: function(json) {
       
   191             _that._requestError.call(_that, json, options.error);
       
   192           },
       
   193           success: function(json) {
       
   194             _that._requestSuccess.call(_that, json, options.success, options.error);
       
   195           }
       
   196         })
       
   197       },
       
   198 
       
   199       // Determines the appropriate request URL to call for a request
       
   200       _requestUrl: function(url, cache) {
       
   201         url = url || this.endPoint;
       
   202         if (!cache) {
       
   203             if (url.indexOf("?") < 0) {
       
   204               url += '?tm=' + new Date().getTime();
       
   205             }
       
   206             else {
       
   207               url += "&tm=" + new Date().getTime();
       
   208             }
       
   209         }
       
   210         return url;
       
   211       },
       
   212 
       
   213       // Creates an RPC suitable request object
       
   214       _requestDataObj: function(method, params, id) {
       
   215         var dataObj = {
       
   216           jsonrpc: this.version,
       
   217           method: this.namespace ? this.namespace +'.'+ method : method,
       
   218           id: id
       
   219         }
       
   220         if(params !== undefined) {
       
   221           dataObj.params = params;
       
   222         }
       
   223         return dataObj;
       
   224       },
       
   225 
       
   226       // Handles calling of error callback function
       
   227       _requestError: function(json, error) {
       
   228         if (error !== undefined && typeof(error) === 'function') {
       
   229           if(typeof(json.responseText) === 'string') {
       
   230             try {
       
   231               error(eval ( '(' + json.responseText + ')' ));
       
   232             }
       
   233             catch(e) {
       
   234               error(this._response());
       
   235             }
       
   236           }
       
   237           else {
       
   238             error(this._response());
       
   239           }
       
   240         }
       
   241       },
       
   242 
       
   243       // Handles calling of RPC success, calls error callback
       
   244       // if the response contains an error
       
   245       // TODO: Handle error checking for batch requests
       
   246       _requestSuccess: function(json, success, error) {
       
   247         var response = this._response(json);
       
   248 
       
   249         // If we've encountered an error in the response, trigger the error callback if it exists
       
   250         if(response.error && typeof(error) === 'function') {
       
   251           error(response);
       
   252           return;
       
   253         }
       
   254 
       
   255         // Otherwise, successful request, run the success request if it exists
       
   256         if(typeof(success) === 'function') {
       
   257           success(response);
       
   258         }
       
   259       },
       
   260 
       
   261       // Returns a generic RPC 2.0 compatible response object
       
   262       _response: function(json) {
       
   263         if (json === undefined) {
       
   264           return {
       
   265             error: 'Internal server error',
       
   266             version: '2.0'
       
   267           };
       
   268         }
       
   269         else {
       
   270           try {
       
   271             if(typeof(json) === 'string') {
       
   272               json = eval ( '(' + json + ')' );
       
   273             }
       
   274 
       
   275             if (($.isArray(json) && json.length > 0 && json[0].jsonrpc !== '2.0') ||
       
   276                 (!$.isArray(json) && json.jsonrpc !== '2.0')) {
       
   277               throw 'Version error';
       
   278             }
       
   279 
       
   280             return json;
       
   281           }
       
   282           catch (e) {
       
   283             return {
       
   284               error: 'Internal server error: ' + e,
       
   285               version: '2.0'
       
   286             }
       
   287           }
       
   288         }
       
   289       }
       
   290 
       
   291     }
       
   292   });
       
   293 })(jQuery);