Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.primefaces.component.tree.Tree Maven / Gradle / Ivy
/*
* The MIT License
*
* Copyright (c) 2009-2023 PrimeTek Informatics
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package org.primefaces.component.tree;
import java.util.*;
import javax.el.MethodExpression;
import javax.faces.FacesException;
import javax.faces.application.ResourceDependency;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.event.AjaxBehaviorEvent;
import javax.faces.event.BehaviorEvent;
import javax.faces.event.FacesEvent;
import javax.faces.event.PhaseId;
import org.primefaces.PrimeFaces;
import org.primefaces.event.*;
import org.primefaces.model.CheckboxTreeNode;
import org.primefaces.model.DefaultTreeNode;
import org.primefaces.model.TreeNode;
import org.primefaces.util.ComponentUtils;
import org.primefaces.util.Constants;
import org.primefaces.util.MapBuilder;
@ResourceDependency(library = "primefaces", name = "components.css")
@ResourceDependency(library = "primefaces", name = "jquery/jquery.js")
@ResourceDependency(library = "primefaces", name = "jquery/jquery-plugins.js")
@ResourceDependency(library = "primefaces", name = "core.js")
@ResourceDependency(library = "primefaces", name = "components.js")
public class Tree extends TreeBase {
public static final String COMPONENT_TYPE = "org.primefaces.component.Tree";
public static final String FILTER_CLASS = "ui-tree-filter ui-inputfield ui-inputtext ui-widget ui-state-default ui-corner-all";
public static final String FILTER_CONTAINER = "ui-tree-filter-container";
public static final String CONTAINER_CLASS = "ui-tree ui-widget ui-widget-content ui-corner-all";
public static final String CONTAINER_RTL_CLASS = "ui-tree ui-tree-rtl ui-widget ui-widget-content ui-corner-all";
public static final String HORIZONTAL_CONTAINER_CLASS = "ui-tree ui-tree-horizontal ui-widget ui-widget-content ui-corner-all";
public static final String ROOT_NODES_CLASS = "ui-tree-container";
public static final String PARENT_NODE_CLASS = "ui-treenode ui-treenode-parent";
public static final String LEAF_NODE_CLASS = "ui-treenode ui-treenode-leaf";
public static final String CHILDREN_NODES_CLASS = "ui-treenode-children";
public static final String NODE_CONTENT_CLASS_V = "ui-treenode-content";
public static final String SELECTABLE_NODE_CONTENT_CLASS_V = "ui-treenode-content ui-tree-selectable";
public static final String NODE_CONTENT_CLASS_H = "ui-treenode-content ui-state-default ui-corner-all";
public static final String SELECTABLE_NODE_CONTENT_CLASS_H = "ui-treenode-content ui-tree-selectable ui-state-default ui-corner-all";
public static final String EXPANDED_ICON_CLASS_V = "ui-tree-toggler ui-icon ui-icon-triangle-1-s";
public static final String COLLAPSED_ICON_CLASS_V = "ui-tree-toggler ui-icon ui-icon-triangle-1-e";
public static final String COLLAPSED_ICON_RTL_CLASS_V = "ui-tree-toggler ui-icon ui-icon-triangle-1-w";
public static final String EXPANDED_ICON_CLASS_H = "ui-tree-toggler ui-icon ui-icon-minus";
public static final String COLLAPSED_ICON_CLASS_H = "ui-tree-toggler ui-icon ui-icon-plus";
public static final String LEAF_ICON_CLASS = "ui-treenode-leaf-icon";
public static final String NODE_ICON_CLASS = "ui-treenode-icon ui-icon";
public static final String NODE_LABEL_CLASS = "ui-treenode-label ui-corner-all";
private static final Map> BEHAVIOR_EVENT_MAPPING = MapBuilder.>builder()
.put("select", NodeSelectEvent.class)
.put("unselect", NodeUnselectEvent.class)
.put("expand", NodeExpandEvent.class)
.put("collapse", NodeCollapseEvent.class)
.put("dragdrop", TreeDragDropEvent.class)
.put("contextMenu", NodeSelectEvent.class)
.put("filter", null)
.build();
private static final Collection EVENT_NAMES = BEHAVIOR_EVENT_MAPPING.keySet();
private Map nodes;
private TreeNode dragNode;
private TreeNode[] dragNodes;
private TreeNode dropNode;
private boolean retValOnDrop = true;
private List filteredRowKeys = new ArrayList<>();
public UITreeNode getUITreeNodeByType(String type) {
UITreeNode node = getTreeNodes().get(type);
if (node == null) {
throw new javax.faces.FacesException("Unsupported tree node type:" + type);
}
else {
return node;
}
}
public boolean isFiltering() {
return getValueExpression("filterBy") != null || getFilterFunction() != null;
}
public boolean isNodeExpandRequest(FacesContext context) {
return context.getExternalContext().getRequestParameterMap().containsKey(getClientId(context) + "_expandNode");
}
public boolean isSelectionRequest(FacesContext context) {
return context.getExternalContext().getRequestParameterMap().containsKey(getClientId(context) + "_instantSelection");
}
public boolean isFilterRequest(FacesContext context) {
return context.getExternalContext().getRequestParameterMap().containsKey(getClientId(context) + "_filtering");
}
public Map getTreeNodes() {
if (nodes == null) {
nodes = new HashMap<>();
for (UIComponent child : getChildren()) {
if (child instanceof UITreeNode) {
UITreeNode node = (UITreeNode) child;
nodes.put(node.getType(), node);
}
}
}
return nodes;
}
@Override
public Map> getBehaviorEventMapping() {
return BEHAVIOR_EVENT_MAPPING;
}
@Override
public Collection getEventNames() {
return EVENT_NAMES;
}
@Override
public void queueEvent(FacesEvent event) {
FacesContext context = getFacesContext();
if (ComponentUtils.isRequestSource(this, context) && event instanceof AjaxBehaviorEvent) {
Map params = context.getExternalContext().getRequestParameterMap();
String eventName = params.get(Constants.RequestParams.PARTIAL_BEHAVIOR_EVENT_PARAM);
String clientId = getClientId(context);
FacesEvent wrapperEvent = null;
AjaxBehaviorEvent behaviorEvent = (AjaxBehaviorEvent) event;
TreeNode root = getValue();
if ("expand".equals(eventName)) {
setRowKey(root, params.get(clientId + "_expandNode"));
TreeNode expandedNode = getRowNode();
expandedNode.setExpanded(true);
wrapperEvent = new NodeExpandEvent(this, behaviorEvent.getBehavior(), expandedNode);
}
else if ("collapse".equals(eventName)) {
setRowKey(root, params.get(clientId + "_collapseNode"));
TreeNode collapsedNode = getRowNode();
collapsedNode.setExpanded(false);
wrapperEvent = new NodeCollapseEvent(this, behaviorEvent.getBehavior(), collapsedNode);
}
else if ("select".equals(eventName)) {
setRowKey(root, params.get(clientId + "_instantSelection"));
wrapperEvent = new NodeSelectEvent(this, behaviorEvent.getBehavior(), getRowNode());
}
else if ("unselect".equals(eventName)) {
setRowKey(root, params.get(clientId + "_instantUnselection"));
wrapperEvent = new NodeUnselectEvent(this, behaviorEvent.getBehavior(), getRowNode());
}
else if ("dragdrop".equals(eventName)) {
if (!retValOnDrop) {
return;
}
int dndIndex = Integer.parseInt(params.get(clientId + "_dndIndex"));
boolean isDroppedNodeCopy = Boolean.parseBoolean(params.get(clientId + "_isDroppedNodeCopy"));
if (isMultipleDrag()) {
wrapperEvent = new TreeDragDropEvent(this, behaviorEvent.getBehavior(), dragNodes, dropNode, dndIndex, isDroppedNodeCopy);
}
else {
wrapperEvent = new TreeDragDropEvent(this, behaviorEvent.getBehavior(), dragNode, dropNode, dndIndex, isDroppedNodeCopy);
}
}
else if ("contextMenu".equals(eventName)) {
setRowKey(root, params.get(clientId + "_contextMenuNode"));
wrapperEvent = new NodeSelectEvent(this, behaviorEvent.getBehavior(), getRowNode(), true);
}
else if ("filter".equals(eventName)) {
wrapperEvent = behaviorEvent;
}
if (wrapperEvent == null) {
throw new FacesException("Component " + this.getClass().getName() + " does not support event " + eventName + "!");
}
wrapperEvent.setPhaseId(behaviorEvent.getPhaseId());
super.queueEvent(wrapperEvent);
setRowKey(root, null);
}
else {
super.queueEvent(event);
}
}
private boolean isToggleRequest(FacesContext context) {
Map params = context.getExternalContext().getRequestParameterMap();
String clientId = getClientId(context);
return params.get(clientId + "_expandNode") != null || params.get(clientId + "_collapseNode") != null;
}
public boolean isDragDropRequest(FacesContext context) {
Map params = context.getExternalContext().getRequestParameterMap();
String clientId = getClientId(context);
String source = context.getExternalContext().getRequestParameterMap().get(Constants.RequestParams.PARTIAL_SOURCE_PARAM);
return clientId.equals(source) && params.get(clientId + "_dragdrop") != null;
}
private boolean shouldSkipNodes(FacesContext context) {
return isToggleRequest(context) || isDragDropRequest(context);
}
@Override
public void processDecodes(FacesContext context) {
if (!isRendered() || isDisabled()) {
return;
}
if (shouldSkipNodes(context)) {
decode(context);
}
else {
super.processDecodes(context);
}
}
@Override
public void processValidators(FacesContext context) {
if (!shouldSkipNodes(context)) {
super.processValidators(context);
}
}
@Override
public void processUpdates(FacesContext context) {
if (shouldSkipNodes(context)) {
if (isSelectionEnabled()) {
updateSelection(context);
}
}
else {
super.processUpdates(context);
}
}
TreeNode getDragNode() {
return dragNode;
}
void setDragNode(TreeNode dragNode) {
this.dragNode = dragNode;
}
TreeNode[] getDragNodes() {
return dragNodes;
}
void setDragNodes(TreeNode[] dragNodes) {
this.dragNodes = dragNodes;
}
TreeNode getDropNode() {
return dropNode;
}
void setDropNode(TreeNode dropNode) {
this.dropNode = dropNode;
}
@Override
protected boolean shouldVisitNode(TreeNode node) {
return !isDynamic() || (node.isExpanded() || node.getParent() == null);
}
@Override
protected void processColumnChildren(FacesContext context, PhaseId phaseId, TreeNode root, String nodeKey) {
setRowKey(root, nodeKey);
TreeNode treeNode = getRowNode();
if (treeNode == null) {
return;
}
String treeNodeType = treeNode.getType();
for (UIComponent child : getChildren()) {
if (child instanceof UITreeNode && child.isRendered()) {
UITreeNode uiTreeNode = (UITreeNode) child;
if (!treeNodeType.equals(uiTreeNode.getType())) {
continue;
}
for (UIComponent grandkid : child.getChildren()) {
if (!grandkid.isRendered()) {
continue;
}
if (phaseId == PhaseId.APPLY_REQUEST_VALUES) {
grandkid.processDecodes(context);
}
else if (phaseId == PhaseId.PROCESS_VALIDATIONS) {
grandkid.processValidators(context);
}
else if (phaseId == PhaseId.UPDATE_MODEL_VALUES) {
grandkid.processUpdates(context);
}
else {
throw new IllegalArgumentException();
}
}
}
}
}
public TreeNode createCopyOfTreeNode(TreeNode node) {
TreeNode newNode;
if (node instanceof CheckboxTreeNode) {
newNode = new CheckboxTreeNode(node.getData());
}
else {
newNode = new DefaultTreeNode(node.getData());
}
newNode.setType(node.getType());
newNode.setSelectable(node.isSelectable());
newNode.setExpanded(node.isExpanded());
if (node.getChildCount() > 0) {
for (TreeNode childNode : node.getChildren()) {
newNode.getChildren().add(createCopyOfTreeNode(childNode));
}
}
return newNode;
}
public boolean isTreeNodeDropped() {
MethodExpression me = getOnDrop();
if (me != null) {
FacesContext context = getFacesContext();
Map params = context.getExternalContext().getRequestParameterMap();
String clientId = getClientId(context);
int dndIndex = Integer.parseInt(params.get(clientId + "_dndIndex"));
boolean isDroppedNodeCopy = Boolean.parseBoolean(params.get(clientId + "_isDroppedNodeCopy"));
TreeDragDropInfo info;
if (isMultipleDrag()) {
info = new TreeDragDropInfo(this, getDragNodes(), getDropNode(), dndIndex, isDroppedNodeCopy);
}
else {
info = new TreeDragDropInfo(this, getDragNode(), getDropNode(), dndIndex, isDroppedNodeCopy);
}
retValOnDrop = (Boolean) me.invoke(context.getELContext(), new Object[]{info});
PrimeFaces.current().ajax().addCallbackParam("access", retValOnDrop);
}
return retValOnDrop;
}
public String getScrollState() {
Map params = getFacesContext().getExternalContext().getRequestParameterMap();
String name = getClientId() + "_scrollState";
String value = params.get(name);
return value == null ? "0,0" : value;
}
public List getFilteredRowKeys() {
return filteredRowKeys;
}
public void setFilteredRowKeys(List filteredRowKeys) {
this.filteredRowKeys = filteredRowKeys;
}
@Override
public Object saveState(FacesContext context) {
// reset component for MyFaces view pooling
nodes = null;
dragNode = null;
dragNodes = null;
dropNode = null;
retValOnDrop = true;
filteredRowKeys = new ArrayList<>();
return super.saveState(context);
}
}