# Coverage details for edu.uci.ics.jung.io.GraphMLFile

Line | Hits | Source
--- | --- | ---
1 |  | `/*`
2 |  | `* Copyright (c) 2003, the JUNG Project and the Regents of the University`
3 |  | `* of California`
4 |  | `* All rights reserved.`
5 |  | `*`
6 |  | `* This software is open-source under the BSD license; see either`
7 |  | `* "license.txt" or`
8 |  | `* http://jung.sourceforge.net/license.txt for a description.`
9 |  | `*/`
10 |  | `package edu.uci.ics.jung.io;`
11 |  | ``
12 |  | `import java.io.File;`
13 |  | `import java.io.FileOutputStream;`
14 |  | `import java.io.FilenameFilter;`
15 |  | `import java.io.InputStream;`
16 |  | `import java.io.PrintStream;`
17 |  | `import java.io.Reader;`
18 |  | `import java.util.ArrayList;`
19 |  | `import java.util.Iterator;`
20 |  | `import java.util.List;`
21 |  | ``
22 |  | `import javax.xml.parsers.SAXParser;`
23 |  | `import javax.xml.parsers.SAXParserFactory;`
24 |  | ``
25 |  | `import org.xml.sax.InputSource;`
26 |  | ``
27 |  | `import edu.uci.ics.jung.exceptions.FatalException;`
28 |  | `import edu.uci.ics.jung.graph.DirectedEdge;`
29 |  | `import edu.uci.ics.jung.graph.Edge;`
30 |  | `import edu.uci.ics.jung.graph.Graph;`
31 |  | `import edu.uci.ics.jung.graph.UndirectedEdge;`
32 |  | `import edu.uci.ics.jung.graph.Vertex;`
33 |  | `import edu.uci.ics.jung.graph.decorators.Indexer;`
34 |  | `import edu.uci.ics.jung.utils.Pair;`
35 |  | `import edu.uci.ics.jung.utils.PredicateUtils;`
36 |  | `import edu.uci.ics.jung.utils.UserData;`
37 |  | `import edu.uci.ics.jung.utils.UserDataContainer;`
38 |  | ``
39 |  | `/**`
40 |  | `* A file reader for GraphML files. Currently, there is only support for directed and undirected graphs.`
41 |  | `* The elements <port>, <hyperedge>, <endpoint>, and <locator> are simply ignored. <p>`
42 |  | `*`
43 |  | `* What follows are the native GraphML attributes that are recognized: <ul>`
44 |  | `* <li> graph: edgedefault (takes values {"undirected","directed"}; determines whether the graph is directed or undirected)`
45 |  | `* <li> node: id (Can be any string value; only used to connect up edges)`
46 |  | `* <li> edge: source, target (take ids; both are used to created either a directed or undirected edge depending`
47 |  | `* on the type of graph) </ul> <br>`
48 |  | `* These attributes are not stored as explicit UserDatum instances. All other attributes are read in and stored as`
49 |  | `* UserDatum String values with the corresponding graph object, i.e. graph, node, or edge. <p>`
50 |  | `*`
51 |  | `* A sample file looks like this: <br>`
52 |  | `* &lt;?xml version="1.0" encoding="iso-8859-1" ?&gt; <br>`
53 |  | `* &lt;?meta name="GENERATOR" content="XML::Smart 1.3.1" ?&gt; <br>`
54 |  | `* &lt;?meta name="GENERATOR" content="XML::Smart 1.3.1" ?&gt; <br>`
55 |  | `* &lt;graph edgedefault="directed" year="1983"&gt; <br>`
56 |  | `* &lt;node id="1" name="V1" color="red"/&gt; <br>`
57 |  | `* &lt;node id="2" name="V2" color="blue"/&gt; <br>`
58 |  | `* &lt;node id="3" name="V3" color="green"/&gt; <br>`
59 |  | `* &lt;edge source="1" target="2" day="Monday"/&gt; <br>`
60 |  | `* &lt;edge source="1" target="3" day="Tuesday"/&gt; <br>`
61 |  | `*&lt;edge source="2" target="3" day="Friday"/&gt; <br>`
62 |  | `* &lt;/graph&gt; <br>`
63 |  | `* Note: In this example, year, color, and day are user-defined attributes that get stored in the object's UserData`
64 |  | `*`
65 |  | `* Assuming we have a Graph g created from the above XML file we can print out the days of`
66 |  | `* the week for each node as follows:`
67 |  | `* <pre>`
68 |  | `* for (Iterator eIt = g.getEdges().iterator(); eIt.hasNext(); ) {`
69 |  | `* Edge v = (Edge) eIt.next();`
70 |  | `* System.out.println(e.getUserDatum("day");`
71 |  | `* }`
72 |  | `* </pre><br>`
73 |  | `*`
74 |  | `* @see "http://graphml.graphdrawing.org/"`
75 |  | `* @author Scott White, John Yesberg`
76 |  | `*/`
77 |  | `public class GraphMLFile implements GraphFile {`
78 |  | `private GraphMLFileHandler mFileHandler;`
79 |  | `protected boolean directed;`
80 |  | `protected boolean undirected;`
81 |  | ``
82 |  | `/**`
83 |  | `* Default constructor which uses default GraphMLFileHandler to parse the graph`
84 |  | `*/`
85 | 18 | `public GraphMLFile() {`
86 | 18 | `mFileHandler = new GraphMLFileHandler();`
87 | 18 | `}`
88 |  | ``
89 |  | `/**`
90 |  | `* Constructors which allows a subclass of GraphMLFileHandler to be used to parse the graph`
91 |  | `* @param handler the user-provided GraphML file handler`
92 |  | `*/`
93 | 0 | `public GraphMLFile(GraphMLFileHandler handler) {`
94 | 0 | `mFileHandler = handler;`
95 | 0 | `}`
96 |  | ``
97 |  | `/**`
98 |  | `* Loads a graph from a GraphML file.`
99 |  | `* @param filename the fully specified file name`
100 |  | `* @return the constructed graph`
101 |  | `*/`
102 |  | `public Graph load(String filename) {`
103 |  | ``
104 |  | `// Use the default (non-validating) parser`
105 | 3 | `SAXParserFactory factory = SAXParserFactory.newInstance();`
106 |  | `try {`
107 |  | `// Parse the input`
108 | 3 | `SAXParser saxParser = factory.newSAXParser();`
109 | 3 | `saxParser.parse(new File(filename), mFileHandler);`
110 |  | ``
111 | 0 | `} catch (Exception e) {`
112 | 0 | `throw new FatalException("Error loading graphml file: " + filename, e);`
113 | 3 | `}`
114 |  | ``
115 | 3 | `return mFileHandler.getGraph();`
116 |  | `}`
117 |  | ``
118 |  | `/**`
119 |  | `* Loads a graph from a GraphML input stream.`
120 |  | `* @param stream the input stream which contains the GraphML data`
121 |  | `* @return the constructed graph`
122 |  | `* @deprecated generally, InputStreams are less robust than Readers`
123 |  | `*/`
124 |  | `public Graph load(InputStream stream) {`
125 |  | ``
126 |  | `// Use the default (non-validating) parser`
127 | 0 | `SAXParserFactory factory = SAXParserFactory.newInstance();`
128 |  | `try {`
129 |  | `// Parse the input`
130 | 0 | `SAXParser saxParser = factory.newSAXParser();`
131 | 0 | `saxParser.parse(stream, mFileHandler);`
132 |  | ``
133 | 0 | `} catch (Exception e) {`
134 | 0 | `throw new FatalException("Error loading graphml file", e);`
135 | 0 | `}`
136 |  | ``
137 | 0 | `return mFileHandler.getGraph();`
138 |  | `}`
139 |  | ``
140 |  | `public Graph load( Reader reader ) {`
141 |  | ``
142 |  | `// Use the default (non-validating) parser`
143 | 15 | `SAXParserFactory factory = SAXParserFactory.newInstance();`
144 |  | `try {`
145 |  | `// Parse the input`
146 | 15 | `SAXParser saxParser = factory.newSAXParser();`
147 | 15 | `InputSource is = new InputSource( reader );`
148 | 15 | `saxParser.parse(is, mFileHandler);`
149 |  | ``
150 | 0 | `} catch (Exception e) {`
151 | 0 | `throw new FatalException("Error loading graphml file", e);`
152 | 15 | `}`
153 |  | ``
154 | 15 | `return mFileHandler.getGraph();`
155 |  | ``
156 |  | `}`
157 |  | ``
158 |  | `/**`
159 |  | `* Loads in a list of graphs whose corresponding filenames pass the file filter and are located in the`
160 |  | `* specified directory`
161 |  | `* @param dirName the directory containing the set of files that are to be screened through the file filter`
162 |  | `* @param filter the file filter`
163 |  | `* @return a list of graphs`
164 |  | `*/`
165 |  | `public List loadGraphCollection(String dirName, FilenameFilter filter) {`
166 | 0 | `File dir = new File(dirName);`
167 | 0 | `if (!dir.isDirectory()) {`
168 | 0 | `throw new FatalException("Parameter dirName must be a directory");`
169 |  | `}`
170 |  | ``
171 | 0 | `String[] files = dir.list(filter);`
172 |  | ``
173 | 0 | `List graphCollection = new ArrayList();`
174 | 0 | `for (int i = 0; i < files.length; i++) {`
175 | 0 | `String currentFile = dirName + File.separatorChar + files[i];`
176 | 0 | `GraphMLFile graphmlFile = new GraphMLFile(mFileHandler);`
177 | 0 | `Graph graph = graphmlFile.load(currentFile);`
178 |  | `//System.out.println("Graph loaded with " + graph.numVertices() + " nodes and " + graph.numEdges() + " edges.");`
179 | 0 | `graphCollection.add(graph);`
180 |  | `}`
181 |  | ``
182 | 0 | `return graphCollection;`
183 |  | `}`
184 |  | ``
185 |  | `public void save(Graph g, String filename) {`
186 |  | `PrintStream out;`
187 |  | `try {`
188 | 1 | `out = new PrintStream(new FileOutputStream(filename, false));`
189 | 0 | `} catch (Exception e) {`
190 | 0 | `throw new FatalException("Could not open file \"" + filename + "\" for writing. " + e);`
191 | 1 | `}`
192 | 1 | `save(g, out);`
193 | 1 | `out.close();`
194 | 1 | `}`
195 |  | ``
196 |  | ``
197 |  | ``
198 |  | `public void save(Graph g, PrintStream out) {`
199 | 1 | `out.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");`
200 | 1 | `out.println("<graphml xmlns=\"http://graphml.graphdrawing.org/xmlns/graphml\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ");`
201 | 1 | `out.println("xsi:schemaLocation=\"http://graphml.graphdrawing.org/xmlns/graphml\">");`
202 | 1 | `out.print("<graph edgedefault=\"");`
203 | 1 | `boolean directed = PredicateUtils.enforcesEdgeConstraint(g, Graph.DIRECTED_EDGE);`
204 | 1 | `boolean undirected = PredicateUtils.enforcesEdgeConstraint(g, Graph.UNDIRECTED_EDGE);`
205 | 1 | `if (directed)`
206 | 0 | `out.print("directed\" ");`
207 | 1 | `else if (undirected)`
208 | 0 | `out.print("undirected\" ");`
209 |  | `else // default for mixed graphs`
210 |  | `{`
211 | 1 | `directed = true;`
212 | 1 | `out.print("directed\" ");`
213 |  | `}`
214 |  | `// throw new IllegalArgumentException("Mixed (directed/undirected) " +`
215 |  | `// "graphs not currently supported");`
216 |  | ``
217 | 1 | `saveUserData(g, out);`
218 | 1 | `out.println(" >");`
219 | 1 | `saveVerticesSection(out, g);`
220 | 1 | `saveEdgesSection(out, g);`
221 | 1 | `out.println("</graph>");`
222 | 1 | `out.println("</graphml>");`
223 |  | ``
224 | 1 | `}`
225 |  | ``
226 |  | `private void saveVerticesSection(PrintStream out, Graph g) {`
227 | 1 | `int numVertices = g.getVertices().size();`
228 | 1 | `Indexer id = Indexer.getIndexer(g);`
229 | 4 | `for (int i = 0; i < numVertices; i++) {`
230 | 3 | `Vertex v = (Vertex) id.getVertex(i);`
231 | 3 | `int vId = i+1;`
232 | 3 | `out.print("<node id=\"" + vId + "\" ");`
233 |  | ``
234 | 3 | `saveUserData(v, out);`
235 | 3 | `out.println("/>");`
236 |  | `}`
237 | 1 | `}`
238 |  | ``
239 |  | `private void saveEdgesSection(PrintStream out, Graph g) {`
240 | 1 | `Indexer id = Indexer.getIndexer(g);`
241 | 1 | `for (Iterator edgeIterator = g.getEdges().iterator(); edgeIterator.hasNext();) {`
242 | 3 | `Edge e = (Edge) edgeIterator.next();`
243 | 3 | `Pair p = e.getEndpoints();`
244 | 3 | `Vertex src = (Vertex) p.getFirst();`
245 | 3 | `Vertex dest = (Vertex) p.getSecond();`
246 | 3 | `int srcId = id.getIndex(src)+1;`
247 | 3 | `out.print("<edge source=\"" + srcId + "\" ");`
248 | 3 | `int destId = id.getIndex(dest)+1;`
249 | 3 | `out.print("target=\"" + destId + "\" ");`
250 |  | ``
251 |  | `// tag the edges that don't match the default`
252 | 3 | `if (directed)`
253 |  | `{`
254 | 0 | `if (e instanceof UndirectedEdge)`
255 | 0 | `out.print("directed=\"false\" ");`
256 |  | `}`
257 |  | `else // undirected`
258 | 3 | `if (e instanceof DirectedEdge)`
259 | 3 | `out.print("directed=\"true\" ");`
260 |  | ``
261 | 3 | `saveUserData(e, out);`
262 | 3 | `out.println("/>");`
263 |  | `}`
264 | 1 | `}`
265 |  | ``
266 |  | `private void saveUserData(UserDataContainer udc, PrintStream out) {`
267 | 7 | `Iterator udki = udc.getUserDatumKeyIterator();`
268 | 11 | `while (udki.hasNext()) {`
269 | 4 | `Object key_obj = udki.next();`
270 | 4 | `if (udc.getUserDatumCopyAction(key_obj) == UserData.REMOVE)`
271 | 1 | `continue;`
272 | 3 | `String key = key_obj.toString();`
273 | 3 | `if (invalidXMLData(key)) continue;`
274 | 3 | `Object o = udc.getUserDatum(key);`
275 | 3 | `if (o == null)`
276 | 0 | `continue;`
277 | 3 | `String datum = o.toString();`
278 | 3 | `if (invalidXMLData(datum)) continue;`
279 | 3 | `out.print(key + "=\"" + datum + "\" ");`
280 |  | `}`
281 | 7 | `}`
282 |  | ``
283 |  | `private boolean invalidXMLData(String str) {`
284 | 6 | `if (str.indexOf("&") >= 0) return true;`
285 | 6 | `if (str.indexOf("<") >= 0) return true;`
286 | 6 | `if (str.indexOf(">") >= 0) return true;`
287 | 6 | `if (str.indexOf("\'") >= 0) return true;`
288 | 6 | `if (str.indexOf("\"") >= 0) return true;`
289 | 6 | `return false;`
290 |  | `}`
291 |  | ``
292 |  | `/**`
293 |  | `* Allows the user to provide his/her own subclassed GraphML file handerl`
294 |  | `* @param fileHandler`
295 |  | `*/`
296 |  | `public void setGraphMLFileHandler(GraphMLFileHandler fileHandler) {`
297 | 0 | `mFileHandler = fileHandler;`
298 | 0 | `}`
299 |  | `}`

this report was generated by version 1.0.5 of jcoverage. visit www.jcoverage.com for updates. | copyright © 2003, jcoverage ltd. all rights reserved. Java is a trademark of Sun Microsystems, Inc. in the United States and other countries.