1 5 package com.tc.object; 6 7 import com.tc.exception.TCRuntimeException; 8 import com.tc.object.appevent.NonPortableEventContext; 9 10 import java.util.ArrayList ; 11 import java.util.IdentityHashMap ; 12 import java.util.Iterator ; 13 import java.util.List ; 14 import java.util.Map ; 15 16 21 public class Traverser { 22 private static final TraverseTest NULL_TEST = new NullTraverseTest(); 23 private final TraversalAction action; 24 private final PortableObjectProvider portableObjectProvider; 25 private NonPortableEventContext context; 26 27 public Traverser(TraversalAction action, PortableObjectProvider portableObjectProvider) { 28 this.action = action; 29 this.portableObjectProvider = portableObjectProvider; 30 } 31 32 private void addReferencedObjects(Map toBeVisited, Object start, Map visited, TraverseTest traverseTest) { 33 Class clazz = start.getClass(); 34 35 while (clazz != null) { 36 TraversedReferences portableObjects = new TraversedReferencesImpl(); 37 portableObjects = portableObjectProvider.getPortableObjects(clazz, start, portableObjects); 38 39 for (Iterator i = portableObjects.iterator(); i.hasNext();) { 40 try { 41 TraversedReference currentReference = (TraversedReference) i.next(); 42 Object currentObject = currentReference.getValue(); 43 44 if (doNotTraverse(traverseTest, visited, currentObject)) { 45 continue; 46 } 47 48 traverseTest.checkPortability(currentReference, start.getClass(), context); 49 50 toBeVisited.put(currentObject, null); 51 } catch (IllegalArgumentException e) { 52 throw new TCRuntimeException(e); 53 } 54 } 55 clazz = clazz.getSuperclass(); 56 } 57 58 } 59 60 private boolean doNotTraverse(TraverseTest traverseTest, Map visited, Object current) { 61 if (current == null) { return true; } 62 63 if (visited.containsKey(current)) { return true; } 64 65 if (!traverseTest.shouldTraverse(current)) { return true; } 66 67 return false; 68 } 69 70 public void traverse(Object object) { 71 traverse(object, NULL_TEST, null); 72 } 73 74 public void traverse(Object object, TraverseTest traverseTest, NonPortableEventContext ctx) { 75 this.context = ctx; 76 Map visited = new IdentityHashMap (); 77 List toAdd = new ArrayList (); 78 79 visited.put(object, null); 80 81 IdentityHashMap toBeVisited = new IdentityHashMap (); 82 addReferencedObjects(toBeVisited, object, visited, traverseTest); 83 toAdd.add(object); 84 85 while (!toBeVisited.isEmpty()) { 86 for (Iterator i = new IdentityHashMap (toBeVisited).keySet().iterator(); i.hasNext();) { 87 Object obj = i.next(); 88 visited.put(obj, null); 89 toBeVisited.remove(obj); 90 addReferencedObjects(toBeVisited, obj, visited, traverseTest); 91 toAdd.add(obj); } 95 } 96 action.visit(toAdd); 97 } 98 } 99 | Popular Tags |