/*
* GeoTools - The Open Source Java GIS Toolkit
* http://geotools.org
*
* (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*/
package org.geotools.graph.structure.basic;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import org.geotools.graph.structure.Edge;
import org.geotools.graph.structure.Graph;
import org.geotools.graph.structure.GraphVisitor;
import org.geotools.graph.structure.Graphable;
import org.geotools.graph.structure.Node;
/**
* Basic implemenation of Graph.
*
* @see Graph
* @author Justin Deoliveira, Refractions Research Inc, jdeolive@refractions.net
*
* @source $URL$
*/
public class BasicGraph implements Graph, Serializable {
/** Nodes belonging to the graph */
transient private Collection m_nodes;
/** Edges belonging to the graph */
transient private Collection m_edges;
/**
* Constructs an empty graph with edge and node collections uninitialized.
* Mainly for serializability purposes.
*/
public BasicGraph() {
}
/**
* Constructs a graph from a collection of nodes and a collection of edges.
* The relationships between the nodes (edges) are already assumed to be
* formed. Only the references to the node and edge collections are copied,
* not the underlying collections themselves.
*
* @param nodes Collection of nodes to be contained by the graph.
* @param edges Collection of edges to be contained by the graph.
*/
public BasicGraph(Collection nodes, Collection edges) {
m_nodes = nodes;
m_edges = edges;
}
/**
* Sets the node collection of the graph.
*
* @param nodes Collection of Node objects.
*/
public void setNodes(Collection nodes) {
m_nodes = nodes;
}
/**
* @see Graph#getNodes()
*/
public Collection getNodes() {
return (m_nodes);
}
/**
* Sets the edge collection for the graph.
*
* @param edges Collection of Edge objects.
*/
public void setEdges(Collection edges) {
m_edges = edges;
}
/**
* @see Graph#getEdges()
*/
public Collection getEdges() {
return (m_edges);
}
/**
* @see Graph#queryNodes(GraphVisitor)
*/
public List queryNodes(GraphVisitor visitor) {
return(query(getNodes(), visitor));
}
/**
* @see Graph#queryEdges(GraphVisitor)
*/
public List queryEdges(GraphVisitor visitor) {
return(query(getEdges(), visitor));
}
/**
* @see Graph#visitNodes(GraphVisitor)
*/
public void visitNodes(GraphVisitor visitor) {
visit(m_nodes, visitor);
}
/**
* @see Graph#visitEdges(GraphVisitor)
*/
public void visitEdges(GraphVisitor visitor) {
visit(m_edges, visitor);
}
/**
* @see Graph#getNodesOfDegree(int)
* @see Node#getDegree()
*/
public List getNodesOfDegree(int n) {
final int degree = n;
return (
queryNodes(
new GraphVisitor() {
public int visit(Graphable component) {
if (((Node) component).getDegree() == degree)
return (PASS_AND_CONTINUE);
return (FAIL_QUERY);
}
}
)
);
}
/**
* @see Graph#getVisitedNodes(boolean)
*/
public List getVisitedNodes(boolean visited) {
return(getVisited(getNodes(), visited));
}
/**
* @see Graph#getVisitedEdges(boolean)
*/
public List getVisitedEdges(boolean visited) {
return(getVisited(getEdges(), visited));
}
/**
* Initializes the nodes in the graph by setting all visited flags to false
* and all visited counts to zero.
*
* @see BasicGraphable#isVisited()
* @see BasicGraphable#getCount()
*/
public void initNodes() {
for (Iterator itr = m_nodes.iterator(); itr.hasNext();) {
Node node = (Node) itr.next();
node.setVisited(false);
node.setCount(0);
}
}
/**
* Initializes the edges in the graph by setting all visited flags to false
* and all visited counts to zero.
*
* @see BasicGraphable#isVisited()
* @see BasicGraphable#getCount()
*/
public void initEdges() {
for (Iterator itr = m_edges.iterator(); itr.hasNext();) {
Edge edge = (Edge) itr.next();
edge.setVisited(false);
edge.setCount(0);
}
}
/**
* Returns the string representation of the graph which is
* just the string representation of the edge and node collections.
*
* @return String represtentaton of graph.
*/
public String toString() {
return("V=" + m_nodes.toString() + "\n" + "E=" + m_edges.toString());
}
/*
* Internal query method.
*/
private List query(Collection components, GraphVisitor visitor) {
ArrayList result = new ArrayList();
for (Iterator itr = components.iterator(); itr.hasNext();) {
Graphable component = (Graphable) itr.next();
switch(visitor.visit(component)) {
case PASS_AND_CONTINUE:
result.add(component);
continue;
case PASS_AND_STOP:
result.add(component);
return(result);
case FAIL_QUERY:
continue;
}
}
return (result);
}
/*
* Internal visit method
*/
private void visit(Collection components, GraphVisitor visitor) {
for (Iterator itr = components.iterator(); itr.hasNext();) {
visitor.visit((Graphable)itr.next());
}
}
/*
* Internal getVisited method.
*/
private List getVisited(Collection components, boolean visited) {
final boolean isVisited = visited;
return (
query(
components,
new GraphVisitor() {
public int visit(Graphable component) {
if (component.isVisited() == isVisited)
return (PASS_AND_CONTINUE);
return (FAIL_QUERY);
}
}
)
);
}
}