Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * JBoss, Home of Professional Open Source
   * Copyright 2010, Red Hat, Inc. and individual contributors
   * by the @authors tag. See the copyright.txt in the distribution for a
   * full listing of individual contributors.
   *
   * This is free software; you can redistribute it and/or modify it
   * under the terms of the GNU Lesser General Public License as
   * published by the Free Software Foundation; either version 2.1 of
  * the License, or (at your option) any later version.
  *
  * This software is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this software; if not, write to the Free
  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
  */
 package org.richfaces.component;
 
 import java.util.Map;
 
 import  javax.faces.application.FacesMessage;
 import  javax.faces.component.UIComponent;
 import  javax.faces.component.UpdateModelException;
 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.convert.Converter;
 import  javax.faces.convert.ConverterException;
 import  javax.faces.event.AbortProcessingException;
 import  javax.faces.event.ExceptionQueuedEvent;
 import  javax.faces.event.ExceptionQueuedEventContext;
 import  javax.faces.event.FacesEvent;
 import  javax.faces.event.PhaseId;
 
 import  org.ajax4jsf.model.DataComponentState;
 import  org.ajax4jsf.model.DataVisitor;
 import  org.ajax4jsf.model.ExtendedDataModel;
 import  org.richfaces.application.FacesMessages;
 import  org.richfaces.application.MessageFactory;
 import  org.richfaces.application.ServiceTracker;
 import  org.richfaces.context.ExtendedVisitContext;
 import  org.richfaces.context.ExtendedVisitContextMode;
 import  org.richfaces.event.TreeSelectionChangeEvent;
 import  org.richfaces.event.TreeSelectionChangeListener;
 import  org.richfaces.event.TreeSelectionChangeSource;
 import  org.richfaces.event.TreeToggleEvent;
 import  org.richfaces.event.TreeToggleListener;
 import  org.richfaces.event.TreeToggleSource;
 import  org.richfaces.model.DeclarativeTreeModel;
 import  org.richfaces.model.TreeDataModel;
 import  org.richfaces.model.TreeDataModelTuple;
 import  org.richfaces.model.TreeDataVisitor;
 import  org.richfaces.model.TreeNode;
 import  org.richfaces.renderkit.MetaComponentRenderer;
 
 import  com.google.common.base.Predicate;
 import  com.google.common.base.Strings;
 import  com.google.common.collect.Iterables;
 import  com.google.common.collect.Iterators;
 import  com.google.common.collect.Maps;

The <rich:tree> component provides a hierarchical tree control. Each <rich:tree> component typically consists of <rich:treeNode> child components. The appearance and behavior of the tree and its nodes can be fully customized.

Author(s):
Nick Belaevski
 
 @JsfComponent(type = ., family = ., tag = @Tag(name = "tree", handler = "org.richfaces.view.facelets.TreeHandler"), renderer = @JsfRenderer(type = "org.richfaces.TreeRenderer"), attributes = {
         "ajax-props.xml""events-mouse-props.xml""events-key-props.xml""core-props.xml""i18n-props.xml",
         "tree-common-props.xml""tree-props.xml""sequence-props.xml""immediate-prop.xml" })
 // TODO add rowData caching for wrapper events
 public abstract class AbstractTree extends UIDataAdaptor implements MetaComponentResolver, MetaComponentEncoder,
         TreeSelectionChangeSource, TreeToggleSource {
     public static final String COMPONENT_TYPE = "org.richfaces.Tree";
    public static final String COMPONENT_FAMILY = "org.richfaces.Tree";
    public static final String SELECTION_META_COMPONENT_ID = "selection";
    public static final String DEFAULT_TREE_NODE_ID = "__defaultTreeNode";
    public static final String DEFAULT_TREE_NODE_FACET_NAME = ;
    private static final String COMPONENT_FOR_MODEL_UNAVAILABLE = "Component is not available for model {0}";
    private static final String CONVERTER_FOR_MODEL_UNAVAILABLE = "Row key converter is not available for model {0}";
    private static final class MatchingTreeNodePredicate implements Predicate<UIComponent> {
        private String type;
        public MatchingTreeNodePredicate(String type) {
            super();
            this. = type;
        }
        public boolean apply(UIComponent input) {
            if (!(input instanceof AbstractTreeNode)) {
                return false;
            }
            String nodeType = ((AbstractTreeNodeinput).getType();
            if ( == null && nodeType == null) {
                return true;
            }
            return  != null && .equals(nodeType);
        }
    }
    ;
    private enum PropertyKeys {
        selection
    }
    private transient TreeRange treeRange;
    private transient UIComponent currentComponent = this;
    private transient Map<String, UIComponent> declatariveModelsMap = null;
    public AbstractTree() {
        setKeepSaved(true);
        setRendererType("org.richfaces.TreeRenderer");
    }
    protected TreeRange getTreeRange() {
        if ( == null) {
             = new TreeRange(this);
        }
        return ;
    }
    @Attribute
    public abstract Object getValue();
    @Attribute
    public abstract boolean isImmediate();
    @Attribute
    public abstract String getNodeClass();
    @Attribute(events = @EventName("nodetoggle"))
    public abstract String getOnnodetoggle();
    @Attribute(events = @EventName("beforenodetoggle"))
    public abstract String getOnbeforenodetoggle();
    @Attribute(events = @EventName("selectionchange"))
    public abstract String getOnselectionchange();
    @Attribute(events = @EventName("beforeselectionchange"))
    public abstract String getOnbeforeselectionchange();
    @Attribute
    public abstract SwitchType getToggleType();
    @Attribute
    public abstract SwitchType getSelectionType();
    @Attribute
    public abstract String getNodeType();
    @Attribute
    public abstract String getToggleNodeEvent();
    @Override
    public String getFamily() {
        return ;
    }
    @Attribute
    public Collection<ObjectgetSelection() {
        @SuppressWarnings("unchecked")
        Collection<Objectselection = (Collection<Object>) getStateHelper().eval(.);
        if (selection == null) {
            selection = new HashSet<Object>();
            if (ve != null) {
                ve.setValue(getFacesContext().getELContext(), selection);
            } else {
                getStateHelper().put(.selection);
            }
        }
        return selection;
    }
    public void setSelection(Collection<Objectselection) {
        getStateHelper().put(.selection);
    }
    @Override
    protected DataComponentState createComponentState() {
        // TODO Auto-generated method stub
        return null;
    }
    @Override
    public Converter getRowKeyConverter() {
        Converter converter = super.getRowKeyConverter();
        if (converter == null) {
            converter = getTreeDataModel().getRowKeyConverter();
        }
        return converter;
    }
    protected Iterator<UIComponent> findMatchingTreeNodeComponent(String nodeType, UIComponent parentComponent) {
        Iterator<UIComponent> children = parentComponent.getChildren().iterator();
        if (parentComponent != this) {
            children = Iterators.concat(childrenthis.getChildren().iterator());
        }
        return Iterators.filter(childrennew MatchingTreeNodePredicate(nodeType));
    }
    protected void setupCurrentComponent() {
        ExtendedDataModel<?> dataModel = getExtendedDataModel();
        if (dataModel instanceof DeclarativeTreeModel) {
             = ((DeclarativeTreeModel) dataModel).getCurrentComponent();
        } else {
             = this;
        }
    }
        String nodeType = getNodeType();
        Iterator<UIComponent> nodesItr = findMatchingTreeNodeComponent(nodeType);
        if (nodesItr.hasNext()) {
            while (nodesItr.hasNext()) {
                AbstractTreeNode node = (AbstractTreeNodenodesItr.next();
                if (node.isRendered()) {
                    return node;
                }
            }
        } else if (Strings.isNullOrEmpty(nodeType)) {
            return (AbstractTreeNodegetFacet();
        }
        return null;
    }
    @Override
    public void broadcast(FacesEvent eventthrows AbortProcessingException {
        super.broadcast(event);
        if (event instanceof TreeSelectionChangeEvent) {
            TreeSelectionChangeEvent selectionEvent = (TreeSelectionChangeEvent) event;
            final Collection<ObjectnewSelection = selectionEvent.getNewSelection();
            Collection<ObjectselectionCollection = getSelection();
            Iterables.removeIf(selectionCollectionnew Predicate<Object>() {
                public boolean apply(Object input) {
                    return !newSelection.contains(input);
                }
                ;
            });
            if (!newSelection.isEmpty()) {
                Iterables.addAll(selectionCollectionnewSelection);
            }
        } else if (event instanceof TreeToggleEvent) {
            TreeToggleEvent toggleEvent = (TreeToggleEvent) event;
            AbstractTreeNode treeNodeComponent = findTreeNodeComponent();
            boolean newExpandedValue = toggleEvent.isExpanded();
            FacesContext context = getFacesContext();
            ValueExpression expression = treeNodeComponent
                    .getValueExpression(...toString());
            if (expression != null) {
                ELContext elContext = context.getELContext();
                Exception caught = null;
                FacesMessage message = null;
                try {
                    expression.setValue(elContextnewExpandedValue);
                } catch (ELException e) {
                    caught = e;
                    String messageStr = e.getMessage();
                    Throwable result = e.getCause();
                    while (null != result && result.getClass().isAssignableFrom(ELException.class)) {
                        messageStr = result.getMessage();
                        result = result.getCause();
                    }
                    if (null == messageStr) {
                        MessageFactory messageFactory = ServiceTracker.getService(MessageFactory.class);
                        message = messageFactory.createMessage(context, FacesMessages.UIINPUT_UPDATE,
                                MessageUtil.getLabel(contextthis));
                    } else {
                        message = new FacesMessage(FacesMessage.SEVERITY_ERROR, messageStrmessageStr);
                    }
                } catch (Exception e) {
                    caught = e;
                    MessageFactory messageFactory = ServiceTracker.getService(MessageFactory.class);
                    message = messageFactory.createMessage(context, FacesMessages.UIINPUT_UPDATE,
                            MessageUtil.getLabel(contextthis));
                }
                if (caught != null) {
                    assert (message != null);
                    UpdateModelException toQueue = new UpdateModelException(messagecaught);
                    ExceptionQueuedEventContext eventContext = new ExceptionQueuedEventContext(contexttoQueuethis,
                            PhaseId.UPDATE_MODEL_VALUES);
                    context.getApplication().publishEvent(context, ExceptionQueuedEvent.classeventContext);
                }
            } else {
                treeNodeComponent.setExpanded(newExpandedValue);
            }
        }
    }
    @Override
    protected boolean visitFixedChildren(VisitContext visitContext, VisitCallback callback) {
        if (visitContext instanceof ExtendedVisitContext) {
            ExtendedVisitContext extendedVisitContext = (ExtendedVisitContext) visitContext;
            if (ExtendedVisitContextMode.RENDER == extendedVisitContext.getVisitMode()) {
                VisitResult result = extendedVisitContext.invokeMetaComponentVisitCallback(thiscallback,
                        );
                if (result != VisitResult.ACCEPT) {
                    return result == VisitResult.COMPLETE;
                }
            }
        }
        return super.visitFixedChildren(visitContextcallback);
    }
    void decodeMetaComponent(FacesContext contextString metaComponentId) {
        ((MetaComponentRenderer) getRenderer(context)).decodeMetaComponent(contextthismetaComponentId);
    }
    public void encodeMetaComponent(FacesContext contextString metaComponentIdthrows IOException {
        ((MetaComponentRenderer) getRenderer(context)).encodeMetaComponent(contextthismetaComponentId);
    }
    public String resolveClientId(FacesContext facesContext, UIComponent contextComponentString metaComponentId) {
        if (.equals(metaComponentId)) {
            return getClientId(facesContext) + MetaComponentResolver.META_COMPONENT_SEPARATOR_CHAR + metaComponentId;
        }
        return null;
    }
    public String substituteUnresolvedClientId(FacesContext facesContext, UIComponent contextComponentString metaComponentId) {
        return null;
    }
    @Override
    protected Iterator<UIComponent> dataChildren() {
        AbstractTreeNode treeNodeComponent = findTreeNodeComponent();
        if (treeNodeComponent != null) {
            return Iterators.<UIComponent> singletonIterator(treeNodeComponent);
        } else {
            return Iterators.<UIComponent> emptyIterator();
        }
    }
    public void addTreeSelectionChangeListener(TreeSelectionChangeListener listener) {
        addFacesListener(listener);
    }
    @Attribute(hidden = true)
    public TreeSelectionChangeListener[] getTreeSelectionChangeListeners() {
        return (TreeSelectionChangeListener[]) getFacesListeners(TreeSelectionChangeListener.class);
    }
    public void removeTreeSelectionChangeListener(TreeSelectionChangeListener listener) {
        removeFacesListener(listener);
    }
    public void addTreeToggleListener(TreeToggleListener listener) {
        addFacesListener(listener);
    }
    @Attribute(hidden = true)
    public TreeToggleListener[] getTreeToggleListeners() {
        return (TreeToggleListener[]) getFacesListeners(TreeToggleListener.class);
    }
    public void removeTreeToggleListener(TreeToggleListener listener) {
        removeFacesListener(listener);
    }
    @Attribute(hidden = true)
    public boolean isExpanded() {
        if (getRowKey() == null) {
            return true;
        }
        AbstractTreeNode treeNode = findTreeNodeComponent();
        if (treeNode == null) {
            return false;
        }
        return treeNode.isExpanded();
    }
    // TODO review
    protected TreeDataModel<?> getTreeDataModel() {
        return (TreeDataModel<?>) getExtendedDataModel();
    }
    @Attribute(hidden = true)
    public boolean isLeaf() {
        return getTreeDataModel().isLeaf();
    }
    @Override
    public void walk(final FacesContext facesfinal DataVisitor visitorfinal Object argument) {
        walkModel(facesnew TreeDataVisitor() {
            public void enterNode() {
                visitor.process(facesgetRowKey(), argument);
            }
            public void exitNode() {
            }
            public void beforeChildrenVisit() {
            }
            public void afterChildrenVisit() {
            }
        });
    }
    @Override
    protected ExtendedDataModel<?> createExtendedDataModel() {
        ExtendedDataModel<?> dataModel;
        Object value = getValue();
        if (value == null) {
            dataModel = new DeclarativeTreeDataModelImpl(this);
        } else if (value instanceof TreeNode) {
            dataModel = new ClassicTreeNodeDataModelImpl();
            dataModel.setWrappedData(value);
        } else if (value instanceof TreeDataModel<?>) {
            if (value instanceof ExtendedDataModel<?>) {
                dataModel = (ExtendedDataModel<?>) value;
            } else {
                throw new IllegalArgumentException(MessageFormat.format(
                        "TreeDataModel implementation {0} is not a subclass of ExtendedDataModel"value.getClass().getName()));
            }
        } else {
            dataModel = new SwingTreeNodeDataModelImpl();
            dataModel.setWrappedData(value);
        }
        return dataModel;
    }
    public void walkModel(FacesContext context, TreeDataVisitor dataVisitor) {
        TreeDataModel<?> model = getTreeDataModel();
        if (!getTreeRange().shouldProcessNode()) {
            return;
        }
        boolean isRootNode = (getRowKey() == null);
        if (!isRootNode) {
            dataVisitor.enterNode();
        }
        walkModelChildren(contextdataVisitormodel);
        if (!isRootNode) {
            dataVisitor.exitNode();
        }
    }
    private void walkModelChildren(FacesContext context, TreeDataVisitor dataVisitor, TreeDataModel<?> model) {
        if (!getTreeRange().shouldIterateChildren()) {
            return;
        }
        dataVisitor.beforeChildrenVisit();
        Iterator<TreeDataModelTuple> childrenTuples = model.children();
        while (childrenTuples.hasNext()) {
            TreeDataModelTuple tuple = childrenTuples.next();
            restoreFromSnapshot(contexttuple);
            if (!getTreeRange().shouldProcessNode()) {
                continue;
            }
            dataVisitor.enterNode();
            walkModelChildren(contextdataVisitormodel);
            dataVisitor.exitNode();
        }
        dataVisitor.afterChildrenVisit();
    }
    @Override
    protected void resetDataModel() {
        super.resetDataModel();
         = null;
         = null;
    }
    public TreeDataModelTuple createSnapshot() {
        return getTreeDataModel().createSnapshot();
    }
    public void restoreFromSnapshot(FacesContext context, TreeDataModelTuple tuple) {
        getTreeDataModel().restoreFromSnapshot(tuple);
        setRowKey(contexttuple.getRowKey());
    }
    @Override
    protected void restoreChildState(FacesContext facesContext) {
        setupCurrentComponent();
        super.restoreChildState(facesContext);
    }
    protected UIComponent findDeclarativeModel(String modelId) {
        if ( == null) {
             = Maps.newHashMap();
        }
        UIComponent adaptor = .get(modelId);
        if (adaptor == null) {
            adaptor = findComponent(modelId);
            if (adaptor != null) {
                .put(modelIdadaptor);
            }
        }
        if (adaptor == null) {
            throw new IllegalStateException(MessageFormat.format(modelId));
        }
        return adaptor;
    }
    public String convertDeclarativeKeyToString(FacesContext contextDeclarativeModelKey declarativeKey)
            throws ConverterException {
        try {
            UIComponent component = findDeclarativeModel(declarativeKey.getModelId());
            TreeModelAdaptor adaptor = (TreeModelAdaptorcomponent;
            Converter rowKeyConverter = adaptor.getRowKeyConverter();
            if (rowKeyConverter == null) {
                throw new ConverterException(MessageFormat.format(declarativeKey.getModelId()));
            }
            return rowKeyConverter.getAsString(context, (UIComponent) adaptordeclarativeKey.getModelKey());
        } catch (ConverterException e) {
            throw e;
        } catch (Exception e) {
            throw new ConverterException(e.getMessage(), e);
        }
    }
    public DeclarativeModelKey convertDeclarativeKeyFromString(FacesContext contextString modelIdString modelKeyAsString)
            throws ConverterException {
        try {
            UIComponent component = findDeclarativeModel(modelId);
            TreeModelAdaptor adaptor = (TreeModelAdaptorcomponent;
            Converter rowKeyConverter = adaptor.getRowKeyConverter();
            if (rowKeyConverter == null) {
                throw new ConverterException(MessageFormat.format(modelId));
            }
            Object modelKey = rowKeyConverter.getAsObject(context, (UIComponent) adaptormodelKeyAsString);
            return new DeclarativeModelKey(modelIdmodelKey);
        } catch (ConverterException e) {
            throw e;
        } catch (Exception e) {
            throw new ConverterException(e.getMessage(), e);
        }
    }
New to GrepCode? Check out our FAQ X