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/12 02:22:13 UTC

svn commit: r898145 - 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: Tue Jan 12 01:22:12 2010
New Revision: 898145

URL: http://svn.apache.org/viewvc?rev=898145&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=898145&r1=898144&r2=898145&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 Tue Jan 12 01:22:12 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=898145&r1=898144&r2=898145&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 Tue Jan 12 01:22:12 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=898145&r1=898144&r2=898145&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 Tue Jan 12 01:22:12 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=898145&r1=898144&r2=898145&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 Tue Jan 12 01:22:12 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=898145&r1=898144&r2=898145&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 Tue Jan 12 01:22:12 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=898145&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 Tue Jan 12 01:22:12 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=898145&r1=898144&r2=898145&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 Tue Jan 12 01:22:12 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=898145&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 Tue Jan 12 01:22:12 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=898145&r1=898144&r2=898145&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 Tue Jan 12 01:22:12 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;
+  }
 }