Source: data/service/data-provider.js

var Montage = require("core/core").Montage,
    Promise = require("core/promise").Promise;

/**
 * This class documents the properties and methods of objects that support the
 * DataProvider [protocol]{@linkplain external:Protocol}. Data provider classes
 * can extend this class but they aren't required to, they just need to have the
 * [data]{@link DataProvider#data} property and the
 * [requestData()]{@link DataProvider#requestData} method of this class.
 *
 * @class
 * @extends external:Montage
 *
 */
exports.DataProvider = Montage.specialize(/** @lends DataProvider.prototype */ {

    /**
     * At any point in time a data provider’s [data]{@link DataProvider#data}
     * array and the length of that array represent the state of the data as it
     * is then known to the data provider. If a data provider knows that an item
     * will need to be in its [data]{@link DataProvider#data} array but doesn’t
     * yet know the value of that item, it will place in the array an undefined
     * value for that item. Data providers can’t be used with data that includes
     * actual `undefined` values, so the presence of an `undefined` value in a
     * data provider’s [data]{@link DataProvider#data} array is an unambiguous
     * indication that the value of the corresponding item is expected but
     * hasn’t yet been received.
     *
     * As a data provider receives new data, or if its data changes for any
     * reason, it will update its [data]{@link DataProvider#data} array
     * correspondingly, most notably by replacing `undefined` values with real
     * objects and by changing the array’s length. A
     * [range change listener]{@linkplain external:RangeChangeListener}
     * can be used to monitor those changes, and components like Montage's
     * [Repetition]{@linkcode external:Repetition} will automatically do this
     * monitoring.
     *
     * Although the contents of a data provider's
     * [data]{@link DataProvider#data} array may change over time, the array
     * itself will not change. Subclasses will typically want to create the
     * [data]{@link DataProvider#data} array lazilly the first time it is needed
     * and then not allow that property to change, with code like the following:
     *
     *     data: {
     *         get: function() {
     *             if (!this._data) {
     *                 this._data = [];
     *             }
     *             return this._data;
     *         }
     *     },
     *
     * @type {Array}
     */
    data: {
        value: undefined
    },

    /**
     * Objects using a data provider can call the provider’s
     * [requestData()]{@link DataProvider#requestData} method to indicate that
     * they want the data in the specified range. If the requested data is not
     * in the provider’s [data]{@link DataProvider#data} array yet, and if that
     * data can be obtained, it will be obtained synchronously or asynchronously
     * and placed in the data array as described in the documentation for the
     * [data]{@link DataProvider#data} property above.
     *
     * When a data provider’s data is obtained asynchronously no guarantee is
     * given about exactly when that data will end up in the provider's
     * [data]{@link DataProvider#data} array. Also, no guarantee is given that a
     * data provider will provide through its [data]{@link DataProvider#data}
     * array only the data specifically requested in
     * [requestData()]{@link DataProvider#requestData} calls: It may obtain and
     * provide more data.
     *
     * In spite of these lack of guarantees data providers try to be smart about
     * what data they provide or withhold based on
     * [requestData()]{@link DataProvider#requestData} calls and based on
     * algorithms specific to each type of provider.
     *
     * This class does nothing when this method is called.
     *
     * @method
     * @argument {int} start  - The index of the start of the range of the
     *                          requested data. When `undefined`, all available
     *                          data is requested.
     * @argument {int} length - The length of the range of the requested data.
     *                          When `undefined`, all available data is
     *                          requested.
     */
    requestData: {
        value: function (start, length) {
            return Promise.resolve(this.data);
        }
    }

});