package graph; import java.util.*; /** * A path in a graph. This can keep track of an algorithm's * traversal or can be useful for other bookkeeping. * * @see Action * @author Michael Shilman (michaels@eecs.berkeley.edu) * @version $Id$ */ public class Path { /** * The path storage. */ public Vector path; /** * Create an empty path. */ Path() { path = new Vector(); } /** * Create an empty path with initial capacity size. * * @param size The initial capacity. */ Path(int size) { path = new Vector(size); } /** * Create an empty path with initial capacity size. * * @param size The initial capacity. * @param incr The increment. */ Path(int size, int incr) { path = new Vector(size, incr); } /** * Insert a node into the path at the specified index. * * @param n The node to insert. * @param index The index. */ public void insert(Node n, int index) { path.insertElementAt(n, index); } /** * Push a node onto the top of the stack. */ public void push(Node n) { path.addElement(n); } /** * Pop a node off the top of the stack. */ public Node pop() { Node n = (Node)path.lastElement(); path.removeElementAt(path.lastIndexOf(n)); return n; } /** * Check to see whether the path is valid, given * the actual graph topology (e.g. it wouldn't be * valid if there was a path from node a to node b * if there wasn't an edge between a and * b or a wasn't the parent of b. * * @returns The validity of the graph (true = valid) * @exception GraphException * If there are two nodes which are connected * by an edge which are not in the same graph, * this is illegal and is a problem with the * graph itself, not just a problem with * the path... */ public boolean valid() throws GraphException { if(path.size() == 0) { return true; } Enumeration e = path.elements(); Node prevNode, curNode; prevNode = (Node)e.nextElement(); for(;e.hasMoreElements();) { curNode = (Node)e.nextElement(); if(!checkConnection(prevNode, curNode)) { return false; } prevNode = curNode; } return true; } /** * Check to see whether or not the nodes are connected by * an edge or a nested relationship. * * @see Path#valid */ boolean checkConnection(Node n1, Node n2) throws GraphException { //check containment if(n1 instanceof Graph) { Graph g1 = (Graph)n1; if(g1.nodes.contains(n1)) { return true; } } //make sure they are in the same graph if(!n1.parent.equals(n2.parent)) { String err = "Path: nodes (" + n1.name + ", " + n2.name + ") do not share the same parent graph!"; throw (new GraphException(err)); } //check for directed edge connection for(Enumeration e = n1.out.elements(); e.hasMoreElements();) { Edge edge = (Edge)e.nextElement(); if(edge.head == n2) { return true; } } //if graph is undirected, check for reverse connection if(!n1.parent.directed) { for(Enumeration e = n1.in.elements(); e.hasMoreElements();) { Edge edge = (Edge)e.nextElement(); if(edge.tail == n2) { return true; } } } return false; } }