Source: src/main/javascript/oracle/oj/ojtree-model/CollectionNodeSet.js

Oracle® JavaScript Extension Toolkit (JET)
1.1.2

E65298-01

/**
 * Copyright (c) 2014, Oracle and/or its affiliates.
 * All rights reserved.
 */

/**
 * A CollectionNodeSet represents a collection of nodes.  The CollectionNodeSet is an object returned by the success callback
 * of the fetchChildren method on CollectionTreeDataSource.  
 * @constructor
 * @export
 */
oj.CollectionNodeSet = function(parentKey, collection, treeDataSource, start, count)
{
    this.parentKey = parentKey;
    this.collection = collection;
    this.childNodeSet = [];
    this.treeDataSource = treeDataSource;
    // Can't have start exceeding valid indices
    this.start = start < collection.length ? start : collection.length-1;
    // Unknown count: we'll assign it.  Also can't have count exceeding collection size
    this.count = count === -1 ? collection.length : Math.min(collection.length, count);
};

oj.CollectionNodeSet.prototype.FetchDescendants = function(callbacks) {
    this._fetchDescendants(this, true).then(function () {
        if (callbacks['success']) {
            callbacks['success']();
        }
    });
};

oj.CollectionNodeSet.prototype._fetchDescendants = function(nodeSet, topLevel) {  
    return new Promise(function(resolve, reject) {
        var count = nodeSet.getCount();

        // Walk over each node in this node set, and fetch all the descendants of each
        function nextNode(index) {
            if (index < count) {
                nodeSet.FetchChildNodeSet(index, {'success':function(childNodeSet) {
                                                            if (childNodeSet !== null) {
                                                                nodeSet._fetchDescendants(childNodeSet, false).then(function() {
                                                                    nextNode(index+1);
                                                                });
                                                            }
                                                            else {
                                                                nextNode(index+1);
                                                            }
                                                        }});
            }
            else {
                resolve(undefined);
            }
        }
        nextNode(0);
    });
};

oj.CollectionNodeSet.prototype.FetchChildNodeSet = function(index, callbacks) {
    var model = this.collection.at(index);
    var parse = this.treeDataSource.parseMetadata(model);
    if (parse['leaf']) {
        // We're at the leaf: don't fetch any more
        this.childNodeSet[index] = null;
        callbacks['success'](null);
        return;
    }
    
    var collection = this.treeDataSource.GetChildCollection(model);
    var parentKey = this.treeDataSource.parseMetadata(model)['key'];
    var self = this;
    this.treeDataSource.FetchCollection(collection, 0, -1, {'success':function(nodeSet) {
            self.childNodeSet[index] = nodeSet;
            callbacks['success'](nodeSet);
    }}, parentKey); 
};

oj.CollectionNodeSet.prototype._getCollection = function() {
    return this.collection;
};

/**
* Gets the parent key for this result set.  
* @return {Object} the parent key for this result set. 
* @export
*/
oj.CollectionNodeSet.prototype.getParent = function()
{
    return this.parentKey;
};

/**
* Gets the start index of the result set.  
* @return {number} the start index of the result set.
* @export	
*/
oj.CollectionNodeSet.prototype.getStart = function()
{
    return this.start;
};

/**
* Gets the actual count of the result set.  
* @return {number} the actual count of the result set.
* @export	
*/
oj.CollectionNodeSet.prototype.getCount = function()
{
    return this.count;
};

/**
* Gets the data of the specified index.  An error is throw when 1) the range is not yet available and
* 2) the index specified is out of bounds. 
* @param {number} index the index of the node/row in which we want to retrieve the data from.  
* @return {Object} the data for the specified index.  oj.RowData should be returned for data that represents a row
*         with a number of columns.
* @export
*/
oj.CollectionNodeSet.prototype.getData = function(index)
{
    this._checkRange(index);
    return this.collection.at(index).attributes;
};

oj.CollectionNodeSet.prototype._checkRange = function(index) {
    if (index < this.start || index > this.start+this.count) {
        // Out of range
        throw "Out of range";
    }
};

/**
* Gets the metadata of the specified index.  An error is throw when 1) the range is not yet available and 
* 2) the index specified is out of bounds. 
* The metadata that the data source must return are:
*  1) key - Object, the key of the node/row.
*  2) leaf - boolean, true if it's a leaf, false otherwise. 
*  3) depth? - number, the depth of the node/row. (or should the caller just calculate it?)
* @param {number} index the index of the node/row in which we want to retrieve the metadata from.  
* @return {Object} the metadata object for the specific index.
* @export
*/	
oj.CollectionNodeSet.prototype.getMetadata = function(index)
{
    this._checkRange(index);
    
    var metadata = {};

    var model = this.collection.at(index);
    
    var parse = this.treeDataSource.parseMetadata(model);
    metadata['key'] = parse['key'];
    metadata['leaf'] = parse['leaf'];
    metadata['depth'] = parse['depth'];

    return metadata;
};


/**
 * Gets the node set child of the specified index.
 * @param {number} index the index of the node/row in which we want to retrieve the child node set
 * @return {oj.CollectionNodeSet|null} the child node set representing the child collection.
 * @export
 */
oj.CollectionNodeSet.prototype.getChildNodeSet = function(index) {
    this._checkRange(index);
    
    return this.childNodeSet[index];
};