diff --git a/src/java/org/apache/commons/graph/domain/basic/DirectedGraphImpl.java b/src/java/org/apache/commons/graph/domain/basic/DirectedGraphImpl.java new file mode 100644 index 0000000..167480a --- /dev/null +++ b/src/java/org/apache/commons/graph/domain/basic/DirectedGraphImpl.java @@ -0,0 +1,457 @@ +package org.apache.commons.graph.domain.basic; + +/* ==================================================================== + * 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 + { + Iterator conts = contracts.iterator(); + while (conts.hasNext()) + { + Contract cont = (Contract) conts.next(); + + cont.addEdge(e, start, end); + } + + 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(source); + edgeSet.remove(e); + + Vertex target = (Vertex) edgeTarget.get(e); + edgeTarget.remove(e); + edgeSet = (Set) inbound.get(target); + 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) { + throw ex.getTargetException(); + } + } + +} diff --git a/src/java/org/apache/commons/graph/domain/basic/DirectedGraphWrapper.java b/src/java/org/apache/commons/graph/domain/basic/DirectedGraphWrapper.java new file mode 100644 index 0000000..8345fe3 --- /dev/null +++ b/src/java/org/apache/commons/graph/domain/basic/DirectedGraphWrapper.java @@ -0,0 +1,142 @@ +package org.apache.commons.graph.domain.basic; + +/* ==================================================================== + * 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/domain/basic/GraphWrapper.java b/src/java/org/apache/commons/graph/domain/basic/GraphWrapper.java new file mode 100644 index 0000000..04d92f2 --- /dev/null +++ b/src/java/org/apache/commons/graph/domain/basic/GraphWrapper.java @@ -0,0 +1,74 @@ +package org.apache.commons.graph.domain.basic; + +/** + * 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/domain/basic/UndirectedGraphImpl.java b/src/java/org/apache/commons/graph/domain/basic/UndirectedGraphImpl.java new file mode 100644 index 0000000..a35a32b --- /dev/null +++ b/src/java/org/apache/commons/graph/domain/basic/UndirectedGraphImpl.java @@ -0,0 +1,252 @@ +package org.apache.commons.graph.domain.basic; + +/* ==================================================================== + * 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 java.lang.reflect.*; + +import org.apache.commons.graph.*; +import org.apache.commons.graph.exception.*; + +/** + * Description of the Class + */ +public class UndirectedGraphImpl + implements UndirectedGraph, + WeightedGraph, + MutableGraph, + InvocationHandler +{ + 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 ) + private Map edgeWeights = new HashMap(); // EDGE X WEIGHT + + /** + * 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); + } + + public void removeVertex( Vertex v ) + throws GraphException + { + vertices.remove( v ); + } + + public void removeEdge( Edge e ) + throws GraphException + { + edges.remove( e ); + } + + public void addEdge(Edge e) + throws GraphException + { + edges.add( e ); + } + + public void disconnect(Edge e, Vertex v) { + if (edgeVerts.containsKey( e )) { + ((Set) edgeVerts.get( e )).remove( v ); + } + + if (vertEdges.containsKey( v )) { + ((Set) vertEdges.get( v )).remove( e ); + } + } + + public void connect( Edge e, Vertex v ) { + Set verts = null; + if (!edgeVerts.containsKey( e )) { + verts = new HashSet(); + edgeVerts.put( e, verts ); + } else { + verts = (Set) edgeVerts.get( e ); + } + + verts.add( v ); + + Set edges = null; + if (!vertEdges.containsKey( v )) { + edges = new HashSet(); + vertEdges.put( v, edges ); + } else { + edges = (Set) vertEdges.get( v ); + } + + edges.add( e ); + + } + + /** + * Adds a feature to the Edge attribute of the UndirectedGraphImpl object + */ + public void addEdge(Edge e, + Set vertices) + throws GraphException + { + addEdge( e ); + + Iterator verts = vertices.iterator(); + while (verts.hasNext()) { + connect( e, (Vertex) verts.next() ); + } + } + + // 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(); + } + } + + public void setWeight( Edge e, double w ) { + if (edgeWeights.containsKey( e )) { + edgeWeights.remove( e ); + } + + edgeWeights.put( e, new Double( w ) ); + } + + 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) { + throw ex.getTargetException(); + } + } + + +} + + + + + + + + + diff --git a/src/java/org/apache/commons/graph/domain/basic/WeightedGraphWrapper.java b/src/java/org/apache/commons/graph/domain/basic/WeightedGraphWrapper.java new file mode 100644 index 0000000..0138a32 --- /dev/null +++ b/src/java/org/apache/commons/graph/domain/basic/WeightedGraphWrapper.java @@ -0,0 +1,108 @@ +package org.apache.commons.graph.domain.basic; + +/* ==================================================================== + * 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/domain/dependency/Dependency.java b/src/java/org/apache/commons/graph/domain/dependency/Dependency.java new file mode 100644 index 0000000..f294bf8 --- /dev/null +++ b/src/java/org/apache/commons/graph/domain/dependency/Dependency.java @@ -0,0 +1,33 @@ +package org.apache.commons.graph.domain.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/domain/dependency/DependencyGraph.java b/src/java/org/apache/commons/graph/domain/dependency/DependencyGraph.java new file mode 100644 index 0000000..2efe8b8 --- /dev/null +++ b/src/java/org/apache/commons/graph/domain/dependency/DependencyGraph.java @@ -0,0 +1,119 @@ +package org.apache.commons.graph.domain.dependency; + +import org.apache.commons.graph.*; +import org.apache.commons.graph.contract.*; +import org.apache.commons.graph.exception.*; +import org.apache.commons.graph.domain.basic.*; +import org.apache.commons.graph.factory.GraphFactory; +import org.apache.commons.graph.decorator.DDirectedGraph; +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 DDirectedGraph + implements Acyclic +{ + 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(); + Contract[] dagContracts = new Contract[1]; + dagContracts[0] = acyclic; + DAG = factory.makeMutableDirectedGraph(dagContracts, + false, + null); + setDirGraph(DAG); + } + + /** + * Description of the Method + */ + private void init() + { + } + + /** + * 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/domain/dependency/DependencyVertex.java b/src/java/org/apache/commons/graph/domain/dependency/DependencyVertex.java new file mode 100644 index 0000000..c2f8029 --- /dev/null +++ b/src/java/org/apache/commons/graph/domain/dependency/DependencyVertex.java @@ -0,0 +1,30 @@ +package org.apache.commons.graph.domain.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/domain/dependency/DependencyVisitor.java b/src/java/org/apache/commons/graph/domain/dependency/DependencyVisitor.java new file mode 100644 index 0000000..0b13523 --- /dev/null +++ b/src/java/org/apache/commons/graph/domain/dependency/DependencyVisitor.java @@ -0,0 +1,76 @@ +package org.apache.commons.graph.domain.dependency; + +import java.util.List; +import java.util.LinkedList; + +import org.apache.commons.graph.*; +import org.apache.commons.graph.algorithm.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/domain/jdepend/ClassVertex.java b/src/java/org/apache/commons/graph/domain/jdepend/ClassVertex.java new file mode 100644 index 0000000..3e28569 --- /dev/null +++ b/src/java/org/apache/commons/graph/domain/jdepend/ClassVertex.java @@ -0,0 +1,41 @@ +package org.apache.commons.graph.domain.jdepend; + +import java.awt.Color; + +import jdepend.framework.*; + +import org.apache.commons.graph.*; +import org.apache.commons.graph.visualize.*; + +public class ClassVertex + implements Vertex, Named, Colored +{ + private JavaClass clazz = null; + + public ClassVertex( JavaClass clazz ) { + this.clazz = clazz; + } + + public JavaClass getJavaClass() { + return clazz; + } + + public String getName() { + return clazz.getName(); + } + + public String toString() { + return getName(); + } + + public Color getBackgroundColor() { + return Color.blue; + } + + public Color getTextColor() { + return Color.white; + } +} + + + diff --git a/src/java/org/apache/commons/graph/domain/jdepend/ImportEdge.java b/src/java/org/apache/commons/graph/domain/jdepend/ImportEdge.java new file mode 100644 index 0000000..9b9f76f --- /dev/null +++ b/src/java/org/apache/commons/graph/domain/jdepend/ImportEdge.java @@ -0,0 +1,35 @@ +package org.apache.commons.graph.domain.jdepend; + +import org.apache.commons.graph.*; +import jdepend.framework.*; + +public class ImportEdge + implements Edge, Named +{ + private JavaPackage pkg = null; + private JavaClass clz = null; + + public ImportEdge( JavaClass clz, + JavaPackage pkg) { + this.pkg = pkg; + this.clz = clz; + } + + public JavaPackage getJavaPackage() { + return pkg; + } + + public JavaClass getJavaClass() { + return clz; + } + + public String getName() { + return clz.getName() + " imports " + pkg.getName(); + } + + public String toString() { + return getName(); + } +} + + diff --git a/src/java/org/apache/commons/graph/domain/jdepend/JDependGraph.java b/src/java/org/apache/commons/graph/domain/jdepend/JDependGraph.java new file mode 100644 index 0000000..e80fe22 --- /dev/null +++ b/src/java/org/apache/commons/graph/domain/jdepend/JDependGraph.java @@ -0,0 +1,92 @@ +package org.apache.commons.graph.domain.jdepend; + +import java.util.Map; +import java.util.HashMap; +import java.util.Iterator; + +import java.io.IOException; + +import jdepend.framework.*; + +import org.apache.commons.graph.*; +import org.apache.commons.graph.domain.basic.*; + +public class JDependGraph + extends DirectedGraphImpl + implements DirectedGraph +{ + private JDepend jdep = new JDepend(); + private Map pkgMap = new HashMap(); // JP X JPV + private Map clazzMap = new HashMap(); // JC X JCV + + public JDependGraph( ) { } + + public void addDirectory( String directory ) + throws IOException + { + jdep.addDirectory( directory ); + } + + /** + * This not only finds the PackageVertex, but also + * adds it to the graph, if it isn't already there. + */ + private PackageVertex findPackageVertex( JavaPackage pkg ) { + if (pkgMap.containsKey( pkg.getName() )) { + return (PackageVertex) pkgMap.get( pkg.getName() ); + } else { + PackageVertex RC = new PackageVertex( pkg ); + pkgMap.put( pkg.getName(), RC ); + addVertex( RC ); + return RC; + } + } + + /** + * This not only finds the PackageVertex, but also + * adds it to the graph, if it isn't already there. + */ + private ClassVertex findClassVertex( JavaClass clz ) { + if (clazzMap.containsKey( clz )) { + return (ClassVertex) clazzMap.get( clz ); + } else { + ClassVertex RC = new ClassVertex( clz ); + clazzMap.put( clz, RC ); + addVertex( RC ); + return RC; + } + } + + public void analyze() { + Iterator pkgs = jdep.analyze().iterator(); + + while (pkgs.hasNext()) { + JavaPackage pkg = (JavaPackage) pkgs.next(); + PackageVertex pv = findPackageVertex( pkg ); + + Iterator clzs = pkg.getClasses().iterator(); + while (clzs.hasNext()) { + JavaClass clz = (JavaClass) clzs.next(); + ClassVertex cv = findClassVertex( clz ); + + OwnershipEdge oe = new OwnershipEdge( pkg, clz ); + addEdge( oe, pv, cv ); + setWeight( oe, 5.0 ); + + Iterator ipkgs = clz.getImportedPackages().iterator(); + while (ipkgs.hasNext()) { + JavaPackage ipkg = (JavaPackage) ipkgs.next(); + PackageVertex ipv = findPackageVertex( ipkg ); + + ImportEdge ie = new ImportEdge( clz, pkg ); + addEdge( ie, cv, ipv ); + setWeight( ie, 200.0 * ipkg.afferentCoupling() + 100.0 ); + } + } + } + } +} + + + + diff --git a/src/java/org/apache/commons/graph/domain/jdepend/OwnershipEdge.java b/src/java/org/apache/commons/graph/domain/jdepend/OwnershipEdge.java new file mode 100644 index 0000000..3292636 --- /dev/null +++ b/src/java/org/apache/commons/graph/domain/jdepend/OwnershipEdge.java @@ -0,0 +1,39 @@ +package org.apache.commons.graph.domain.jdepend; + +import org.apache.commons.graph.*; +import jdepend.framework.*; + +public class OwnershipEdge + implements Edge, Named +{ + private JavaPackage pkg = null; + private JavaClass clz = null; + + public OwnershipEdge( JavaPackage pkg, + JavaClass clz) { + this.pkg = pkg; + this.clz = clz; + } + + public JavaPackage getJavaPackage() { + return pkg; + } + + public JavaClass getJavaClass() { + return clz; + } + + public String getName() { + return pkg.getName() + " owns " + clz.getName(); + } + + public String toString() { + return getName(); + } + +} + + + + + diff --git a/src/java/org/apache/commons/graph/domain/jdepend/PackageVertex.java b/src/java/org/apache/commons/graph/domain/jdepend/PackageVertex.java new file mode 100644 index 0000000..ee4b988 --- /dev/null +++ b/src/java/org/apache/commons/graph/domain/jdepend/PackageVertex.java @@ -0,0 +1,38 @@ +package org.apache.commons.graph.domain.jdepend; + +import java.awt.Color; + +import org.apache.commons.graph.*; +import org.apache.commons.graph.visualize.*; + +import jdepend.framework.*; + +public class PackageVertex + implements Vertex, Named, Colored +{ + private JavaPackage pkg = null; + + public PackageVertex( JavaPackage pkg ) { + this.pkg = pkg; + } + + public JavaPackage getJavaPackage() { + return pkg; + } + + public Color getBackgroundColor() { + return Color.red; + } + + public Color getTextColor() { + return Color.white; + } + + public String getName() { + return pkg.getName(); + } + + public String toString() { + return getName(); + } +} diff --git a/src/java/org/apache/commons/graph/domain/statemachine/State.java b/src/java/org/apache/commons/graph/domain/statemachine/State.java new file mode 100644 index 0000000..f509817 --- /dev/null +++ b/src/java/org/apache/commons/graph/domain/statemachine/State.java @@ -0,0 +1,48 @@ +package org.apache.commons.graph.domain.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/domain/statemachine/StateMachine.java b/src/java/org/apache/commons/graph/domain/statemachine/StateMachine.java new file mode 100644 index 0000000..634f61e --- /dev/null +++ b/src/java/org/apache/commons/graph/domain/statemachine/StateMachine.java @@ -0,0 +1,164 @@ +package org.apache.commons.graph.domain.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.exception.*; +import org.apache.commons.graph.domain.basic.*; +import org.apache.commons.graph.contract.Contract; +import org.apache.commons.graph.factory.GraphFactory; +import org.apache.commons.graph.decorator.DDirectedGraph; +import org.apache.commons.graph.statemachine.exception.*; + +/** + * StateMachine - + * + * This represents a Finite State Machine. It has a collection + * of states and transitions which move between them. + */ +public class StateMachine + extends DDirectedGraph +{ + 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 MutableDirectedGraph graph = null; + private String name; + private GraphFactory factory = new GraphFactory(); + + /** + * Create a new StateMachine given the name. + * + * @param name Name (or Namespace) of StateMachine + */ + public StateMachine(String name) + { + this.name = name; + + Contract[] contracts = new Contract[0]; + graph = factory.makeMutableDirectedGraph( contracts, + false, + null ); + setDirGraph( graph ); + } + + /** + * Gets the StateMachines name (or namespace) + */ + public String getName() + { + return name; + } + + /** + * Adds a State to the collection of states maintained + * by the machine. + */ + public void addState(State state) + throws GraphException + { + states.put(state.getName(), state); + graph.addVertex(state); + } + + /** + * Creates a new State with name provided. Adds it to the + * machine. + */ + 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; + } + + /** + * Adds the state to the set of Final States available. + */ + public void addFinalState(State state) + { + finalStates.add(state); + } + + /** + * Add a Transition to the diagram with the name provided. + * + * This transition traverses from the State specified in source + * and the target. + * @param name Name of the Transition. + * @param source Name of the Source State. + * @param target Name of the Target State. + */ + 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. + * @param name Name of the Transition + * @param source Source of the Transition + * @param target Target of the Transition + */ + 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. + * Transition is expected to know its source and target. + */ + public void addTransition(Transition trans) + throws GraphException + { + transes.put(trans.getName(), trans); + graph.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 associated with the Name. + */ + public Transition getTransition(String name) + { + return (Transition) transes.get(name); + } +} + + + + + + + + diff --git a/src/java/org/apache/commons/graph/domain/statemachine/Transition.java b/src/java/org/apache/commons/graph/domain/statemachine/Transition.java new file mode 100644 index 0000000..180869b --- /dev/null +++ b/src/java/org/apache/commons/graph/domain/statemachine/Transition.java @@ -0,0 +1,121 @@ +package org.apache.commons.graph.domain.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; + private String trigger = 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 setTrigger( String trigger ) + { + this.trigger = trigger; + } + + /** + * Sets the action attribute of the Transition object + */ + public void setAction( String action ) + { + 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/domain/uml/ModelFactory.java b/src/java/org/apache/commons/graph/domain/uml/ModelFactory.java new file mode 100644 index 0000000..73f372f --- /dev/null +++ b/src/java/org/apache/commons/graph/domain/uml/ModelFactory.java @@ -0,0 +1,96 @@ +package org.apache.commons.graph.domain.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.domain.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.domain.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/domain/uml/StateMachineFactory.java b/src/java/org/apache/commons/graph/domain/uml/StateMachineFactory.java new file mode 100644 index 0000000..f11f2ee --- /dev/null +++ b/src/java/org/apache/commons/graph/domain/uml/StateMachineFactory.java @@ -0,0 +1,232 @@ +package org.apache.commons.graph.domain.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.domain.uml.exception.*; + +import org.apache.log4j.Category; + +import org.apache.commons.graph.exception.*; +import org.apache.commons.graph.domain.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.*; + +/** + * Description of the Class + */ +public class StateMachineFactory +{ + private static Category log = + Category.getInstance(org.apache.commons.graph.domain.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.addFinalState(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 trigger = trans.getTrigger(); + MGuard guard = trans.getGuard(); + + String trigStr = null; + String guardStr = null; + + if (guard != null) { + guardStr = guard.getName(); + } + + if (trigger != null) + { + trigStr = trigger.getName(); + } + else + { + trigStr = 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); + + String transName = source + "-" + target + "/" + trigStr; + if (guardStr != null) { + transName = transName + "[" + guardStr + "]"; + } + + Transition tranx = + new Transition(transName, + source, target); + tranx.setTrigger( trigStr ); + tranx.setGuard( guardStr ); + + 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; + } +} +