
com.icesoft.faces.component.tree.Tree Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of icefaces-compat Show documentation
Show all versions of icefaces-compat Show documentation
${icefaces.product.name} Compat Component Library
/*
* Copyright 2004-2012 ICEsoft Technologies Canada Corp.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an "AS
* IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language
* governing permissions and limitations under the License.
*/
package com.icesoft.faces.component.tree;
import com.icesoft.faces.component.CSS_DEFAULT;
import com.icesoft.faces.component.ext.taglib.Util;
import com.icesoft.faces.util.CoreUtils;
import javax.faces.FacesException;
import javax.faces.component.ContextCallback;
import javax.faces.application.FacesMessage;
import javax.faces.component.EditableValueHolder;
import javax.faces.component.NamingContainer;
import javax.faces.component.UIColumn;
import javax.faces.component.UICommand;
import javax.faces.component.UIComponent;
import javax.faces.component.UINamingContainer;
import javax.faces.component.visit.VisitCallback;
import javax.faces.component.visit.VisitContext;
import javax.faces.component.visit.VisitResult;
import javax.faces.context.FacesContext;
import javax.faces.el.ValueBinding;
import javax.faces.event.AbortProcessingException;
import javax.faces.event.FacesEvent;
import javax.faces.event.FacesListener;
import javax.faces.event.PhaseId;
import javax.faces.event.ActionEvent;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreeModel;
import javax.swing.tree.DefaultTreeModel;
import java.io.IOException;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
/**
* Tree is a JSF component class that represent an ICEfaces tree.
*
* The tree component displays hierarchical data as a "tree" of branches and
* leaf nodes. Optionally, the tree may also display navigation controls for the
* dynamic expansion and collapse of branch nodes. Nodes may also support an
* action event when clicked that can be used to respond to user click events.
*
* This component extends the JSF UICommand component and implemnents the JSF
* NamingContainer interface.
*
* By default this component is rendered by the "com.icesoft.faces.View"
* renderer type.
*
* @author Chris Brown
* @author gmccleary
* @version 1.1
*/
public class Tree extends UICommand implements NamingContainer {
// default style classes
private static final String DEFAULT_CSSIMAGEDIR =
"/xmlhttp/css/xp/css-images/";
private static final String DEFAULT_NAV_OPEN_TOP_GIF =
"tree_nav_top_open.gif";
private static final String DEFAULT_NAV_CLOSE_TOP_GIF =
"tree_nav_top_close.gif";
private static final String DEFAULT_NAV_OPEN_TOP_NO_SIBLINGS_GIF =
"tree_nav_top_open_no_siblings.gif";
private static final String DEFAULT_NAV_CLOSE_TOP_NO_SIBLINGS_GIF =
"tree_nav_top_close_no_siblings.gif";
private static final String DEFAULT_NAV_OPEN_MIDDLE_GIF =
"tree_nav_middle_open.gif";
private static final String DEFAULT_NAV_CLOSE_MIDDLE_GIF =
"tree_nav_middle_close.gif";
private static final String DEFAULT_NAV_CLOSE_BOTTOM_GIF =
"tree_nav_bottom_close.gif";
private static final String DEFAULT_NAV_OPEN_BOTTOM_GIF =
"tree_nav_bottom_open.gif";
private static final String DEFAULT_LINE_MIDDLE_NODE_GIF =
"tree_line_middle_node.gif";
private static final String DEFAULT_LINE_VERTICAL_GIF =
"tree_line_vertical.gif";
private static final String DEFAULT_LINE_BLANK_GIF = "tree_line_blank.gif";
private static final String DEFAULT_LINE_BOTTOM_NODE_GIF =
"tree_line_last_node.gif";
private static final String DEFAULT_DOCUMENT_GIF = "tree_document.gif";
private static final String DEFAULT_FOLDER_GIF = "tree_folder_close.gif";
private static final String DEFAULT_FOLDER_OPEN_GIF =
"tree_folder_open.gif";
/**
* String constant for tree node collapse event.
*/
public static final String NAVIGATION_EVENT_COLLAPSE = "collapse";
/**
* String constant for tree node expand event.
*/
public static final String NAVIGATION_EVENT_EXPAND = "expand";
/**
* String constant for tree node id prefix.
*/
public static final String ID_PREFIX = "n-";
// private attributes
transient private DefaultMutableTreeNode navigatedNode;
private String navigationEventType;
// images
private String imageDir;
private String navOpenTop;
private String navOpenTopNoSiblings;
private String navCloseTopNoSiblings;
private String navCloseTop;
private String navCloseMiddle;
private String navOpenMiddle;
private String lineMiddleNode;
private String lineBottomNode;
private String lineVertical;
private String lineBlank;
private String documentImage;
private String folderImage;
private String folderOpenImage;
private String navCloseBottom;
private String navOpenBottom;
private String var;
private String styleClass;
private String style;
private String hideRootNode;
private String hideNavigation;
private String pathToExpandedNode;
private Boolean keyboardNavigationEnabled;
transient private DefaultMutableTreeNode currentNode;
private String nodePath;
private String title;
private TreeModel dummyModel = null;
/**
* default no args constructor
*/
public Tree() {
}
/**
* String constant specifying component type
*/
public static final String COMPONENT_TYPE = "com.icesoft.faces.TreeView";
/**
* @return the renderer type of the tree component.
*/
public String getRendererType() {
return "com.icesoft.faces.View";
}
/**
* @return the component type of the tree component.
*/
public String getComponentType() {
return COMPONENT_TYPE;
}
/*
* (non-Javadoc)
*
* @see javax.faces.component.UIComponent#getFamily()
*/
public String getFamily() {
return "com.icesoft.faces.TreeView";
}
// accessors & modifiers aka getters and setters
/**
* @param currentNode
*/
public void setCurrentNode(DefaultMutableTreeNode currentNode) {
this.currentNode = currentNode;
}
/**
* @return DefaultMutableTreeNode currentNode
*/
public DefaultMutableTreeNode getCurrentNode() {
return this.currentNode;
}
public void encodeBegin(FacesContext context) throws IOException {
if (!keepSaved(context)) {
savedChildren = new HashMap();
}
super.encodeBegin(context);
}
private boolean keepSaved(FacesContext context) {
Iterator clientIds = savedChildren.keySet().iterator();
while (clientIds.hasNext()) {
String clientId = (String) clientIds.next();
Iterator messages = context.getMessages(clientId);
while (messages.hasNext()) {
FacesMessage message = (FacesMessage) messages.next();
if (message.getSeverity().compareTo(FacesMessage.SEVERITY_ERROR)
>= 0) {
return (true);
}
}
}
return false;
}
/**
* @param nodePath
*/
public void setNodePath(String nodePath) {
FacesContext facesContext = getFacesContext();
this.nodePath = nodePath;
// save the state of the last node
saveChildrenState(facesContext);
// put the current node on the request map
this.setCurrentVarToRequestMap(facesContext, getCurrentNode());
// restore the state for current node
restoreChildrenState(facesContext);
}
/**
* @return String nodePath
*/
public String getNodePath() {
return this.nodePath;
}
/**
* @return TreeModel model associated with tree
*/
public TreeModel getModel() {
ValueBinding vb = getValueBinding("value");
TreeModel model = (TreeModel) vb.getValue(getFacesContext());
if (model == null) {
return getDummyModel();
}
return model;
}
public TreeModel getDummyModel() {
if (dummyModel == null) {
DefaultMutableTreeNode defaultMutableTreeNode = new DefaultMutableTreeNode();
IceUserObject iceUserObject = new IceUserObject(defaultMutableTreeNode);
dummyModel = new DefaultTreeModel(new DefaultMutableTreeNode(iceUserObject));
}
return dummyModel;
}
/**
* @return TreeNode template
* @throws MalformedTreeTagException
*/
public TreeNode getTreeNodeTemplate() throws MalformedTreeTagException {
TreeNode template = null;
int childCount = this.getChildCount();
if (childCount != 1) {
throw new MalformedTreeTagException(
"The tree tag requires a single treeNode child tag. Found ["
+ childCount + "] children");
}
UIComponent treeNodeTemplate = (UIComponent) getChildren().get(0);
if (treeNodeTemplate == null) {
throw new MalformedTreeTagException(
"The Tree requires a TreeNode child. None found.");
}
if (!(treeNodeTemplate instanceof TreeNode)) {
throw new MalformedTreeTagException(
"The Tree requires a TreeNode child. Found child of type ["
+ treeNodeTemplate.getClass() + "]");
}
return template;
}
/**
* @param pathToSelectedNode
* @return DefaultMutableTreeNode node at specified path
*/
public DefaultMutableTreeNode getNodeAtPathsEnd(String pathToSelectedNode) {
if (pathToSelectedNode.equalsIgnoreCase("root")) {
return (DefaultMutableTreeNode) getModel().getRoot();
}
String[] indices = pathToSelectedNode
.split(TreeRenderer.PATH_DELIMITER);
DefaultMutableTreeNode parent = (DefaultMutableTreeNode) getModel()
.getRoot();
for (int i = 0; i < indices.length; i++) {
parent = (DefaultMutableTreeNode) parent.getChildAt(Integer
.parseInt(indices[i]));
}
return parent;
}
// image paths
/**
* @return String imageDir
*/
public String getImageDir() {
if (imageDir != null) {
return imageDir;
}
ValueBinding vb = getValueBinding("imageDir");
return CoreUtils.resolveResourceURL(getFacesContext(),
vb != null ? (String) vb.getValue(getFacesContext()) : DEFAULT_CSSIMAGEDIR);
}
/**
* Set the value of the styleClass
property.
*
* @return String style class property value.
*/
public String getStyleClass() {
return Util.getQualifiedStyleClass(this,
styleClass,
CSS_DEFAULT.TREE_DEFAULT_STYLE_CLASS,
"styleClass");
}
/**
* Set the value of the styleClass
property.
*
* @param styleClass
*/
public void setStyleClass(String styleClass) {
this.styleClass = styleClass;
}
/**
* Set the value of the style
property.
*
* @return String style property value.
*/
public String getStyle() {
if (style != null) {
return style;
}
ValueBinding vb = getValueBinding("style");
return vb != null ? (String) vb.getValue(getFacesContext()) : "";
}
/**
* Set the value of the style
property.
*
* @param style
*/
public void setStyle(String style) {
this.style = style;
}
String getTreeRowStyleClass() {
return Util.getQualifiedStyleClass(this,
CSS_DEFAULT.STYLE_TREEROW);
}
/**
* @param imageProperty
* @param bindingName
* @param defaultImage
* @return String img src
*/
public String getImage(String imageProperty, String bindingName,
String defaultImage) {
if (imageProperty != null) {
return imageProperty;
}
ValueBinding vb = getValueBinding(bindingName);
if (vb != null) {
return (String) vb.getValue(getFacesContext());
}
return getImageDir() + defaultImage;
}
/**
* @return String folder img src
*/
public String getFolderImage() {
return getImage(folderImage, "folderImage", DEFAULT_FOLDER_GIF);
}
/**
* @return String folder open img src
*/
public String getFolderOpenImage() {
return getImage(folderOpenImage, "folderOpenImage",
DEFAULT_FOLDER_OPEN_GIF);
}
/**
* @return String document img src
*/
public String getDocumentImage() {
return getImage(documentImage, "documentImage", DEFAULT_DOCUMENT_GIF);
}
/**
* @return String line bottom img src
*/
public String getLineBottomImage() {
return getImage(lineBottomNode, "lineBottom",
DEFAULT_LINE_BOTTOM_NODE_GIF);
}
/**
* @return String line vertical img src
*/
public String getLineVerticalImage() {
return getImage(lineVertical, "lineVertical",
DEFAULT_LINE_VERTICAL_GIF);
}
/**
* @return String line middle img src
*/
public String getLineMiddleImage() {
return getImage(lineMiddleNode, "lineMiddle",
DEFAULT_LINE_MIDDLE_NODE_GIF);
}
/**
* @return String navigation close middle img src
*/
public String getNavCloseMiddleImage() {
return getImage(navCloseMiddle, "navCloseMiddleImage",
DEFAULT_NAV_CLOSE_MIDDLE_GIF);
}
/**
* @return String navigation open middle img src
*/
public String getNavOpenMiddleImage() {
return getImage(navOpenMiddle, "navOpenMiddle",
DEFAULT_NAV_OPEN_MIDDLE_GIF);
}
/**
* @return String navigation close top img src
*/
public String getNavCloseTopImage() {
return getImage(navCloseTop, "navCloseTop", DEFAULT_NAV_CLOSE_TOP_GIF);
}
/**
* @return String navigation open top img src
*/
public String getNavOpenTopImage() {
return getImage(navOpenTop, "navOpenTopImage",
DEFAULT_NAV_OPEN_TOP_GIF);
}
/**
* @return String navigation open top img src
*/
public String getNavOpenTopNoSiblingsImage() {
return getImage(navOpenTopNoSiblings, "navOpenTopNoSiblingsImage",
DEFAULT_NAV_OPEN_TOP_NO_SIBLINGS_GIF);
}
/**
* @return String navigation close top img src
*/
public String getNavCloseTopNoSiblingsImage() {
return getImage(navCloseTopNoSiblings, "navCloseTopNoSiblingsImage",
DEFAULT_NAV_CLOSE_TOP_NO_SIBLINGS_GIF);
}
/**
* @return String navigation close bottom img src
*/
public String getNavCloseBottomImage() {
return getImage(navCloseBottom, "navCloseBottomImage",
DEFAULT_NAV_CLOSE_BOTTOM_GIF);
}
/**
* @return String navigation open bottom img src
*/
public String getNavOpenBottomImage() {
return getImage(navOpenBottom, "navOpenBottomImage",
DEFAULT_NAV_OPEN_BOTTOM_GIF);
}
/**
* @return String blank img src
*/
public String getLineBlankImage() {
return getImage(lineBlank, "lineBlank", DEFAULT_LINE_BLANK_GIF);
}
/**
* @return String line bottom node
*/
public String getLineBottomNode() {
return lineBottomNode;
}
/**
* @param lineBottomNode
*/
public void setLineBottomNode(String lineBottomNode) {
this.lineBottomNode = lineBottomNode;
}
/**
* @return String line middle node
*/
public String getLineMiddleNode() {
return lineMiddleNode;
}
/**
* @param lineMiddleNode
*/
public void setLineMiddleNode(String lineMiddleNode) {
this.lineMiddleNode = lineMiddleNode;
}
/**
* @return String line vertical
*/
public String getLineVertical() {
return lineVertical;
}
/**
* @param lineVertical
*/
public void setLineVertical(String lineVertical) {
this.lineVertical = lineVertical;
}
/**
* @return String navigation expand middle
*/
public String getNavExpandedMiddle() {
return navCloseMiddle;
}
/**
* @param navExpandedMiddle
*/
public void setNavExpandedMiddle(String navExpandedMiddle) {
this.navCloseMiddle = navExpandedMiddle;
}
/**
* @return String navigation expanded top
*/
public String getNavExpandedTop() {
return navOpenTop;
}
/**
* @param navExpandedTop
*/
public void setNavExpandedTop(String navExpandedTop) {
this.navOpenTop = navExpandedTop;
}
/**
* @param imageDir
*/
public void setImageDir(String imageDir) {
this.imageDir = imageDir;
}
/**
* @param documentImage
*/
public void setDocumentImage(String documentImage) {
this.documentImage = documentImage;
}
/**
* @param folderImage
*/
public void setFolderImage(String folderImage) {
this.folderImage = folderImage;
}
/**
* @return String navigation close top
*/
public String getNavCloseTop() {
return navCloseTop;
}
/**
* @param navCloseTop
*/
public void setNavCloseTop(String navCloseTop) {
this.navCloseTop = navCloseTop;
}
/**
* @return String navigation open top
*/
public String getNavOpenTop() {
return navOpenTop;
}
/**
* @param navOpenTop
*/
public void setNavOpenTop(String navOpenTop) {
this.navOpenTop = navOpenTop;
}
/**
* @return String navigation open top
*/
public String getNavOpenTopNoSiblings() {
return navOpenTopNoSiblings;
}
/**
* @param navOpenTopNoSiblings
*/
public void setNavOpenTopNoSiblings(String navOpenTopNoSiblings) {
this.navOpenTopNoSiblings = navOpenTopNoSiblings;
}
/**
* @return String navigation close top
*/
public String getNavCloseTopNoSiblings() {
return navCloseTopNoSiblings;
}
/**
* @param navCloseTopNoSiblings
*/
public void setNavCloseTopNoSiblings(String navCloseTopNoSiblings) {
this.navCloseTopNoSiblings = navCloseTopNoSiblings;
}
/**
* @param folderOpenImage
*/
public void setFolderOpenImage(String folderOpenImage) {
this.folderOpenImage = folderOpenImage;
}
/**
* @return String navigation close bottom
*/
public String getNavCloseBottom() {
return navCloseBottom;
}
/**
* @param navCloseBottom
*/
public void setNavCloseBottom(String navCloseBottom) {
this.navCloseBottom = navCloseBottom;
}
/**
* @return String navigation close middle
*/
public String getNavCloseMiddle() {
return navCloseMiddle;
}
/**
* @param navCloseMiddle
*/
public void setNavCloseMiddle(String navCloseMiddle) {
this.navCloseMiddle = navCloseMiddle;
}
/**
* @return String navigation open bottom
*/
public String getNavOpenBottom() {
return navOpenBottom;
}
/**
* @param navOpenBottom
*/
public void setNavOpenBottom(String navOpenBottom) {
this.navOpenBottom = navOpenBottom;
}
/**
* @return String navigation open middle
*/
public String getNavOpenMiddle() {
return navOpenMiddle;
}
/**
* @param navOpenMiddle
*/
public void setNavOpenMiddle(String navOpenMiddle) {
this.navOpenMiddle = navOpenMiddle;
}
/**
* @return String var
*/
public String getVar() {
return var;
}
/**
* @param var
*/
public void setVar(String var) {
this.var = var;
}
/**
* @return String lineBlank
*/
public String getLineBlank() {
return lineBlank;
}
/**
* @param lineBlank
*/
public void setLineBlank(String lineBlank) {
this.lineBlank = lineBlank;
}
/**
* @return DefaultMutableTreeNode navigatedNode
*/
public DefaultMutableTreeNode getNavigatedNode() {
if (pathToExpandedNode != null) {
return getNodeAtPathsEnd(pathToExpandedNode);
}
return navigatedNode;
}
/**
* @param navigatedNode
*/
public void setNavigatedNode(DefaultMutableTreeNode navigatedNode) {
pathToExpandedNode = null;
this.navigatedNode = navigatedNode;
}
/**
* @param string
*/
public void setNavigationEventType(String string) {
this.navigationEventType = string;
}
/**
* @return String navigationEventType
*/
public String getNavigationEventType() {
return navigationEventType;
}
// StateHolder Methods
/**
* save the tree component state
*
* @param context
* @return Object values[]
*/
public Object saveState(FacesContext context) {
Object values[] = new Object[28];
values[0] = super.saveState(context);
values[1] = title;
values[2] = navigationEventType;
values[3] = imageDir;
values[4] = navOpenTop;
values[5] = navOpenTopNoSiblings;
values[6] = navCloseTopNoSiblings;
values[7] = navCloseTop;
values[8] = navCloseMiddle;
values[9] = navOpenMiddle;
values[10] = lineMiddleNode;
values[11] = lineBottomNode;
values[12] = lineVertical;
values[13] = lineBlank;
values[14] = documentImage;
values[15] = folderImage;
values[16] = folderOpenImage;
values[17] = navCloseBottom;
values[18] = navOpenBottom;
values[19] = var;
values[20] = styleClass;
values[21] = style;
values[22] = hideRootNode;
values[23] = hideNavigation;
values[24] = nodePath;
values[25] = savedChildren;
values[26] = pathToExpandedNode;
values[27] = keyboardNavigationEnabled;
return (values);
}
/**
* restore the tree component state
*
* @param context
* @param state
*/
public void restoreState(FacesContext context, Object state) {
Object values[] = (Object[]) state;
super.restoreState(context, values[0]);
title = (String) values[1];
navigationEventType = (String) values[2];
imageDir = (String) values[3];
navOpenTop = (String) values[4];
navOpenTopNoSiblings = (String) values[5];
navCloseTopNoSiblings = (String) values[6];
navCloseTop = (String) values[7];
navCloseMiddle = (String) values[8];
navOpenMiddle = (String) values[9];
lineMiddleNode = (String) values[10];
lineBottomNode = (String) values[11];
lineVertical = (String) values[12];
lineBlank = (String) values[13];
documentImage = (String) values[14];
folderImage = (String) values[15];
folderOpenImage = (String) values[16];
navCloseBottom = (String) values[17];
navOpenBottom = (String) values[18];
var = (String) values[19];
styleClass = (String) values[20];
style = (String) values[21];
hideRootNode = (String) values[22];
hideNavigation = (String) values[23];
nodePath = (String) values[24];
savedChildren = (Map) values[25];
pathToExpandedNode = (String) values[26];
keyboardNavigationEnabled = (Boolean) values[27];
}
/*
* (non-Javadoc)
*
* @see javax.faces.component.UIComponent#processDecodes(javax.faces.context.FacesContext)
*/
public void processDecodes(FacesContext context) {
if (context == null) {
throw new NullPointerException("context");
}
if (!isRendered()) {
return;
}
if (null == savedChildren || !keepSaved(context)) {
savedChildren = new HashMap();
}
this.processTreeNodes((DefaultMutableTreeNode) getModel().getRoot(),
PhaseId.APPLY_REQUEST_VALUES, context);
try {
this.setNodePath(null);
this.setCurrentNode(null);
decode(context);
} catch (RuntimeException e) {
context.renderResponse();
throw e;
}
}
// see superclass for documentation
/* (non-Javadoc)
* @see javax.faces.component.UIComponentBase#processValidators(javax.faces.context.FacesContext)
*/
public void processValidators(FacesContext context) {
if (context == null) {
throw new NullPointerException("context");
}
if (!isRendered()) {
return;
}
this.processTreeNodes((DefaultMutableTreeNode) getModel().getRoot(),
PhaseId.PROCESS_VALIDATIONS, context);
this.setNodePath(null);
this.setCurrentNode(null);
}
// see superclass for documentation
/* (non-Javadoc)
* @see javax.faces.component.UIComponentBase#processUpdates(javax.faces.context.FacesContext)
*/
public void processUpdates(FacesContext context) {
if (context == null) {
throw new NullPointerException("context");
}
if (!isRendered()) {
return;
}
this.processTreeNodes((DefaultMutableTreeNode) getModel().getRoot(),
PhaseId.UPDATE_MODEL_VALUES, context);
this.setNodePath(null);
this.setCurrentNode(null);
}
/**
* Recursively process all TreeNodes starting at the currentNode. TreeNodes
* will be process according the the phaseId
*
* @param currentNode
* @param phaseId
* @param context
*/
private void processTreeNodes(DefaultMutableTreeNode currentNode,
Object phaseId,
FacesContext context) {
// set currentNode on tree
this.setCurrentNode(currentNode);
TreeNode treeNodeTemplate = (TreeNode) this.getChildren().get(0);
String pathToCurrentNode = TreeRenderer.getPathAsString(currentNode,
(DefaultMutableTreeNode) getModel()
.getRoot());
treeNodeTemplate.setMutable(currentNode);
treeNodeTemplate.setId(ID_PREFIX + pathToCurrentNode);
this.setNodePath(pathToCurrentNode);
// get TreeNode facets from treeNodeTemplate
UIComponent iconFacet;
UIComponent contentFacet;
iconFacet = treeNodeTemplate.getIcon();
contentFacet = treeNodeTemplate.getContent();
// call appropriate phase handler
if (phaseId == PhaseId.APPLY_REQUEST_VALUES) {
if (iconFacet != null) {
iconFacet.processDecodes(context);
}
if (contentFacet != null) {
contentFacet.processDecodes(context);
}
} else if (phaseId == PhaseId.PROCESS_VALIDATIONS) {
if (iconFacet != null) {
iconFacet.processValidators(context);
}
if (contentFacet != null) {
contentFacet.processValidators(context);
}
} else if (phaseId == PhaseId.UPDATE_MODEL_VALUES) {
if (iconFacet != null) {
iconFacet.processUpdates(context);
}
if (contentFacet != null) {
contentFacet.processUpdates(context);
}
}
// recurse currentRoot's children
IceUserObject userObject = (IceUserObject) currentNode.getUserObject();
if (userObject.isExpanded()) {
int childCount = currentNode.getChildCount();
for (int childIndex = 0; childIndex < childCount; childIndex++) {
DefaultMutableTreeNode nextNode =
(DefaultMutableTreeNode) currentNode
.getChildAt(childIndex);
processTreeNodes(nextNode,
phaseId,
context);
}
}
}
/*
* (non-Javadoc)
*
* @see javax.faces.component.UIComponent#queueEvent(javax.faces.event.FacesEvent)
*/
public void queueEvent(FacesEvent event) {
UIComponent eventComponent = event.getComponent();
UIComponent parentTreeNode = eventComponent.getParent();
while (parentTreeNode != null &&
!(parentTreeNode instanceof TreeNode)) {
parentTreeNode = parentTreeNode.getParent();
}
if (parentTreeNode != null) {
event = new NodeEvent(
this, event, ((TreeNode) parentTreeNode).getMutable());
}
// ICE-1956 UICommand subclasses shouldn't call super.queueEvent
// on ActionEvents or else the immediate flag is ignored
// Shouldn't really be an issue for Tree though, since it tries
// to wrap event in NodeEvent, which doesn't extend ActionEvent,
// but we might as well still have this code so we're not brittle
if( (event instanceof ActionEvent) &&
!this.equals(event.getComponent()) &&
getParent() != null )
{
getParent().queueEvent(event);
}
else
super.queueEvent(event);
}
/*
* (non-Javadoc)
*
* @see javax.faces.component.UIComponent#broadcast(javax.faces.event.FacesEvent)
*/
public void broadcast(FacesEvent event) throws AbortProcessingException {
if (!(event instanceof NodeEvent)) {
super.broadcast(event);
return;
}
// Set up the correct context and fire our wrapped event
NodeEvent wrapperEvent = (NodeEvent) event;
DefaultMutableTreeNode eventNode = wrapperEvent.getNode();
this.setCurrentNode(eventNode);
this.setNodePath(TreeRenderer.getPathAsString(eventNode,
(DefaultMutableTreeNode) getModel()
.getRoot()));
FacesEvent facesEvent = wrapperEvent.getFacesEvent();
facesEvent.getComponent().broadcast(facesEvent);
}
/**
* @param context
* @param currentVar
*/
private void setCurrentVarToRequestMap(FacesContext context,
DefaultMutableTreeNode currentVar) {
Map requestMap = context.getExternalContext().getRequestMap();
String varAttribute = getVar();
if (currentVar != null) {
requestMap.put(varAttribute, currentVar);
}
}
/**
* @return String hideNavigation
*/
public String getHideNavigation() {
if (hideNavigation != null) {
return hideNavigation;
}
ValueBinding vb = getValueBinding("hideNavigation");
if (vb != null) {
return vb.getValue(getFacesContext()).toString();
}
return String.valueOf(false);
}
/**
* @param b
*/
public void setHideNavigation(String b) {
hideNavigation = b;
}
/**
* @return String hideRootNode
*/
public String getHideRootNode() {
if (hideRootNode != null) {
return hideRootNode;
}
ValueBinding vb = getValueBinding("hideRootNode");
if (vb != null) {
return vb.getValue(getFacesContext()).toString();
}
return String.valueOf(false);
}
/**
* @param b
*/
public void setHideRootNode(String b) {
hideRootNode = b;
}
public String getTitle() {
if (title != null) return title;
ValueBinding vb = getValueBinding("title");
if (vb == null) return null;
return (String) vb.getValue(getFacesContext());
}
public void setTitle(String title) {
this.title = title;
}
// This class wraps TreeNode events
// the TreeNode generates an event and the Tree.queueEvent()
// wraps the event in a NodeEvent which the Tree.broadcast
// recieves and passes on to the TreeNode.
class NodeEvent extends FacesEvent {
/**
*
*/
private static final long serialVersionUID = 1L;
private FacesEvent event = null;
private DefaultMutableTreeNode node = null;
/**
* @param component
* @param event
* @param node
*/
public NodeEvent(UIComponent component, FacesEvent event,
DefaultMutableTreeNode node) {
super(component);
this.event = event;
this.node = node;
}
/**
* @return DefaultMutableTreeNode node
*/
public DefaultMutableTreeNode getNode() {
return node;
}
/**
* @param node
*/
public void setNode(DefaultMutableTreeNode node) {
this.node = node;
}
/**
* @return FacesEvent event
*/
public FacesEvent getFacesEvent() {
return (this.event);
}
/* (non-Javadoc)
* @see javax.faces.event.FacesEvent#getPhaseId()
*/
public PhaseId getPhaseId() {
return (this.event.getPhaseId());
}
/* (non-Javadoc)
* @see javax.faces.event.FacesEvent#setPhaseId(javax.faces.event.PhaseId)
*/
public void setPhaseId(PhaseId phaseId) {
this.event.setPhaseId(phaseId);
}
/* (non-Javadoc)
* @see javax.faces.event.FacesEvent#isAppropriateListener(javax.faces.event.FacesListener)
*/
public boolean isAppropriateListener(FacesListener listener) {
return (false);
}
/* (non-Javadoc)
* @see javax.faces.event.FacesEvent#processListener(javax.faces.event.FacesListener)
*/
public void processListener(FacesListener listener) {
throw new IllegalStateException();
}
}
/**
* This map contains ChildState
instances for each child
* component, keyed by the client id of the child.
*/
protected Map savedChildren = new HashMap();
/**
* Restore state information for all child components.
*
* @param context
*/
protected void restoreChildrenState(FacesContext context) {
if (getChildCount() == 0) return;
Iterator kids = getChildren().iterator();
while (kids.hasNext()) {
UIComponent kid = (UIComponent) kids.next();
restoreChildState(kid, context);
}
}
/**
* Restore state information for the given child component.
*
* @param component
* @param context
*/
protected void restoreChild(UIComponent component, FacesContext context) {
// Restore state for this component (if it is a EditableValueHolder)
if (component instanceof EditableValueHolder) {
EditableValueHolder input = (EditableValueHolder) component;
String clientId = component.getClientId(context);
ChildState state = (ChildState) savedChildren.get(clientId);
if (state == null) {
state = new ChildState();
}
input.setValue(state.getValue());
input.setValid(state.isValid());
input.setSubmittedValue(state.getSubmittedValue());
input.setLocalValueSet(state.isLocalValueSet());
}
}
/**
* Restore state information for the given child component and its
* children.
*
* @param component
* @param context
*/
private void restoreChildState(UIComponent component,
FacesContext context) {
// Reset the client identifier for this component
String id = component.getId();
component.setId(id); // Forces client id to be reset
// restore state for child component
restoreChild(component, context);
// Restore state for children of this component
Iterator kids = component.getFacetsAndChildren();
while (kids.hasNext()) {
restoreChildState((UIComponent) kids.next(), context);
}
}
/**
* Save state information for all children of this component.
*
* @param context
*/
protected void saveChildrenState(FacesContext context) {
if (getChildCount() == 0) return;
Iterator kids = getChildren().iterator();
while (kids.hasNext()) {
UIComponent kid = (UIComponent) kids.next();
saveChildState(kid, context);
}
}
/**
* Save state information for the given child component.
*
* @param component
* @param context
*/
protected void saveChild(UIComponent component, FacesContext context) {
// Save state for this component (if it is a EditableValueHolder)
if (component instanceof EditableValueHolder) {
EditableValueHolder input = (EditableValueHolder) component;
String clientId = component.getClientId(context);
ChildState state = (ChildState) savedChildren.get(clientId);
if (state == null) {
state = new ChildState();
savedChildren.put(clientId, state);
}
state.setValue(input.getLocalValue());
state.setValid(input.isValid());
state.setSubmittedValue(input.getSubmittedValue());
state.setLocalValueSet(input.isLocalValueSet());
}
}
/**
* Save state information for the given child component and its
* children.
*
* @param component
* @param context
*/
protected void saveChildState(UIComponent component, FacesContext context) {
// Save state for this child
saveChild(component, context);
// Save state for children of this component including facets as tree nodes are made up of facets
Iterator kids = component.getFacetsAndChildren();
while (kids.hasNext()) {
saveChildState((UIComponent) kids.next(), context);
}
}
String getPathToExpandedNode() {
return pathToExpandedNode;
}
void setPathToExpandedNode(String pathToExpandedNode) {
this.pathToExpandedNode = pathToExpandedNode;
}
public boolean invokeOnComponent(FacesContext context, String clientId,
ContextCallback callback) throws FacesException {
if (null == context || null == clientId || null == callback) {
throw new NullPointerException();
}
// String myId = super.getClientId(context);
// boolean found = false;
// if (clientId.equals(myId)) {
// try {
// callback.invokeContextCallback(context, this);
// return true;
// }
// catch (Exception e) {
// throw new FacesException(e);
// }
// }
return true;
}
@Override
public boolean visitTree(VisitContext context,
VisitCallback callback) {
if (!isRendered())
return false;
if (!isVisitable(context))
return false;
// Push ourselves to EL
FacesContext facesContext = context.getFacesContext();
pushComponentToEL(facesContext, null);
try {
// Visit ourselves
VisitResult result = context.invokeVisitCallback(this, callback);
// If the visit is complete, short-circuit out and end the visit
if (result == VisitResult.COMPLETE)
return true;
// Visit children, short-circuiting as necessary
if ((result == VisitResult.ACCEPT)) {
// Next column facets
if (visitTreeNodeFacets(context, callback))
return true;
// And finally, visit rows
if (visitRows(context, callback))
return true;
}
}
finally {
// Clean up - pop EL and restore old row index
popComponentFromEL(facesContext);
}
// Return false to allow the visit to continue
return false;
}
// Visit each facet of our child UIColumn components exactly once
private boolean visitTreeNodeFacets(VisitContext context,
VisitCallback callback) {
if (getChildCount() > 0) {
for (UIComponent treeNode : getChildren()) {
if (treeNode.getFacetCount() > 0) {
for (UIComponent columnFacet : treeNode.getFacets().values()) {
if (columnFacet.visitTree(context, callback))
return true;
}
}
}
}
return false;
}
private boolean visitRows(VisitContext context, VisitCallback callback) {
//visit all TreeNodes
if (getChildCount() > 0) {
for (UIComponent kid : getChildren()) {
if (!(kid instanceof TreeNode)) {
continue;
}
if (kid.visitTree(context, callback)) {
return true;
}
}
}
//visit through the model
this.visitTreeNodes((DefaultMutableTreeNode) getModel().getRoot(),
context, callback);
this.setCurrentNode(null);
return false;
}
private void visitTreeNodes(DefaultMutableTreeNode currentNode,
VisitContext visitContext,
VisitCallback callback) {
// set currentNode on tree
this.setCurrentNode(currentNode);
TreeNode treeNodeTemplate = (TreeNode) this.getChildren().get(0);
String pathToCurrentNode = TreeRenderer.getPathAsString(currentNode,
(DefaultMutableTreeNode) getModel()
.getRoot());
treeNodeTemplate.setMutable(currentNode);
treeNodeTemplate.setId(ID_PREFIX + pathToCurrentNode);
this.setNodePath(pathToCurrentNode);
// get TreeNode facets from treeNodeTemplate
UIComponent iconFacet;
UIComponent contentFacet;
iconFacet = treeNodeTemplate.getIcon();
contentFacet = treeNodeTemplate.getContent();
if (iconFacet != null) {
iconFacet.visitTree(visitContext, callback);
}
if (contentFacet != null) {
contentFacet.visitTree(visitContext, callback);
}
//
// recurse currentRoot's children
IceUserObject userObject = (IceUserObject) currentNode.getUserObject();
if (userObject.isExpanded()) {
int childCount = currentNode.getChildCount();
for (int childIndex = 0; childIndex < childCount; childIndex++) {
DefaultMutableTreeNode nextNode =
(DefaultMutableTreeNode) currentNode
.getChildAt(childIndex);
visitTreeNodes(nextNode,
visitContext,
callback);
}
}
}
public boolean isKeyboardNavigationEnabled() {
if (keyboardNavigationEnabled != null) {
return keyboardNavigationEnabled.booleanValue();
}
ValueBinding vb = getValueBinding("keyboardNavigationEnabled");
Boolean boolVal = vb != null ?
(Boolean) vb.getValue(getFacesContext()) : null;
return boolVal != null ? boolVal.booleanValue() : true;
}
public void setKeyboardNavigationEnabled(boolean keyboardNavigationEnabled) {
this.keyboardNavigationEnabled = new Boolean(keyboardNavigationEnabled);
}
}
// Private class to represent saved state information for the children of the Tree component
class ChildState implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private Object submittedValue;
private boolean valid = true;
private Object value;
private boolean localValueSet;
Object getSubmittedValue() {
return (this.submittedValue);
}
void setSubmittedValue(Object submittedValue) {
this.submittedValue = submittedValue;
}
boolean isValid() {
return (this.valid);
}
void setValid(boolean valid) {
this.valid = valid;
}
Object getValue() {
return (this.value);
}
/**
* @param value
*/
public void setValue(Object value) {
this.value = value;
}
boolean isLocalValueSet() {
return (this.localValueSet);
}
/**
* @param localValueSet
*/
public void setLocalValueSet(boolean localValueSet) {
this.localValueSet = localValueSet;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy