KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tc > object > walker > ObjectGraphWalker


1 /*
2  * All content copyright (c) 2003-2007 Terracotta, Inc., except as may otherwise be noted in a separate copyright
3  * notice. All rights reserved.
4  */

5 package com.tc.object.walker;
6
7 import java.util.Collection JavaDoc;
8 import java.util.IdentityHashMap JavaDoc;
9 import java.util.LinkedList JavaDoc;
10 import java.util.Map JavaDoc;
11
12 public class ObjectGraphWalker {
13
14   private final VisitedSet visited;
15   private final LinkedList JavaDoc backtrack = new LinkedList JavaDoc();
16   private final Visitor visitor;
17   private final MemberValue root;
18   private int currentDepth = 0;
19   private final WalkTest walkTest;
20
21   public ObjectGraphWalker(Object JavaDoc root, WalkTest walkTest, Visitor visitor) {
22     if (root == null) { throw new IllegalArgumentException JavaDoc("refusing to traverse null"); }
23     if (walkTest == null) { throw new NullPointerException JavaDoc("null walk test"); }
24     if (visitor == null) { throw new NullPointerException JavaDoc("null visitor"); }
25     this.root = MemberValue.rootValue(root);
26     this.visitor = visitor;
27     this.visited = new VisitedSet(this.root);
28     this.walkTest = walkTest;
29   }
30
31   public void walk() {
32     visitor.visitRootObject(root);
33     currentDepth++;
34
35     if (!walkTest.shouldTraverse(root)) { return; }
36
37     backtrack.addFirst(makeNode(root.getValueObject()));
38
39     while (backtrack.size() > 0) {
40       Node current = (Node) backtrack.getFirst();
41       visit(current);
42     }
43   }
44
45   private Node makeNode(Object JavaDoc o) {
46     if (o == null) { throw new NullPointerException JavaDoc(); }
47
48     if (o.getClass().isArray()) {
49       return new ArrayNode(o);
50     } else if (o instanceof Collection JavaDoc) {
51       return new CollectionNode((Collection JavaDoc) o);
52     } else if (o instanceof Map JavaDoc) {
53       return new MapNode((Map JavaDoc) o);
54     } else if (o instanceof MapEntry) {
55       return new MapEntryNode((MapEntry) o);
56     } else {
57       return new PlainNode(o);
58     }
59   }
60
61   private void visit(Node node) {
62     while (!node.done()) {
63       MemberValue value = node.next();
64
65       if (value instanceof MapEntry) {
66         MapEntry entry = (MapEntry) value;
67         visitor.visitMapEntry(entry.getIndex(), currentDepth);
68         currentDepth++;
69         backtrack.addFirst(makeNode(entry));
70         return;
71       }
72
73       Object JavaDoc o = value.getValueObject();
74
75       boolean shouldTraverse = walkTest.shouldTraverse(value);
76
77       if (shouldTraverse) {
78         visited.visit(value);
79       }
80
81       visitor.visitValue(value, currentDepth);
82
83       if (o != null && shouldTraverse && !value.isRepeated()) {
84         Node next = makeNode(o);
85         currentDepth++;
86         backtrack.addFirst(next);
87         return;
88       }
89     }
90
91     currentDepth--;
92     backtrack.removeFirst();
93   }
94
95   private static class VisitedSet {
96     private final IdentityHashMap JavaDoc visited = new IdentityHashMap JavaDoc();
97
98     VisitedSet(MemberValue root) {
99       visit(root);
100     }
101
102     void visit(MemberValue value) {
103       Object JavaDoc o = value.getValueObject();
104
105       Integer JavaDoc id = (Integer JavaDoc) visited.get(o);
106       if (id == null) {
107         id = new Integer JavaDoc(visited.size());
108         visited.put(o, id);
109       } else {
110         value.setRepeated(true);
111       }
112
113       value.setId(id.intValue());
114     }
115   }
116
117 }
118
Popular Tags