/* Copyright (c) 2010, Yahoo! Inc. All rights reserved. Code licensed under the BSD License: http://developer.yahoo.com/yui/license.html version: 3.3.0 build: 3167 */ YUI.add('dataschema-json', function(Y) { /** * Provides a DataSchema implementation which can be used to work with JSON data. * * @module dataschema * @submodule dataschema-json */ /** * JSON subclass for the DataSchema Utility. * @class DataSchema.JSON * @extends DataSchema.Base * @static */ var LANG = Y.Lang, SchemaJSON = { ///////////////////////////////////////////////////////////////////////////// // // DataSchema.JSON static methods // ///////////////////////////////////////////////////////////////////////////// /** * Utility function converts JSON locator strings into walkable paths * * @method DataSchema.JSON.getPath * @param locator {String} JSON value locator. * @return {String[]} Walkable path to data value. * @static */ getPath: function(locator) { var path = null, keys = [], i = 0; if (locator) { // Strip the ["string keys"] and [1] array indexes locator = locator. replace(/\[(['"])(.*?)\1\]/g, function (x,$1,$2) {keys[i]=$2;return '.@'+(i++);}). replace(/\[(\d+)\]/g, function (x,$1) {keys[i]=parseInt($1,10)|0;return '.@'+(i++);}). replace(/^\./,''); // remove leading dot // Validate against problematic characters. if (!/[^\w\.\$@]/.test(locator)) { path = locator.split('.'); for (i=path.length-1; i >= 0; --i) { if (path[i].charAt(0) === '@') { path[i] = keys[parseInt(path[i].substr(1),10)]; } } } else { } } return path; }, /** * Utility function to walk a path and return the value located there. * * @method DataSchema.JSON.getLocationValue * @param path {String[]} Locator path. * @param data {String} Data to traverse. * @return {Object} Data value at location. * @static */ getLocationValue: function (path, data) { var i = 0, len = path.length; for (;i=0; --i) { record = {}; result = array_in[i]; if(result) { // 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.call(this, (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.call(this, (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.call(this, record[key]); // Safety net if (LANG.isUndefined(record[key])) { record[key] = null; } } results[i] = record; } } data_out.results = results; return data_out; }, /** * Parses results data according to schema * * @method _parseMeta * @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. * @static * @protected */ _parseMeta: function(metaFields, json_in, data_out) { if(LANG.isObject(metaFields)) { var key, path; for(key in metaFields) { if (metaFields.hasOwnProperty(key)) { path = SchemaJSON.getPath(metaFields[key]); if (path && json_in) { data_out.meta[key] = SchemaJSON.getLocationValue(path, json_in); } } } } else { data_out.error = new Error("JSON meta data retrieval failure"); } return data_out; } }; Y.DataSchema.JSON = Y.mix(SchemaJSON, Y.DataSchema.Base); }, '3.3.0' ,{requires:['dataschema-base','json']});