You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by ar...@apache.org on 2010/01/13 19:41:52 UTC
svn commit: r898873 - in
/myfaces/trinidad/branches/1.2.12.1-branch/trinidad-api/src/main:
java-templates/org/apache/myfaces/trinidad/component/
java/org/apache/myfaces/trinidad/component/
java/org/apache/myfaces/trinidad/model/
Author: arobinson74
Date: Wed Jan 13 18:41:52 2010
New Revision: 898873
URL: http://svn.apache.org/viewvc?rev=898873&view=rev
Log:
Commit patch for TRINIDAD-1620
Added:
myfaces/trinidad/branches/1.2.12.1-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/model/LocalRowKeyIndex.java (with props)
myfaces/trinidad/branches/1.2.12.1-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/model/TreeLocalRowKeyIndex.java (with props)
Modified:
myfaces/trinidad/branches/1.2.12.1-branch/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXIteratorTemplate.java
myfaces/trinidad/branches/1.2.12.1-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/component/UIXCollection.java
myfaces/trinidad/branches/1.2.12.1-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/component/UIXHierarchy.java
myfaces/trinidad/branches/1.2.12.1-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/model/CollectionModel.java
myfaces/trinidad/branches/1.2.12.1-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/model/CollectionModelDecorator.java
myfaces/trinidad/branches/1.2.12.1-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/model/RowKeyIndex.java
myfaces/trinidad/branches/1.2.12.1-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/model/TreeModel.java
Modified: myfaces/trinidad/branches/1.2.12.1-branch/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXIteratorTemplate.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/1.2.12.1-branch/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXIteratorTemplate.java?rev=898873&r1=898872&r2=898873&view=diff
==============================================================================
--- myfaces/trinidad/branches/1.2.12.1-branch/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXIteratorTemplate.java (original)
+++ myfaces/trinidad/branches/1.2.12.1-branch/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXIteratorTemplate.java Wed Jan 13 18:41:52 2010
@@ -31,6 +31,7 @@
import javax.faces.render.Renderer;
import org.apache.myfaces.trinidad.model.CollectionModel;
+import org.apache.myfaces.trinidad.model.LocalRowKeyIndex;
import org.apache.myfaces.trinidad.model.ModelUtils;
/**
@@ -41,7 +42,7 @@
* If {@link #getRows()} returns 0, then the iteration continues until
* there are no more elements in the underlying data.
*/
-public abstract class UIXIteratorTemplate extends UIXCollection implements FlattenedComponent
+public abstract class UIXIteratorTemplate extends UIXCollection implements FlattenedComponent, LocalRowKeyIndex
{
/**/ abstract public int getFirst();
Modified: myfaces/trinidad/branches/1.2.12.1-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/component/UIXCollection.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/1.2.12.1-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/component/UIXCollection.java?rev=898873&r1=898872&r2=898873&view=diff
==============================================================================
--- myfaces/trinidad/branches/1.2.12.1-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/component/UIXCollection.java (original)
+++ myfaces/trinidad/branches/1.2.12.1-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/component/UIXCollection.java Wed Jan 13 18:41:52 2010
@@ -43,6 +43,7 @@
import org.apache.myfaces.trinidad.event.SelectionEvent;
import org.apache.myfaces.trinidad.logging.TrinidadLogger;
import org.apache.myfaces.trinidad.model.CollectionModel;
+import org.apache.myfaces.trinidad.model.LocalRowKeyIndex;
import org.apache.myfaces.trinidad.model.SortCriterion;
import org.apache.myfaces.trinidad.render.ClientRowKeyManager;
import org.apache.myfaces.trinidad.render.ClientRowKeyManagerFactory;
@@ -328,6 +329,62 @@
}
/**
+ * Check for an available row by row key.
+ * @param rowKey the row key for the row to check.
+ * @return true if a value exists; false otherwise.
+ */
+ public final boolean isRowAvailable(Object rowKey)
+ {
+ return getCollectionModel().isRowAvailable(rowKey);
+ }
+
+ /**
+ * Get row data by row key.
+ * @param rowKey the row key for the row to get data.
+ * @return row data
+ */
+ public final Object getRowData(Object rowKey)
+ {
+ return getCollectionModel().getRowData(rowKey);
+ }
+
+ /**
+ * Check if a range of rows is available starting from the current position
+ * @param rowCount number of rows to check
+ * @return true if all rows in range are available
+ */
+ public final boolean areRowsAvailable(int rowCount)
+ {
+ return getCollectionModel().areRowsAvailable(rowCount);
+ }
+
+ /**
+ * Check if a range of rows is available from a starting index without
+ * requiring the client to iterate over the rows
+ * @param startIndex the starting index for the range
+ * @param rowCount number of rows to check
+ * @return true if all rows in range are available
+ */
+ public final boolean areRowsAvailable(int startIndex, int rowCount)
+ {
+ return getCollectionModel().areRowsAvailable(startIndex, rowCount);
+ }
+
+ /**
+ * Check if a range of rows is available from a starting row key without
+ * requiring the client to iterate over the rows
+ * @param startRowKey the starting row key for the range
+ * @param rowCount number of rows to check
+ * @return true if all rows in range are available
+ */
+ public final boolean areRowsAvailable(Object startRowKey, int rowCount)
+ {
+ return getCollectionModel().areRowsAvailable(startRowKey, rowCount);
+ }
+
+
+
+ /**
* Gets the total number of rows in this table.
* @see CollectionModel#getRowCount
* @return -1 if the total number is not known.
@@ -1177,6 +1234,140 @@
};
}
+
+ //
+ // LocalRowKeyIndex implementation
+ //
+
+ /**
+ * Given a row index, check if a row is locally available
+ * @param rowIndex index of row to check
+ * @return true if row is locally available
+ */
+ public boolean isRowLocallyAvailable(int rowIndex)
+ {
+ return getCollectionModel().isRowLocallyAvailable(rowIndex);
+ }
+
+ /**
+ * Given a row key, check if a row is locally available
+ * @param rowKey row key for the row to check
+ * @return true if row is locally available
+ */
+ public boolean isRowLocallyAvailable(Object rowKey)
+ {
+ return getCollectionModel().isRowLocallyAvailable(rowKey);
+ }
+
+ /**
+ * Check if a range of rows is locally available starting from current position
+ * @param rowCount number of rows in the range
+ * @return true if range of rows is locally available
+ */
+ public boolean areRowsLocallyAvailable(int rowCount)
+ {
+ return getCollectionModel().areRowsLocallyAvailable(rowCount);
+ }
+
+ /**
+ * Check if a range of rows is locally available starting from a row index
+ * @param startIndex staring index for the range
+ * @param rowCount number of rows in the range
+ * @return true if range of rows is locally available
+ */
+ public boolean areRowsLocallyAvailable(int startIndex, int rowCount)
+ {
+ return getCollectionModel().areRowsLocallyAvailable(startIndex, rowCount);
+ }
+
+ /**
+ * Check if a range of rows is locally available starting from a row key
+ * @param startRowKey staring row key for the range
+ * @param rowCount number of rows in the range
+ * @return true if range of rows is locally available
+ */
+ public boolean areRowsLocallyAvailable(Object startRowKey, int rowCount)
+ {
+ return getCollectionModel().areRowsLocallyAvailable(startRowKey, rowCount);
+ }
+
+ /**
+ * Convenient API to return a row count estimate. This method can be optimized
+ * to avoid a data fetch which may be required to return an exact row count
+ * @return estimated row count
+ */
+ public int getEstimatedRowCount()
+ {
+ return getCollectionModel().getEstimatedRowCount();
+ }
+
+
+ /**
+ * Helper API to determine if the row count returned from {@link #getEstimatedRowCount}
+ * is EXACT, or an ESTIMATE
+ */
+ public LocalRowKeyIndex.Confidence getEstimatedRowCountConfidence()
+ {
+ return getCollectionModel().getEstimatedRowCountConfidence();
+ }
+
+ /**
+ * clear all rows from the local cache
+ */
+ public void clearLocalCache()
+ {
+ getCollectionModel().clearLocalCache();
+ }
+
+ /**
+ * Clear the requested range of rows from the local cache
+ * @param startingIndex starting row index for the range to clear
+ * @param rowsToClear number of rows to clear from the cache
+ */
+ public void clearCachedRows(int startingIndex, int rowsToClear)
+ {
+ getCollectionModel().clearCachedRows(startingIndex, rowsToClear);
+ }
+
+ /**
+ * Clear the requested range of rows from the local cache
+ * @param startingRowKey starting row key for the range to clear
+ * @param rowsToClear number of rows to clear from the cache
+ */
+ public void clearCachedRows(Object startingRowKey, int rowsToClear)
+ {
+ getCollectionModel().clearCachedRows(startingRowKey, rowsToClear);
+ }
+
+ /**
+ * Clear a row from the local cache by row index
+ * @param index row index for the row to clear from the cache
+ */
+ public void clearCachedRow(int index)
+ {
+ getCollectionModel().clearCachedRow(index);
+ }
+
+ /**
+ * Clear a row from the local cache by row key
+ * @param rowKey row key for the row to clear from the cache
+ */
+ public void clearCachedRow(Object rowKey)
+ {
+ getCollectionModel().clearCachedRow(rowKey);
+ }
+
+ /**
+ * Indicates the caching strategy supported by the model
+ * @see LocalCachingStrategy
+ * @return caching strategy supported by the model
+ */
+ public LocalRowKeyIndex.LocalCachingStrategy getCachingStrategy()
+ {
+ return getCollectionModel().getCachingStrategy();
+ }
+
+
/**
* override this method to place initialization code that must run
* once this component is created and the jsp engine has finished setting
Modified: myfaces/trinidad/branches/1.2.12.1-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/component/UIXHierarchy.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/1.2.12.1-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/component/UIXHierarchy.java?rev=898873&r1=898872&r2=898873&view=diff
==============================================================================
--- myfaces/trinidad/branches/1.2.12.1-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/component/UIXHierarchy.java (original)
+++ myfaces/trinidad/branches/1.2.12.1-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/component/UIXHierarchy.java Wed Jan 13 18:41:52 2010
@@ -25,7 +25,10 @@
import javax.faces.component.UIComponent;
import org.apache.myfaces.trinidad.model.CollectionModel;
+import org.apache.myfaces.trinidad.model.LocalRowKeyIndex;
import org.apache.myfaces.trinidad.model.ModelUtils;
+import org.apache.myfaces.trinidad.model.RowKeySet;
+import org.apache.myfaces.trinidad.model.TreeLocalRowKeyIndex;
import org.apache.myfaces.trinidad.model.TreeModel;
@@ -34,7 +37,8 @@
*
* @version $Name: $ ($Revision: adfrt/faces/adf-faces-api/src/main/java/oracle/adf/view/faces/component/UIXHierarchy.java#0 $) $Date: 10-nov-2005.19:09:52 $
*/
-abstract public class UIXHierarchy extends UIXCollection implements CollectionComponent
+abstract public class UIXHierarchy extends UIXCollection implements CollectionComponent, LocalRowKeyIndex,
+ TreeLocalRowKeyIndex
{
/**
* Create a Page component with the given render-type
@@ -175,6 +179,93 @@
return getTreeModel().getAllAncestorContainerRowKeys(childRowKey);
}
+ //
+ // TreeLocalRowKeyIndex implementation
+ //
+
+ /**
+ * Indicates whether data for a child model (children of the current node) is
+ * locally available.
+ * @see TreeModel#isChildCollectionLocallyAvailable()
+ * @return true if child data is locally available
+ */
+ public boolean isChildCollectionLocallyAvailable()
+ {
+ return getTreeModel().isChildCollectionLocallyAvailable();
+ }
+
+ /**
+ * Indicates whether child data for the node with the given index is
+ * locally available.
+ * @see TreeModel#isChildCollectionLocallyAvailable(int)
+ * @param index row index to check
+ * @return true if child data is available, false otherwise
+ */
+ public boolean isChildCollectionLocallyAvailable(int index)
+ {
+ return getTreeModel().isChildCollectionLocallyAvailable(index);
+ }
+
+ /**
+ * Indicates whether child data for the node with the given row key is
+ * locally available.
+ * @see TreeModel#isChildCollectionLocallyAvailable(Object)
+ * @param rowKey row key to check
+ * @return true if child data is available, false otherwise
+ */
+ public boolean isChildCollectionLocallyAvailable(Object rowKey)
+ {
+ return getTreeModel().isChildCollectionLocallyAvailable(rowKey);
+ }
+
+ /**
+ * Check if a range of rows is locally available starting from a row index. The range
+ * can include child nodes in any expanded nodes within the range.
+ * @param startIndex staring index for the range
+ * @param rowCount number of rows in the range
+ * @param disclosedRowKeys set of expanded nodes which may fall within the range to check for
+ * availability
+ * @return <code>true</code> if range of rows is locally available <code>flase</code> otherwise
+ * @see TreeModel#areRowsLocallyAvailable(int, int, RowKeySet)
+ */
+ public boolean areRowsLocallyAvailable(int startIndex, int rowCount,
+ RowKeySet disclosedRowKeys)
+ {
+ return getTreeModel().areRowsLocallyAvailable(startIndex, rowCount, disclosedRowKeys);
+ }
+
+ /**
+ * Check if a range of rows is locally available starting from a row key. The range
+ * can include child nodes in any expanded nodes within the range.
+ * @param startRowKey staring row key for the range
+ * @param rowCount number of rows in the range
+ * @param disclosedRowKeys set of expanded nodes which may fall within the range to check for
+ * availability
+ * @return <code>true</code> if range of rows is locally available <code>flase</code> otherwise
+ * @see TreeModel#areRowsLocallyAvailable(Object, int, RowKeySet)
+ */
+ public boolean areRowsLocallyAvailable(Object startRowKey, int rowCount,
+ RowKeySet disclosedRowKeys)
+ {
+ return getTreeModel().areRowsLocallyAvailable(startRowKey, rowCount, disclosedRowKeys);
+ }
+
+ /**
+ * Check if a range of rows is locally available starting from current position. The range
+ * can include child nodes in any expanded nodes within the range.
+ * @param rowCount number of rows in the range
+ * @param disclosedRowKeys set of expanded nodes which may fall within the range to check for
+ * availability
+ * @return <code>true</code> if range of rows is locally available <code>flase</code> otherwise
+ * @see TreeModel#areRowsLocallyAvailable(int , RowKeySet)
+ */
+ public boolean areRowsLocallyAvailable(int rowCount,
+ RowKeySet disclosedRowKeys)
+ {
+ return getTreeModel().areRowsLocallyAvailable(rowCount, disclosedRowKeys);
+ }
+
+
/**
* Gets the TreeModel that this tree is displaying.
*/
Modified: myfaces/trinidad/branches/1.2.12.1-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/model/CollectionModel.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/1.2.12.1-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/model/CollectionModel.java?rev=898873&r1=898872&r2=898873&view=diff
==============================================================================
--- myfaces/trinidad/branches/1.2.12.1-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/model/CollectionModel.java (original)
+++ myfaces/trinidad/branches/1.2.12.1-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/model/CollectionModel.java Wed Jan 13 18:41:52 2010
@@ -46,7 +46,7 @@
* <p>
*/
public abstract class CollectionModel extends DataModel
- implements RowKeyIndex
+ implements RowKeyIndex, LocalRowKeyIndex
{
/**
@@ -75,6 +75,7 @@
* {@link #isRowAvailable()}.
* Finally, the row that was current before this method was called
* is made current again.
+ * @see CollectionModel#isRowAvailable()
* @param rowIndex the index of the row to check.
* @return true if data for the row exists.
*/
@@ -93,11 +94,36 @@
}
/**
+ * Check for an available row by row key.
+ * This method makes the given row current and calls
+ * {@link #isRowAvailable()}.
+ * Finally, the row that was current before this method was called
+ * is made current again.
+ * @see CollectionModel#isRowAvailable()
+ * @param rowKey the row key for the row to check.
+ * @return true if data for the row exists otherwise return false
+ */
+ public boolean isRowAvailable(Object rowKey)
+ {
+ Object oldKey = getRowKey();
+ try
+ {
+ setRowKey(rowKey);
+ return isRowAvailable();
+ }
+ finally
+ {
+ setRowKey(oldKey);
+ }
+ }
+
+ /**
* Gets the rowData at the given index.
* This method makes the given row current and calls
* {@link #getRowData()}.
* Finally, the row that was current before this method was called
* is made current again.
+ * @see CollectionModel#getRowData()
* @param rowIndex the index of the row to get data from.
* @return the data for the given row.
*/
@@ -116,6 +142,30 @@
}
/**
+ * Gets the rowData at the given row key.
+ * This method makes the given row current and calls
+ * {@link #getRowData()}.
+ * Finally, the row that was current before this method was called
+ * is made current again.
+ * @see CollectionModel#getRowData()
+ * @param rowKey the row key of the row to get data from.
+ * @return the data for the given row.
+ */
+ public Object getRowData(Object rowKey)
+ {
+ Object oldKey = getRowKey();
+ try
+ {
+ setRowKey(rowKey);
+ return getRowData();
+ }
+ finally
+ {
+ setRowKey(oldKey);
+ }
+ }
+
+ /**
* Return true if this collection is sortable by the given property.
* This implementation always returns false;
*/
@@ -148,4 +198,260 @@
{
}
+ /**
+ * Check if a range of rows is available from a starting index.
+ * The current row does not change after this call
+ * @param startIndex the starting index for the range
+ * @param rowsToCheck number of rows to check. If rowsToCheck < 0 set
+ * startIndex = startIndex - abs(rowsToCheck) + 1. This
+ * allows for checking for row availability from the end position. For example
+ * to check for availability of n rows from the end, call
+ * isRangeAvailable(getRowCount()-1, -n)
+ * @return true if rows are available otherwise return <code>false</code>
+ */
+ public boolean areRowsAvailable(int startIndex, int rowsToCheck)
+ {
+ int oldIndex = getRowIndex();
+ try
+ {
+ if (rowsToCheck < 0)
+ {
+ rowsToCheck = Math.abs(rowsToCheck);
+ startIndex = startIndex - rowsToCheck + 1;
+ }
+ setRowIndex(startIndex);
+ return areRowsAvailable(rowsToCheck);
+ }
+ finally
+ {
+ setRowIndex(oldIndex);
+ }
+ }
+
+ /**
+ * Check if a range of rows is available from a starting row key
+ * This method makes the row with the given row key current and calls
+ * {@link #areRowsAvailable(rowsToCheck)}.
+ * The current row does not change after this call
+ * @see CollectionModel#areRowsAvailable(int).
+ * @param startRowKey the starting row key for the range
+ * @param rowsToCheck number of rows to check
+ * @return true if rows are available otherwise return false
+ */
+ public boolean areRowsAvailable(Object startRowKey, int rowsToCheck)
+ {
+ Object oldKey = getRowKey();
+ try
+ {
+ setRowKey(startRowKey);
+ return areRowsAvailable(rowsToCheck);
+ }
+ finally
+ {
+ setRowKey(oldKey);
+ }
+ }
+
+ /**
+ * Check if a range of rows is available starting from the
+ * current row. This implementation checks the start and end rows in the range
+ * for availability. If the number of requested rows is greater than the total
+ * row count, this implementation checks for available rows up to the row count.
+ * The current row does not change after this call
+ * @param rowsToCheck number of rows to check
+ * @return true rows are available otherwise return false
+ */
+ public boolean areRowsAvailable(int rowsToCheck)
+ {
+ int startIndex = getRowIndex();
+
+ if (startIndex < 0 || rowsToCheck <= 0)
+ return false;
+
+
+ long count = getRowCount();
+ if (count != -1)
+ {
+ if (startIndex >= count)
+ return false;
+
+ if (startIndex + rowsToCheck > count)
+ rowsToCheck = (int)count - startIndex;
+ }
+ int last = startIndex + rowsToCheck - 1;
+
+ try
+ {
+ // check start index
+ if (!isRowAvailable())
+ return false;
+
+ // check end index
+ setRowIndex(last);
+ return isRowAvailable();
+ }
+ finally
+ {
+ setRowIndex(startIndex);
+ }
+ }
+
+ //
+ // Below is the default implemenation for the LocalRowKeyIndex interface.
+ //
+
+ /**
+ * Check if a range of rows is locally available starting from a row index.
+ * @see CollectionModel#areRowsAvailable(int, int)
+ * @param startIndex starting row index to check
+ * @param rowsToCheck number of rows to check
+ * @return default implementation returns <code>false</code>
+
+ */
+ public boolean areRowsLocallyAvailable(int startIndex, int rowsToCheck)
+ {
+ return false;
+ }
+
+ /**
+ * Check if a range of rows is locally available starting from a row key.
+ * @see CollectionModel#areRowsAvailable(Object, int)
+ * @param startRowKey starting row key to check
+ * @param rowsToCheck number of rows to check
+ * @return default implementation returns <code>false</code>
+ */
+ public boolean areRowsLocallyAvailable(Object startRowKey, int rowsToCheck)
+ {
+ return false;
+ }
+
+
+ /**
+ * Check if a range of rows is locally available starting from current position.
+ * This implementation checks for a valid current index and delegates to
+ * <code>areRowsLocallyAvailable(startIndex, rowsToCheck)</code>
+ * @param rowsToCheck number of rows to check
+ * @return default implementation returns <code>false</code>
+ * @see <code>areRowsLocallyAvailable(startIndex, rowsToCheck)</code>
+ */
+ public boolean areRowsLocallyAvailable(int rowsToCheck)
+ {
+ boolean available = false;
+ int startIndex = getRowIndex();
+
+ if (startIndex >= 0)
+ {
+ available = areRowsLocallyAvailable(startIndex, rowsToCheck);
+ }
+ return available;
+ }
+
+ /**
+ * Given a row index, check if the row is locally available.
+ * @param rowIndex row index to check
+ * @return default implementation returns <code>false</code>
+ */
+ public boolean isRowLocallyAvailable(int rowIndex)
+ {
+ return false;
+ }
+
+ /**
+ * Given a row key, check if the row is locally available.
+ * @param rowKey row key to check
+ * @return default implementation returns <code>false</code>
+ */
+ public boolean isRowLocallyAvailable(Object rowKey)
+ {
+ return false;
+ }
+
+ /**
+ * Convenient API to return a row count estimate.
+ * @see CollectionModel#getRowCount
+ * @return This implementation returns exact row count
+ */
+ public int getEstimatedRowCount()
+ {
+ return getRowCount();
+ }
+
+ /**
+ * Helper API to determine if the row count returned from {@link #getEstimatedRowCount}
+ * is EXACT, or an ESTIMATE.
+ * @see CollectionModel#getRowCount
+ * @return This implementation returns exact row count
+ */
+ public LocalRowKeyIndex.Confidence getEstimatedRowCountConfidence()
+ {
+ return LocalRowKeyIndex.Confidence.EXACT;
+ }
+
+ /**
+ * Clears the row with the given index from local cache.
+ * This is a do nothing implementaionĀ§
+ * @see #clearCachedRows(int, int)
+ * @param index row index for the row to remove from cache
+ */
+ public void clearCachedRow(int index)
+ {
+ clearCachedRows(index, 1);
+ }
+
+ /**
+ * Clears the row with the given row key from local cache.
+ * This is a do nothing implementaion which delegates to the
+ * correcsponding range based api
+ * @see #clearCachedRows(Object, int)
+ * @param rowKey row key for the row to remove from cache
+ */
+ public void clearCachedRow(Object rowKey)
+ {
+ clearCachedRows(rowKey, 1);
+ }
+
+ /**
+ * Clears a range of rows from local cache starting from a row index.
+ * This is a do nothing implemenation.
+ * @see #clearLocalCache
+ * @param startingIndex starting row index to clear the local cache from
+ * @param rowsToClear number of rows to clear
+ */
+ public void clearCachedRows(int startingIndex, int rowsToClear)
+ {
+ clearLocalCache();
+ }
+
+ /**
+ * Clears a range of rows from local cache starting from a row key
+ * This is a do nothing implemenation.
+ * @see #clearLocalCache
+ * @param startingRowKey starting row key to clear the local cache from
+ * @param rowsToClear number of rows to clear
+ */
+ public void clearCachedRows(Object startingRowKey, int rowsToClear)
+ {
+ clearLocalCache();
+ }
+
+ /**
+ * Clears the local cache.
+ * This is a do nothing implementation
+ */
+ public void clearLocalCache()
+ {
+ // do nothing
+ }
+
+ /**
+ * Returns the row caching strategy used by this implemenation. Default
+ * implementation indicates no caching supported
+ * @see LocalRowKeyIndex.LocalCachingStrategy
+ * @return caching strategy none
+ */
+ public LocalRowKeyIndex.LocalCachingStrategy getCachingStrategy()
+ {
+ return LocalRowKeyIndex.LocalCachingStrategy.NONE;
+ }
+
}
Modified: myfaces/trinidad/branches/1.2.12.1-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/model/CollectionModelDecorator.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/1.2.12.1-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/model/CollectionModelDecorator.java?rev=898873&r1=898872&r2=898873&view=diff
==============================================================================
--- myfaces/trinidad/branches/1.2.12.1-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/model/CollectionModelDecorator.java (original)
+++ myfaces/trinidad/branches/1.2.12.1-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/model/CollectionModelDecorator.java Wed Jan 13 18:41:52 2010
@@ -49,6 +49,11 @@
return getCollectionModel().isRowAvailable(rowIndex);
}
+ public boolean isRowAvailable(Object rowKey)
+ {
+ return getCollectionModel().isRowAvailable(rowKey);
+ }
+
public Object getRowData(int rowIndex)
{
return getCollectionModel().getRowData(rowIndex);
@@ -69,6 +74,116 @@
getCollectionModel().setSortCriteria(criteria);
}
+ public boolean areRowsAvailable(int startIndex, int rowCount)
+ {
+ return getCollectionModel().areRowsAvailable(startIndex, rowCount);
+ }
+
+ public boolean areRowsAvailable(Object startRowKey, int rowCount)
+ {
+ return getCollectionModel().areRowsAvailable(startRowKey, rowCount);
+ }
+
+ public boolean areRowsAvailable(int rowCount)
+ {
+ return getCollectionModel().areRowsAvailable(rowCount);
+ }
+
+ //
+ // below are the LocalRowKeyIndex APIs
+ //
+
+ public boolean areRowsLocallyAvailable(int startIndex, int rowCount)
+ {
+ return getCollectionModel().areRowsLocallyAvailable(startIndex, rowCount);
+ }
+
+ public boolean areRowsLocallyAvailable(Object startRowKey, int rowCount)
+ {
+ return getCollectionModel().areRowsLocallyAvailable(startRowKey, rowCount);
+ }
+
+ public boolean areRowsLocallyAvailable(int rowCount)
+ {
+ return getCollectionModel().areRowsLocallyAvailable(rowCount);
+ }
+
+ public boolean isRowLocallyAvailable(int rowIndex)
+ {
+ return getCollectionModel().isRowLocallyAvailable(rowIndex);
+ }
+
+ public boolean isRowLocallyAvailable(Object rowKey)
+ {
+ return getCollectionModel().isRowLocallyAvailable(rowKey);
+ }
+
+ public int getEstimatedRowCount()
+ {
+ return getCollectionModel().getEstimatedRowCount();
+ }
+
+ public LocalRowKeyIndex.Confidence getEstimatedRowCountConfidence()
+ {
+ return getCollectionModel().getEstimatedRowCountConfidence();
+ }
+
+ /**
+ * clear all rows from the local cache
+ */
+ public void clearLocalCache()
+ {
+ getCollectionModel().clearLocalCache();
+ }
+
+ /**
+ * Clear the requested range of rows from the local cache
+ * @param startingIndex starting row index for the range to clear
+ * @param rowsToClear number of rows to clear from the cache
+ */
+ public void clearCachedRows(int startingIndex, int rowsToClear)
+ {
+ getCollectionModel().clearCachedRows(startingIndex, rowsToClear);
+ }
+
+ /**
+ * Clear the requested range of rows from the local cache
+ * @param startingRowKey starting row key for the range to clear
+ * @param rowsToClear number of rows to clear from the cache
+ */
+ public void clearCachedRows(Object startingRowKey, int rowsToClear)
+ {
+ getCollectionModel().clearCachedRows(startingRowKey, rowsToClear);
+ }
+
+ /**
+ * Clear a row from the local cache by row index
+ * @param index row index for the row to clear from the cache
+ */
+ public void clearCachedRow(int index)
+ {
+ getCollectionModel().clearCachedRow(index);
+ }
+
+ /**
+ * Clear a row from the local cache by row key
+ * @param rowKey row key for the row to clear from the cache
+ */
+ public void clearCachedRow(Object rowKey)
+ {
+ getCollectionModel().clearCachedRow(rowKey);
+ }
+
+ /**
+ * Indicates the caching strategy supported by the model
+ * @see LocalCachingStrategy
+ * @return caching strategy supported by the model
+ */
+ public LocalRowKeyIndex.LocalCachingStrategy getCachingStrategy()
+ {
+ return getCollectionModel().getCachingStrategy();
+ }
+
//
// below are the DataModel public APIs
//
Added: myfaces/trinidad/branches/1.2.12.1-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/model/LocalRowKeyIndex.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/1.2.12.1-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/model/LocalRowKeyIndex.java?rev=898873&view=auto
==============================================================================
--- myfaces/trinidad/branches/1.2.12.1-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/model/LocalRowKeyIndex.java (added)
+++ myfaces/trinidad/branches/1.2.12.1-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/model/LocalRowKeyIndex.java Wed Jan 13 18:41:52 2010
@@ -0,0 +1,151 @@
+package org.apache.myfaces.trinidad.model;
+
+/**
+ * Defines a set of "local" APIs for a CollectionModel.
+ * The "local" APIs allow a client to query the model and determine if a
+ * set of rows are locally available. "Locally available" can mean the
+ * model has the given set of rows in a local cache and can honor a fetch request
+ * efficiently (for example, without performing a SQL query).
+ */
+public interface LocalRowKeyIndex
+{
+
+ /**
+ * Given a row index, check if a row is locally available
+ * @param rowIndex index of row to check
+ * @return <code>true</code> if row is locally available <code>flase</code> otherwise
+ */
+ public boolean isRowLocallyAvailable(int rowIndex);
+
+ /**
+ * Given a row key, check if a row is locally available
+ * @param rowKey row key for the row to check
+ * @return <code>true</code> if row is locally available <code>flase</code> otherwise
+ */
+ public boolean isRowLocallyAvailable(Object rowKey);
+
+ /**
+ * Check if a range of rows is locally available starting from a row index
+ * @param startIndex staring index for the range
+ * @param rowCount number of rows in the range
+ * @return <code>true</code> if range of rows is locally available <code>flase</code> otherwise
+ */
+ public boolean areRowsLocallyAvailable(int startIndex, int rowCount);
+
+ /**
+ * Check if a range of rows is locally available starting from a row key
+ * @param startRowKey staring row key for the range
+ * @param rowCount number of rows in the range
+ * @return <code>true</code> if range of rows is locally available <code>flase</code> otherwise
+ */
+ public boolean areRowsLocallyAvailable(Object startRowKey, int rowCount);
+
+ /**
+ * Check if a range of rows is locally available starting from the current row
+ * @param rowCount number of rows in the range
+ * @return <code>true</code> if range of rows is locally available <code>flase</code> otherwise
+ */
+ public boolean areRowsLocallyAvailable(int rowCount);
+
+ /**
+ * Convenient API to return a row count estimate. This method can be optimized
+ * to avoid a data fetch which may be required to return an exact row count.
+ * <p>
+ * This method can return -1 or a row count estimate if determining
+ * exact row count requires a data fetch. When dealing with estimated row counts,
+ * the model user needs to gracefully handle the case where isRowAvailable
+ * returns <code>false</code> for a row index or a row key.
+ * @return estimated row count
+ */
+ public int getEstimatedRowCount();
+
+
+ /**
+ * Helper API to determine if the row count returned from {@link #getEstimatedRowCount}
+ * is EXACT, or an ESTIMATE
+ */
+ public Confidence getEstimatedRowCountConfidence();
+
+
+ /**
+ * Enum used in the {@link #getEstimatedRowCountConfidence} API to determine
+ * if the row count is exact or an estimate
+ */
+ public enum Confidence
+ {
+ /**
+ * The row count returned by {@link #getEstimatedRowCount} is exact
+ */
+ EXACT,
+
+ /**
+ * The row count returned by {@link #getEstimatedRowCount} is an estimate
+ */
+ ESTIMATE
+ }
+
+
+ //
+ // Local Cache management APIs
+ //
+
+ /**
+ * clear all rows from the local cache
+ */
+ public void clearLocalCache();
+
+ /**
+ * Clear the requested range of rows from the local cache
+ * @param startingIndex starting row index for the range to clear
+ * @param rowsToClear number of rows to clear from the cache
+ */
+ public void clearCachedRows(int startingIndex, int rowsToClear);
+
+ /**
+ * Clear the requested range of rows from the local cache
+ * @param startingRowKey starting row key for the range to clear
+ * @param rowsToClear number of rows to clear from the cache
+ */
+ public void clearCachedRows(Object startingRowKey, int rowsToClear);
+
+ /**
+ * Clear a row from the local cache by row index
+ * @param index row index for the row to clear from the cache
+ */
+ public void clearCachedRow(int index);
+
+ /**
+ * Clear a row from the local cache by row key
+ * @param rowKey row key for the row to clear from the cache
+ */
+ public void clearCachedRow(Object rowKey);
+
+ /**
+ * Indicates the caching strategy supported by the model
+ * @see LocalCachingStrategy
+ * @return caching strategy supported by the model
+ */
+ public LocalCachingStrategy getCachingStrategy();
+
+ /**
+ * Enum used to indicate the type of caching supported by the model
+ * @see #getCachingStrategy()
+ */
+ public enum LocalCachingStrategy
+ {
+ /**
+ * Caching is not supported
+ */
+ NONE,
+
+ /**
+ * Supports caching certain ranges of rows
+ */
+ PARTIAL,
+
+ /**
+ * Caches all rows
+ */
+ ALL
+ }
+}
Propchange: myfaces/trinidad/branches/1.2.12.1-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/model/LocalRowKeyIndex.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: myfaces/trinidad/branches/1.2.12.1-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/model/RowKeyIndex.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/1.2.12.1-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/model/RowKeyIndex.java?rev=898873&r1=898872&r2=898873&view=diff
==============================================================================
--- myfaces/trinidad/branches/1.2.12.1-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/model/RowKeyIndex.java (original)
+++ myfaces/trinidad/branches/1.2.12.1-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/model/RowKeyIndex.java Wed Jan 13 18:41:52 2010
@@ -95,4 +95,46 @@
*/
public Object getRowData(int rowIndex);
+
+ /**
+ * Check for an available row by row key.
+ * @param rowKey the row key for the row to check.
+ * @return true if a value exists; false otherwise.
+ */
+ public boolean isRowAvailable(Object rowKey);
+
+
+ /**
+ * Get row data by row key.
+ * @param rowKey the row key for the row to get data.
+ * @return row data
+ */
+ public Object getRowData(Object rowKey);
+
+
+ /**
+ * Check if a range of rows is available starting from the current position
+ * @param rowsToCheck number of rows to check
+ * @return true if all rows in range are available
+ */
+ public boolean areRowsAvailable(int rowsToCheck);
+
+ /**
+ * Check if a range of rows is available from a starting index without
+ * requiring the client to iterate over the rows
+ * @param startIndex the starting index for the range
+ * @param rowsToCheck number of rows to check
+ * @return true if all rows in range are available
+ */
+ public boolean areRowsAvailable(int startIndex, int rowsToCheck) ;
+
+
+ /**
+ * Check if a range of rows is available from a starting row key without
+ * requiring the client to iterate over the rows
+ * @param startRowKey the starting row key for the range
+ * @param rowsToCheck number of rows to check
+ * @return true if all rows in range are available
+ */
+ public boolean areRowsAvailable(Object startRowKey, int rowsToCheck) ;
}
Added: myfaces/trinidad/branches/1.2.12.1-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/model/TreeLocalRowKeyIndex.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/1.2.12.1-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/model/TreeLocalRowKeyIndex.java?rev=898873&view=auto
==============================================================================
--- myfaces/trinidad/branches/1.2.12.1-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/model/TreeLocalRowKeyIndex.java (added)
+++ myfaces/trinidad/branches/1.2.12.1-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/model/TreeLocalRowKeyIndex.java Wed Jan 13 18:41:52 2010
@@ -0,0 +1,68 @@
+package org.apache.myfaces.trinidad.model;
+
+/**
+ * Defines a set of "local" APIs for a TreeModel.
+ * The "local" APIs allow a client to query the tree model and determine if a
+ * set of rows are locally available. "Locally available" can mean the
+ * model has the given set of rows in a local cache and can honor a fetch request
+ * efficiently (for example, without performing a SQL query).
+ */
+public interface TreeLocalRowKeyIndex
+{
+ /**
+ * Indicates whether data for a child model (children of the current node) is
+ * locally available. Locally available means no data fetch is required
+ * as a result of a call to <code>enterContainer</code>.
+ * @return true if child data is locally available
+ */
+ public boolean isChildCollectionLocallyAvailable();
+
+ /**
+ * Indicates whether child data for the node with the given index is
+ * locally available.
+ * @param index row index to check
+ * @return true if child data is available, false otherwise
+ */
+ public boolean isChildCollectionLocallyAvailable(int index);
+
+ /**
+ * Indicates whether child data for the node with the given row key is
+ * locally available.
+ * @param rowKey row key to check
+ * @return true if child data is available, false otherwise
+ */
+ public boolean isChildCollectionLocallyAvailable(Object rowKey);
+
+ /**
+ * Check if a range of rows is locally available starting from a row index. The range
+ * can include child nodes in any expanded nodes within the range.
+ * @param startIndex staring index for the range
+ * @param rowCount number of rows in the range
+ * @param disclosedRowKeys set of expanded nodes which may fall within the range to check for
+ * availability
+ * @return <code>true</code> if range of rows is locally available <code>flase</code> otherwise
+ */
+ public boolean areRowsLocallyAvailable(int startIndex, int rowCount, RowKeySet disclosedRowKeys);
+
+ /**
+ * Check if a range of rows is locally available starting from a row key. The range
+ * can include child nodes in any expanded nodes within the range.
+ * @param startRowKey staring row key for the range
+ * @param rowCount number of rows in the range
+ * @param disclosedRowKeys set of expanded nodes which may fall within the range to check for
+ * availability
+ * @return <code>true</code> if range of rows is locally available <code>flase</code> otherwise
+ */
+ public boolean areRowsLocallyAvailable(Object startRowKey, int rowCount, RowKeySet disclosedRowKeys);
+
+ /**
+ * Check if a range of rows is locally available starting from current position. The range
+ * can include child nodes in any expanded nodes within the range.
+ * @param rowCount number of rows in the range
+ * @param disclosedRowKeys set of expanded nodes which may fall within the range to check for
+ * availability
+ * @return <code>true</code> if range of rows is locally available <code>flase</code> otherwise
+ */
+ public boolean areRowsLocallyAvailable(int rowCount, RowKeySet disclosedRowKeys);
+
+}
Propchange: myfaces/trinidad/branches/1.2.12.1-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/model/TreeLocalRowKeyIndex.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: myfaces/trinidad/branches/1.2.12.1-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/model/TreeModel.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/1.2.12.1-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/model/TreeModel.java?rev=898873&r1=898872&r2=898873&view=diff
==============================================================================
--- myfaces/trinidad/branches/1.2.12.1-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/model/TreeModel.java (original)
+++ myfaces/trinidad/branches/1.2.12.1-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/model/TreeModel.java Wed Jan 13 18:41:52 2010
@@ -126,7 +126,7 @@
* getRowData();
* </pre>
*/
-public abstract class TreeModel extends CollectionModel
+public abstract class TreeModel extends CollectionModel implements TreeLocalRowKeyIndex
{
/**
@@ -293,4 +293,260 @@
}
return depth;
}
+
+
+ //
+ // Below is the default implemenation for the TreeLocalRowKeyIndex interface.
+ //
+
+ /**
+ * Indicates whether data for a child model (children of the current node) is
+ * locally available. Locally available means no data fetch is required
+ * as a result of a call to {@link #enterContainer}.
+ * @return The default implementation returns <code>false</code>
+ * <p>
+ * Override this method if the TreeModel implementation supports caching of nodes.
+ * If caching is supported, the implementation should also return a caching strategy from
+ * <code>CollectionModel.getCachingStrategy()</code>
+ */
+ public boolean isChildCollectionLocallyAvailable()
+ {
+ return false;
+ }
+
+ /**
+ * Indicates whether child data for the node with the given index is
+ * locally available. This method first checks to see if the parent node
+ * at the given index is locally available by calling {@link #isRowLocallyAvailable(int}.
+ * If the parent node is locally available, this method moves the model to the
+ * parent node and calls {@link #isChildCollectionLocallyAvailable()}
+ * The current row does not change after this call
+ * @param index
+ * @return true if child data is available, false otherwise
+ */
+ public boolean isChildCollectionLocallyAvailable(int index)
+ {
+ if (isRowLocallyAvailable(index))
+ {
+ int oldIndex = getRowIndex();
+ try
+ {
+ setRowIndex(index);
+ return isChildCollectionLocallyAvailable();
+ }
+ finally
+ {
+ setRowIndex(oldIndex);
+ }
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ /**
+ * Indicates whether child data for the node with the given row key is
+ * locally available.
+ * <p>
+ * This method first checks to see if the parent node
+ * with the given row key is locally available by calling {@link #isRowLocallyAvailable(Object)}.
+ * If the parent node is locally available, this method moves the model to the
+ * parent node and calls {@link #isChildCollectionLocallyAvailable()}
+ * The current row does not change after this call
+ * @param rowKey
+ * @return true if child data is available, false otherwise
+ */
+ public boolean isChildCollectionLocallyAvailable(Object rowKey)
+ {
+ if (isRowLocallyAvailable(rowKey))
+ {
+ Object oldKey = getRowKey();
+ try
+ {
+ setRowKey(rowKey);
+ return isChildCollectionLocallyAvailable();
+ }
+ finally
+ {
+ setRowKey(oldKey);
+ }
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ /**
+ * Check if a range of rows is locally available starting from a row index. The range
+ * can include child nodes in any expanded nodes within the range.
+ * <p>
+ * This implementation checks the row at startIndex for availability and, if
+ * available, moves the model to startIndex and calls
+ * <code>areRowsLocallyAvailable(rowCount, disclosedRowKeys)</code>.
+ * The current row does not change after this call
+ * @param startIndex staring index for the range
+ * @param rowCount number of rows in the range
+ * @return true if range of rows is locally available false otherwise
+ */
+ public boolean areRowsLocallyAvailable(int startIndex, int rowCount, RowKeySet disclosedRowKeys)
+ {
+
+ boolean available = false;
+ if (isRowLocallyAvailable(startIndex))
+ {
+ Object oldKey = getRowKey();
+ try
+ {
+ setRowIndex(startIndex);
+ available = areRowsLocallyAvailable(rowCount, disclosedRowKeys);
+ }
+ finally
+ {
+ setRowKey(oldKey);
+ }
+ }
+ return available;
+ }
+
+ /**
+ * Check if a range of rows is locally available starting from a row key. The range
+ * can include child nodes in any expanded nodes within the range.
+ * <p>
+ * This implementation checks the row at startRowKey for availability and, if
+ * available, moves the model to startRowKey and calls
+ * <code>areRowsLocallyAvailable(rowCount, disclosedRowKeys)</code>.
+ * The current row does not change after this call
+ * @param startRowKey staring row key for the range
+ * @param rowCount number of rows in the range
+ * @param disclosedRowKeys set of expanded nodes which may fall within the range to check for
+ * @return true if range of rows is locally available false otherwise
+ */
+ public boolean areRowsLocallyAvailable(Object startRowKey, int rowCount, RowKeySet disclosedRowKeys)
+ {
+ boolean available = false;
+ if (isRowLocallyAvailable(startRowKey))
+ {
+ Object oldKey = getRowKey();
+ try
+ {
+ setRowKey(startRowKey);
+ available = areRowsLocallyAvailable(rowCount, disclosedRowKeys);
+ }
+ finally
+ {
+ setRowKey(oldKey);
+ }
+ }
+ return available;
+ }
+
+ /**
+ * Check if a range of rows is locally available starting from current position. The range
+ * can include child nodes in any expanded nodes within the range.
+ * This implementation walks locally available nodes in the current collection and drills into any expanded child
+ * collections. The node traversal can continue to the siblings of the current node.
+ * Node traversal ends when a node or a child collection is not locally available or
+ * when rowCount nodes are visited or the last root node is reached.
+ * The current row does not change after this call.
+ * @param rowCount number of rows in the range
+ * @param disclosedRowKeys set of expanded nodes which may fall within the range to check for
+ * @return true if range of rows is locally available false otherwise
+ */
+ public boolean areRowsLocallyAvailable(int rowCount, RowKeySet disclosedRowKeys)
+ {
+
+ boolean available = false;
+ Object startingRowKey = getRowKey();
+
+ if (startingRowKey != null)
+ {
+ available = _areRowsLocallyAvailable(startingRowKey, rowCount, disclosedRowKeys);
+ }
+ return available;
+ }
+
+
+ /**
+ * Check if a total of "count" rows are locally available starting from a "rowKey". Take into account
+ * child rows in expanded nodes within the range
+ * @param rowKey starting row key to check
+ * @param count row count to check
+ * @param disclosedRows set of expanded nodes
+ * @return true if count rows are locally available false otherwise
+ */
+ private boolean _areRowsLocallyAvailable(Object rowKey, int count, RowKeySet disclosedRows)
+ {
+ if (!isRowLocallyAvailable(rowKey))
+ return false;
+
+ Object oldKey = getRowKey();
+ try
+ {
+ setRowKey(rowKey);
+ int startIndex = getRowIndex();
+ // start from the current node and walk up the parent hierarchy if necessary
+ while ((count = _walkAvailableNodes(startIndex, count, disclosedRows)) > 0 && getDepth() > 0)
+ {
+ exitContainer();
+ startIndex = getRowIndex();
+ startIndex += 1;
+ }
+ return count >= 0;
+ }
+ finally
+ {
+ setRowKey(oldKey);
+ }
+ }
+
+ /**
+ * Walk available child nodes starting from a row index in the current collection
+ * and consume "count" nodes. Drill into expanded nodes.
+ * @param startIndex starting child index within the current collection
+ * @param count number of nodes to check
+ * @param disclosedRows set of expanded nodes
+ * @return -1 if rows are not available; 0 if "count" rows are available; > 0
+ * if the requested count is greater than child row count for the current
+ * collection and all rows up to child row count are locally available
+ */
+ private int _walkAvailableNodes(int startIndex, int count, RowKeySet disclosedRows)
+ {
+ int index = startIndex;
+ int rowCount = getRowCount();
+
+ if (rowCount < 0)
+ return -1;
+
+ while (index < rowCount && count > 0)
+ {
+ if (!isRowLocallyAvailable(index))
+ return -1;
+
+ --count;
+ setRowIndex(index);
+ Object key = getRowKey();
+ if (disclosedRows.contains(key))
+ {
+ if (isChildCollectionLocallyAvailable())
+ {
+ enterContainer();
+ setRowIndex(0);
+ count = _walkAvailableNodes(0, count, disclosedRows);
+ if (count < 0)
+ return -1;
+ exitContainer();
+ }
+ else
+ {
+ // children of expanded node are not available
+ return -1;
+ }
+ }
+ ++index;
+ }
+
+ return count;
+ }
}