diff --git a/build.properties b/build.properties index 7ff3dc4..4fdc8ee 100644 --- a/build.properties +++ b/build.properties @@ -12,7 +12,7 @@ test.home = ${source.home}/test build.dir = . # Compiler defaults -compile.debug = false +compile.debug = true compile.deprecation = true compile.optimize = true diff --git a/src/java/org/apache/commons/graph/BFS.java b/src/java/org/apache/commons/graph/BFS.java index 123fb08..b60a0b0 100644 --- a/src/java/org/apache/commons/graph/BFS.java +++ b/src/java/org/apache/commons/graph/BFS.java @@ -68,7 +68,7 @@ import org.apache.commons.graph.visitor.Visitor; * outgoing edges of the vertex. Extremes are searched last. This is typically * implemented with a queue. * - * @version $Id: BFS.java,v 1.3 2001/12/01 19:03:59 jvanzyl Exp $ + * @version $Id: BFS.java,v 1.4 2001/12/02 18:07:18 jvanzyl Exp $ * @author M. Dahm */ public class BFS extends TraversalOrder { @@ -109,7 +109,7 @@ public class BFS extends TraversalOrder { /* Initially mark all vertices as WHITE */ for(int i=0; i < size; i++) { - vertices[i].setColor(WHITE); + vertices[i].setColor(GraphConstants.WHITE); vertices[i].setPredecessor(null); } @@ -121,7 +121,7 @@ public class BFS extends TraversalOrder { visitor.discoverVertex(start); // Initialization - start.setColor(GRAY); + start.setColor(GraphConstants.GRAY); q.enqueue(start); while(!q.empty() && !stopped) { @@ -135,10 +135,10 @@ public class BFS extends TraversalOrder { visitor.discoverEdge(edges[i]); Vertex v = vertices[i]; - if(v.getColor() == WHITE) { // Unvisited vertex? + if(v.getColor() == GraphConstants.WHITE) { // Unvisited vertex? visitor.discoverVertex(v); - v.setColor(GRAY); + v.setColor(GraphConstants.GRAY); q.enqueue(v); } @@ -147,7 +147,7 @@ public class BFS extends TraversalOrder { visitor.finishVertex(u); q.dequeue(); - u.setColor(BLACK); + u.setColor(GraphConstants.BLACK); } visitor.finishGraph(g); diff --git a/src/java/org/apache/commons/graph/DFS.java b/src/java/org/apache/commons/graph/DFS.java index 993b6ec..329a5ac 100644 --- a/src/java/org/apache/commons/graph/DFS.java +++ b/src/java/org/apache/commons/graph/DFS.java @@ -67,7 +67,7 @@ import org.apache.commons.graph.visitor.Visitor; * (2) An algorithm which marks all vertices in a directed graph in the order they are * discovered and finished, partitioning the graph into a forest. * - * @version $Id: DFS.java,v 1.3 2001/12/01 19:02:07 jvanzyl Exp $ + * @version $Id: DFS.java,v 1.4 2001/12/02 18:07:18 jvanzyl Exp $ * @author M. Dahm */ public class DFS extends TraversalOrder { @@ -105,10 +105,9 @@ public class DFS extends TraversalOrder { visitor.discoverGraph(g); - /* Initially mark all vertices as WHITE - */ + // Initially mark all vertices as WHITE for(int i=0; i < size; i++) - vertices[i].setColor(WHITE); + vertices[i].setColor(GraphConstants.WHITE); if(start != null && g.contains(start)) // Start DFS at (white) start vertex DFS_Visit(start); @@ -117,7 +116,7 @@ public class DFS extends TraversalOrder { for(int i=0; (i < size) && !stopped; i++) { Vertex v = vertices[i]; - if(v.getColor() == WHITE) // Unvisited vertex? + if(v.getColor() == GraphConstants.WHITE) // Unvisited vertex? DFS_Visit(v); } } @@ -126,26 +125,27 @@ public class DFS extends TraversalOrder { } private final void DFS_Visit(Vertex u) { - u.setColor(GRAY); // Mark as visited + u.setColor(GraphConstants.GRAY); // Mark as visited visitor.discoverVertex(u); Vertex[] vertices = graph.getVertexArray(u); // Get adjacent vertices Edge[] edges = graph.getEdgeArray(u); // and edges int size = vertices.length; - //System.out.println(java.util.Arrays.asList(edges)); for(int i=0; (i < size) && !stopped; i++) { // Explore all edges visitor.discoverEdge(edges[i]); Vertex v = vertices[i]; - if(v.getColor() == WHITE) - DFS_Visit(v); + if(v.getColor() == GraphConstants.WHITE) + { + DFS_Visit(v); + } visitor.finishEdge(edges[i]); } - u.setColor(BLACK); // Mark as finished + u.setColor(GraphConstants.BLACK); // Mark as finished visitor.finishVertex(u); } } diff --git a/src/java/org/apache/commons/graph/Edge.java b/src/java/org/apache/commons/graph/Edge.java index 932a01e..4364b74 100644 --- a/src/java/org/apache/commons/graph/Edge.java +++ b/src/java/org/apache/commons/graph/Edge.java @@ -54,18 +54,31 @@ package org.apache.commons.graph; * . */ +import java.io.Serializable; + import org.apache.commons.graph.visitor.Visitor; /** * Describes an edge between two vertices of a graph, i.e. a relation between * two arbitrary vertices. * - * @version $Id: Edge.java,v 1.2 2001/11/29 14:17:33 jvanzyl Exp $ + * @version $Id: Edge.java,v 1.3 2001/12/02 18:07:18 jvanzyl Exp $ * @author M. Dahm */ -public class Edge implements Cloneable, Constants, java.io.Serializable { - private int ident; // unique number, i.e. identifier - private static int counter; // produce default numbers +public class Edge + implements Cloneable,Serializable +{ + + /** + * Unique identifer for this edge. + */ + private int ident; + + /** + * Counter that is incremented to give + * this edge a unique identity. + */ + private static int counter; /** * Create edge. @@ -88,16 +101,18 @@ public class Edge implements Cloneable, Constants, java.io.Serializable { * @return String representation. */ public String toString() { - return toString(PLAIN); + return toString(GraphConstants.PLAIN); } - + /** * @param verbose toggle output format * @return String representation. */ public String toString(int verbose) { - if((verbose == TALKATIVE) || (verbose == V_TALKATIVE)) + if((verbose == GraphConstants.TALKATIVE) || (verbose == GraphConstants.V_TALKATIVE)) + { return "Edge(" + ident + ")"; + } return ""; } diff --git a/src/java/org/apache/commons/graph/Graph.java b/src/java/org/apache/commons/graph/Graph.java index b7feac8..24568e5 100644 --- a/src/java/org/apache/commons/graph/Graph.java +++ b/src/java/org/apache/commons/graph/Graph.java @@ -65,10 +65,16 @@ import org.apache.commons.graph.visitor.PrintVisitor; /** * Describes a generic graph G = (V, E), i.e. a set of vertices and edges. * - * @version $Id: Graph.java,v 1.2 2001/11/29 14:17:33 jvanzyl Exp $ + * @version $Id: Graph.java,v 1.3 2001/12/02 18:07:18 jvanzyl Exp $ * @author M. Dahm */ -public class Graph implements Cloneable, Constants, Serializable { +public class Graph implements Cloneable, Serializable { + + /** + * Debugging flag + */ + private boolean debug = true; + private boolean directed = true; /* Map Vertex to VertexWrapper and Edge to EdgeWrapper, @@ -146,8 +152,15 @@ public class Graph implements Cloneable, Constants, Serializable { */ public void addVertex(Vertex v) { if(v == null) + { throw new GraphError("Vertex must not be null"); + } + if (debug) + { + System.out.println("Adding vertex: " + v); + } + vmap.put(v, new VertexWrapper(v)); } @@ -173,13 +186,18 @@ public class Graph implements Cloneable, Constants, Serializable { VertexWrapper vw = getWrapper(v); if(e == null) + { throw new GraphError("Edge must not be null"); + } emap.put(e, new EdgeWrapper(e, u, v)); uw.addEdge(e); - if(!directed) // Add edge to the other side, too - vw.addEdge(e); + if(!directed) + { + // Add edge to the other side, too + vw.addEdge(e); + } vw.addPredecessorEdge(e); } @@ -233,6 +251,15 @@ public class Graph implements Cloneable, Constants, Serializable { vw.removeEdge(e); } } + + /** + * Reset the graph so that it can be used over again. + */ + public void reset() + { + vmap.clear(); + emap.clear(); + } /** * Get source vertex of edge. Order between source and target doesn't @@ -509,20 +536,20 @@ public class Graph implements Cloneable, Constants, Serializable { } public String toString() { - return toString(PLAIN); + return toString(GraphConstants.PLAIN); } /** * @return graph contents traversed with DFS */ public String toString(int verbose) { - if(verbose == PLAIN) + if(verbose == GraphConstants.PLAIN) return printArray(getVertexArray()); else { ByteArrayOutputStream bos = new ByteArrayOutputStream(); PrintWriter out = new PrintWriter(bos); - new DFS(new PrintVisitor(out, VERBOSE)).start(this); + new DFS(new PrintVisitor(out, GraphConstants.VERBOSE)).start(this); out.close(); return bos.toString(); diff --git a/src/java/org/apache/commons/graph/GraphAlgorithms.java b/src/java/org/apache/commons/graph/GraphAlgorithms.java index 336e96d..a93b44a 100644 --- a/src/java/org/apache/commons/graph/GraphAlgorithms.java +++ b/src/java/org/apache/commons/graph/GraphAlgorithms.java @@ -59,10 +59,11 @@ import java.util.*; /** * Collection of graph algorithms such as transposeGraph. * - * @version $Id: GraphAlgorithms.java,v 1.1 2001/11/12 16:05:18 jvanzyl Exp $ + * @version $Id: GraphAlgorithms.java,v 1.2 2001/12/02 18:07:18 jvanzyl Exp $ * @author M. Dahm */ -public abstract class GraphAlgorithms implements Constants { +public abstract class GraphAlgorithms +{ /** * Compute the inverse of a graph, i.e. with all edges reverted */ diff --git a/src/java/org/apache/commons/graph/Constants.java b/src/java/org/apache/commons/graph/GraphConstants.java similarity index 95% rename from src/java/org/apache/commons/graph/Constants.java rename to src/java/org/apache/commons/graph/GraphConstants.java index 43622d3..c6284b7 100644 --- a/src/java/org/apache/commons/graph/Constants.java +++ b/src/java/org/apache/commons/graph/GraphConstants.java @@ -55,13 +55,14 @@ package org.apache.commons.graph; */ /** - * Constants useful for graph algorithms. + * GraphConstants useful for graph algorithms. * - * @version $Id: Constants.java,v 1.1 2001/11/12 16:05:17 jvanzyl Exp $ + * @version $Id: GraphConstants.java,v 1.1 2001/12/02 18:07:18 jvanzyl Exp $ * @author M. Dahm */ -public interface Constants { +public interface GraphConstants +{ public static final int WHITE = 0; public static final int GRAY = 1; public static final int BLACK = 2; diff --git a/src/java/org/apache/commons/graph/Sequential.java b/src/java/org/apache/commons/graph/Sequential.java index 7fefd6e..f85433a 100644 --- a/src/java/org/apache/commons/graph/Sequential.java +++ b/src/java/org/apache/commons/graph/Sequential.java @@ -59,10 +59,12 @@ import org.apache.commons.graph.visitor.Visitor; /** * Visit graph in sequential order, i.e. in the order returned by Graph.getVertices(). * - * @version $Id: Sequential.java,v 1.2 2001/11/29 14:17:33 jvanzyl Exp $ + * @version $Id: Sequential.java,v 1.3 2001/12/02 18:07:18 jvanzyl Exp $ * @author M. Dahm */ -public final class Sequential extends TraversalOrder { +public final class Sequential + extends TraversalOrder +{ /** * Depth first search algorithm. * @@ -88,7 +90,7 @@ public final class Sequential extends TraversalOrder { /* Initially mark all vertices as WHITE */ for(int i=0; i < size; i++) { - vertices[i].setColor(WHITE); + vertices[i].setColor(GraphConstants.WHITE); if(vertices[i] == start) index = i; } @@ -97,7 +99,7 @@ public final class Sequential extends TraversalOrder { Vertex v = vertices[index++ % size]; visitor.discoverVertex(v); - v.setColor(GRAY); + v.setColor(GraphConstants.GRAY); Edge[] edges = g.getEdgeArray(v); for(int j=0; j < edges.length; j++) { @@ -106,7 +108,7 @@ public final class Sequential extends TraversalOrder { } visitor.finishVertex(v); - v.setColor(BLACK); + v.setColor(GraphConstants.BLACK); } visitor.finishGraph(g); diff --git a/src/java/org/apache/commons/graph/TraversalOrder.java b/src/java/org/apache/commons/graph/TraversalOrder.java index df84061..2d26d03 100644 --- a/src/java/org/apache/commons/graph/TraversalOrder.java +++ b/src/java/org/apache/commons/graph/TraversalOrder.java @@ -63,13 +63,14 @@ import org.apache.commons.graph.visitor.Visitor; * * This relates to the "Strategy" design pattern. * - * @version $Id: TraversalOrder.java,v 1.2 2001/11/29 14:17:33 jvanzyl Exp $ + * @version $Id: TraversalOrder.java,v 1.3 2001/12/02 18:07:18 jvanzyl Exp $ * @author M. Dahm * @see DFS * @see BFS * @see Sequential */ -public abstract class TraversalOrder implements Constants { +public abstract class TraversalOrder +{ protected Visitor visitor; protected Graph graph; protected boolean stopped; diff --git a/src/java/org/apache/commons/graph/Vertex.java b/src/java/org/apache/commons/graph/Vertex.java index 9f0ed9e..dd4410d 100644 --- a/src/java/org/apache/commons/graph/Vertex.java +++ b/src/java/org/apache/commons/graph/Vertex.java @@ -54,15 +54,19 @@ package org.apache.commons.graph; * . */ +import java.io.Serializable; + import org.apache.commons.graph.visitor.Visitor; /** * Describes a vertex of a graph. * - * @version $Id: Vertex.java,v 1.2 2001/11/29 14:17:33 jvanzyl Exp $ + * @version $Id: Vertex.java,v 1.3 2001/12/02 18:07:18 jvanzyl Exp $ * @author M. Dahm */ -public class Vertex implements Cloneable, Constants, java.io.Serializable { +public class Vertex + implements Graphable,Cloneable,Serializable +{ private int ident; // unique number, i.e. identifier private static int counter; // produce default numbers @@ -95,28 +99,36 @@ public class Vertex implements Cloneable, Constants, java.io.Serializable { * @return String representation. */ public String toString() { - return toString(PLAIN); + return toString(GraphConstants.PLAIN); } - + + /** + * @return name to be used in output. + */ + public String getName() + { + return toString(); + } + /** * @param verbose toggle output format * @return String representation. */ public String toString(int verbose) { switch(verbose) { - case VERBOSE: case TALKATIVE: + case GraphConstants.VERBOSE: case GraphConstants.TALKATIVE: return "Vertex(" + ident + ", pred=" + ((pred == null)? "null" : ("" + pred.ident)) + ", discovery=" + dtime + ", finishing=" + ftime + ", distance=" + distance + ")"; - case V_VERBOSE: case V_TALKATIVE: + case GraphConstants.V_VERBOSE: case GraphConstants.V_TALKATIVE: return "Vertex(" + ident + ")\npred=" + ((pred == null)? "null" : ("" + pred.ident)) + "\ndiscovery=" + dtime + "\nfinishing=" + ftime + "\ndistance=" + distance; - case PLAIN: case V_PLAIN: default: + case GraphConstants.PLAIN: case GraphConstants.V_PLAIN: default: return "Vertex(" + ident + ")"; } } @@ -184,11 +196,4 @@ public class Vertex implements Cloneable, Constants, java.io.Serializable { Vertex v = (Vertex)o; return v.ident == ident; } - -// private void readObject(java.io.ObjectInputStream in) -// throws java.io.IOException, ClassNotFoundException -// { -// counter++; // Adjust counter, since a new object has been created -// in.defaultReadObject(); -// } } diff --git a/src/java/org/apache/commons/graph/WeightedEdge.java b/src/java/org/apache/commons/graph/WeightedEdge.java index 076c4d2..a51f9cc 100644 --- a/src/java/org/apache/commons/graph/WeightedEdge.java +++ b/src/java/org/apache/commons/graph/WeightedEdge.java @@ -57,10 +57,12 @@ package org.apache.commons.graph; /** * Describes an edge with a weight. * - * @version $Id: WeightedEdge.java,v 1.1 2001/11/12 16:05:20 jvanzyl Exp $ + * @version $Id: WeightedEdge.java,v 1.2 2001/12/02 18:07:18 jvanzyl Exp $ * @author M. Dahm */ -public class WeightedEdge extends Edge { +public class WeightedEdge + extends Edge +{ private int weight; /** @@ -76,7 +78,7 @@ public class WeightedEdge extends Edge { */ public String toString(int verbose) { switch(verbose) { - case TALKATIVE: case V_TALKATIVE: + case GraphConstants.TALKATIVE: case GraphConstants.V_TALKATIVE: return "WeightedEdge(" + getIdent() + "\nweight=" + weight + ")"; default: return "" + weight; diff --git a/src/java/org/apache/commons/graph/util/DependencyResolver.java b/src/java/org/apache/commons/graph/util/DependencyResolver.java new file mode 100644 index 0000000..e4ac537 --- /dev/null +++ b/src/java/org/apache/commons/graph/util/DependencyResolver.java @@ -0,0 +1,156 @@ +package org.apache.commons.graph.util; + +/** + * What is transitive closure? + * + * Consider a directed graph G=(V,E), where V is the set of vertices and E is the + * set of edges. The transitive closure of G is a graph G+ = (V,E+) such + * that for all v,w in V there is an edge (v,w) in E+ if and only if + * there is a non-null path from v to w in G. + */ + +// V = { a, b, c, d, e, f } +// E = { (a,b), (c,d), (e,f) } +// G = (V,E) + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.apache.commons.graph.DFS; +import org.apache.commons.graph.Graph; +import org.apache.commons.graph.Graphable; +import org.apache.commons.graph.LabeledVertex; +import org.apache.commons.graph.Vertex; +import org.apache.commons.graph.visitor.DependencyVisitor; + +public class DependencyResolver +{ + /** + * Graph of the entities for which the dependencies + * must be resolved. + */ + private Graph graph; + + private Map vertices; + + /** + * Default constructor + */ + public DependencyResolver() + { + // Create a directed graph. + graph = new Graph(true); + + // Create a map to collapse duplicate vertices. + // This should be handled in the graph package but + // I will take care of it here for now. + vertices = new HashMap(); + } + + /** + * Return a list of sorted dependencies given a starting + * vertex. + * + * @param g Starting vertex in the form of a Graphable object. + * @return A list of Graphable objects in sorted dependency order. + */ + public List getSortedDependencies(Graphable g) + { + // Create the DFS + DependencyVisitor visitor = new DependencyVisitor(); + DFS dfs = new DFS(visitor); + dfs.start(graph,(Vertex)g); + return visitor.getSortedDependencies(); + } + + /** + * Return a list of sorted dependencies given a starting + * vertex. + * + * @param g Starting vertex in the form of a String object. + * @return A list of Strings in sorted dependency order. + */ + public List getSortedDependencies(String g) + { + List l = getSortedDependencies(new LabeledVertex(g)); + ArrayList sl = new ArrayList(); + + for (Iterator i = l.iterator(); i.hasNext();) + { + sl.add(((Graphable)i.next()).getName()); + } + return sl; + } + + /** + * Remove all the vertices and edges from the graph. + */ + public void reset() + { + graph.reset(); + } + + /** + * Return a String representation of all the vertices + * present in the graph. + * + * @return String representation of the vertices in the graph. + */ + public String getVerticesString() + { + Vertex[] va = graph.getVertexArray(); + StringBuffer sb = new StringBuffer(); + + for (int i = 0; i < va.length; i++) + { + sb.append(va[i].toString()); + } + + return sb.toString(); + } + + /** + * Given a Graphable object which is our starting vertex + * and a list of dependencies, a List of Graphables, we + * will create the requisite graph. + * + * @param g The starting vertex + * @param dependencies List of Graphable dependencies + */ + public void addGraphable(String g, List dependencies) + { + LabeledVertex startingVertex = null; + + if (vertices.get(g) == null) + { + // Create a labeled vertex with our starting vertex g. + startingVertex = new LabeledVertex(g); + vertices.put(g, startingVertex); + graph.addVertex(startingVertex); + } + + for (Iterator i = dependencies.iterator(); i.hasNext();) + { + // Create a vertex and add to the graph. + String dependencyName = (String) i.next(); + + // Look to see if this vertex is already contained in + // the graph and only add it if it isn't. We need to + // add some code to the graph object to deal with this + // automatically. + if (vertices.get(dependencyName) == null) + { + LabeledVertex dependency = new LabeledVertex(dependencyName); + vertices.put(dependencyName, dependency); + graph.addVertex(dependency); + + // Create an edge between the starting vertex and + // the dependency. + graph.addEdge(startingVertex, dependency); + } + } + } +} diff --git a/src/java/org/apache/commons/graph/visitor/BFSVisitor.java b/src/java/org/apache/commons/graph/visitor/BFSVisitor.java index 2549b05..df98b63 100644 --- a/src/java/org/apache/commons/graph/visitor/BFSVisitor.java +++ b/src/java/org/apache/commons/graph/visitor/BFSVisitor.java @@ -55,7 +55,7 @@ package org.apache.commons.graph.visitor; */ import org.apache.commons.graph.BFS; -import org.apache.commons.graph.Constants; +import org.apache.commons.graph.GraphConstants; import org.apache.commons.graph.Edge; import org.apache.commons.graph.Graph; import org.apache.commons.graph.Vertex; @@ -65,11 +65,11 @@ import org.apache.commons.graph.VStack; * Visit graph with BFS and compute predecessors during traversal as * well as the "distance" to the source node (number of edges in between). * - * @version $Id: BFSVisitor.java,v 1.1 2001/11/29 14:17:34 jvanzyl Exp $ + * @version $Id: BFSVisitor.java,v 1.2 2001/12/02 18:07:18 jvanzyl Exp $ * @author M. Dahm * @see BFS */ -public class BFSVisitor extends DefaultVisitor implements Constants { +public class BFSVisitor extends DefaultVisitor implements GraphConstants { private VStack stack; // Stack to remember predecessors public BFSVisitor() {} diff --git a/src/java/org/apache/commons/graph/visitor/DependencyVisitor.java b/src/java/org/apache/commons/graph/visitor/DependencyVisitor.java new file mode 100644 index 0000000..f236fc9 --- /dev/null +++ b/src/java/org/apache/commons/graph/visitor/DependencyVisitor.java @@ -0,0 +1,101 @@ +package org.apache.commons.graph.visitor; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.graph.Vertex; + +/** + * Visit graph with DFS and compute predecessors during traversal as + * well as discovery and finishing time of all vertices. Instances of + * this class (and of course its descendants) may be passed to a DFS + * object. + * + * @version $Id: DependencyVisitor.java,v 1.1 2001/12/02 18:07:18 jvanzyl Exp $ + * @author M. Dahm + * @see DFS + */ +public class DependencyVisitor + extends DFSVisitor +{ + /** + * Dependencies in sorted order. The order in which + * the vertices are finished is the order in which + * they must be processed by the mechanism using + * the dependency list. + */ + List sortedDependencies; + + /** + * Default constructor. + */ + public DependencyVisitor() + { + sortedDependencies = new ArrayList(); + } + + public void finishVertex(Vertex v) + { + super.finishVertex(v); + sortedDependencies.add(v); + } + + public List getSortedDependencies() + { + return sortedDependencies; + } +} diff --git a/src/java/org/apache/commons/graph/visitor/PrintVisitor.java b/src/java/org/apache/commons/graph/visitor/PrintVisitor.java index 1b00949..9050f21 100644 --- a/src/java/org/apache/commons/graph/visitor/PrintVisitor.java +++ b/src/java/org/apache/commons/graph/visitor/PrintVisitor.java @@ -66,7 +66,7 @@ import org.apache.commons.graph.Vertex; * vertices and edges as they are discovered. May be used with DFS, BFS, * Sequential or any other visitor. Uses DFS by default. * - * @version $Id: PrintVisitor.java,v 1.1 2001/11/29 14:17:34 jvanzyl Exp $ + * @version $Id: PrintVisitor.java,v 1.2 2001/12/02 18:07:18 jvanzyl Exp $ * @author M. Dahm */ public class PrintVisitor implements Visitor { @@ -78,7 +78,7 @@ public class PrintVisitor implements Visitor { * * @param o stream to print to * @param v toggle verbosity of output - * @see Constants + * @see GraphConstants */ public PrintVisitor(PrintWriter o, int v) { out = o; diff --git a/src/java/org/apache/commons/graph/visualize/DaVinciVisualizer.java b/src/java/org/apache/commons/graph/visualize/DaVinciVisualizer.java index e94568d..fbb90dd 100644 --- a/src/java/org/apache/commons/graph/visualize/DaVinciVisualizer.java +++ b/src/java/org/apache/commons/graph/visualize/DaVinciVisualizer.java @@ -56,7 +56,7 @@ package org.apache.commons.graph.visualize; import java.io.OutputStream; -import org.apache.commons.graph.Constants; +import org.apache.commons.graph.GraphConstants; import org.apache.commons.graph.Edge; import org.apache.commons.graph.Graph; import org.apache.commons.graph.Sequential; @@ -70,10 +70,10 @@ import org.apache.commons.graph.Vertex; * * Traverses graph with the Sequential visitor, since it uses invariants of that algorithm. * - * @version $Id: DaVinciVisualizer.java,v 1.1 2001/11/29 14:24:23 jvanzyl Exp $ + * @version $Id: DaVinciVisualizer.java,v 1.2 2001/12/02 18:07:18 jvanzyl Exp $ * @author M. Dahm */ -public class DaVinciVisualizer extends GraphVisualizer implements Constants { +public class DaVinciVisualizer extends GraphVisualizer implements GraphConstants { private Graph graph; private int no_edges, edges; private int no_vertices, vertices; diff --git a/src/java/org/apache/commons/graph/visualize/GMLVisualizer.java b/src/java/org/apache/commons/graph/visualize/GMLVisualizer.java index acc5944..e761a04 100644 --- a/src/java/org/apache/commons/graph/visualize/GMLVisualizer.java +++ b/src/java/org/apache/commons/graph/visualize/GMLVisualizer.java @@ -56,7 +56,7 @@ package org.apache.commons.graph.visualize; import java.io.OutputStream; -import org.apache.commons.graph.Constants; +import org.apache.commons.graph.GraphConstants; import org.apache.commons.graph.DFS; import org.apache.commons.graph.Edge; import org.apache.commons.graph.Graph; @@ -66,7 +66,7 @@ import org.apache.commons.graph.Vertex; * Visualizes graphs into the GML * format. * - * @version $Id: GMLVisualizer.java,v 1.1 2001/11/29 14:24:23 jvanzyl Exp $ + * @version $Id: GMLVisualizer.java,v 1.2 2001/12/02 18:07:18 jvanzyl Exp $ * @author M. Dahm */ public class GMLVisualizer extends GraphVisualizer { diff --git a/src/java/org/apache/commons/graph/visualize/GraphMLVisualizer.java b/src/java/org/apache/commons/graph/visualize/GraphMLVisualizer.java index 3e3a520..897ddd6 100644 --- a/src/java/org/apache/commons/graph/visualize/GraphMLVisualizer.java +++ b/src/java/org/apache/commons/graph/visualize/GraphMLVisualizer.java @@ -56,7 +56,7 @@ package org.apache.commons.graph.visualize; import java.io.OutputStream; -import org.apache.commons.graph.Constants; +import org.apache.commons.graph.GraphConstants; import org.apache.commons.graph.DFS; import org.apache.commons.graph.Edge; import org.apache.commons.graph.Graph; @@ -66,7 +66,7 @@ import org.apache.commons.graph.Vertex; * Visualizes graphs into the GML * format. * - * @version $Id: GraphMLVisualizer.java,v 1.1 2001/11/29 21:12:40 jvanzyl Exp $ + * @version $Id: GraphMLVisualizer.java,v 1.2 2001/12/02 18:07:18 jvanzyl Exp $ * @author Jason van Zyl */ public class GraphMLVisualizer @@ -100,15 +100,15 @@ public class GraphMLVisualizer public void discoverVertex(Vertex v) { - println(0, ""); + println(0, ""); } public void finishVertex(Vertex v) {} public void discoverEdge(Edge e) { - int src = graph.getSource(e).getIdent(); - int target = graph.getTarget(e).getIdent(); + String src = graph.getSource(e).toString(); + String target = graph.getTarget(e).toString(); println(0, ""); } diff --git a/src/java/org/apache/commons/graph/visualize/GraphVisualizer.java b/src/java/org/apache/commons/graph/visualize/GraphVisualizer.java index 7bcb6d2..052e57c 100644 --- a/src/java/org/apache/commons/graph/visualize/GraphVisualizer.java +++ b/src/java/org/apache/commons/graph/visualize/GraphVisualizer.java @@ -56,7 +56,7 @@ package org.apache.commons.graph.visualize; import java.io.*; import java.util.StringTokenizer; -import org.apache.commons.graph.Constants; +import org.apache.commons.graph.GraphConstants; import org.apache.commons.graph.Edge; import org.apache.commons.graph.Graph; import org.apache.commons.graph.Vertex; @@ -73,7 +73,7 @@ import org.apache.commons.graph.visitor.Visitor; * By default graphs are dumped in the native Java format, i.e. by using the * Serialization feature. * - * @version $Id: GraphVisualizer.java,v 1.1 2001/11/29 14:24:23 jvanzyl Exp $ + * @version $Id: GraphVisualizer.java,v 1.2 2001/12/02 18:07:18 jvanzyl Exp $ * @author M. Dahm * @see DaVinciVisualizer * @see GMLVisualizer diff --git a/src/java/org/apache/commons/graph/visualize/VCGVisualizer.java b/src/java/org/apache/commons/graph/visualize/VCGVisualizer.java index c37fdcc..2372d45 100644 --- a/src/java/org/apache/commons/graph/visualize/VCGVisualizer.java +++ b/src/java/org/apache/commons/graph/visualize/VCGVisualizer.java @@ -55,7 +55,7 @@ package org.apache.commons.graph.visualize; */ import java.io.OutputStream; -import org.apache.commons.graph.Constants; +import org.apache.commons.graph.GraphConstants; import org.apache.commons.graph.DFS; import org.apache.commons.graph.Edge; import org.apache.commons.graph.Graph; @@ -66,7 +66,7 @@ import org.apache.commons.graph.Vertex; * HREF="http://www.cs.uni-sb.de/RW/users/sander/html/gsvcg1.html">VCG * format. * - * @version $Id: VCGVisualizer.java,v 1.1 2001/11/29 14:24:23 jvanzyl Exp $ + * @version $Id: VCGVisualizer.java,v 1.2 2001/12/02 18:07:18 jvanzyl Exp $ * @author M. Dahm */ public class VCGVisualizer extends GraphVisualizer { diff --git a/src/test/org/apache/commons/graph/util/TestDependencyResolver.java b/src/test/org/apache/commons/graph/util/TestDependencyResolver.java new file mode 100644 index 0000000..6f24e63 --- /dev/null +++ b/src/test/org/apache/commons/graph/util/TestDependencyResolver.java @@ -0,0 +1,200 @@ +package org.apache.commons.graph.util; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.StringTokenizer; + +/** + * @author Jason van Zyl + * @version $Id: TestDependencyResolver.java,v 1.1 2001/12/02 18:07:19 jvanzyl Exp $ + */ +public class TestDependencyResolver + extends TestCase +{ + private DependencyResolver d; + + public TestDependencyResolver(String testName) + { + super(testName); + } + + public static Test suite() + { + return new TestSuite(TestDependencyResolver.class); + } + + public void setUp() + { + d = new DependencyResolver(); + } + + /* + public void testCookieList() + { + String compare = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + + try + { + addAlphabetProjects(d); + } + catch(Exception e) + { + fail(); + } + } + */ + + /* + public void testReset() + { + String compare = ""; + + try + { + addAlphabetProjects(d); + d.reset(); + assertEquals(compare,getList(d.getSortedDependencies(""))); + } + catch(Exception e) + { + fail(); + } + } + */ + + public void testSingleProjectDependency() + { + // tests the engine with + // + // A B C + // ^ ^ ^\ + // \/ \/ | + // D <-E | + // ^ / + // \ / + // F <- + + String compare = "ABD"; + + try + { + d.reset(); + d.addGraphable("A", deps(null)); + d.addGraphable("B", deps(null)); + d.addGraphable("C", deps("F")); + d.addGraphable("D", deps("A,B")); + d.addGraphable("E", deps("B,C,D")); + d.addGraphable("F", deps("D")); + + System.out.println(">>> " + d.getVerticesString()); + + // Get the dependencies where we exclude the + // specified target. + assertEquals(compare,getList(d.getSortedDependencies("F"))); + + } + catch( Exception e ) + { + fail(); + } + } + + /* + public void testMultiProjectDependency() + { + String compare = "12BCDA3"; + + try + { + d.reset(); + d.addGraphable("A", deps("B,C,D")); + d.addGraphable("B", deps("1,2")); + d.addGraphable("C", deps(null)); + d.addGraphable("D", deps(null)); + d.addGraphable("1", deps(null)); + d.addGraphable("2", deps(null)); + d.addGraphable("3", deps("C")); + + ArrayList projects = new ArrayList(); + projects.add("A"); + projects.add("3"); + + // We do not want to exclude the target. This is simulating + // maven where all dependencies are built including the + // target package. + assertEquals(compare,getList(d.getSortedDependencies(""))); + + } + catch( Exception e ) + { + fail(); + } + } + */ + + private void addAlphabetProjects(DependencyResolver d) + throws Exception + { + d.addGraphable( "Z", deps("Y")); + d.addGraphable( "Y", deps("X")); + d.addGraphable( "X", deps("W")); + d.addGraphable( "W", deps("V")); + d.addGraphable( "V", deps("U")); + d.addGraphable( "U", deps("T")); + d.addGraphable( "T", deps("S")); + d.addGraphable( "S", deps("R")); + d.addGraphable( "R", deps("Q")); + d.addGraphable( "Q", deps("P")); + d.addGraphable( "P", deps("O")); + d.addGraphable( "O", deps("N")); + d.addGraphable( "N", deps("M")); + d.addGraphable( "M", deps("L")); + d.addGraphable( "L", deps("K")); + d.addGraphable( "K", deps("J")); + d.addGraphable( "J", deps("I")); + d.addGraphable( "I", deps("H")); + d.addGraphable( "H", deps("G")); + d.addGraphable( "G", deps("F")); + d.addGraphable( "F", deps("E")); + d.addGraphable( "E", deps("D")); + d.addGraphable( "D", deps("C")); + d.addGraphable( "C", deps("B")); + d.addGraphable( "B", deps("A")); + d.addGraphable( "A", deps(null)); + } + + private String getList(List list) + throws Exception + { + StringBuffer sb = new StringBuffer(); + Iterator i = list.iterator(); + while(i.hasNext()) + { + String item = (String) i.next(); + sb.append(item); + } + + return sb.toString(); + } + + private List deps(String project) + { + ArrayList deps = new ArrayList(); + + if (project != null) + { + StringTokenizer st = new StringTokenizer(project, ","); + + while(st.hasMoreTokens()) + { + deps.add(st.nextToken()); + } + } + + return deps; + } +}