diff --git a/.cvsignore b/.cvsignore new file mode 100644 index 0000000..c027565 --- /dev/null +++ b/.cvsignore @@ -0,0 +1,4 @@ +target +test-reports +*~ +velocity.log* diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..cbe4f26 --- /dev/null +++ b/LICENSE @@ -0,0 +1,54 @@ +/* + * 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 acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Commons", and "Apache Software + * Foundation" 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" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * 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 + * . + */ + diff --git a/build.xml b/build.xml new file mode 100644 index 0000000..67718ba --- /dev/null +++ b/build.xml @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/project.xml b/project.xml new file mode 100644 index 0000000..4c43321 --- /dev/null +++ b/project.xml @@ -0,0 +1,101 @@ + + + + jakarta-commons-graph + graph + 0.1 + Apache Software Foundation + 2001 + org.apache.commons.graph + + Graph Manipulation Tools + + Jakarta Graph is an API which assists in dealing with Graphs, + and graph based structures. It is currently Sandboxed meaning + special care must be taken in usage of it. + + + http://jakarta.apache.org/commons/graph/ + + http://cvs.apache.org/viewcvs/jakarta-commons-sandbox/graph + + jakarta.apache.org + /www/jakarta.apache.org/commons/graph/ + + + + David Dixon-Peugh + dpeugh + dpeugh@mindspring.com + Ultra*Log Project + + + + Jason van Zyl + jvanzyl + jason@zenplex.com + Zenplex + + + + + + jakarta-commons-collection + required + 1.0 + commons-collections.jar + + + + nsuml + required + 1.0 + nsuml.jar + + + + nsuml + required + 1.0 + nsuml.jar + + + + log4j + required + 1.1.3 + log4j-1.1.3.jar + + + + + + src/java + + + + src/test + src/java + + + + + + + + exclude = **/*.class + + + + + + + + + + + + + + + diff --git a/src/java/org/apache/commons/graph/AcyclicGraph.java b/src/java/org/apache/commons/graph/AcyclicGraph.java new file mode 100644 index 0000000..abaef86 --- /dev/null +++ b/src/java/org/apache/commons/graph/AcyclicGraph.java @@ -0,0 +1,64 @@ +package org.apache.commons.graph; + +/* ==================================================================== + * 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 + * "Commons" 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", + * "Commons", 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 + * . + */ + +/** + * Description of the Interface + */ +public interface AcyclicGraph + extends Graph +{ + +} diff --git a/src/java/org/apache/commons/graph/DirectedAcyclicGraph.java b/src/java/org/apache/commons/graph/DirectedAcyclicGraph.java new file mode 100644 index 0000000..bf87c29 --- /dev/null +++ b/src/java/org/apache/commons/graph/DirectedAcyclicGraph.java @@ -0,0 +1,64 @@ +package org.apache.commons.graph; + +/* ==================================================================== + * 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 + * "Commons" 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", + * "Commons", 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 + * . + */ + +/** + * Description of the Interface + */ +public interface DirectedAcyclicGraph + extends Graph, AcyclicGraph +{ + +} diff --git a/src/java/org/apache/commons/graph/DirectedGraph.java b/src/java/org/apache/commons/graph/DirectedGraph.java new file mode 100644 index 0000000..f72a9ac --- /dev/null +++ b/src/java/org/apache/commons/graph/DirectedGraph.java @@ -0,0 +1,86 @@ +package org.apache.commons.graph; + +/* ==================================================================== + * 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 + * "Commons" 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", + * "Commons", 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.Set; + +/** + * Description of the Interface + */ +public interface DirectedGraph + extends Graph +{ + /** + * getInbound( Vertex ) Returns the set of edges which are inbound to the + * Vertex. + */ + public Set getInbound(Vertex v); + + /** + * getOutbound( Vertex ) Returns the set of edges which lead away from the + * Vertex. + */ + public Set getOutbound(Vertex v); + + /** + * getSource( Edge ) Returns the vertex which originates the edge. + */ + public Vertex getSource(Edge e); + + /** + * getTarget( Edge ) Returns the vertex which terminates the edge. + */ + public Vertex getTarget(Edge e); +} diff --git a/src/java/org/apache/commons/graph/Edge.java b/src/java/org/apache/commons/graph/Edge.java new file mode 100644 index 0000000..21abf9d --- /dev/null +++ b/src/java/org/apache/commons/graph/Edge.java @@ -0,0 +1,62 @@ +package org.apache.commons.graph; + +/* ==================================================================== + * 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 + * "Commons" 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", + * "Commons", 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 + * . + */ + +/** + * Description of the Interface + */ +public interface Edge +{ +} diff --git a/src/java/org/apache/commons/graph/Graph.java b/src/java/org/apache/commons/graph/Graph.java new file mode 100644 index 0000000..b75880d --- /dev/null +++ b/src/java/org/apache/commons/graph/Graph.java @@ -0,0 +1,91 @@ +package org.apache.commons.graph; + +/* ==================================================================== + * 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 + * "Commons" 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", + * "Commons", 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 + * . + */ +/** + * Graph This is the basic interface for a graph. G = { v, e } + * getAdjacentVertices and getAdjacentEdges helps to define the behavior of + * Edges. + */ + +import java.util.Set; + +/** + * Description of the Interface + */ +public interface Graph +{ + /** + * getVertices - Returns the total set of Vertices in the graph. + */ + public Set getVertices(); + + /** + * getEdges - Returns the total set of Edges in the graph. + */ + public Set getEdges(); + + /** + * getEdges( Vertex ) - This method will return all edges which touch this + * vertex. + */ + public Set getEdges(Vertex v); + + /** + * getVertices( Edge ) - This method will return the set of Verticies on + * this Edge. (2 for normal edges, > 2 for HyperEdges.) + */ + public Set getVertices(Edge e); +} + diff --git a/src/java/org/apache/commons/graph/MutableDirectedGraph.java b/src/java/org/apache/commons/graph/MutableDirectedGraph.java new file mode 100644 index 0000000..110af72 --- /dev/null +++ b/src/java/org/apache/commons/graph/MutableDirectedGraph.java @@ -0,0 +1,90 @@ +package org.apache.commons.graph; + +/* ==================================================================== + * 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 + * "Commons" 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", + * "Commons", 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 org.apache.commons.graph.exception.*; + +/** + * Description of the Interface + */ +public interface MutableDirectedGraph + extends DirectedGraph +{ + /** + * Adds a feature to the Vertex attribute of the MutableDirectedGraph object + */ + public void addVertex(Vertex v) + throws GraphException; + + /** + * Adds a feature to the Edge attribute of the MutableDirectedGraph object + */ + public void addEdge(Edge e, + Vertex source, + Vertex target) + throws GraphException; + + /** + * Description of the Method + */ + public void removeVertex(Vertex v) + throws GraphException; + + /** + * Description of the Method + */ + public void removeEdge(Edge e) + throws GraphException; +} diff --git a/src/java/org/apache/commons/graph/MutableGraph.java b/src/java/org/apache/commons/graph/MutableGraph.java new file mode 100644 index 0000000..e395f4f --- /dev/null +++ b/src/java/org/apache/commons/graph/MutableGraph.java @@ -0,0 +1,100 @@ +package org.apache.commons.graph; + +/* ==================================================================== + * 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 + * "Commons" 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", + * "Commons", 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 org.apache.commons.graph.exception.*; + +/** + * Description of the Interface + */ +public interface MutableGraph + extends Graph +{ + /** + * Adds a feature to the Vertex attribute of the MutableGraph object + */ + public void addVertex(Vertex v) + throws GraphException; + + /** + * Description of the Method + */ + public void removeVertex(Vertex v) + throws GraphException; + + /** + * Adds a feature to the Edge attribute of the MutableGraph object + */ + public void addEdge(Edge e) + throws GraphException; + + /** + * Description of the Method + */ + public void removeEdge(Edge e) + throws GraphException; + + /** + * Description of the Method + */ + public void connect(Edge e, Vertex v) + throws GraphException; + + /** + * Description of the Method + */ + public void disconnect(Edge e, Vertex v) + throws GraphException; +} diff --git a/src/java/org/apache/commons/graph/Named.java b/src/java/org/apache/commons/graph/Named.java new file mode 100644 index 0000000..e494297 --- /dev/null +++ b/src/java/org/apache/commons/graph/Named.java @@ -0,0 +1,12 @@ +package org.apache.commons.graph; + +/** + * Description of the Interface + */ +public interface Named +{ + /** + * Gets the name attribute of the Named object + */ + public String getName(); +} diff --git a/src/java/org/apache/commons/graph/Path.java b/src/java/org/apache/commons/graph/Path.java new file mode 100644 index 0000000..5c44ca5 --- /dev/null +++ b/src/java/org/apache/commons/graph/Path.java @@ -0,0 +1,87 @@ +package org.apache.commons.graph; + +/* ==================================================================== + * 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 + * "Commons" 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", + * "Commons", 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.List; + +/** + * Description of the Interface + */ +public interface Path +{ + /** + * Returns the start of the path. + */ + public Vertex getStart(); + + /** + * Returns the end of the path. + */ + public Vertex getEnd(); + + /** + * getVertices() - This returns a list of Vertices, in order as they go from + * Start to End. This includes the Start and End vertex, and will have one + * more entry than the Edges list. + */ + public List getVertices(); + + /** + * getEdges() - This returns a list of Edges which comprise the path. It + * will have one less than the list of Vertices. + */ + public List getEdges(); + +} diff --git a/src/java/org/apache/commons/graph/UndirectedGraph.java b/src/java/org/apache/commons/graph/UndirectedGraph.java new file mode 100644 index 0000000..a409e16 --- /dev/null +++ b/src/java/org/apache/commons/graph/UndirectedGraph.java @@ -0,0 +1,63 @@ +package org.apache.commons.graph; + +/* ==================================================================== + * 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 + * "Commons" 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", + * "Commons", 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 + * . + */ + +/** + * Description of the Interface + */ +public interface UndirectedGraph + extends Graph +{ +} diff --git a/src/java/org/apache/commons/graph/Vertex.java b/src/java/org/apache/commons/graph/Vertex.java new file mode 100644 index 0000000..3c211f2 --- /dev/null +++ b/src/java/org/apache/commons/graph/Vertex.java @@ -0,0 +1,62 @@ +package org.apache.commons.graph; + +/* ==================================================================== + * 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 + * "Commons" 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", + * "Commons", 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 + * . + */ + +/** + * Description of the Interface + */ +public interface Vertex +{ +} diff --git a/src/java/org/apache/commons/graph/WeightedEdge.java b/src/java/org/apache/commons/graph/WeightedEdge.java new file mode 100644 index 0000000..4b096e3 --- /dev/null +++ b/src/java/org/apache/commons/graph/WeightedEdge.java @@ -0,0 +1,67 @@ +package org.apache.commons.graph; + +/* ==================================================================== + * 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 + * "Commons" 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", + * "Commons", 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 + * . + */ + +/** + * Description of the Interface + */ +public interface WeightedEdge + extends Edge +{ + /** + * Gets the weight attribute of the WeightedEdge object + */ + public double getWeight(); +} diff --git a/src/java/org/apache/commons/graph/WeightedGraph.java b/src/java/org/apache/commons/graph/WeightedGraph.java new file mode 100644 index 0000000..70cfc76 --- /dev/null +++ b/src/java/org/apache/commons/graph/WeightedGraph.java @@ -0,0 +1,68 @@ +package org.apache.commons.graph; + +/* ==================================================================== + * 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 + * "Commons" 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", + * "Commons", 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.Comparator; + +/** + * Description of the Interface + */ +public interface WeightedGraph extends Graph +{ + /** + * Gets the weight attribute of the WeightedGraph object + */ + public double getWeight(Edge e); +} diff --git a/src/java/org/apache/commons/graph/WeightedPath.java b/src/java/org/apache/commons/graph/WeightedPath.java new file mode 100644 index 0000000..3d5fe37 --- /dev/null +++ b/src/java/org/apache/commons/graph/WeightedPath.java @@ -0,0 +1,67 @@ +package org.apache.commons.graph; + +/* ==================================================================== + * 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 + * "Commons" 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", + * "Commons", 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 + * . + */ + +/** + * Description of the Interface + */ +public interface WeightedPath + extends Path +{ + /** + * Gets the weight attribute of the WeightedPath object + */ + public double getWeight(); +} diff --git a/src/java/org/apache/commons/graph/contract/Acyclic.java b/src/java/org/apache/commons/graph/contract/Acyclic.java new file mode 100644 index 0000000..aff291d --- /dev/null +++ b/src/java/org/apache/commons/graph/contract/Acyclic.java @@ -0,0 +1,8 @@ +package org.apache.commons.graph.contract; + +/** + * Description of the Interface + */ +public interface Acyclic +{ +} diff --git a/src/java/org/apache/commons/graph/contract/AcyclicContract.java b/src/java/org/apache/commons/graph/contract/AcyclicContract.java new file mode 100644 index 0000000..12b7982 --- /dev/null +++ b/src/java/org/apache/commons/graph/contract/AcyclicContract.java @@ -0,0 +1,205 @@ +package org.apache.commons.graph.contract; + +/* ==================================================================== + * 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 + * "Commons" 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", + * "Commons", 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.Iterator; + +import org.apache.commons.graph.*; +import org.apache.commons.graph.search.*; +import org.apache.commons.graph.exception.*; +import org.apache.commons.graph.decorator.*; + +/** + * Description of the Class + */ +public class AcyclicContract + implements Contract +{ + private DDirectedGraph graph = null; + + /** + * Description of the Class + */ + public class CycleDetector + implements Visitor + { + private DFS dfs = null; + private boolean isCyclic = false; + private DirectedGraph graph = null; + + /** + * Constructor for the CycleDetector object + * + * @param graph + */ + public CycleDetector(DirectedGraph graph) + { + this.dfs = new DFS(); + this.graph = graph; + Iterator verts = graph.getVertices().iterator(); + + if (verts.hasNext()) + { + dfs.visit(graph, (Vertex) verts.next(), this); + } + } + + /** + * Description of the Method + */ + public void discoverGraph(Graph graph) { } + + /** + * Description of the Method + */ + public void discoverVertex(Vertex v) { } + + /** + * Description of the Method + */ + public void discoverEdge(Edge e) + { + if (dfs.getColor(graph.getTarget(e)) == DFS.GRAY) + { + this.isCyclic = true; + } + } + + /** + * Description of the Method + */ + public void finishEdge(Edge e) { } + + /** + * Description of the Method + */ + public void finishVertex(Vertex v) { } + + /** + * Description of the Method + */ + public void finishGraph(Graph graph) { } + + /** + * Description of the Method + */ + public boolean hasCycle() + { + return isCyclic; + } + } + + /** + * Constructor for the AcyclicContract object + */ + public AcyclicContract() { } + + /** + * Sets the impl attribute of the AcyclicContract object + */ + public void setImpl(DirectedGraph graph) + { + this.graph = DDirectedGraph.decorateGraph(graph); + } + + /** + * Gets the interface attribute of the AcyclicContract object + */ + public Class getInterface() + { + return org.apache.commons.graph.contract.Acyclic.class; + } + + /** + * Description of the Method + */ + public void verify() + throws CycleException + { + CycleDetector cd = new CycleDetector(graph); + if (cd.hasCycle()) + { + throw new CycleException("Cycle detected in Graph."); + } + } + + /** + * Adds a feature to the Vertex attribute of the AcyclicContract object + */ + public void addVertex(Vertex v) { } + + /** + * Adds a feature to the Edge attribute of the AcyclicContract object + */ + public void addEdge(Edge e, + Vertex start, + Vertex end) + throws GraphException + { + if (graph.hasConnection(end, start)) + { + throw new CycleException("Introducing edge will cause a Cycle."); + } + } + + /** + * Description of the Method + */ + public void removeVertex(Vertex v) { } + + /** + * Description of the Method + */ + public void removeEdge(Edge e) { } +} diff --git a/src/java/org/apache/commons/graph/contract/Contract.java b/src/java/org/apache/commons/graph/contract/Contract.java new file mode 100644 index 0000000..c19baa9 --- /dev/null +++ b/src/java/org/apache/commons/graph/contract/Contract.java @@ -0,0 +1,57 @@ +package org.apache.commons.graph.contract; + +import org.apache.commons.graph.*; +import org.apache.commons.graph.exception.*; + +/** + * Description of the Interface + */ +public interface Contract +{ + /** + * The impl that gets passed in is read-only. This is the representation of + * the graph you should work off of. If an edge or vertex addition is + * illegal to the contract, raise a GraphException with and explanation. + */ + public void setImpl(DirectedGraph impl); + + /** + * getInterface This returns the marker interface which is associated with + * the Contract. For instance, AcyclicContract will return AcyclicGraph + * here. + */ + public Class getInterface(); + + /** + * verify - This verifies that the graph it is working on complies. + */ + public void verify() + throws GraphException; + + /** + * Adds a feature to the Edge attribute of the Contract object + */ + public void addEdge(Edge e, + Vertex start, + Vertex end) + throws GraphException; + + /** + * Adds a feature to the Vertex attribute of the Contract object + */ + public void addVertex(Vertex v) + throws GraphException; + + /** + * Description of the Method + */ + public void removeEdge(Edge e) + throws GraphException; + + /** + * Description of the Method + */ + public void removeVertex(Vertex v) + throws GraphException; + +} diff --git a/src/java/org/apache/commons/graph/decorator/DDirectedGraph.java b/src/java/org/apache/commons/graph/decorator/DDirectedGraph.java new file mode 100644 index 0000000..8d73e97 --- /dev/null +++ b/src/java/org/apache/commons/graph/decorator/DDirectedGraph.java @@ -0,0 +1,224 @@ +package org.apache.commons.graph.decorator; + +/* ==================================================================== + * 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 + * "Commons" 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", + * "Commons", 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.Set; +import java.util.Map; +import java.util.HashSet; +import java.util.HashMap; +import java.util.Iterator; + +import org.apache.commons.graph.*; +import org.apache.commons.graph.impl.*; +import org.apache.commons.graph.exception.*; + +/** + * Description of the Class + */ +public class DDirectedGraph + extends DirectedGraphWrapper + implements DirectedGraph, + WeightedGraph +{ + private WeightedGraph weighted; + private Map weights = new HashMap();// EDGE X DOUBLE + private static Map decoratedGraphs = new HashMap();// DGRAPH X DDGRAPH + private AllPaths allPaths = null; + + /** + * Constructor for the DDirectedGraph object + * + * @param impl + */ + private DDirectedGraph(DirectedGraph impl) + { + super(impl); + + if (impl instanceof WeightedGraph) + { + weighted = (WeightedGraph) impl; + } + } + + /** + * Description of the Method + */ + public static DDirectedGraph decorateGraph(DirectedGraph graph) + { + if (graph instanceof DDirectedGraph) + { + return (DDirectedGraph) graph; + } + + if (decoratedGraphs.containsKey(graph)) + { + return (DDirectedGraph) decoratedGraphs.get(graph); + } + + DDirectedGraph RC = new DDirectedGraph(graph); + decoratedGraphs.put(graph, RC); + return RC; + } + + // WeightedGraph Implementation + /** + * Gets the weight attribute of the DDirectedGraph object + */ + public double getWeight(Edge e) + { + if (weighted != null) + { + return weighted.getWeight(e); + } + else + { + if (weights.containsKey(e)) + { + return ((Double) weights.get(e)).doubleValue(); + } + else + { + return 1.0; + } + } + } + + /** + * Sets the weight attribute of the DDirectedGraph object + */ + public void setWeight(Edge e, double value) + throws GraphException + { + if (weighted != null) + { + throw new GraphException("Unable to set weight."); + } + + weights.put(e, new Double(value)); + } + + /** + * Description of the Method + */ + public DirectedGraph transpose() + throws GraphException + { + try + { + DirectedGraphImpl RC = new DirectedGraphImpl(); + Set vertexSet = getVertices(); + Set edgeSet = getEdges(); + + Iterator vertices = vertexSet.iterator(); + while (vertices.hasNext()) + { + RC.addVertex((Vertex) vertices.next()); + } + + Iterator edges = edgeSet.iterator(); + while (edges.hasNext()) + { + Edge edge = (Edge) edges.next(); + + RC.addEdge(edge, + getTarget(edge), + getSource(edge)); + } + + return RC; + } + catch (GraphException e) + { + throw e; + } + catch (Exception e) + { + throw new GraphException(e); + } + } + + /** + * Description of the Method + */ + public boolean hasConnection(Vertex start, Vertex end) + throws GraphException + { + if (start == end) + { + return true; + } + + try + { + if (allPaths == null) + { + allPaths = new AllPaths(this); + } + else + { + allPaths.update(this); + } + + WeightedPath path = + allPaths.getShortestPath(start, end); + } + catch (GraphException ex) + { + return false; + } + + return true; + } + +} diff --git a/src/java/org/apache/commons/graph/dependency/Dependency.java b/src/java/org/apache/commons/graph/dependency/Dependency.java new file mode 100644 index 0000000..8f5e9d9 --- /dev/null +++ b/src/java/org/apache/commons/graph/dependency/Dependency.java @@ -0,0 +1,33 @@ +package org.apache.commons.graph.dependency; + +import org.apache.commons.graph.*; + +/** + * Description of the Class + */ +public class Dependency implements Edge +{ + private Object head = null; + private Object dep = null; + + /** + * Constructor for the Dependency object + * + * @param head + * @param dep + */ + public Dependency(Object head, + Object dep) + { + this.head = head; + this.dep = dep; + } + + /** + * Description of the Method + */ + public String description() + { + return head + " depends on " + dep; + } +} diff --git a/src/java/org/apache/commons/graph/dependency/DependencyGraph.java b/src/java/org/apache/commons/graph/dependency/DependencyGraph.java new file mode 100644 index 0000000..2a49bd6 --- /dev/null +++ b/src/java/org/apache/commons/graph/dependency/DependencyGraph.java @@ -0,0 +1,115 @@ +package org.apache.commons.graph.dependency; + +import org.apache.commons.graph.*; +import org.apache.commons.graph.impl.*; +import org.apache.commons.graph.contract.*; +import org.apache.commons.graph.exception.*; +import org.apache.commons.graph.dependency.exception.*; + +import java.util.Map; +import java.util.List; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Collection; + +/** + * Description of the Class + */ +public class DependencyGraph + extends DirectedGraphWrapper +{ + private GraphFactory factory = new GraphFactory(); + private AcyclicContract acyclic = new AcyclicContract(); + private DependencyVisitor visitor = new DependencyVisitor(); + + private Map vertices = new HashMap(); + + private MutableDirectedGraph DAG = null; + + /** + * Constructor for the DependencyGraph object + */ + public DependencyGraph() + { + super(); + init(); + } + + /** + * Description of the Method + */ + private void init() + { + Contract[] dagContracts = new Contract[1]; + dagContracts[0] = acyclic; + DAG = factory.makeMutableDirectedGraph(dagContracts, + false, + null); + setDirGraph(DAG); + } + + /** + * Adds a feature to the Dependencies attribute of the DependencyGraph + * object + */ + public void addDependencies(Object head, + Collection deps) + throws GraphException, + CircularDependencyException + { + DependencyVertex vHead = findVertex(head); + + if (!getVertices().contains(vHead)) + { + DAG.addVertex(vHead); + } + + try + { + Iterator v = deps.iterator(); + + while (v.hasNext()) + { + DependencyVertex vDep = findVertex(v.next()); + + if (!getVertices().contains(vDep)) + { + DAG.addVertex(vDep); + } + + DAG.addEdge(new Dependency(vHead.getValue(), + vDep.getValue()), + vHead, vDep); + } + } + catch (CycleException ex) + { + throw new CircularDependencyException(ex); + } + } + + /** + * Description of the Method + */ + public DependencyVertex findVertex(Object o) + { + if (vertices.containsKey(o)) + { + return (DependencyVertex) vertices.get(o); + } + else + { + DependencyVertex RC = new DependencyVertex(o); + vertices.put(o, RC); + return RC; + } + } + + /** + * Gets the sortedDependencies attribute of the DependencyGraph object + */ + public List getSortedDependencies(Object head) + { + return visitor.getSortedDependencies(this, findVertex(head)); + } +} diff --git a/src/java/org/apache/commons/graph/dependency/DependencyVertex.java b/src/java/org/apache/commons/graph/dependency/DependencyVertex.java new file mode 100644 index 0000000..facfdc5 --- /dev/null +++ b/src/java/org/apache/commons/graph/dependency/DependencyVertex.java @@ -0,0 +1,30 @@ +package org.apache.commons.graph.dependency; + +import org.apache.commons.graph.*; + +/** + * Description of the Class + */ +public class DependencyVertex + implements Vertex +{ + private Object value; + + /** + * Constructor for the DependencyVertex object + * + * @param value + */ + public DependencyVertex(Object value) + { + this.value = value; + } + + /** + * Gets the value attribute of the DependencyVertex object + */ + public Object getValue() + { + return value; + } +} diff --git a/src/java/org/apache/commons/graph/dependency/DependencyVisitor.java b/src/java/org/apache/commons/graph/dependency/DependencyVisitor.java new file mode 100644 index 0000000..86f6d46 --- /dev/null +++ b/src/java/org/apache/commons/graph/dependency/DependencyVisitor.java @@ -0,0 +1,76 @@ +package org.apache.commons.graph.dependency; + +import java.util.List; +import java.util.LinkedList; + +import org.apache.commons.graph.*; +import org.apache.commons.graph.search.*; + +/** + * Description of the Class + */ +public class DependencyVisitor + implements Visitor +{ + private List deps = null; + private DFS dfs = new DFS(); + + + /** + * Constructor for the DependencyVisitor object + */ + public DependencyVisitor() { } + + /** + * Description of the Method + */ + public void discoverGraph(Graph g) { } + + /** + * Description of the Method + */ + public void discoverVertex(Vertex v) { } + + /** + * Description of the Method + */ + public void discoverEdge(Edge e) { } + + /** + * Description of the Method + */ + public void finishGraph(Graph g) { } + + /** + * Description of the Method + */ + public void finishVertex(Vertex v) + { + if (v instanceof DependencyVertex) + { + deps.add(((DependencyVertex) v).getValue()); + } + else + { + deps.add(v); + } + } + + /** + * Description of the Method + */ + public void finishEdge(Edge e) { } + + /** + * Gets the sortedDependencies attribute of the DependencyVisitor object + */ + public synchronized List + getSortedDependencies(DependencyGraph dg, + Vertex root) + { + deps = new LinkedList(); + dfs.visit(dg, root, this); + return deps; + } +} + diff --git a/src/java/org/apache/commons/graph/dependency/exception/CircularDependencyException.java b/src/java/org/apache/commons/graph/dependency/exception/CircularDependencyException.java new file mode 100644 index 0000000..78a870a --- /dev/null +++ b/src/java/org/apache/commons/graph/dependency/exception/CircularDependencyException.java @@ -0,0 +1,38 @@ +package org.apache.commons.graph.dependency.exception; + +import org.apache.commons.graph.exception.*; + +/** + * Description of the Class + */ +public class CircularDependencyException + extends CycleException +{ + /** + * Constructor for the CircularDependencyException object + */ + public CircularDependencyException() + { + super(); + } + + /** + * Constructor for the CircularDependencyException object + * + * @param msg + */ + public CircularDependencyException(String msg) + { + super(msg); + } + + /** + * Constructor for the CircularDependencyException object + * + * @param cause + */ + public CircularDependencyException(Throwable cause) + { + super(cause); + } +} diff --git a/src/java/org/apache/commons/graph/exception/ContractVerificationException.java b/src/java/org/apache/commons/graph/exception/ContractVerificationException.java new file mode 100644 index 0000000..bd8d135 --- /dev/null +++ b/src/java/org/apache/commons/graph/exception/ContractVerificationException.java @@ -0,0 +1,35 @@ +package org.apache.commons.graph.exception; + +/** + * Description of the Class + */ +public class ContractVerificationException extends GraphException +{ + /** + * Constructor for the ContractVerificationException object + */ + public ContractVerificationException() + { + super(); + } + + /** + * Constructor for the ContractVerificationException object + * + * @param msg + */ + public ContractVerificationException(String msg) + { + super(msg); + } + + /** + * Constructor for the ContractVerificationException object + * + * @param cause + */ + public ContractVerificationException(Throwable cause) + { + super(cause); + } +} diff --git a/src/java/org/apache/commons/graph/exception/CycleException.java b/src/java/org/apache/commons/graph/exception/CycleException.java new file mode 100644 index 0000000..1b388e3 --- /dev/null +++ b/src/java/org/apache/commons/graph/exception/CycleException.java @@ -0,0 +1,88 @@ +package org.apache.commons.graph.exception; +/* ==================================================================== + * 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 + * "Commons" 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", + * "Commons", 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 + * . + */ + +/** + * Description of the Class + */ +public class CycleException extends GraphException +{ + /** + * Constructor for the CycleException object + */ + public CycleException() + { + super(); + } + + /** + * Constructor for the CycleException object + * + * @param msg + */ + public CycleException(String msg) + { + super(msg); + } + + /** + * Constructor for the CycleException object + * + * @param cause + */ + public CycleException(Throwable cause) + { + super(cause); + } +} diff --git a/src/java/org/apache/commons/graph/exception/GraphException.java b/src/java/org/apache/commons/graph/exception/GraphException.java new file mode 100644 index 0000000..c2f0a36 --- /dev/null +++ b/src/java/org/apache/commons/graph/exception/GraphException.java @@ -0,0 +1,93 @@ +package org.apache.commons.graph.exception; + +/* ==================================================================== + * 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 + * "Commons" 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", + * "Commons", 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 + * . + */ + +/** + * GraphException This is the superclass of all exceptions that can be thrown. + */ + +public class GraphException extends RuntimeException +{ + private Throwable cause = null; + + /** + * Constructor for the GraphException object + */ + public GraphException() + { + super(); + } + + /** + * Constructor for the GraphException object + * + * @param msg + */ + public GraphException(String msg) + { + super(msg); + } + + /** + * Constructor for the GraphException object + * + * @param cause + */ + public GraphException(Throwable cause) + { + super(cause.getMessage()); + this.cause = cause; + } +} diff --git a/src/java/org/apache/commons/graph/exception/NegativeCycleException.java b/src/java/org/apache/commons/graph/exception/NegativeCycleException.java new file mode 100644 index 0000000..4df0af4 --- /dev/null +++ b/src/java/org/apache/commons/graph/exception/NegativeCycleException.java @@ -0,0 +1,89 @@ +package org.apache.commons.graph.exception; + +/* ==================================================================== + * 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 + * "Commons" 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", + * "Commons", 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 + * . + */ + +/** + * Description of the Class + */ +public class NegativeCycleException extends GraphException +{ + /** + * Constructor for the NegativeCycleException object + */ + public NegativeCycleException() + { + super(); + } + + /** + * Constructor for the NegativeCycleException object + * + * @param msg + */ + public NegativeCycleException(String msg) + { + super(msg); + } + + /** + * Constructor for the NegativeCycleException object + * + * @param cause + */ + public NegativeCycleException(Throwable cause) + { + super(cause); + } +} diff --git a/src/java/org/apache/commons/graph/exception/NoPathException.java b/src/java/org/apache/commons/graph/exception/NoPathException.java new file mode 100644 index 0000000..ff6d6e1 --- /dev/null +++ b/src/java/org/apache/commons/graph/exception/NoPathException.java @@ -0,0 +1,90 @@ +package org.apache.commons.graph.exception; + +/* ==================================================================== + * 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 + * "Commons" 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", + * "Commons", 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 + * . + */ + +/** + * Description of the Class + */ +public class NoPathException + extends GraphException +{ + /** + * Constructor for the NoPathException object + */ + public NoPathException() + { + super(); + } + + /** + * Constructor for the NoPathException object + * + * @param msg + */ + public NoPathException(String msg) + { + super(msg); + } + + /** + * Constructor for the NoPathException object + * + * @param t + */ + public NoPathException(Throwable t) + { + super(t); + } +} diff --git a/src/java/org/apache/commons/graph/impl/AllPaths.java b/src/java/org/apache/commons/graph/impl/AllPaths.java new file mode 100644 index 0000000..c95d484 --- /dev/null +++ b/src/java/org/apache/commons/graph/impl/AllPaths.java @@ -0,0 +1,393 @@ +package org.apache.commons.graph.impl; + +/* ==================================================================== + * 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 + * "Commons" 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", + * "Commons", 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 + * . + */ + +/** + * AllPairs solves the All Points Shortest Path problem for a DirectedGraph. (If + * it is weighted, it will do shortest path by weight. Otherwise shortest path + * by jumps.) Uses Floyd's Algorithm. + */ + +import java.util.Set; +import java.util.Map; +import java.util.List; +import java.util.HashMap; +import java.util.Iterator; +import java.util.ArrayList; +import java.util.AbstractList; + +import org.apache.commons.graph.*; +import org.apache.commons.graph.exception.*; + +/** + * Description of the Class + */ +public class AllPaths +{ + private int pred[][]; + private double cost[][]; + private Vertex vArray[]; + private DirectedGraph graph; + private Map vertexIndex = new HashMap();// VERTEX X INTEGER + + /** + * Description of the Class + */ + public class EdgeList + extends AbstractList + { + private DirectedGraph graph; + private List vertices; + + /** + * Constructor for the EdgeList object + * + * @param graph + * @param vertices + */ + public EdgeList(DirectedGraph graph, + List vertices) + { + this.graph = graph; + this.vertices = vertices; + } + + /** + * Description of the Method + */ + public int size() + { + return vertices.size() - 1; + } + + /** + * Description of the Method + */ + public Object get(int index) + { + Edge RC = null; + + Vertex source = (Vertex) vertices.get(index); + Vertex target = (Vertex) vertices.get(index + 1); + + Set outboundSet = graph.getOutbound(source); + if (outboundSet == null) + { + return null; + } + + Iterator outbound = outboundSet.iterator(); + while (outbound.hasNext()) + { + RC = (Edge) outbound.next(); + if (graph.getTarget(RC) == target) + { + break; + } + } + + if (graph.getTarget(RC) != target) + { + return null; + } + + return RC; + } + } + + /** + * Description of the Class + */ + public class WPath + implements WeightedPath + { + private Vertex start; + private Vertex finish; + private List vertexList = new ArrayList(); + private DirectedGraph graph; + private double cost; + + /** + * Constructor for the WPath object + * + * @param graph + * @param vArray + * @param pred + * @param start + * @param finish + * @param cost + * @exception GraphException + */ + public WPath(DirectedGraph graph, + Vertex vArray[], int pred[][], + int start, int finish, double cost) + throws GraphException + { + this.start = vArray[start]; + this.finish = vArray[finish]; + this.cost = cost; + this.graph = graph; + + vertexList.addAll(segment(vArray, pred, + start, finish)); + vertexList.add(vArray[finish]); + } + + /** + * Returns a List of Vectors in order. Includes the start, but not the + * finish. + */ + private List segment(Vertex vArray[], int pred[][], + int start, int finish) + throws GraphException + { + int mid = pred[start][finish]; + if (mid == -1) + { + throw new NoPathException("No SubPath Available: " + + vArray[start] + " -> " + + vArray[finish]); + } + List RC = new ArrayList(); + + if (start == finish) + { + return RC; + } + + if (start == mid) + { + RC.add(vArray[start]); + + } + else + { + RC.addAll(segment(vArray, pred, + start, mid)); + RC.add(vArray[mid]); + } + + if (mid == pred[mid][finish]) + { + } + else + { + RC.addAll(segment(vArray, pred, + mid, finish)); + } + return RC; + } + + /** + * Gets the weight attribute of the WPath object + */ + public double getWeight() + { + return cost; + } + + /** + * Gets the vertices attribute of the WPath object + */ + public List getVertices() + { + return vertexList; + } + + /** + * Gets the edges attribute of the WPath object + */ + public List getEdges() + { + return new EdgeList(graph, vertexList); + } + + /** + * Gets the start attribute of the WPath object + */ + public Vertex getStart() + { + return start; + } + + /** + * Gets the end attribute of the WPath object + */ + public Vertex getEnd() + { + return finish; + } + } + + /** + * Constructor for the AllPaths object + * + * @param graph + * @exception NegativeCycleException + */ + public AllPaths(DirectedGraph graph) + throws NegativeCycleException + { + update(graph); + } + + + /** + * Description of the Method + */ + private void initIndex(Vertex vArray[]) + { + for (int i = 0; i < vArray.length; i++) + { + vertexIndex.put(vArray[i], new Integer(i)); + } + } + + /** + * Description of the Method + */ + public void update(DirectedGraph graph) + { + this.graph = graph; + + Set vertexSet = graph.getVertices(); + vArray = (Vertex[]) vertexSet.toArray(new Vertex[vertexSet.size()]); + + initIndex(vArray); + + pred = new int[vArray.length][vArray.length]; + cost = new double[vArray.length][vArray.length]; + + for (int i = 0; i < vArray.length; i++) + { + for (int j = 0; j < vArray.length; j++) + { + pred[i][j] = -1; + cost[i][j] = Double.POSITIVE_INFINITY; + } + + // First round values need to be in the matrix. + Iterator edgeSet = graph.getOutbound(vArray[i]).iterator(); + while (edgeSet.hasNext()) + { + Edge e = (Edge) edgeSet.next(); + int j = index(graph.getTarget(e)); + pred[i][j] = i; + if (graph instanceof WeightedGraph) + { + cost[i][j] = ((WeightedGraph) graph).getWeight(e); + } + else + { + cost[i][j] = 1.0; + } + } + + // Cost from any node to itself is 0.0 + cost[i][i] = 0.0; + pred[i][i] = i; + } + + compute(graph, vArray); + + } + + /** + * Description of the Method + */ + private int index(Vertex v) + { + return ((Integer) vertexIndex.get(v)).intValue(); + } + + /** + * Description of the Method + */ + private void compute(DirectedGraph graph, Vertex vArray[]) + throws NegativeCycleException + { + for (int k = 0; k < vArray.length; k++) + {// Mid Point + for (int i = 0; i < vArray.length; i++) + {// Source + for (int j = 0; j < vArray.length; j++) + {// Target + if (cost[i][k] + cost[k][j] < cost[i][j]) + { + if (i == j) + { + throw new NegativeCycleException(); + } + + // It is cheaper to go through K. + cost[i][j] = cost[i][k] + cost[k][j]; + pred[i][j] = k; + } + } + } + } + } + + /** + * Gets the shortestPath attribute of the AllPaths object + */ + public WeightedPath getShortestPath(Vertex start, Vertex end) + throws GraphException + { + return new WPath(graph, vArray, pred, + index(start), index(end), + cost[index(start)][index(end)]); + } +} diff --git a/src/java/org/apache/commons/graph/impl/DirectedAcyclicGraphImpl.java b/src/java/org/apache/commons/graph/impl/DirectedAcyclicGraphImpl.java new file mode 100644 index 0000000..1612eab --- /dev/null +++ b/src/java/org/apache/commons/graph/impl/DirectedAcyclicGraphImpl.java @@ -0,0 +1,96 @@ +package org.apache.commons.graph.impl; + +/* ==================================================================== + * 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 + * "Commons" 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", + * "Commons", 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 org.apache.commons.graph.*; +import org.apache.commons.graph.exception.*; + +/** + * Description of the Class + */ +public class DirectedAcyclicGraphImpl + extends DirectedGraphImpl +{ + /** + * Constructor for the DirectedAcyclicGraphImpl object + */ + public DirectedAcyclicGraphImpl() { } + + /** + * Description of the Method + */ + public boolean connected(Vertex start, Vertex end) + { + return false; + } + + /** + * Adds a feature to the Edge attribute of the DirectedAcyclicGraphImpl + * object + */ + public void addEdge(Edge e, + Vertex start, + Vertex end) + throws GraphException + { + if (connected(end, start)) + { + // We are going to introduce a cycle. + throw new CycleException("Adding Edge will add a Cycle."); + } + + super.addEdge(e, start, end); + } +} diff --git a/src/java/org/apache/commons/graph/impl/DirectedGraphImpl.java b/src/java/org/apache/commons/graph/impl/DirectedGraphImpl.java new file mode 100644 index 0000000..df9ee46 --- /dev/null +++ b/src/java/org/apache/commons/graph/impl/DirectedGraphImpl.java @@ -0,0 +1,467 @@ +package org.apache.commons.graph.impl; + +/* ==================================================================== + * 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 + * "Commons" 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", + * "Commons", 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.lang.reflect.*; + +import java.util.Set; +import java.util.Map; +import java.util.List; +import java.util.HashSet; +import java.util.HashMap; +import java.util.Iterator; +import java.util.ArrayList; + +import org.apache.commons.graph.*; +import org.apache.commons.graph.contract.*; +import org.apache.commons.graph.exception.*; + +/** + * Description of the Class + */ +public class DirectedGraphImpl + implements DirectedGraph, + WeightedGraph, + MutableDirectedGraph, + InvocationHandler +{ + private Set vertices = new HashSet(); + private Set edges = new HashSet(); + private List contracts = new ArrayList(); + + private Map inbound = new HashMap();// VERTEX X SET( EDGE ) + private Map outbound = new HashMap();// - " " - + + private Map edgeSource = new HashMap();// EDGE X VERTEX + private Map edgeTarget = new HashMap();// EDGE X TARGET + + private Map edgeWeights = new HashMap();// EDGE X WEIGHT + + /** + * Constructor for the DirectedGraphImpl object + */ + public DirectedGraphImpl() { } + + /** + * Constructor for the DirectedGraphImpl object + * + * @param dg + */ + public DirectedGraphImpl(DirectedGraph dg) + { + + Iterator v = dg.getVertices().iterator(); + while (v.hasNext()) + { + addVertexI((Vertex) v.next()); + } + + Iterator e = dg.getEdges().iterator(); + while (e.hasNext()) + { + Edge edge = (Edge) e.next(); + addEdgeI(edge, + dg.getSource(edge), + dg.getTarget(edge)); + + if (dg instanceof WeightedGraph) + { + setWeight(edge, ((WeightedGraph) dg).getWeight(edge)); + } + } + } + + /** + * Adds a feature to the Contract attribute of the DirectedGraphImpl object + */ + public void addContract(Contract c) + throws GraphException + { + c.setImpl(this); + c.verify(); + contracts.add(c); + } + + /** + * Description of the Method + */ + public void removeContract(Contract c) + { + contracts.remove(c); + } + + /** + * Sets the weight attribute of the DirectedGraphImpl object + */ + public void setWeight(Edge e, double value) + { + if (edgeWeights.containsKey(e)) + { + edgeWeights.remove(e); + } + edgeWeights.put(e, new Double(value)); + } + + // Interface Methods + // Graph + /** + * Gets the vertices attribute of the DirectedGraphImpl object + */ + public Set getVertices() + { + return new HashSet(vertices); + } + + /** + * Gets the vertices attribute of the DirectedGraphImpl object + */ + public Set getVertices(Edge e) + { + Set RC = new HashSet(); + if (edgeSource.containsKey(e)) + { + RC.add(edgeSource.get(e)); + } + + if (edgeTarget.containsKey(e)) + { + RC.add(edgeTarget.get(e)); + } + + return RC; + } + + /** + * Gets the edges attribute of the DirectedGraphImpl object + */ + public Set getEdges() + { + return new HashSet(edges); + } + + /** + * Gets the edges attribute of the DirectedGraphImpl object + */ + public Set getEdges(Vertex v) + { + Set RC = new HashSet(); + if (inbound.containsKey(v)) + { + RC.addAll((Set) inbound.get(v)); + } + + if (outbound.containsKey(v)) + { + RC.addAll((Set) outbound.get(v)); + } + + return RC; + } + + // Directed Graph + /** + * Gets the source attribute of the DirectedGraphImpl object + */ + public Vertex getSource(Edge e) + { + return (Vertex) edgeSource.get(e); + } + + /** + * Gets the target attribute of the DirectedGraphImpl object + */ + public Vertex getTarget(Edge e) + { + return (Vertex) edgeTarget.get(e); + } + + /** + * Gets the inbound attribute of the DirectedGraphImpl object + */ + public Set getInbound(Vertex v) + { + if (inbound.containsKey(v)) + { + return new HashSet((Set) inbound.get(v)); + } + else + { + return new HashSet(); + } + } + + /** + * Gets the outbound attribute of the DirectedGraphImpl object + */ + public Set getOutbound(Vertex v) + { + if (outbound.containsKey(v)) + { + return new HashSet((Set) outbound.get(v)); + } + else + { + return new HashSet(); + } + } + + + // MutableDirectedGraph + /** + * Adds a feature to the VertexI attribute of the DirectedGraphImpl object + */ + private void addVertexI(Vertex v) + throws GraphException + { + vertices.add(v); + } + + /** + * Adds a feature to the Vertex attribute of the DirectedGraphImpl object + */ + public void addVertex(Vertex v) + throws GraphException + { + Iterator conts = contracts.iterator(); + while (conts.hasNext()) + { + ((Contract) conts.next()).addVertex(v); + } + addVertexI(v); + } + + /** + * Description of the Method + */ + private void removeVertexI(Vertex v) + throws GraphException + { + try + { + vertices.remove(v); + } + catch (Exception ex) + { + throw new GraphException(ex); + } + } + + /** + * Description of the Method + */ + public void removeVertex(Vertex v) + throws GraphException + { + Iterator conts = contracts.iterator(); + while (conts.hasNext()) + { + ((Contract) conts.next()).removeVertex(v); + } + + removeVertexI(v); + } + + + /** + * Adds a feature to the EdgeI attribute of the DirectedGraphImpl object + */ + private void addEdgeI(Edge e, Vertex start, Vertex end) + throws GraphException + { + edges.add(e); + + if (e instanceof WeightedEdge) + { + edgeWeights.put(e, new Double(((WeightedEdge) e).getWeight())); + } + else + { + edgeWeights.put(e, new Double(1.0)); + } + + edgeSource.put(e, start); + edgeTarget.put(e, end); + + if (!outbound.containsKey(start)) + { + Set edgeSet = new HashSet(); + edgeSet.add(e); + + outbound.put(start, edgeSet); + } + else + { + ((Set) outbound.get(start)).add(e); + } + + if (!inbound.containsKey(end)) + { + Set edgeSet = new HashSet(); + edgeSet.add(e); + + inbound.put(end, edgeSet); + } + else + { + ((Set) inbound.get(end)).add(e); + } + } + + /** + * Adds a feature to the Edge attribute of the DirectedGraphImpl object + */ + public void addEdge(Edge e, + Vertex start, + Vertex end) + throws GraphException + { + try + { + Iterator conts = contracts.iterator(); + while (conts.hasNext()) + { + ((Contract) conts.next()).addEdge(e, start, end); + } + } + catch (GraphException ex) + { + throw ex; + } + + addEdgeI(e, start, end); + } + + + /** + * Description of the Method + */ + private void removeEdgeI(Edge e) + throws GraphException + { + try + { + Set edgeSet = null; + + Vertex source = (Vertex) edgeSource.get(e); + edgeSource.remove(e); + edgeSet = (Set) outbound.get(e); + edgeSet.remove(e); + + Vertex target = (Vertex) edgeTarget.get(e); + edgeTarget.remove(e); + edgeSet = (Set) inbound.get(e); + edgeSet.remove(e); + + if (edgeWeights.containsKey(e)) + { + edgeWeights.remove(e); + } + } + catch (Exception ex) + { + throw new GraphException(ex); + } + } + + /** + * Description of the Method + */ + public void removeEdge(Edge e) + throws GraphException + { + Iterator conts = contracts.iterator(); + while (conts.hasNext()) + { + ((Contract) conts.next()).removeEdge(e); + } + removeEdgeI(e); + } + + // WeightedGraph + /** + * Gets the weight attribute of the DirectedGraphImpl object + */ + public double getWeight(Edge e) + { + if (edgeWeights.containsKey(e)) + { + return ((Double) edgeWeights.get(e)).doubleValue(); + } + else + { + return 1.0; + } + } + + /** + * Description of the Method + */ + public Object invoke(Object proxy, + Method method, + Object args[]) + throws Throwable + { + try + { + return method.invoke(this, args); + } + catch (InvocationTargetException ex) + { + //!! David can fix this, this needs to run on 1.3 + return null; + //throw ex.getCause(); + } + } + +} diff --git a/src/java/org/apache/commons/graph/impl/DirectedGraphWrapper.java b/src/java/org/apache/commons/graph/impl/DirectedGraphWrapper.java new file mode 100644 index 0000000..a4ac1a3 --- /dev/null +++ b/src/java/org/apache/commons/graph/impl/DirectedGraphWrapper.java @@ -0,0 +1,135 @@ +package org.apache.commons.graph.impl; + +/* ==================================================================== + * 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 + * "Commons" 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", + * "Commons", 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 + * . + */ + +/** + * DirectedGraphWrapper This is a superclass to all wrappers that work over + * DirectedGraphs. + */ + +import java.util.Set; + +import org.apache.commons.graph.*; + +/** + * Description of the Class + */ +public class DirectedGraphWrapper + extends GraphWrapper + implements DirectedGraph +{ + private DirectedGraph impl = null; + + /** + * Constructor for the DirectedGraphWrapper object + * + * @param graph + */ + public DirectedGraphWrapper(DirectedGraph graph) + { + super(graph); + impl = graph; + } + + /** + * Constructor for the DirectedGraphWrapper object + */ + public DirectedGraphWrapper() + { + super(); + } + + /** + * Sets the dirGraph attribute of the DirectedGraphWrapper object + */ + public void setDirGraph(DirectedGraph graph) + { + impl = graph; + setGraph(graph); + } + + /** + * Gets the inbound attribute of the DirectedGraphWrapper object + */ + public Set getInbound(Vertex v) + { + return impl.getInbound(v); + } + + /** + * Gets the outbound attribute of the DirectedGraphWrapper object + */ + public Set getOutbound(Vertex v) + { + return impl.getOutbound(v); + } + + /** + * Gets the source attribute of the DirectedGraphWrapper object + */ + public Vertex getSource(Edge e) + { + return impl.getSource(e); + } + + /** + * Gets the target attribute of the DirectedGraphWrapper object + */ + public Vertex getTarget(Edge e) + { + return impl.getTarget(e); + } + +} diff --git a/src/java/org/apache/commons/graph/impl/GraphFactory.java b/src/java/org/apache/commons/graph/impl/GraphFactory.java new file mode 100644 index 0000000..a2774ae --- /dev/null +++ b/src/java/org/apache/commons/graph/impl/GraphFactory.java @@ -0,0 +1,190 @@ +package org.apache.commons.graph.impl; + +/* ==================================================================== + * 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 + * "Commons" 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", + * "Commons", 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.lang.reflect.*; + +import org.apache.commons.graph.*; +import org.apache.commons.graph.contract.*; +import org.apache.commons.graph.exception.*; + +/** + * Description of the Class + */ +public class GraphFactory +{ + + /** + * Constructor for the GraphFactory object + */ + public GraphFactory() { } + + /** + * makeGraph + * + * @param contracts Which contracts to enforce. + * @param baseGraph Is the actual *GraphImpl which will be at the core of + * the Proxy. + * @param baseGraphType Interface which is returned. + * @param isWeighted Does the graph handle Weights? + * @param init Initialization Graph. + */ + private Object makeGraph(Contract contracts[], + InvocationHandler baseGraph, + Class baseGraphType, + boolean isWeighted) + throws GraphException + { + int interfaceCount = contracts.length; + interfaceCount++;// BaseGraph Type + if (isWeighted) + { + interfaceCount++; + }// WeightedGraph Type + + Class inter[] = new Class[interfaceCount]; + + int pos = 0; + for (pos = 0; pos < contracts.length; pos++) + { + inter[pos] = contracts[pos].getInterface(); + } + + if (isWeighted) + { + inter[pos] = org.apache.commons.graph.WeightedGraph.class; + pos++; + } + + inter[pos] = baseGraphType; + + return Proxy.newProxyInstance(baseGraph.getClass().getClassLoader(), + inter, baseGraph); + } + + /** + * makeDirectedGraph + * + * @param contracts - Array of Contracts this Graph should meet. + * @param isWeighted - If true, the Graph will implement the WeightedGraph + * interface. + * @param graph - If it is provided, the graph will initially be equal to + * the graph. + */ + public DirectedGraph makeDirectedGraph(Contract contracts[], + boolean isWeighted, + DirectedGraph graph) + throws GraphException + { + DirectedGraphImpl dgi = null; + + if (graph != null) + { + dgi = new DirectedGraphImpl(graph); + } + else + { + dgi = new DirectedGraphImpl(); + } + + for (int i = 0; i < contracts.length; i++) + { + dgi.addContract(contracts[i]); + } + + return (DirectedGraph) + makeGraph(contracts, + dgi, org.apache.commons.graph.DirectedGraph.class, + isWeighted); + } + + /** + * makeMutableDirectedGraph + * + * @param contracts - Array of Contracts this Graph should meet. + * @param isWeighted - If true, the Graph will implement the WeightedGraph + * interface. + * @param graph - If it is provided, the graph will initially be equal to + * the graph. + */ + public MutableDirectedGraph + makeMutableDirectedGraph(Contract contracts[], + boolean isWeighted, + DirectedGraph graph) + throws GraphException + { + + DirectedGraphImpl dgi = null; + + if (graph != null) + { + dgi = new DirectedGraphImpl(graph); + } + else + { + dgi = new DirectedGraphImpl(); + } + + for (int i = 0; i < contracts.length; i++) + { + dgi.addContract(contracts[i]); + } + + return (MutableDirectedGraph) + makeGraph(contracts, + dgi, + org.apache.commons.graph.MutableDirectedGraph.class, + isWeighted); + } +} diff --git a/src/java/org/apache/commons/graph/impl/GraphWrapper.java b/src/java/org/apache/commons/graph/impl/GraphWrapper.java new file mode 100644 index 0000000..4394beb --- /dev/null +++ b/src/java/org/apache/commons/graph/impl/GraphWrapper.java @@ -0,0 +1,74 @@ +package org.apache.commons.graph.impl; + +/** + * GraphWrapper This is a superclass of all Wrapper implementations. It + * basically does a redirection to the graph. + */ + +import java.util.Set; + +import org.apache.commons.graph.*; + +/** + * Description of the Class + */ +public class GraphWrapper +{ + private Graph impl = null; + + /** + * Constructor for the GraphWrapper object + * + * @param impl + */ + public GraphWrapper(Graph impl) + { + this.impl = impl; + } + + /** + * Constructor for the GraphWrapper object + */ + public GraphWrapper() { } + + /** + * Sets the graph attribute of the GraphWrapper object + */ + public void setGraph(Graph impl) + { + this.impl = impl; + } + + // Graph Implementation. . . + /** + * Gets the vertices attribute of the GraphWrapper object + */ + public Set getVertices() + { + return impl.getVertices(); + } + + /** + * Gets the edges attribute of the GraphWrapper object + */ + public Set getEdges() + { + return impl.getEdges(); + } + + /** + * Gets the vertices attribute of the GraphWrapper object + */ + public Set getVertices(Edge e) + { + return impl.getVertices(e); + } + + /** + * Gets the edges attribute of the GraphWrapper object + */ + public Set getEdges(Vertex v) + { + return impl.getEdges(v); + } +} diff --git a/src/java/org/apache/commons/graph/impl/SingleSourcePaths.java b/src/java/org/apache/commons/graph/impl/SingleSourcePaths.java new file mode 100644 index 0000000..2bed860 --- /dev/null +++ b/src/java/org/apache/commons/graph/impl/SingleSourcePaths.java @@ -0,0 +1,128 @@ +package org.apache.commons.graph.impl; + +import java.util.Map; +import java.util.Set; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; + +import org.apache.commons.graph.*; +import org.apache.commons.graph.exception.*; + +/** + * Description of the Class + */ +public class SingleSourcePaths +{ + private WeightedGraph weights = null; + private Map pred = new HashMap(); + private Map weight = new HashMap(); + + /** + * Description of the Class + */ + public class WeightedVertex + implements Comparable + { + private Vertex v; + private double value; + + /** + * Constructor for the WeightedVertex object + * + * @param v + * @param value + */ + public WeightedVertex(Vertex v, double value) + { + this.v = v; + this.value = value; + } + + /** + * Description of the Method + */ + public void relax(double value) + { + this.value = value; + } + + /** + * Description of the Method + */ + public int compareTo(Object o) + { + WeightedVertex wv = (WeightedVertex) o; + if (wv.value > this.value) + { + return 1; + } + if (wv.value == this.value) + { + return 0; + } + if (wv.value < this.value) + { + return -1; + } + + return 0; + } + } + + /** + * Constructor for the SingleSourcePaths object + * + * @param graph + * @param root + * @exception GraphException + */ + public SingleSourcePaths(WeightedGraph graph, + Vertex root) + throws GraphException + { + this.weights = graph; + + if (graph instanceof DirectedGraph) + { + init((DirectedGraph) graph); + } + else + { + init((Graph) graph); + } + } + + /** + * Description of the Method + */ + public void init(DirectedGraph graph, + Vertex root) + throws GraphException + { + Iterator i = graph.getVertices().iterator(); + while (i.hasNext()) + { + Vertex v = (Vertex) i.next(); + if (v != root) + { + weight.put(v, new Double(Double.POSITIVE_INFINITY)); + } + else + { + weight.put(v, new Double(0)); + } + } + i = graph.getVertices().iterator(); + + } + + /** + * Description of the Method + */ + public void init(Graph graph) + throws GraphException + { + throw new GraphException("Not Supported"); + } +} diff --git a/src/java/org/apache/commons/graph/impl/UndirectedGraphImpl.java b/src/java/org/apache/commons/graph/impl/UndirectedGraphImpl.java new file mode 100644 index 0000000..559233c --- /dev/null +++ b/src/java/org/apache/commons/graph/impl/UndirectedGraphImpl.java @@ -0,0 +1,182 @@ +package org.apache.commons.graph.impl; + +/* ==================================================================== + * 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 + * "Commons" 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", + * "Commons", 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.Set; +import java.util.Map; +import java.util.HashSet; +import java.util.HashMap; +import java.util.Iterator; + +import org.apache.commons.graph.*; +import org.apache.commons.graph.exception.*; + +/** + * Description of the Class + */ +public class UndirectedGraphImpl + implements UndirectedGraph +{ + private Set vertices = new HashSet(); + private Set edges = new HashSet(); + + private Map edgeVerts = new HashMap();// EDGE X SET( VERTS ) + private Map vertEdges = new HashMap();// VERTEX X SET( EDGE ) + + /** + * Constructor for the UndirectedGraphImpl object + */ + public UndirectedGraphImpl() { } + + /** + * Adds a feature to the Vertex attribute of the UndirectedGraphImpl object + */ + public void addVertex(Vertex v) + throws GraphException + { + vertices.add(v); + } + + /** + * Adds a feature to the Edge attribute of the UndirectedGraphImpl object + */ + public void addEdge(Edge e, + Set vertices) + throws GraphException + { + + edges.add(e); + + // Set up Edge -> Vertices + Set edgeVert = null; + if (!edgeVerts.containsKey(e)) + { + edgeVert = new HashSet(); + edgeVerts.put(e, edgeVert); + } + else + { + edgeVert = (Set) edgeVerts.get(e); + } + + edgeVert.addAll(vertices); + + // Setup Vertex -> Edges + Iterator i = vertices.iterator(); + while (i.hasNext()) + { + Vertex v = (Vertex) i.next(); + + if (!vertEdges.containsKey(v)) + { + Set edgeSet = new HashSet(); + edgeSet.add(e); + vertEdges.put(v, edgeSet); + } + else + { + ((Set) vertEdges.get(v)).add(e); + } + } + } + + // Interface Methods + /** + * Gets the vertices attribute of the UndirectedGraphImpl object + */ + public Set getVertices() + { + return new HashSet(vertices); + } + + /** + * Gets the vertices attribute of the UndirectedGraphImpl object + */ + public Set getVertices(Edge e) + { + if (edgeVerts.containsKey(e)) + { + return new HashSet((Set) edgeVerts.get(e)); + } + else + { + return new HashSet(); + } + } + + /** + * Gets the edges attribute of the UndirectedGraphImpl object + */ + public Set getEdges() + { + return new HashSet(edges); + } + + /** + * Gets the edges attribute of the UndirectedGraphImpl object + */ + public Set getEdges(Vertex v) + { + if (vertEdges.containsKey(v)) + { + return new HashSet((Set) vertEdges.get(v)); + } + else + { + return new HashSet(); + } + } +} + diff --git a/src/java/org/apache/commons/graph/impl/WeightedGraphWrapper.java b/src/java/org/apache/commons/graph/impl/WeightedGraphWrapper.java new file mode 100644 index 0000000..745e99a --- /dev/null +++ b/src/java/org/apache/commons/graph/impl/WeightedGraphWrapper.java @@ -0,0 +1,108 @@ +package org.apache.commons.graph.impl; + +/* ==================================================================== + * 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 + * "Commons" 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", + * "Commons", 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 + * . + */ + +/** + * This is a simple wrapper to wrap around a graph, and create a weighted graph. + */ + +import java.util.Map; +import java.util.HashMap; + +import org.apache.commons.graph.*; + +/** + * Description of the Class + */ +public class WeightedGraphWrapper + extends GraphWrapper + implements WeightedGraph +{ + private Map weights = new HashMap();// EDGE X WEIGHT + + /** + * Constructor for the WeightedGraphWrapper object + * + * @param graph + */ + public WeightedGraphWrapper(Graph graph) + { + super(graph); + } + + /** + * Gets the weight attribute of the WeightedGraphWrapper object + */ + public double getWeight(Edge e) + { + if (weights.containsKey(e)) + { + return ((Double) weights.get(e)).doubleValue(); + } + else + { + return 1.0; + } + } + + /** + * Sets the weight attribute of the WeightedGraphWrapper object + */ + public void setWeight(Edge e, double weight) + { + weights.put(e, new Double(weight)); + } + +} diff --git a/src/java/org/apache/commons/graph/search/CostSearch.java b/src/java/org/apache/commons/graph/search/CostSearch.java new file mode 100644 index 0000000..05d4c9b --- /dev/null +++ b/src/java/org/apache/commons/graph/search/CostSearch.java @@ -0,0 +1,291 @@ +package org.apache.commons.graph.search; + +/* ==================================================================== + * 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 + * "Commons" 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", + * "Commons", 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 + * . + */ + +/** + * This is a Cost searching algorithm. It will basically follow edges/paths with + * minimal cost first, and then go to the later costs. + */ + +import java.util.Set; +import java.util.Map; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; + +import org.apache.commons.graph.*; + +import org.apache.commons.collections.*; + +/** + * Description of the Class + */ +public class CostSearch +{ + /** + * Description of the Class + */ + public class ComparableEdge + implements Edge, Comparable + { + private Edge e; + private double cost; + + /** + * Constructor for the ComparableEdge object + * + * @param e + * @param cost + */ + public ComparableEdge(Edge e, double cost) + { + this.e = e; + this.cost = cost; + } + + /** + * Gets the edge attribute of the ComparableEdge object + */ + public Edge getEdge() + { + return e; + } + + /** + * Gets the cost attribute of the ComparableEdge object + */ + public double getCost() + { + return cost; + } + + /** + * Description of the Method + */ + public int compareTo(Object o) + { + ComparableVertex cv = (ComparableVertex) o; + if (cv.cost > cost) + { + return 1; + } + if (cv.cost == cost) + { + return 0; + } + if (cv.cost < cost) + { + return -1; + } + return 0; + } + } + + /** + * Description of the Class + */ + public class ComparableVertex + implements Vertex, Comparable + { + private Vertex v; + private double cost; + + /** + * Constructor for the ComparableVertex object + * + * @param v + * @param cost + */ + public ComparableVertex(Vertex v, double cost) + { + this.v = v; + this.cost = cost; + } + + /** + * Description of the Method + */ + public int compareTo(Object o) + { + ComparableVertex cv = (ComparableVertex) o; + if (cv.cost > cost) + { + return 1; + } + if (cv.cost == cost) + { + return 0; + } + if (cv.cost < cost) + { + return -1; + } + return 0; + } + + /** + * Gets the vertex attribute of the ComparableVertex object + */ + public Vertex getVertex() + { + return v; + } + } + + private Map colors = new HashMap();// VERTEX X COLOR + private PriorityQueue tasks = null; + + private String WHITE = "white"; + private String BLACK = "black"; + private String GRAY = "gray"; + + /** + * Constructor for the CostSearch object + */ + public CostSearch() + { + tasks = new BinaryHeap(true); + } + + /** + * Constructor for the CostSearch object + * + * @param isMin + */ + public CostSearch(boolean isMin) + { + tasks = new BinaryHeap(isMin); + } + + /** + * Description of the Method + */ + public void visitVertex(WeightedGraph graph, + Vertex vertex, + double cost, + Visitor visitor) + { + colors.remove(vertex); + colors.put(vertex, GRAY); + + visitor.discoverVertex(vertex); + Iterator edges = graph.getEdges(vertex).iterator(); + while (edges.hasNext()) + { + Edge edge = (Edge) edges.next(); + + double edgeCost = graph.getWeight(edge); + ComparableEdge wEdge = + new ComparableEdge(edge, edgeCost + cost); + tasks.insert(wEdge); + } + + visitor.finishVertex(vertex); + colors.remove(vertex); + colors.put(vertex, BLACK); + } + + /** + * Description of the Method + */ + public void visitEdge(WeightedGraph graph, + Edge e, + double cost, + Visitor visitor) + { + visitor.discoverEdge(e); + + Iterator vertices = graph.getVertices(e).iterator(); + while (vertices.hasNext()) + { + Vertex v = (Vertex) vertices.next(); + if (colors.get(v) == WHITE) + { + visitVertex(graph, v, cost, visitor); + } + } + + visitor.finishEdge(e); + } + + + /** + * Description of the Method + */ + public void visit(WeightedGraph graph, + Vertex root, + Visitor visitor) + { + Iterator vertices = graph.getVertices().iterator(); + while (vertices.hasNext()) + { + colors.put(vertices.next(), WHITE); + } + + visitor.discoverGraph(graph); + + visitVertex(graph, root, 0.0, visitor); + + while (!tasks.isEmpty()) + { + ComparableEdge wEdge = (ComparableEdge) tasks.pop(); + visitEdge(graph, wEdge.getEdge(), wEdge.getCost(), visitor); + } + + visitor.finishGraph(graph); + } +} + + diff --git a/src/java/org/apache/commons/graph/search/DFS.java b/src/java/org/apache/commons/graph/search/DFS.java new file mode 100644 index 0000000..5973670 --- /dev/null +++ b/src/java/org/apache/commons/graph/search/DFS.java @@ -0,0 +1,168 @@ +package org.apache.commons.graph.search; + +/* ==================================================================== + * 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 + * "Commons" 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", + * "Commons", 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 + * . + */ + +/** + * This class does a Depth First Search. It visits all of the children nodes + * before moving to the siblling nodes. + */ + +import java.util.Set; +import java.util.Map; +import java.util.HashSet; +import java.util.HashMap; +import java.util.Iterator; + +import org.apache.commons.graph.*; + +/** + * Description of the Class + */ +public class DFS +{ + private Map colors = new HashMap();// VERTEX X COLOR + /** + * Description of the Field + */ + public final static String WHITE = "white"; + /** + * Description of the Field + */ + public final static String BLACK = "black"; + /** + * Description of the Field + */ + public final static String GRAY = "gray"; + + /** + * Constructor for the DFS object + */ + public DFS() { } + + /** + * Gets the color attribute of the DFS object + */ + public String getColor(Vertex v) + { + return (String) colors.get(v); + } + + + /** + * Description of the Method + */ + private void visitEdge(DirectedGraph graph, + Edge e, + Visitor visitor) + { + visitor.discoverEdge(e); + + Vertex v = graph.getTarget(e); + + if (colors.get(v) == WHITE) + { + visitVertex(graph, v, visitor); + } + + visitor.finishEdge(e); + } + + /** + * Description of the Method + */ + private void visitVertex(DirectedGraph graph, + Vertex v, + Visitor visitor) + { + colors.remove(v); + colors.put(v, GRAY); + + visitor.discoverVertex(v); + + Iterator edges = graph.getOutbound(v).iterator(); + while (edges.hasNext()) + { + Edge e = (Edge) edges.next(); + visitEdge(graph, e, visitor); + } + + visitor.finishVertex(v); + + colors.remove(v); + colors.put(v, BLACK); + } + + /** + * visit - Visits the graph + */ + public void visit(DirectedGraph graph, + Vertex root, + Visitor visitor) + { + Iterator vertices = graph.getVertices().iterator(); + while (vertices.hasNext()) + { + colors.put(vertices.next(), WHITE); + } + + visitor.discoverGraph(graph); + + visitVertex(graph, root, visitor); + + visitor.finishGraph(graph); + } + +} + diff --git a/src/java/org/apache/commons/graph/search/Visitor.java b/src/java/org/apache/commons/graph/search/Visitor.java new file mode 100644 index 0000000..3b05ba0 --- /dev/null +++ b/src/java/org/apache/commons/graph/search/Visitor.java @@ -0,0 +1,93 @@ +package org.apache.commons.graph.search; + +/* ==================================================================== + * 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 + * "Commons" 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", + * "Commons", 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 org.apache.commons.graph.*; + +/** + * Description of the Interface + */ +public interface Visitor +{ + /** + * Description of the Method + */ + public void discoverGraph(Graph graph); + + /** + * Description of the Method + */ + public void discoverVertex(Vertex vertex); + + /** + * Description of the Method + */ + public void discoverEdge(Edge edge); + + /** + * Description of the Method + */ + public void finishEdge(Edge edge); + + /** + * Description of the Method + */ + public void finishVertex(Vertex vertex); + + /** + * Description of the Method + */ + public void finishGraph(Graph graph); +} diff --git a/src/java/org/apache/commons/graph/statemachine/State.java b/src/java/org/apache/commons/graph/statemachine/State.java new file mode 100644 index 0000000..cd39294 --- /dev/null +++ b/src/java/org/apache/commons/graph/statemachine/State.java @@ -0,0 +1,48 @@ +package org.apache.commons.graph.statemachine; + +import org.apache.commons.graph.*; + +/** + * Description of the Class + */ +public class State + implements Vertex, Named +{ + private String name; + private StateMachine subMachine = null; + + /** + * Constructor for the State object + * + * @param name + */ + public State(String name) + { + this.name = name; + } + + /** + * Gets the name attribute of the State object + */ + public String getName() + { + return name; + } + + /** + * Sets the submachine attribute of the State object + */ + public void setSubmachine(StateMachine subMachine) + { + this.subMachine = subMachine; + } + + /** + * Gets the submachine attribute of the State object + */ + public StateMachine getSubmachine() + { + return this.subMachine; + } + +} diff --git a/src/java/org/apache/commons/graph/statemachine/StateMachine.java b/src/java/org/apache/commons/graph/statemachine/StateMachine.java new file mode 100644 index 0000000..8abc0e6 --- /dev/null +++ b/src/java/org/apache/commons/graph/statemachine/StateMachine.java @@ -0,0 +1,131 @@ +package org.apache.commons.graph.statemachine; + +import java.util.Map; +import java.util.Set; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; + +import org.apache.commons.graph.*; +import org.apache.commons.graph.impl.*; +import org.apache.commons.graph.exception.*; +import org.apache.commons.graph.statemachine.exception.*; + +/** + * Description of the Class + */ +public class StateMachine + extends DirectedGraphImpl +{ + private Map states = new HashMap();// NAME X STATE + private Map transes = new HashMap();// NAME X TRANSITION + private Set finalStates = new HashSet(); + private State startState = null; + + private String name; + + /** + * Constructor for the StateMachine object + * + * @param name + */ + public StateMachine(String name) + { + this.name = name; + } + + /** + * Gets the name attribute of the StateMachine object + */ + public String getName() + { + return name; + } + + /** + * Adds a feature to the State attribute of the StateMachine object + */ + public void addState(State state) + throws GraphException + { + states.put(state.getName(), state); + addVertex(state); + } + + /** + * Adds a feature to the State attribute of the StateMachine object + */ + public void addState(String name) + throws GraphException + { + State newState = new State(name); + addState(new State(name)); + } + + /** + * Sets the startState attribute of the StateMachine object + */ + public void setStartState(State state) + { + startState = state; + } + + /** + * Sets the finalState attribute of the StateMachine object + */ + public void setFinalState(State state) + { + finalStates.add(state); + } + + /** + * Adds a feature to the Transition attribute of the StateMachine object + */ + public void addTransition(String name, + String source, + String target) + throws GraphException + { + addTransition(name, + getState(source), + getState(target)); + } + + /** + * Adds a feature to the Transition attribute of the StateMachine object + */ + public void addTransition(String name, + State source, + State target) + throws GraphException + { + Transition trans = new Transition(name, source, target); + addTransition(trans); + } + + /** + * Adds a feature to the Transition attribute of the StateMachine object + */ + public void addTransition(Transition trans) + throws GraphException + { + transes.put(trans.getName(), trans); + addEdge(trans, trans.getSource(), trans.getTarget()); + } + + /** + * Gets the state attribute of the StateMachine object + */ + public State getState(String name) + { + return (State) states.get(name); + } + + /** + * Gets the transition attribute of the StateMachine object + */ + public Transition getTransition(String name) + { + return (Transition) transes.get(name); + } +} diff --git a/src/java/org/apache/commons/graph/statemachine/Transition.java b/src/java/org/apache/commons/graph/statemachine/Transition.java new file mode 100644 index 0000000..49aeb10 --- /dev/null +++ b/src/java/org/apache/commons/graph/statemachine/Transition.java @@ -0,0 +1,111 @@ +package org.apache.commons.graph.statemachine; + +import org.apache.commons.graph.*; + +/** + * Description of the Class + */ +public class Transition + implements Edge, Named +{ + private String name; + private State source; + private State target; + + private String action = null; + private String guard = null; + private String output = null; + + /** + * Description of the Field + */ + public final static String EPSILON = "\u03B5"; + + /** + * Constructor for the Transition object + * + * @param name + * @param source + * @param target + */ + public Transition(String name, + State source, + State target) + { + this.name = name; + this.source = source; + this.target = target; + } + + /** + * Gets the name attribute of the Transition object + */ + public String getName() + { + return name; + } + + /** + * Gets the source attribute of the Transition object + */ + public State getSource() + { + return source; + } + + /** + * Gets the target attribute of the Transition object + */ + public State getTarget() + { + return target; + } + + /** + * Sets the action attribute of the Transition object + */ + public void setAction() + { + this.action = action; + } + + /** + * Gets the action attribute of the Transition object + */ + public String getAction() + { + return action; + } + + /** + * Sets the guard attribute of the Transition object + */ + public void setGuard(String guard) + { + this.guard = guard; + } + + /** + * Gets the guard attribute of the Transition object + */ + public String getGuard() + { + return guard; + } + + /** + * Gets the output attribute of the Transition object + */ + public String getOutput() + { + return output; + } + + /** + * Sets the output attribute of the Transition object + */ + public void setOutput(String output) + { + this.output = output; + } +} diff --git a/src/java/org/apache/commons/graph/statemachine/exception/StateMachineException.java b/src/java/org/apache/commons/graph/statemachine/exception/StateMachineException.java new file mode 100644 index 0000000..c1999ab --- /dev/null +++ b/src/java/org/apache/commons/graph/statemachine/exception/StateMachineException.java @@ -0,0 +1,38 @@ +package org.apache.commons.graph.statemachine.exception; + +import org.apache.commons.graph.exception.*; + +/** + * Description of the Class + */ +public class StateMachineException + extends GraphException +{ + /** + * Constructor for the StateMachineException object + */ + public StateMachineException() + { + super(); + } + + /** + * Constructor for the StateMachineException object + * + * @param msg + */ + public StateMachineException(String msg) + { + super(msg); + } + + /** + * Constructor for the StateMachineException object + * + * @param t + */ + public StateMachineException(Throwable t) + { + super(t); + } +} diff --git a/src/java/org/apache/commons/graph/uml/ModelFactory.java b/src/java/org/apache/commons/graph/uml/ModelFactory.java new file mode 100644 index 0000000..db92ceb --- /dev/null +++ b/src/java/org/apache/commons/graph/uml/ModelFactory.java @@ -0,0 +1,96 @@ +package org.apache.commons.graph.uml; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.FileInputStream; +import java.io.FileNotFoundException; + +import java.util.Enumeration; + +import java.util.zip.*; + +import org.xml.sax.InputSource; + +import org.apache.commons.graph.uml.exception.*; + +import org.apache.log4j.Category; + +import ru.novosoft.uml.xmi.XMIReader; +import ru.novosoft.uml.model_management.MModel; + +/** + * Description of the Class + */ +public class ModelFactory +{ + private XMIReader xmiReader = null; + private final static String xmiVersion = "1.1"; + private static Category log = + Category.getInstance(org.apache.commons.graph.uml.ModelFactory.class); + + /** + * Constructor for the ModelFactory object + * + * @exception Exception + */ + public ModelFactory() + throws Exception + { + log.debug("ModelFactory.__init__()"); + try + { + xmiReader = new XMIReader(); + } + catch (Exception e) + { + log.error(e); + throw e; + } + } + + /** + * Gets the fromStream attribute of the ModelFactory object + */ + public MModel getFromStream(InputStream stream) + { + log.debug("getFromStream"); + return xmiReader.parse(new InputSource(stream)); + } + + /** + * Gets the fromXMI attribute of the ModelFactory object + */ + public MModel getFromXMI(File xmiFile) + throws IOException + { + log.debug("getFromXMI(" + xmiFile.getName() + ")"); + return getFromStream(new FileInputStream(xmiFile)); + } + + /** + * Gets the fromZargo attribute of the ModelFactory object + */ + public MModel getFromZargo(File zargoFile) + throws IOException + { + log.debug("getFromZargo(" + zargoFile.getName() + ")"); + MModel RC = null; + + ZipFile zargoZip = new ZipFile(zargoFile); + + Enumeration entries = zargoZip.entries(); + while (entries.hasMoreElements()) + { + ZipEntry entry = (ZipEntry) entries.nextElement(); + + if (entry.getName().endsWith(".xmi")) + { + log.debug("Zargo Entry: " + entry.getName()); + return getFromStream(zargoZip.getInputStream(entry)); + } + } + throw new FileNotFoundException(); + } + +} diff --git a/src/java/org/apache/commons/graph/uml/StateMachineFactory.java b/src/java/org/apache/commons/graph/uml/StateMachineFactory.java new file mode 100644 index 0000000..f456bc8 --- /dev/null +++ b/src/java/org/apache/commons/graph/uml/StateMachineFactory.java @@ -0,0 +1,219 @@ +package org.apache.commons.graph.uml; + +/** + * StateMachineFactory This class will build a State Machine from an NSUML Model + * which can be used for testing. + */ + +import java.util.Set; +import java.util.Map; +import java.util.HashSet; +import java.util.HashMap; +import java.util.Iterator; + +import org.apache.commons.graph.uml.exception.*; + +import org.apache.log4j.Category; + +import org.apache.commons.graph.exception.*; +import org.apache.commons.graph.statemachine.*; + +import ru.novosoft.uml.foundation.data_types.*; +import ru.novosoft.uml.model_management.MModel; +import ru.novosoft.uml.foundation.core.*; +import ru.novosoft.uml.behavior.state_machines.*; +import ru.novosoft.uml.behavior.common_behavior.*; + +import org.apache.commons.graph.uml.exception.*; + +/** + * Description of the Class + */ +public class StateMachineFactory +{ + private static Category log = + Category.getInstance(org.apache.commons.graph.uml.StateMachineFactory.class); + + private MModel extent = null; + + private Map stateNames = new HashMap();// MSTATEVERTEX X NAME + + /** + * Constructor for the StateMachineFactory object + * + * @param extent + */ + public StateMachineFactory(MModel extent) + { + this.extent = extent; + } + + /** + * Gets the name attribute of the StateMachineFactory object + */ + private String getName(String namespace, MStateVertex msv) + { + if (msv.getName() != null) + { + return namespace + "/" + msv.getName(); + } + + if (msv instanceof MPseudostate) + { + return namespace + "/_" + + ((MPseudostate) msv).getKind().getName() + "_"; + } + + if (msv instanceof MFinalState) + { + return namespace + "/_final_"; + } + + return namespace + "/_unknown_"; + } + + /** + * Description of the Method + */ + private StateMachine makeStateMachine(String namespace, + MCompositeState mcs) + throws GraphException + { + log.debug("makeStateMachine(" + getName(namespace, mcs) + "): Entry"); + StateMachine RC = new StateMachine(namespace); + + // Step 1 - Add States to the State Machine + Iterator states = + mcs.getSubvertices().iterator(); + + while (states.hasNext()) + { + MStateVertex msv = + (MStateVertex) states.next(); + + RC.addState(getName(namespace, msv)); + + stateNames.put(msv, getName(namespace, msv)); + + if (msv instanceof MPseudostate) + { + if (((MPseudostate) msv).getKind() == + MPseudostateKind.INITIAL) + { + RC.setStartState(RC.getState(getName(namespace, msv))); + } + } + + if (msv instanceof MCompositeState) + { + StateMachine ssm = makeStateMachine(getName(namespace, msv), + (MCompositeState) msv); + RC.getState(getName(namespace, msv)).setSubmachine(ssm); + } + + if (msv instanceof MFinalState) + { + RC.setFinalState(RC.getState(getName(namespace, msv))); + } + } + + // Step 2 - Add Transitions to State Machine + states = mcs.getSubvertices().iterator(); + while (states.hasNext()) + { + MStateVertex msv = (MStateVertex) states.next(); + String msvName = getName(namespace, msv); + + Iterator transes = + msv.getIncomings().iterator(); + while (transes.hasNext()) + { + MTransition trans = + (MTransition) transes.next(); + MEvent event = trans.getTrigger(); + String trigger = null; + + if (event != null) + { + trigger = event.getName(); + } + else + { + trigger = Transition.EPSILON; + } + + String sourceName = + (String) stateNames.get(trans.getSource()); + String targetName = + (String) stateNames.get(trans.getTarget()); + + State source = RC.getState(sourceName); + State target = RC.getState(targetName); + + Transition tranx = + new Transition(source + "-" + target + "/" + trigger, + source, target); + RC.addTransition(tranx); + } + } + + log.debug("makeStateMachine(" + getName(namespace, mcs) + "): Exit"); + return RC; + } + + + /** + * Description of the Method + */ + public StateMachine makeStateMachine(String selector) + throws GraphException, ModelNotFoundException + { + log.debug("makeStateMachine(" + selector + "):Enter"); + MStateMachine model = null; + StateMachine RC = null; + + Iterator owned = + extent.getOwnedElements().iterator(); + + while (owned.hasNext()) + { + Object next = owned.next(); + if (next instanceof + ru.novosoft.uml.foundation.core.MClass) + { + MClass mClass = (MClass) next; + + if (selector.equals(mClass.getName())) + { + Iterator machines = mClass.getBehaviors().iterator(); + if (machines.hasNext()) + { + model = (MStateMachine) machines.next(); + log.info("StateMachine Found: " + model); + } + } + } + } + + if (model == null) + { + throw new ModelNotFoundException("Cannot find StateMachine for " + + selector); + } + + MState top = model.getTop(); + if (top instanceof MCompositeState) + { + RC = makeStateMachine(selector, + (MCompositeState) top); + } + else + { + throw new ModelNotFoundException("Expecting CompositeState at top."); + } + + log.debug("makeStateMachine(" + selector + "):Exit"); + return RC; + } +} + diff --git a/src/java/org/apache/commons/graph/uml/exception/ModelNotFoundException.java b/src/java/org/apache/commons/graph/uml/exception/ModelNotFoundException.java new file mode 100644 index 0000000..51a3490 --- /dev/null +++ b/src/java/org/apache/commons/graph/uml/exception/ModelNotFoundException.java @@ -0,0 +1,38 @@ +package org.apache.commons.graph.uml.exception; + +/** + * Description of the Class + */ +public class ModelNotFoundException extends Exception +{ + private Throwable cause = null; + + /** + * Constructor for the ModelNotFoundException object + */ + public ModelNotFoundException() + { + super(); + } + + /** + * Constructor for the ModelNotFoundException object + * + * @param msg + */ + public ModelNotFoundException(String msg) + { + super(msg); + } + + /** + * Constructor for the ModelNotFoundException object + * + * @param cause + */ + public ModelNotFoundException(Throwable cause) + { + super(cause.getMessage()); + this.cause = cause; + } +} diff --git a/src/java/org/apache/commons/graph/visualize/TouchGraph.java b/src/java/org/apache/commons/graph/visualize/TouchGraph.java new file mode 100644 index 0000000..986f7d6 --- /dev/null +++ b/src/java/org/apache/commons/graph/visualize/TouchGraph.java @@ -0,0 +1,234 @@ +package org.apache.commons.graph.visualize; + +import java.util.Random; +import java.util.Iterator; + +import java.io.OutputStream; +import java.io.PrintWriter; + +import java.awt.Color; + +import org.apache.commons.graph.*; + +/** + * Description of the Class + */ +public class TouchGraph +{ + private Color vertexColor = Color.yellow; + private Color textColor = Color.black; + private Color edgeColor = Color.red; + + private double lengthFactor = 500.0; + private double defaultLength = 1.0; + private int fontSize = 18; + + private Random random = new Random(); + + /** + * Constructor for the TouchGraph object + */ + public TouchGraph() { } + + /** + * Gets the colorText attribute of the TouchGraph object + */ + private String getColorText(Color color) + { + return Integer.toHexString(color.getRGB()).toUpperCase(); + } + + /** + * Sets the vertexColor attribute of the TouchGraph object + */ + public void setVertexColor(Color vertexColor) + { + this.vertexColor = vertexColor; + } + + /** + * Gets the vertexColor attribute of the TouchGraph object + */ + public Color getVertexColor() + { + return this.vertexColor; + } + + /** + * Gets the vertexColorText attribute of the TouchGraph object + */ + private String getVertexColorText() + { + return getColorText(getVertexColor()); + } + + /** + * Sets the textColor attribute of the TouchGraph object + */ + public void setTextColor(Color vertexColor) + { + this.vertexColor = vertexColor; + } + + /** + * Gets the textColor attribute of the TouchGraph object + */ + public Color getTextColor() + { + return this.vertexColor; + } + + /** + * Gets the textColorText attribute of the TouchGraph object + */ + private String getTextColorText() + { + return getColorText(getTextColor()); + } + + /** + * Sets the edgeColor attribute of the TouchGraph object + */ + public void setEdgeColor(Color edgeColor) + { + this.edgeColor = edgeColor; + } + + /** + * Gets the edgeColor attribute of the TouchGraph object + */ + public Color getEdgeColor() + { + return this.edgeColor; + } + + /** + * Gets the edgeColorText attribute of the TouchGraph object + */ + private String getEdgeColorText() + { + return getColorText(getEdgeColor()); + } + + /** + * Sets the fontSize attribute of the TouchGraph object + */ + public void setFontSize(int size) + { + this.fontSize = size; + } + + /** + * Gets the fontSize attribute of the TouchGraph object + */ + public int getFontSize() + { + return fontSize; + } + + /** + * Sets the defaultEdgeLength attribute of the TouchGraph object + */ + public void setDefaultEdgeLength(int length) + { + this.defaultLength = length; + } + + /** + * Gets the defaultEdgeLength attribute of the TouchGraph object + */ + public double getDefaultEdgeLength() + { + return defaultLength; + } + + /** + * Description of the Method + */ + protected void writeNodeset(PrintWriter pw, + DirectedGraph graph) + { + pw.println(""); + Iterator vertices = + graph.getVertices().iterator(); + while (vertices.hasNext()) + { + Vertex v = (Vertex) vertices.next(); + + pw.println(""); + pw.println(""); + + String label; + if (v instanceof Named) + { + label = ((Named) v).getName(); + } + else + { + label = v.toString(); + } + + pw.println(""); + + pw.println(""); + } + + pw.println(""); + } + + /** + * Description of the Method + */ + protected void writeEdgeset(PrintWriter pw, DirectedGraph graph) + { + pw.println(""); + + Iterator edges = graph.getEdges().iterator(); + while (edges.hasNext()) + { + Edge next = (Edge) edges.next(); + + int length = new Double(lengthFactor * + defaultLength).intValue(); + + if (graph instanceof WeightedGraph) + { + length = + new Double(lengthFactor * + ((WeightedGraph) graph) + .getWeight(next)).intValue(); + } + + pw.println(""); + + } + pw.println(""); + } + + /** + * Description of the Method + */ + public void toXML(DirectedGraph graph, + OutputStream os) + { + PrintWriter pw = new PrintWriter(os); + pw.println(""); + pw.println(""); + writeNodeset(pw, graph); + writeEdgeset(pw, graph); + pw.println(""); + pw.flush(); + + return; + } +} diff --git a/src/test/org/apache/commons/graph/DirGraphTest.java b/src/test/org/apache/commons/graph/DirGraphTest.java new file mode 100644 index 0000000..84a9909 --- /dev/null +++ b/src/test/org/apache/commons/graph/DirGraphTest.java @@ -0,0 +1,478 @@ +package org.apache.commons.graph; + +/* ==================================================================== + * 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 + * "Commons" 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", + * "Commons", 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 + * . + */ + +/** + * DirGraphTest This test will ensure that we can represent a Directed Graph. + */ + +import java.util.Set; +import java.util.HashSet; +import java.util.Iterator; + +/** + * Description of the Class + */ +public class DirGraphTest + extends GraphTest +{ + private String testName = null; + + /** + * Constructor for the DirGraphTest object + * + * @param name + */ + public DirGraphTest(String name) + { + super(name); + this.testName = name; + } + + /** + * A unit test for JUnit + */ + public void testDirNull() + throws Throwable + { + verifyGraph(makeDirNullGraph(), 0, 0); + } + + /** + * A unit test for JUnit + */ + public void testSingleVertex() + throws Throwable + { + verifyGraph(makeDirSingleVertex(), 1, 0); + } + + /** + * A unit test for JUnit + */ + public void testDoubleVertex() + throws Throwable + { + verifyGraph(makeDirDoubleVertex(), 2, 0); + } + + /** + * A unit test for JUnit + */ + public void testSelfLoop() + throws Throwable + { + DirectedGraph IUT = makeSelfLoop(); + try + { + + verifyGraph(IUT, 1, 1); + + verifyAdjVertices(IUT, V1, + makeSet(V1)); + + verifyAdjVertices(IUT, V1, + makeSet(V1), + makeSet(V1)); + } + catch (Throwable t) + { + printGraph(t, IUT); + throw t; + } + } + + /** + * A unit test for JUnit + */ + public void testDirectedEdge() + throws Throwable + { + DirectedGraph IUT = makeDirectedEdge(); + try + { + + verifyGraph(IUT, 2, 1); + + verifyAdjVertices(IUT, V1, + makeSet(V1, V2)); + verifyAdjVertices(IUT, V1, + makeSet(V1, V2)); + + verifyAdjVertices(IUT, V1, + makeSet(), + makeSet(V2)); + verifyAdjVertices(IUT, V2, + makeSet(V1), + makeSet()); + } + catch (Throwable t) + { + printGraph(t, IUT); + throw t; + } + } + + /** + * A unit test for JUnit + */ + public void testDirParallelEdges() + throws Throwable + { + DirectedGraph IUT = makeDirParallelEdges(); + try + { + + verifyGraph(IUT, 2, 2); + + verifyAdjVertices(IUT, V1, + makeSet(V1, V2)); + verifyAdjVertices(IUT, V2, + makeSet(V1, V2)); + + verifyAdjVertices(IUT, V1, + makeSet(), + makeSet(V2)); + verifyAdjVertices(IUT, V2, + makeSet(V1), + makeSet()); + + } + catch (Throwable t) + { + printGraph(t, IUT); + throw t; + } + } + + /** + * A unit test for JUnit + */ + public void testTwoCycle() + throws Throwable + { + DirectedGraph IUT = makeTwoCycle(); + try + { + + verifyGraph(IUT, 2, 2); + + verifyAdjVertices(IUT, V1, + makeSet(V1, V2)); + verifyAdjVertices(IUT, V2, + makeSet(V1, V2)); + + verifyAdjVertices(IUT, V1, + makeSet(V2), + makeSet(V2)); + verifyAdjVertices(IUT, V2, + makeSet(V1), + makeSet(V1)); + } + catch (Throwable t) + { + printGraph(t, IUT); + throw t; + } + } + + /** + * A unit test for JUnit + */ + public void testDirectedCycle() + throws Throwable + { + DirectedGraph IUT = makeDirectedCycle(); + try + { + + verifyGraph(IUT, 3, 3); + + verifyAdjVertices(IUT, V1, + makeSet(V1, V2, V3)); + verifyAdjVertices(IUT, V2, + makeSet(V1, V2, V3)); + verifyAdjVertices(IUT, V3, + makeSet(V1, V2, V3)); + + verifyAdjVertices(IUT, V1, + makeSet(V3), + makeSet(V2)); + verifyAdjVertices(IUT, V2, + makeSet(V1), + makeSet(V3)); + verifyAdjVertices(IUT, V3, + makeSet(V2), + makeSet(V1)); + } + catch (Throwable t) + { + printGraph(t, IUT); + throw t; + } + } + + + /** + * A unit test for JUnit + */ + public void testPipe() + throws Throwable + { + DirectedGraph IUT = makePipe(); + try + { + + verifyGraph(IUT, 3, 2); + + verifyAdjVertices(IUT, V1, + makeSet(V1, V2)); + verifyAdjVertices(IUT, V2, + makeSet(V1, V2, V3)); + verifyAdjVertices(IUT, V3, + makeSet(V2, V3)); + + verifyAdjVertices(IUT, V1, + makeSet(), + makeSet(V2)); + verifyAdjVertices(IUT, V2, + makeSet(V1), + makeSet(V3)); + verifyAdjVertices(IUT, V3, + makeSet(V2), + makeSet()); + } + catch (Throwable t) + { + printGraph(t, IUT); + throw t; + } + } + + /** + * A unit test for JUnit + */ + public void testDiamond() + throws Throwable + { + DirectedGraph IUT = makeDiamond(); + try + { + + verifyGraph(IUT, 4, 4); + + verifyAdjVertices(IUT, V1, + makeSet(V1, V2, V3)); + verifyAdjVertices(IUT, V2, + makeSet(V1, V2, V4)); + verifyAdjVertices(IUT, V3, + makeSet(V1, V3, V4)); + verifyAdjVertices(IUT, V4, + makeSet(V2, V3, V4)); + + verifyAdjVertices(IUT, V1, + makeSet(), + makeSet(V2, V3)); + verifyAdjVertices(IUT, V2, + makeSet(V1), + makeSet(V4)); + verifyAdjVertices(IUT, V3, + makeSet(V1), + makeSet(V4)); + verifyAdjVertices(IUT, V4, + makeSet(V2, V3), + makeSet()); + } + catch (Throwable t) + { + printGraph(t, IUT); + throw t; + } + } + + /** + * A unit test for JUnit + */ + public void testPipelessCycle() + throws Throwable + { + DirectedGraph IUT = makePipelessCycle(); + try + { + + verifyGraph(IUT, 4, 4); + + verifyAdjVertices(IUT, V1, + makeSet(V1, V2, V3)); + verifyAdjVertices(IUT, V2, + makeSet(V1, V2, V4)); + verifyAdjVertices(IUT, V3, + makeSet(V1, V3, V4)); + verifyAdjVertices(IUT, V4, + makeSet(V2, V3, V4)); + + verifyAdjVertices(IUT, V1, + makeSet(), + makeSet(V2, V3)); + verifyAdjVertices(IUT, V2, + makeSet(V1, V4), + makeSet()); + verifyAdjVertices(IUT, V3, + makeSet(V1, V4), + makeSet()); + verifyAdjVertices(IUT, V4, + makeSet(), + makeSet(V2, V3)); + } + catch (Throwable t) + { + printGraph(t, IUT); + throw t; + } + } + + /** + * A unit test for JUnit + */ + public void testParentTree() + throws Throwable + { + DirectedGraph IUT = makeParentTree(); + try + { + + verifyGraph(IUT, 5, 4); + + verifyAdjVertices(IUT, V1, + makeSet(V1, V2, V3)); + verifyAdjVertices(IUT, V2, + makeSet(V1, V2)); + verifyAdjVertices(IUT, V3, + makeSet(V1, V3, V4, V5)); + verifyAdjVertices(IUT, V4, + makeSet(V3, V4)); + verifyAdjVertices(IUT, V5, + makeSet(V3, V5)); + + verifyAdjVertices(IUT, V1, + makeSet(V2, V3), + makeSet()); + verifyAdjVertices(IUT, V2, + makeSet(), + makeSet(V1)); + verifyAdjVertices(IUT, V3, + makeSet(V4, V5), + makeSet(V1)); + verifyAdjVertices(IUT, V4, + makeSet(), + makeSet(V3)); + verifyAdjVertices(IUT, V5, + makeSet(), + makeSet(V3)); + } + catch (Throwable t) + { + printGraph(t, IUT); + throw t; + } + } + + /** + * A unit test for JUnit + */ + public void testChildTree() + throws Throwable + { + DirectedGraph IUT = makeChildTree(); + try + { + + verifyGraph(IUT, 5, 4); + + verifyAdjVertices(IUT, V1, + makeSet(V1, V2, V3)); + verifyAdjVertices(IUT, V2, + makeSet(V1, V2)); + verifyAdjVertices(IUT, V3, + makeSet(V1, V3, V4, V5)); + verifyAdjVertices(IUT, V4, + makeSet(V3, V4)); + verifyAdjVertices(IUT, V5, + makeSet(V3, V5)); + + verifyAdjVertices(IUT, V1, + makeSet(), + makeSet(V2, V3)); + verifyAdjVertices(IUT, V2, + makeSet(V1), + makeSet()); + verifyAdjVertices(IUT, V3, + makeSet(V1), + makeSet(V4, V5)); + verifyAdjVertices(IUT, V4, + makeSet(V3), + makeSet()); + verifyAdjVertices(IUT, V5, + makeSet(V3), + makeSet()); + } + catch (Throwable t) + { + printGraph(t, IUT); + throw t; + } + } + +} diff --git a/src/test/org/apache/commons/graph/GraphTest.java b/src/test/org/apache/commons/graph/GraphTest.java new file mode 100644 index 0000000..79d4683 --- /dev/null +++ b/src/test/org/apache/commons/graph/GraphTest.java @@ -0,0 +1,952 @@ +package org.apache.commons.graph; + +/* ==================================================================== + * 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 + * "Commons" 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", + * "Commons", 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 + * . + */ +/** + * GraphTest This is a superclass of other tests to provide some utilities in + * verifying graphs. This test will provide Undirected and Directed Graphs as + * well. We will implement the following graphs. Undirected Graphs + * ------------------- () No Vertex, No Edges @ One Vertex, No Edges @ @ Two + * Vertices, No Edges @-@ Two Vertices, One edge /-\ @ @ Two Vertices, Two Edges + * (Parallel Edges) \-/ @ / \ Three Vertices, Three Edges (Cycle) @---@ @--@--@ + * Three Vertices, Two Edges (No Cycle) @ / \ @ @ 5 Vertices, 4 Edges (Tree) / \ + * @ @ @-@ @-@ 4 Vertices, 2 Edges (Disconnected) + */ + +import java.util.Set; +import java.util.Map; +import java.util.HashSet; +import java.util.HashMap; +import java.util.Iterator; + +import junit.framework.*; + +import org.apache.commons.graph.impl.*; +import org.apache.commons.graph.exception.*; + +/** + * Description of the Class + */ +public class GraphTest extends TestCase +{ + /** + * Description of the Class + */ + public class VertexImpl + implements Vertex + { + private String name = null; + + /** + * Constructor for the VertexImpl object + * + * @param name + */ + public VertexImpl(String name) + { + this.name = name; + } + + /** + * Description of the Method + */ + public String toString() + { + return name; + } + } + + /** + * Description of the Class + */ + public class EdgeImpl + implements Edge + { + private Vertex start; + private Vertex end; + + /** + * Constructor for the EdgeImpl object + * + * @param start + * @param end + */ + public EdgeImpl(Vertex start, + Vertex end) + { + this.start = start; + this.end = end; + } + + /** + * Gets the otherVertex attribute of the EdgeImpl object + */ + public Vertex getOtherVertex(Vertex v) + { + if (v == start) + { + return end; + } + if (v == end) + { + return start; + } + return null; + } + + /** + * Gets the vertices attribute of the EdgeImpl object + */ + public Set getVertices() + { + Set RC = new HashSet(); + RC.add(start); + RC.add(end); + return RC; + } + + /** + * Gets the source attribute of the EdgeImpl object + */ + public Vertex getSource() + { + return start; + } + + /** + * Gets the target attribute of the EdgeImpl object + */ + public Vertex getTarget() + { + return end; + } + + /** + * Description of the Method + */ + public String toString() + { + return start.toString() + " <-> " + end.toString(); + } + } + + /** + * Description of the Field + */ + public Vertex V1 = new VertexImpl("V1"); + /** + * Description of the Field + */ + public Vertex V2 = new VertexImpl("V2"); + /** + * Description of the Field + */ + public Vertex V3 = new VertexImpl("V3"); + /** + * Description of the Field + */ + public Vertex V4 = new VertexImpl("V4"); + /** + * Description of the Field + */ + public Vertex V5 = new VertexImpl("V5"); + + /** + * Description of the Field + */ + public EdgeImpl V1_V1 = new EdgeImpl(V1, V1);// For Self-Loops. + /** + * Description of the Field + */ + public EdgeImpl V1_V2 = new EdgeImpl(V1, V2); + /** + * Description of the Field + */ + public EdgeImpl V1_V2_ = new EdgeImpl(V1, V2);// For Parallel + /** + * Description of the Field + */ + public EdgeImpl V1_V2__ = new EdgeImpl(V1, V2);// For Parallel #2 + /** + * Description of the Field + */ + public EdgeImpl V1_V3 = new EdgeImpl(V1, V3); + /** + * Description of the Field + */ + public EdgeImpl V1_V4 = new EdgeImpl(V1, V4); + /** + * Description of the Field + */ + public EdgeImpl V1_V5 = new EdgeImpl(V1, V5); + + /** + * Description of the Field + */ + public EdgeImpl V2_V1 = new EdgeImpl(V2, V1); + /** + * Description of the Field + */ + public EdgeImpl V2_V3 = new EdgeImpl(V2, V3); + /** + * Description of the Field + */ + public EdgeImpl V2_V4 = new EdgeImpl(V2, V4); + /** + * Description of the Field + */ + public EdgeImpl V2_V5 = new EdgeImpl(V2, V5); + + /** + * Description of the Field + */ + public EdgeImpl V3_V1 = new EdgeImpl(V3, V1); + /** + * Description of the Field + */ + public EdgeImpl V3_V2 = new EdgeImpl(V3, V2); + /** + * Description of the Field + */ + public EdgeImpl V3_V4 = new EdgeImpl(V3, V4); + /** + * Description of the Field + */ + public EdgeImpl V3_V5 = new EdgeImpl(V3, V5); + + /** + * Description of the Field + */ + public EdgeImpl V4_V1 = new EdgeImpl(V4, V1); + /** + * Description of the Field + */ + public EdgeImpl V4_V2 = new EdgeImpl(V4, V2); + /** + * Description of the Field + */ + public EdgeImpl V4_V3 = new EdgeImpl(V4, V3); + /** + * Description of the Field + */ + public EdgeImpl V4_V5 = new EdgeImpl(V4, V5); + + /** + * Description of the Field + */ + public EdgeImpl V5_V1 = new EdgeImpl(V5, V1); + /** + * Description of the Field + */ + public EdgeImpl V5_V2 = new EdgeImpl(V5, V2); + /** + * Description of the Field + */ + public EdgeImpl V5_V3 = new EdgeImpl(V5, V3); + /** + * Description of the Field + */ + public EdgeImpl V5_V4 = new EdgeImpl(V5, V4); + + /** + * Constructor for the GraphTest object + * + * @param name + */ + public GraphTest(String name) + { + super(name); + this.testName = name; + } + + private String testName = null; + + /** + * Return this graph: () + */ + public UndirectedGraph makeNullGraph() + throws GraphException + { + return new UndirectedGraphImpl(); + } + + /** + * Description of the Method + */ + public DirectedGraph makeDirNullGraph() + throws GraphException + { + return new DirectedGraphImpl(); + } + + /** + * Return this graph: v1 + */ + public UndirectedGraph makeSingleVertex() + throws GraphException + { + UndirectedGraphImpl RC = new UndirectedGraphImpl(); + RC.addVertex(V1); + return RC; + } + + /** + * Description of the Method + */ + public DirectedGraph makeDirSingleVertex() + throws GraphException + { + DirectedGraphImpl RC = new DirectedGraphImpl(); + RC.addVertex(V1); + return RC; + } + + /** + * /--\ v1 | ^--/ + */ + public DirectedGraph makeSelfLoop() + throws GraphException + { + DirectedGraphImpl RC = new DirectedGraphImpl(); + RC.addVertex(V1); + RC.addEdge(V1_V1, V1, V1); + return RC; + } + + /** + * v1 v2 Two Vertices, No Edges + */ + public UndirectedGraph makeDoubleVertex() + throws GraphException + { + UndirectedGraphImpl RC = new UndirectedGraphImpl(); + RC.addVertex(V1); + RC.addVertex(V2); + return RC; + } + + /** + * Description of the Method + */ + public DirectedGraph makeDirDoubleVertex() + throws GraphException + { + DirectedGraphImpl RC = new DirectedGraphImpl(); + RC.addVertex(V1); + RC.addVertex(V2); + return RC; + } + + /** + * v1-v2 Two Vertices, One edge + */ + public UndirectedGraph makeSingleEdge() + throws GraphException + { + UndirectedGraphImpl RC = new UndirectedGraphImpl(); + + RC.addVertex(V1); + RC.addVertex(V2); + + RC.addEdge(V1_V2, V1_V2.getVertices()); + + return RC; + } + + /** + * v1 -> v2 Directed Edge + */ + public DirectedGraph makeDirectedEdge() + throws GraphException + { + DirectedGraphImpl RC = new DirectedGraphImpl(); + + RC.addVertex(V1); + RC.addVertex(V2); + + RC.addEdge(V1_V2, + V1, V2); + + return RC; + } + + /** + * /-\ v1 v2 Two Vertices, Two Edges (Parallel Edges) \-/ + */ + public UndirectedGraph makeParallelEdges() + throws GraphException + { + UndirectedGraphImpl RC = new UndirectedGraphImpl(); + + RC.addVertex(V1); + RC.addVertex(V2); + + RC.addEdge(V1_V2, V1_V2.getVertices()); + RC.addEdge(V1_V2_, V1_V2_.getVertices()); + + return RC; + } + + /** + * /--->\ @ @ \--->/ + */ + public DirectedGraph makeDirParallelEdges() + throws GraphException + { + DirectedGraphImpl RC = new DirectedGraphImpl(); + + RC.addVertex(V1); + RC.addVertex(V2); + + RC.addEdge(V1_V2, V1, V2); + // Second edge must be distinct. . . + RC.addEdge(V1_V2_, V1, V2); + + return RC; + } + + /** + * v1 / \ Three Vertices, Three Edges (Cycle) v2---v3 + */ + public UndirectedGraph makeCycle() + throws GraphException + { + UndirectedGraphImpl RC = new UndirectedGraphImpl(); + + RC.addVertex(V1); + RC.addVertex(V2); + RC.addVertex(V3); + + RC.addEdge(V1_V2, V1_V2.getVertices()); + RC.addEdge(V2_V3, V2_V3.getVertices()); + RC.addEdge(V3_V1, V3_V1.getVertices()); + + return RC; + } + + /** + * /--->\ v1 v2 \<---/ + */ + public DirectedGraph makeTwoCycle() + throws GraphException + { + DirectedGraphImpl RC = new DirectedGraphImpl(); + + RC.addVertex(V1); + RC.addVertex(V2); + + RC.addEdge(V1_V2, V1, V2); + RC.addEdge(V2_V1, V2, V1); + + return RC; + } + + /** + * v1 / ^ v \ v2 ---> v3 + */ + public DirectedGraph makeDirectedCycle() + throws GraphException + { + DirectedGraphImpl RC = new DirectedGraphImpl(); + + RC.addVertex(V1); + RC.addVertex(V2); + RC.addVertex(V3); + + RC.addEdge(V1_V2, V1, V2); + RC.addEdge(V2_V3, V2, V3); + RC.addEdge(V3_V1, V3, V1); + + return RC; + } + + /** + * v1--v2--v3 Three Vertices, Two Edges (No Cycle) + */ + public UndirectedGraph makeNoCycle() + throws GraphException + { + UndirectedGraphImpl RC = new UndirectedGraphImpl(); + + RC.addVertex(V1); + RC.addVertex(V2); + RC.addVertex(V3); + + RC.addEdge(V1_V2, V1_V2.getVertices()); + RC.addEdge(V2_V3, V2_V3.getVertices()); + + return RC; + } + + /** + * v1 --> v2 --> v3 + */ + public DirectedGraph makePipe() + throws GraphException + { + DirectedGraphImpl RC = new DirectedGraphImpl(); + + RC.addVertex(V1); + RC.addVertex(V2); + RC.addVertex(V3); + + RC.addEdge(V1_V2, V1, V2); + RC.addEdge(V2_V3, V2, V3); + + return RC; + } + + /** + * v1 / \ v v v2 v3 \ / v v v4 + */ + public DirectedGraph makeDiamond() + throws GraphException + { + DirectedGraphImpl RC = new DirectedGraphImpl(); + + RC.addVertex(V1); + RC.addVertex(V2); + RC.addVertex(V3); + RC.addVertex(V4); + + RC.addEdge(V1_V2, V1, V2); + RC.addEdge(V1_V3, V1, V3); + RC.addEdge(V2_V4, V2, V4); + RC.addEdge(V3_V4, V3, V4); + + return RC; + } + + /** + * v1 / \ v v v2 v3 ^ ^ \ / v4 + */ + public DirectedGraph makePipelessCycle() + throws GraphException + { + DirectedGraphImpl RC = new DirectedGraphImpl(); + + RC.addVertex(V1); + RC.addVertex(V2); + RC.addVertex(V3); + RC.addVertex(V4); + + RC.addEdge(V1_V2, V1, V2); + RC.addEdge(V1_V3, V1, V3); + RC.addEdge(V4_V2, V4, V2); + RC.addEdge(V4_V3, V4, V3); + + return RC; + } + + /** + * v1 / \ v2 v3 5 Vertices, 4 Edges (Tree) / \ v4 v5 + */ + public UndirectedGraph makeTree() + throws GraphException + { + UndirectedGraphImpl RC = new UndirectedGraphImpl(); + + RC.addVertex(V1); + RC.addVertex(V2); + RC.addVertex(V3); + RC.addVertex(V4); + RC.addVertex(V5); + + RC.addEdge(V1_V2, V1_V2.getVertices()); + RC.addEdge(V1_V3, V1_V3.getVertices()); + RC.addEdge(V3_V4, V3_V4.getVertices()); + RC.addEdge(V3_V5, V3_V5.getVertices()); + + return RC; + } + + /** + * Description of the Method + */ + public DirectedGraph makeParentTree() + throws GraphException + { + DirectedGraphImpl RC = new DirectedGraphImpl(); + + RC.addVertex(V1); + RC.addVertex(V2); + RC.addVertex(V3); + RC.addVertex(V4); + RC.addVertex(V5); + + RC.addEdge(V2_V1, V2, V1); + RC.addEdge(V3_V1, V3, V1); + RC.addEdge(V4_V3, V4, V3); + RC.addEdge(V5_V3, V5, V3); + + return RC; + } + + /** + * Description of the Method + */ + public DirectedGraph makeChildTree() + throws GraphException + { + DirectedGraphImpl RC = new DirectedGraphImpl(); + + RC.addVertex(V1); + RC.addVertex(V2); + RC.addVertex(V3); + RC.addVertex(V4); + RC.addVertex(V5); + + RC.addEdge(V1_V2, V1, V2); + RC.addEdge(V1_V3, V1, V3); + RC.addEdge(V3_V4, V3, V4); + RC.addEdge(V3_V5, V3, V5); + + return RC; + } + + /** + * v1-v2 v3-v4 4 Vertices, 2 Edges (Disconnected) + */ + public UndirectedGraph makeDisconnected() + throws GraphException + { + UndirectedGraphImpl RC = new UndirectedGraphImpl(); + + RC.addVertex(V1); + RC.addVertex(V2); + RC.addVertex(V3); + RC.addVertex(V4); + + RC.addEdge(V1_V2, V1_V2.getVertices()); + RC.addEdge(V3_V4, V3_V4.getVertices()); + + return RC; + } + + /** + * A unit test for JUnit + */ + public void testNothing() + throws Throwable { } + + /** + * Description of the Method + */ + public void verifyVertexEdgeCount(Graph IUT, + Vertex v, + int numEdge) + throws Throwable + { + assertEquals(v.toString() + " has wrong number of adjacent edges.", + IUT.getEdges(v).size(), numEdge); + } + + /** + * Gets the outboundVertices attribute of the GraphTest object + */ + private Set getOutboundVertices(DirectedGraph IUT, + Vertex v) + { + Set RC = new HashSet(); + Iterator edges = IUT.getOutbound(v).iterator(); + + while (edges.hasNext()) + { + Edge e = (Edge) edges.next(); + RC.add(IUT.getTarget(e)); + } + + return RC; + } + + /** + * Gets the inboundVertices attribute of the GraphTest object + */ + private Set getInboundVertices(DirectedGraph IUT, + Vertex v) + { + Set RC = new HashSet(); + Iterator edges = IUT.getInbound(v).iterator(); + + while (edges.hasNext()) + { + Edge e = (Edge) edges.next(); + RC.add(IUT.getSource(e)); + } + + return RC; + } + + + /** + * Gets the adjVertices attribute of the GraphTest object + */ + private Set getAdjVertices(Graph IUT, + Vertex v) + { + Set RC = new HashSet(); + Iterator edges = IUT.getEdges(v).iterator(); + + while (edges.hasNext()) + { + Edge e = (Edge) edges.next(); + + Set verts = IUT.getVertices(e); + RC.addAll(verts); + } + + return RC; + } + + /** + * Description of the Method + */ + public Set makeSet() + { + return new HashSet(); + } + + /** + * Description of the Method + */ + public Set makeSet(Vertex v) + { + Set RC = new HashSet(); + RC.add(v); + return RC; + } + + /** + * Description of the Method + */ + public Set makeSet(Vertex v1, + Vertex v2) + { + Set RC = makeSet(v1); + RC.add(v2); + return RC; + } + + /** + * Description of the Method + */ + public Set makeSet(Set s1, + Set s2) + { + Set RC = new HashSet(); + RC.addAll(s1); + RC.addAll(s2); + return RC; + } + + /** + * Description of the Method + */ + public Set makeSet(Vertex v1, + Vertex v2, + Vertex v3) + { + return makeSet(makeSet(v1, v2), + makeSet(v3)); + } + + /** + * Description of the Method + */ + public Set makeSet(Vertex v1, + Vertex v2, + Vertex v3, + Vertex v4) + { + return makeSet(makeSet(v1, v2), + makeSet(v3, v4)); + } + + + /** + * Description of the Method + */ + public void verifyAdjVertices(DirectedGraph IUT, + Vertex v, + Set inExpect, + Set outExpect) + { + Set inbound = getInboundVertices(IUT, v); + Set outbound = getOutboundVertices(IUT, v); + + Iterator verts; + + // inbound is a subset of inExpect + verts = inbound.iterator(); + + while (verts.hasNext()) + { + Vertex curr = (Vertex) verts.next(); + + assertTrue(curr.toString() + " is not supposed to be " + + "next to " + v.toString(), + inExpect.contains(curr)); + } + + // inExpect is a subset of inbound + verts = inExpect.iterator(); + + while (verts.hasNext()) + { + Vertex curr = (Vertex) verts.next(); + assertTrue(curr.toString() + " is supposed to be next to " + + v.toString(), + inbound.contains(curr)); + } + + // outbound is a subset of outExpect + verts = outbound.iterator(); + + while (verts.hasNext()) + { + Vertex curr = (Vertex) verts.next(); + + assertTrue(curr.toString() + " is not supposed to be " + + "next to " + v.toString(), + outExpect.contains(curr)); + } + + // outExpect is a subset of outbound + verts = outExpect.iterator(); + + while (verts.hasNext()) + { + Vertex curr = (Vertex) verts.next(); + assertTrue(curr.toString() + " is supposed to be next to " + + v.toString(), + outbound.contains(curr)); + } + + } + + /** + * Description of the Method + */ + public void verifyAdjVertices(Graph IUT, + Vertex v, + Set expected) + throws Throwable + { + Set adjacent = getAdjVertices(IUT, v); + Iterator adjV = adjacent.iterator(); + + while (adjV.hasNext()) + { + Vertex curr = (Vertex) adjV.next(); + assertTrue(curr.toString() + " is not supposed to be " + + "next to " + v.toString(), + expected.contains(curr)); + } + + Iterator expect = expected.iterator(); + + while (expect.hasNext()) + { + Vertex curr = (Vertex) expect.next(); + assertTrue(curr.toString() + " is supposed to be next to " + + v.toString(), + adjacent.contains(curr)); + } + } + + /** + * Description of the Method + */ + public void verifyGraph(Graph g, int numVertex, int numEdge) + throws Throwable + { + assertEquals("Incorrect Number of Vertices.", + numVertex, g.getVertices().size()); + assertEquals("Incorrect Number of Edges.", + numEdge, g.getEdges().size()); + } + + /** + * Description of the Method + */ + public void printGraph(Throwable t, + DirectedGraph IUT) + { + System.err.println(testName + ": " + t.toString()); + System.err.println("VERTICES: " + IUT.getVertices()); + System.err.println("EDGES: " + IUT.getEdges()); + + Iterator verts = IUT.getVertices().iterator(); + while (verts.hasNext()) + { + Vertex vert = (Vertex) verts.next(); + System.err.println("[ " + vert + " ]"); + + Iterator inbounds = IUT.getInbound(vert).iterator(); + while (inbounds.hasNext()) + { + Edge inbound = (Edge) inbounds.next(); + System.err.println("\tI [" + inbound + "]"); + } + + Iterator outbounds = IUT.getOutbound(vert).iterator(); + while (outbounds.hasNext()) + { + Edge outbound = (Edge) outbounds.next(); + System.err.println("\tO [" + outbound + "]"); + } + } + } + +} diff --git a/src/test/org/apache/commons/graph/UndirGraphTest.java b/src/test/org/apache/commons/graph/UndirGraphTest.java new file mode 100644 index 0000000..c94ed06 --- /dev/null +++ b/src/test/org/apache/commons/graph/UndirGraphTest.java @@ -0,0 +1,379 @@ +package org.apache.commons.graph; + +/* ==================================================================== + * 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 + * "Commons" 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", + * "Commons", 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 + * . + */ +/** + * GraphTest This test will ensure that we can indeed represent a graph. We will + * implement the following graphs. () No Vertex, No Edges @ One Vertex, No Edges + * @ @ Two Vertices, No Edges @-@ Two Vertices, One edge /-\ @ @ Two Vertices, + * Two Edges (Parallel Edges) \-/ @ / \ Three Vertices, Three Edges (Cycle) + * @---@ @--@--@ Three Vertices, Two Edges (No Cycle) @ / \ @ @ 5 Vertices, 4 + * Edges (Tree) / \ @ @ @-@ @-@ 4 Vertices, 2 Edges (Disconnected) + */ + +import java.util.Set; +import java.util.Map; +import java.util.HashSet; +import java.util.HashMap; +import java.util.Iterator; + +import junit.framework.*; + +/** + * Description of the Class + */ +public class UndirGraphTest extends GraphTest +{ + /** + * Constructor for the UndirGraphTest object + * + * @param name + */ + public UndirGraphTest(String name) + { + super(name); + } + + /** + * Test the NULL Graph. + */ + public void testNullGraph() + throws Throwable + { + verifyGraph(makeNullGraph(), 0, 0); + } + + + /** + * Test the Single Vertex. + */ + public void testSingleVertex() + throws Throwable + { + verifyGraph(makeSingleVertex(), 1, 0); + } + + /** + * Tests Double Vertex graph. + */ + public void testDoubleVertex() + throws Throwable + { + verifyGraph(makeDoubleVertex(), 2, 0); + } + + /** + * Test Single Edge Graph. + */ + public void testSingleEdge() + throws Throwable + { + Graph IUT = makeSingleEdge(); + + verifyGraph(IUT, 2, 1); + + // Verify Edge from Vertex Count + verifyVertexEdgeCount(IUT, V1, 1); + verifyVertexEdgeCount(IUT, V2, 1); + + Set expectV1 = new HashSet(); + expectV1.add(V2); + + verifyAdjVertices(IUT, V1, expectV1); + + Set expectV2 = new HashSet(); + expectV2.add(V1); + + verifyAdjVertices(IUT, V2, expectV2); + } + + /** + * Test Parallel Edges, make sure the representation is right. + */ + public void testParallelEdges() + throws Throwable + { + Graph IUT = makeParallelEdges(); + + verifyGraph(IUT, 2, 2); + + // Verify Edge from Vertex Count + verifyVertexEdgeCount(IUT, V1, 2); + verifyVertexEdgeCount(IUT, V2, 2); + + // Verify Adjacent Vertex + Set expectV1 = new HashSet(); + Set expectV2 = new HashSet(); + + expectV1.add(V2); + expectV2.add(V1); + + verifyAdjVertices(IUT, V1, expectV1); + verifyAdjVertices(IUT, V2, expectV2); + + } + + /** + * Test the Cycle Graph. + */ + public void testCycle() + throws Throwable + { + Graph IUT = makeCycle(); + + verifyGraph(IUT, 3, 3); + + // Verify Edge from Vertex Count + verifyVertexEdgeCount(IUT, V1, 2); + verifyVertexEdgeCount(IUT, V2, 2); + verifyVertexEdgeCount(IUT, V3, 2); + + // Verify Adjacent Vertex + Set expectV1 = new HashSet(); + Set expectV2 = new HashSet(); + Set expectV3 = new HashSet(); + + expectV1.add(V2); + expectV1.add(V3); + expectV2.add(V1); + expectV2.add(V3); + expectV3.add(V1); + expectV3.add(V2); + + verifyAdjVertices(IUT, V1, expectV1); + verifyAdjVertices(IUT, V2, expectV2); + verifyAdjVertices(IUT, V3, expectV3); + } + + /** + * Test the No Cycle Graph. + */ + public void testNoCycle() + throws Throwable + { + Graph IUT = makeNoCycle(); + + verifyGraph(IUT, 3, 2); + + // Verify Edge from Vertex Count + verifyVertexEdgeCount(IUT, V1, 1); + verifyVertexEdgeCount(IUT, V2, 2); + verifyVertexEdgeCount(IUT, V3, 1); + + // Verify Adjacent Vertex + Set expectV1 = new HashSet(); + Set expectV2 = new HashSet(); + Set expectV3 = new HashSet(); + + expectV1.add(V2); + expectV2.add(V1); + expectV2.add(V3); + expectV3.add(V2); + + verifyAdjVertices(IUT, V1, expectV1); + verifyAdjVertices(IUT, V2, expectV2); + verifyAdjVertices(IUT, V3, expectV3); + } + + /** + * Test the Tree Graph. + */ + public void testTree() + throws Throwable + { + Graph IUT = makeTree(); + + verifyGraph(IUT, 5, 4); + + // Verify Edge from Vertex Count + verifyVertexEdgeCount(IUT, V1, 2); + verifyVertexEdgeCount(IUT, V2, 1); + verifyVertexEdgeCount(IUT, V3, 3); + verifyVertexEdgeCount(IUT, V4, 1); + verifyVertexEdgeCount(IUT, V5, 1); + + // Verify Adjacent Vertex + Set expectV1 = new HashSet(); + Set expectV2 = new HashSet(); + Set expectV3 = new HashSet(); + Set expectV4 = new HashSet(); + Set expectV5 = new HashSet(); + + expectV1.add(V2); + expectV1.add(V3); + expectV2.add(V1); + expectV3.add(V1); + expectV3.add(V4); + expectV3.add(V5); + expectV4.add(V3); + expectV5.add(V3); + + verifyAdjVertices(IUT, V1, expectV1); + verifyAdjVertices(IUT, V2, expectV2); + verifyAdjVertices(IUT, V3, expectV3); + verifyAdjVertices(IUT, V4, expectV4); + verifyAdjVertices(IUT, V5, expectV5); + } + + /** + * Test the Disconnected Graph. + */ + public void testDisconnected() + throws Throwable + { + Graph IUT = makeDisconnected(); + + verifyGraph(IUT, 4, 2); + + // Verify Edge from Vertex Count + verifyVertexEdgeCount(IUT, V1, 1); + verifyVertexEdgeCount(IUT, V2, 1); + verifyVertexEdgeCount(IUT, V3, 1); + verifyVertexEdgeCount(IUT, V4, 1); + + // Verify Adjacent Vertex + Set expectV1 = new HashSet(); + Set expectV2 = new HashSet(); + Set expectV3 = new HashSet(); + Set expectV4 = new HashSet(); + + expectV1.add(V2); + expectV2.add(V1); + expectV3.add(V4); + expectV4.add(V3); + + verifyAdjVertices(IUT, V1, expectV1); + verifyAdjVertices(IUT, V2, expectV2); + verifyAdjVertices(IUT, V3, expectV3); + verifyAdjVertices(IUT, V4, expectV4); + } + + + /** + * Description of the Method + */ + public void verifyVertexEdgeCount(Graph IUT, + Vertex v, + int numEdge) + throws Throwable + { + assertEquals(v.toString() + " has wrong number of adjacent edges.", + IUT.getEdges(v).size(), numEdge); + } + + /** + * Gets the adjVertices attribute of the UndirGraphTest object + */ + private Set getAdjVertices(Graph IUT, + Vertex v) + { + Set RC = new HashSet(); + Iterator edges = IUT.getEdges(v).iterator(); + + while (edges.hasNext()) + { + Edge e = (Edge) edges.next(); + + Set verts = IUT.getVertices(e); + verts.remove(v); + RC.addAll(verts); + } + + return RC; + } + + /** + * Description of the Method + */ + public void verifyAdjVertices(Graph IUT, + Vertex v, + Set expected) + throws Throwable + { + Set adjacent = getAdjVertices(IUT, v); + Iterator adjV = adjacent.iterator(); + + while (adjV.hasNext()) + { + Vertex curr = (Vertex) adjV.next(); + + assertTrue(curr.toString() + " is not supposed to be " + + "next to " + v.toString(), + expected.contains(curr)); + } + + Iterator expect = expected.iterator(); + + while (expect.hasNext()) + { + Vertex curr = (Vertex) expect.next(); + + assertTrue(curr.toString() + " is supposed to be next to " + + v.toString(), + adjacent.contains(curr)); + } + } + + /** + * Description of the Method + */ + public void verifyGraph(Graph g, int numVertex, int numEdge) + throws Throwable + { + assertEquals("Incorrect Number of Vertices.", + g.getVertices().size(), numVertex); + assertEquals("Incorrect Number of Edges.", + g.getEdges().size(), numEdge); + } +} diff --git a/src/test/org/apache/commons/graph/WeightedGraphTest.java b/src/test/org/apache/commons/graph/WeightedGraphTest.java new file mode 100644 index 0000000..ad02a18 --- /dev/null +++ b/src/test/org/apache/commons/graph/WeightedGraphTest.java @@ -0,0 +1,567 @@ +package org.apache.commons.graph; + +/* ==================================================================== + * 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 + * "Commons" 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", + * "Commons", 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 + * . + */ + +/** + * WeightedGraphTest This class will test Weighted Graphs, and make sure they + * are possible. + */ + +import org.apache.commons.graph.impl.*; +import org.apache.commons.graph.exception.*; + +/** + * Description of the Class + */ +public class WeightedGraphTest + extends DirGraphTest +{ + /** + * Constructor for the WeightedGraphTest object + * + * @param name + */ + public WeightedGraphTest(String name) + { + super(name); + } + + /** + * 5.0 + * + * @---------> @ + */ + public DirectedGraphImpl makeWDirectedEdge() + throws GraphException + { + DirectedGraphImpl RC = + (DirectedGraphImpl) makeDirectedEdge(); + RC.setWeight(V1_V2, 5.0); + return RC; + } + + /** + * A unit test for JUnit + */ + public void testWDirectedEdge() + throws Throwable + { + DirectedGraphImpl IUT = makeWDirectedEdge(); + + verifyGraph(IUT, 2, 1); + assertEquals("Wrong Weight on V1->V2", + 5.0, IUT.getWeight(V1_V2), 0.00001); + } + + /** + * /----\ / 5.0 \ @ | \ / \----/ + */ + public DirectedGraphImpl makeWSelfLoop() + throws GraphException + { + DirectedGraphImpl RC = + (DirectedGraphImpl) makeSelfLoop(); + RC.setWeight(V1_V1, 5.0); + return RC; + } + + /** + * A unit test for JUnit + */ + public void testWSelfLoop() + throws Throwable + { + DirectedGraphImpl IUT = makeWSelfLoop(); + + verifyGraph(IUT, 1, 1); + assertEquals("Wrong Weight on V1->V1", + 5.0, IUT.getWeight(V1_V1), 0.00001); + } + + /** + * v1 / ^ 2.0 / \ 1.5 v \ v2------->v3 4.0 + */ + public DirectedGraphImpl makePositiveCycle() + throws GraphException + { + DirectedGraphImpl RC = + (DirectedGraphImpl) makeDirectedCycle(); + + RC.setWeight(V1_V2, 2.0); + RC.setWeight(V2_V3, 4.0); + RC.setWeight(V3_V1, 1.5); + + return RC; + } + + /** + * A unit test for JUnit + */ + public void testPositiveCycle() + throws Throwable + { + DirectedGraphImpl IUT = makePositiveCycle(); + verifyGraph(IUT, 3, 3); + + assertEquals("Wrong Weight on V1->V2", + IUT.getWeight(V1_V2), 2.0, 0.00001); + + assertEquals("Wrong Weight on V2->V3", + IUT.getWeight(V2_V3), 4.0, 0.00001); + + assertEquals("Wrong Weight on V1->V2", + IUT.getWeight(V3_V1), 1.5, 0.00001); + } + + /** + * v1 / ^ 2.0 / \ - 1.5 v \ v2------->v3 4.0 + */ + public DirectedGraphImpl makePositivePartNegCycle() + throws GraphException + { + DirectedGraphImpl RC = + (DirectedGraphImpl) makeDirectedCycle(); + + RC.setWeight(V1_V2, 2.0); + RC.setWeight(V2_V3, 4.0); + RC.setWeight(V3_V1, -1.5); + + return RC; + } + + /** + * A unit test for JUnit + */ + public void testPositivePartNegCycle() + throws Throwable + { + DirectedGraphImpl IUT = makePositivePartNegCycle(); + verifyGraph(IUT, 3, 3); + + assertEquals("Wrong Weight on V1->V2", + IUT.getWeight(V1_V2), 2.0, 0.00001); + + assertEquals("Wrong Weight on V2->V3", + IUT.getWeight(V2_V3), 4.0, 0.00001); + + assertEquals("Wrong Weight on V1->V2", + IUT.getWeight(V3_V1), -1.5, 0.00001); + } + + /** + * v1 / ^ - 2.0 / \ - 1.5 v \ v2------->v3 - 4.0 + */ + public DirectedGraphImpl makeNegativeCycle() + throws GraphException + { + DirectedGraphImpl RC = + (DirectedGraphImpl) makeDirectedCycle(); + + RC.setWeight(V1_V2, -2.0); + RC.setWeight(V2_V3, -4.0); + RC.setWeight(V3_V1, -1.5); + + return RC; + } + + /** + * A unit test for JUnit + */ + public void testNegativeCycle() + throws Throwable + { + DirectedGraphImpl IUT = makeNegativeCycle(); + verifyGraph(IUT, 3, 3); + + assertEquals("Wrong Weight on V1->V2", + IUT.getWeight(V1_V2), -2.0, 0.00001); + + assertEquals("Wrong Weight on V2->V3", + IUT.getWeight(V2_V3), -4.0, 0.00001); + + assertEquals("Wrong Weight on V1->V2", + IUT.getWeight(V3_V1), -1.5, 0.00001); + } + + /** + * v1 / ^ - 2.0 / \ 1.5 v \ v2------->v3 - 4.0 + */ + public DirectedGraphImpl makeNegativePartPosCycle() + throws GraphException + { + DirectedGraphImpl RC = + (DirectedGraphImpl) makeDirectedCycle(); + + RC.setWeight(V1_V2, -2.0); + RC.setWeight(V2_V3, -4.0); + RC.setWeight(V3_V1, 1.5); + + return RC; + } + + /** + * A unit test for JUnit + */ + public void testNegativePartPosCycle() + throws Throwable + { + DirectedGraphImpl IUT = makeNegativePartPosCycle(); + verifyGraph(IUT, 3, 3); + + assertEquals("Wrong Weight on V1->V2", + IUT.getWeight(V1_V2), -2.0, 0.00001); + + assertEquals("Wrong Weight on V2->V3", + IUT.getWeight(V2_V3), -4.0, 0.00001); + + assertEquals("Wrong Weight on V1->V2", + IUT.getWeight(V3_V1), 1.5, 0.00001); + } + + /** + * 1.5 3.5 v1 ---> v2 --->v3 + */ + public DirectedGraphImpl makePositivePipe() + throws GraphException + { + DirectedGraphImpl RC = + (DirectedGraphImpl) makePipe(); + + RC.setWeight(V1_V2, 1.5); + RC.setWeight(V2_V3, 3.5); + + return RC; + } + + /** + * A unit test for JUnit + */ + public void testPositivePipe() + throws Throwable + { + DirectedGraphImpl IUT = makePositivePipe(); + verifyGraph(IUT, 3, 2); + + assertEquals("Wrong Weight on V1->V2", + IUT.getWeight(V1_V2), 1.5, 0.00001); + + assertEquals("Wrong Weight on V2->V3", + IUT.getWeight(V2_V3), 3.5, 0.00001); + } + + /** + * -1.5 3.5 v1 ---> v2 --->v3 + */ + public DirectedGraphImpl makePositivePartNegPipe() + throws GraphException + { + DirectedGraphImpl RC = + (DirectedGraphImpl) makePipe(); + + RC.setWeight(V1_V2, -1.5); + RC.setWeight(V2_V3, 3.5); + + return RC; + } + + /** + * A unit test for JUnit + */ + public void testPositivePartNegPipe() + throws Throwable + { + DirectedGraphImpl IUT = makePositivePartNegPipe(); + verifyGraph(IUT, 3, 2); + + assertEquals("Wrong Weight on V1->V2", + IUT.getWeight(V1_V2), -1.5, 0.00001); + + assertEquals("Wrong Weight on V2->V3", + IUT.getWeight(V2_V3), 3.5, 0.00001); + } + + + /** + * -1.5 -3.5 v1 ---> v2 --->v3 + */ + public DirectedGraphImpl makeNegativePipe() + throws GraphException + { + DirectedGraphImpl RC = + (DirectedGraphImpl) makePipe(); + + RC.setWeight(V1_V2, -1.5); + RC.setWeight(V2_V3, -3.5); + + return RC; + } + + /** + * A unit test for JUnit + */ + public void testNegativePipe() + throws Throwable + { + DirectedGraphImpl IUT = makeNegativePipe(); + verifyGraph(IUT, 3, 2); + + assertEquals("Wrong Weight on V1->V2", + IUT.getWeight(V1_V2), -1.5, 0.0001); + + assertEquals("Wrong Weight on V2->V3", + IUT.getWeight(V2_V3), -3.5, 0.0001); + } + + /** + * 1.5 -3.5 v1 ---> v2 --->v3 + */ + public DirectedGraphImpl makeNegativePartPosPipe() + throws GraphException + { + DirectedGraphImpl RC = + (DirectedGraphImpl) makePipe(); + + RC.setWeight(V1_V2, 1.5); + RC.setWeight(V2_V3, -3.5); + + return RC; + } + + /** + * A unit test for JUnit + */ + public void testNegativePartPosPipe() + throws Throwable + { + DirectedGraphImpl IUT = makeNegativePartPosPipe(); + verifyGraph(IUT, 3, 2); + + assertEquals("Wrong Weight on V1->V2", + IUT.getWeight(V1_V2), 1.5, 0.0001); + + assertEquals("Wrong Weight on V2->V3", + IUT.getWeight(V2_V3), -3.5, 0.0001); + } + + + /** + * v1 1.5 / \ 2.5 v v v2 v3 1.5 \ / 2.5 vv v4 + */ + + public DirectedGraphImpl makeMultiplePathL() + throws GraphException + { + DirectedGraphImpl RC = + (DirectedGraphImpl) makeDiamond(); + + RC.setWeight(V1_V2, 1.5); + RC.setWeight(V2_V4, 1.5); + + RC.setWeight(V1_V3, 2.5); + RC.setWeight(V3_V4, 2.5); + + return RC; + } + + /** + * A unit test for JUnit + */ + public void testMultiplePathL() + throws Throwable + { + DirectedGraphImpl IUT = makeMultiplePathL(); + verifyGraph(IUT, 4, 4); + + assertEquals("Wrong Weight on V1->V2", + IUT.getWeight(V1_V2), 1.5, 0.0001); + + assertEquals("Wrong Weight on V2->V4", + IUT.getWeight(V2_V4), 1.5, 0.0001); + + assertEquals("Wrong Weight on V1->V3", + IUT.getWeight(V1_V3), 2.5, 0.0001); + + assertEquals("Wrong Weight on V3->V4", + IUT.getWeight(V3_V4), 2.5, 0.0001); + } + + + /** + * v1 2.5 / \ 1.5 v v v2 v3 2.5 \ / 1.5 vv v4 + */ + + public DirectedGraphImpl makeMultiplePathR() + throws GraphException + { + DirectedGraphImpl RC = + (DirectedGraphImpl) makeDiamond(); + + RC.setWeight(V1_V2, 2.5); + RC.setWeight(V2_V4, 2.5); + + RC.setWeight(V1_V3, 1.5); + RC.setWeight(V3_V4, 1.5); + + return RC; + } + + /** + * A unit test for JUnit + */ + public void testMultiplePathR() + throws Throwable + { + DirectedGraphImpl IUT = makeMultiplePathR(); + verifyGraph(IUT, 4, 4); + + assertEquals("Wrong Weight on V1->V2", + IUT.getWeight(V1_V2), 2.5, 0.0001); + + assertEquals("Wrong Weight on V2->V4", + IUT.getWeight(V2_V4), 2.5, 0.0001); + + assertEquals("Wrong Weight on V1->V3", + IUT.getWeight(V1_V3), 1.5, 0.0001); + + assertEquals("Wrong Weight on V3->V4", + IUT.getWeight(V3_V4), 1.5, 0.0001); + } + + + /** + * v1 10.0 / \ 0.5 v v v2 v3 10.0 \ / 10.5 vv v4 + */ + + public DirectedGraphImpl makeMultiplePathEarlyLow() + throws GraphException + { + DirectedGraphImpl RC = + (DirectedGraphImpl) makeDiamond(); + + RC.setWeight(V1_V2, 10.0); + RC.setWeight(V2_V4, 10.0); + + RC.setWeight(V1_V3, 0.5); + RC.setWeight(V3_V4, 10.5); + + return RC; + } + + /** + * A unit test for JUnit + */ + public void testMultiplePathEarlyLow() + throws Throwable + { + DirectedGraphImpl IUT = makeMultiplePathEarlyLow(); + verifyGraph(IUT, 4, 4); + + assertEquals("Wrong Weight on V1->V2", + IUT.getWeight(V1_V2), 10.0, 0.0001); + + assertEquals("Wrong Weight on V2->V4", + IUT.getWeight(V2_V4), 10.0, 0.0001); + + assertEquals("Wrong Weight on V1->V3", + IUT.getWeight(V1_V3), 0.5, 0.0001); + + assertEquals("Wrong Weight on V3->V4", + IUT.getWeight(V3_V4), 10.5, 0.0001); + } + + + /** + * v1 10.0 / \ 10.5 v v v2 v3 10.0 \ / 0.5 vv v4 + */ + + public DirectedGraphImpl makeMultiplePathEarlyHigh() + throws GraphException + { + DirectedGraphImpl RC = + (DirectedGraphImpl) makeDiamond(); + + RC.setWeight(V1_V2, 10.0); + RC.setWeight(V2_V4, 10.0); + + RC.setWeight(V1_V3, 10.5); + RC.setWeight(V3_V4, 0.5); + + return RC; + } + + + /** + * A unit test for JUnit + */ + public void testMultiplePathEarlyHigh() + throws Throwable + { + DirectedGraphImpl IUT = makeMultiplePathEarlyHigh(); + verifyGraph(IUT, 4, 4); + + assertEquals("Wrong Weight on V1->V2", + IUT.getWeight(V1_V2), 10.0, 0.0001); + + assertEquals("Wrong Weight on V2->V4", + IUT.getWeight(V2_V4), 10.0, 0.0001); + + assertEquals("Wrong Weight on V1->V3", + IUT.getWeight(V1_V3), 10.5, 0.0001); + + assertEquals("Wrong Weight on V3->V4", + IUT.getWeight(V3_V4), 0.5, 0.0001); + } + +} diff --git a/src/test/org/apache/commons/graph/contract/AcyclicContractTest.java b/src/test/org/apache/commons/graph/contract/AcyclicContractTest.java new file mode 100644 index 0000000..a386786 --- /dev/null +++ b/src/test/org/apache/commons/graph/contract/AcyclicContractTest.java @@ -0,0 +1,461 @@ +package org.apache.commons.graph.contract; + +/* ==================================================================== + * 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 + * "Commons" 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", + * "Commons", 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 org.apache.commons.graph.*; +import org.apache.commons.graph.exception.*; + +/** + * Description of the Class + */ +public class AcyclicContractTest + extends GraphTest +{ + /** + * Constructor for the AcyclicContractTest object + * + * @param name + */ + public AcyclicContractTest(String name) + { + super(name); + } + + /** + * A unit test for JUnit + */ + public void testDirNullGraph() + throws Throwable + { + AcyclicContract IUT = + new AcyclicContract(); + IUT.setImpl(makeDirNullGraph()); + + IUT.verify(); + } + + /** + * A unit test for JUnit + */ + public void testDirSingleVertex() + throws Throwable + { + AcyclicContract IUT = + new AcyclicContract(); + IUT.setImpl(makeDirSingleVertex()); + IUT.verify(); + + try + { + IUT.addEdge(V1_V1, V1, V1); + fail("No GraphException thrown when Self-Cycle introduced."); + } + catch (CycleException ex) + {} + } + + /** + * A unit test for JUnit + */ + public void testSelfLoop() + throws Throwable + { + AcyclicContract IUT = + new AcyclicContract(); + IUT.setImpl(makeSelfLoop()); + + try + { + IUT.verify(); + fail("No CycleException thrown on Verification."); + } + catch (CycleException ex) + {} + } + + /** + * A unit test for JUnit + */ + public void testDirDoubleVertex() + throws Throwable + { + AcyclicContract IUT = + new AcyclicContract(); + IUT.setImpl(makeDirDoubleVertex()); + IUT.verify(); + + try + { + IUT.addEdge(V1_V1, V1, V1); + fail("No GraphException thrown when Self-Cycle introduced."); + } + catch (CycleException ex) + {} + + try + { + IUT.addEdge(V1_V2, V1, V2); + } + catch (GraphException ex) + { + fail("Contract prevented adding of valid edge. V1->V2"); + } + } + + + /** + * A unit test for JUnit + */ + public void testDirectedEdge() + throws Throwable + { + AcyclicContract IUT = + new AcyclicContract(); + IUT.setImpl(makeDirectedEdge()); + IUT.verify(); + + try + { + IUT.addEdge(V1_V1, V1, V1); + fail("No GraphException thrown when Self-Cycle introduced."); + } + catch (CycleException ex) + {} + + try + { + IUT.addEdge(V1_V2_, V1, V2); + } + catch (GraphException ex) + { + fail("Contract prevented adding of valid edge. V1->V2'"); + } + + try + { + IUT.addEdge(V2_V1, V2, V1); + fail("Contract allowed cycle to be introduced."); + } + catch (CycleException ex) + {} + } + + /** + * A unit test for JUnit + */ + public void testDirParallelEdges() + throws Throwable + { + AcyclicContract IUT = + new AcyclicContract(); + IUT.setImpl(makeDirParallelEdges()); + IUT.verify(); + + try + { + IUT.addEdge(V1_V1, V1, V1); + fail("No GraphException thrown when Self-Cycle introduced."); + } + catch (CycleException ex) + {} + + try + { + IUT.addEdge(V1_V2__, V1, V2); + } + catch (GraphException ex) + { + fail("Contract prevented adding of valid edge. V1->V2'"); + } + + try + { + IUT.addEdge(V2_V1, V2, V1); + fail("Contract allowed cycle to be introduced."); + } + catch (CycleException ex) + {} + } + + + /** + * A unit test for JUnit + */ + public void testTwoCycle() + throws Throwable + { + AcyclicContract IUT = + new AcyclicContract(); + IUT.setImpl(makeTwoCycle()); + + try + { + IUT.verify(); + fail("No CycleException thrown on Verification."); + } + catch (CycleException ex) + {} + } + + + /** + * A unit test for JUnit + */ + public void testDirectedCycle() + throws Throwable + { + AcyclicContract IUT = + new AcyclicContract(); + IUT.setImpl(makeDirectedCycle()); + + try + { + IUT.verify(); + fail("No CycleException thrown on Verification."); + } + catch (CycleException ex) + {} + } + + /** + * A unit test for JUnit + */ + public void testPipe() + throws Throwable + { + AcyclicContract IUT = + new AcyclicContract(); + IUT.setImpl(makePipe()); + IUT.verify(); + + try + { + IUT.addEdge(V1_V1, V1, V1); + fail("No GraphException thrown when Self-Cycle introduced."); + } + catch (CycleException ex) + {} + + try + { + IUT.addEdge(V1_V2_, V1, V2); + } + catch (GraphException ex) + { + fail("Contract prevented adding of valid edge. V1->V2'"); + } + + try + { + IUT.addEdge(V3_V1, V3, V1); + fail("Contract allowed cycle to be introduced."); + } + catch (CycleException ex) + {} + + } + + /** + * A unit test for JUnit + */ + public void testDiamond() + throws Throwable + { + AcyclicContract IUT = + new AcyclicContract(); + IUT.setImpl(makeDiamond()); + IUT.verify(); + + try + { + IUT.addEdge(V1_V1, V1, V1); + fail("No GraphException thrown when Self-Cycle introduced."); + } + catch (CycleException ex) + {} + + try + { + IUT.addEdge(V2_V3, V2, V3); + } + catch (GraphException ex) + { + fail("Contract prevented adding of valid edge. V2->V3"); + } + + try + { + IUT.addEdge(V4_V1, V4, V1); + fail("Contract allowed cycle to be introduced."); + } + catch (CycleException ex) + {} + } + + /** + * A unit test for JUnit + */ + public void testPipelessCycle() + throws Throwable + { + AcyclicContract IUT = + new AcyclicContract(); + IUT.setImpl(makePipelessCycle()); + IUT.verify(); + + try + { + IUT.addEdge(V1_V1, V1, V1); + fail("No GraphException thrown when Self-Cycle introduced."); + } + catch (CycleException ex) + {} + + try + { + IUT.addEdge(V2_V3, V2, V3); + } + catch (GraphException ex) + { + fail("Contract prevented adding of valid edge. V2->V3"); + } + + try + { + IUT.addEdge(V3_V4, V3, V4); + fail("Contract allowed cycle to be introduced."); + } + catch (CycleException ex) + {} + + } + + + /** + * A unit test for JUnit + */ + public void testParentTree() + throws Throwable + { + System.err.println("---- PARENT TREE ----"); + AcyclicContract IUT = + new AcyclicContract(); + IUT.setImpl(makeParentTree()); + IUT.verify(); + + try + { + IUT.addEdge(V1_V1, V1, V1); + fail("No GraphException thrown when Self-Cycle introduced."); + } + catch (CycleException ex) + {} + + try + { + IUT.addEdge(V2_V3, V2, V3); + } + catch (GraphException ex) + { + fail("Contract prevented adding of valid edge. V2->V3"); + } + + try + { + IUT.addEdge(V1_V5, V1, V5); + fail("Contract allowed cycle to be introduced."); + } + catch (CycleException ex) + {} + } + + + /** + * A unit test for JUnit + */ + public void testChildTree() + throws Throwable + { + AcyclicContract IUT = + new AcyclicContract(); + IUT.setImpl(makeChildTree()); + IUT.verify(); + + try + { + IUT.addEdge(V1_V1, V1, V1); + fail("No GraphException thrown when Self-Cycle introduced."); + } + catch (CycleException ex) + {} + + try + { + IUT.addEdge(V2_V3, V2, V3); + } + catch (GraphException ex) + { + fail("Contract prevented adding of valid edge. V2->V3"); + } + + try + { + IUT.addEdge(V5_V1, V5, V1); + fail("Contract allowed cycle to be introduced."); + } + catch (CycleException ex) + {} + + } +} diff --git a/src/test/org/apache/commons/graph/contract/DAGTest.java b/src/test/org/apache/commons/graph/contract/DAGTest.java new file mode 100644 index 0000000..63c9f41 --- /dev/null +++ b/src/test/org/apache/commons/graph/contract/DAGTest.java @@ -0,0 +1,275 @@ +package org.apache.commons.graph.contract; + +/** + * DAGTest This test looks to verify that yes indeed contracts are being called + * when created through the GraphFactory. + */ + +import org.apache.commons.graph.*; +import org.apache.commons.graph.impl.*; +import org.apache.commons.graph.contract.*; +import org.apache.commons.graph.exception.*; + +/** + * Description of the Class + */ +public class DAGTest + extends GraphTest +{ + private Contract[] dagContracts = new Contract[1]; + private GraphFactory factory = new GraphFactory(); + private String testName = null; + + /** + * Constructor for the DAGTest object + * + * @param name + */ + public DAGTest(String name) + { + super(name); + this.testName = name; + } + + /** + * The JUnit setup method + */ + public void setUp() + { + dagContracts[0] = new AcyclicContract(); + } + + /** + * A unit test for JUnit + */ + public void testDAGSelfLoop() + throws Throwable + { + DirectedGraph dg = null; + try + { + try + { + dg = factory.makeDirectedGraph(dagContracts, + true, + makeSelfLoop()); + fail("Should not have created DAG."); + } + catch (CycleException ex) + {} + } + catch (Throwable ex) + { + printGraph(ex, dg); + throw ex; + } + } + + /** + * A unit test for JUnit + */ + public void testDAGTwoLoop() + throws Throwable + { + DirectedGraph dg = null; + try + { + try + { + dg = factory.makeDirectedGraph(dagContracts, + true, + makeTwoCycle()); + fail("Should not have created DAG."); + } + catch (CycleException ex) + {} + } + catch (Throwable ex) + { + printGraph(ex, dg); + throw ex; + } + } + + /** + * A unit test for JUnit + */ + public void testMakeDAGDirCycle() + throws Throwable + { + MutableDirectedGraph mdg = null; + try + { + mdg = factory.makeMutableDirectedGraph(dagContracts, + true, + null); + mdg.addVertex(V1); + mdg.addVertex(V2); + mdg.addEdge(V1_V2, V1, V2); + + mdg.addVertex(V3); + mdg.addEdge(V2_V3, V2, V3); + + try + { + mdg.addEdge(V3_V1, V3, V1); + fail("No CycleException thrown on introduction of cycle."); + } + catch (CycleException ex) + {} + } + catch (Throwable t) + { + printGraph(t, mdg); + } + } + + /** + * A unit test for JUnit + */ + public void testDAGDirCycle() + throws Throwable + { + DirectedGraph dg = null; + try + { + try + { + dg = factory.makeDirectedGraph(dagContracts, + true, + makeDirectedCycle()); + fail("Should not have created DAG."); + } + catch (CycleException ex) + {} + } + catch (Throwable ex) + { + printGraph(ex, dg); + throw ex; + } + } + + /** + * A unit test for JUnit + */ + public void testDAGAddCycleToPipe() + throws Throwable + { + MutableDirectedGraph mdg = null; + try + { + try + { + mdg = factory.makeMutableDirectedGraph(dagContracts, + true, + makePipe()); + mdg.addEdge(V3_V1, V3, V1); + fail("No Exception thrown on adding of invalid edge."); + } + catch (CycleException e) + {} + } + catch (Throwable ex) + { + printGraph(ex, mdg); + throw ex; + } + } + + /** + * A unit test for JUnit + */ + public void testDAGAddCycleToDirEdge() + throws Throwable + { + MutableDirectedGraph mdg = null; + try + { + try + { + mdg = factory.makeMutableDirectedGraph(dagContracts, + true, + makeDirectedEdge()); + mdg.addEdge(V2_V1, V2, V1); + fail("Failed to throw exception on introducing Cycle."); + } + catch (CycleException ex) + {} + } + catch (Throwable ex) + { + printGraph(ex, mdg); + throw ex; + } + } + + /** + * A unit test for JUnit + */ + public void testDAGAddSelfLoop() + throws Throwable + { + MutableDirectedGraph mdg = null; + try + { + try + { + mdg = factory.makeMutableDirectedGraph(dagContracts, + true, + makeDirSingleVertex()); + mdg.addEdge(V1_V1, V1, V1); + fail("Failed to throw exception on introducing Self Loop."); + } + catch (CycleException ex) + {} + } + catch (Throwable ex) + { + printGraph(ex, mdg); + throw ex; + } + } + + /** + * A unit test for JUnit + */ + public void testDAGValidEdge() + throws Throwable + { + MutableDirectedGraph mdg = null; + try + { + mdg = factory.makeMutableDirectedGraph(dagContracts, + true, + makeParentTree()); + mdg.addEdge(V2_V3, V2, V3); + } + catch (Throwable ex) + { + printGraph(ex, mdg); + throw ex; + } + } + + /** + * A unit test for JUnit + */ + public void testDAGValidEdge2() + throws Throwable + { + MutableDirectedGraph mdg = null; + try + { + mdg = factory.makeMutableDirectedGraph(dagContracts, + true, + makeDirDoubleVertex()); + mdg.addEdge(V1_V2, V1, V2); + } + catch (Throwable ex) + { + printGraph(ex, mdg); + throw ex; + } + } +} diff --git a/src/test/org/apache/commons/graph/decorator/ShortestPathTest.java b/src/test/org/apache/commons/graph/decorator/ShortestPathTest.java new file mode 100644 index 0000000..1b13f23 --- /dev/null +++ b/src/test/org/apache/commons/graph/decorator/ShortestPathTest.java @@ -0,0 +1,21 @@ +package org.apache.commons.graph.decorator; + +import org.apache.commons.graph.*; + +/** + * Description of the Class + */ +public class ShortestPathTest + extends WeightedGraphTest +{ + /** + * Constructor for the ShortestPathTest object + * + * @param name + */ + public ShortestPathTest(String name) + { + super(name); + } + +} diff --git a/src/test/org/apache/commons/graph/decorator/TransposeTest.java b/src/test/org/apache/commons/graph/decorator/TransposeTest.java new file mode 100644 index 0000000..1ffec25 --- /dev/null +++ b/src/test/org/apache/commons/graph/decorator/TransposeTest.java @@ -0,0 +1,122 @@ +package org.apache.commons.graph.decorator; + +/* ==================================================================== + * 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 + * "Commons" 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", + * "Commons", 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.Set; +import java.util.Map; +import java.util.HashSet; +import java.util.HashMap; +import java.util.Iterator; + +import org.apache.commons.graph.*; + +/** + * Description of the Class + */ +public class TransposeTest + extends GraphTest +{ + /** + * Constructor for the TransposeTest object + * + * @param name + */ + public TransposeTest(String name) + { + super(name); + } + + /** + * A unit test for JUnit + */ + public void testParentTree() + throws Throwable + { + DDirectedGraph graph = + DDirectedGraph.decorateGraph(makeParentTree()); + + DirectedGraph IUT = graph.transpose(); + + // Copied from DirGraphTest.testChildTree + verifyGraph(IUT, 5, 4); + + verifyAdjVertices(IUT, V1, + makeSet(V1, V2, V3)); + verifyAdjVertices(IUT, V2, + makeSet(V1, V2)); + verifyAdjVertices(IUT, V3, + makeSet(V1, V3, V4, V5)); + verifyAdjVertices(IUT, V4, + makeSet(V3, V4)); + verifyAdjVertices(IUT, V5, + makeSet(V3, V5)); + + verifyAdjVertices(IUT, V1, + makeSet(), + makeSet(V2, V3)); + verifyAdjVertices(IUT, V2, + makeSet(V1), + makeSet()); + verifyAdjVertices(IUT, V3, + makeSet(V1), + makeSet(V4, V5)); + verifyAdjVertices(IUT, V4, + makeSet(V3), + makeSet()); + verifyAdjVertices(IUT, V5, + makeSet(V3), + makeSet()); + } +} diff --git a/src/test/org/apache/commons/graph/dependency/DependencyTest.java b/src/test/org/apache/commons/graph/dependency/DependencyTest.java new file mode 100644 index 0000000..fa306b4 --- /dev/null +++ b/src/test/org/apache/commons/graph/dependency/DependencyTest.java @@ -0,0 +1,269 @@ +package org.apache.commons.graph.dependency; + +import java.util.Set; +import java.util.List; +import java.util.HashSet; + +import org.apache.commons.graph.*; +import org.apache.commons.graph.dependency.exception.*; + +/** + * Description of the Class + */ +public class DependencyTest + extends GraphTest +{ + private DependencyGraph IUT = null; + + /** + * Constructor for the DependencyTest object + * + * @param name + */ + public DependencyTest(String name) + { + super(name); + } + + /** + * The JUnit setup method + */ + public void setUp() + { + IUT = new DependencyGraph(); + } + + /** + * Description of the Class + */ + private class Task + { + private String name; + + /** + * Constructor for the Task object + * + * @param name + */ + public Task(String name) + { + this.name = name; + } + + /** + * Description of the Method + */ + public String toString() + { + return name; + } + } + + /** + * Description of the Field + */ + public Task T1 = new Task("T1"); + /** + * Description of the Field + */ + public Task T2 = new Task("T2"); + /** + * Description of the Field + */ + public Task T3 = new Task("T3"); + /** + * Description of the Field + */ + public Task T4 = new Task("T4"); + /** + * Description of the Field + */ + public Task T5 = new Task("T5"); + + /** + * A unit test for JUnit + */ + public void testNoDeps() + throws Throwable + { + Set deps = new HashSet(); + + IUT.addDependencies(T1, deps); + } + + /** + * A unit test for JUnit + */ + public void testTwoTasksNoDeps() + throws Throwable + { + Set deps = new HashSet(); + IUT.addDependencies(T1, deps); + IUT.addDependencies(T2, deps); + } + + /** + * A unit test for JUnit + */ + public void testSelfDep() + throws Throwable + { + Set deps = new HashSet(); + deps.add(T1); + + try + { + IUT.addDependencies(T1, deps); + fail("Self Dependency added without exception."); + } + catch (CircularDependencyException ex) + {} + } + + /** + * A unit test for JUnit + */ + public void testTwoCyclicDeps() + throws Throwable + { + Set t1Deps = new HashSet(); + t1Deps.add(T2); + + Set t2Deps = new HashSet(); + t2Deps.add(T1); + + IUT.addDependencies(T1, t1Deps); + try + { + IUT.addDependencies(T2, t2Deps); + fail("No CircularDependencyException thrown."); + } + catch (CircularDependencyException ex) + {} + } + + /** + * A unit test for JUnit + */ + public void testThreeCyclicDeps() + throws Throwable + { + Set t1Deps = new HashSet(); + t1Deps.add(T2); + + Set t2Deps = new HashSet(); + t2Deps.add(T3); + + Set t3Deps = new HashSet(); + t3Deps.add(T1); + + IUT.addDependencies(T1, t1Deps); + IUT.addDependencies(T2, t2Deps); + + try + { + IUT.addDependencies(T3, t3Deps); + fail("No CircularDependencyException Thrown."); + } + catch (CircularDependencyException ex) + {} + } + + /** + * A unit test for JUnit + */ + public void testSortedDepsEasy() + throws Throwable + { + Set t1Deps = new HashSet(); + t1Deps.add(T2); + + Set t2Deps = new HashSet(); + t2Deps.add(T3); + + IUT.addDependencies(T1, t1Deps); + IUT.addDependencies(T2, t2Deps); + IUT.addDependencies(T3, new HashSet()); + + // T3 + List t3SDeps = + IUT.getSortedDependencies(T3); + assertEquals("T3: Wrong number of Deps for T3", + 1, t3SDeps.size()); + + assertEquals("T3: Wrong thing at pos 0", + T3, t3SDeps.get(0)); + + // T2 + List t2SDeps = + IUT.getSortedDependencies(T2); + assertEquals("T2: Wrong number of Deps for T2", + 2, t2SDeps.size()); + + try + { + assertEquals("T2: Wrong thing at pos 0", + T3, t2SDeps.get(0)); + assertEquals("T2: Wrong thing at pos 1", + T2, t2SDeps.get(1)); + } + catch (Throwable ex) + { + System.err.println(t2SDeps); + throw ex; + } + + // T1 + List t1SDeps = + IUT.getSortedDependencies(T1); + assertEquals("T1: Wrong number of Deps for T1", + 3, t1SDeps.size()); + + assertEquals("T1: Wrong thing at pos 0", + T3, t1SDeps.get(0)); + assertEquals("T1: Wrong thing at pos 1", + T2, t1SDeps.get(1)); + assertEquals("T1: Wrong thing at pos 2", + T1, t1SDeps.get(2)); + + } + + /** + * A unit test for JUnit + */ + public void testSortedDepsHard() + { + Set t1Deps = new HashSet(); + t1Deps.add(T2); + t1Deps.add(T3); + t1Deps.add(T5); + + Set t2Deps = new HashSet(); + t2Deps.add(T4); + t2Deps.add(T5); + + IUT.addDependencies(T1, t1Deps); + IUT.addDependencies(T2, t2Deps); + + List t1SDeps = IUT.getSortedDependencies(T1); + assertEquals("T1: Wrong number of dependents.", + 5, t1SDeps.size()); + + List t2SDeps = IUT.getSortedDependencies(T2); + assertEquals("T2: Wrong number of dependents.", + 3, t2SDeps.size()); + + List t3SDeps = IUT.getSortedDependencies(T3); + assertEquals("T1: Wrong number of dependents.", + 1, t3SDeps.size()); + + List t4SDeps = IUT.getSortedDependencies(T4); + assertEquals("T4: Wrong number of dependents.", + 1, t4SDeps.size()); + + List t5SDeps = IUT.getSortedDependencies(T5); + assertEquals("T5: Wrong number of dependents.", + 1, t5SDeps.size()); + + } +} diff --git a/src/test/org/apache/commons/graph/impl/AllPathsTest.java b/src/test/org/apache/commons/graph/impl/AllPathsTest.java new file mode 100644 index 0000000..09ab6f1 --- /dev/null +++ b/src/test/org/apache/commons/graph/impl/AllPathsTest.java @@ -0,0 +1,567 @@ +package org.apache.commons.graph.impl; + +/* ==================================================================== + * 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 + * "Commons" 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", + * "Commons", 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 + * . + */ + +/** + * AllPathsTest This tests the All Pairs Shortest Path solution. + */ + +import org.apache.commons.graph.*; +import org.apache.commons.graph.exception.*; + +import java.util.List; +import java.util.Iterator; + +import junit.framework.*; + +/** + * Description of the Class + */ +public class AllPathsTest + extends WeightedGraphTest +{ + /** + * Constructor for the AllPathsTest object + * + * @param name + */ + public AllPathsTest(String name) + { + super(name); + } + + /** + * A unit test for JUnit + */ + public void testAPWDirectedEdge() + throws Throwable + { + DirectedGraph g = makeWDirectedEdge(); + AllPaths IUT = new AllPaths(g); + + verifyPath(g, IUT.getShortestPath(V1, V1), + V1, V1, V1, + 0.0, 1, 0); + verifyPath(g, IUT.getShortestPath(V2, V2), + V2, V2, V2, + 0.0, 1, 0); + + verifyPath(g, IUT.getShortestPath(V1, V2), + V1, V2, V1, V1_V2, + 5.0, 2, 1); + try + { + IUT.getShortestPath(V2, V1); + fail("NoPathException not thrown."); + } + catch (NoPathException ex) + {} + } + + /** + * A unit test for JUnit + */ + public void testAPPositiveCycle() + throws Throwable + { + DirectedGraph g = makePositiveCycle(); + AllPaths IUT = new AllPaths(g); + + verifyPath(g, IUT.getShortestPath(V1, V1), + V1, V1, V1, + 0.0, 1, 0); + verifyPath(g, IUT.getShortestPath(V2, V2), + V2, V2, V2, + 0.0, 1, 0); + verifyPath(g, IUT.getShortestPath(V3, V3), + V3, V3, V3, + 0.0, 1, 0); + + verifyPath(g, IUT.getShortestPath(V1, V2), + V1, V2, V1, V1_V2, + 2.0, 2, 1); + verifyPath(g, IUT.getShortestPath(V2, V3), + V2, V3, V2, V2_V3, + 4.0, 2, 1); + verifyPath(g, IUT.getShortestPath(V3, V1), + V3, V1, V3, V3_V1, + 1.5, 2, 1); + + verifyPath(g, IUT.getShortestPath(V1, V3), + V1, V3, V2, V1_V2, + 6.0, 3, 2); + verifyPath(g, IUT.getShortestPath(V2, V1), + V2, V1, V3, V2_V3, + 5.5, 3, 2); + verifyPath(g, IUT.getShortestPath(V3, V2), + V3, V2, V1, V1_V2, + 3.5, 3, 2); + } + + /** + * A unit test for JUnit + */ + public void testAPPositivePartNegCycle() + throws Throwable + { + DirectedGraph g = makePositivePartNegCycle(); + AllPaths IUT = new AllPaths(g); + + verifyPath(g, IUT.getShortestPath(V1, V1), + V1, V1, V1, + 0.0, 1, 0); + verifyPath(g, IUT.getShortestPath(V2, V2), + V2, V2, V2, + 0.0, 1, 0); + verifyPath(g, IUT.getShortestPath(V3, V3), + V3, V3, V3, + 0.0, 1, 0); + + verifyPath(g, IUT.getShortestPath(V1, V2), + V1, V2, V1, V1_V2, + 2.0, 2, 1); + verifyPath(g, IUT.getShortestPath(V2, V3), + V2, V3, V2, V2_V3, + 4.0, 2, 1); + verifyPath(g, IUT.getShortestPath(V3, V1), + V3, V1, V3, V3_V1, + -1.5, 2, 1); + + verifyPath(g, IUT.getShortestPath(V1, V3), + V1, V3, V2, V2_V3, + 6.0, 3, 2); + verifyPath(g, IUT.getShortestPath(V2, V1), + V2, V1, V3, V2_V3, + 2.5, 3, 2); + verifyPath(g, IUT.getShortestPath(V3, V2), + V3, V2, V1, V1_V2, + 0.5, 3, 2); + } + + /** + * A unit test for JUnit + */ + public void testAPNegativeCycle() + throws Throwable + { + try + { + AllPaths IUT = new AllPaths(makeNegativeCycle()); + fail("NegativeCycleException not thrown."); + } + catch (NegativeCycleException ex) + {} + } + + /** + * A unit test for JUnit + */ + public void testAPNegativePartPosCycle() + throws Throwable + { + try + { + AllPaths IUT = new AllPaths(makeNegativePartPosCycle()); + fail("NegativeCycleException not thrown."); + } + catch (NegativeCycleException ex) + {} + } + + /* + * Test Pipes now. . . + */ + /** + * A unit test for JUnit + */ + public void testAPPositivePipe() + throws Throwable + { + DirectedGraph g = makePositivePipe(); + AllPaths IUT = new AllPaths(g); + + verifyPath(g, IUT.getShortestPath(V1, V1), + V1, V1, V1, + 0.0, 1, 0); + verifyPath(g, IUT.getShortestPath(V2, V2), + V2, V2, V2, + 0.0, 1, 0); + verifyPath(g, IUT.getShortestPath(V3, V3), + V3, V3, V3, + 0.0, 1, 0); + + verifyPath(g, IUT.getShortestPath(V1, V2), + V1, V2, V1, V1_V2, + 1.5, 2, 1); + verifyPath(g, IUT.getShortestPath(V2, V3), + V2, V3, V2, V2_V3, + 3.5, 2, 1); + + verifyPath(g, IUT.getShortestPath(V1, V3), + V1, V3, V2, V1_V2, + 5.0, 3, 2); + + } + + /** + * A unit test for JUnit + */ + public void testAPPositivePartNegPipe() + throws Throwable + { + DirectedGraph g = makePositivePartNegPipe(); + AllPaths IUT = new AllPaths(g); + + verifyPath(g, IUT.getShortestPath(V1, V1), + V1, V1, V1, + 0.0, 1, 0); + verifyPath(g, IUT.getShortestPath(V2, V2), + V2, V2, V2, + 0.0, 1, 0); + verifyPath(g, IUT.getShortestPath(V3, V3), + V3, V3, V3, + 0.0, 1, 0); + + verifyPath(g, IUT.getShortestPath(V1, V2), + V1, V2, V1, V1_V2, + -1.5, 2, 1); + verifyPath(g, IUT.getShortestPath(V2, V3), + V2, V3, V2, V2_V3, + 3.5, 2, 1); + + verifyPath(g, IUT.getShortestPath(V1, V3), + V1, V3, V2, V2_V3, + 2.0, 3, 2); + + } + + /** + * A unit test for JUnit + */ + public void testAPNegativePipe() + throws Throwable + { + DirectedGraph g = makeNegativePipe(); + AllPaths IUT = new AllPaths(g); + + verifyPath(g, IUT.getShortestPath(V1, V1), + V1, V1, V1, + 0.0, 1, 0); + verifyPath(g, IUT.getShortestPath(V2, V2), + V2, V2, V2, + 0.0, 1, 0); + verifyPath(g, IUT.getShortestPath(V3, V3), + V3, V3, V3, + 0.0, 1, 0); + + verifyPath(g, IUT.getShortestPath(V1, V2), + V1, V2, V1, V1_V2, + -1.5, 2, 1); + verifyPath(g, IUT.getShortestPath(V2, V3), + V2, V3, V2, V2_V3, + -3.5, 2, 1); + + verifyPath(g, IUT.getShortestPath(V1, V3), + V1, V3, V2, V1_V2, + -5.0, 3, 2); + + } + + /** + * A unit test for JUnit + */ + public void testAPNegativePartPosPipe() + throws Throwable + { + DirectedGraph g = makeNegativePartPosPipe(); + AllPaths IUT = new AllPaths(g); + + verifyPath(g, IUT.getShortestPath(V1, V1), + V1, V1, V1, + 0.0, 1, 0); + verifyPath(g, IUT.getShortestPath(V2, V2), + V2, V2, V2, + 0.0, 1, 0); + verifyPath(g, IUT.getShortestPath(V3, V3), + V3, V3, V3, + 0.0, 1, 0); + + verifyPath(g, IUT.getShortestPath(V1, V2), + V1, V2, V1, V1_V2, + 1.5, 2, 1); + verifyPath(g, IUT.getShortestPath(V2, V3), + V2, V3, V2, V2_V3, + -3.5, 2, 1); + + verifyPath(g, IUT.getShortestPath(V1, V3), + V1, V3, V2, V1_V2, + -2.0, 3, 2); + + } + + /** + * A unit test for JUnit + */ + public void testMultiplePathL() + throws Throwable + { + DirectedGraph g = makeMultiplePathL(); + AllPaths IUT = new AllPaths(g); + + verifyPath(g, IUT.getShortestPath(V1, V1), + V1, V1, V1, + 0.0, 1, 0); + verifyPath(g, IUT.getShortestPath(V2, V2), + V2, V2, V2, + 0.0, 1, 0); + verifyPath(g, IUT.getShortestPath(V3, V3), + V3, V3, V3, + 0.0, 1, 0); + verifyPath(g, IUT.getShortestPath(V4, V4), + V4, V4, V4, + 0.0, 1, 0); + + verifyPath(g, IUT.getShortestPath(V1, V2), + V1, V2, V1, V1_V2, + 1.5, 2, 1); + verifyPath(g, IUT.getShortestPath(V1, V3), + V1, V3, V1, V1_V3, + 2.5, 2, 1); + verifyPath(g, IUT.getShortestPath(V2, V4), + V2, V4, V2, V2_V4, + 1.5, 2, 1); + verifyPath(g, IUT.getShortestPath(V3, V4), + V3, V4, V3, V3_V4, + 2.5, 2, 1); + + verifyPath(g, IUT.getShortestPath(V1, V4), + V1, V4, V2, V1_V2, + 3.0, 3, 2); + } + + /** + * A unit test for JUnit + */ + public void testMultiplePathR() + throws Throwable + { + DirectedGraph g = makeMultiplePathR(); + AllPaths IUT = new AllPaths(g); + + verifyPath(g, IUT.getShortestPath(V1, V1), + V1, V1, V1, + 0.0, 1, 0); + verifyPath(g, IUT.getShortestPath(V2, V2), + V2, V2, V2, + 0.0, 1, 0); + verifyPath(g, IUT.getShortestPath(V3, V3), + V3, V3, V3, + 0.0, 1, 0); + verifyPath(g, IUT.getShortestPath(V4, V4), + V4, V4, V4, + 0.0, 1, 0); + + verifyPath(g, IUT.getShortestPath(V1, V2), + V1, V2, V1, V1_V2, + 2.5, 2, 1); + verifyPath(g, IUT.getShortestPath(V1, V3), + V1, V3, V1, V1_V3, + 1.5, 2, 1); + verifyPath(g, IUT.getShortestPath(V2, V4), + V2, V4, V2, V2_V4, + 2.5, 2, 1); + verifyPath(g, IUT.getShortestPath(V3, V4), + V3, V4, V3, V3_V4, + 1.5, 2, 1); + + verifyPath(g, IUT.getShortestPath(V1, V4), + V1, V4, V3, V1_V3, + 3.0, 3, 2); + } + + /** + * A unit test for JUnit + */ + public void testMultiplePathEarlyLow() + throws Throwable + { + DirectedGraph g = makeMultiplePathEarlyLow(); + AllPaths IUT = new AllPaths(g); + + verifyPath(g, IUT.getShortestPath(V1, V1), + V1, V1, V1, + 0.0, 1, 0); + verifyPath(g, IUT.getShortestPath(V2, V2), + V2, V2, V2, + 0.0, 1, 0); + verifyPath(g, IUT.getShortestPath(V3, V3), + V3, V3, V3, + 0.0, 1, 0); + verifyPath(g, IUT.getShortestPath(V4, V4), + V4, V4, V4, + 0.0, 1, 0); + + verifyPath(g, IUT.getShortestPath(V1, V2), + V1, V2, V1, V1_V2, + 10.0, 2, 1); + verifyPath(g, IUT.getShortestPath(V1, V3), + V1, V3, V1, V1_V3, + 0.5, 2, 1); + verifyPath(g, IUT.getShortestPath(V2, V4), + V2, V4, V2, V2_V4, + 10.0, 2, 1); + verifyPath(g, IUT.getShortestPath(V3, V4), + V3, V4, V3, V3_V4, + 10.5, 2, 1); + + verifyPath(g, IUT.getShortestPath(V1, V4), + V1, V4, V3, V3_V4, + 11.0, 3, 2); + } + + /** + * A unit test for JUnit + */ + public void testMultiplePathEarlyHigh() + throws Throwable + { + DirectedGraph g = makeMultiplePathEarlyHigh(); + AllPaths IUT = new AllPaths(g); + + verifyPath(g, IUT.getShortestPath(V1, V1), + V1, V1, V1, + 0.0, 1, 0); + verifyPath(g, IUT.getShortestPath(V2, V2), + V2, V2, V2, + 0.0, 1, 0); + verifyPath(g, IUT.getShortestPath(V3, V3), + V3, V3, V3, + 0.0, 1, 0); + verifyPath(g, IUT.getShortestPath(V4, V4), + V4, V4, V4, + 0.0, 1, 0); + + verifyPath(g, IUT.getShortestPath(V1, V2), + V1, V2, V1, V1_V2, + 10.0, 2, 1); + verifyPath(g, IUT.getShortestPath(V1, V3), + V1, V3, V1, V1_V3, + 10.5, 2, 1); + verifyPath(g, IUT.getShortestPath(V2, V4), + V2, V4, V2, V2_V4, + 10.0, 2, 1); + verifyPath(g, IUT.getShortestPath(V3, V4), + V3, V4, V3, V3_V4, + 0.5, 2, 1); + + verifyPath(g, IUT.getShortestPath(V1, V4), + V1, V4, V3, V1_V3, + 11.0, 3, 2); + } + + /** + * Description of the Method + */ + public void verifyPath(DirectedGraph g, WeightedPath wp, + Vertex start, Vertex end, Vertex mid, + double cost, int vertexCount, int edgeCount) + throws Throwable + { + verifyPath(g, wp, start, end, mid, + null, cost, vertexCount, edgeCount); + } + + /** + * Description of the Method + */ + public void verifyPath(DirectedGraph g, WeightedPath wp, + Vertex start, Vertex end, Vertex mid, Edge midE, + double cost, int vertexCount, int edgeCount) + throws Throwable + { + assertEquals("Wrong Start", + start, wp.getStart()); + assertEquals("Wrong End", + end, wp.getEnd()); + assertEquals("Wrong Cost of Path: " + start + "->" + end, + cost, wp.getWeight(), 0.0001); + assertEquals("Wrong number of Vertices in " + start + "->" + end, + vertexCount, wp.getVertices().size()); + assertEquals("Wrong number of Edges in " + start + "->" + end, + edgeCount, wp.getEdges().size()); + assertTrue("Path " + start + "->" + end + " doesn't contain: " + mid, + wp.getVertices().contains(mid)); + if (midE != null) + { + assertTrue("Path " + start + "-> " + end + " doesn't contain edge: " + midE, + wp.getEdges().contains(midE)); + } + + List edgeList = wp.getEdges(); + List vertList = wp.getVertices(); + + for (int i = 0; i < edgeList.size(); i++) + { + assertEquals("Edge: " + edgeList.get(i) + " doesn't use " + + vertList.get(i) + " as source.", + g.getSource((Edge) edgeList.get(i)), + (Vertex) vertList.get(i)); + assertEquals("Edge: " + edgeList.get(i) + " doesn't use " + + vertList.get(i) + " as target.", + g.getTarget((Edge) edgeList.get(i)), + (Vertex) vertList.get(i + 1)); + } + } +} diff --git a/src/test/org/apache/commons/graph/impl/Dummy.java b/src/test/org/apache/commons/graph/impl/Dummy.java new file mode 100644 index 0000000..739b426 --- /dev/null +++ b/src/test/org/apache/commons/graph/impl/Dummy.java @@ -0,0 +1,10 @@ +package org.apache.commons.graph.impl; + +/** + * Dummy This is a dummy interface with no methods to ensure that things are + * getting built by the Factory properly. + */ + +public interface Dummy +{ +} diff --git a/src/test/org/apache/commons/graph/impl/DummyContract.java b/src/test/org/apache/commons/graph/impl/DummyContract.java new file mode 100644 index 0000000..bd84f2e --- /dev/null +++ b/src/test/org/apache/commons/graph/impl/DummyContract.java @@ -0,0 +1,120 @@ +package org.apache.commons.graph.impl; + +import java.util.Set; +import java.util.HashSet; + +import org.apache.commons.graph.*; +import org.apache.commons.graph.contract.*; +import org.apache.commons.graph.exception.*; + +/** + * Description of the Class + */ +public class DummyContract + implements Contract +{ + /** + * Description of the Field + */ + public DirectedGraph impl = null; + /** + * Description of the Field + */ + public boolean doVerify = false; + + /** + * Description of the Field + */ + public Set acceptAddEdges = new HashSet(); + /** + * Description of the Field + */ + public Set acceptAddVertices = new HashSet(); + /** + * Description of the Field + */ + public Set acceptDelEdges = new HashSet(); + /** + * Description of the Field + */ + public Set acceptDelVertices = new HashSet(); + + /** + * Sets the impl attribute of the DummyContract object + */ + public void setImpl(DirectedGraph impl) + { + this.impl = impl; + } + + /** + * Gets the interface attribute of the DummyContract object + */ + public Class getInterface() + { + return org.apache.commons.graph.impl.Dummy.class; + } + + /** + * Description of the Method + */ + public void verify() + throws GraphException + { + if (!doVerify) + { + throw new GraphException("Verify Failed."); + } + } + + /** + * Adds a feature to the Edge attribute of the DummyContract object + */ + public void addEdge(Edge e, + Vertex start, + Vertex end) + throws GraphException + { + if (acceptAddEdges.contains(e)) + { + throw new GraphException("Edge " + e + " not on list."); + } + } + + /** + * Adds a feature to the Vertex attribute of the DummyContract object + */ + public void addVertex(Vertex v) + throws GraphException + { + if (acceptAddVertices.contains(v)) + { + throw new GraphException("Vertex " + v + " not on list."); + } + } + + /** + * Description of the Method + */ + public void removeEdge(Edge e) + throws GraphException + { + if (acceptDelEdges.contains(e)) + { + throw new GraphException("Edge " + e + " not on list."); + } + } + + /** + * Description of the Method + */ + public void removeVertex(Vertex v) + throws GraphException + { + if (acceptDelVertices.contains(v)) + { + throw new GraphException("Vertex " + v + " not on list."); + } + } +} + diff --git a/src/test/org/apache/commons/graph/impl/GraphFactoryTest.java b/src/test/org/apache/commons/graph/impl/GraphFactoryTest.java new file mode 100644 index 0000000..3a1580c --- /dev/null +++ b/src/test/org/apache/commons/graph/impl/GraphFactoryTest.java @@ -0,0 +1,217 @@ +package org.apache.commons.graph.impl; + +/* ==================================================================== + * 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 + * "Commons" 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", + * "Commons", 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 org.apache.commons.graph.*; +import org.apache.commons.graph.contract.*; +import org.apache.commons.graph.exception.*; + +/** + * Description of the Class + */ +public class GraphFactoryTest extends GraphTest +{ + private GraphFactory IUT = null; + + /** + * Constructor for the GraphFactoryTest object + * + * @param name + */ + public GraphFactoryTest(String name) + { + super(name); + } + + /** + * The JUnit setup method + */ + public void setUp() + { + IUT = new GraphFactory(); + } + + // Are the Interfaces right? + /** + * A unit test for JUnit + */ + public void testInterfaceNoWeight() + throws Throwable + { + Contract contracts[] = + new Contract[1]; + DummyContract c0 = new DummyContract(); + c0.doVerify = true; + contracts[0] = c0; + + DirectedGraph dg = + IUT.makeDirectedGraph(contracts, + false, + makeTwoCycle()); + assertTrue("Graph should implement Dummy.", + dg instanceof Dummy); + assertTrue("Graph should not implement WeightedGraph.", + !(dg instanceof WeightedGraph)); + } + + /** + * A unit test for JUnit + */ + public void testInterfaceWeight() + throws Throwable + { + Contract contracts[] = + new Contract[1]; + DummyContract c0 = new DummyContract(); + c0.doVerify = true; + contracts[0] = c0; + + DirectedGraph dg = + IUT.makeDirectedGraph(contracts, + true, + makeTwoCycle()); + assertTrue("Graph should implement Dummy.", + dg instanceof Dummy); + assertTrue("Graph should implement WeightedGraph.", + dg instanceof WeightedGraph); + } + + /** + * A unit test for JUnit + */ + public void testMInterfaceNoWeight() + throws Throwable + { + Contract contracts[] = + new Contract[1]; + DummyContract c0 = new DummyContract(); + c0.doVerify = true; + contracts[0] = c0; + + MutableDirectedGraph dg = + IUT.makeMutableDirectedGraph(contracts, + false, + makeTwoCycle()); + assertTrue("Graph should implement Dummy.", + dg instanceof Dummy); + assertTrue("Graph should not implement WeightedGraph.", + !(dg instanceof WeightedGraph)); + } + + /** + * A unit test for JUnit + */ + public void testMInterfaceWeight() + throws Throwable + { + Contract contracts[] = + new Contract[1]; + DummyContract c0 = new DummyContract(); + c0.doVerify = true; + contracts[0] = c0; + + MutableDirectedGraph dg = + IUT.makeMutableDirectedGraph(contracts, + true, + makeTwoCycle()); + assertTrue("Graph should implement Dummy.", + dg instanceof Dummy); + assertTrue("Graph should implement WeightedGraph.", + dg instanceof WeightedGraph); + } + + // Does it utilize the Contracts? + /** + * A unit test for JUnit + */ + public void testInvalidContract() + throws Throwable + { + Contract contracts[] = + new Contract[1]; + DummyContract c0 = new DummyContract(); + c0.doVerify = false; + contracts[0] = c0; + + try + { + DirectedGraph dg = + IUT.makeDirectedGraph(contracts, + false, + makeTwoCycle()); + fail("GraphException not thrown."); + } + catch (GraphException e) + {} + } + + + /** + * A unit test for JUnit + */ + public void testValidContract() + throws Throwable + { + Contract contracts[] = + new Contract[1]; + DummyContract c0 = new DummyContract(); + c0.doVerify = true; + contracts[0] = c0; + + DirectedGraph dg = + IUT.makeDirectedGraph(contracts, + false, + makeTwoCycle()); + } +}