001: /*
002: * GeoTools - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2002-2006, GeoTools Project Managment Committee (PMC)
005: * (C) 2002, Refractions Reserach Inc.
006: *
007: * This library is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU Lesser General Public
009: * License as published by the Free Software Foundation;
010: * version 2.1 of the License.
011: *
012: * This library is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: */
017: package org.geotools.graph.build.basic;
018:
019: import java.util.ArrayList;
020: import java.util.Collection;
021: import java.util.HashSet;
022: import java.util.Iterator;
023:
024: import org.geotools.graph.build.GraphBuilder;
025: import org.geotools.graph.structure.Edge;
026: import org.geotools.graph.structure.Graph;
027: import org.geotools.graph.structure.Node;
028: import org.geotools.graph.structure.basic.BasicEdge;
029: import org.geotools.graph.structure.basic.BasicGraph;
030: import org.geotools.graph.structure.basic.BasicNode;
031:
032: /**
033: * Basic implementation of GraphBuilder. This implementation of builder
034: * creates the graph when the builder is created. The underlying graph
035: * implementation makes copies of the references to the node and edge
036: * collections, not copies of the underlying collections themselves. In this
037: * way as nodes and edges are added to the builder, it is reflected in the
038: * built graph.
039: *
040: * @author Justin Deoliveira, Refractions Research Inc, jdeolive@refractions.net
041: *
042: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/extension/graph/src/main/java/org/geotools/graph/build/basic/BasicGraphBuilder.java $
043: */
044: public class BasicGraphBuilder implements GraphBuilder {
045:
046: /** graph being built **/
047: private Graph m_graph;
048:
049: /** nodes of graph being built **/
050: private HashSet m_nodes;
051:
052: /** edges of graph being built **/
053: private HashSet m_edges;
054:
055: /**
056: * Constructs a new empty graph builder.
057: */
058: public BasicGraphBuilder() {
059: m_nodes = new HashSet();
060: m_edges = new HashSet();
061: m_graph = buildGraph();
062: }
063:
064: /**
065: * @see GraphBuilder#buildNode()
066: */
067: public Node buildNode() {
068: return (new BasicNode());
069: }
070:
071: /**
072: * @see GraphBuilder#buildEdge(Node, Node)
073: */
074: public Edge buildEdge(Node nodeA, Node nodeB) {
075: return (new BasicEdge(nodeA, nodeB));
076: }
077:
078: /**
079: * @see GraphBuilder#addNode(Node)
080: */
081: public void addNode(Node node) {
082: m_nodes.add(node);
083: }
084:
085: /**
086: * Checks for loops in which case it only added the edge to the adjacency
087: * list of one of the nodes (both of its nodes are the same node).
088: *
089: * @see GraphBuilder#addEdge(Edge)
090: */
091: public void addEdge(Edge edge) {
092: edge.getNodeA().add(edge);
093:
094: //if the edge is a loop edge, which is legal, only add to node once
095: if (!edge.getNodeA().equals(edge.getNodeB()))
096: edge.getNodeB().add(edge);
097: m_edges.add(edge);
098: }
099:
100: /**
101: * @see GraphBuilder#removeNode(Node)
102: */
103: public void removeNode(Node node) {
104: //prevents concurrent modification
105: ArrayList toRemove = new ArrayList(node.getEdges());
106: removeEdges(toRemove);
107: m_nodes.remove(node);
108: }
109:
110: /**
111: * @see GraphBuilder#removeNodes(Collection)
112: */
113: public void removeNodes(Collection nodes) {
114: for (Iterator itr = nodes.iterator(); itr.hasNext();) {
115: Node n = (Node) itr.next();
116: removeNode(n);
117: }
118: }
119:
120: /**
121: * @see GraphBuilder#removeEdge(Edge)
122: */
123: public void removeEdge(Edge edge) {
124: edge.getNodeA().remove(edge);
125: edge.getNodeB().remove(edge);
126: m_edges.remove(edge);
127: }
128:
129: /**
130: * @see GraphBuilder#removeEdges(Collection)
131: */
132: public void removeEdges(Collection edges) {
133: for (Iterator itr = edges.iterator(); itr.hasNext();) {
134: Edge e = (Edge) itr.next();
135: removeEdge(e);
136: }
137: }
138:
139: /**
140: * @see GraphBuilder#getGraph()
141: */
142: public Graph getGraph() {
143: return (m_graph);
144: }
145:
146: /**
147: * @see GraphBuilder#clone(boolean)
148: */
149: public Object clone(boolean deep) throws Exception {
150: GraphBuilder builder = (GraphBuilder) getClass().newInstance();
151: if (deep)
152: builder.importGraph(getGraph());
153:
154: return (builder);
155: }
156:
157: /**
158: * @see GraphBuilder#importGraph(Graph)
159: */
160: public void importGraph(Graph g) {
161: m_nodes = new HashSet(g.getNodes());
162: m_edges = new HashSet(g.getEdges());
163: m_graph = buildGraph();
164: }
165:
166: /**
167: * Returns the nodes belonging to the graph being built.
168: *
169: * @return A collection of nodes.
170: */
171: public Collection getNodes() {
172: return (m_nodes);
173: }
174:
175: /**
176: * Returns the edges belonging to the graph being built.
177: *
178: * @return A collection of edges.
179: */
180: public Collection getEdges() {
181: return (m_edges);
182: }
183:
184: /**
185: * Creates the underlying graph object.
186: *
187: * @return A Graph object.
188: */
189: protected Graph buildGraph() {
190: return (new BasicGraph(m_nodes, m_edges));
191: }
192: }
|