. Removing the "implements Constants" as it is a bad pattern. Interfaces
should represent types. It also makes the UML diagrams very hard
to follow. We're just going to use the fully qualified GraphConstants.{x}
idiom.
. Added the Graphable interface to allow any arbitrary object to be
manipulated like a vertex in a graph.
. Added a util package that has a dependency resolver that uses a depth first
search to sort the dependencies for a set of objects that implement
the Graphable interface. The resolver also works with Strings and
lists and deps stated as lists of strings so I can resuse the test
I wrote for the DependencyEngine in jjar.
PR:
Obtained from:
Submitted by:
Reviewed by:
git-svn-id: https://svn.apache.org/repos/asf/jakarta/commons/sandbox/graph/trunk@144586 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
1 parent
41f1622c83
commit
f3a7176baf
21 files changed
+590
-79
No files matched your search
+1
-1
@@ -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
|
||||
|
||||
|
||||
@@ -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 <A HREF="http://www.inf.fu-berlin.de/~dahm">M. Dahm</A>
|
||||
*/
|
||||
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);
|
||||
|
||||
@@ -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 <A HREF="http://www.inf.fu-berlin.de/~dahm">M. Dahm</A>
|
||||
*/
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -54,18 +54,31 @@ package org.apache.commons.graph;
|
||||
* <http://www.apache.org/>.
|
||||
*/
|
||||
|
||||
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 <A HREF="http://www.inf.fu-berlin.de/~dahm">M. Dahm</A>
|
||||
*/
|
||||
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 "";
|
||||
}
|
||||
|
||||
@@ -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 <A HREF="http://www.inf.fu-berlin.de/~dahm">M. Dahm</A>
|
||||
*/
|
||||
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();
|
||||
|
||||
@@ -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 <A HREF="http://www.inf.fu-berlin.de/~dahm">M. Dahm</A>
|
||||
*/
|
||||
public abstract class GraphAlgorithms implements Constants {
|
||||
public abstract class GraphAlgorithms
|
||||
{
|
||||
/**
|
||||
* Compute the inverse of a graph, i.e. with all edges reverted
|
||||
*/
|
||||
|
||||
+4
-3
@@ -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 <A HREF="http://www.inf.fu-berlin.de/~dahm">M. Dahm</A>
|
||||
*/
|
||||
|
||||
public interface Constants {
|
||||
public interface GraphConstants
|
||||
{
|
||||
public static final int WHITE = 0;
|
||||
public static final int GRAY = 1;
|
||||
public static final int BLACK = 2;
|
||||
@@ -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 <A HREF="http://www.inf.fu-berlin.de/~dahm">M. Dahm</A>
|
||||
*/
|
||||
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);
|
||||
|
||||
@@ -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 <A HREF="http://www.inf.fu-berlin.de/~dahm">M. Dahm</A>
|
||||
* @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;
|
||||
|
||||
@@ -54,15 +54,19 @@ package org.apache.commons.graph;
|
||||
* <http://www.apache.org/>.
|
||||
*/
|
||||
|
||||
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 <A HREF="http://www.inf.fu-berlin.de/~dahm">M. Dahm</A>
|
||||
*/
|
||||
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();
|
||||
// }
|
||||
}
|
||||
@@ -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 <A HREF="http://www.inf.fu-berlin.de/~dahm">M. Dahm</A>
|
||||
*/
|
||||
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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 <A HREF="http://www.inf.fu-berlin.de/~dahm">M. Dahm</A>
|
||||
* @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() {}
|
||||
|
||||
@@ -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
|
||||
* <http://www.apache.org/>.
|
||||
*/
|
||||
|
||||
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 <A HREF="http://www.inf.fu-berlin.de/~dahm">M. Dahm</A>
|
||||
* @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;
|
||||
}
|
||||
}
|
||||
@@ -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 <A HREF="http://www.inf.fu-berlin.de/~dahm">M. Dahm</A>
|
||||
*/
|
||||
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;
|
||||
|
||||
@@ -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 <A HREF="http://www.inf.fu-berlin.de/~dahm">M. Dahm</A>
|
||||
*/
|
||||
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;
|
||||
|
||||
@@ -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 <A HREF="http://www.fmi.uni-passau.de/Graphlet/">GML</A>
|
||||
* 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 <A HREF="http://www.inf.fu-berlin.de/~dahm">M. Dahm</A>
|
||||
*/
|
||||
public class GMLVisualizer extends GraphVisualizer {
|
||||
|
||||
@@ -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 <A HREF="http://www.fmi.uni-passau.de/Graphlet/">GML</A>
|
||||
* 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 <a href="mailto:jvanzyl@zenplex.com">Jason van Zyl</a>
|
||||
*/
|
||||
public class GraphMLVisualizer
|
||||
@@ -100,15 +100,15 @@ public class GraphMLVisualizer
|
||||
|
||||
public void discoverVertex(Vertex v)
|
||||
{
|
||||
println(0, "<node name=\"" + v.getIdent() + "\"/>");
|
||||
println(0, "<node name=\"" + v + "\"/>");
|
||||
}
|
||||
|
||||
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, "<edge source=\"" + src + "\" target=\"" + target + "\"/>");
|
||||
}
|
||||
|
||||
@@ -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 <A HREF="http://www.inf.fu-berlin.de/~dahm">M. Dahm</A>
|
||||
* @see DaVinciVisualizer
|
||||
* @see GMLVisualizer
|
||||
|
||||
@@ -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</A>
|
||||
* 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 <A HREF="http://www.inf.fu-berlin.de/~dahm">M. Dahm</A>
|
||||
*/
|
||||
public class VCGVisualizer extends GraphVisualizer {
|
||||
|
||||
@@ -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 <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
|
||||
* @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;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user