/**
* Copyright (c) 2014, Oracle and/or its affiliates.
* All rights reserved.
*/
/**
* Flattens a hierarchical node set, which can happen in node set returned from
* fetchDescendants call.
* @param {Object} nodeSet the node set to flatten
* @param {number=} actualStart in the fetch descendant case the result set would
* be a subset of the node set. This param gives the exact start index in the
* wrapped node set where the result should start.
* @constructor
* @export
*/
oj.FlattenedNodeSet = function(nodeSet, actualStart)
{
this.m_nodeSet = nodeSet;
this.m_start = actualStart;
};
/**
* Gets the parent
* @return {Object} the key of the parent.
* @export
*/
oj.FlattenedNodeSet.prototype.getParent = function()
{
return this.m_nodeSet.getParent();
};
/**
* Gets the start index of the result set.
* @return {number} the start index of the result set.
* @export
*/
oj.FlattenedNodeSet.prototype.getStart = function()
{
// if explicit start index is specified, use it, otherwise
// delegate to wrapped node set
if (this.m_start != undefined)
{
return this.m_start;
}
else
{
return this.m_nodeSet.getStart();
}
};
/**
* Gets the actual count of the result set.
* @return {number} the actual count of the result set.
* @export
*/
oj.FlattenedNodeSet.prototype.getCount = function()
{
// see if it's calculated already
if (this.m_count === undefined)
{
this.m_count = this._getCount(this.m_nodeSet, 0);
// if explicit start is specified (subset), need to take that into
// account when calculating total count
if (this.m_start != undefined)
{
this.m_count = this.m_count - this.m_start;
}
}
return this.m_count;
};
/**
* Recursive function to calculate the total number of nodes in the node set.
* @param {Object} nodeSet the node set to calculate count
* @param {number} total the total number of nodes so far
* @return {number} the total number of nodes
* @private
*/
oj.FlattenedNodeSet.prototype._getCount = function(nodeSet, total)
{
var start, count, i, child;
start = nodeSet.getStart();
count = nodeSet.getCount();
total = total + count;
// if there's child node set
if (nodeSet.getChildNodeSet)
{
for (i=0; i<count; i++)
{
child = nodeSet.getChildNodeSet(i+start);
if (child != null)
total = this._getCount(child, total);
}
}
return total;
};
/**
* 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.
* @export
*/
oj.FlattenedNodeSet.prototype.getData = function(index)
{
return this._getDataOrMetadata(this.m_nodeSet, index, {'index': this.m_nodeSet.getStart()}, this._getData);
};
/**
* 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) state - state of the node, valid values are 'expanded', 'collapsed', 'leaf'.
* 3) depth - number, the depth of the node/row.
* @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.FlattenedNodeSet.prototype.getMetadata = function(index)
{
return this._getDataOrMetadata(this.m_nodeSet, index, {'index': this.m_nodeSet.getStart()}, this._getMetadata);
};
/**
* Callback function to retrieve metadata of specified index in node set
* @param {Object} nodeSet the node set to retrieve metadata from
* @param {number} index the index to retrieve metadata from
* @return {Object} the metadata
* @private
*/
oj.FlattenedNodeSet.prototype._getMetadata = function(nodeSet, index)
{
return nodeSet.getMetadata(index);
};
/**
* Callback function to retrieve data of specified index in node set
* @param {Object} nodeSet the node set to retrieve data from
* @param {number} index the index to retrieve data from
* @return {Object} the data
* @private
*/
oj.FlattenedNodeSet.prototype._getData = function(nodeSet, index)
{
return nodeSet.getData(index);
};
/**
* Retrieve data or metadata (depending on callback function) from the node set
* @param {Object} nodeSet the node set to retrieve data from
* @param {number} index the index to retrieve data from
* @param {Object} current contains the current index keep track by the method
* @param {function(Object, number)} func the callback function to retrieve data or metadata
* @return {Object} the data or metadata
* @private
*/
oj.FlattenedNodeSet.prototype._getDataOrMetadata = function(nodeSet, index, current, func)
{
var start, count, i, currIndex, child, result;
// walk the node set recursively until we found the index
start = nodeSet.getStart();
count = nodeSet.getCount();
for (i=0; i<count; i++)
{
currIndex = current['index'];
// found the index
if (currIndex === index)
return func.call(this, nodeSet, i+start);
current['index'] = currIndex+1;
// if there's child node set
if (nodeSet.getChildNodeSet)
{
child = nodeSet.getChildNodeSet(i+start);
if (child != null)
{
result = this._getDataOrMetadata(child, index, current, func);
if (result != null)
return result;
}
}
}
return null;
};
Source: src/main/javascript/oracle/oj/ojrowexpander/FlattenedNodeSet.js
Oracle® JavaScript Extension Toolkit (JET)
1.1.2
E65298-01