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.io.standard;
018:
019: import java.io.BufferedInputStream;
020: import java.io.BufferedOutputStream;
021: import java.io.EOFException;
022: import java.io.FileInputStream;
023: import java.io.FileOutputStream;
024: import java.io.ObjectInputStream;
025: import java.io.ObjectOutputStream;
026: import java.util.Iterator;
027:
028: import org.geotools.graph.build.GraphBuilder;
029: import org.geotools.graph.io.GraphReaderWriter;
030: import org.geotools.graph.structure.Edge;
031: import org.geotools.graph.structure.Graph;
032: import org.geotools.graph.structure.Node;
033:
034: /**
035: * An implementation of GraphReaderWriter that uses java serialization to
036: * read and write graph objects. During the graph serialization process
037: * edges are written to the object output stream. Along with the edges,
038: * the two nodes incident to the edge are also written. However, edge adjacency
039: * lists of nodes are <B>not</B> written to the output stream in order to
040: * prevent deep recursive calls that often result in a stack overflow. Therefore
041: * it is important that any implementation of the Node interface declare its
042: * edge adjacecny list (if any) as transient in order to support graph
043: * serializability. <BR>
044: * Because edge adjacency lists are not serialized, they must be reconstructed
045: * upon deserialization in order to preserve the original graph structure.<BR>
046: *
047: * @author Justin Deoliveira, Refractions Research Inc, jdeolive@refractions.net
048: *
049: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/extension/graph/src/main/java/org/geotools/graph/io/standard/SerializedReaderWriter.java $
050: */
051: public class SerializedReaderWriter extends AbstractReaderWriter
052: implements FileReaderWriter {
053:
054: /**
055: * Deserializes the graph and reconstructs the original structure.
056: *
057: * @see GraphReaderWriter#read()
058: */
059: public Graph read() throws Exception {
060: //read builder property
061: GraphBuilder builder = (GraphBuilder) getProperty(BUILDER);
062:
063: //create file input stream
064: ObjectInputStream objin = new ObjectInputStream(
065: new BufferedInputStream(new FileInputStream(
066: (String) getProperty(FILENAME))));
067:
068: //read header
069: int nnodes = objin.readInt();
070: int nedges = objin.readInt();
071:
072: //rebuild edge collection, upon reading an edge, at the edge to the
073: // adjacency list of each of its nodes
074: int count = 0;
075: while (count++ < nedges) {
076: Edge e = (Edge) objin.readObject();
077: e.getNodeA().setVisited(false);
078: e.getNodeB().setVisited(false);
079: builder.addEdge(e);
080: }
081:
082: //rebuild node collection
083: for (Iterator itr = builder.getGraph().getEdges().iterator(); itr
084: .hasNext();) {
085: Edge e = (Edge) itr.next();
086:
087: if (!e.getNodeA().isVisited()) {
088: e.getNodeA().setVisited(true);
089: builder.addNode(e.getNodeA());
090: }
091:
092: if (!e.getNodeB().isVisited()) {
093: e.getNodeB().setVisited(true);
094: builder.addNode(e.getNodeB());
095: }
096: }
097:
098: //check if object stream is empty, if not, there are nodes of degree 0
099: // in the graph
100: try {
101: Node n;
102:
103: while ((n = (Node) objin.readObject()) != null) {
104: builder.addNode(n);
105: }
106: } catch (EOFException ignore) {
107: }
108:
109: return (builder.getGraph());
110: }
111:
112: /**
113: * Serializes the graph by writing each edge in the graph to an object
114: * output stream. If there any nodes of degree 0 in the graph, then they are
115: * appended to the end of the object output stream.
116: *
117: * @see GraphReaderWriter#write()
118: */
119: public void write(Graph graph) throws Exception {
120: //create file output stream
121: ObjectOutputStream objout = new ObjectOutputStream(
122: new BufferedOutputStream(new FileOutputStream(
123: (String) getProperty(FILENAME))));
124:
125: //create header
126: // 1. number of nodes
127: // 2. number of edges
128: objout.writeInt(graph.getNodes().size());
129: objout.writeInt(graph.getEdges().size());
130:
131: //write out edges (note: nodes do not write out adjacent edges)
132: for (Iterator itr = graph.getEdges().iterator(); itr.hasNext();) {
133: Edge e = (Edge) itr.next();
134: objout.writeObject(e);
135: }
136:
137: //write out any nodes that have no adjacent edges
138: for (Iterator itr = graph.getNodesOfDegree(0).iterator(); itr
139: .hasNext();) {
140: Node n = (Node) itr.next();
141: objout.writeObject(n);
142: }
143:
144: objout.flush();
145: objout.close();
146: }
147: }
|