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