dataschema-json.js revision 3a38d5b7ad9ebee258ce6cb2ebe712f058ea27c5
69N/A * The DataSchema utility provides a common configurable interface for widgets to 69N/A * apply a given schema to a variety of data. 69N/A * @module dataschema 69N/A * JSON subclass for the YUI DataSchema utility. 69N/A * @extends DataSchema.Base 69N/A ///////////////////////////////////////////////////////////////////////////// 69N/A ///////////////////////////////////////////////////////////////////////////// 69N/A * Returns string name. 69N/A * @return {String} String representation for this object. 69N/A * Utility function converts JSON locator strings into walkable paths 69N/A * @param locator {String} JSON value locator. 69N/A * @return {String[]} Walkable path to data value. 69N/A // Strip the ["string keys"] and [1] array indexes 69N/A function (x,$1,$2) {keys[i]=$2;return '.@
'+(i++);}). 69N/A replace(/\[(\d+)\]/g, 69N/A function (x,$1) {keys[i]=parseInt($1,10)|0;return '.@
'+(i++);}). 69N/A replace(/^\./,''); // remove leading dot 69N/A // Validate against problematic characters. 69N/A if (!/[^\w\.\$@]/.test(locator)) { 69N/A path = locator.split('.
'); 69N/A for (i=path.length-1; i >= 0; --i) { 69N/A if (path[i].charAt(0) === '@
') { 69N/A path[i] = keys[parseInt(path[i].substr(1),10)]; 69N/A * Utility function to walk a path and return the value located there. 69N/A * @param path {String[]} Locator path. 69N/A * @param data {String} Data to traverse. 72N/A * @return {Object} Data value at location. 69N/A getLocationValue: function (path, data) { 69N/A data = data[path[i]]; 69N/A * Applies a given schema to given JSON data. 69N/A * @param schema {Object} Schema to apply. 69N/A * @param data {Object} JSON data. 69N/A * @return {Object} Schema-parsed data. 69N/A apply: function(schema, data) { 69N/A var data_in = data, 69N/A data_out = {results:[],meta:{}}; 69N/A // Convert incoming JSON strings 69N/A if(!LANG.isObject(data)) { 69N/A data_out.error = e; 69N/A if(LANG.isObject(data_in) && schema) { 69N/A // Parse results data 69N/A if(!LANG.isUndefined(schema.resultsLocator)) { 69N/A data_out = SchemaJSON._parseResults(schema, data_in, data_out); 69N/A if(!LANG.isUndefined(schema.metaFields)) { 69N/A data_out = SchemaJSON._parseMeta(schema.metaFields, data_in, data_out); 69N/A data_out.error = new Error(this.toString() + " Schema parse failure"); 69N/A * Schema-parsed list of results from full data 69N/A * @method _parseResults 69N/A * @param schema {Object} Schema to parse against. 69N/A * @param json_in {Object} JSON to parse. 69N/A * @param data_out {Object} In-progress parsed data to update. 69N/A * @return {Object} Parsed data object. _parseResults: function(schema, json_in, data_out) { if(schema.resultsLocator) { path = SchemaJSON.getPath(schema.resultsLocator); results = SchemaJSON.getLocationValue(path, json_in); if (results === undefined) { error = new Error(this.toString() + " Results retrieval failure"); if(LANG.isArray(schema.resultsFields) && LANG.isArray(results)) { data_out = SchemaJSON._getFieldValues(schema.resultsFields, results, data_out); error = new Error(this.toString() + " Fields retrieval failure"); error = new Error(this.toString() + " Results locator failure"); * Get field data values out of list of full results * @method _getFieldValues * @param fields {Array} Fields to find. * @param array_in {Array} Results to parse. * @param data_out {Object} In-progress parsed data to update. * @return {Object} Parsed data object. _getFieldValues: function(fields, array_in, data_out) { field, key, path, parser, simplePaths = [], complexPaths = [], fieldParsers = [], // First collect hashes of simple paths, complex paths, and parsers field = fields[i]; // A field can be a simple string or a hash key = field.key || field; // Find the key // Validate and store locators for later path = SchemaJSON.getPath(key); simplePaths[simplePaths.length] = {key:key, path:path[0]}; complexPaths[complexPaths.length] = {key:key, path:path}; // Validate and store parsers for later //TODO: use Y.DataSchema.parse? parser = (LANG.isFunction(field.parser)) ? field.parser : Y.Parsers[field.parser+'']; fieldParsers[fieldParsers.length] = {key:key, parser:parser}; // Traverse list of array_in, creating records of simple fields, // complex fields, and applying parsers as necessary for (i=array_in.length-1; i>=0; --i) { // Cycle through simpleLocators for (j=simplePaths.length-1; j>=0; --j) { // Bug 1777850: The result might be an array instead of object record[simplePaths[j].key] = Y.DataSchema.Base.parse( (LANG.isUndefined(result[simplePaths[j].path]) ? result[j] : result[simplePaths[j].path]), simplePaths[j]); // Cycle through complexLocators for (j=complexPaths.length - 1; j>=0; --j) { record[complexPaths[j].key] = Y.DataSchema.Base.parse( (SchemaJSON.getLocationValue(complexPaths[j].path, result)), complexPaths[j] ); // Cycle through fieldParsers for (j=fieldParsers.length-1; j>=0; --j) { key = fieldParsers[j].key; record[key] = fieldParsers[j].parser(record[key]); if (LANG.isUndefined(record[key])) { data_out.results = results; * Parses results data according to schema * @param metaFields {Object} Metafields definitions. * @param json_in {Object} JSON to parse. * @param data_out {Object} In-progress parsed data to update. * @return {Object} Schema-parsed meta data. _parseMeta: function(metaFields, json_in, data_out) { if(LANG.isObject(metaFields)) { if (metaFields.hasOwnProperty(key)) { path = SchemaJSON.getPath(metaFields[key]); data_out.meta[key] = SchemaJSON.getLocationValue(path, json_in); data_out.error = new Error(this.toString() + " Meta retrieval failure");