package edu.neu.ccs.demeter.dj; import java.util.*; /** * A compact, efficient representation of a set of paths through a * class graph that can be used to traverse an object graph. */ public class Traversal extends edu.neu.ccs.demeter.aplib.Traversal { /** The DJ version string. */ public static String getVersion() { return ClassGraph.getVersion(); } Strategy strategy; edu.neu.ccs.demeter.aplib.Traversal traversal; /** * Compute the traversal determined by s and cg. * * @throws TraversalException if the resulting traversal is * empty. */ public Traversal(Strategy s, ClassGraph cg) { super(cg); strategy = s; try { traversal = compute(s, cg); } catch (edu.neu.ccs.demeter.aplib.TraversalException e) { throw new TraversalException(e.getMessage()); } } /** * Compute the traversal determined by strategy s and cg. * * @throws TraversalException if the resulting traversal is * empty. */ public Traversal(String s, ClassGraph cg) { this(new Strategy(s), cg); } /** * The strategy expression used to compute the traversal. */ public Strategy getStrategy() { return strategy; } /** * The slice of the object graph rooted at o determined by the * traversal. */ public ObjectGraphSlice slice(Object o) { return new ObjectGraphSlice(o, this); } /** * Traverse the object graph rooted at o according to the traversal, * visiting v at each node and returning the value of * v.getReturnValue() at the end of the traversal. */ public Object traverse(Object o, Visitor v) { return slice(o).traverse(v); } /** * Traverse the object graph rooted at o according to the traversal, * visiting the visitors in array v in sequence at each node and * returning the value of v[0].getReturnValue() at the end of the * traversal. */ public Object traverse(Object o, Visitor v[]) { return slice(o).traverse(v); } /** * Fetch the object in the object graph rooted at o corresponding * to the target(s) of the traversal. */ public Object fetch(Object o) throws FetchException { return slice(o).fetch(); } /** * Gather into a list the objects in the object graph rooted at o * corresponding to the target(s) of the traversal. */ public List gather(Object o) { return slice(o).gather(); } /** * A fixed-size List backed by the object graph rooted at o. The * elements of the list are the objects reachable by the strategy in * the object graph with the given root whose class is a target of * the strategy. Note that this list (like the List returned by * Arrays.asList, but unlike the List returned by gather()) is * write-through, i.e. modifying it will modify the underlying * object graph, and vice versa. * * @throws TraversalSourceException if the type of o is not a * source of the strategy. */ public java.util.List asList(Object o) { return slice(o).asList(); } /** * Make a class graph with just the classes and edges in the * traversal. */ public ClassGraph toClassGraph() { return new ClassGraph(this); } // Delegation stuff, to implement the parent's abstract methods. // This is sort of like the Proxy and Decorator patterns, although // the purpose is to subclass all the classes in a Composite pattern. public List getNodeSets() { return traversal.getNodeSets(); } public NodeSet getNodeSet(Object v) { return traversal.getNodeSet(v); } public List getStartSet() { return traversal.getStartSet(); } public NodeSet getStartSet(Object v) { return traversal.getStartSet(v); } public List getFinishSet() { return traversal.getFinishSet(); } public NodeSet getFinishSet(Object v) { return traversal.getFinishSet(v); } public List getEdgeSets() { return traversal.getEdgeSets(); } public EdgeSet getEdgeSet(String key) { return traversal.getEdgeSet(key); } public String toString() { return traversal.toString(); } public boolean equals(Object t) { return traversal.equals(t); } public int hashCode() { return traversal.hashCode(); } }