001    package org.apache.myfaces.tobago.model;
002    
003    /*
004     * Licensed to the Apache Software Foundation (ASF) under one or more
005     * contributor license agreements.  See the NOTICE file distributed with
006     * this work for additional information regarding copyright ownership.
007     * The ASF licenses this file to You under the Apache License, Version 2.0
008     * (the "License"); you may not use this file except in compliance with
009     * the License.  You may obtain a copy of the License at
010     *
011     *      http://www.apache.org/licenses/LICENSE-2.0
012     *
013     * Unless required by applicable law or agreed to in writing, software
014     * distributed under the License is distributed on an "AS IS" BASIS,
015     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
016     * See the License for the specific language governing permissions and
017     * limitations under the License.
018     */
019    
020    import javax.swing.tree.DefaultMutableTreeNode;
021    
022    import org.apache.commons.lang.StringUtils;
023    
024    import java.util.Enumeration;
025    import java.util.HashSet;
026    import java.util.Set;
027    
028    /**
029     * Manages the state on a Tree:<br />
030     * 1. selection: selected tree-nodes<br />
031     * 2. expandState: open/close folder state<br />
032     * 3. marker: last used action object<br />
033     */
034    public class TreeState {
035    
036      public static final String SEP = ";";
037    
038      private Set<DefaultMutableTreeNode> selection;
039      private Set<DefaultMutableTreeNode> expandState;
040      private DefaultMutableTreeNode marker;
041      private DefaultMutableTreeNode lastMarker;
042      private String lastCommand;
043      private Integer[] scrollPosition;
044    
045      public TreeState() {
046        selection = new HashSet<DefaultMutableTreeNode>();
047        expandState = new HashSet<DefaultMutableTreeNode>();
048      }
049    
050      public void addExpandState(DefaultMutableTreeNode expandStateItem) {
051        expandState.add(expandStateItem);
052      }
053    
054      public void addSelection(DefaultMutableTreeNode selectItem) {
055        selection.add(selectItem);
056      }
057    
058      public void clearExpandState() {
059        expandState.clear();
060      }
061    
062      public void clearSelection() {
063        selection.clear();
064      }
065    
066      /**
067       * Adds a (external created) node to the actually marked node.
068       */
069      public void commandNew(DefaultMutableTreeNode newNode) {
070        marker.insert(newNode, 0);
071        setLastMarker(null);
072        setLastCommand(null);
073      }
074    
075      public void expand(DefaultMutableTreeNode node, int level) {
076        if (level > 0) {
077          if (!expandState.contains(node)) {
078            expandState.add(node);
079          }
080          for (Enumeration i = node.children(); i.hasMoreElements();) {
081            DefaultMutableTreeNode child = (DefaultMutableTreeNode) i.nextElement();
082            expand(child, level - 1);
083          }
084        }
085      }
086    
087      /**
088       * Expands all parents which contains selected children.
089       */
090      public void expandSelection() {
091        for (DefaultMutableTreeNode treeNode : selection) {
092          expandTo(treeNode);
093        }
094      }
095    
096      public void expandTo(DefaultMutableTreeNode node) {
097        node = (DefaultMutableTreeNode) node.getParent();
098        while (node != null) {
099          if (!expandState.contains(node)) {
100            expandState.add(node);
101          }
102          node = (DefaultMutableTreeNode) node.getParent();
103        }
104      }
105    
106      public boolean isExpanded(DefaultMutableTreeNode node) {
107        return expandState.contains(node);
108      }
109    
110      public boolean isMarked(DefaultMutableTreeNode node) {
111        return node != null && node.equals(marker);
112      }
113    
114      public boolean isSelected(DefaultMutableTreeNode node) {
115        return selection.contains(node);
116      }
117    
118      public Set<DefaultMutableTreeNode> getExpandState() {
119        return expandState;
120      }
121    
122      public void setExpandState(Set<DefaultMutableTreeNode> expandState) {
123        this.expandState = expandState;
124      }
125    
126      public String getLastCommand() {
127        return lastCommand;
128      }
129    
130      public void setLastCommand(String lastCommand) {
131        this.lastCommand = lastCommand;
132      }
133    
134      public DefaultMutableTreeNode getLastMarker() {
135        return lastMarker;
136      }
137    
138      public void setLastMarker(DefaultMutableTreeNode lastMarker) {
139        this.lastMarker = lastMarker;
140      }
141    
142      public DefaultMutableTreeNode getMarker() {
143        return marker;
144      }
145    
146      public void setMarker(DefaultMutableTreeNode marker) {
147        this.marker = marker;
148      }
149    
150      public Set<DefaultMutableTreeNode> getSelection() {
151        return selection;
152      }
153    
154      public void setSelection(Set<DefaultMutableTreeNode> selection) {
155        this.selection = selection;
156      }
157    
158      public Integer[] getScrollPosition() {
159        return scrollPosition;
160      }
161    
162      public void setScrollPosition(Integer[] scrollPosition) {
163        this.scrollPosition = scrollPosition;
164      }
165    
166      public static Integer[] parseScrollPosition(String value) {
167        Integer[] position = null;
168        if (!StringUtils.isBlank(value)) {
169          int sep = value.indexOf(";");
170          if (sep == -1) {
171            throw new NumberFormatException(value);
172          }
173          int left = Integer.parseInt(value.substring(0, sep));
174          int top = Integer.parseInt(value.substring(sep + 1));
175          position = new Integer[2];
176          position[0] = left;
177          position[1] = top;
178        }
179        return position;
180      }
181    
182    }
183