Added basic graph functionality as a first step towards simplifying the container...
[utils] / system / general / src / main / java / org / wamblee / system / graph / Graph.java
1 /*
2  * Copyright 2008 the original author or authors.
3  * 
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  * 
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  * 
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package org.wamblee.system.graph;
17
18 import java.util.ArrayList;
19 import java.util.List;
20
21 public class Graph {
22
23     private List<Node> _nodes;
24     private List<Edge> _edges;
25
26     public Graph() {
27         _nodes = new ArrayList<Node>();
28         _edges = new ArrayList<Edge>();
29     }
30
31     public void addNode(Node aNode) {
32         if (_nodes.contains(aNode)) {
33             throw new IllegalArgumentException("Node '" + aNode.getName()
34                     + "' already exists");
35         }
36         _nodes.add(aNode);
37     }
38     
39     public Node findNode(String aName) { 
40         for (Node node: _nodes) { 
41             if ( node.getName().equals(aName)) { 
42                 return node; 
43             }
44         }
45         return null; 
46     }
47
48     public boolean removeNode(Node aNode) {
49         if (!findOutgoing(aNode).isEmpty() || !findIncoming(aNode).isEmpty()) {
50             throw new IllegalArgumentException("Cannot remove node '"
51                     + aNode.getName()
52                     + "' because it is connected to one or more edges");
53         }
54         return _nodes.remove(aNode);
55     }
56
57     public void addNodes(List<Node> aNodes) {
58         for (Node node : aNodes) {
59             addNode(node);
60         }
61     }
62
63     public void addEdge(Edge aEdge) {
64         if (_edges.contains(aEdge)) {
65             throw new IllegalArgumentException("Edge '" + aEdge
66                     + "' already exists");
67         }
68         if (!_nodes.contains(aEdge.getFrom())) {
69             throw new IllegalArgumentException("From node '" + aEdge.getFrom()
70                     + "' from edge '" + aEdge + "' is not part of the graph");
71         }
72         if (!_nodes.contains(aEdge.getTo())) {
73             throw new IllegalArgumentException("To node '" + aEdge.getTo()
74                     + "' from edge '" + aEdge + "' is not part of the graph");
75         }
76         _edges.add(aEdge);
77     }
78
79     public boolean removeEdge(Edge aEdge) {
80         return _edges.remove(aEdge);
81     }
82
83     public void addEdges(List<Edge> aEdges) {
84         for (Edge edge : aEdges) {
85             addEdge(edge);
86         }
87     }
88
89     public List<Node> getNodes() {
90         return new ArrayList<Node>(_nodes);
91     }
92
93     public List<Edge> getEdges() {
94         return new ArrayList<Edge>(_edges);
95     }
96
97     public void extend(EdgeFactory aFactory) {
98         for (Node from : _nodes) {
99             for (Node to : _nodes) {
100                 _edges.addAll(aFactory.create(from, to));
101             }
102         }
103     }
104
105     public List<Edge> findOutgoing(Node aNode) {
106         List<Edge> result = new ArrayList<Edge>();
107         for (Edge edge : _edges) {
108             if (edge.getFrom().getName().equals(aNode.getName())) {
109                 result.add(edge);
110             }
111         }
112         return result;
113     }
114
115     public List<Edge> findIncoming(Node aNode) {
116         List<Edge> result = new ArrayList<Edge>();
117         for (Edge edge : _edges) {
118             if (edge.getTo().getName().equals(aNode.getName())) {
119                 result.add(edge);
120             }
121         }
122         return result;
123     }
124
125     public void accept(Visitor aVisitor) {
126         List<Node> nodes = getNodes(); // copy to make sure the visitor can
127                                         // modify the
128         // list of nodes as part of the loop.
129         List<Edge> edges = getEdges(); // copy ..... (see above).
130
131         for (Node node : nodes) {
132             aVisitor.visitNode(node);
133         }
134         for (Edge edge : edges) {
135             aVisitor.visitEdge(edge);
136         }
137     }
138 }