KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectstyle > cayenne > modeler > ProjectTreeModel


1 /* ====================================================================
2  *
3  * The ObjectStyle Group Software License, version 1.1
4  * ObjectStyle Group - http://objectstyle.org/
5  *
6  * Copyright (c) 2002-2005, Andrei (Andrus) Adamchik and individual authors
7  * of the software. All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  *
13  * 1. Redistributions of source code must retain the above copyright
14  * notice, this list of conditions and the following disclaimer.
15  *
16  * 2. Redistributions in binary form must reproduce the above copyright
17  * notice, this list of conditions and the following disclaimer in
18  * the documentation and/or other materials provided with the
19  * distribution.
20  *
21  * 3. The end-user documentation included with the redistribution, if any,
22  * must include the following acknowlegement:
23  * "This product includes software developed by independent contributors
24  * and hosted on ObjectStyle Group web site (http://objectstyle.org/)."
25  * Alternately, this acknowlegement may appear in the software itself,
26  * if and wherever such third-party acknowlegements normally appear.
27  *
28  * 4. The names "ObjectStyle Group" and "Cayenne" must not be used to endorse
29  * or promote products derived from this software without prior written
30  * permission. For written permission, email
31  * "andrus at objectstyle dot org".
32  *
33  * 5. Products derived from this software may not be called "ObjectStyle"
34  * or "Cayenne", nor may "ObjectStyle" or "Cayenne" appear in their
35  * names without prior written permission.
36  *
37  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
38  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
39  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
40  * DISCLAIMED. IN NO EVENT SHALL THE OBJECTSTYLE GROUP OR
41  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
42  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
43  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
44  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
45  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
46  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
47  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
48  * SUCH DAMAGE.
49  * ====================================================================
50  *
51  * This software consists of voluntary contributions made by many
52  * individuals and hosted on ObjectStyle Group web site. For more
53  * information on the ObjectStyle Group, please see
54  * <http://objectstyle.org/>.
55  */

56 package org.objectstyle.cayenne.modeler;
57
58 import java.util.Comparator JavaDoc;
59 import java.util.Enumeration JavaDoc;
60 import java.util.HashMap JavaDoc;
61 import java.util.Map JavaDoc;
62
63 import javax.swing.tree.DefaultMutableTreeNode JavaDoc;
64 import javax.swing.tree.DefaultTreeModel JavaDoc;
65 import javax.swing.tree.MutableTreeNode JavaDoc;
66 import javax.swing.tree.TreeNode JavaDoc;
67
68 import org.objectstyle.cayenne.access.DataDomain;
69 import org.objectstyle.cayenne.access.DataNode;
70 import org.objectstyle.cayenne.map.DataMap;
71 import org.objectstyle.cayenne.project.Project;
72 import org.objectstyle.cayenne.project.ProjectPath;
73 import org.objectstyle.cayenne.project.ProjectTraversal;
74 import org.objectstyle.cayenne.project.ProjectTraversalHandler;
75
76 /**
77  * ProjectTreeModel is a model of Cayenne project tree.
78  *
79  * @author Andrei Adamchik
80  */

81 public class ProjectTreeModel extends DefaultTreeModel JavaDoc {
82
83     /**
84      * Creates a tree of Swing TreeNodes wrapping Cayenne project. Returns the root node
85      * of the tree.
86      */

87     public static DefaultMutableTreeNode JavaDoc wrapProject(Project project) {
88         return wrapProjectNode(project);
89     }
90
91     /**
92      * Creates a tree of Swing TreeNodes wrapping Cayenne project object. Returns the root
93      * node of the tree.
94      */

95     public static DefaultMutableTreeNode JavaDoc wrapProjectNode(Object JavaDoc node) {
96         TraversalHelper helper = new TraversalHelper();
97         new ProjectTraversal(helper).traverse(node);
98         return helper.getStartNode();
99     }
100
101     /**
102      * Creates a tree of Swing TreeNodes wrapping Cayenne project object. Returns the root
103      * node of the tree.
104      */

105     public static DefaultMutableTreeNode JavaDoc wrapProjectNode(
106             Object JavaDoc node,
107             DefaultMutableTreeNode JavaDoc parentPath) {
108
109         TraversalHelper helper = new TraversalHelper();
110
111         // build a project path from tree node
112
ProjectPath path = new ProjectPath();
113         if (parentPath != null) {
114             path = helper.registerNodes(parentPath.getPath());
115         }
116
117         new ProjectTraversal(helper).traverse(node, path);
118         return helper.getStartNode();
119     }
120
121     /**
122      * Constructor for ProjectTreeModel.
123      *
124      * @param root
125      */

126     public ProjectTreeModel(Project project) {
127         super(wrapProject(project));
128     }
129
130     /**
131      * Re-inserts a tree node to preserve the correct ordering of items. Assumes that the
132      * tree is already ordered, except for one node.
133      */

134     public void positionNode(
135             MutableTreeNode JavaDoc parent,
136             DefaultMutableTreeNode JavaDoc treeNode,
137             Comparator JavaDoc comparator) {
138
139         if (treeNode == null) {
140             return;
141         }
142
143         if (parent == null && treeNode != getRoot()) {
144             parent = (MutableTreeNode JavaDoc) treeNode.getParent();
145             if (parent == null) {
146                 parent = getRootNode();
147             }
148         }
149
150         Object JavaDoc object = treeNode.getUserObject();
151
152         int len = parent.getChildCount();
153         int ins = -1;
154         int rm = -1;
155
156         for (int i = 0; i < len; i++) {
157             DefaultMutableTreeNode JavaDoc node = (DefaultMutableTreeNode JavaDoc) parent.getChildAt(i);
158
159             // remember to remove node
160
if (node == treeNode) {
161                 rm = i;
162                 continue;
163             }
164
165             // no more insert checks
166
if (ins >= 0) {
167                 continue;
168             }
169
170             // ObjEntities go before DbEntities
171
if (comparator.compare(object, node.getUserObject()) <= 0) {
172                 ins = i;
173             }
174         }
175
176         if (ins < 0) {
177             ins = len;
178         }
179
180         if (rm == ins) {
181             return;
182         }
183
184         // remove
185
if (rm >= 0) {
186             removeNodeFromParent(treeNode);
187             if (rm < ins) {
188                 ins--;
189             }
190         }
191
192         // insert
193
insertNodeInto(treeNode, parent, ins);
194     }
195
196     /**
197      * Returns root node cast into DefaultMutableTreeNode.
198      */

199     public DefaultMutableTreeNode JavaDoc getRootNode() {
200         return (DefaultMutableTreeNode JavaDoc) super.getRoot();
201     }
202
203     public DefaultMutableTreeNode JavaDoc getNodeForObjectPath(Object JavaDoc[] path) {
204         if (path == null || path.length == 0) {
205             return null;
206         }
207
208         DefaultMutableTreeNode JavaDoc currentNode = getRootNode();
209
210         // adjust for root node being in the path
211
int start = 0;
212         if (currentNode.getUserObject() == path[0]) {
213             start = 1;
214         }
215
216         for (int i = start; i < path.length; i++) {
217             DefaultMutableTreeNode JavaDoc foundNode = null;
218             Enumeration JavaDoc children = currentNode.children();
219             while (children.hasMoreElements()) {
220                 DefaultMutableTreeNode JavaDoc child = (DefaultMutableTreeNode JavaDoc) children
221                         .nextElement();
222                 if (child.getUserObject() == path[i]) {
223                     foundNode = child;
224                     break;
225                 }
226             }
227
228             if (foundNode == null) {
229                 return null;
230             }
231             else {
232                 currentNode = foundNode;
233             }
234         }
235
236         return currentNode;
237     }
238
239     static class TraversalHelper implements ProjectTraversalHandler {
240
241         protected DefaultMutableTreeNode JavaDoc startNode;
242         protected Map JavaDoc nodesMap;
243
244         public TraversalHelper() {
245             this.nodesMap = new HashMap JavaDoc();
246         }
247
248         public DefaultMutableTreeNode JavaDoc getStartNode() {
249             return startNode;
250         }
251
252         /**
253          * Creates a starting point for tree traversal.
254          */

255         public ProjectPath registerNodes(TreeNode JavaDoc[] nodes) {
256             ProjectPath path = new ProjectPath();
257
258             for (int i = 0; i < nodes.length; i++) {
259                 DefaultMutableTreeNode JavaDoc treeNode = (DefaultMutableTreeNode JavaDoc) nodes[i];
260
261                 path = path.appendToPath(treeNode.getUserObject());
262
263                 // register node with helper
264
registerNode(treeNode);
265             }
266
267             return path;
268         }
269
270         public void registerNode(DefaultMutableTreeNode JavaDoc node) {
271             nodesMap.put(node.getUserObject(), node);
272         }
273
274         public void projectNode(ProjectPath nodePath) {
275
276             Object JavaDoc parent = nodePath.getObjectParent();
277             Object JavaDoc nodeObj = nodePath.getObject();
278             DefaultMutableTreeNode JavaDoc node = new DefaultMutableTreeNode JavaDoc(nodeObj);
279
280             if (startNode == null) {
281                 startNode = node;
282             }
283             else {
284                 DefaultMutableTreeNode JavaDoc nodeParent = (DefaultMutableTreeNode JavaDoc) nodesMap
285                         .get(parent);
286                 nodeParent.add(node);
287             }
288
289             registerNode(node);
290         }
291
292         public boolean shouldReadChildren(Object JavaDoc node, ProjectPath parentPath) {
293             // do not read deatils of linked maps
294
if ((node instanceof DataMap)
295                     && parentPath != null
296                     && (parentPath.getObject() instanceof DataNode)) {
297                 return false;
298             }
299
300             return (node instanceof Project)
301                     || (node instanceof DataDomain)
302                     || (node instanceof DataMap)
303                     || (node instanceof DataNode);
304         }
305     }
306
307     /**
308      * Traversal hanlder that rebuilds the tree from another tree. Used to reorder tree
309      * nodes.
310      */

311     class CopyTraversalHelper extends TraversalHelper {
312
313         public void projectNode(ProjectPath nodePath) {
314             DefaultMutableTreeNode JavaDoc node;
315
316             if (startNode == null) {
317                 startNode = new DefaultMutableTreeNode JavaDoc(nodePath.getObject());
318                 node = startNode;
319             }
320             else {
321                 DefaultMutableTreeNode JavaDoc original = ProjectTreeModel.this
322                         .getNodeForObjectPath(nodePath.getPath());
323                 DefaultMutableTreeNode JavaDoc nodeParent = (DefaultMutableTreeNode JavaDoc) nodesMap
324                         .get(nodePath.getObjectParent());
325                 node = new DefaultMutableTreeNode JavaDoc(original.getUserObject());
326                 nodeParent.add(node);
327             }
328
329             registerNode(node);
330         }
331     }
332 }
Popular Tags