]> git.pond.sub.org Git - eow/blobdiff - static/dojo-release-1.1.1/dojox/data/jsonPathStore.js
Replace Dojo with jQuery
[eow] / static / dojo-release-1.1.1 / dojox / data / jsonPathStore.js
diff --git a/static/dojo-release-1.1.1/dojox/data/jsonPathStore.js b/static/dojo-release-1.1.1/dojox/data/jsonPathStore.js
deleted file mode 100644 (file)
index 01e4e23..0000000
+++ /dev/null
@@ -1,1191 +0,0 @@
-if(!dojo._hasResource["dojox.data.jsonPathStore"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
-dojo._hasResource["dojox.data.jsonPathStore"] = true;
-dojo.provide("dojox.data.jsonPathStore");
-dojo.require("dojox.jsonPath");
-dojo.require("dojo.date");
-dojo.require("dojo.date.locale");
-dojo.require("dojo.date.stamp");
-
-dojox.data.ASYNC_MODE = 0;
-dojox.data.SYNC_MODE = 1;
-
-dojo.declare("dojox.data.jsonPathStore",
-       null,
-       {
-               mode: dojox.data.ASYNC_MODE,
-               metaLabel: "_meta",
-               hideMetaAttributes: false,
-               autoIdPrefix: "_auto_",
-               autoIdentity: true,
-               idAttribute: "_id",
-               indexOnLoad: true,
-               labelAttribute: "",
-               url: "",
-               _replaceRegex: /\'\]/gi,
-               
-               constructor: function(options){
-                       //summary:
-                       //      jsonPathStore constructor, instantiate a new jsonPathStore 
-                       //
-                       //      Takes a single optional parameter in the form of a Javascript object
-                       //      containing one or more of the following properties. 
-                       //
-                       //      data: /*JSON String*/ || /* Javascript Object */, 
-                       //              JSON String or Javascript object this store will control
-                       //              JSON is converted into an object, and an object passed to
-                       //              the store will be used directly.  If no data and no url
-                       //              is provide, an empty object, {}, will be used as the initial
-                       //              store.
-                       //
-                       //      url: /* string url */   
-                       //              Load data from this url in JSON format and use the Object
-                       //              created from the data as the data source.
-                       //
-                       //      indexOnLoad: /* boolean */ 
-                       //              Defaults to true, but this may change in the near future.
-                       //              Parse the data object and set individual objects up as
-                       //              appropriate.  This will add meta data and assign
-                       //              id's to objects that dont' have them as defined by the
-                       //              idAttribute option.  Disabling this option will keep this 
-                       //              parsing from happening until a query is performed at which
-                       //              time only the top level of an item has meta info stored.
-                       //              This might work in some situations, but you will almost
-                       //              always want to indexOnLoad or use another option which
-                       //              will create an index.  In the future we will support a 
-                       //              generated index that maps by jsonPath allowing the
-                       //              server to take some of this load for larger data sets. 
-                       //
-                       //      idAttribute: /* string */
-                       //              Defaults to '_id'. The name of the attribute that holds an objects id.
-                       //              This can be a preexisting id provided by the server.  
-                       //              If an ID isn't already provided when an object
-                       //              is fetched or added to the store, the autoIdentity system
-                       //              will generate an id for it and add it to the index. There
-                       //              are utility routines for exporting data from the store
-                       //              that can clean any generated IDs before exporting and leave
-                       //              preexisting id's in tact.
-                       //
-                       //      metaLabel: /* string */
-                       //              Defaults to '_meta' overrides the attribute name that is used by the store
-                       //              for attaching meta information to an object while
-                       //              in the store's control.  Defaults to '_meta'. 
-                       //      
-                       //      hideMetaAttributes: /* boolean */
-                       //              Defaults to False.  When enabled, calls to getAttributes() will not 
-                       //              include the meta attribute.
-                       //
-                       //      autoIdPrefix: /*string*/
-                       //              Defaults to "_auto_".  This string is used as the prefix to any
-                       //              objects which have a generated id. A numeric index is appended
-                       //              to this string to complete the ID
-                       //
-                       //      mode: dojox.data.ASYNC_MODE || dojox.data.SYNC_MODE
-                       //              Defaults to ASYNC_MODE.  This option sets the default mode for this store.
-                       //              Sync calls return their data immediately from the calling function
-                       //              instead of calling the callback functions.  Functions such as 
-                       //              fetchItemByIdentity() and fetch() both accept a string parameter in addtion
-                       //              to the normal keywordArgs parameter.  When passed this option, SYNC_MODE will
-                       //              automatically be used even when the default mode of the system is ASYNC_MODE.
-                       //              A normal request to fetch or fetchItemByIdentity (with kwArgs object) can also 
-                       //              include a mode property to override this setting for that one request.
-
-                       //setup a byId alias to the api call    
-                       this.byId=this.fetchItemByIdentity;
-
-                       if (options){
-                               dojo.mixin(this,options);
-                       }
-
-                       this._dirtyItems=[];
-                       this._autoId=0;
-                       this._referenceId=0;
-                       this._references={};
-                       this._fetchQueue=[];
-                       this.index={};
-
-                       //regex to identify when we're travelling down metaObject (which we don't want to do) 
-                       var expr="("+this.metaLabel+"\'\])";
-                       this.metaRegex = new RegExp(expr);
-
-
-                       //no data or url, start with an empty object for a store
-                       if (!this.data && !this.url){
-                               this.setData({});
-                       }       
-
-                       //we have data, but no url, set the store as the data
-                       if (this.data && !this.url){
-                               this.setData(this.data);
-
-                               //remove the original refernce, we're now using _data from here on out
-                               delete this.data;
-                       }
-
-                       //given a url, load json data from as the store
-                       if (this.url){
-                               dojo.xhrGet({
-                                       url: options.url,
-                                       handleAs: "json",
-                                       load: dojo.hitch(this, "setData"),
-                                       sync: this.mode
-                               });
-                       }
-               },
-
-               _loadData: function(data){
-                       // summary:
-                       //      load data into the store. Index it if appropriate.
-                       if (this._data){
-                               delete this._data;
-                       }
-
-                       if (dojo.isString(data)){
-                               this._data = dojo.fromJson(data);
-                       }else{
-                               this._data = data;
-                       }
-                       
-                       if (this.indexOnLoad){
-                               this.buildIndex();              
-                       }       
-
-                       this._updateMeta(this._data, {path: "$"});
-
-                       this.onLoadData(this._data);
-               },
-
-               onLoadData: function(data){
-                       // summary
-                       //      Called after data has been loaded in the store.  
-                       //      If any requests happened while the startup is happening
-                       //      then process them now.
-
-                       while (this._fetchQueue.length>0){
-                               var req = this._fetchQueue.shift();
-                               this.fetch(req);
-                       }       
-
-               },
-
-               setData: function(data){
-                       // summary:
-                       //      set the stores' data to the supplied object and then 
-                       //      load and/or setup that data with the required meta info         
-                       this._loadData(data);
-               },
-
-               buildIndex: function(path, item){
-                       //summary: 
-                       //      parse the object structure, and turn any objects into
-                       //      jsonPathStore items. Basically this just does a recursive
-                       //      series of fetches which itself already examines any items
-                       //      as they are retrieved and setups up the required meta information. 
-                       //
-                       //      path: /* string */
-                       //              jsonPath Query for the starting point of this index construction.
-
-                       if (!this.idAttribute){
-                               throw new Error("buildIndex requires idAttribute for the store");
-                       }
-
-                       item = item || this._data;
-                       var origPath = path;
-                       path = path||"$";
-                       path += "[*]";
-                       var data = this.fetch({query: path,mode: dojox.data.SYNC_MODE});
-                       for(var i=0; i<data.length;i++){
-                               if(dojo.isObject(data[i])){
-                                       var newPath = data[i][this.metaLabel]["path"];
-                                       if (origPath){
-                                               //console.log("newPath: ", newPath);
-                                               //console.log("origPath: ", origPath);
-                                               //console.log("path: ", path);
-                                               //console.log("data[i]: ", data[i]);
-                                               var parts = origPath.split("\[\'");
-                                               var attribute = parts[parts.length-1].replace(this._replaceRegex,'');
-                                               //console.log("attribute: ", attribute);
-                                               //console.log("ParentItem: ", item, attribute);
-                                               if (!dojo.isArray(data[i])){
-                                                       this._addReference(data[i], {parent: item, attribute:attribute});
-                                                       this.buildIndex(newPath, data[i]);
-                                               }else{
-                                                       this.buildIndex(newPath,item);
-                                               }
-                                       }else{
-                                               var parts = newPath.split("\[\'");
-                                               var attribute = parts[parts.length-1].replace(this._replaceRegex,'');
-                                               this._addReference(data[i], {parent: this._data, attribute:attribute});
-                                               this.buildIndex(newPath, data[i]);
-                                       }
-                               }
-                       }
-               },
-
-               _correctReference: function(item){
-                       // summary:
-                       //      make sure we have an reference to the item in the store
-                       //      and not a clone. Takes an item, matches it to the corresponding
-                       //      item in the store and if it is the same, returns itself, otherwise
-                       //      it returns the item from the store.
-               
-                       if (this.index[item[this.idAttribute]][this.metaLabel]===item[this.metaLabel]){
-                               return this.index[item[this.idAttribute]];
-                       }
-                       return item;    
-               },
-
-               getValue: function(item, property){
-                       // summary:
-                       //      Gets the value of an item's 'property'
-                       //
-                       //      item: /* object */
-                       //      property: /* string */
-                       //              property to look up value for   
-                       item = this._correctReference(item);
-                       return item[property];
-               },
-
-               getValues: function(item, property){
-                       // summary:
-                       //      Gets the value of an item's 'property' and returns
-                       //      it.  If this value is an array it is just returned,
-                       //      if not, the value is added to an array and that is returned.
-                       //
-                       //      item: /* object */
-                       //      property: /* string */
-                       //              property to look up value for   
-       
-                       item = this._correctReference(item);
-                       return dojo.isArray(item[property]) ? item[property] : [item[property]];
-               },
-
-               getAttributes: function(item){
-                       // summary:
-                       //      Gets the available attributes of an item's 'property' and returns
-                       //      it as an array. If the store has 'hideMetaAttributes' set to true
-                       //      the attributed identified by 'metaLabel' will not be included.
-                       //
-                       //      item: /* object */
-
-                       item = this._correctReference(item);
-                       var res = [];
-                       for (var i in item){
-                               if (this.hideMetaAttributes && (i==this.metaLabel)){continue;}
-                               res.push(i);
-                       }
-                       return res;
-               },
-
-               hasAttribute: function(item,attribute){
-                       // summary:
-                       //      Checks to see if item has attribute
-                       //
-                       //      item: /* object */
-                       //      attribute: /* string */
-               
-                       item = this._correctReference(item);
-                       if (attribute in item){return true;}
-                       return false;   
-               },
-
-               containsValue: function(item, attribute, value){
-                       // summary:
-                       //      Checks to see if 'item' has 'value' at 'attribute'
-                       //
-                       //      item: /* object */
-                       //      attribute: /* string */
-                       //      value: /* anything */
-                       item = this._correctReference(item);
-
-                       if (item[attribute] && item[attribute]==value){return true}
-                       if (dojo.isObject(item[attribute]) || dojo.isObject(value)){
-                               if (this._shallowCompare(item[attribute],value)){return true}
-                       }
-                       return false;   
-               },
-
-               _shallowCompare: function(a, b){
-                       //summary does a simple/shallow compare of properties on an object
-                       //to the same named properties on the given item. Returns
-                       //true if all props match. It will not descend into child objects
-                       //but it will compare child date objects
-
-                       if ((dojo.isObject(a) && !dojo.isObject(b))|| (dojo.isObject(b) && !dojo.isObject(a))) {
-                               return false;
-                       }
-
-                       if ( a["getFullYear"] || b["getFullYear"] ){
-                               //confirm that both are dates
-                               if ( (a["getFullYear"] && !b["getFullYear"]) || (b["getFullYear"] && !a["getFullYear"]) ){
-                                       return false;
-                               }else{
-                                       if (!dojo.date.compare(a,b)){
-                                               return true;
-                                       }
-                                       return false;
-                                       }
-                       }
-
-                       for (var i in b){       
-                               if (dojo.isObject(b[i])){
-                                       if (!a[i] || !dojo.isObject(a[i])){return false}
-
-                                       if (b[i]["getFullYear"]){
-                                               if(!a[i]["getFullYear"]){return false}
-                                               if (dojo.date.compare(a,b)){return false}       
-                                       }else{
-                                               if (!this._shallowCompare(a[i],b[i])){return false}
-                                       }
-                               }else{  
-                                       if (!b[i] || (a[i]!=b[i])){return false}
-                               }
-                       }
-
-                       //make sure there werent props on a that aren't on b, if there aren't, then
-                       //the previous section will have already evaluated things.
-
-                       for (var i in a){
-                               if (!b[i]){return false}
-                       }
-                       
-                       return true;
-               },
-
-               isItem: function(item){
-                       // summary:
-                       //      Checks to see if a passed 'item'
-                       //      is really a jsonPathStore item.  Currently
-                       //      it only verifies structure.  It does not verify
-                       //      that it belongs to this store at this time.
-                       //
-                       //      item: /* object */
-                       //      attribute: /* string */
-               
-                       if (!dojo.isObject(item) || !item[this.metaLabel]){return false}
-                       if (this.requireId && this._hasId && !item[this._id]){return false}
-                       return true;
-               },
-
-               isItemLoaded: function(item){
-                       // summary:
-                       //      returns isItem() :)
-                       //
-                       //      item: /* object */
-
-                       item = this._correctReference(item);
-                       return this.isItem(item);
-               },
-
-               loadItem: function(item){
-                       // summary:
-                       //      returns true. Future implementatins might alter this 
-                       return true;
-               },
-
-               _updateMeta: function(item, props){
-                       // summary:
-                       //      verifies that 'item' has a meta object attached
-                       //      and if not it creates it by setting it to 'props'
-                       //      if the meta attribute already exists, mix 'props'
-                       //      into it.
-
-                       if (item && item[this.metaLabel]){
-                               dojo.mixin(item[this.metaLabel], props);
-                               return;
-                       }
-
-                       item[this.metaLabel]=props;
-               },
-
-               cleanMeta: function(data, options){
-                       // summary
-                       //      Recurses through 'data' and removes an
-                       //      meta information that has been attached. This
-                       //      function will also removes any id's that were autogenerated
-                       //      from objects.  It will not touch id's that were not generated
-
-                       data = data || this._data;
-
-                       if (data[this.metaLabel]){
-                               if(data[this.metaLabel]["autoId"]){
-                                       delete data[this.idAttribute];
-                               }
-                               delete data[this.metaLabel];
-                       }
-
-                       if (dojo.isArray(data)){
-                               for(var i=0; i<data.length;i++){
-                                       if(dojo.isObject(data[i]) || dojo.isArray(data[i]) ){
-                                               this.cleanMeta(data[i]);
-                                       }
-                               }
-                       } else if (dojo.isObject(data)){
-                               for (var i in data){
-                                       this.cleanMeta(data[i]);
-                               }
-                       }
-               }, 
-
-               fetch: function(args){
-                       //console.log("fetch() ", args);
-                       // summary
-                       //      
-                       //      fetch takes either a string argument or a keywordArgs
-                       //      object containing the parameters for the search.
-                       //      If passed a string, fetch will interpret this string
-                       //      as the query to be performed and will do so in 
-                       //      SYNC_MODE returning the results immediately.
-                       //      If an object is supplied as 'args', its options will be 
-                       //      parsed and then contained query executed. 
-                       //
-                       //      query: /* string or object */
-                       //              Defaults to "$..*". jsonPath query to be performed 
-                       //              on data store. **note that since some widgets
-                       //              expect this to be an object, an object in the form
-                       //              of {query: '$[*'], queryOptions: "someOptions"} is
-                       //              acceptable      
-                       //
-                       //      mode: dojox.data.SYNC_MODE || dojox.data.ASYNC_MODE
-                       //              Override the stores default mode.
-                       //
-                       //      queryOptions: /* object */
-                       //              Options passed on to the underlying jsonPath query
-                       //              system.
-                       //
-                       //      start: /* int */
-                       //              Starting item in result set
-                       //
-                       //      count: /* int */
-                       //              Maximum number of items to return
-                       //
-                       //      sort: /* function */
-                       //              Not Implemented yet
-                       //
-                       //      The following only apply to ASYNC requests (the default)
-                       //
-                       //      onBegin: /* function */
-                       //              called before any results are returned. Parameters
-                       //              will be the count and the original fetch request
-                       //      
-                       //      onItem: /*function*/
-                       //              called for each returned item.  Parameters will be
-                       //              the item and the fetch request
-                       //
-                       //      onComplete: /* function */
-                       //              called on completion of the request.  Parameters will   
-                       //              be the complete result set and the request
-                       //
-                       //      onError: /* function */
-                       //              colled in the event of an error
-
-                       // we're not started yet, add this request to a queue and wait till we do       
-                       if (!this._data){
-                               this._fetchQueue.push(args);
-                               return args;
-                       }       
-                       if(dojo.isString(args)){
-                                       query = args;
-                                       args={query: query, mode: dojox.data.SYNC_MODE};
-                                       
-                       }
-
-                       var query;
-                       if (!args || !args.query){
-                               if (!args){
-                                       var args={};    
-                               }
-
-                               if (!args.query){
-                                       args.query="$..*";
-                                       query=args.query;
-                               }
-
-                       }
-
-                       if (dojo.isObject(args.query)){
-                               if (args.query.query){
-                                       query = args.query.query;
-                               }else{
-                                       query = args.query = "$..*";
-                               }
-                               if (args.query.queryOptions){
-                                       args.queryOptions=args.query.queryOptions
-                               }
-                       }else{
-                               query=args.query;
-                       }
-
-                       if (!args.mode) {args.mode = this.mode;}
-                       if (!args.queryOptions) {args.queryOptions={};}
-
-                       args.queryOptions.resultType='BOTH';
-                       var results = dojox.jsonPath.query(this._data, query, args.queryOptions);
-                       var tmp=[];
-                       var count=0;
-                       for (var i=0; i<results.length; i++){
-                               if(args.start && i<args.start){continue;}
-                               if (args.count && (count >= args.count)) { continue; }
-
-                               var item = results[i]["value"];
-                               var path = results[i]["path"];
-                               if (!dojo.isObject(item)){continue;}
-                               if(this.metaRegex.exec(path)){continue;}
-
-                               //this automatically records the objects path
-                               this._updateMeta(item,{path: results[i].path});
-
-                               //if autoIdentity and no id, generate one and add it to the item
-                               if(this.autoIdentity && !item[this.idAttribute]){
-                                       var newId = this.autoIdPrefix + this._autoId++;
-                                       item[this.idAttribute]=newId;
-                                       item[this.metaLabel]["autoId"]=true;
-                               }
-
-                               //add item to the item index if appropriate
-                               if(item[this.idAttribute]){this.index[item[this.idAttribute]]=item}
-                               count++;
-                               tmp.push(item);
-                       }
-                       results = tmp;
-                       var scope = args.scope || dojo.global;
-
-                       if ("sort" in args){
-                               console.log("TODO::add support for sorting in the fetch");
-                       }       
-
-                       if (args.mode==dojox.data.SYNC_MODE){ 
-                               return results; 
-                       };
-
-                       if (args.onBegin){      
-                               args["onBegin"].call(scope, results.length, args);
-                       }
-
-                       if (args.onItem){
-                               for (var i=0; i<results.length;i++){    
-                                       args["onItem"].call(scope, results[i], args);
-                               }
-                       }
-                       if (args.onComplete){
-                               args["onComplete"].call(scope, results, args);
-                       }
-
-                       return args;
-               },
-
-               dump: function(options){
-                       // summary:
-                       //
-                       //      exports the store data set. Takes an options
-                       //      object with a number of parameters
-                       //
-                       //      data: /* object */
-                       //              Defaults to the root of the store.
-                       //              The data to be exported.
-                       //      
-                       //      clone: /* boolean */
-                       //              clone the data set before returning it 
-                       //              or modifying it for export
-                       //
-                       //      cleanMeta: /* boolean */
-                       //              clean the meta data off of the data. Note
-                       //              that this will happen to the actual
-                       //              store data if !clone. If you want
-                       //              to continue using the store after
-                       //              this operation, it is probably better to export
-                       //              it as a clone if you want it cleaned.
-                       //
-                       //      suppressExportMeta: /* boolean */
-                       //              By default, when data is exported from the store
-                       //              some information, such as as a timestamp, is
-                       //              added to the root of exported data.  This
-                       //              prevents that from happening.  It is mainly used
-                       //              for making tests easier.
-                       //
-                       //      type: "raw" || "json"
-                       //              Defaults to 'json'. 'json' will convert the data into 
-                       //              json before returning it. 'raw' will just return a
-                       //              reference to the object  
-
-                       var options = options || {};
-                       var d=options.data || this._data;
-       
-                       if (!options.suppressExportMeta && options.clone){
-                               data = dojo.clone(d);
-                               if (data[this.metaLabel]){
-                                       data[this.metaLabel]["clone"]=true;
-                               }
-                       }else{
-                               var data=d;
-                       }
-
-                       if (!options.suppressExportMeta &&  data[this.metaLabel]){
-                               data[this.metaLabel]["last_export"]=new Date().toString()
-                       }
-
-                       if(options.cleanMeta){
-                               this.cleanMeta(data);
-                       }
-
-                       //console.log("Exporting: ", options, dojo.toJson(data));       
-                       switch(options.type){
-                               case "raw":
-                                       return data;
-                               case "json":
-                               default:
-                                       return dojo.toJson(data);
-                       }
-               },      
-
-               getFeatures: function(){
-                       // summary:
-                       //      return the store feature set
-
-                       return { 
-                               "dojo.data.api.Read": true,
-                               "dojo.data.api.Identity": true,
-                               "dojo.data.api.Write": true,
-                               "dojo.data.api.Notification": true
-                       }
-               },
-
-               getLabel: function(item){
-                       // summary
-                       //      returns the label for an item. The label
-                       //      is created by setting the store's labelAttribute 
-                       //      property with either an attribute name  or an array
-                       //      of attribute names.  Developers can also
-                       //      provide the store with a createLabel function which
-                       //      will do the actaul work of creating the label.  If not
-                       //      the default will just concatenate any of the identified
-                       //      attributes together.
-                       item = this._correctReference(item);
-                       var label="";
-
-                       if (dojo.isFunction(this.createLabel)){
-                               return this.createLabel(item);
-                       }
-
-                       if (this.labelAttribute){
-                               if (dojo.isArray(this.labelAttribute))  {
-                                       for(var i=0; i<this.labelAttribute.length; i++){
-                                               if (i>0) { label+=" ";}
-                                               label += item[this.labelAttribute[i]];
-                                       }
-                                       return label;
-                               }else{
-                                       return item[this.labelAttribute];
-                               }
-                       }
-                       return item.toString();
-               },
-
-               getLabelAttributes: function(item){
-                       // summary:
-                       //      returns an array of attributes that are used to create the label of an item
-                       item = this._correctReference(item);
-                       return dojo.isArray(this.labelAttribute) ? this.labelAttribute : [this.labelAttribute];
-               },
-
-               sort: function(a,b){
-                       console.log("TODO::implement default sort algo");
-               },
-
-               //Identity API Support
-
-               getIdentity: function(item){
-                       // summary
-                       //      returns the identity of an item or throws
-                       //      a not found error.
-
-                       if (this.isItem(item)){
-                               return item[this.idAttribute];
-                       }
-                       throw new Error("Id not found for item");
-               },
-
-               getIdentityAttributes: function(item){
-                       // summary:
-                       //      returns the attributes which are used to make up the 
-                       //      identity of an item.  Basically returns this.idAttribute
-
-                       return [this.idAttribute];
-               },
-
-               fetchItemByIdentity: function(args){
-                       // summary: 
-                       //      fetch an item by its identity. This store also provides
-                       //      a much more finger friendly alias, 'byId' which does the
-                       //      same thing as this function.  If provided a string
-                       //      this call will be treated as a SYNC request and will 
-                       //      return the identified item immediatly.  Alternatively it
-                       //      takes a object as a set of keywordArgs:
-                       //      
-                       //      identity: /* string */
-                       //              the id of the item you want to retrieve
-                       //      
-                       //      mode: dojox.data.SYNC_MODE || dojox.data.ASYNC_MODE
-                       //              overrides the default store fetch mode
-                       //      
-                       //      onItem: /* function */
-                       //              Result call back.  Passed the fetched item.
-                       //
-                       //      onError: /* function */
-                       //              error callback. 
-                       var id; 
-                       if (dojo.isString(args)){
-                               id = args;
-                               args = {identity: id, mode: dojox.data.SYNC_MODE}
-                       }else{
-                               if (args){
-                                       id = args["identity"];          
-                               }
-                               if (!args.mode){args.mode = this.mode}  
-                       }
-
-                       if (this.index && (this.index[id] || this.index["identity"])){
-                               
-                               if (args.mode==dojox.data.SYNC_MODE){
-                                       return this.index[id];
-                               }
-
-                               if (args.onItem){
-                                       args["onItem"].call(args.scope || dojo.global, this.index[id], args);
-                               }
-
-                               return args;
-                       }else{
-                               if (args.mode==dojox.data.SYNC_MODE){
-                                       return false;
-                               }
-                       }
-
-
-                       if(args.onError){
-                               args["onItem"].call(args.scope || dojo.global, new Error("Item Not Found: " + id), args);
-                       }
-                       
-                       return args;
-               },
-
-               //Write API Support
-               newItem: function(data, options){
-                       // summary:
-                       //      adds a new item to the store at the specified point.
-                       //      Takes two parameters, data, and options. 
-                       //
-                       //      data: /* object */
-                       //              The data to be added in as an item.  This could be a
-                       //              new javascript object, or it could be an item that 
-                       //              already exists in the store.  If it already exists in the 
-                       //              store, then this will be added as a reference.  
-                       //
-                       //      options: /* object */
-                       //
-                       //              item: /* item */
-                       //                      reference to an existing store item
-                       //
-                       //              attribute: /* string */
-                       //                      attribute to add the item at.  If this is
-                       //                      not provided, the item's id will be used as the
-                       //                      attribute name. If specified attribute is an
-                       //                      array, the new item will be push()d on to the
-                       //                      end of it.
-                       //              oldValue: /* old value of item[attribute]
-                       //              newValue: new value item[attribute]
-
-                       var meta={};
-
-                       //default parent to the store root;
-                       var pInfo ={item:this._data};
-
-                       if (options){
-                               if (options.parent){
-                                       options.item = options.parent;
-                               }
-
-                               dojo.mixin(pInfo, options);
-                       }
-
-                       if (this.idAttribute && !data[this.idAttribute]){
-                               if (this.requireId){throw new Error("requireId is enabled, new items must have an id defined to be added");}
-                               if (this.autoIdentity){
-                                       var newId = this.autoIdPrefix + this._autoId++;
-                                       data[this.idAttribute]=newId;
-                                       meta["autoId"]=true;
-                               }
-                       }       
-
-                       if (!pInfo && !pInfo.attribute && !this.idAttribute && !data[this.idAttribute]){
-                               throw new Error("Adding a new item requires, at a minumum, either the pInfo information, including the pInfo.attribute, or an id on the item in the field identified by idAttribute");
-                       }
-
-                       //pInfo.parent = this._correctReference(pInfo.parent);
-                       //if there is no parent info supplied, default to the store root
-                       //and add to the pInfo.attribute or if that doestn' exist create an
-                       //attribute with the same name as the new items ID 
-                       if(!pInfo.attribute){pInfo.attribute = data[this.idAttribute]}
-
-                       pInfo.oldValue = this._trimItem(pInfo.item[pInfo.attribute]);
-                       if (dojo.isArray(pInfo.item[pInfo.attribute])){
-                               this._setDirty(pInfo.item);
-                               pInfo.item[pInfo.attribute].push(data);
-                       }else{
-                               this._setDirty(pInfo.item);
-                               pInfo.item[pInfo.attribute]=data;
-                       }
-
-                       pInfo.newValue = pInfo.item[pInfo.attribute];
-
-                       //add this item to the index
-                       if(data[this.idAttribute]){this.index[data[this.idAttribute]]=data}
-
-                       this._updateMeta(data, meta)
-
-                       //keep track of all references in the store so we can delete them as necessary
-                       this._addReference(data, pInfo);
-
-                       //mark this new item as dirty
-                       this._setDirty(data);
-
-                       //Notification API
-                       this.onNew(data, pInfo);
-
-                       //returns the original item, now decorated with some meta info
-                       return data;
-               },
-
-               _addReference: function(item, pInfo){
-                       // summary
-                       //      adds meta information to an item containing a reference id
-                       //      so that references can be deleted as necessary, when passed
-                       //      only a string, the string for parent info, it will only
-                       //      it will be treated as a string reference
-
-                       //console.log("_addReference: ", item, pInfo);  
-                       var rid = '_ref_' + this._referenceId++;
-                       if (!item[this.metaLabel]["referenceIds"]){
-                               item[this.metaLabel]["referenceIds"]=[];
-                       }
-
-                       item[this.metaLabel]["referenceIds"].push(rid);
-                       this._references[rid] = pInfo;                          
-               },
-
-               deleteItem: function(item){     
-                       // summary
-                       //      deletes item and any references to that item from the store.
-                       //      If the desire is to delete only one reference, unsetAttribute or
-                       //      setValue is the way to go.
-
-                       item = this._correctReference(item);
-                       console.log("Item: ", item);
-                       if (this.isItem(item)){
-                               while(item[this.metaLabel]["referenceIds"].length>0){
-                                       console.log("refs map: " , this._references);
-                                       console.log("item to delete: ", item);
-                                       var rid = item[this.metaLabel]["referenceIds"].pop();
-                                       var pInfo = this._references[rid];
-
-                                       console.log("deleteItem(): ", pInfo, pInfo.parent);
-                                       parentItem = pInfo.parent;
-                                       var attribute = pInfo.attribute;        
-                                       if(parentItem && parentItem[attribute] && !dojo.isArray(parentItem[attribute])){
-                                               this._setDirty(parentItem);
-                                               this.unsetAttribute(parentItem, attribute);
-                                               delete parentItem[attribute];
-                                       }
-
-                                       if (dojo.isArray(parentItem[attribute])){
-                                               console.log("Parent is array");
-                                               var oldValue = this._trimItem(parentItem[attribute]);
-                                               var found=false;
-                                               for (var i=0; i<parentItem[attribute].length && !found;i++){
-                                                       if (parentItem[attribute][i][this.metaLabel]===item[this.metaLabel]){
-                                                               found=true;     
-                                                       }                       
-                                               }       
-
-                                               if (found){
-                                                       this._setDirty(parentItem);
-                                                       var del =  parentItem[attribute].splice(i-1,1);
-                                                       delete del;
-                                               }
-
-                                               var newValue = this._trimItem(parentItem[attribute]);
-                                               this.onSet(parentItem,attribute,oldValue,newValue);     
-                                       }
-                                       delete this._references[rid];
-
-                               }
-                               this.onDelete(item);            
-                               delete item;
-                       }
-               },
-
-               _setDirty: function(item){
-                       // summary:
-                       //      adds an item to the list of dirty items.  This item
-                       //      contains a reference to the item itself as well as a
-                       //      cloned and trimmed version of old item for use with
-                       //      revert.
-
-                       //if an item is already in the list of dirty items, don't add it again
-                       //or it will overwrite the premodification data set.
-                       for (var i=0; i<this._dirtyItems.length; i++){
-                               if (item[this.idAttribute]==this._dirtyItems[i][this.idAttribute]){
-                                       return; 
-                               }       
-                       }
-
-                       this._dirtyItems.push({item: item, old: this._trimItem(item)});
-                       this._updateMeta(item, {isDirty: true});
-               },
-
-               setValue: function(item, attribute, value){
-                       // summary:
-                       //      sets 'attribute' on 'item' to 'value'
-                       item = this._correctReference(item);
-
-                       this._setDirty(item);
-                       var old = item[attribute] | undefined;
-                       item[attribute]=value;
-                       this.onSet(item,attribute,old,value);
-
-               },
-
-               setValues: function(item, attribute, values){
-                       // summary:
-                       //      sets 'attribute' on 'item' to 'value' value
-                       //      must be an array.
-
-
-                       item = this._correctReference(item);
-                       if (!dojo.isArray(values)){throw new Error("setValues expects to be passed an Array object as its value");}
-                       this._setDirty(item);
-                       var old = item[attribute] || null;
-                       item[attribute]=values
-                       this.onSet(item,attribute,old,values);
-               },
-
-               unsetAttribute: function(item, attribute){
-                       // summary:
-                       //      unsets 'attribute' on 'item'
-
-                       item = this._correctReference(item);
-                       this._setDirty(item);
-                       var old = item[attribute];
-                       delete item[attribute];
-                       this.onSet(item,attribute,old,null);
-               },
-
-               save: function(kwArgs){
-                       // summary:
-                       //      Takes an optional set of keyword Args with
-                       //      some save options.  Currently only format with options
-                       //      being "raw" or "json".  This function goes through
-                       //      the dirty item lists, clones and trims the item down so that
-                       //      the items children are not part of the data (the children are replaced
-                       //      with reference objects). This data is compiled into a single array, the dirty objects
-                       //      are all marked as clean, and the new data is then passed on to the onSave handler.
-
-                       var data = [];
-               
-                       if (!kwArgs){kwArgs={}}
-                       while (this._dirtyItems.length > 0){
-                               var item = this._dirtyItems.pop()["item"];
-                               var t = this._trimItem(item);
-                               var d;  
-                               switch(kwArgs.format){  
-                                       case "json":
-                                               d = dojo.toJson(t);     
-                                               break;
-                                       case "raw":
-                                       default:
-                                               d = t;
-                               }
-                               data.push(d);
-                               this._markClean(item);
-                       }
-
-                       this.onSave(data);
-               },
-
-               _markClean: function(item){
-                       // summary
-                       //      remove this meta information marking an item as "dirty"
-
-                       if (item && item[this.metaLabel] && item[this.metaLabel]["isDirty"]){
-                               delete item[this.metaLabel]["isDirty"];
-                       }       
-               },
-
-               revert: function(){
-                       // summary
-                       //      returns any modified data to its original state prior to a save();
-
-                       while (this._dirtyItems.length>0){
-                               var d = this._dirtyItems.pop();
-                               this._mixin(d.item, d.old);
-                       }
-                       this.onRevert();
-               },
-
-               _mixin: function(target, data){
-                       // summary:
-                       //      specialized mixin that hooks up objects in the store where references are identified.
-
-                       if (dojo.isObject(data)){
-                               if (dojo.isArray(data)){
-                                       while(target.length>0){target.pop();}
-                                       for (var i=0; i<data.length;i++){
-                                               if (dojo.isObject(data[i])){
-                                                       if (dojo.isArray(data[i])){
-                                                               var mix=[];
-                                                       }else{
-                                                               var mix={};
-                                                               if (data[i][this.metaLabel] && data[i][this.metaLabel]["type"] && data[i][this.metaLabel]["type"]=='reference'){
-                                                                       target[i]=this.index[data[i][this.idAttribute]];
-                                                                       continue;
-                                                               }
-                                                       }
-
-                                                       this._mixin(mix, data[i]);
-                                                       target.push(mix);
-                                               }else{
-                                                       target.push(data[i]);
-                                               }
-                                       }       
-                               }else{
-                                       for (var i in target){
-                                               if (i in data){continue;}
-                                               delete target[i];
-                                       }
-
-                                       for (var i in data){
-                                               if (dojo.isObject(data[i])){
-                                                       if (dojo.isArray(data[i])){
-                                                               var mix=[];
-                                                       }else{
-                                                               if (data[i][this.metaLabel] && data[i][this.metaLabel]["type"] && data[i][this.metaLabel]["type"]=='reference'){
-                                                                       target[i]=this.index[data[i][this.idAttribute]];
-                                                                       continue;
-                                                               }
-
-                                                               var mix={};
-                                                       }
-                                                       this._mixin(mix, data[i]);
-                                                       target[i]=mix;
-                                               }else{
-                                                       target[i]=data[i];
-                                               }
-                                       }       
-
-                               }
-                       }
-               },
-
-               isDirty: function(item){
-                       // summary
-                       //      returns true if the item is marked as dirty.
-
-                       item = this._correctReference(item);
-                       return item && item[this.metaLabel] && item[this.metaLabel]["isDirty"];
-               },
-
-               _createReference: function(item){
-                       // summary
-                       //      Create a small reference object that can be used to replace
-                       //      child objects during a trim
-
-                       var obj={};
-                       obj[this.metaLabel]={
-                               type:'reference'
-                       };
-
-                       obj[this.idAttribute]=item[this.idAttribute];
-                       return obj;
-               },
-
-               _trimItem: function(item){
-                       //summary:
-                       //      copy an item recursively stoppying at other items that have id's
-                       //      and replace them with a refrence object;
-                       var copy;
-                       if (dojo.isArray(item)){
-                               copy = [];
-                               for (var i=0; i<item.length;i++){
-                                       if (dojo.isArray(item[i])){
-                                               copy.push(this._trimItem(item[i]))
-                                       }else if (dojo.isObject(item[i])){
-                                               if (item[i]["getFullYear"]){
-                                                       copy.push(dojo.date.stamp.toISOString(item[i]));
-                                               }else if (item[i][this.idAttribute]){
-                                                       copy.push(this._createReference(item[i]));
-                                               }else{
-                                                       copy.push(this._trimItem(item[i]));     
-                                               }
-                                       } else {
-                                               copy.push(item[i]);     
-                                       }
-                               }
-                               return copy;
-                       } 
-
-                       if (dojo.isObject(item)){
-                               copy = {};
-
-                               for (var attr in item){
-                                       if (!item[attr]){ copy[attr]=undefined;continue;}
-                                       if (dojo.isArray(item[attr])){
-                                               copy[attr] = this._trimItem(item[attr]);
-                                       }else if (dojo.isObject(item[attr])){
-                                               if (item[attr]["getFullYear"]){
-                                                       copy[attr] =  dojo.date.stamp.toISOString(item[attr]);
-                                               }else if(item[attr][this.idAttribute]){
-                                                       copy[attr]=this._createReference(item[attr]);
-                                               } else {
-                                                       copy[attr]=this._trimItem(item[attr]);
-                                               }
-                                       } else {
-                                               copy[attr]=item[attr];
-                                       }
-                               }
-                               return copy;
-                       }
-               },
-
-               //Notifcation Support
-
-               onSet: function(){
-               },
-
-               onNew: function(){
-
-               },
-
-               onDelete: function(){
-
-               },      
-       
-               onSave: function(items){
-                       // summary:
-                       //      notification of the save event..not part of the notification api, 
-                       //      but probably should be.
-                       //console.log("onSave() ", items);
-               },
-
-               onRevert: function(){
-                       // summary:
-                       //      notification of the revert event..not part of the notification api, 
-                       //      but probably should be.
-
-               }
-       }
-);
-
-//setup an alias to byId, is there a better way to do this?
-dojox.data.jsonPathStore.byId=dojox.data.jsonPathStore.fetchItemByIdentity;
-
-}