a:51:{s:9:"#provides";s:27:"dojo.data.ItemFileReadStore";s:9:"#resource";s:25:"data/ItemFileReadStore.js";s:9:"#requires";a:3:{i:0;a:2:{i:0;s:6:"common";i:1;s:21:"dojo.data.util.filter";}i:1;a:2:{i:0;s:6:"common";i:1;s:26:"dojo.data.util.simpleFetch";}i:2;a:2:{i:0;s:6:"common";i:1;s:15:"dojo.date.stamp";}}s:27:"dojo.data.ItemFileReadStore";a:6:{s:4:"type";s:8:"Function";s:7:"summary";s:11:"constructor";s:10:"parameters";a:1:{s:17:"keywordParameters";a:2:{s:4:"type";s:6:"Object";s:7:"summary";s:520:"typeMap: object) The structure of the typeMap object is as follows: { type0: function || object, type1: function || object, ... typeN: function || object } Where if it is a function, it is assumed to be an object constructor that takes the value of _value as the initialization parameters. If it is an object, then it is assumed to be an object of general form: { type: function, //constructor. deserialize: function(value) //The function that parses the value and constructs the object defined by type appropriately. }";}}s:6:"source";s:1486:" this._arrayOfAllItems = []; this._arrayOfTopLevelItems = []; this._loadFinished = false; this._jsonFileUrl = keywordParameters.url; this._jsonData = keywordParameters.data; this._datatypeMap = keywordParameters.typeMap || {}; if(!this._datatypeMap['Date']){ //If no default mapping for dates, then set this as default. //We use the dojo.date.stamp here because the ISO format is the 'dojo way' //of generically representing dates. this._datatypeMap['Date'] = { type: Date, deserialize: function(value){ return dojo.date.stamp.fromISOString(value); } }; } this._features = {'dojo.data.api.Read':true, 'dojo.data.api.Identity':true}; this._itemsByIdentity = null; this._storeRefPropName = "_S"; // Default name for the store reference to attach to every item. this._itemNumPropName = "_0"; // Default Item Id for isItem to attach to every item. this._rootItemPropName = "_RI"; // Default Item Id for isItem to attach to every item. this._reverseRefMap = "_RRM"; // Default attribute for constructing a reverse reference map for use with reference integrity this._loadInProgress = false; //Got to track the initial load to prevent duelling loads of the dataset. this._queuedFetches = []; if(keywordParameters.urlPreventCache !== undefined){ this.urlPreventCache = keywordParameters.urlPreventCache?true:false; } if(keywordParameters.clearOnClose){ this.clearOnClose = true; }";s:6:"mixins";a:1:{s:9:"prototype";a:1:{i:0;s:26:"dojo.data.util.simpleFetch";}}s:9:"classlike";b:1;}s:31:"dojo.data.ItemFileReadStore.url";a:2:{s:9:"prototype";s:27:"dojo.data.ItemFileReadStore";s:7:"summary";s:0:"";}s:32:"dojo.data.ItemFileReadStore.data";a:2:{s:9:"prototype";s:27:"dojo.data.ItemFileReadStore";s:7:"summary";s:0:"";}s:35:"dojo.data.ItemFileReadStore.typeMap";a:2:{s:9:"prototype";s:27:"dojo.data.ItemFileReadStore";s:7:"summary";s:0:"";}s:40:"dojo.data.ItemFileReadStore.clearOnClose";a:3:{s:9:"prototype";s:27:"dojo.data.ItemFileReadStore";s:8:"instance";s:27:"dojo.data.ItemFileReadStore";s:7:"summary";s:0:"";}s:43:"dojo.data.ItemFileReadStore.urlPreventCache";a:3:{s:9:"prototype";s:27:"dojo.data.ItemFileReadStore";s:8:"instance";s:27:"dojo.data.ItemFileReadStore";s:7:"summary";s:0:"";}s:41:"dojo.data.ItemFileReadStore._assertIsItem";a:6:{s:9:"prototype";s:27:"dojo.data.ItemFileReadStore";s:4:"type";s:8:"Function";s:10:"parameters";a:1:{s:4:"item";a:2:{s:4:"type";s:4:"item";s:7:"summary";s:50:"The item to test for being contained by the store.";}}s:6:"source";s:105:" if(!this.isItem(item)){ throw new Error("dojo.data.ItemFileReadStore: Invalid item argument."); }";s:7:"summary";s:78:"This function tests whether the item passed in is indeed an item in the store.";s:7:"private";b:1;}s:46:"dojo.data.ItemFileReadStore._assertIsAttribute";a:6:{s:9:"prototype";s:27:"dojo.data.ItemFileReadStore";s:4:"type";s:8:"Function";s:10:"parameters";a:1:{s:9:"attribute";a:2:{s:4:"type";s:21:"attribute-name-string";s:7:"summary";s:55:"The attribute to test for being contained by the store.";}}s:6:"source";s:121:" if(typeof attribute !== "string"){ throw new Error("dojo.data.ItemFileReadStore: Invalid attribute argument."); }";s:7:"summary";s:101:"This function tests whether the item passed in is indeed a valid 'attribute' like type for the store.";s:7:"private";b:1;}s:36:"dojo.data.ItemFileReadStore.getValue";a:6:{s:9:"prototype";s:27:"dojo.data.ItemFileReadStore";s:4:"type";s:8:"Function";s:10:"parameters";a:3:{s:4:"item";a:1:{s:4:"type";s:4:"item";}s:9:"attribute";a:1:{s:4:"type";s:21:"attribute-name-string";}s:12:"defaultValue";a:2:{s:8:"optional";b:1;s:4:"type";s:5:"value";}}s:6:"source";s:109:" var values = this.getValues(item, attribute); return (values.length > 0)?values[0]:defaultValue; // mixed";s:7:"summary";s:33:"See dojo.data.api.Read.getValue()";s:7:"returns";s:5:"mixed";}s:37:"dojo.data.ItemFileReadStore.getValues";a:6:{s:9:"prototype";s:27:"dojo.data.ItemFileReadStore";s:4:"type";s:8:"Function";s:10:"parameters";a:2:{s:4:"item";a:1:{s:4:"type";s:4:"item";}s:9:"attribute";a:1:{s:4:"type";s:21:"attribute-name-string";}}s:6:"source";s:106:" this._assertIsItem(item); this._assertIsAttribute(attribute); return item[attribute] || []; // Array";s:7:"summary";s:34:"See dojo.data.api.Read.getValues()";s:7:"returns";s:5:"Array";}s:41:"dojo.data.ItemFileReadStore.getAttributes";a:6:{s:9:"prototype";s:27:"dojo.data.ItemFileReadStore";s:4:"type";s:8:"Function";s:10:"parameters";a:1:{s:4:"item";a:1:{s:4:"type";s:4:"item";}}s:6:"source";s:372:" this._assertIsItem(item); var attributes = []; for(var key in item){ // Save off only the real item attributes, not the special id marks for O(1) isItem. if((key !== this._storeRefPropName) && (key !== this._itemNumPropName) && (key !== this._rootItemPropName) && (key !== this._reverseRefMap)){ attributes.push(key); } } return attributes; // Array";s:7:"summary";s:38:"See dojo.data.api.Read.getAttributes()";s:7:"returns";s:5:"Array";}s:40:"dojo.data.ItemFileReadStore.hasAttribute";a:5:{s:9:"prototype";s:27:"dojo.data.ItemFileReadStore";s:4:"type";s:8:"Function";s:10:"parameters";a:2:{s:4:"item";a:1:{s:4:"type";s:4:"item";}s:9:"attribute";a:1:{s:4:"type";s:21:"attribute-name-string";}}s:6:"source";s:52:" return this.getValues(item, attribute).length > 0;";s:7:"summary";s:37:"See dojo.data.api.Read.hasAttribute()";}s:41:"dojo.data.ItemFileReadStore.containsValue";a:6:{s:9:"prototype";s:27:"dojo.data.ItemFileReadStore";s:4:"type";s:8:"Function";s:10:"parameters";a:3:{s:4:"item";a:1:{s:4:"type";s:4:"item";}s:9:"attribute";a:1:{s:4:"type";s:21:"attribute-name-string";}s:5:"value";a:1:{s:4:"type";s:8:"anything";}}s:6:"source";s:200:" var regexp = undefined; if(typeof value === "string"){ regexp = dojo.data.util.filter.patternToRegExp(value, false); } return this._containsValue(item, attribute, value, regexp); //boolean.";s:7:"summary";s:38:"See dojo.data.api.Read.containsValue()";s:7:"returns";s:8:"boolean.";}s:42:"dojo.data.ItemFileReadStore._containsValue";a:8:{s:9:"prototype";s:27:"dojo.data.ItemFileReadStore";s:4:"type";s:8:"Function";s:10:"parameters";a:4:{s:4:"item";a:2:{s:4:"type";s:4:"item";s:7:"summary";s:46:"The data item to examine for attribute values.";}s:9:"attribute";a:2:{s:4:"type";s:21:"attribute-name-string";s:7:"summary";s:25:"The attribute to inspect.";}s:5:"value";a:2:{s:4:"type";s:8:"anything";s:7:"summary";s:19:"The value to match.";}s:6:"regexp";a:3:{s:8:"optional";b:1;s:4:"type";s:6:"RegExp";s:7:"summary";s:196:"Optional regular expression generated off value if value was of string type to handle wildcarding. If present and attribute values are string, then it can be used for comparison instead of 'value'";}}s:6:"source";s:310:" return dojo.some(this.getValues(item, attribute), function(possibleValue){ if(possibleValue !== null && !dojo.isObject(possibleValue) && regexp){ if(possibleValue.toString().match(regexp)){ return true; // Boolean } }else if(value === possibleValue){ return true; // Boolean } });";s:7:"summary";s:66:"Internal function for looking at the values contained by the item.";s:11:"description";s:230:"Internal function for looking at the values contained by the item. This function allows for denoting if the comparison should be case sensitive for strings or not (for handling filtering cases where string case should not matter)";s:7:"returns";s:7:"Boolean";s:7:"private";b:1;}s:34:"dojo.data.ItemFileReadStore.isItem";a:6:{s:9:"prototype";s:27:"dojo.data.ItemFileReadStore";s:4:"type";s:8:"Function";s:10:"parameters";a:1:{s:9:"something";a:1:{s:4:"type";s:8:"anything";}}s:6:"source";s:193:" if(something && something[this._storeRefPropName] === this){ if(this._arrayOfAllItems[something[this._itemNumPropName]] === something){ return true; } } return false; // Boolean";s:7:"summary";s:31:"See dojo.data.api.Read.isItem()";s:7:"returns";s:7:"Boolean";}s:40:"dojo.data.ItemFileReadStore.isItemLoaded";a:6:{s:9:"prototype";s:27:"dojo.data.ItemFileReadStore";s:4:"type";s:8:"Function";s:10:"parameters";a:1:{s:9:"something";a:1:{s:4:"type";s:8:"anything";}}s:6:"source";s:42:" return this.isItem(something); //boolean";s:7:"summary";s:37:"See dojo.data.api.Read.isItemLoaded()";s:7:"returns";s:7:"boolean";}s:36:"dojo.data.ItemFileReadStore.loadItem";a:5:{s:9:"prototype";s:27:"dojo.data.ItemFileReadStore";s:4:"type";s:8:"Function";s:10:"parameters";a:1:{s:11:"keywordArgs";a:1:{s:4:"type";s:6:"object";}}s:6:"source";s:39:" this._assertIsItem(keywordArgs.item);";s:7:"summary";s:33:"See dojo.data.api.Read.loadItem()";}s:39:"dojo.data.ItemFileReadStore.getFeatures";a:5:{s:9:"prototype";s:27:"dojo.data.ItemFileReadStore";s:4:"type";s:8:"Function";s:6:"source";s:33:" return this._features; //Object";s:7:"summary";s:36:"See dojo.data.api.Read.getFeatures()";s:7:"returns";s:6:"Object";}s:36:"dojo.data.ItemFileReadStore.getLabel";a:6:{s:9:"prototype";s:27:"dojo.data.ItemFileReadStore";s:4:"type";s:8:"Function";s:10:"parameters";a:1:{s:4:"item";a:1:{s:4:"type";s:4:"item";}}s:6:"source";s:135:" if(this._labelAttr && this.isItem(item)){ return this.getValue(item,this._labelAttr); //String } return undefined; //undefined";s:7:"summary";s:33:"See dojo.data.api.Read.getLabel()";s:7:"returns";s:16:"String|undefined";}s:46:"dojo.data.ItemFileReadStore.getLabelAttributes";a:6:{s:9:"prototype";s:27:"dojo.data.ItemFileReadStore";s:4:"type";s:8:"Function";s:10:"parameters";a:1:{s:4:"item";a:1:{s:4:"type";s:4:"item";}}s:6:"source";s:85:" if(this._labelAttr){ return [this._labelAttr]; //array } return null; //null";s:7:"summary";s:43:"See dojo.data.api.Read.getLabelAttributes()";s:7:"returns";s:10:"array|null";}s:39:"dojo.data.ItemFileReadStore._fetchItems";a:6:{s:9:"prototype";s:27:"dojo.data.ItemFileReadStore";s:4:"type";s:8:"Function";s:10:"parameters";a:3:{s:11:"keywordArgs";a:1:{s:4:"type";s:6:"Object";}s:12:"findCallback";a:1:{s:4:"type";s:8:"Function";}s:13:"errorCallback";a:1:{s:4:"type";s:8:"Function";}}s:6:"source";s:3849:" var self = this; var filter = function(requestArgs, arrayOfItems){ var items = []; var i, key; if(requestArgs.query){ var value; var ignoreCase = requestArgs.queryOptions ? requestArgs.queryOptions.ignoreCase : false; //See if there are any string values that can be regexp parsed first to avoid multiple regexp gens on the //same value for each item examined. Much more efficient. var regexpList = {}; for(key in requestArgs.query){ value = requestArgs.query[key]; if(typeof value === "string"){ regexpList[key] = dojo.data.util.filter.patternToRegExp(value, ignoreCase); } } for(i = 0; i < arrayOfItems.length; ++i){ var match = true; var candidateItem = arrayOfItems[i]; if(candidateItem === null){ match = false; }else{ for(key in requestArgs.query) { value = requestArgs.query[key]; if (!self._containsValue(candidateItem, key, value, regexpList[key])){ match = false; } } } if(match){ items.push(candidateItem); } } findCallback(items, requestArgs); }else{ // We want a copy to pass back in case the parent wishes to sort the array. // We shouldn't allow resort of the internal list, so that multiple callers // can get lists and sort without affecting each other. We also need to // filter out any null values that have been left as a result of deleteItem() // calls in ItemFileWriteStore. for(i = 0; i < arrayOfItems.length; ++i){ var item = arrayOfItems[i]; if(item !== null){ items.push(item); } } findCallback(items, requestArgs); } }; if(this._loadFinished){ filter(keywordArgs, this._getItemsArray(keywordArgs.queryOptions)); }else{ if(this._jsonFileUrl){ //If fetches come in before the loading has finished, but while //a load is in progress, we have to defer the fetching to be //invoked in the callback. if(this._loadInProgress){ this._queuedFetches.push({args: keywordArgs, filter: filter}); }else{ this._loadInProgress = true; var getArgs = { url: self._jsonFileUrl, handleAs: "json-comment-optional", preventCache: this.urlPreventCache }; var getHandler = dojo.xhrGet(getArgs); getHandler.addCallback(function(data){ try{ self._getItemsFromLoadedData(data); self._loadFinished = true; self._loadInProgress = false; filter(keywordArgs, self._getItemsArray(keywordArgs.queryOptions)); self._handleQueuedFetches(); }catch(e){ self._loadFinished = true; self._loadInProgress = false; errorCallback(e, keywordArgs); } }); getHandler.addErrback(function(error){ self._loadInProgress = false; errorCallback(error, keywordArgs); }); //Wire up the cancel to abort of the request //This call cancel on the deferred if it hasn't been called //yet and then will chain to the simple abort of the //simpleFetch keywordArgs var oldAbort = null; if(keywordArgs.abort){ oldAbort = keywordArgs.abort; } keywordArgs.abort = function(){ var df = getHandler; if (df && df.fired === -1){ df.cancel(); df = null; } if(oldAbort){ oldAbort.call(keywordArgs); } }; } }else if(this._jsonData){ try{ this._loadFinished = true; this._getItemsFromLoadedData(this._jsonData); this._jsonData = null; filter(keywordArgs, this._getItemsArray(keywordArgs.queryOptions)); }catch(e){ errorCallback(e, keywordArgs); } }else{ errorCallback(new Error("dojo.data.ItemFileReadStore: No JSON source data was provided as either URL or a nested Javascript object."), keywordArgs); } }";s:7:"summary";s:38:"See dojo.data.util.simpleFetch.fetch()";s:7:"private";b:1;}s:48:"dojo.data.ItemFileReadStore._handleQueuedFetches";a:5:{s:9:"prototype";s:27:"dojo.data.ItemFileReadStore";s:4:"type";s:8:"Function";s:6:"source";s:414:" if (this._queuedFetches.length > 0) { for(var i = 0; i < this._queuedFetches.length; i++){ var fData = this._queuedFetches[i]; var delayedQuery = fData.args; var delayedFilter = fData.filter; if(delayedFilter){ delayedFilter(delayedQuery, this._getItemsArray(delayedQuery.queryOptions)); }else{ this.fetchItemByIdentity(delayedQuery); } } this._queuedFetches = []; }";s:7:"summary";s:92:"Internal function to execute delayed request in the store. Execute any deferred fetches now.";s:7:"private";b:1;}s:42:"dojo.data.ItemFileReadStore._getItemsArray";a:6:{s:9:"prototype";s:27:"dojo.data.ItemFileReadStore";s:4:"type";s:8:"Function";s:10:"parameters";a:1:{s:12:"queryOptions";a:3:{s:8:"optional";b:1;s:4:"type";s:6:"object";s:7:"summary";s:36:"The query options parameter, if any.";}}s:6:"source";s:116:" if(queryOptions && queryOptions.deep) { return this._arrayOfAllItems; } return this._arrayOfTopLevelItems;";s:7:"summary";s:66:"Internal function to determine which list of items to search over.";s:7:"private";b:1;}s:33:"dojo.data.ItemFileReadStore.close";a:5:{s:9:"prototype";s:27:"dojo.data.ItemFileReadStore";s:4:"type";s:8:"Function";s:10:"parameters";a:1:{s:7:"request";a:1:{s:4:"type";s:44:"dojo.data.api.Request || keywordArgs || null";}}s:6:"source";s:450:" if(this.clearOnClose && (this._jsonFileUrl !== "")){ //Reset all internalsback to default state. This will force a reload //on next fetch, but only if the data came from a url. Passed in data //means it should not clear the data. this._arrayOfAllItems = []; this._arrayOfTopLevelItems = []; this._loadFinished = false; this._itemsByIdentity = null; this._loadInProgress = false; this._queuedFetches = []; }";s:7:"summary";s:30:"See dojo.data.api.Read.close()";}s:51:"dojo.data.ItemFileReadStore._getItemsFromLoadedData";a:9:{s:9:"prototype";s:27:"dojo.data.ItemFileReadStore";s:4:"type";s:8:"Function";s:10:"parameters";a:1:{s:10:"dataObject";a:2:{s:4:"type";s:6:"Object";s:7:"summary";s:71:"The JS data object containing the raw data to convery into item format.";}}s:6:"source";s:8805:" var addingArrays = false; function valueIsAnItem(/* anything */ aValue){ // summary: // Given any sort of value that could be in the raw json data, // return true if we should interpret the value as being an // item itself, rather than a literal value or a reference. // example: // | false == valueIsAnItem("Kermit"); // | false == valueIsAnItem(42); // | false == valueIsAnItem(new Date()); // | false == valueIsAnItem({_type:'Date', _value:'May 14, 1802'}); // | false == valueIsAnItem({_reference:'Kermit'}); // | true == valueIsAnItem({name:'Kermit', color:'green'}); // | true == valueIsAnItem({iggy:'pop'}); // | true == valueIsAnItem({foo:42}); var isItem = ( (aValue !== null) && (typeof aValue === "object") && (!dojo.isArray(aValue) || addingArrays) && (!dojo.isFunction(aValue)) && (aValue.constructor == Object || dojo.isArray(aValue)) && (typeof aValue._reference === "undefined") && (typeof aValue._type === "undefined") && (typeof aValue._value === "undefined") ); return isItem; } var self = this; function addItemAndSubItemsToArrayOfAllItems(/* Item */ anItem){ self._arrayOfAllItems.push(anItem); for(var attribute in anItem){ var valueForAttribute = anItem[attribute]; if(valueForAttribute){ if(dojo.isArray(valueForAttribute)){ var valueArray = valueForAttribute; for(var k = 0; k < valueArray.length; ++k){ var singleValue = valueArray[k]; if(valueIsAnItem(singleValue)){ addItemAndSubItemsToArrayOfAllItems(singleValue); } } }else{ if(valueIsAnItem(valueForAttribute)){ addItemAndSubItemsToArrayOfAllItems(valueForAttribute); } } } } } this._labelAttr = dataObject.label; // We need to do some transformations to convert the data structure // that we read from the file into a format that will be convenient // to work with in memory. // Step 1: Walk through the object hierarchy and build a list of all items var i; var item; this._arrayOfAllItems = []; this._arrayOfTopLevelItems = dataObject.items; for(i = 0; i < this._arrayOfTopLevelItems.length; ++i){ item = this._arrayOfTopLevelItems[i]; if(dojo.isArray(item)){ addingArrays = true; } addItemAndSubItemsToArrayOfAllItems(item); item[this._rootItemPropName]=true; } // Step 2: Walk through all the attribute values of all the items, // and replace single values with arrays. For example, we change this: // { name:'Miss Piggy', pets:'Foo-Foo'} // into this: // { name:['Miss Piggy'], pets:['Foo-Foo']} // // We also store the attribute names so we can validate our store // reference and item id special properties for the O(1) isItem var allAttributeNames = {}; var key; for(i = 0; i < this._arrayOfAllItems.length; ++i){ item = this._arrayOfAllItems[i]; for(key in item){ if (key !== this._rootItemPropName) { var value = item[key]; if(value !== null){ if(!dojo.isArray(value)){ item[key] = [value]; } }else{ item[key] = [null]; } } allAttributeNames[key]=key; } } // Step 3: Build unique property names to use for the _storeRefPropName and _itemNumPropName // This should go really fast, it will generally never even run the loop. while(allAttributeNames[this._storeRefPropName]){ this._storeRefPropName += "_"; } while(allAttributeNames[this._itemNumPropName]){ this._itemNumPropName += "_"; } while(allAttributeNames[this._reverseRefMap]){ this._reverseRefMap += "_"; } // Step 4: Some data files specify an optional 'identifier', which is // the name of an attribute that holds the identity of each item. // If this data file specified an identifier attribute, then build a // hash table of items keyed by the identity of the items. var arrayOfValues; var identifier = dataObject.identifier; if(identifier){ this._itemsByIdentity = {}; this._features['dojo.data.api.Identity'] = identifier; for(i = 0; i < this._arrayOfAllItems.length; ++i){ item = this._arrayOfAllItems[i]; arrayOfValues = item[identifier]; var identity = arrayOfValues[0]; if(!this._itemsByIdentity[identity]){ this._itemsByIdentity[identity] = item; }else{ if(this._jsonFileUrl){ throw new Error("dojo.data.ItemFileReadStore: The json data as specified by: [" + this._jsonFileUrl + "] is malformed. Items within the list have identifier: [" + identifier + "]. Value collided: [" + identity + "]"); }else if(this._jsonData){ throw new Error("dojo.data.ItemFileReadStore: The json data provided by the creation arguments is malformed. Items within the list have identifier: [" + identifier + "]. Value collided: [" + identity + "]"); } } } }else{ this._features['dojo.data.api.Identity'] = Number; } // Step 5: Walk through all the items, and set each item's properties // for _storeRefPropName and _itemNumPropName, so that store.isItem() will return true. for(i = 0; i < this._arrayOfAllItems.length; ++i){ item = this._arrayOfAllItems[i]; item[this._storeRefPropName] = this; item[this._itemNumPropName] = i; } // Step 6: We walk through all the attribute values of all the items, // looking for type/value literals and item-references. // // We replace item-references with pointers to items. For example, we change: // { name:['Kermit'], friends:[{_reference:{name:'Miss Piggy'}}] } // into this: // { name:['Kermit'], friends:[miss_piggy] } // (where miss_piggy is the object representing the 'Miss Piggy' item). // // We replace type/value pairs with typed-literals. For example, we change: // { name:['Nelson Mandela'], born:[{_type:'Date', _value:'July 18, 1918'}] } // into this: // { name:['Kermit'], born:(new Date('July 18, 1918')) } // // We also generate the associate map for all items for the O(1) isItem function. for(i = 0; i < this._arrayOfAllItems.length; ++i){ item = this._arrayOfAllItems[i]; // example: { name:['Kermit'], friends:[{_reference:{name:'Miss Piggy'}}] } for(key in item){ arrayOfValues = item[key]; // example: [{_reference:{name:'Miss Piggy'}}] for(var j = 0; j < arrayOfValues.length; ++j) { value = arrayOfValues[j]; // example: {_reference:{name:'Miss Piggy'}} if(value !== null && typeof value == "object"){ if(value._type && value._value){ var type = value._type; // examples: 'Date', 'Color', or 'ComplexNumber' var mappingObj = this._datatypeMap[type]; // examples: Date, dojo.Color, foo.math.ComplexNumber, {type: dojo.Color, deserialize(value){ return new dojo.Color(value)}} if(!mappingObj){ throw new Error("dojo.data.ItemFileReadStore: in the typeMap constructor arg, no object class was specified for the datatype '" + type + "'"); }else if(dojo.isFunction(mappingObj)){ arrayOfValues[j] = new mappingObj(value._value); }else if(dojo.isFunction(mappingObj.deserialize)){ arrayOfValues[j] = mappingObj.deserialize(value._value); }else{ throw new Error("dojo.data.ItemFileReadStore: Value provided in typeMap was neither a constructor, nor a an object with a deserialize function"); } } if(value._reference){ var referenceDescription = value._reference; // example: {name:'Miss Piggy'} if(!dojo.isObject(referenceDescription)){ // example: 'Miss Piggy' // from an item like: { name:['Kermit'], friends:[{_reference:'Miss Piggy'}]} arrayOfValues[j] = this._itemsByIdentity[referenceDescription]; }else{ // example: {name:'Miss Piggy'} // from an item like: { name:['Kermit'], friends:[{_reference:{name:'Miss Piggy'}}] } for(var k = 0; k < this._arrayOfAllItems.length; ++k){ var candidateItem = this._arrayOfAllItems[k]; var found = true; for(var refKey in referenceDescription){ if(candidateItem[refKey] != referenceDescription[refKey]){ found = false; } } if(found){ arrayOfValues[j] = candidateItem; } } } if(this.referenceIntegrity){ var refItem = arrayOfValues[j]; if(this.isItem(refItem)){ this._addReferenceToMap(refItem, item, key); } } }else if(this.isItem(value)){ //It's a child item (not one referenced through _reference). //We need to treat this as a referenced item, so it can be cleaned up //in a write store easily. if(this.referenceIntegrity){ this._addReferenceToMap(value, item, key); } } } } } }";s:7:"summary";s:86:"Function to parse the loaded data into item format and build the internal items array.";s:11:"description";s:86:"Function to parse the loaded data into item format and build the internal items array.";s:14:"return_summary";s:97:"array Array of items in store item format. First, we define a couple little utility functions...";s:7:"returns";s:121:"examples: Date, dojo.Color, foo.math.ComplexNumber, {type: dojo.Color, deserialize(value){ return new dojo.Color(value)}}";s:7:"private";b:1;}s:46:"dojo.data.ItemFileReadStore._addReferenceToMap";a:7:{s:9:"prototype";s:27:"dojo.data.ItemFileReadStore";s:4:"type";s:8:"Function";s:10:"parameters";a:3:{s:7:"refItem";a:2:{s:4:"type";s:4:"item";s:7:"summary";s:28:"The item that is referenced.";}s:10:"parentItem";a:2:{s:4:"type";s:4:"item";s:7:"summary";s:49:"The item that holds the new reference to refItem.";}s:9:"attribute";a:2:{s:4:"type";s:6:"string";s:7:"summary";s:133:"The attribute on parentItem that contains the new reference. Stub function, does nothing. Real processing is in ItemFileWriteStore.";}}s:6:"source";s:474:" // summary: // Method to add an reference map entry for an item and attribute. // description: // Method to add an reference map entry for an item and attribute. // // refItem: // The item that is referenced. // parentItem: // The item that holds the new reference to refItem. // attribute: // The attribute on parentItem that contains the new reference. //Stub function, does nothing. Real processing is in ItemFileWriteStore.";s:7:"summary";s:63:"Method to add an reference map entry for an item and attribute.";s:11:"description";s:69:"Method to add an reference map entry for an item and attribute. //";s:7:"private";b:1;}s:39:"dojo.data.ItemFileReadStore.getIdentity";a:6:{s:9:"prototype";s:27:"dojo.data.ItemFileReadStore";s:4:"type";s:8:"Function";s:10:"parameters";a:1:{s:4:"item";a:1:{s:4:"type";s:4:"item";}}s:6:"source";s:291:" var identifier = this._features['dojo.data.api.Identity']; if(identifier === Number){ return item[this._itemNumPropName]; // Number }else{ var arrayOfValues = item[identifier]; if(arrayOfValues){ return arrayOfValues[0]; // Object || String } } return null; // null";s:7:"summary";s:40:"See dojo.data.api.Identity.getIdentity()";s:7:"returns";s:28:"Number|Object || String|null";}s:47:"dojo.data.ItemFileReadStore.fetchItemByIdentity";a:7:{s:9:"prototype";s:27:"dojo.data.ItemFileReadStore";s:4:"type";s:8:"Function";s:10:"parameters";a:1:{s:11:"keywordArgs";a:1:{s:4:"type";s:6:"Object";}}s:6:"source";s:26546:"dojo.provide("dojo.data.ItemFileReadStore"); dojo.require("dojo.data.util.filter"); dojo.require("dojo.data.util.simpleFetch"); dojo.require("dojo.date.stamp"); dojo.declare("dojo.data.ItemFileReadStore", null,{ // summary: // The ItemFileReadStore implements the dojo.data.api.Read API and reads // data from JSON files that have contents in this format -- // { items: [ // { name:'Kermit', color:'green', age:12, friends:['Gonzo', {_reference:{name:'Fozzie Bear'}}]}, // { name:'Fozzie Bear', wears:['hat', 'tie']}, // { name:'Miss Piggy', pets:'Foo-Foo'} // ]} // Note that it can also contain an 'identifer' property that specified which attribute on the items // in the array of items that acts as the unique identifier for that item. // constructor: function(/* Object */ keywordParameters){ // summary: constructor // keywordParameters: {url: String} // keywordParameters: {data: jsonObject} // keywordParameters: {typeMap: object) // The structure of the typeMap object is as follows: // { // type0: function || object, // type1: function || object, // ... // typeN: function || object // } // Where if it is a function, it is assumed to be an object constructor that takes the // value of _value as the initialization parameters. If it is an object, then it is assumed // to be an object of general form: // { // type: function, //constructor. // deserialize: function(value) //The function that parses the value and constructs the object defined by type appropriately. // } this._arrayOfAllItems = []; this._arrayOfTopLevelItems = []; this._loadFinished = false; this._jsonFileUrl = keywordParameters.url; this._jsonData = keywordParameters.data; this._datatypeMap = keywordParameters.typeMap || {}; if(!this._datatypeMap['Date']){ //If no default mapping for dates, then set this as default. //We use the dojo.date.stamp here because the ISO format is the 'dojo way' //of generically representing dates. this._datatypeMap['Date'] = { type: Date, deserialize: function(value){ return dojo.date.stamp.fromISOString(value); } }; } this._features = {'dojo.data.api.Read':true, 'dojo.data.api.Identity':true}; this._itemsByIdentity = null; this._storeRefPropName = "_S"; // Default name for the store reference to attach to every item. this._itemNumPropName = "_0"; // Default Item Id for isItem to attach to every item. this._rootItemPropName = "_RI"; // Default Item Id for isItem to attach to every item. this._reverseRefMap = "_RRM"; // Default attribute for constructing a reverse reference map for use with reference integrity this._loadInProgress = false; //Got to track the initial load to prevent duelling loads of the dataset. this._queuedFetches = []; if(keywordParameters.urlPreventCache !== undefined){ this.urlPreventCache = keywordParameters.urlPreventCache?true:false; } if(keywordParameters.clearOnClose){ this.clearOnClose = true; } }, url: "", // use "" rather than undefined for the benefit of the parser (#3539) data: null, // define this so that the parser can populate it typeMap: null, //Define so parser can populate. //Parameter to allow users to specify if a close call should force a reload or not. //By default, it retains the old behavior of not clearing if close is called. But //if set true, the store will be reset to default state. Note that by doing this, //all item handles will become invalid and a new fetch must be issued. clearOnClose: false, //Parameter to allow specifying if preventCache should be passed to the xhrGet call or not when loading data from a url. //Note this does not mean the store calls the server on each fetch, only that the data load has preventCache set as an option. //Added for tracker: #6072 urlPreventCache: false, _assertIsItem: function(/* item */ item){ // summary: // This function tests whether the item passed in is indeed an item in the store. // item: // The item to test for being contained by the store. if(!this.isItem(item)){ throw new Error("dojo.data.ItemFileReadStore: Invalid item argument."); } }, _assertIsAttribute: function(/* attribute-name-string */ attribute){ // summary: // This function tests whether the item passed in is indeed a valid 'attribute' like type for the store. // attribute: // The attribute to test for being contained by the store. if(typeof attribute !== "string"){ throw new Error("dojo.data.ItemFileReadStore: Invalid attribute argument."); } }, getValue: function( /* item */ item, /* attribute-name-string */ attribute, /* value? */ defaultValue){ // summary: // See dojo.data.api.Read.getValue() var values = this.getValues(item, attribute); return (values.length > 0)?values[0]:defaultValue; // mixed }, getValues: function(/* item */ item, /* attribute-name-string */ attribute){ // summary: // See dojo.data.api.Read.getValues() this._assertIsItem(item); this._assertIsAttribute(attribute); return item[attribute] || []; // Array }, getAttributes: function(/* item */ item){ // summary: // See dojo.data.api.Read.getAttributes() this._assertIsItem(item); var attributes = []; for(var key in item){ // Save off only the real item attributes, not the special id marks for O(1) isItem. if((key !== this._storeRefPropName) && (key !== this._itemNumPropName) && (key !== this._rootItemPropName) && (key !== this._reverseRefMap)){ attributes.push(key); } } return attributes; // Array }, hasAttribute: function( /* item */ item, /* attribute-name-string */ attribute) { // summary: // See dojo.data.api.Read.hasAttribute() return this.getValues(item, attribute).length > 0; }, containsValue: function(/* item */ item, /* attribute-name-string */ attribute, /* anything */ value){ // summary: // See dojo.data.api.Read.containsValue() var regexp = undefined; if(typeof value === "string"){ regexp = dojo.data.util.filter.patternToRegExp(value, false); } return this._containsValue(item, attribute, value, regexp); //boolean. }, _containsValue: function( /* item */ item, /* attribute-name-string */ attribute, /* anything */ value, /* RegExp?*/ regexp){ // summary: // Internal function for looking at the values contained by the item. // description: // Internal function for looking at the values contained by the item. This // function allows for denoting if the comparison should be case sensitive for // strings or not (for handling filtering cases where string case should not matter) // // item: // The data item to examine for attribute values. // attribute: // The attribute to inspect. // value: // The value to match. // regexp: // Optional regular expression generated off value if value was of string type to handle wildcarding. // If present and attribute values are string, then it can be used for comparison instead of 'value' return dojo.some(this.getValues(item, attribute), function(possibleValue){ if(possibleValue !== null && !dojo.isObject(possibleValue) && regexp){ if(possibleValue.toString().match(regexp)){ return true; // Boolean } }else if(value === possibleValue){ return true; // Boolean } }); }, isItem: function(/* anything */ something){ // summary: // See dojo.data.api.Read.isItem() if(something && something[this._storeRefPropName] === this){ if(this._arrayOfAllItems[something[this._itemNumPropName]] === something){ return true; } } return false; // Boolean }, isItemLoaded: function(/* anything */ something){ // summary: // See dojo.data.api.Read.isItemLoaded() return this.isItem(something); //boolean }, loadItem: function(/* object */ keywordArgs){ // summary: // See dojo.data.api.Read.loadItem() this._assertIsItem(keywordArgs.item); }, getFeatures: function(){ // summary: // See dojo.data.api.Read.getFeatures() return this._features; //Object }, getLabel: function(/* item */ item){ // summary: // See dojo.data.api.Read.getLabel() if(this._labelAttr && this.isItem(item)){ return this.getValue(item,this._labelAttr); //String } return undefined; //undefined }, getLabelAttributes: function(/* item */ item){ // summary: // See dojo.data.api.Read.getLabelAttributes() if(this._labelAttr){ return [this._labelAttr]; //array } return null; //null }, _fetchItems: function( /* Object */ keywordArgs, /* Function */ findCallback, /* Function */ errorCallback){ // summary: // See dojo.data.util.simpleFetch.fetch() var self = this; var filter = function(requestArgs, arrayOfItems){ var items = []; var i, key; if(requestArgs.query){ var value; var ignoreCase = requestArgs.queryOptions ? requestArgs.queryOptions.ignoreCase : false; //See if there are any string values that can be regexp parsed first to avoid multiple regexp gens on the //same value for each item examined. Much more efficient. var regexpList = {}; for(key in requestArgs.query){ value = requestArgs.query[key]; if(typeof value === "string"){ regexpList[key] = dojo.data.util.filter.patternToRegExp(value, ignoreCase); } } for(i = 0; i < arrayOfItems.length; ++i){ var match = true; var candidateItem = arrayOfItems[i]; if(candidateItem === null){ match = false; }else{ for(key in requestArgs.query) { value = requestArgs.query[key]; if (!self._containsValue(candidateItem, key, value, regexpList[key])){ match = false; } } } if(match){ items.push(candidateItem); } } findCallback(items, requestArgs); }else{ // We want a copy to pass back in case the parent wishes to sort the array. // We shouldn't allow resort of the internal list, so that multiple callers // can get lists and sort without affecting each other. We also need to // filter out any null values that have been left as a result of deleteItem() // calls in ItemFileWriteStore. for(i = 0; i < arrayOfItems.length; ++i){ var item = arrayOfItems[i]; if(item !== null){ items.push(item); } } findCallback(items, requestArgs); } }; if(this._loadFinished){ filter(keywordArgs, this._getItemsArray(keywordArgs.queryOptions)); }else{ if(this._jsonFileUrl){ //If fetches come in before the loading has finished, but while //a load is in progress, we have to defer the fetching to be //invoked in the callback. if(this._loadInProgress){ this._queuedFetches.push({args: keywordArgs, filter: filter}); }else{ this._loadInProgress = true; var getArgs = { url: self._jsonFileUrl, handleAs: "json-comment-optional", preventCache: this.urlPreventCache }; var getHandler = dojo.xhrGet(getArgs); getHandler.addCallback(function(data){ try{ self._getItemsFromLoadedData(data); self._loadFinished = true; self._loadInProgress = false; filter(keywordArgs, self._getItemsArray(keywordArgs.queryOptions)); self._handleQueuedFetches(); }catch(e){ self._loadFinished = true; self._loadInProgress = false; errorCallback(e, keywordArgs); } }); getHandler.addErrback(function(error){ self._loadInProgress = false; errorCallback(error, keywordArgs); }); //Wire up the cancel to abort of the request //This call cancel on the deferred if it hasn't been called //yet and then will chain to the simple abort of the //simpleFetch keywordArgs var oldAbort = null; if(keywordArgs.abort){ oldAbort = keywordArgs.abort; } keywordArgs.abort = function(){ var df = getHandler; if (df && df.fired === -1){ df.cancel(); df = null; } if(oldAbort){ oldAbort.call(keywordArgs); } }; } }else if(this._jsonData){ try{ this._loadFinished = true; this._getItemsFromLoadedData(this._jsonData); this._jsonData = null; filter(keywordArgs, this._getItemsArray(keywordArgs.queryOptions)); }catch(e){ errorCallback(e, keywordArgs); } }else{ errorCallback(new Error("dojo.data.ItemFileReadStore: No JSON source data was provided as either URL or a nested Javascript object."), keywordArgs); } } }, _handleQueuedFetches: function(){ // summary: // Internal function to execute delayed request in the store. //Execute any deferred fetches now. if (this._queuedFetches.length > 0) { for(var i = 0; i < this._queuedFetches.length; i++){ var fData = this._queuedFetches[i]; var delayedQuery = fData.args; var delayedFilter = fData.filter; if(delayedFilter){ delayedFilter(delayedQuery, this._getItemsArray(delayedQuery.queryOptions)); }else{ this.fetchItemByIdentity(delayedQuery); } } this._queuedFetches = []; } }, _getItemsArray: function(/*object?*/queryOptions){ // summary: // Internal function to determine which list of items to search over. // queryOptions: The query options parameter, if any. if(queryOptions && queryOptions.deep) { return this._arrayOfAllItems; } return this._arrayOfTopLevelItems; }, close: function(/*dojo.data.api.Request || keywordArgs || null */ request){ // summary: // See dojo.data.api.Read.close() if(this.clearOnClose && (this._jsonFileUrl !== "")){ //Reset all internalsback to default state. This will force a reload //on next fetch, but only if the data came from a url. Passed in data //means it should not clear the data. this._arrayOfAllItems = []; this._arrayOfTopLevelItems = []; this._loadFinished = false; this._itemsByIdentity = null; this._loadInProgress = false; this._queuedFetches = []; } }, _getItemsFromLoadedData: function(/* Object */ dataObject){ // summary: // Function to parse the loaded data into item format and build the internal items array. // description: // Function to parse the loaded data into item format and build the internal items array. // // dataObject: // The JS data object containing the raw data to convery into item format. // // returns: array // Array of items in store item format. // First, we define a couple little utility functions... var addingArrays = false; function valueIsAnItem(/* anything */ aValue){ // summary: // Given any sort of value that could be in the raw json data, // return true if we should interpret the value as being an // item itself, rather than a literal value or a reference. // example: // | false == valueIsAnItem("Kermit"); // | false == valueIsAnItem(42); // | false == valueIsAnItem(new Date()); // | false == valueIsAnItem({_type:'Date', _value:'May 14, 1802'}); // | false == valueIsAnItem({_reference:'Kermit'}); // | true == valueIsAnItem({name:'Kermit', color:'green'}); // | true == valueIsAnItem({iggy:'pop'}); // | true == valueIsAnItem({foo:42}); var isItem = ( (aValue !== null) && (typeof aValue === "object") && (!dojo.isArray(aValue) || addingArrays) && (!dojo.isFunction(aValue)) && (aValue.constructor == Object || dojo.isArray(aValue)) && (typeof aValue._reference === "undefined") && (typeof aValue._type === "undefined") && (typeof aValue._value === "undefined") ); return isItem; } var self = this; function addItemAndSubItemsToArrayOfAllItems(/* Item */ anItem){ self._arrayOfAllItems.push(anItem); for(var attribute in anItem){ var valueForAttribute = anItem[attribute]; if(valueForAttribute){ if(dojo.isArray(valueForAttribute)){ var valueArray = valueForAttribute; for(var k = 0; k < valueArray.length; ++k){ var singleValue = valueArray[k]; if(valueIsAnItem(singleValue)){ addItemAndSubItemsToArrayOfAllItems(singleValue); } } }else{ if(valueIsAnItem(valueForAttribute)){ addItemAndSubItemsToArrayOfAllItems(valueForAttribute); } } } } } this._labelAttr = dataObject.label; // We need to do some transformations to convert the data structure // that we read from the file into a format that will be convenient // to work with in memory. // Step 1: Walk through the object hierarchy and build a list of all items var i; var item; this._arrayOfAllItems = []; this._arrayOfTopLevelItems = dataObject.items; for(i = 0; i < this._arrayOfTopLevelItems.length; ++i){ item = this._arrayOfTopLevelItems[i]; if(dojo.isArray(item)){ addingArrays = true; } addItemAndSubItemsToArrayOfAllItems(item); item[this._rootItemPropName]=true; } // Step 2: Walk through all the attribute values of all the items, // and replace single values with arrays. For example, we change this: // { name:'Miss Piggy', pets:'Foo-Foo'} // into this: // { name:['Miss Piggy'], pets:['Foo-Foo']} // // We also store the attribute names so we can validate our store // reference and item id special properties for the O(1) isItem var allAttributeNames = {}; var key; for(i = 0; i < this._arrayOfAllItems.length; ++i){ item = this._arrayOfAllItems[i]; for(key in item){ if (key !== this._rootItemPropName) { var value = item[key]; if(value !== null){ if(!dojo.isArray(value)){ item[key] = [value]; } }else{ item[key] = [null]; } } allAttributeNames[key]=key; } } // Step 3: Build unique property names to use for the _storeRefPropName and _itemNumPropName // This should go really fast, it will generally never even run the loop. while(allAttributeNames[this._storeRefPropName]){ this._storeRefPropName += "_"; } while(allAttributeNames[this._itemNumPropName]){ this._itemNumPropName += "_"; } while(allAttributeNames[this._reverseRefMap]){ this._reverseRefMap += "_"; } // Step 4: Some data files specify an optional 'identifier', which is // the name of an attribute that holds the identity of each item. // If this data file specified an identifier attribute, then build a // hash table of items keyed by the identity of the items. var arrayOfValues; var identifier = dataObject.identifier; if(identifier){ this._itemsByIdentity = {}; this._features['dojo.data.api.Identity'] = identifier; for(i = 0; i < this._arrayOfAllItems.length; ++i){ item = this._arrayOfAllItems[i]; arrayOfValues = item[identifier]; var identity = arrayOfValues[0]; if(!this._itemsByIdentity[identity]){ this._itemsByIdentity[identity] = item; }else{ if(this._jsonFileUrl){ throw new Error("dojo.data.ItemFileReadStore: The json data as specified by: [" + this._jsonFileUrl + "] is malformed. Items within the list have identifier: [" + identifier + "]. Value collided: [" + identity + "]"); }else if(this._jsonData){ throw new Error("dojo.data.ItemFileReadStore: The json data provided by the creation arguments is malformed. Items within the list have identifier: [" + identifier + "]. Value collided: [" + identity + "]"); } } } }else{ this._features['dojo.data.api.Identity'] = Number; } // Step 5: Walk through all the items, and set each item's properties // for _storeRefPropName and _itemNumPropName, so that store.isItem() will return true. for(i = 0; i < this._arrayOfAllItems.length; ++i){ item = this._arrayOfAllItems[i]; item[this._storeRefPropName] = this; item[this._itemNumPropName] = i; } // Step 6: We walk through all the attribute values of all the items, // looking for type/value literals and item-references. // // We replace item-references with pointers to items. For example, we change: // { name:['Kermit'], friends:[{_reference:{name:'Miss Piggy'}}] } // into this: // { name:['Kermit'], friends:[miss_piggy] } // (where miss_piggy is the object representing the 'Miss Piggy' item). // // We replace type/value pairs with typed-literals. For example, we change: // { name:['Nelson Mandela'], born:[{_type:'Date', _value:'July 18, 1918'}] } // into this: // { name:['Kermit'], born:(new Date('July 18, 1918')) } // // We also generate the associate map for all items for the O(1) isItem function. for(i = 0; i < this._arrayOfAllItems.length; ++i){ item = this._arrayOfAllItems[i]; // example: { name:['Kermit'], friends:[{_reference:{name:'Miss Piggy'}}] } for(key in item){ arrayOfValues = item[key]; // example: [{_reference:{name:'Miss Piggy'}}] for(var j = 0; j < arrayOfValues.length; ++j) { value = arrayOfValues[j]; // example: {_reference:{name:'Miss Piggy'}} if(value !== null && typeof value == "object"){ if(value._type && value._value){ var type = value._type; // examples: 'Date', 'Color', or 'ComplexNumber' var mappingObj = this._datatypeMap[type]; // examples: Date, dojo.Color, foo.math.ComplexNumber, {type: dojo.Color, deserialize(value){ return new dojo.Color(value)}} if(!mappingObj){ throw new Error("dojo.data.ItemFileReadStore: in the typeMap constructor arg, no object class was specified for the datatype '" + type + "'"); }else if(dojo.isFunction(mappingObj)){ arrayOfValues[j] = new mappingObj(value._value); }else if(dojo.isFunction(mappingObj.deserialize)){ arrayOfValues[j] = mappingObj.deserialize(value._value); }else{ throw new Error("dojo.data.ItemFileReadStore: Value provided in typeMap was neither a constructor, nor a an object with a deserialize function"); } } if(value._reference){ var referenceDescription = value._reference; // example: {name:'Miss Piggy'} if(!dojo.isObject(referenceDescription)){ // example: 'Miss Piggy' // from an item like: { name:['Kermit'], friends:[{_reference:'Miss Piggy'}]} arrayOfValues[j] = this._itemsByIdentity[referenceDescription]; }else{ // example: {name:'Miss Piggy'} // from an item like: { name:['Kermit'], friends:[{_reference:{name:'Miss Piggy'}}] } for(var k = 0; k < this._arrayOfAllItems.length; ++k){ var candidateItem = this._arrayOfAllItems[k]; var found = true; for(var refKey in referenceDescription){ if(candidateItem[refKey] != referenceDescription[refKey]){ found = false; } } if(found){ arrayOfValues[j] = candidateItem; } } } if(this.referenceIntegrity){ var refItem = arrayOfValues[j]; if(this.isItem(refItem)){ this._addReferenceToMap(refItem, item, key); } } }else if(this.isItem(value)){ //It's a child item (not one referenced through _reference). //We need to treat this as a referenced item, so it can be cleaned up //in a write store easily. if(this.referenceIntegrity){ this._addReferenceToMap(value, item, key); } } } } } } }, _addReferenceToMap: function(/*item*/ refItem, /*item*/ parentItem, /*string*/ attribute){ // summary: // Method to add an reference map entry for an item and attribute. // description: // Method to add an reference map entry for an item and attribute. // // refItem: // The item that is referenced. // parentItem: // The item that holds the new reference to refItem. // attribute: // The attribute on parentItem that contains the new reference. //Stub function, does nothing. Real processing is in ItemFileWriteStore. }, getIdentity: function(/* item */ item){ // summary: // See dojo.data.api.Identity.getIdentity() var identifier = this._features['dojo.data.api.Identity']; if(identifier === Number){ return item[this._itemNumPropName]; // Number }else{ var arrayOfValues = item[identifier]; if(arrayOfValues){ return arrayOfValues[0]; // Object || String } } return null; // null }, fetchItemByIdentity: function(/* Object */ keywordArgs){ // summary: // See dojo.data.api.Identity.fetchItemByIdentity() // Hasn't loaded yet, we have to trigger the load. var item; var scope; if(!this._loadFinished){ var self = this; if(this._jsonFileUrl){ if(this._loadInProgress){ this._queuedFetches.push({args: keywordArgs}); }else{ this._loadInProgress = true; var getArgs = { url: self._jsonFileUrl, handleAs: "json-comment-optional", preventCache: this.urlPreventCache }; var getHandler = dojo.xhrGet(getArgs); getHandler.addCallback(function(data){ var scope = keywordArgs.scope?keywordArgs.scope:dojo.global; try{ self._getItemsFromLoadedData(data); self._loadFinished = true; self._loadInProgress = false; item = self._getItemByIdentity(keywordArgs.identity); if(keywordArgs.onItem){ keywordArgs.onItem.call(scope, item); } self._handleQueuedFetches(); }catch(error){ self._loadInProgress = false; if(keywordArgs.onError){ keywordArgs.onError.call(scope, error); } } }); getHandler.addErrback(function(error){ self._loadInProgress = false; if(keywordArgs.onError){ var scope = keywordArgs.scope?keywordArgs.scope:dojo.global; keywordArgs.onError.call(scope, error); } }); } }else if(this._jsonData){ // Passed in data, no need to xhr. self._getItemsFromLoadedData(self._jsonData); self._jsonData = null; self._loadFinished = true; item = self._getItemByIdentity(keywordArgs.identity); if(keywordArgs.onItem){ scope = keywordArgs.scope?keywordArgs.scope:dojo.global; keywordArgs.onItem.call(scope, item); } } }else{ // Already loaded. We can just look it up and call back. item = this._getItemByIdentity(keywordArgs.identity); if(keywordArgs.onItem){ scope = keywordArgs.scope?keywordArgs.scope:dojo.global; keywordArgs.onItem.call(scope, item); } }";s:7:"returns";s:217:"mixed|Array|boolean.|Boolean|boolean|Object|String|undefined|array|null|examples: Date, dojo.Color, foo.math.ComplexNumber, {type: dojo.Color, deserialize(value){ return new dojo.Color(value)}}|Number|Object || String";s:6:"chains";a:1:{s:4:"call";a:2:{i:0;s:18:"keywordArgs.onItem";i:1;s:19:"keywordArgs.onError";}}s:7:"summary";s:0:"";}s:46:"dojo.data.ItemFileReadStore._getItemByIdentity";a:7:{s:9:"prototype";s:27:"dojo.data.ItemFileReadStore";s:4:"type";s:8:"Function";s:10:"parameters";a:1:{s:8:"identity";a:1:{s:4:"type";s:6:"Object";}}s:6:"source";s:217:" var item = null; if(this._itemsByIdentity){ item = this._itemsByIdentity[identity]; }else{ item = this._arrayOfAllItems[identity]; } if(item === undefined){ item = null; } return item; // Object";s:7:"summary";s:57:"Internal function to look an item up by its identity map.";s:7:"returns";s:6:"Object";s:7:"private";b:1;}s:49:"dojo.data.ItemFileReadStore.getIdentityAttributes";a:6:{s:9:"prototype";s:27:"dojo.data.ItemFileReadStore";s:4:"type";s:8:"Function";s:10:"parameters";a:1:{s:4:"item";a:1:{s:4:"type";s:4:"item";}}s:6:"source";s:393:" var identifier = this._features['dojo.data.api.Identity']; if(identifier === Number){ // If (identifier === Number) it means getIdentity() just returns // an integer item-number for each item. The dojo.data.api.Identity // spec says we need to return null if the identity is not composed // of attributes return null; // null }else{ return [identifier]; // Array }";s:7:"summary";s:52:"See dojo.data.api.Identity.getIdentifierAttributes()";s:7:"returns";s:10:"null|Array";}s:38:"dojo.data.ItemFileReadStore._forceLoad";a:5:{s:9:"prototype";s:27:"dojo.data.ItemFileReadStore";s:4:"type";s:8:"Function";s:6:"source";s:1468:" var self = this; if(this._jsonFileUrl){ var getArgs = { url: self._jsonFileUrl, handleAs: "json-comment-optional", preventCache: this.urlPreventCache, sync: true }; var getHandler = dojo.xhrGet(getArgs); getHandler.addCallback(function(data){ try{ //Check to be sure there wasn't another load going on concurrently //So we don't clobber data that comes in on it. If there is a load going on //then do not save this data. It will potentially clobber current data. //We mainly wanted to sync/wait here. //TODO: Revisit the loading scheme of this store to improve multi-initial //request handling. if(self._loadInProgress !== true && !self._loadFinished){ self._getItemsFromLoadedData(data); self._loadFinished = true; }else if(self._loadInProgress){ //Okay, we hit an error state we can't recover from. A forced load occurred //while an async load was occurring. Since we cannot block at this point, the best //that can be managed is to throw an error. throw new Error("dojo.data.ItemFileReadStore: Unable to perform a synchronous load, an async load is in progress."); } }catch(e){ console.log(e); throw e; } }); getHandler.addErrback(function(error){ throw error; }); }else if(this._jsonData){ self._getItemsFromLoadedData(self._jsonData); self._jsonData = null; self._loadFinished = true; } ";s:7:"summary";s:132:"Internal function to force a load of the store if it hasn't occurred yet. This is required for specific functions to work properly.";s:7:"private";b:1;}s:43:"dojo.data.ItemFileReadStore._loadInProgress";a:3:{s:8:"instance";s:27:"dojo.data.ItemFileReadStore";s:7:"private";b:1;s:7:"summary";s:0:"";}s:41:"dojo.data.ItemFileReadStore._loadFinished";a:3:{s:8:"instance";s:27:"dojo.data.ItemFileReadStore";s:7:"private";b:1;s:7:"summary";s:0:"";}s:37:"dojo.data.ItemFileReadStore._jsonData";a:3:{s:8:"instance";s:27:"dojo.data.ItemFileReadStore";s:7:"private";b:1;s:7:"summary";s:0:"";}s:42:"dojo.data.ItemFileReadStore._queuedFetches";a:3:{s:8:"instance";s:27:"dojo.data.ItemFileReadStore";s:7:"private";b:1;s:7:"summary";s:0:"";}s:44:"dojo.data.ItemFileReadStore._arrayOfAllItems";a:3:{s:8:"instance";s:27:"dojo.data.ItemFileReadStore";s:7:"private";b:1;s:7:"summary";s:0:"";}s:49:"dojo.data.ItemFileReadStore._arrayOfTopLevelItems";a:3:{s:8:"instance";s:27:"dojo.data.ItemFileReadStore";s:7:"private";b:1;s:7:"summary";s:0:"";}s:44:"dojo.data.ItemFileReadStore._itemsByIdentity";a:3:{s:8:"instance";s:27:"dojo.data.ItemFileReadStore";s:7:"private";b:1;s:7:"summary";s:0:"";}s:38:"dojo.data.ItemFileReadStore._labelAttr";a:3:{s:8:"instance";s:27:"dojo.data.ItemFileReadStore";s:7:"private";b:1;s:7:"summary";s:0:"";}s:40:"dojo.data.ItemFileReadStore._jsonFileUrl";a:3:{s:8:"instance";s:27:"dojo.data.ItemFileReadStore";s:7:"private";b:1;s:7:"summary";s:0:"";}s:40:"dojo.data.ItemFileReadStore._datatypeMap";a:3:{s:8:"instance";s:27:"dojo.data.ItemFileReadStore";s:7:"private";b:1;s:7:"summary";s:0:"";}s:37:"dojo.data.ItemFileReadStore._features";a:3:{s:8:"instance";s:27:"dojo.data.ItemFileReadStore";s:7:"private";b:1;s:7:"summary";s:0:"";}s:45:"dojo.data.ItemFileReadStore._storeRefPropName";a:3:{s:8:"instance";s:27:"dojo.data.ItemFileReadStore";s:7:"private";b:1;s:7:"summary";s:0:"";}s:44:"dojo.data.ItemFileReadStore._itemNumPropName";a:3:{s:8:"instance";s:27:"dojo.data.ItemFileReadStore";s:7:"private";b:1;s:7:"summary";s:0:"";}s:45:"dojo.data.ItemFileReadStore._rootItemPropName";a:3:{s:8:"instance";s:27:"dojo.data.ItemFileReadStore";s:7:"private";b:1;s:7:"summary";s:0:"";}s:42:"dojo.data.ItemFileReadStore._reverseRefMap";a:3:{s:8:"instance";s:27:"dojo.data.ItemFileReadStore";s:7:"private";b:1;s:7:"summary";s:0:"";}s:9:"dojo.data";a:2:{s:4:"type";s:6:"Object";s:7:"summary";s:0:"";}s:4:"dojo";a:2:{s:4:"type";s:6:"Object";s:7:"summary";s:0:"";}}