package edu.neu.ccs.demeter.aplib; import java.util.*; /** * A compact, efficient representation of a set of paths through a * class graph that can be used to guide a traversal of an object * graph. */ public abstract class Traversal { /** The version string for this version of the AP Library. */ public static String getVersion() { return "AP Library version 0.8.6"; } protected Traversal(ClassGraphI cg) { classGraph = cg; } /** * Compute the traversal determined by an encapsulated strategy and * a class graph. * * @throws TraversalException if the resulting traversal graph is empty. */ public static Traversal compute(StrategyI S, ClassGraphI G) throws TraversalException { return compute(S, G, null, null); } /** * Compute the traversal determined by an encapsulated strategy, * a class graph, a name map, and a constraint map. The two maps, * if not null, are combined with the maps in the encapsulated * strategy. * * @throws TraversalException if: *
-l->
v in the traversal, or null if there
* are none. Note that u and v may be either nodes or their string
* representations.
*/
public EdgeSet getConstructionEdgeSet(Object u, String l, Object v) {
return getEdgeSet(cedgeKey(u, l, v));
}
/**
* The set of copies of class graph alternation edge u
* =>
v in the traversal, or null if there are none.
* Note that u and v may be either nodes or their string
* representations.
*/
public EdgeSet getAlternationEdgeSet(Object u, Object v) {
return getEdgeSet(aedgeKey(u, v));
}
/**
* The set of copies of class graph inheritance edge u
* :>
v in the traversal, or null if there are none.
* Note that u and v may be either nodes or their string
* representations.
*/
public EdgeSet getInheritanceEdgeSet(Object u, Object v) {
return getEdgeSet(iedgeKey(u, v));
}
/**
* A set of edges ui -l->
vj
* in a traversal graph, where the edges in the set are all copies
* of the same class graph edge u -l->
v with
* different endpoint indices i and j.
*/
public abstract class EdgeSet {
EdgeSet(EdgeI e) { edge = e; }
/**
* The class graph edge u -l->
v corresponding to
* this edge set.
*/
public EdgeI getEdge() { return edge; }
EdgeI edge;
/** Is s a set of copies of the same edge as this? */
public boolean sameEdge(EdgeSet s) {
return edge.equals(s.edge);
}
public boolean equals(Object x) {
return x instanceof EdgeSet && sameEdge((EdgeSet) x);
}
public String toString() {
return edgeKey(edge) + ": " + indicesToString();
}
abstract String indicesToString();
/** The set of target nodes of edges in this set. */
public abstract NodeSet getTargetNodeSet();
}
/**
* A unique identifying string for the given edge. Useful for
* hashing.
*/
public static String edgeKey(EdgeI e) {
return
e == null ? "null" :
e.isConstructionEdge() ? cedgeKey(e.getSource(),
e.getLabel(),
e.getTarget()) :
e.isAlternationEdge() ? aedgeKey(e.getSource(), e.getTarget()) :
e.isInheritanceEdge() ? iedgeKey(e.getSource(), e.getTarget()) :
null;
}
/**
* A unique identifying string for the construction edge
* u -l->
v.
*/
static String cedgeKey(Object u, String l, Object v) {
return "-> " + u + "," + l + "," + v;
}
/**
* A unique identifying string for the alternation edge
* u =>
v.
*/
static String aedgeKey(Object u, Object v) {
return "=> " + u + "," + v;
}
/**
* A unique identifying string for the inheritance edge
* u :>
v.
*/
static String iedgeKey(Object u, Object v) {
return ":> " + u + "," + v;
}
/** A string representation of the nodes and edges in the traversal. */
public String toCompactString() {
String s = "";
s += "Start set: " + getStartSet() + "\n";
s += "Nodes:\n";
for (Iterator it = getNodeSets().iterator(); it.hasNext();)
s += " " + it.next() + "\n";
s += "Edges:\n";
for (Iterator it = getEdgeSets().iterator(); it.hasNext();)
s += " " + it.next() + "\n";
s += "Finish set: " + getFinishSet() + "\n";
return s;
}
}