blob: ede46c6181f7400525e03dc17ec9843d1af53143 [file] [log] [blame]
package org.apache.myfaces.tobago.component;
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*/
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.myfaces.tobago.TobagoConstants;
import org.apache.myfaces.tobago.context.ResourceManagerUtil;
import org.apache.myfaces.tobago.model.TreeState;
import org.apache.myfaces.tobago.taglib.component.ToolBarTag;
import org.apache.myfaces.tobago.util.MessageFactory;
import org.apache.myfaces.tobago.util.StringUtil;
import javax.faces.application.FacesMessage;
import javax.faces.component.ActionSource;
import javax.faces.component.NamingContainer;
import javax.faces.component.UICommand;
import javax.faces.component.UIComponent;
import javax.faces.component.UIPanel;
import javax.faces.context.FacesContext;
import javax.faces.el.MethodBinding;
import javax.faces.el.ValueBinding;
import javax.faces.event.AbortProcessingException;
import javax.faces.event.ActionListener;
import javax.faces.event.FacesEvent;
import javax.faces.validator.Validator;
import javax.faces.validator.ValidatorException;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreeNode;
import java.io.IOException;
import java.io.Serializable;
import java.util.Iterator;
import java.util.Set;
@Deprecated
public class UITreeOld extends javax.faces.component.UIInput implements NamingContainer, ActionSource {
private static final Log LOG = LogFactory.getLog(UITreeOld.class);
public static final String COMPONENT_TYPE = "org.apache.myfaces.tobago.TreeOld";
public static final String MESSAGE_NOT_LEAF = "tobago.tree.MESSAGE_NOT_LEAF";
public static final String SEP = "-";
public static final String TREE_STATE = SEP + "treeState";
public static final String SELECT_STATE = SEP + "selectState";
public static final String MARKER = SEP + "marker";
public static final String FACET_TREE_NODE_COMMAND = "treeNodeCommand";
public static final String PARAMETER_TREE_NODE_ID = "treeNodeId";
public static final String COMMAND_PREFIX = "command";
public static final String COMMAND_NEW = "new";
public static final String COMMAND_DELETE = "delete";
public static final String COMMAND_EDIT = "edit";
public static final String COMMAND_CUT = "cut";
public static final String COMMAND_COPY = "copy";
public static final String COMMAND_PASTE = "paste";
public static final String COMMAND_MOVE_UP = "moveUp";
public static final String COMMAND_MOVE_DOWN = "moveDown";
private UITreeOld.Command[] treeCommands;
private MethodBinding actionListenerBinding;
private TreeState treeState;
private boolean showJunctions = true;
private boolean showJunctionsSet = false;
private boolean showIcons = true;
private boolean showIconsSet = false;
private boolean showRoot = true;
private boolean showRootSet = false;
private boolean showRootJunction = true;
private boolean showRootJunctionSet = false;
private String mode;
public UITreeOld() {
treeCommands = new UITreeOld.Command[]{
new UITreeOld.Command(COMMAND_NEW),
new UITreeOld.Command(COMMAND_DELETE),
new UITreeOld.Command(COMMAND_EDIT),
new UITreeOld.Command(COMMAND_CUT),
new UITreeOld.Command(COMMAND_COPY),
new UITreeOld.Command(COMMAND_PASTE),
new UITreeOld.Command(COMMAND_MOVE_UP),
new UITreeOld.Command(COMMAND_MOVE_DOWN),
};
}
// ---------------------------- interface ActionSource
public void broadcast(FacesEvent event) throws AbortProcessingException {
super.broadcast(event);
MethodBinding binding = getActionListener();
if (binding != null) {
FacesContext context = getFacesContext();
binding.invoke(context, new Object[] {event});
}
}
public MethodBinding getAction() {
return null;
}
public void setAction(MethodBinding methodBinding) {
}
public String getMode() {
if (mode != null) {
return mode;
}
ValueBinding vb = getValueBinding(TobagoConstants.ATTR_MODE);
if (vb != null) {
return (String) vb.getValue(getFacesContext());
} else {
return "tree";
}
}
public void setMode(String mode) {
this.mode = mode;
}
public MethodBinding getActionListener() {
return actionListenerBinding;
}
public void setActionListener(MethodBinding actionListener) {
this.actionListenerBinding = actionListener;
}
public void addActionListener(ActionListener actionListener) {
addFacesListener(actionListener);
}
public ActionListener[] getActionListeners() {
return (ActionListener[]) getFacesListeners(ActionListener.class);
}
public void removeActionListener(ActionListener actionListener) {
removeFacesListener(actionListener);
}
public void encodeBegin(FacesContext facesContext)
throws IOException {
recreateTreeNodes();
if (ComponentUtil.getBooleanAttribute(this, TobagoConstants.ATTR_MUTABLE)
&& getFacet("mutableToolbar") == null
&& getFacet("defaultToolbar") == null) {
createDefaultToolbar(facesContext);
}
super.encodeBegin(facesContext);
}
// TODO move this to renderkit
public void createDefaultToolbar(FacesContext facesContext) {
UIComponent toolbar = ComponentUtil.createComponent(
facesContext, UIPanel.COMPONENT_TYPE,
TobagoConstants.RENDERER_TYPE_TOOL_BAR);
toolbar.getAttributes().put(TobagoConstants.ATTR_ICON_SIZE, ToolBarTag.ICON_SMALL);
toolbar.getAttributes().put(TobagoConstants.ATTR_LABEL_POSITION, ToolBarTag.LABEL_OFF);
ActionListener[] handlers = getActionListeners();
if ((handlers == null || handlers.length == 0) && getActionListener() == null) {
LOG.error("No actionListener found in tree, so tree editing will not work!");
}
UITreeOld.Command[] commands = getCommands();
for (int i = 0; i < commands.length; i++) {
UICommand command = (UICommand) ComponentUtil.createComponent(
facesContext, UICommand.COMPONENT_TYPE,
TobagoConstants.RENDERER_TYPE_LINK);
toolbar.getChildren().add(command);
command.setId(commands[i].getCommand());
for (ActionListener listener : getActionListeners()) {
command.addActionListener(listener);
}
command.setActionListener(getActionListener());
command.getAttributes().put(
TobagoConstants.ATTR_IMAGE, "image/tobago.tree." + commands[i].getCommand() + ".gif");
String title = ResourceManagerUtil.getPropertyNotNull(facesContext, "tobago",
"tree" + StringUtil.firstToUpperCase(commands[i].getCommand()));
command.getAttributes().put(TobagoConstants.ATTR_TIP, title);
}
getFacets().put("defaultToolbar", toolbar);
}
private void recreateTreeNodes() {
UITreeOldNode root = getRoot();
// Delete all UIComponent childs, because moving of childen will not work
// in Mutable Tree.
// They may have invalid modelReferences.
try {
if (root != null) {
if (LOG.isDebugEnabled()) {
LOG.debug("removing root 1");
}
getChildren().remove(root);
if (LOG.isDebugEnabled()) {
LOG.debug("removing root 2");
}
}
} catch (Exception e) {
LOG.error("", e);
}
try {
root = new UITreeOldNode(this, 0);
root.createTreeNodes();
} catch (Exception e) {
LOG.error(e, e);
}
}
public UITreeOldNode getRoot() {
// find the UITreeOldNode in the childen.
for (Iterator i = getChildren().iterator(); i.hasNext();) {
UIComponent child = (UIComponent) i.next();
if (child instanceof UITreeOldNode) {
return (UITreeOldNode) child;
}
}
// in a new UITree isn't a root
return null;
}
public void encodeChildren(FacesContext context)
throws IOException {
// will be called from end.jsp
}
public UITreeOldNode findUITreeNode(UITreeOldNode node, TreeNode treeNode) {
UITreeOldNode found = null;
if (node.getTreeNode().equals(treeNode)) {
return node;
} else {
for (Iterator iter = node.getChildren().iterator(); iter.hasNext();) {
UITreeOldNode uiTreeNode = (UITreeOldNode) iter.next();
found = findUITreeNode(uiTreeNode, treeNode);
if (found != null) {
break;
}
}
}
return found;
}
public boolean getRendersChildren() {
return true;
}
public boolean isSelectableTree() {
final Object selectable
= ComponentUtil.getAttribute(this , TobagoConstants.ATTR_SELECTABLE);
return selectable != null
&& (selectable.equals("multi") || selectable.equals("multiLeafOnly")
|| selectable.equals("single") || selectable.equals("singleLeafOnly")
|| selectable.equals("sibling") || selectable.equals("siblingLeafOnly"));
}
public void processDecodes(FacesContext facesContext) {
if (ComponentUtil.isOutputOnly(this)) {
setValid(true);
} else {
// in tree first decode node and than decode children
decode(facesContext);
for (Iterator i = getFacetsAndChildren(); i.hasNext();) {
UIComponent uiComponent = ((UIComponent) i.next());
uiComponent.processDecodes(facesContext);
}
}
}
public void validate(FacesContext context) {
if (isRequired() && getState().getSelection().size() == 0) {
setValid(false);
FacesMessage facesMessage = MessageFactory.createFacesMessage(context,
UISelectOne.MESSAGE_VALUE_REQUIRED, FacesMessage.SEVERITY_ERROR);
context.addMessage(getClientId(context), facesMessage);
}
String selectable = ComponentUtil.getStringAttribute(this,
TobagoConstants.ATTR_SELECTABLE);
if (selectable != null && selectable.endsWith("LeafOnly")) {
Set<DefaultMutableTreeNode> selection = getState().getSelection();
for (DefaultMutableTreeNode node : selection) {
if (!node.isLeaf()) {
setValid(false);
FacesMessage facesMessage = MessageFactory.createFacesMessage(
context, MESSAGE_NOT_LEAF, FacesMessage.SEVERITY_ERROR);
context.addMessage(getClientId(context), facesMessage);
break; // don't continue iteration, no dublicate messages needed
}
}
}
// call all validators
if (getValidators() != null) {
for (Validator validator : getValidators()) {
try {
validator.validate(context, this, null);
} catch (ValidatorException ve) {
// If the validator throws an exception, we're
// invalid, and we need to add a message
setValid(false);
FacesMessage message = ve.getFacesMessage();
if (message != null) {
message.setSeverity(FacesMessage.SEVERITY_ERROR);
context.addMessage(getClientId(context), message);
}
}
}
}
}
public void updateModel(FacesContext facesContext) {
// nothig to update for tree's
// TODO: updateing the model here and *NOT* in the decode phase
}
public Object saveState(FacesContext context) {
Object[] state = new Object[7];
state[0] = super.saveState(context);
state[1] = saveAttachedState(context, actionListenerBinding);
state[2] = showJunctionsSet ? showJunctions : null;
state[3] = showIconsSet ? showIcons : null;
state[4] = showRootSet ? showRoot : null;
state[5] = showRootJunctionSet ? showRootJunction : null;
state[6] = mode;
return state;
}
public void restoreState(FacesContext context, Object state) {
Object[] values = (Object[]) state;
super.restoreState(context, values[0]);
actionListenerBinding = (MethodBinding) restoreAttachedState(context, values[1]);
if (values[2] != null) {
showJunctions = (Boolean) values[2];
showJunctionsSet = true;
}
if (values[3] != null) {
showIcons = (Boolean) values[3];
showIconsSet = true;
}
if (values[4] != null) {
showRoot = (Boolean) values[4];
showRootSet = true;
}
if (values[5] != null) {
showRootJunction = (Boolean) values[5];
showRootJunctionSet = true;
}
mode = (String) values[6];
}
public UITreeOld.Command[] getCommands() {
return treeCommands;
}
public TreeState getState() {
if (treeState != null) {
return treeState;
}
ValueBinding valueBinding = getValueBinding(TobagoConstants.ATTR_STATE);
if (valueBinding != null) {
return (TreeState) valueBinding.getValue(getFacesContext());
} else {
return null;
}
}
public void setState(TreeState state) {
this.treeState = state;
}
public boolean isShowJunctions() {
if (showJunctionsSet) {
return (showJunctions);
}
ValueBinding vb = getValueBinding(TobagoConstants.ATTR_SHOW_JUNCTIONS);
if (vb != null) {
return (!Boolean.FALSE.equals(vb.getValue(getFacesContext())));
} else {
return (this.showJunctions);
}
}
public void setShowJunctions(boolean showJunctions) {
this.showJunctions = showJunctions;
this.showJunctionsSet = true;
}
public boolean isShowIcons() {
if (showIconsSet) {
return (showIcons);
}
ValueBinding vb = getValueBinding(TobagoConstants.ATTR_SHOW_ICONS);
if (vb != null) {
return (!Boolean.FALSE.equals(vb.getValue(getFacesContext())));
} else {
return (this.showIcons);
}
}
public void setShowIcons(boolean showIcons) {
this.showIcons = showIcons;
this.showIconsSet = true;
}
public boolean isShowRoot() {
if (showRootSet) {
return (showRoot);
}
ValueBinding vb = getValueBinding(TobagoConstants.ATTR_SHOW_ROOT);
if (vb != null) {
return (!Boolean.FALSE.equals(vb.getValue(getFacesContext())));
} else {
return (this.showRoot);
}
}
public void setShowRoot(boolean showRoot) {
this.showRoot = showRoot;
this.showRootSet = true;
}
public boolean isShowRootJunction() {
if (showRootJunctionSet) {
return (showRootJunction);
}
ValueBinding vb = getValueBinding(TobagoConstants.ATTR_SHOW_ROOT_JUNCTION);
if (vb != null) {
return (!Boolean.FALSE.equals(vb.getValue(getFacesContext())));
} else {
return (this.showRootJunction);
}
}
public void setShowRootJunction(boolean showRootJunction) {
this.showRootJunction = showRootJunction;
this.showRootJunctionSet = true;
}
public static class Command implements Serializable {
private String command;
public Command(String command) {
this.command = command;
}
public String getCommand() {
return command;
}
}
}