KickJava   Java API By Example, From Geeks To Geeks.

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


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.cayenne.project;
21
22 import java.util.Collections JavaDoc;
23 import java.util.Comparator JavaDoc;
24 import java.util.Iterator JavaDoc;
25
26 import org.apache.cayenne.access.DataDomain;
27 import org.apache.cayenne.access.DataNode;
28 import org.apache.cayenne.map.Attribute;
29 import org.apache.cayenne.map.DataMap;
30 import org.apache.cayenne.map.Entity;
31 import org.apache.cayenne.map.Procedure;
32 import org.apache.cayenne.map.Relationship;
33 import org.apache.cayenne.query.Query;
34 import org.apache.cayenne.util.CayenneMapEntry;
35 import org.apache.cayenne.util.Util;
36
37 /**
38  * ProjectTraversal allows to traverse Cayenne project tree in a "depth-first" order
39  * starting from an arbitrary level to its children.
40  * <p>
41  * <i>Current implementation is not very efficient and would actually first read the whole
42  * tree, before returning the first element from the iterator.</i>
43  * </p>
44  *
45  * @author Andrus Adamchik
46  */

47 public class ProjectTraversal {
48
49     protected static final Comparator JavaDoc mapObjectComparator = new MapObjectComparator();
50     protected static final Comparator JavaDoc dataMapComparator = new DataMapComparator();
51     protected static final Comparator JavaDoc dataDomainComparator = new DataDomainComparator();
52     protected static final Comparator JavaDoc dataNodeComparator = new DataNodeComparator();
53     protected static final Comparator JavaDoc queryComparator = new QueryComparator();
54
55     protected ProjectTraversalHandler handler;
56     protected boolean sort;
57
58     public ProjectTraversal(ProjectTraversalHandler handler) {
59         this(handler, false);
60     }
61
62     /**
63      * Creates ProjectTraversal instance with a given handler and sort policy. If
64      * <code>sort</code> is true, children of each node will be sorted using a
65      * predefined Comparator for a given type of child nodes.
66      */

67     public ProjectTraversal(ProjectTraversalHandler handler, boolean sort) {
68         this.handler = handler;
69         this.sort = sort;
70     }
71
72     /**
73      * Performs traversal starting from the root node. Root node can be of any type
74      * supported in Cayenne projects (Configuration, DataMap, DataNode, etc...)
75      */

76     public void traverse(Object JavaDoc rootNode) {
77         this.traverse(rootNode, new ProjectPath());
78     }
79
80     public void traverse(Object JavaDoc rootNode, ProjectPath path) {
81         if (rootNode instanceof Project) {
82             this.traverseProject((Project) rootNode, path);
83         }
84         else if (rootNode instanceof DataDomain) {
85             this.traverseDomains(Collections.singletonList(rootNode).iterator(), path);
86         }
87         else if (rootNode instanceof DataMap) {
88             this.traverseMaps(Collections.singletonList(rootNode).iterator(), path);
89         }
90         else if (rootNode instanceof Entity) {
91             this.traverseEntities(Collections.singletonList(rootNode).iterator(), path);
92         }
93         else if (rootNode instanceof Attribute) {
94             this.traverseAttributes(Collections.singletonList(rootNode).iterator(), path);
95         }
96         else if (rootNode instanceof Relationship) {
97             this.traverseRelationships(
98                     Collections.singletonList(rootNode).iterator(),
99                     path);
100         }
101         else if (rootNode instanceof DataNode) {
102             this.traverseNodes(Collections.singletonList(rootNode).iterator(), path);
103         }
104         else {
105             String JavaDoc nodeClass = (rootNode != null)
106                     ? rootNode.getClass().getName()
107                     : "(null)";
108             throw new IllegalArgumentException JavaDoc("Unsupported root node: " + nodeClass);
109         }
110     }
111
112     /**
113      * Performs traversal starting from the Project and down to its children.
114      */

115     public void traverseProject(Project project, ProjectPath path) {
116         ProjectPath projectPath = path.appendToPath(project);
117         handler.projectNode(projectPath);
118
119         if (handler.shouldReadChildren(project, path)) {
120             Iterator JavaDoc it = project.getChildren().iterator();
121             while (it.hasNext()) {
122                 this.traverse(it.next(), projectPath);
123             }
124         }
125     }
126
127     /**
128      * Performs traversal starting from a list of domains.
129      */

130     public void traverseDomains(Iterator JavaDoc domains, ProjectPath path) {
131
132         if (sort) {
133             domains = Util.sortedIterator(domains, ProjectTraversal.dataDomainComparator);
134         }
135
136         while (domains.hasNext()) {
137             DataDomain domain = (DataDomain) domains.next();
138             ProjectPath domainPath = path.appendToPath(domain);
139             handler.projectNode(domainPath);
140
141             if (handler.shouldReadChildren(domain, path)) {
142                 this.traverseMaps(domain.getDataMaps().iterator(), domainPath);
143                 this.traverseNodes(domain.getDataNodes().iterator(), domainPath);
144             }
145         }
146     }
147
148     public void traverseNodes(Iterator JavaDoc nodes, ProjectPath path) {
149         if (sort) {
150             nodes = Util.sortedIterator(nodes, ProjectTraversal.dataNodeComparator);
151         }
152
153         while (nodes.hasNext()) {
154             DataNode node = (DataNode) nodes.next();
155             ProjectPath nodePath = path.appendToPath(node);
156             handler.projectNode(nodePath);
157
158             if (handler.shouldReadChildren(node, path)) {
159                 this.traverseMaps(node.getDataMaps().iterator(), nodePath);
160             }
161         }
162     }
163
164     public void traverseMaps(Iterator JavaDoc maps, ProjectPath path) {
165         if (sort) {
166             maps = Util.sortedIterator(maps, ProjectTraversal.dataMapComparator);
167         }
168
169         while (maps.hasNext()) {
170             DataMap map = (DataMap) maps.next();
171             ProjectPath mapPath = path.appendToPath(map);
172             handler.projectNode(mapPath);
173
174             if (handler.shouldReadChildren(map, path)) {
175                 this.traverseEntities(map.getObjEntities().iterator(), mapPath);
176                 this.traverseEntities(map.getDbEntities().iterator(), mapPath);
177                 this.traverseProcedures(map.getProcedures().iterator(), mapPath);
178                 this.traverseQueries(map.getQueries().iterator(), mapPath);
179             }
180         }
181     }
182
183     /**
184      * Performs recursive traversal of an Iterator of Cayenne Query objects.
185      */

186     public void traverseQueries(Iterator JavaDoc queries, ProjectPath path) {
187         if (sort) {
188             queries = Util.sortedIterator(queries, ProjectTraversal.queryComparator);
189         }
190
191         while (queries.hasNext()) {
192             Query query = (Query) queries.next();
193             ProjectPath queryPath = path.appendToPath(query);
194             handler.projectNode(queryPath);
195         }
196     }
197
198     /**
199      * Performs recusrive traversal of an Iterator of Cayenne Procedure objects.
200      */

201     public void traverseProcedures(Iterator JavaDoc procedures, ProjectPath path) {
202         if (sort) {
203             procedures = Util.sortedIterator(
204                     procedures,
205                     ProjectTraversal.mapObjectComparator);
206         }
207
208         while (procedures.hasNext()) {
209             Procedure procedure = (Procedure) procedures.next();
210             ProjectPath procedurePath = path.appendToPath(procedure);
211             handler.projectNode(procedurePath);
212
213             if (handler.shouldReadChildren(procedure, path)) {
214                 this.traverseProcedureParameters(
215                         procedure.getCallParameters().iterator(),
216                         procedurePath);
217             }
218         }
219     }
220
221     public void traverseEntities(Iterator JavaDoc entities, ProjectPath path) {
222         if (sort) {
223             entities = Util
224                     .sortedIterator(entities, ProjectTraversal.mapObjectComparator);
225         }
226
227         while (entities.hasNext()) {
228             Entity ent = (Entity) entities.next();
229             ProjectPath entPath = path.appendToPath(ent);
230             handler.projectNode(entPath);
231
232             if (handler.shouldReadChildren(ent, path)) {
233                 this.traverseAttributes(ent.getAttributes().iterator(), entPath);
234                 this.traverseRelationships(ent.getRelationships().iterator(), entPath);
235             }
236         }
237     }
238
239     public void traverseAttributes(Iterator JavaDoc attributes, ProjectPath path) {
240         if (sort) {
241             attributes = Util.sortedIterator(
242                     attributes,
243                     ProjectTraversal.mapObjectComparator);
244         }
245
246         while (attributes.hasNext()) {
247             handler.projectNode(path.appendToPath(attributes.next()));
248         }
249     }
250
251     public void traverseRelationships(Iterator JavaDoc relationships, ProjectPath path) {
252         if (sort) {
253             relationships = Util.sortedIterator(
254                     relationships,
255                     ProjectTraversal.mapObjectComparator);
256         }
257
258         while (relationships.hasNext()) {
259             handler.projectNode(path.appendToPath(relationships.next()));
260         }
261     }
262
263     public void traverseProcedureParameters(Iterator JavaDoc parameters, ProjectPath path) {
264         // Note: !! do not try to sort parameters - they are positional by definition
265

266         while (parameters.hasNext()) {
267             handler.projectNode(path.appendToPath(parameters.next()));
268         }
269     }
270
271     static class QueryComparator implements Comparator JavaDoc {
272
273         public int compare(Object JavaDoc o1, Object JavaDoc o2) {
274             String JavaDoc name1 = ((Query) o1).getName();
275             String JavaDoc name2 = ((Query) o2).getName();
276
277             if (name1 == null) {
278                 return (name2 != null) ? -1 : 0;
279             }
280             else if (name2 == null) {
281                 return 1;
282             }
283             else {
284                 return name1.compareTo(name2);
285             }
286         }
287     }
288
289     static class MapObjectComparator implements Comparator JavaDoc {
290
291         public int compare(Object JavaDoc o1, Object JavaDoc o2) {
292             String JavaDoc name1 = ((CayenneMapEntry) o1).getName();
293             String JavaDoc name2 = ((CayenneMapEntry) o2).getName();
294
295             if (name1 == null) {
296                 return (name2 != null) ? -1 : 0;
297             }
298             else if (name2 == null) {
299                 return 1;
300             }
301             else {
302                 return name1.compareTo(name2);
303             }
304         }
305     }
306
307     static class DataMapComparator implements Comparator JavaDoc {
308
309         public int compare(Object JavaDoc o1, Object JavaDoc o2) {
310             String JavaDoc name1 = ((DataMap) o1).getName();
311             String JavaDoc name2 = ((DataMap) o2).getName();
312
313             if (name1 == null) {
314                 return (name2 != null) ? -1 : 0;
315             }
316             else if (name2 == null) {
317                 return 1;
318             }
319             else {
320                 return name1.compareTo(name2);
321             }
322         }
323
324     }
325
326     static class DataDomainComparator implements Comparator JavaDoc {
327
328         public int compare(Object JavaDoc o1, Object JavaDoc o2) {
329             String JavaDoc name1 = ((DataDomain) o1).getName();
330             String JavaDoc name2 = ((DataDomain) o2).getName();
331
332             if (name1 == null) {
333                 return (name2 != null) ? -1 : 0;
334             }
335             else if (name2 == null) {
336                 return 1;
337             }
338             else {
339                 return name1.compareTo(name2);
340             }
341         }
342
343     }
344
345     static class DataNodeComparator implements Comparator JavaDoc {
346
347         public int compare(Object JavaDoc o1, Object JavaDoc o2) {
348             String JavaDoc name1 = ((DataNode) o1).getName();
349             String JavaDoc name2 = ((DataNode) o2).getName();
350
351             if (name1 == null) {
352                 return (name2 != null) ? -1 : 0;
353             }
354             else if (name2 == null) {
355                 return 1;
356             }
357             else {
358                 return name1.compareTo(name2);
359             }
360         }
361     }
362 }
363
Popular Tags