com.mycompany.jsf.component
Class UITree

java.lang.Object
  extended byjavax.faces.component.UIComponent
      extended byjavax.faces.component.UIComponentBase
          extended bycom.mycompany.jsf.component.UITree
All Implemented Interfaces:
javax.faces.component.NamingContainer, javax.faces.component.StateHolder

public class UITree
extends javax.faces.component.UIComponentBase
implements javax.faces.component.NamingContainer

This class is a JSF component that represents a tree control. Facets named "openNode", "closedNode" and "leafNode" represent the components resposible for processing nodes of a TreeModel in all request processing lifecycle phases, and may be either input or output components. The class implements the NamingContainer interface to adjust the client IDs for the facets, so that a unique client ID is used for each node even though all nodes are in fact processed by one set of components.

The value of this component must be either a TreeModel or a TreeNode representing the root node of a tree.

The component is rendered by the "com.mycompany.Tree" renderer type by default.

Version:
1.0
Author:
Hans Bergsten, Gefion Software

Nested Class Summary
private static class UITree.ChildEvent
          Private class to wrap an event with a node ID.
static class UITree.NodeToggler
          A class with an action method that toggles the "expanded" property value of the current node.
private static class UITree.SavedState
          Private class to represent saved state information.
 
Nested classes inherited from class javax.faces.component.UIComponentBase
 
Field Summary
static java.lang.String COMPONENT_FAMILY
           
static java.lang.String COMPONENT_TYPE
           
private  TreeModel model
          The TreeModel used by this component, either set explicitly as the value of created as a wrapper around a TreeNode value.
private  java.lang.String nodeId
          The current node ID.
private  UITree.NodeToggler nodeToggler
          The NodeToggler instance.
private  java.util.Map saved
          This map contains SavedState instances for each node in the tree, keyed by the client identifier of the component representing node, which contains the nodeId value for uniqueness.
private  java.lang.Object value
          The component's value, either a TreeModel or a TreeNode instance.
private  java.lang.String var
          The name of the request scope variable through which the data object for the current node is exposed.
private  java.lang.String varNodeToggler
          The name of the request scope variable through which the node toggler object is exposed.
 
Fields inherited from class javax.faces.component.UIComponentBase
 
Fields inherited from interface javax.faces.component.NamingContainer
SEPARATOR_CHAR
 
Constructor Summary
UITree()
          Creates an instance and sets the renderer type to "com.mycompany.Tree".
 
Method Summary
 void broadcast(javax.faces.event.FacesEvent event)
          If the event is a ChildEvent, unwraps the real event, calls setNodeId() with the node ID in the ChildEvent and delegates the processing to the real event source.
 void encodeBegin(javax.faces.context.FacesContext context)
          Before delegating to the superclass, resets the saved per-node state for facet input components unless it is needed to rerender the current page with errors, as determined by the keepSaved() method.
 java.lang.String getClientId(javax.faces.context.FacesContext context)
          Returns a client ID composed from the regular client ID (returned by the superclass getClientId() method) and the current node ID (if any) separated by a colon.
 javax.faces.component.UIComponent getClosedNode()
          Returns the "closedNode" facet.
private  TreeModel getDataModel()
          Returns the cached model, if any, or the components value, as-is if it's a TreeModel or wrapped in a new TreeModel if it's a TreeNode, saving a reference in the "model" variable.
 java.lang.String getFamily()
          Returns the COMPONENT_TYPE value.
 javax.faces.component.UIComponent getLeafNode()
          Returns the "leafNode" facet.
 TreeNode getNode()
          Returns the current node from the TreeModel, or "null" if no node is currently processed.
 java.lang.String getNodeId()
          Returns the current node ID, or "null" if no node is currently processed.
private  UITree.NodeToggler getNodeToggler()
          Returns the single instance of the NodeToggler, creating it if needed.
 javax.faces.component.UIComponent getOpenNode()
          Returns the "openNode" facet.
 java.lang.Object getValue()
          Returns the component value, set explicitly or through a ValueBinding, or null if the value isn't set.
 java.lang.String getVar()
          Returns the name of the request scope through which the data object for the current node is exposed.
 java.lang.String getVarNodeToggler()
          Returns the name of the request scope through which the NodeToggler is exposed.
private  boolean keepSaved(javax.faces.context.FacesContext context)
          Returns "true" if there's at least one error message queued for a client ID matching one of the nodes.
 void processDecodes(javax.faces.context.FacesContext context)
          If "rendered" is true, resets the cached model and saved per-node state, calls processNodes() with a PhaseId for this phase, resets the node ID, and calls the decode() method.
private  void processNodes(javax.faces.context.FacesContext context, javax.faces.event.PhaseId phaseId, java.lang.String parentId, int childLevel)
          Recursively process all nodes at the root of the tree and all nodes under an open node for the provided phase, i.e., by calling processDecodes(), processValidators() or processUpdates() on the facet representing the node type.
 void processUpdates(javax.faces.context.FacesContext context)
          If "rendered" is true, calls processNodes() with a PhaseId for this phase, resets the node ID, and calls the decode() method.
 void processValidators(javax.faces.context.FacesContext context)
          If "rendered" is true, calls processNodes() with a PhaseId for this phase, resets the node ID, and calls the decode() method.
 void queueEvent(javax.faces.event.FacesEvent event)
          Wraps the event in a ChildEvent and calls the superclass method add it to the queue with this component as the event source.
private  void restoreDescendantState()
          Restores state information for all facets by calling the restoreDescendantState(UIComponent, FacesContext) method on each facet.
private  void restoreDescendantState(javax.faces.component.UIComponent component, javax.faces.context.FacesContext context)
          Restore state information for the specified component and its children from the previously saved state, if any.
 void restoreState(javax.faces.context.FacesContext context, java.lang.Object state)
          Restores the component to the provided state, previously returned by the saveState() method.
private  void saveDescendantState()
          Saves state information for all facets by calling the saveDescendantState(UIComponent, FacesContext) method on each facet.
private  void saveDescendantState(javax.faces.component.UIComponent component, javax.faces.context.FacesContext context)
          Saves state information for the specified component, if it implements the EditableValueHolder interface, and its children.
 java.lang.Object saveState(javax.faces.context.FacesContext context)
          Returns the component state to be saved as part of the view state.
 void setClosedNode(javax.faces.component.UIComponent closedNode)
          Sets the "openNode" facet.
 void setLeafNode(javax.faces.component.UIComponent closedNode)
          Sets the "leafNode" facet.
 void setNodeId(java.lang.String nodeId)
          Sets the node ID, saving the state of all facet components for the previous node ID and restoring it for the new if it was saved for the new node ID previously, and exposes the node for the new node ID and the NodeToggler through their request scope variables.
 void setOpenNode(javax.faces.component.UIComponent openNode)
          Sets the "openNode" facet.
 void setValue(java.lang.Object value)
          Sets the component value, either a TreeModel or a TreeNode, and resets the previously cached model, if any.
 void setValueBinding(java.lang.String name, javax.faces.el.ValueBinding binding)
          Throws an IllegalArgumentException if the name is "var", "varToggler" or "nodeId" (these properties must be set to explicit values); otherwise, delegates to the superclass.
 void setVar(java.lang.String var)
          Sets the name of the request-scope variable through which the data object for the current node is exposed.
 void setVarNodeToggler(java.lang.String varNodeToggler)
          Sets the name of the request scope through which the NodeToggler is exposed.
 
Methods inherited from class javax.faces.component.UIComponentBase
addFacesListener, decode, encodeChildren, encodeEnd, findComponent, getAttributes, getChildCount, getChildren, getFacesContext, getFacesListeners, getFacet, getFacets, getFacetsAndChildren, getId, getParent, getRenderer, getRendererType, getRendersChildren, getValueBinding, isRendered, isTransient, processRestoreState, processSaveState, removeFacesListener, restoreAttachedState, saveAttachedState, setId, setParent, setRendered, setRendererType, setTransient
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

COMPONENT_TYPE

public static final java.lang.String COMPONENT_TYPE
See Also:
Constant Field Values

COMPONENT_FAMILY

public static final java.lang.String COMPONENT_FAMILY
See Also:
Constant Field Values

value

private java.lang.Object value
The component's value, either a TreeModel or a TreeNode instance.


model

private TreeModel model
The TreeModel used by this component, either set explicitly as the value of created as a wrapper around a TreeNode value.


nodeId

private java.lang.String nodeId
The current node ID.


saved

private java.util.Map saved
This map contains SavedState instances for each node in the tree, keyed by the client identifier of the component representing node, which contains the nodeId value for uniqueness.


var

private java.lang.String var
The name of the request scope variable through which the data object for the current node is exposed.


varNodeToggler

private java.lang.String varNodeToggler
The name of the request scope variable through which the node toggler object is exposed.


nodeToggler

private UITree.NodeToggler nodeToggler
The NodeToggler instance.

Constructor Detail

UITree

public UITree()
Creates an instance and sets the renderer type to "com.mycompany.Tree".

Method Detail

getFamily

public java.lang.String getFamily()
Returns the COMPONENT_TYPE value.


getVar

public java.lang.String getVar()
Returns the name of the request scope through which the data object for the current node is exposed.


setVar

public void setVar(java.lang.String var)
Sets the name of the request-scope variable through which the data object for the current node is exposed.


getVarNodeToggler

public java.lang.String getVarNodeToggler()
Returns the name of the request scope through which the NodeToggler is exposed.


setVarNodeToggler

public void setVarNodeToggler(java.lang.String varNodeToggler)
Sets the name of the request scope through which the NodeToggler is exposed.


getNodeToggler

private UITree.NodeToggler getNodeToggler()
Returns the single instance of the NodeToggler, creating it if needed.


getOpenNode

public javax.faces.component.UIComponent getOpenNode()
Returns the "openNode" facet.


setOpenNode

public void setOpenNode(javax.faces.component.UIComponent openNode)
Sets the "openNode" facet.


getClosedNode

public javax.faces.component.UIComponent getClosedNode()
Returns the "closedNode" facet.


setClosedNode

public void setClosedNode(javax.faces.component.UIComponent closedNode)
Sets the "openNode" facet.


getLeafNode

public javax.faces.component.UIComponent getLeafNode()
Returns the "leafNode" facet.


setLeafNode

public void setLeafNode(javax.faces.component.UIComponent closedNode)
Sets the "leafNode" facet.


getNode

public TreeNode getNode()
Returns the current node from the TreeModel, or "null" if no node is currently processed.


getNodeId

public java.lang.String getNodeId()
Returns the current node ID, or "null" if no node is currently processed.


setNodeId

public void setNodeId(java.lang.String nodeId)
Sets the node ID, saving the state of all facet components for the previous node ID and restoring it for the new if it was saved for the new node ID previously, and exposes the node for the new node ID and the NodeToggler through their request scope variables.


getValue

public java.lang.Object getValue()
Returns the component value, set explicitly or through a ValueBinding, or null if the value isn't set.


setValue

public void setValue(java.lang.Object value)
Sets the component value, either a TreeModel or a TreeNode, and resets the previously cached model, if any.


setValueBinding

public void setValueBinding(java.lang.String name,
                            javax.faces.el.ValueBinding binding)
Throws an IllegalArgumentException if the name is "var", "varToggler" or "nodeId" (these properties must be set to explicit values); otherwise, delegates to the superclass.


getClientId

public java.lang.String getClientId(javax.faces.context.FacesContext context)
Returns a client ID composed from the regular client ID (returned by the superclass getClientId() method) and the current node ID (if any) separated by a colon.


queueEvent

public void queueEvent(javax.faces.event.FacesEvent event)
Wraps the event in a ChildEvent and calls the superclass method add it to the queue with this component as the event source.


broadcast

public void broadcast(javax.faces.event.FacesEvent event)
               throws javax.faces.event.AbortProcessingException
If the event is a ChildEvent, unwraps the real event, calls setNodeId() with the node ID in the ChildEvent and delegates the processing to the real event source.

Throws:
javax.faces.event.AbortProcessingException

encodeBegin

public void encodeBegin(javax.faces.context.FacesContext context)
                 throws java.io.IOException
Before delegating to the superclass, resets the saved per-node state for facet input components unless it is needed to rerender the current page with errors, as determined by the keepSaved() method.

Throws:
java.io.IOException

processDecodes

public void processDecodes(javax.faces.context.FacesContext context)
If "rendered" is true, resets the cached model and saved per-node state, calls processNodes() with a PhaseId for this phase, resets the node ID, and calls the decode() method.


processValidators

public void processValidators(javax.faces.context.FacesContext context)
If "rendered" is true, calls processNodes() with a PhaseId for this phase, resets the node ID, and calls the decode() method.


processUpdates

public void processUpdates(javax.faces.context.FacesContext context)
If "rendered" is true, calls processNodes() with a PhaseId for this phase, resets the node ID, and calls the decode() method.


saveState

public java.lang.Object saveState(javax.faces.context.FacesContext context)
Returns the component state to be saved as part of the view state.

Specified by:
saveState in interface javax.faces.component.StateHolder

restoreState

public void restoreState(javax.faces.context.FacesContext context,
                         java.lang.Object state)
Restores the component to the provided state, previously returned by the saveState() method.

Specified by:
restoreState in interface javax.faces.component.StateHolder

getDataModel

private TreeModel getDataModel()
Returns the cached model, if any, or the components value, as-is if it's a TreeModel or wrapped in a new TreeModel if it's a TreeNode, saving a reference in the "model" variable.


processNodes

private void processNodes(javax.faces.context.FacesContext context,
                          javax.faces.event.PhaseId phaseId,
                          java.lang.String parentId,
                          int childLevel)
Recursively process all nodes at the root of the tree and all nodes under an open node for the provided phase, i.e., by calling processDecodes(), processValidators() or processUpdates() on the facet representing the node type.


keepSaved

private boolean keepSaved(javax.faces.context.FacesContext context)
Returns "true" if there's at least one error message queued for a client ID matching one of the nodes.


restoreDescendantState

private void restoreDescendantState()
Restores state information for all facets by calling the restoreDescendantState(UIComponent, FacesContext) method on each facet.


restoreDescendantState

private void restoreDescendantState(javax.faces.component.UIComponent component,
                                    javax.faces.context.FacesContext context)
Restore state information for the specified component and its children from the previously saved state, if any.


saveDescendantState

private void saveDescendantState()
Saves state information for all facets by calling the saveDescendantState(UIComponent, FacesContext) method on each facet.


saveDescendantState

private void saveDescendantState(javax.faces.component.UIComponent component,
                                 javax.faces.context.FacesContext context)
Saves state information for the specified component, if it implements the EditableValueHolder interface, and its children.