summaryrefslogtreecommitdiff
path: root/js/dojo-1.6/dojox/data/CdfStore.js
diff options
context:
space:
mode:
authorTristan Zur <tzur@web.web.ccwn.org>2014-03-27 22:27:47 +0100
committerTristan Zur <tzur@web.web.ccwn.org>2014-03-27 22:27:47 +0100
commitb62676ca5d3d6f6ba3f019ea3f99722e165a98d8 (patch)
tree86722cb80f07d4569f90088eeaea2fc2f6e2ef94 /js/dojo-1.6/dojox/data/CdfStore.js
Initial commit of intern.ccwn.org contentsHEADmaster
Diffstat (limited to 'js/dojo-1.6/dojox/data/CdfStore.js')
-rw-r--r--js/dojo-1.6/dojox/data/CdfStore.js609
1 files changed, 609 insertions, 0 deletions
diff --git a/js/dojo-1.6/dojox/data/CdfStore.js b/js/dojo-1.6/dojox/data/CdfStore.js
new file mode 100644
index 0000000..5234210
--- /dev/null
+++ b/js/dojo-1.6/dojox/data/CdfStore.js
@@ -0,0 +1,609 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+if(!dojo._hasResource["dojox.data.CdfStore"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.data.CdfStore"] = true;
+dojo.provide("dojox.data.CdfStore");
+dojo.require("dojo.data.util.sorter");
+
+
+
+dojox.data.ASYNC_MODE = 0;
+dojox.data.SYNC_MODE = 1;
+
+dojo.declare("dojox.data.CdfStore", null, {
+ // summary:
+ // IMPORTANT: The CDF Store is designed to work with Tibco GI, and references Tibco's
+ // JSX3 JavaScript library and will not work without it.
+ //
+ // The CDF Store implements dojo.data.Read, Write, and Identity api's. It is a local
+ // (in memory) store that handles XML documents formatted according to the
+ // Common Data Format (CDF) spec:
+ // http://www.tibco.com/devnet/resources/gi/3_1/tips_and_techniques/CommonDataFormatCDF.pdf
+ //
+ // The purpose of this store is to provide a glue between a jsx3 CDF file and a Dijit.
+ //
+ // While a CDF document is an XML file, other than the initial input, all data returned
+ // from and written to this store should be in object format.
+ //
+ // identity: [const] String
+ // The unique identifier for each item. Defaults to "jsxid" which is standard for a CDF
+ // document. Should not be changed.
+ identity: "jsxid",
+ //
+ // url : String
+ // The location from which to fetch the XML (CDF) document.
+ url: "",
+ //
+ // xmlStr: String
+ // A string that can be parsed into an XML document and should be formatted according
+ // to the CDF spec.
+ // example:
+ // | '<data jsxid="jsxroot"><record jsxtext="A"/><record jsxtext="B" jsxid="2" jsxid="2"/></data>'
+ xmlStr:"",
+ //
+ // data: Object
+ // A object that will be converted into the xmlStr property, and then parsed into a CDF.
+ data:null,
+ //
+ // label: String
+ // The property within each item used to define the item.
+ label: "",
+ //
+ // mode [const]: dojox.data.ASYNC_MODE | dojox.data.SYNC_MODE
+ // This store supports syncronous fetches if this property is set to dojox.data.SYNC_MODE.
+ mode:dojox.data.ASYNC_MODE,
+
+ constructor: function(/* Object */ args){
+ // summary:
+ // Constructor for the CDF store. Instantiate a new CdfStore.
+ //
+ if(args){
+ this.url = args.url;
+ this.xmlStr = args.xmlStr || args.str;
+ if(args.data){
+ this.xmlStr = this._makeXmlString(args.data);
+ }
+ this.identity = args.identity || this.identity;
+ this.label = args.label || this.label;
+ this.mode = args.mode !== undefined ? args.mode : this.mode;
+ }
+ this._modifiedItems = {};
+
+ this.byId = this.fetchItemByIdentity;
+ },
+
+ /* dojo.data.api.Read */
+
+ getValue: function(/* jsx3.xml.Entity */ item, /* String */ property, /* value? */ defaultValue){
+ // summary:
+ // Return an property value of an item
+ //
+ return item.getAttribute(property) || defaultValue; // anything
+ },
+
+ getValues: function(/* jsx3.xml.Entity */ item, /* String */ property){
+ // summary:
+ // Return an array of values
+ //
+ // TODO!!! Can't find an example of an array in any CDF files
+ //
+ var v = this.getValue(item, property, []);
+ return dojo.isArray(v) ? v : [v];
+ },
+
+ getAttributes: function(/* jsx3.xml.Entity */ item){
+ // summary:
+ // Return an array of property names
+ //
+ return item.getAttributeNames(); // Array
+ },
+
+ hasAttribute: function(/* jsx3.xml.Entity */ item, /* String */ property){
+ // summary:
+ // Check whether an item has a property
+ //
+ return (this.getValue(item, property) !== undefined); // Boolean
+ },
+
+ hasProperty: function(/* jsx3.xml.Entity */ item, /* String */ property){
+ // summary:
+ // Alias for hasAttribute
+ return this.hasAttribute(item, property);
+ },
+
+ containsValue: function(/* jsx3.xml.Entity */ item, /* String */ property, /* anything */ value){
+ // summary:
+ // Check whether an item contains a value
+ //
+ var values = this.getValues(item, property);
+ for(var i = 0; i < values.length; i++){
+ if(values[i] === null){ continue; }
+ if((typeof value === "string")){
+ if(values[i].toString && values[i].toString() === value){
+ return true;
+ }
+ }else if(values[i] === value){
+ return true; //boolean
+ }
+ }
+ return false;//boolean
+ },
+
+ isItem: function(/* anything */ something){
+ // summary:
+ // Check whether the object is an item (jsx3.xml.Entity)
+ //
+ if(something.getClass && something.getClass().equals(jsx3.xml.Entity.jsxclass)){
+ return true; //boolean
+ }
+ return false; //boolran
+ },
+
+ isItemLoaded: function(/* anything */ something){
+ // summary:
+ // Check whether the object is a jsx3.xml.Entity object and loaded
+ //
+ return this.isItem(something); // Boolean
+ },
+
+ loadItem: function(/* object */ keywordArgs){
+ // summary:
+ // Load an item
+ // description:
+ // The store always loads all items, so if it's an item, then it's loaded.
+ },
+
+ getFeatures: function(){
+ // summary:
+ // Return supported data APIs
+ //
+ return {
+ "dojo.data.api.Read": true,
+ "dojo.data.api.Write": true,
+ "dojo.data.api.Identity":true
+ }; // Object
+ },
+
+ getLabel: function(/* jsx3.xml.Entity */ item){
+ // summary:
+ // See dojo.data.api.Read.getLabel()
+ //
+ if((this.label !== "") && this.isItem(item)){
+ var label = this.getValue(item,this.label);
+ if(label){
+ return label.toString();
+ }
+ }
+ return undefined; //undefined
+ },
+
+ getLabelAttributes: function(/* jsx3.xml.Entity */ item){
+ // summary:
+ // returns an array of what properties of the item that were used
+ // to generate its label
+ // See dojo.data.api.Read.getLabelAttributes()
+ //
+ if(this.label !== ""){
+ return [this.label]; //array
+ }
+ return null; //null
+ },
+
+
+ fetch: function(/* Object? */ request){
+ // summary:
+ // Returns an Array of items based on the request arguments.
+ // description:
+ // Returns an Array of items based on the request arguments.
+ // If the store is in ASYNC mode, the items should be expected in an onComplete
+ // method passed in the request object. If store is in SYNC mode, the items will
+ // be return directly as well as within the onComplete method.
+ // note:
+ // The mode can be set on store initialization or during a fetch as one of the
+ // parameters.
+ //
+ // query: String
+ // The items in the store are treated as objects, but this is reading an XML
+ // document. Further, the actual querying of the items takes place in Tibco GI's
+ // jsx3.xml.Entity. Therefore, we are using their syntax which is xpath.
+ // Note:
+ // As conforming to a CDF document, most, if not all nodes are considered "records"
+ // and their tagNames are as such. The root node is named "data".
+ //
+ // examples:
+ // All items:
+ // | store.fetch({query:"*"});
+ // Item with a jsxid attribute equal to "1" (note you could use byId for this)
+ // | store.fetch({query:"//record[@jsxid='1']"});
+ // All items with any jsxid attribute:
+ // | "//record[@jsxid='*']"
+ // The items with a jsxid of '1' or '4':
+ // | "//record[@jsxid='4' or @jsxid='1']"
+ // All children within a "group" node (could be multiple group nodes):
+ // "//group/record"
+ // All children within a specific group node:
+ // "//group[@name='mySecondGroup']/record"
+ // Any record, anywhere in the document:
+ // | "//record"
+ // Only the records beneath the root (data) node:
+ // | "//data/record"
+ //
+ // See:
+ // http://www.tibco.com/devnet/resources/gi/3_7/api/html/jsx3/xml/Entity.html#method:selectNodes
+ // http://www.w3.org/TR/xpath
+ // http://msdn.microsoft.com/en-us/library/ms256086.aspx
+ //
+ // See dojo.data.Read.fetch():
+ // onBegin
+ // onComplete
+ // onItem
+ // onError
+ // scope
+ // start
+ // count
+ // sort
+ //
+ request = request || {};
+ if(!request.store){
+ request.store = this;
+ }
+ if(request.mode !== undefined){
+ this.mode = request.mode;
+ }
+ var self = this;
+
+ var errorHandler = function(errorData){
+ if(request.onError){
+ var scope = request.scope || dojo.global;
+ request.onError.call(scope, errorData, request);
+ }else{
+ console.error("cdfStore Error:", errorData);
+ }
+ };
+
+ var fetchHandler = function(items, requestObject){
+ requestObject = requestObject || request;
+ var oldAbortFunction = requestObject.abort || null;
+ var aborted = false;
+
+ var startIndex = requestObject.start?requestObject.start:0;
+ var endIndex = (requestObject.count && (requestObject.count !== Infinity))?(startIndex + requestObject.count):items.length;
+
+ requestObject.abort = function(){
+ aborted = true;
+ if(oldAbortFunction){
+ oldAbortFunction.call(requestObject);
+ }
+ };
+
+ var scope = requestObject.scope || dojo.global;
+ if(!requestObject.store){
+ requestObject.store = self;
+ }
+ if(requestObject.onBegin){
+ requestObject.onBegin.call(scope, items.length, requestObject);
+ }
+ if(requestObject.sort){
+ items.sort(dojo.data.util.sorter.createSortFunction(requestObject.sort, self));
+ }
+
+ if(requestObject.onItem){
+ for(var i = startIndex; (i < items.length) && (i < endIndex); ++i){
+ var item = items[i];
+ if(!aborted){
+ requestObject.onItem.call(scope, item, requestObject);
+ }
+ }
+ }
+ if(requestObject.onComplete && !aborted){
+ if(!requestObject.onItem){
+ items = items.slice(startIndex, endIndex);
+ if(requestObject.byId){
+ items = items[0];
+ }
+ }
+ requestObject.onComplete.call(scope, items, requestObject);
+ }else{
+ items = items.slice(startIndex, endIndex);
+ if(requestObject.byId){
+ items = items[0];
+ }
+ }
+ return items;
+ };
+
+ if(!this.url && !this.data && !this.xmlStr){
+ errorHandler(new Error("No URL or data specified."));
+ return false;
+ }
+ var localRequest = request || "*"; // use request for _getItems()
+
+ if(this.mode == dojox.data.SYNC_MODE){
+ // sync mode. items returned directly
+ var res = this._loadCDF();
+ if(res instanceof Error){
+ if(request.onError){
+ request.onError.call(request.scope || dojo.global, res, request);
+ }else{
+ console.error("CdfStore Error:", res);
+ }
+ return res;
+ }
+ this.cdfDoc = res;
+
+ var items = this._getItems(this.cdfDoc, localRequest);
+ if(items && items.length > 0){
+ items = fetchHandler(items, request);
+ }else{
+ items = fetchHandler([], request);
+ }
+ return items;
+
+ }else{
+
+ // async mode. Return a Deferred.
+ var dfd = this._loadCDF();
+ dfd.addCallbacks(dojo.hitch(this, function(cdfDoc){
+ var items = this._getItems(this.cdfDoc, localRequest);
+ if(items && items.length > 0){
+ fetchHandler(items, request);
+ }else{
+ fetchHandler([], request);
+ }
+ }),
+ dojo.hitch(this, function(err){
+ errorHandler(err, request);
+ }));
+
+ return dfd; // Object
+ }
+ },
+
+
+ _loadCDF: function(){
+ // summary:
+ // Internal method.
+ // If a cdfDoc exists, return it. Otherwise, get one from JSX3,
+ // load the data or url, and return the doc or a deferred.
+ var dfd = new dojo.Deferred();
+ if(this.cdfDoc){
+ if(this.mode == dojox.data.SYNC_MODE){
+ return this.cdfDoc; // jsx3.xml.CDF
+ }else{
+ setTimeout(dojo.hitch(this, function(){
+ dfd.callback(this.cdfDoc);
+ }), 0);
+ return dfd; // dojo.Deferred
+ }
+ }
+
+ this.cdfDoc = jsx3.xml.CDF.Document.newDocument();
+ this.cdfDoc.subscribe("response", this, function(evt){
+ dfd.callback(this.cdfDoc);
+ });
+ this.cdfDoc.subscribe("error", this, function(err){
+ dfd.errback(err);
+ });
+
+ this.cdfDoc.setAsync(!this.mode);
+ if(this.url){
+ this.cdfDoc.load(this.url);
+ }else if(this.xmlStr){
+ this.cdfDoc.loadXML(this.xmlStr);
+ if(this.cdfDoc.getError().code){
+ return new Error(this.cdfDoc.getError().description); // Error
+ }
+ }
+
+ if(this.mode == dojox.data.SYNC_MODE){
+ return this.cdfDoc; // jsx3.xml.CDF
+ }else{
+ return dfd; // dojo.Deferred
+ }
+ },
+
+ _getItems: function(/* jsx3.xml.Entity */cdfDoc, /* Object */request){
+ // summary:
+ // Internal method.
+ // Requests the items from jsx3.xml.Entity with an xpath query.
+ //
+ var itr = cdfDoc.selectNodes(request.query, false, 1);
+ var items = [];
+ while(itr.hasNext()){
+ items.push(itr.next());
+ }
+ return items;
+ },
+
+ close: function(/*dojo.data.api.Request || keywordArgs || null */ request){
+ // summary:
+ // See dojo.data.api.Read.close()
+ },
+
+/* dojo.data.api.Write */
+
+ newItem: function(/* object? */ keywordArgs, /* object? || String? */parentInfo){
+ // summary:
+ // Creates a jsx3.xml.Entity item and inserts it either inside the
+ // parent or appends it to the root
+ //
+ keywordArgs = (keywordArgs || {});
+ if(keywordArgs.tagName){
+ // record tagName is automatic and this would add it
+ // as a property
+ if(keywordArgs.tagName!="record"){
+ // TODO: How about some sort of group?
+ console.warn("Only record inserts are supported at this time");
+ }
+ delete keywordArgs.tagName;
+ }
+ keywordArgs.jsxid = keywordArgs.jsxid || this.cdfDoc.getKey();
+ if(this.isItem(parentInfo)){
+ parentInfo = this.getIdentity(parentInfo);
+ }
+ var item = this.cdfDoc.insertRecord(keywordArgs, parentInfo);
+
+ this._makeDirty(item);
+
+ return item; // jsx3.xml.Entity
+ },
+
+ deleteItem: function(/* jsx3.xml.Entity */ item){
+ // summary:
+ // Delete an jsx3.xml.Entity (wrapper to a XML element).
+ //
+ this.cdfDoc.deleteRecord(this.getIdentity(item));
+ this._makeDirty(item);
+ return true; //boolean
+ },
+
+ setValue: function(/* jsx3.xml.Entity */ item, /* String */ property, /* almost anything */ value){
+ // summary:
+ // Set an property value
+ //
+ this._makeDirty(item);
+ item.setAttribute(property, value);
+ return true; // Boolean
+ },
+
+ setValues: function(/* jsx3.xml.Entity */ item, /* String */ property, /*array*/ values){
+ // summary:
+ // Set property values
+ // TODO: Needs to be fully implemented.
+ //
+ this._makeDirty(item);
+ console.warn("cdfStore.setValues only partially implemented.");
+ return item.setAttribute(property, values);
+
+ },
+
+ unsetAttribute: function(/* jsx3.xml.Entity */ item, /* String */ property){
+ // summary:
+ // Remove an property
+ //
+ this._makeDirty(item);
+ item.removeAttribute(property);
+ return true; // Boolean
+ },
+
+ revert: function(){
+ // summary:
+ // Invalidate changes (new and/or modified elements)
+ // Resets data by simply deleting the reference to the cdfDoc.
+ // Subsequent fetches will load the new data.
+ // Note:
+ // Any items outside the store will no longer be valid and may cause errors.
+ //
+ delete this.cdfDoc;
+ this._modifiedItems = {};
+ return true; //boolean
+ },
+
+ isDirty: function(/* jsx3.xml.Entity ? */ item){
+ // summary:
+ // Check whether an item is new, modified or deleted.
+ // If no item is passed, checks if anything in the store has changed.
+ //
+ if(item){
+ return !!this._modifiedItems[this.getIdentity(item)]; // Boolean
+ }else{
+ var _dirty = false;
+ for(var nm in this._modifiedItems){ _dirty = true; break; }
+ return _dirty; // Boolean
+ }
+ },
+
+
+
+/* internal API */
+
+ _makeDirty: function(item){
+ // summary:
+ // Internal method.
+ // Marks items as modified, deleted or new.
+ var id = this.getIdentity(item);
+ this._modifiedItems[id] = item;
+ },
+
+
+ _makeXmlString: function(obj){
+ // summary:
+ // Internal method.
+ // Converts an object into an XML string.
+ //
+ var parseObj = function(obj, name){
+ var xmlStr = "";
+ var nm;
+ if(dojo.isArray(obj)){
+ for(var i=0;i<obj.length;i++){
+ xmlStr += parseObj(obj[i], name);
+ }
+ }else if(dojo.isObject(obj)){
+ xmlStr += '<'+name+' ';
+ for(nm in obj){
+ if(!dojo.isObject(obj[nm])){
+ xmlStr += nm+'="'+obj[nm]+'" ';
+ }
+ }
+ xmlStr +='>';
+ for(nm in obj){
+ if(dojo.isObject(obj[nm])){
+ xmlStr += parseObj(obj[nm], nm);
+ }
+ }
+ xmlStr += '</'+name+'>';
+ }
+ return xmlStr;
+ };
+ return parseObj(obj, "data");
+ },
+
+ /*************************************
+ * Dojo.data Identity implementation *
+ *************************************/
+ getIdentity: function(/* jsx3.xml.Entity */ item){
+ // summary:
+ // Returns the identifier for an item.
+ //
+ return this.getValue(item, this.identity); // String
+ },
+
+ getIdentityAttributes: function(/* jsx3.xml.Entity */ item){
+ // summary:
+ // Returns the property used for the identity.
+ //
+ return [this.identity]; // Array
+ },
+
+
+ fetchItemByIdentity: function(/* Object || String */ args){
+ // summary:
+ // See dojo.data.api.Identity.fetchItemByIdentity(keywordArgs)
+ //
+ // Note:
+ // This method can be synchronous if mode is set.
+ // Also, there is a more finger friendly alias of this method, byId();
+ if(dojo.isString(args)){
+ var id = args;
+ args = {query:"//record[@jsxid='"+id+"']", mode: dojox.data.SYNC_MODE};
+ }else{
+ if(args){
+ args.query = "//record[@jsxid='"+args.identity+"']";
+ }
+ if(!args.mode){args.mode = this.mode;}
+ }
+ args.byId = true;
+ return this.fetch(args); // dojo.Deferred || Array
+ },
+ byId: function(/* Object || String */ args){
+ // stub. See fetchItemByIdentity
+ }
+
+});
+
+}