org.apache.myfaces.trinidad.model

## Class TreeModel

- java.lang.Object
- - javax.faces.model.DataModel
  - - org.apache.myfaces.trinidad.model.CollectionModel
    - - org.apache.myfaces.trinidad.model.TreeModel

- All Implemented Interfaces:
    Iterable, LocalRowKeyIndex, RowKeyIndex, TreeLocalRowKeyIndex
  Direct Known Subclasses:
    ChildPropertyTreeModel, MenuModel, TreeModelDecorator

      public abstract class TreeModel
      extends CollectionModel
      implements TreeLocalRowKeyIndex

  The data model used by Trinidad Tree components. A TreeModel is responsible for understanding how to iterate through an object graph, enter and leave containers, and identify rows of objects within each container. Within any one container, a TreeModel looks just like a CollectionModel, which extends the JSF DataModel class. (So, to understand this class, start by learning how DataModel works).

  ### Entering and exiting containers

  TreeModel extends CollectionModel to add support for container rows, which are entered and exited with enterContainer() and exitContainer() methods. Within a container, row indices (get/setRowIndex()) are relative to the container. However, row keys - get/setRowKey(), from the CollectionModel API - are always global for the entire tree model, so it is sufficient to call setRowKey() to enter and exit all the needed parents.

  ### Lazy loading of contents

  When a tree or treeTable iterates through the model, it will generally seek to see if a given node is a container - with the `isContainer()` method - and also see if the node is empty (and therefore not expandable) with the `isContainerEmpty()` method. The default implementation of that latter method involves entering the child and seeing how many children it has. As a result, by default, you will see one more level of content being requested than is actually visible on screen. To avoid this, provide a custom override of `isContainerEmpty()` to return a value without actually entering the container. It is acceptable for this method to return a "false negative" - to return false when there might actually not be any contents - if that is the most efficient approach possible.

  The `ChildPropertyTreeModel` class is a useful basic subclass, but largely requires that you have the entire object model fully loaded. If you require lazy loading, you'll likely need a custom implementation.

  ### Further documentation

  Rows in the TreeModel may (recursively) contain other rows. To figure out if the current row is a container, call the `isContainer()` method. If a row is a container, use the `enterContainer()` method to access its child rows. Once the `enterContainer()` method is called all the CollectionModel API's methods (like `DataModel.getRowCount()`) operate on the child collection. To return back to the parent row, use the `exitContainer()` method.

  Given the following tree structure:

       |-Root1 (rowKey="r1", rowIndex=0)
       |  |-Folder1 (rowKey="r1f1", rowIndex=0)
       |  |  |-Node1 (rowKey="r1f1n1", rowIndex=0)
       |  |  |-Node2 (rowKey="r1f1n2", rowIndex=1)
       |  |  |-Node3 (rowKey="r1f1n3", rowIndex=2)
       |  |
       |  |-Folder2 (rowKey="r1f2", rowIndex=1)
       |     |-Node4 (rowKey="r1f2n1", rowIndex=0)
       |
       |-Root2 (rowKey="r2", rowIndex=1)
       |-Root3 (rowKey="r3", rowIndex=2)
       |-Root4 (rowKey="r4", rowIndex=3)

  To point the tree to the root collection call: `setRowKey(null)`.
  Now, `getRowCount()` returns 4.
  `setRowIndex(1);getRowData()` returns `Root2`.
  `setRowKey("r4");getRowData()` returns `Root4`.

  To access `Node4` use:

       setRowIndex(0); // isContainer()==true
       enterContainer(); // enter Root1, getRowCount()==2
       setRowIndex(1); // isContainer()==true
       enterContainer(); // enter Folder2, getRowCount()==1
       setRowIndex(0); // isContainer()==false
       getRowData();

  Or, more simply:

       setRowKey("r1f2n1");
       getRowData();

  At this point, to get at `Node3` use:

       exitContainer(); // exit Folder2, Root1 is now the current row.
       setRowIndex(0);
       enterContainer(); // enter Folder1, getRowCount()==3
       setRowIndex(2);
       getRowData();

  Or, more simply:

       setRowKey("r1f1n3");
       getRowData();

- - ### Nested Class Summary

    - ### Nested classes/interfaces inherited from interface org.apache.myfaces.trinidad.model.LocalRowKeyIndex

      `LocalRowKeyIndex.Confidence, LocalRowKeyIndex.LocalCachingStrategy`

  - ### Field Summary

    - ### Fields inherited from class org.apache.myfaces.trinidad.model.CollectionModel

      `UNKNOWN_ROW_LIMIT, UNLIMITED_ROW`

  - ### Constructor Summary

    Constructors
    Constructor and Description
    `TreeModel()`

  - ### Method Summary

    Methods
    Modifier and Type | Method and Description
    --- | ---
    `boolean` | `areRowsLocallyAvailable(int startIndex, int rowCount, RowKeySet disclosedRowKeys)` Check if a range of rows is locally available starting from a row index.
    `boolean` | `areRowsLocallyAvailable(int rowCount, RowKeySet disclosedRowKeys)` Check if a range of rows is locally available starting from current position.
    `boolean` | `areRowsLocallyAvailable(Object startRowKey, int rowCount, RowKeySet disclosedRowKeys)` Check if a range of rows is locally available starting from a row key.
    `abstract void` | `enterContainer()` This Collection changes to reflect the children of the current rowData, and the current rowData changes to be null.
    `abstract void` | `exitContainer()` Pops back up to the parent collection.
    `List<Object>` | `getAllAncestorContainerRowKeys(Object childRowKey)` Gets the rowkey of each container, starting from the top most container, down to the container of the given child rowKey.
    `Object` | `getContainerRowKey()` Gets the rowKey of the current row's container row.
    `abstract Object` | `getContainerRowKey(Object childRowKey)` Gets the rowKey of a given child row's container row.
    `int` | `getDepth()` Gets the depth of the current row within this tree hierarchy.
    `int` | `getDepth(Object rowKey)` Gets the depth of the given row within the tree hierarchy.
    `boolean` | `isChildCollectionLocallyAvailable()` Indicates whether data for a child model (children of the current node) is locally available.
    `boolean` | `isChildCollectionLocallyAvailable(int index)` Indicates whether child data for the node with the given index is locally available.
    `boolean` | `isChildCollectionLocallyAvailable(Object rowKey)` Indicates whether child data for the node with the given row key is locally available.
    `abstract boolean` | `isContainer()` Tests to see if the row identified by getRowData() is a container element.
    `boolean` | `isContainerEmpty()` Tests to see if the current container element actually has children.

    - ### Methods inherited from class org.apache.myfaces.trinidad.model.CollectionModel

      `addRowKeyChangeListener, areRowsAvailable, areRowsAvailable, areRowsAvailable, areRowsLocallyAvailable, areRowsLocallyAvailable, areRowsLocallyAvailable, clearCachedRow, clearCachedRow, clearCachedRows, clearCachedRows, clearLocalCache, ensureRowsAvailable, fireRowKeyChange, getCachingStrategy, getEstimatedRowCount, getEstimatedRowCountConfidence, getRowData, getRowData, getRowKey, getRowLimit, getSortCriteria, isRowAvailable, isRowAvailable, isRowLocallyAvailable, isRowLocallyAvailable, isSortable, removeRowKeyChangeListener, setRowKey, setSortCriteria`

    - ### Methods inherited from class javax.faces.model.DataModel

      `addDataModelListener, getDataModelListeners, getRowCount, getRowData, getRowIndex, getWrappedData, isRowAvailable, iterator, removeDataModelListener, setRowIndex, setWrappedData`

    - ### Methods inherited from class java.lang.Object

      `clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

    - ### Methods inherited from interface org.apache.myfaces.trinidad.model.RowKeyIndex

      `getRowCount, getRowData, getRowIndex, isRowAvailable, setRowIndex`

- - ### Constructor Detail

    - #### TreeModel

          public TreeModel()

  - ### Method Detail

    - #### isContainer

          public abstract boolean isContainer()

      Tests to see if the row identified by getRowData() is a container element. Use `isContainerEmpty()` to see if the current container element actually has children, or is an empty container.
      Returns:
        true if the current element may contain children.

    - #### isContainerEmpty

          public boolean isContainerEmpty()

      Tests to see if the current container element actually has children. This could be more efficient than calling `enterContainer()` followed by `DataModel.getRowCount()`. This method is permitted to return false even if the container is actually empty. This method should only be called if `isContainer()` returns true.
      Returns:
        true if the current container element has no children. If there is any doubt as to whether or not the container has children, this method should return false.

    - #### enterContainer

          public abstract void enterContainer()

      This Collection changes to reflect the children of the current rowData, and the current rowData changes to be null. The current rowIndex becomes -1. This method should only be called if `isContainer()` returns true. `DataModel.getRowCount()` can be used to get the number of children.

    - #### exitContainer

          public abstract void exitContainer()

      Pops back up to the parent collection. The current rowData becomes the rowData of the parent. This Collection will change to include the children of the new rowData.

    - #### getContainerRowKey

          public final Object getContainerRowKey()

      Gets the rowKey of the current row's container row. This implementation calls `getContainerRowKey(Object)` with the current rowKey.

    - #### getAllAncestorContainerRowKeys

          public List<Object> getAllAncestorContainerRowKeys(Object childRowKey)

      Gets the rowkey of each container, starting from the top most container, down to the container of the given child rowKey. The root container (which always has the null rowKey) is not included in this list. The given childRowKey is not included in this list.

      Given the following tree structure:

           |-Root1 (rowKey="r1")
           |  |-Folder1 (rowKey="r1f1")
           |  |  |-Node1 (rowKey="r1f1n1")

      Calling `getAllAncestorContainerRowKeys("r1f1n1")` returns a List of two items:"r1" and "r1f1", in that order.
      Parameters:
        `childRowKey` - identifies the child row.
      Returns:
        An empty list is returned if the child row is a root row and has no parent containers. Each item in this list is a rowKey and is of type `Object`. The first rowKey (in this list) is the top most container. The last rowKey is the immediate container of the given childRowKey.

    - #### getContainerRowKey

          public abstract Object getContainerRowKey(Object childRowKey)

      Gets the rowKey of a given child row's container row.

           |-Root1 (rowKey="r1", containerRowKey=null)
           |  |-Folder1 (rowKey="r1f1", containerRowKey="r1")
           |  |  |-Node1 (rowKey="r1f1n1", containerRowKey="r1f1")
           |  |  |-Node2 (rowKey="r1f1n2", containerRowKey="r1f1")

      Parameters:
        `childRowKey` - the rowKey of the child row.
      Returns:
        the rowKey of the container, or null if the child is a root row.

    - #### getDepth

          public final int getDepth()

      Gets the depth of the current row within this tree hierarchy.
      This implementation simply calls `getDepth(Object)` with the current rowKey.

    - #### getDepth

          public int getDepth(Object rowKey)

      Gets the depth of the given row within the tree hierarchy. The depth is a measure of how far the given row is from its top-level container row. Root-level rows have a depth of zero. All the immediate children of each root row have a depth of one.

           |-Root1 (depth=0)
           |  |-Folder1 (depth=1)
           |  |  |-Node1 (depth=2)
           |  |  |-Node2 (depth=2)
           |  |  |-Node3 (depth=2)
           |  |-Folder2 (depth=1)
           |-Root2 (depth=0)

    - #### isChildCollectionLocallyAvailable

          public boolean isChildCollectionLocallyAvailable()

      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 `enterContainer()`.
      Specified by:
        `isChildCollectionLocallyAvailable` in interface `TreeLocalRowKeyIndex`
      Returns:
        The default implementation returns `false`

        Override this method if the TreeModel implementation supports caching of nodes. If caching is supported, the implementation should also return a caching strategy from `CollectionModel.getCachingStrategy()`

    - #### isChildCollectionLocallyAvailable

          public boolean isChildCollectionLocallyAvailable(int index)

      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 `#isRowLocallyAvailable(int`. If the parent node is locally available, this method moves the model to the parent node and calls `isChildCollectionLocallyAvailable()` The current row does not change after this call
      Specified by:
        `isChildCollectionLocallyAvailable` in interface `TreeLocalRowKeyIndex`
      Parameters:
        `index` -
      Returns:
        true if child data is available, false otherwise

    - #### isChildCollectionLocallyAvailable

          public boolean isChildCollectionLocallyAvailable(Object rowKey)

      Indicates whether child data for the node with the given row key is locally available.

      This method first checks to see if the parent node with the given row key is locally available by calling `CollectionModel.isRowLocallyAvailable(Object)`. If the parent node is locally available, this method moves the model to the parent node and calls `isChildCollectionLocallyAvailable()` The current row does not change after this call

      Specified by:
        `isChildCollectionLocallyAvailable` in interface `TreeLocalRowKeyIndex`
      Parameters:
        `rowKey` -
      Returns:
        true if child data is available, false otherwise

    - #### areRowsLocallyAvailable

          public boolean areRowsLocallyAvailable(int startIndex,
                                        int rowCount,
                                        RowKeySet disclosedRowKeys)

      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.

      This implementation checks the row at startIndex for availability and, if available, moves the model to startIndex and calls `areRowsLocallyAvailable(rowCount, disclosedRowKeys)`. The current row does not change after this call

      Specified by:
        `areRowsLocallyAvailable` in interface `TreeLocalRowKeyIndex`
      Parameters:
        `startIndex` - staring index for the range
        `rowCount` - number of rows in the range
        `disclosedRowKeys` - set of expanded nodes which may fall within the range to check for availability
      Returns:
        true if range of rows is locally available false otherwise

    - #### areRowsLocallyAvailable

          public boolean areRowsLocallyAvailable(Object startRowKey,
                                        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.

      This implementation checks the row at startRowKey for availability and, if available, moves the model to startRowKey and calls `areRowsLocallyAvailable(rowCount, disclosedRowKeys)`. The current row does not change after this call

      Specified by:
        `areRowsLocallyAvailable` in interface `TreeLocalRowKeyIndex`
      Parameters:
        `startRowKey` - staring row key for the range
        `rowCount` - number of rows in the range
        `disclosedRowKeys` - set of expanded nodes which may fall within the range to check for
      Returns:
        true if range of rows is locally available false otherwise

    - #### areRowsLocallyAvailable

          public boolean areRowsLocallyAvailable(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. 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.
      Specified by:
        `areRowsLocallyAvailable` in interface `TreeLocalRowKeyIndex`
      Parameters:
        `rowCount` - number of rows in the range
        `disclosedRowKeys` - set of expanded nodes which may fall within the range to check for
      Returns:
        true if range of rows is locally available false otherwise

Copyright © 2001-2017 The Apache Software Foundation. All Rights Reserved.