13.2. Tree adaptors
Use a tree adaptor to populate a tree model declaratively from a non-hierarchical model, such as a list or a map.
13.2.1. <rich:treeModelAdaptor>
The
<rich:treeModelAdaptor> component takes an object which implements the Map or Iterable interfaces. It adds all the object entries to the parent node as child nodes.
13.2.1.1. Basic usage
The
<rich:treeModelAdaptor> component is added as a nested child component to a <rich:tree> component, or to another tree adaptor component.
The
<rich:treeModelAdaptor> component requires the nodes attribute for basic usage. The nodes attribute defines a collection of elements to iterate through for populating the nodes.
Define the appearance of each node added by the adaptor with a child
<rich:treeNode> component. Refer to Section 13.1.10, “<rich:treeNode>” for details on the <rich:treeNode> component.
13.2.1.2. Identifying nodes
Adaptors that use
Map interfaces or models with non-string keys require a row key converter in order to correctly identify nodes. Refer to Section 13.1.5, “Identifying nodes with the rowKeyConverter attribute” for details on the use of the rowKeyConverter attribute.
Adaptors that use
Iterable interfaces have simple integer row keys. A default converter is provided and does not need to be referenced explicitly.
13.2.1.3. Reference data
component-type:org.richfaces.treeModelAdaptorcomponent-class:org.richfaces.component.UITreeModelAdaptorcomponent-family:org.richfaces.TreeModelAdaptorhandler-class:org.richfaces.view.facelets.TreeModelAdaptorHandler
13.2.2. <rich:treeModelRecursiveAdaptor>
The
<rich:treeModelRecursiveAdaptor> component iterates through recursive collections in order to populate a tree with hierarchical nodes, such as for a file system with multiple levels of directories and files.
13.2.2.1. Basic usage
The
<rich:treeModelRecursiveAdaptor> component is an extension of the <rich:treeModelAdaptor> component. As such, the <rich:treeModelRecursiveAdaptor> component uses all of the same attributes. Refer to Section 13.2.1, “<rich:treeModelAdaptor>” for details on the <rich:treeModelAdaptor> component.
In addition, the
<rich:treeModelRecursiveAdaptor> component requires the roots attribute. The roots attribute defines the collection to use at the top of the recursion. For subsequent levels, the nodes attribute is used for the collection.
Example 13.4, “Basic usage” demonstrates how the
<rich:treeModelRecursiveAdaptor> component can be used in conjunction with the <rich:treeModelAdaptor> component to recursively iterate through a file system and create a tree of directories and files.

Example 13.4. Basic usage
<rich:tree var="item"> <rich:treeModelRecursiveAdaptor roots="#{fileSystemBean.sourceRoots}" nodes="#{item.directories}" > <rich:treeNode> #{item.shortPath} </rich:treeNode> <rich:treeModelAdaptor nodes="#{item.files}"> <rich:treeNode>#{item}</rich:treeNode> </rich:treeModelAdaptor> </rich:treeModelRecursiveAdaptor> </rich:tree>
The
<rich:treeModelRecursiveAdaptor> component references the FileSystemBean class as the source for the data.
@ManagedBean @RequestScoped public class FileSystemBean { private static final String SRC_PATH = "/WEB-INF"; private List<FileSystemNode> srcRoots; public synchronized List<FileSystemNode> getSourceRoots() { if (srcRoots == null) { srcRoots = new FileSystemNode(SRC_PATH).getDirectories(); } return srcRoots; } }
The
FileSystemBean class in turn uses the FileSystemNode class to recursively iterate through the collection.
public class FileSystemNode { ... public synchronized List<FileSystemNode> getDirectories() { if (directories == null) { directories = Lists.newArrayList(); Iterables.addAll(directories, transform(filter(getResourcePaths(), containsPattern("/$")), FACTORY)); } return directories; } public synchronized List<String> getFiles() { if (files == null) { files = new ArrayList<String>(); Iterables.addAll(files, transform(filter(getResourcePaths(), not(containsPattern("/$"))), TO_SHORT_PATH)); } return files; } private Iterable<String> getResourcePaths() { FacesContext facesContext = FacesContext.getCurrentInstance(); ExternalContext externalContext = facesContext.getExternalContext(); Set<String> resourcePaths = externalContext.getResourcePaths(this.path); if (resourcePaths == null) { resourcePaths = Collections.emptySet(); } return resourcePaths; } ... }
The
getDirectories() function is used recursively until the object has the collection of children. The model adaptor calls the getFiles() function at each level in order to add the file nodes.
The resulting tree hierarchically lists the directories and files in the collection.

13.2.2.2. Identifying nodes
Adaptors that use
Map interfaces or models with non-string keys require a row key converter in order to correctly identify nodes. Refer to Section 13.1.5, “Identifying nodes with the rowKeyConverter attribute” for details on the use of the rowKeyConverter attribute.
Adaptors that use
Iterable interfaces have simple integer row keys. A default converter is provided and does not need to be referenced explicitly.
13.2.2.3. Reference data
component-type:org.richfaces.TreeModelRecursiveAdaptorcomponent-class:org.richfaces.component.UITreeModelRecursiveAdaptorcomponent-family:org.richfaces.TreeModelRecursiveAdaptorhandler-class:org.richfaces.view.facelets.TreeModelRecursiveAdaptorHandler