datasource-local.js revision 3cd3e1a007f7fd6874030808f97ef48e3a950b40
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan/**
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan * The DataSource utility provides a common configurable interface for widgets to
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan * access a variety of data, from JavaScript arrays to online database servers.
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan *
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan * @module datasource
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan */
9df1de8309feb43d162df756c9290ce3afab802aDirk Hoganvar LANG = Y.Lang,
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan/**
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan * Base class for the YUI DataSource utility.
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan * @class DataSource.Local
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan * @extends Base
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan * @constructor
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan */
9df1de8309feb43d162df756c9290ce3afab802aDirk HoganDSLocal = function() {
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan DSLocal.superclass.constructor.apply(this, arguments);
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan};
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan /////////////////////////////////////////////////////////////////////////////
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan //
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan // DataSource static properties
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan //
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan /////////////////////////////////////////////////////////////////////////////
9df1de8309feb43d162df756c9290ce3afab802aDirk HoganY.mix(DSLocal, {
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan /**
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan * Class name.
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan *
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan * @property NAME
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan * @type String
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan * @static
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan * @final
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan * @value "DataSource.Local"
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan */
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan NAME: "DataSource.Local",
564945e59b60a40c3b9458177b2ff63e2947686cPeter Major
564945e59b60a40c3b9458177b2ff63e2947686cPeter Major /////////////////////////////////////////////////////////////////////////////
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan //
954d71f34d584a7bcc51a5df9933427542081d62Dirk Hogan // DataSource Attributes
954d71f34d584a7bcc51a5df9933427542081d62Dirk Hogan //
954d71f34d584a7bcc51a5df9933427542081d62Dirk Hogan /////////////////////////////////////////////////////////////////////////////
954d71f34d584a7bcc51a5df9933427542081d62Dirk Hogan
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan ATTRS: {
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan /**
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan * @attribute source
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan * @description Pointer to live data.
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan * @type MIXED
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan * @default null
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan */
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan source: {
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan value: null
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan }
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan },
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan /**
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan * Global transaction counter.
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan *
addc51736ee961d7b52d048021139920d4364671Neil Madden * @property DataSource._tId
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan * @type Number
6057736124e265febf1603affd1ec9be4428d99dDirk Hogan * @static
6057736124e265febf1603affd1ec9be4428d99dDirk Hogan * @private
6057736124e265febf1603affd1ec9be4428d99dDirk Hogan * @default 0
6057736124e265febf1603affd1ec9be4428d99dDirk Hogan */
6057736124e265febf1603affd1ec9be4428d99dDirk Hogan _tId: 0,
6057736124e265febf1603affd1ec9be4428d99dDirk Hogan
6057736124e265febf1603affd1ec9be4428d99dDirk Hogan /**
6057736124e265febf1603affd1ec9be4428d99dDirk Hogan * Executes a given callback. The third param determines whether to execute
6057736124e265febf1603affd1ec9be4428d99dDirk Hogan *
6057736124e265febf1603affd1ec9be4428d99dDirk Hogan * @method DataSource.issueCallback
6057736124e265febf1603affd1ec9be4428d99dDirk Hogan * @param callback {Object} The callback object.
6057736124e265febf1603affd1ec9be4428d99dDirk Hogan * @param params {Array} params to be passed to the callback method
6057736124e265febf1603affd1ec9be4428d99dDirk Hogan * @param error {Boolean} whether an error occurred
6057736124e265febf1603affd1ec9be4428d99dDirk Hogan * @static
6057736124e265febf1603affd1ec9be4428d99dDirk Hogan */
6057736124e265febf1603affd1ec9be4428d99dDirk Hogan issueCallback: function (e) {
6057736124e265febf1603affd1ec9be4428d99dDirk Hogan if(e.callback) {
6057736124e265febf1603affd1ec9be4428d99dDirk Hogan var scope = e.callback.scope || this,
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan callbackFunc = (e.error && e.callback.failure) || e.callback.success;
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan if (callbackFunc) {
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan callbackFunc.apply(scope, [e]);
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan }
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan }
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan }
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan});
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan
9df1de8309feb43d162df756c9290ce3afab802aDirk HoganY.extend(DSLocal, Y.Base, {
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan /**
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan * Internal init() handler.
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan *
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan * @method initializer
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan * @param config {Object} Config object.
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan * @private
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan */
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan initializer: function(config) {
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan this._initEvents();
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan },
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan /**
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan * Internal destroy() handler.
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan *
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan * @method destructor
9d406c6b25ce9f6bf266b077443e723b95962914Dirk Hogan * @private
9d406c6b25ce9f6bf266b077443e723b95962914Dirk Hogan */
9d406c6b25ce9f6bf266b077443e723b95962914Dirk Hogan destructor: function() {
9d406c6b25ce9f6bf266b077443e723b95962914Dirk Hogan },
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan /**
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan * This method creates all the events for this module.
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan * @method _initEvents
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan * @private
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan */
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan _initEvents: function() {
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan /**
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan * Fired when a data request is received.
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan *
56f76965098d6cc3ae531ce0a73bda588abdf1d3Dirk Hogan * @event request
56f76965098d6cc3ae531ce0a73bda588abdf1d3Dirk Hogan * @param e {Event.Facade} Event Facade.
56f76965098d6cc3ae531ce0a73bda588abdf1d3Dirk Hogan * @param o {Object} Object with the following properties:
56f76965098d6cc3ae531ce0a73bda588abdf1d3Dirk Hogan * <dl>
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan * <dt>tId (Number)</dt> <dd>Unique transaction ID.</dd>
9df1de8309feb43d162df756c9290ce3afab802aDirk Hogan * <dt>request (Object)</dt> <dd>The request.</dd>
* <dt>callback (Object)</dt> <dd>The callback object.</dd>
* </dl>
* @preventable _defRequestFn
*/
//this.publish("request", {defaultFn: this._defRequestFn});
//this.publish("request", {defaultFn:function(e){
// this._defRequestFn(e);
//}});
this.publish("request", {defaultFn: Y.bind("_defRequestFn", this)});
/**
* Fired when raw data is received.
*
* @event data
* @param e {Event.Facade} Event Facade with the following properties:
* <dl>
* <dt>tId (Number)</dt> <dd>Unique transaction ID.</dd>
* <dt>request (Object)</dt> <dd>The request.</dd>
* <dt>callback (Object)</dt> <dd>The callback object with the following properties:
* <dl>
* <dt>success (Function)</dt> <dd>Success handler.</dd>
* <dt>failure (Function)</dt> <dd>Failure handler.</dd>
* <dt>scope (Object)</dt> <dd>Execution context.</dd>
* </dl>
* </dd>
* <dt>data (Object)</dt> <dd>Raw data.</dd>
* </dl>
* @preventable _defDataFn
*/
//this.publish("data", {defaultFn: this._defDataFn});
//this.publish("data", {defaultFn:function(e){
// this._defDataFn(e);
//}});
this.publish("data", {defaultFn: Y.bind("_defDataFn", this)});
/**
* Fired when response is returned.
*
* @event response
* @param e {Event.Facade} Event Facade with the following properties:
* <dl>
* <dt>tId (Number)</dt> <dd>Unique transaction ID.</dd>
* <dt>request (Object)</dt> <dd>The request.</dd>
* <dt>callback (Object)</dt> <dd>The callback object with the following properties:
* <dl>
* <dt>success (Function)</dt> <dd>Success handler.</dd>
* <dt>failure (Function)</dt> <dd>Failure handler.</dd>
* <dt>scope (Object)</dt> <dd>Execution context.</dd>
* </dl>
* </dd>
* <dt>data (Object)</dt> <dd>Raw data.</dd>
* <dt>response (Object)</dt> <dd>Normalized resopnse object with the following properties:
* <dl>
* <dt>results (Object)</dt> <dd>Parsed results.</dd>
* <dt>meta (Object)</dt> <dd>Parsed meta data.</dd>
* <dt>error (Boolean)</dt> <dd>Error flag.</dd>
* </dl>
* </dd>
* </dl>
* @preventable _defResponseFn
*/
//this.publish("response", {defaultFn: this._defResponseFn});
//this.publish("response", {defaultFn:function(e){
// this._defResponseFn(e);
//}});
this.publish("response", {defaultFn: Y.bind("_defResponseFn", this)});
/**
* Fired when an error is encountered.
*
* @event error
* @param e {Event.Facade} Event Facade with the following properties:
* <dl>
* <dt>tId (Number)</dt> <dd>Unique transaction ID.</dd>
* <dt>request (Object)</dt> <dd>The request.</dd>
* <dt>callback (Object)</dt> <dd>The callback object with the following properties:
* <dl>
* <dt>success (Function)</dt> <dd>Success handler.</dd>
* <dt>failure (Function)</dt> <dd>Failure handler.</dd>
* <dt>scope (Object)</dt> <dd>Execution context.</dd>
* </dl>
* </dd>
* <dt>data (Object)</dt> <dd>Raw data.</dd>
* <dt>response (Object)</dt> <dd>Normalized resopnse object with the following properties:
* <dl>
* <dt>results (Object)</dt> <dd>Parsed results.</dd>
* <dt>meta (Object)</dt> <dd>Parsed meta data.</dd>
* <dt>error (Object)</dt> <dd>Error object.</dd>
* </dl>
* </dd>
* </dl>
*/
},
/**
* Manages request/response transaction. Must fire <code>response</code>
* event when response is received. This method should be implemented by
* subclasses to achieve more complex behavior such as accessing remote data.
*
* @method _defRequestFn
* @param e {Event.Facade} Event Facadewith the following properties:
* <dl>
* <dt>tId (Number)</dt> <dd>Unique transaction ID.</dd>
* <dt>request (Object)</dt> <dd>The request.</dd>
* <dt>callback (Object)</dt> <dd>The callback object with the following properties:
* <dl>
* <dt>success (Function)</dt> <dd>Success handler.</dd>
* <dt>failure (Function)</dt> <dd>Failure handler.</dd>
* <dt>scope (Object)</dt> <dd>Execution context.</dd>
* </dl>
* </dd>
* </dl>
* @protected
*/
_defRequestFn: function(e) {
var data = this.get("source");
// Problematic data
if(LANG.isUndefined(data)) {
e.error = new Error(this.toString() + " Source undefined");
}
if(e.error) {
this.fire("error", e);
Y.log("Error in response", "error", this.toString());
}
this.fire("data", Y.mix({data:data}, e));
Y.log("Transaction " + e.tId + " complete. Request: " +
Y.dump(e.request) + " . Response: " + Y.dump(e.response), "info", this.toString());
},
/**
* Normalizes raw data into a response that includes results and meta properties.
*
* @method _defDataFn
* @param e {Event.Facade} Event Facade with the following properties:
* <dl>
* <dt>tId (Number)</dt> <dd>Unique transaction ID.</dd>
* <dt>request (Object)</dt> <dd>The request.</dd>
* <dt>callback (Object)</dt> <dd>The callback object with the following properties:
* <dl>
* <dt>success (Function)</dt> <dd>Success handler.</dd>
* <dt>failure (Function)</dt> <dd>Failure handler.</dd>
* <dt>scope (Object)</dt> <dd>Execution context.</dd>
* </dl>
* </dd>
* <dt>data (Object)</dt> <dd>Raw data.</dd>
* </dl>
* @protected
*/
_defDataFn: function(e) {
var data = e.data,
meta = e.meta,
response = {
results: (LANG.isArray(data)) ? data : [data],
meta: (meta) ? meta : {}
};
this.fire("response", Y.mix({response: response}, e));
},
/**
* Sends data as a normalized response to callback.
*
* @method _defResponseFn
* @param e {Event.Facade} Event Facade with the following properties:
* <dl>
* <dt>tId (Number)</dt> <dd>Unique transaction ID.</dd>
* <dt>request (Object)</dt> <dd>The request.</dd>
* <dt>callback (Object)</dt> <dd>The callback object with the following properties:
* <dl>
* <dt>success (Function)</dt> <dd>Success handler.</dd>
* <dt>failure (Function)</dt> <dd>Failure handler.</dd>
* <dt>scope (Object)</dt> <dd>Execution context.</dd>
* </dl>
* </dd>
* <dt>data (Object)</dt> <dd>Raw data.</dd>
* <dt>response (Object)</dt> <dd>Normalized resopnse object with the following properties:
* <dl>
* <dt>results (Object)</dt> <dd>Parsed results.</dd>
* <dt>meta (Object)</dt> <dd>Parsed meta data.</dd>
* <dt>error (Boolean)</dt> <dd>Error flag.</dd>
* </dl>
* </dd>
* </dl>
* @protected
*/
_defResponseFn: function(e) {
// Send the response back to the callback
DSLocal.issueCallback(e);
},
/**
* Generates a unique transaction ID and fires <code>request</code> event.
*
* @method sendRequest
* @param request {Object} Request.
* @param callback {Object} An object literal with the following properties:
* <dl>
* <dt><code>success</code></dt>
* <dd>The function to call when the data is ready.</dd>
* <dt><code>failure</code></dt>
* <dd>The function to call upon a response failure condition.</dd>
* <dt><code>scope</code></dt>
* <dd>The object to serve as the scope for the success and failure handlers.</dd>
* <dt><code>argument</code></dt>
* <dd>Arbitrary data payload that will be passed back to the success and failure handlers.</dd>
* </dl>
* @return {Number} Transaction ID.
*/
sendRequest: function(request, callback) {
var tId = DSLocal._tId++;
this.fire("request", {tId:tId, request:request,callback:callback});
Y.log("Transaction " + tId + " sent request: " + Y.dump(request), "info", this.toString());
return tId;
}
});
Y.namespace("DataSource").Local = DSLocal;