--- /dev/null
+/*
+ * Copyright 2008 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wamblee.system.graph;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class Graph {
+
+ private List<Node> _nodes;
+ private List<Edge> _edges;
+
+ public Graph() {
+ _nodes = new ArrayList<Node>();
+ _edges = new ArrayList<Edge>();
+ }
+
+ public void addNode(Node aNode) {
+ if (_nodes.contains(aNode)) {
+ throw new IllegalArgumentException("Node '" + aNode.getName()
+ + "' already exists");
+ }
+ _nodes.add(aNode);
+ }
+
+ public Node findNode(String aName) {
+ for (Node node: _nodes) {
+ if ( node.getName().equals(aName)) {
+ return node;
+ }
+ }
+ return null;
+ }
+
+ public boolean removeNode(Node aNode) {
+ if (!findOutgoing(aNode).isEmpty() || !findIncoming(aNode).isEmpty()) {
+ throw new IllegalArgumentException("Cannot remove node '"
+ + aNode.getName()
+ + "' because it is connected to one or more edges");
+ }
+ return _nodes.remove(aNode);
+ }
+
+ public void addNodes(List<Node> aNodes) {
+ for (Node node : aNodes) {
+ addNode(node);
+ }
+ }
+
+ public void addEdge(Edge aEdge) {
+ if (_edges.contains(aEdge)) {
+ throw new IllegalArgumentException("Edge '" + aEdge
+ + "' already exists");
+ }
+ if (!_nodes.contains(aEdge.getFrom())) {
+ throw new IllegalArgumentException("From node '" + aEdge.getFrom()
+ + "' from edge '" + aEdge + "' is not part of the graph");
+ }
+ if (!_nodes.contains(aEdge.getTo())) {
+ throw new IllegalArgumentException("To node '" + aEdge.getTo()
+ + "' from edge '" + aEdge + "' is not part of the graph");
+ }
+ _edges.add(aEdge);
+ }
+
+ public boolean removeEdge(Edge aEdge) {
+ return _edges.remove(aEdge);
+ }
+
+ public void addEdges(List<Edge> aEdges) {
+ for (Edge edge : aEdges) {
+ addEdge(edge);
+ }
+ }
+
+ public List<Node> getNodes() {
+ return new ArrayList<Node>(_nodes);
+ }
+
+ public List<Edge> getEdges() {
+ return new ArrayList<Edge>(_edges);
+ }
+
+ public void extend(EdgeFactory aFactory) {
+ for (Node from : _nodes) {
+ for (Node to : _nodes) {
+ _edges.addAll(aFactory.create(from, to));
+ }
+ }
+ }
+
+ public List<Edge> findOutgoing(Node aNode) {
+ List<Edge> result = new ArrayList<Edge>();
+ for (Edge edge : _edges) {
+ if (edge.getFrom().getName().equals(aNode.getName())) {
+ result.add(edge);
+ }
+ }
+ return result;
+ }
+
+ public List<Edge> findIncoming(Node aNode) {
+ List<Edge> result = new ArrayList<Edge>();
+ for (Edge edge : _edges) {
+ if (edge.getTo().getName().equals(aNode.getName())) {
+ result.add(edge);
+ }
+ }
+ return result;
+ }
+
+ public void accept(Visitor aVisitor) {
+ List<Node> nodes = getNodes(); // copy to make sure the visitor can
+ // modify the
+ // list of nodes as part of the loop.
+ List<Edge> edges = getEdges(); // copy ..... (see above).
+
+ for (Node node : nodes) {
+ aVisitor.visitNode(node);
+ }
+ for (Edge edge : edges) {
+ aVisitor.visitEdge(edge);
+ }
+ }
+}