KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectstyle > cayenne > project > ProjectTraversal


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.project;
57
58 import java.util.Collections JavaDoc;
59 import java.util.Comparator JavaDoc;
60 import java.util.Iterator JavaDoc;
61
62 import org.objectstyle.cayenne.access.DataDomain;
63 import org.objectstyle.cayenne.access.DataNode;
64 import org.objectstyle.cayenne.map.Attribute;
65 import org.objectstyle.cayenne.map.DataMap;
66 import org.objectstyle.cayenne.map.Entity;
67 import org.objectstyle.cayenne.map.MapObject;
68 import org.objectstyle.cayenne.map.Procedure;
69 import org.objectstyle.cayenne.map.Relationship;
70 import org.objectstyle.cayenne.query.Query;
71 import org.objectstyle.cayenne.util.Util;
72
73 /**
74  * ProjectTraversal allows to traverse Cayenne project tree in a
75  * "depth-first" order starting from an arbitrary level to its children.
76  *
77  * <p><i>Current implementation is not very efficient
78  * and would actually first read the whole tree, before returning
79  * the first element from the iterator.</i></p>
80  *
81  * @author Andrei Adamchik
82  */

83 public class ProjectTraversal {
84
85     protected static final Comparator JavaDoc mapObjectComparator = new MapObjectComparator();
86     protected static final Comparator JavaDoc dataMapComparator = new DataMapComparator();
87     protected static final Comparator JavaDoc dataDomainComparator = new DataDomainComparator();
88     protected static final Comparator JavaDoc dataNodeComparator = new DataNodeComparator();
89     protected static final Comparator JavaDoc queryComparator = new QueryComparator();
90
91     protected ProjectTraversalHandler handler;
92     protected boolean sort;
93
94     public ProjectTraversal(ProjectTraversalHandler handler) {
95         this(handler, false);
96     }
97
98     /**
99      * Creates ProjectTraversal instance with a given handler and
100      * sort policy. If <code>sort</code> is true, children of each
101      * node will be sorted using a predefined Comparator for a given
102      * type of child nodes.
103      */

104     public ProjectTraversal(ProjectTraversalHandler handler, boolean sort) {
105         this.handler = handler;
106         this.sort = sort;
107     }
108
109     /**
110      * Performs traversal starting from the root node. Root node can be
111      * of any type supported in Cayenne projects (Configuration, DataMap, DataNode, etc...)
112      */

113     public void traverse(Object JavaDoc rootNode) {
114         this.traverse(rootNode, new ProjectPath());
115     }
116
117     public void traverse(Object JavaDoc rootNode, ProjectPath path) {
118         if (rootNode instanceof Project) {
119             this.traverseProject((Project) rootNode, path);
120         }
121         else if (rootNode instanceof DataDomain) {
122             this.traverseDomains(Collections.singletonList(rootNode).iterator(), path);
123         }
124         else if (rootNode instanceof DataMap) {
125             this.traverseMaps(Collections.singletonList(rootNode).iterator(), path);
126         }
127         else if (rootNode instanceof Entity) {
128             this.traverseEntities(Collections.singletonList(rootNode).iterator(), path);
129         }
130         else if (rootNode instanceof Attribute) {
131             this.traverseAttributes(Collections.singletonList(rootNode).iterator(), path);
132         }
133         else if (rootNode instanceof Relationship) {
134             this.traverseRelationships(
135                 Collections.singletonList(rootNode).iterator(),
136                 path);
137         }
138         else if (rootNode instanceof DataNode) {
139             this.traverseNodes(Collections.singletonList(rootNode).iterator(), path);
140         }
141         else {
142             String JavaDoc nodeClass =
143                 (rootNode != null) ? rootNode.getClass().getName() : "(null)";
144             throw new IllegalArgumentException JavaDoc("Unsupported root node: " + nodeClass);
145         }
146     }
147
148     /**
149      * Performs traversal starting from the Project and down to its children.
150      */

151     public void traverseProject(Project project, ProjectPath path) {
152         ProjectPath projectPath = path.appendToPath(project);
153         handler.projectNode(projectPath);
154
155         if (handler.shouldReadChildren(project, path)) {
156             Iterator JavaDoc it = project.getChildren().iterator();
157             while (it.hasNext()) {
158                 this.traverse(it.next(), projectPath);
159             }
160         }
161     }
162
163     /**
164       * Performs traversal starting from a list of domains.
165       */

166     public void traverseDomains(Iterator JavaDoc domains, ProjectPath path) {
167
168         if (sort) {
169             domains = Util.sortedIterator(domains, ProjectTraversal.dataDomainComparator);
170         }
171
172         while (domains.hasNext()) {
173             DataDomain domain = (DataDomain) domains.next();
174             ProjectPath domainPath = path.appendToPath(domain);
175             handler.projectNode(domainPath);
176
177             if (handler.shouldReadChildren(domain, path)) {
178                 this.traverseMaps(domain.getDataMaps().iterator(), domainPath);
179                 this.traverseNodes(domain.getDataNodes().iterator(), domainPath);
180             }
181         }
182     }
183
184     public void traverseNodes(Iterator JavaDoc nodes, ProjectPath path) {
185         if (sort) {
186             nodes = Util.sortedIterator(nodes, ProjectTraversal.dataNodeComparator);
187         }
188
189         while (nodes.hasNext()) {
190             DataNode node = (DataNode) nodes.next();
191             ProjectPath nodePath = path.appendToPath(node);
192             handler.projectNode(nodePath);
193
194             if (handler.shouldReadChildren(node, path)) {
195                 this.traverseMaps(node.getDataMaps().iterator(), nodePath);
196             }
197         }
198     }
199
200     public void traverseMaps(Iterator JavaDoc maps, ProjectPath path) {
201         if (sort) {
202             maps = Util.sortedIterator(maps, ProjectTraversal.dataMapComparator);
203         }
204
205         while (maps.hasNext()) {
206             DataMap map = (DataMap) maps.next();
207             ProjectPath mapPath = path.appendToPath(map);
208             handler.projectNode(mapPath);
209
210             if (handler.shouldReadChildren(map, path)) {
211                 this.traverseEntities(map.getObjEntities().iterator(), mapPath);
212                 this.traverseEntities(map.getDbEntities().iterator(), mapPath);
213                 this.traverseProcedures(map.getProcedures().iterator(), mapPath);
214                 this.traverseQueries(map.getQueries().iterator(), mapPath);
215             }
216         }
217     }
218
219     /**
220      * Performs recusrive traversal of an Iterator of Cayenne Query objects.
221      */

222     public void traverseQueries(Iterator JavaDoc queries, ProjectPath path) {
223         if (sort) {
224             queries =
225                 Util.sortedIterator(queries, ProjectTraversal.queryComparator);
226         }
227
228         while (queries.hasNext()) {
229             Query query = (Query) queries.next();
230             ProjectPath queryPath = path.appendToPath(query);
231             handler.projectNode(queryPath);
232         }
233     }
234     
235     /**
236      * Performs recusrive traversal of an Iterator of Cayenne Procedure objects.
237      */

238     public void traverseProcedures(Iterator JavaDoc procedures, ProjectPath path) {
239         if (sort) {
240             procedures =
241                 Util.sortedIterator(procedures, ProjectTraversal.mapObjectComparator);
242         }
243
244         while (procedures.hasNext()) {
245             Procedure procedure = (Procedure) procedures.next();
246             ProjectPath procedurePath = path.appendToPath(procedure);
247             handler.projectNode(procedurePath);
248
249             if (handler.shouldReadChildren(procedure, path)) {
250                 this.traverseProcedureParameters(
251                     procedure.getCallParameters().iterator(),
252                     procedurePath);
253             }
254         }
255     }
256
257     public void traverseEntities(Iterator JavaDoc entities, ProjectPath path) {
258         if (sort) {
259             entities =
260                 Util.sortedIterator(entities, ProjectTraversal.mapObjectComparator);
261         }
262
263         while (entities.hasNext()) {
264             Entity ent = (Entity) entities.next();
265             ProjectPath entPath = path.appendToPath(ent);
266             handler.projectNode(entPath);
267
268             if (handler.shouldReadChildren(ent, path)) {
269                 this.traverseAttributes(ent.getAttributes().iterator(), entPath);
270                 this.traverseRelationships(ent.getRelationships().iterator(), entPath);
271             }
272         }
273     }
274
275     public void traverseAttributes(Iterator JavaDoc attributes, ProjectPath path) {
276         if (sort) {
277             attributes =
278                 Util.sortedIterator(attributes, ProjectTraversal.mapObjectComparator);
279         }
280
281         while (attributes.hasNext()) {
282             handler.projectNode(path.appendToPath(attributes.next()));
283         }
284     }
285
286     public void traverseRelationships(Iterator JavaDoc relationships, ProjectPath path) {
287         if (sort) {
288             relationships =
289                 Util.sortedIterator(relationships, ProjectTraversal.mapObjectComparator);
290         }
291
292         while (relationships.hasNext()) {
293             handler.projectNode(path.appendToPath(relationships.next()));
294         }
295     }
296
297     public void traverseProcedureParameters(Iterator JavaDoc parameters, ProjectPath path) {
298         // Note: !! do not try to sort parameters - they are positional by definition
299

300         while (parameters.hasNext()) {
301             handler.projectNode(path.appendToPath(parameters.next()));
302         }
303     }
304
305     static class QueryComparator implements Comparator JavaDoc {
306         public int compare(Object JavaDoc o1, Object JavaDoc o2) {
307             String JavaDoc name1 = ((Query) o1).getName();
308             String JavaDoc name2 = ((Query) o2).getName();
309
310             if (name1 == null) {
311                 return (name2 != null) ? -1 : 0;
312             }
313             else if (name2 == null) {
314                 return 1;
315             }
316             else {
317                 return name1.compareTo(name2);
318             }
319         }
320     }
321     
322     static class MapObjectComparator implements Comparator JavaDoc {
323         public int compare(Object JavaDoc o1, Object JavaDoc o2) {
324             String JavaDoc name1 = ((MapObject) o1).getName();
325             String JavaDoc name2 = ((MapObject) o2).getName();
326
327             if (name1 == null) {
328                 return (name2 != null) ? -1 : 0;
329             }
330             else if (name2 == null) {
331                 return 1;
332             }
333             else {
334                 return name1.compareTo(name2);
335             }
336         }
337     }
338
339     static class DataMapComparator implements Comparator JavaDoc {
340         public int compare(Object JavaDoc o1, Object JavaDoc o2) {
341             String JavaDoc name1 = ((DataMap) o1).getName();
342             String JavaDoc name2 = ((DataMap) o2).getName();
343
344             if (name1 == null) {
345                 return (name2 != null) ? -1 : 0;
346             }
347             else if (name2 == null) {
348                 return 1;
349             }
350             else {
351                 return name1.compareTo(name2);
352             }
353         }
354
355     }
356
357     static class DataDomainComparator implements Comparator JavaDoc {
358         public int compare(Object JavaDoc o1, Object JavaDoc o2) {
359             String JavaDoc name1 = ((DataDomain) o1).getName();
360             String JavaDoc name2 = ((DataDomain) o2).getName();
361
362             if (name1 == null) {
363                 return (name2 != null) ? -1 : 0;
364             }
365             else if (name2 == null) {
366                 return 1;
367             }
368             else {
369                 return name1.compareTo(name2);
370             }
371         }
372
373     }
374
375     static class DataNodeComparator implements Comparator JavaDoc {
376         public int compare(Object JavaDoc o1, Object JavaDoc o2) {
377             String JavaDoc name1 = ((DataNode) o1).getName();
378             String JavaDoc name2 = ((DataNode) o2).getName();
379
380             if (name1 == null) {
381                 return (name2 != null) ? -1 : 0;
382             }
383             else if (name2 == null) {
384                 return 1;
385             }
386             else {
387                 return name1.compareTo(name2);
388             }
389         }
390     }
391 }
392
Popular Tags