View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  
20  package org.apache.myfaces.tobago.example.demo;
21  
22  import org.slf4j.Logger;
23  import org.slf4j.LoggerFactory;
24  
25  import javax.enterprise.context.SessionScoped;
26  import javax.faces.application.FacesMessage;
27  import javax.faces.context.FacesContext;
28  import javax.inject.Named;
29  import javax.swing.tree.DefaultMutableTreeNode;
30  import java.io.Serializable;
31  import java.lang.invoke.MethodHandles;
32  import java.util.Enumeration;
33  
34  @SessionScoped
35  @Named
36  public class TreeEditorController implements Serializable {
37  
38    private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
39  
40    private DefaultMutableTreeNode categoryTree;
41    private String name;
42    private DefaultMutableTreeNode copyNode;
43    private DefaultMutableTreeNode cutNode;
44  
45  
46    public TreeEditorController() {
47      this.categoryTree = CategoryTree.createSample();
48    }
49  
50    public DefaultMutableTreeNode getCategoryTree() {
51      return categoryTree;
52    }
53  
54    public String getName() {
55      return name;
56    }
57  
58    public void setName(final String name) {
59      this.name = name;
60    }
61  
62    public String create() {
63      final DefaultMutableTreeNode node = findFirstSelected();
64      if (node != null) {
65        node.insert(CategoryTree.createNode(name, "id" + System.identityHashCode(name)), 0);
66        LOG.debug("Creating one node in {}", node.getUserObject());
67      } else {
68        LOG.warn("No node selected.");
69      }
70      return null;
71    }
72  
73    public String delete() {
74      final DefaultMutableTreeNode node = findFirstSelected();
75      if (node != null) {
76        if (node.getParent() != null) {
77          node.removeFromParent();
78        } else {
79          FacesContext.getCurrentInstance().addMessage(null,
80                  new FacesMessage(FacesMessage.SEVERITY_INFO, "Root node cannot be removed", null));
81        }
82      } else {
83        LOG.warn("No node selected.");
84      }
85      return null;
86    }
87  
88    public String rename() {
89      final DefaultMutableTreeNode node = findFirstSelected();
90      if (node != null && node.getUserObject() instanceof Node) {
91        final Node userObject = (Node) node.getUserObject();
92        LOG.debug("Renaming node from {} to {}", userObject.getName(), name);
93        userObject.setName(name);
94      } else {
95        LOG.warn("No node selected.");
96      }
97      return null;
98    }
99  
100   public String cut() {
101     copyNode = null;
102     cutNode = findFirstSelected();
103     return null;
104   }
105 
106   public String copy() {
107     cutNode = null;
108     copyNode = cloneNode(findFirstSelected());
109     return null;
110   }
111 
112   private DefaultMutableTreeNode cloneNode(final DefaultMutableTreeNode node) {
113     final String nodeName = ((Node) node.getUserObject()).getName();
114     final DefaultMutableTreeNode resultNode = new DefaultMutableTreeNode(new Node(nodeName));
115 
116     final Enumeration children = node.children();
117     while (children.hasMoreElements()) {
118       final DefaultMutableTreeNode child = (DefaultMutableTreeNode) children.nextElement();
119       resultNode.insert(cloneNode(child), resultNode.getChildCount());
120     }
121 
122     return resultNode;
123   }
124 
125   public String paste() {
126     final DefaultMutableTreeNode node = findFirstSelected();
127     if (node != null) {
128       if (cutNode != null) {
129         if (isBaseNodeContainSelectedNode(cutNode, node)) {
130           FacesContext.getCurrentInstance().addMessage(null,
131                   new FacesMessage(FacesMessage.SEVERITY_INFO, "Cannot past a cut node into itself.", null));
132         } else {
133           node.insert(cutNode, 0);
134           cutNode = null;
135         }
136       } else if (copyNode != null) {
137         node.insert(copyNode, 0);
138         copyNode = null;
139         deselectAllNodes(categoryTree);
140       }
141     }
142     return null;
143   }
144 
145   private boolean isBaseNodeContainSelectedNode(
146       final DefaultMutableTreeNode base, final DefaultMutableTreeNode selected) {
147     if (base.equals(selected)) {
148       return true;
149     }
150     final Enumeration children = base.children();
151     while (children.hasMoreElements()) {
152       final DefaultMutableTreeNode baseChild = (DefaultMutableTreeNode) children.nextElement();
153 
154       if (isBaseNodeContainSelectedNode(baseChild, selected)) {
155         return true;
156       }
157     }
158 
159     return false;
160   }
161 
162   private void deselectAllNodes(final DefaultMutableTreeNode node) {
163     ((Node) node.getUserObject()).setSelected(false);
164 
165     final Enumeration children = node.children();
166     while (children.hasMoreElements()) {
167       final DefaultMutableTreeNode child = (DefaultMutableTreeNode) children.nextElement();
168       deselectAllNodes(child);
169     }
170   }
171 
172   public String moveUp() {
173     final DefaultMutableTreeNode node = findFirstSelected();
174     if (node != null) {
175       final DefaultMutableTreeNode previousSibling = node.getPreviousSibling();
176       if (previousSibling != null) {
177         final DefaultMutableTreeNode parent = (DefaultMutableTreeNode) node.getParent();
178         parent.insert(node, parent.getIndex(previousSibling));
179       } else {
180         FacesContext.getCurrentInstance().addMessage(null,
181                 new FacesMessage(FacesMessage.SEVERITY_INFO, "The node cannot moved up further.", null));
182       }
183     }
184     return null;
185   }
186 
187   public String moveDown() {
188     final DefaultMutableTreeNode node = findFirstSelected();
189     if (node != null) {
190       final DefaultMutableTreeNode nextSibling = node.getNextSibling();
191       if (nextSibling != null) {
192         final DefaultMutableTreeNode parent = (DefaultMutableTreeNode) node.getParent();
193         parent.insert(node, parent.getIndex(nextSibling));
194       } else {
195         FacesContext.getCurrentInstance().addMessage(null,
196                 new FacesMessage(FacesMessage.SEVERITY_INFO, "The node cannot moved down further.", null));
197       }
198     }
199     return null;
200   }
201 
202   public String reset() {
203     categoryTree = CategoryTree.createSample();
204     cutNode = null;
205     copyNode = null;
206     return null;
207   }
208 
209   private DefaultMutableTreeNode findFirstSelected() {
210     final Enumeration enumeration = categoryTree.depthFirstEnumeration();
211     while (enumeration.hasMoreElements()) {
212       final DefaultMutableTreeNode node = (DefaultMutableTreeNode) enumeration.nextElement();
213       if (((Node) node.getUserObject()).isSelected()) {
214         return node;
215       }
216     }
217     return null;
218   }
219 }