API Docs for:
Show:

File: /Users/lsmith/dev/yui3-gallery/src/gallery-dataschema-class/js/dataschema-class.js

var L = Y.Lang,
    isFunction = L.isFunction,
    isObject   = L.isObject;

/**
 * Abstract class encapsulation for any DataSchema implementation.  Pass the
 * constructor configuration an object containing these keys:
 *
 * <ul>
 *   <li><code>type</code> - "json", "JSON", Y.DataSchema.JSON, a custom
 *       implementation object (must provide an apply method), or a custom
 *       function used as the apply method.</li>
 *   <li><code>schema</code> - the object containing the appropriate schema
 *       key:values for the specified type of schema parser.  What you would
 *       pass as the first argument to
 *       Y.DataSchema.JSON.apply( SCHEMA, data );</li>
 * </ul>
 *
 * This class constructor replaces the Y.DataSchema object namespace.  All
 * loaded schema parser implementations are preserved.
 *
 * @module dataschema
 * @submodule dataschema-class
 * @class DataSchema
 * @constructor
 * @param config {Object} object containing keys "type" and "schema"
 */
function DataSchema(config) {
    this._init(config);
}

DataSchema.prototype = {
    /**
     * Initialize the instance, resolve the configured schema parser
     * implementation, and add any other properties or custom methods onto this
     * object.  Generally, the "any other properties" should be just the
     * schema.
     *
     * @method _init
     * @param config {Object} object passed in from constructor
     * @protected
     */
    _init: function (config) {
        config = isObject(config) ? config : {};

        Y.mix(this, config);

        this._impl = this._resolve(config.type || 'Base');
    },

    /**
     * <p>Resolves the configured type to an implementation object (e.g.
     * Y.DataSchema.JSON).</p>
     *
     * <p>Accepts type as a string, object, or function.  Defalts to
     * Y.DataSchema.Base.</p>
     *
     * <p>If a string is supplied, an implementation is searched for as a
     * static property of Y.DataSchema.  If one cannot be found, two more
     * attempts are made with the string in upper case and then the string with
     * first letter capitalized.</p>
     *
     * <p>If an object that contains a method named "apply" is passed, that
     * object is used.</p>
     *
     * <p>If a function is passed, that function is treated as the "apply"
     * method of a Y.DataSchema.Base implementation.</p>
     *
     * @method _resolve
     * @param type {Object|String|Function} schema parser implemantation, its
     *  name, or a custom apply function to use over Base implementation
     * @return {Object} DataSchema parser implementation object
     * @protected
     */
    _resolve: function (type) {
        var impl;

        if (L.isString(type)) {
            // Tries e.g. DataSchema.json, DataSchema.JSON, then DataSchema.Json
            impl = DataSchema[type] || DataSchema[type.toUpperCase()] ||
                   DataSchema[type.charAt(0).toUpperCase() + type.slice(1)];
        } else if (isFunction(type)) {
            impl = Y.Object(DataSchema.Base);
            impl.apply = type;
        } else if (isObject(type) && isFunction(type.apply)) {
            impl = type;
        }

        if (!impl) {
            Y.log(type + " DataSchema not found. Defaulting to Base", "warn", "dataSchema");
        }

        return impl || DataSchema.Base;
    },

    /**
     * Pass the data to the schema parser implementation with the configured
     * schema.
     *
     * @method apply
     * @param data {mixed} input data to be parsed by the schema implementation
     * @return {Object} Schema-parsed data
     */
    apply: function (data) {
        var args = Y.Array(arguments,0,true);
        args.unshift(this.schema);

        return this._impl.apply.apply(this._impl, args);
    }

};

// Replace the object namespace with the constructor, migrating all
// schema implementations to static properties.
Y.DataSchema = Y.mix(DataSchema, Y.DataSchema);