View Javadoc
1   /*
2    * Copyright (c) 2008, The JUNG Authors
3    *
4    * All rights reserved.
5    *
6    * This software is open-source under the BSD license; see either
7    * "license.txt" or
8    * https://github.com/jrtom/jung/blob/master/LICENSE for a description.
9    */
10  
11  package edu.uci.ics.jung.io.graphml;
12  
13  import java.io.InputStream;
14  import java.io.InputStreamReader;
15  import java.io.Reader;
16  import java.io.StringReader;
17  import java.util.ArrayList;
18  import java.util.Collections;
19  import java.util.Comparator;
20  import java.util.HashSet;
21  import java.util.List;
22  import java.util.Set;
23  
24  import org.junit.After;
25  import org.junit.Assert;
26  import org.junit.Test;
27  
28  import com.google.common.base.Function;
29  
30  import edu.uci.ics.jung.graph.Hypergraph;
31  import edu.uci.ics.jung.graph.SetHypergraph;
32  import edu.uci.ics.jung.graph.util.EdgeType;
33  import edu.uci.ics.jung.io.GraphIOException;
34  
35  public class TestGraphMLReader2 {
36      static final String graphMLDocStart = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
37              + "<graphml xmlns=\"http://graphml.graphdrawing.org/xmlns\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" "
38              + "xsi:schemaLocation=\"http://graphml.graphdrawing.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd\">";
39  
40      private GraphMLReader2<Hypergraph<DummyVertex, DummyEdge>, DummyVertex, DummyEdge> reader;
41  
42      @After
43      public void tearDown() throws Exception {
44          if (reader != null) {
45              reader.close();
46          }
47          reader = null;
48      }
49  
50  
51      @Test(expected = GraphIOException.class)
52      public void testEmptyFile() throws Exception {
53  
54          String xml = "";
55          readGraph(xml, new DummyGraphObjectBase.UndirectedSparseGraphFactory(),
56                  new DummyVertex.Factory(), new DummyEdge.EdgeFactory(), new DummyEdge.HyperEdgeFactory());
57      }
58  
59      @Test
60      public void testBasics() throws Exception {
61  
62          String xml = graphMLDocStart
63                  + "<key id=\"d0\" for=\"node\" attr.name=\"color\" attr.type=\"string\">"
64                  + "<default>yellow</default>"
65                  + "</key>"
66                  + "<key id=\"d1\" for=\"edge\" attr.name=\"weight\" attr.type=\"double\"/>"
67                  + "<graph id=\"G\" edgedefault=\"undirected\">"
68                  + "<node id=\"n0\">" + "<data key=\"d0\">green</data>"
69                  + "</node>" + "<node id=\"n1\"/>" + "<node id=\"n2\">"
70                  + "<data key=\"d0\">blue</data>" + "</node>"
71                  + "<edge id=\"e0\" source=\"n0\" target=\"n2\">"
72                  + "<data key=\"d1\">1.0</data>" + "</edge>" + "</graph>" + "</graphml>";
73  
74          // Read the graph object.
75          Hypergraph<DummyVertex, DummyEdge> graph = readGraph(xml, new DummyGraphObjectBase.UndirectedSparseGraphFactory(),
76                  new DummyVertex.Factory(), new DummyEdge.EdgeFactory(), new DummyEdge.HyperEdgeFactory());
77  
78          // Check out the graph.
79          Assert.assertNotNull(graph);
80          Assert.assertEquals(3, graph.getVertexCount());
81          Assert.assertEquals(1, graph.getEdgeCount());
82          Assert.assertEquals(0, graph.getEdgeCount(EdgeType.DIRECTED));
83          Assert.assertEquals(1, graph.getEdgeCount(EdgeType.UNDIRECTED));
84  
85          // Check out metadata.
86          Assert.assertEquals(1, reader.getGraphMLDocument().getGraphMetadata().size());
87          List<EdgeMetadata> edges = new ArrayList<EdgeMetadata>(reader.getGraphMLDocument().getGraphMetadata().get(0).getEdgeMap().values());
88          Assert.assertEquals(1, edges.size());
89          Assert.assertEquals("n0", edges.get(0).getSource());
90          Assert.assertEquals("n2", edges.get(0).getTarget());
91      }
92  
93      @Test
94      public void testData() throws Exception {
95  
96          String xml =
97                  graphMLDocStart +
98                          "<key id=\"d0\" for=\"node\" attr.name=\"color\" attr.type=\"string\">" +
99                          "<default>yellow</default>" +
100                         "</key>" +
101                         "<key id=\"d1\" for=\"edge\" attr.name=\"weight\" attr.type=\"double\"/>" +
102                         "<graph id=\"G\" edgedefault=\"undirected\">" +
103                         "<node id=\"n0\">" +
104                         "<data key=\"d0\">green</data>" +
105                         "</node>" +
106                         "<node id=\"n1\"/>" +
107                         "<node id=\"n2\">" +
108                         "<data key=\"d0\">blue</data>" +
109                         "</node>" +
110                         "<edge id=\"e0\" source=\"n0\" target=\"n2\">" +
111                         "<data key=\"d1\">1.0</data>" +
112                         "</edge>" +
113                         "</graph>" +
114                         "</graphml>";
115 
116         // Read the graph object.
117         readGraph(xml, new DummyGraphObjectBase.UndirectedSparseGraphFactory(),
118                 new DummyVertex.Factory(), new DummyEdge.EdgeFactory(), new DummyEdge.HyperEdgeFactory());
119 
120         // Check out metadata.
121         Assert.assertEquals(1, reader.getGraphMLDocument().getGraphMetadata().size());
122         List<EdgeMetadata> edges = new ArrayList<EdgeMetadata>(reader.getGraphMLDocument().getGraphMetadata().get(0).getEdgeMap().values());
123         List<NodeMetadata> nodes = new ArrayList<NodeMetadata>(reader.getGraphMLDocument().getGraphMetadata().get(0).getNodeMap().values());
124         Collections.sort(nodes, new Comparator<NodeMetadata>() {
125             public int compare(NodeMetadata o1, NodeMetadata o2) {
126                 return o1.getId().compareTo(o2.getId());
127             }            
128         });
129         Assert.assertEquals(1, edges.size());
130         Assert.assertEquals("1.0", edges.get(0).getProperties().get("d1"));
131         Assert.assertEquals(3, nodes.size());
132         Assert.assertEquals("green", nodes.get(0).getProperties().get("d0"));
133         Assert.assertEquals("yellow", nodes.get(1).getProperties().get("d0"));
134         Assert.assertEquals("blue", nodes.get(2).getProperties().get("d0"));
135     }
136 
137     @Test(expected = GraphIOException.class)
138     public void testEdgeWithInvalidNode() throws Exception {
139 
140         String xml = graphMLDocStart
141                 + "<key id=\"d0\" for=\"node\" attr.name=\"color\" attr.type=\"string\">"
142                 + "<default>yellow</default>"
143                 + "</key>"
144                 + "<key id=\"d1\" for=\"edge\" attr.name=\"weight\" attr.type=\"double\"/>"
145                 + "<graph id=\"G\" edgedefault=\"undirected\">"
146                 + "<node id=\"n0\">" + "<data key=\"d0\">green</data>"
147                 + "</node>" + "<node id=\"n1\"/>" + "<node id=\"n2\">"
148                 + "<data key=\"d0\">blue</data>" + "</node>"
149                 + "<edge id=\"e0\" source=\"n0\" target=\"n3\">" + // Invalid
150                 // node: n3
151                 "<data key=\"d1\">1.0</data>" + "</edge>" + "</graphml>";
152 
153         readGraph(xml, new DummyGraphObjectBase.UndirectedSparseGraphFactory(), new DummyVertex.Factory(),
154                 new DummyEdge.EdgeFactory(), new DummyEdge.HyperEdgeFactory());
155     }
156 
157     @Test
158     public void testHypergraph() throws Exception {
159 
160         String xml = graphMLDocStart
161                 + "<key id=\"d0\" for=\"node\" attr.name=\"color\" attr.type=\"string\">"
162                 + "<default>yellow</default>"
163                 + "</key>"
164                 + "<key id=\"d1\" for=\"edge\" attr.name=\"weight\" attr.type=\"double\"/>"
165                 + "<graph id=\"G\" edgedefault=\"undirected\">"
166                 + "<node id=\"n0\">" + "<data key=\"d0\">green</data>"
167                 + "</node>" + "<node id=\"n1\"/>" + "<node id=\"n2\">"
168                 + "<data key=\"d0\">blue</data>" + "</node>"
169                 + "<hyperedge id=\"e0\">"
170                 + "<endpoint node=\"n0\"/>" + "<endpoint node=\"n1\"/>"
171                 + "<endpoint node=\"n2\"/>" + "</hyperedge>" + "</graph>" + "</graphml>";
172 
173         // Read the graph object.
174         Hypergraph<DummyVertex, DummyEdge> graph = readGraph(xml, new DummyGraphObjectBase.SetHypergraphFactory(),
175                 new DummyVertex.Factory(), new DummyEdge.EdgeFactory(), new DummyEdge.HyperEdgeFactory());
176 
177         // Check out the graph.
178         Assert.assertNotNull(graph);
179         Assert.assertEquals(3, graph.getVertexCount());
180         Assert.assertEquals(1, graph.getEdgeCount());
181         Assert.assertEquals(0, graph.getEdgeCount(EdgeType.DIRECTED));
182         Assert.assertEquals(1, graph.getEdgeCount(EdgeType.UNDIRECTED));
183 
184         // Check out metadata.
185         Assert.assertEquals(1, reader.getGraphMLDocument().getGraphMetadata().size());
186         List<HyperEdgeMetadata> edges = new ArrayList<HyperEdgeMetadata>(reader.getGraphMLDocument().getGraphMetadata().get(0).getHyperEdgeMap().values());
187         Assert.assertEquals(1, edges.size());
188         Assert.assertEquals(3, edges.get(0).getEndpoints().size());
189         Assert.assertEquals("n0", edges.get(0).getEndpoints().get(0).getNode());
190         Assert.assertEquals("n1", edges.get(0).getEndpoints().get(1).getNode());
191         Assert.assertEquals("n2", edges.get(0).getEndpoints().get(2).getNode());
192     }
193 
194     @Test(expected = IllegalArgumentException.class)
195     public void testInvalidGraphFactory() throws Exception {
196 
197         // Need a hypergraph
198         String xml = graphMLDocStart
199                 + "<key id=\"d0\" for=\"node\" attr.name=\"color\" attr.type=\"string\">"
200                 + "<default>yellow</default>"
201                 + "</key>"
202                 + "<key id=\"d1\" for=\"edge\" attr.name=\"weight\" attr.type=\"double\"/>"
203                 + "<graph id=\"G\" edgedefault=\"undirected\">"
204                 + "<node id=\"n0\">" + "<data key=\"d0\">green</data>"
205                 + "</node>" + "<node id=\"n1\"/>" + "<node id=\"n2\">"
206                 + "<data key=\"d0\">blue</data>" + "</node>"
207                 + "<hyperedge id=\"e0\">"
208                 + "<endpoint node=\"n0\"/>" + "<endpoint node=\"n1\"/>"
209                 + "<endpoint node=\"n2\"/>" + "</hyperedge>" + "</graphml>";
210 
211 	// This will attempt to add an edge with an invalid number of incident vertices (3)
212 	// for an UndirectedGraph, which should trigger an IllegalArgumentException.
213         readGraph(xml, new DummyGraphObjectBase.UndirectedSparseGraphFactory(),
214                 new DummyVertex.Factory(), new DummyEdge.EdgeFactory(), new DummyEdge.HyperEdgeFactory());
215     }
216 
217     @Test
218     public void testAttributesFile() throws Exception {
219 
220         // Read the graph object.
221         Hypergraph<DummyVertex, DummyEdge> graph = readGraphFromFile("attributes.graphml", new DummyGraphObjectBase.UndirectedSparseGraphFactory(),
222                 new DummyVertex.Factory(), new DummyEdge.EdgeFactory(), new DummyEdge.HyperEdgeFactory());
223 
224         Assert.assertEquals(6, graph.getVertexCount());
225         Assert.assertEquals(7, graph.getEdgeCount());
226 
227         Assert.assertEquals(1, reader.getGraphMLDocument().getGraphMetadata().size());
228 
229         // Test node ids
230         int id = 0;        
231         List<NodeMetadata> nodes = new ArrayList<NodeMetadata>(reader.getGraphMLDocument().getGraphMetadata().get(0).getNodeMap().values());
232         Collections.sort(nodes, new Comparator<NodeMetadata>() {
233             public int compare(NodeMetadata o1, NodeMetadata o2) {
234                 return o1.getId().compareTo(o2.getId());
235             }            
236         });
237         Assert.assertEquals(6, nodes.size());
238         for (NodeMetadata md : nodes) {
239             Assert.assertEquals('n', md.getId().charAt(0));
240             Assert.assertEquals(id++, Integer.parseInt(md.getId().substring(1)));
241         }
242 
243         // Test edge ids
244         id = 0;
245         List<EdgeMetadata> edges = new ArrayList<EdgeMetadata>(reader.getGraphMLDocument().getGraphMetadata().get(0).getEdgeMap().values());
246         Collections.sort(edges, new Comparator<EdgeMetadata>() {
247             public int compare(EdgeMetadata o1, EdgeMetadata o2) {
248                 return o1.getId().compareTo(o2.getId());
249             }            
250         });
251         Assert.assertEquals(7, edges.size());
252         for (EdgeMetadata md : edges) {
253             Assert.assertEquals('e', md.getId().charAt(0));
254             Assert.assertEquals(id++, Integer.parseInt(md.getId().substring(1)));
255         }
256 
257         Assert.assertEquals("green", nodes.get(0).getProperties().get("d0"));
258         Assert.assertEquals("yellow", nodes.get(1).getProperties().get("d0"));
259         Assert.assertEquals("blue", nodes.get(2).getProperties().get("d0"));
260         Assert.assertEquals("red", nodes.get(3).getProperties().get("d0"));
261         Assert.assertEquals("yellow", nodes.get(4).getProperties().get("d0"));
262         Assert.assertEquals("turquoise", nodes.get(5).getProperties().get("d0"));
263 
264         Assert.assertEquals("1.0", edges.get(0).getProperties().get("d1"));
265         Assert.assertEquals("1.0", edges.get(1).getProperties().get("d1"));
266         Assert.assertEquals("2.0", edges.get(2).getProperties().get("d1"));
267         Assert.assertEquals(null, edges.get(3).getProperties().get("d1"));
268         Assert.assertEquals(null, edges.get(4).getProperties().get("d1"));
269         Assert.assertEquals(null, edges.get(5).getProperties().get("d1"));
270         Assert.assertEquals("1.1", edges.get(6).getProperties().get("d1"));
271     }
272 
273     @Test
274     public void testHypergraphFile() throws Exception {
275 
276         Function<GraphMetadata, Hypergraph<Number, Number>> graphFactory = new Function<GraphMetadata, Hypergraph<Number, Number>>() {
277             public Hypergraph<Number, Number> apply(GraphMetadata md) {
278                 return new SetHypergraph<Number, Number>();
279             }
280         };
281 
282         Function<NodeMetadata, Number> vertexFactory = new Function<NodeMetadata, Number>() {
283             int n = 0;
284 
285             public Number apply(NodeMetadata md) {
286                 return n++;
287             }
288         };
289 
290         Function<EdgeMetadata, Number> edgeFactory = new Function<EdgeMetadata, Number>() {
291             int n = 100;
292 
293             public Number apply(EdgeMetadata md) {
294                 return n++;
295             }
296         };
297 
298         Function<HyperEdgeMetadata, Number> hyperEdgeFactory = new Function<HyperEdgeMetadata, Number>() {
299             int n = 0;
300 
301             public Number apply(HyperEdgeMetadata md) {
302                 return n++;
303             }
304         };
305 
306         // Read the graph object.        
307         Reader fileReader = new InputStreamReader(getClass().getResourceAsStream("hyper.graphml"));
308         GraphMLReader2<Hypergraph<Number, Number>, Number, Number> hyperreader =
309                 new GraphMLReader2<Hypergraph<Number, Number>, Number, Number>(fileReader,
310                         graphFactory, vertexFactory, edgeFactory, hyperEdgeFactory);
311 
312         // Read the graph.
313         Hypergraph<Number, Number> graph = hyperreader.readGraph();
314 
315         Assert.assertEquals(graph.getVertexCount(), 7);
316         Assert.assertEquals(graph.getEdgeCount(), 4);
317 
318         // n0
319         Set<Number> incident = new HashSet<Number>();
320         incident.add(0);
321         incident.add(100);
322         Assert.assertEquals(incident, graph.getIncidentEdges(0));
323 
324         // n1
325         incident.clear();
326         incident.add(0);
327         incident.add(2);
328         Assert.assertEquals(incident, graph.getIncidentEdges(1));
329 
330         // n2
331         incident.clear();
332         incident.add(0);
333         Assert.assertEquals(incident, graph.getIncidentEdges(2));
334 
335         // n3
336         incident.clear();
337         incident.add(1);
338         incident.add(2);
339         Assert.assertEquals(incident, graph.getIncidentEdges(3));
340 
341         // n4
342         incident.clear();
343         incident.add(1);
344         incident.add(100);
345         Assert.assertEquals(incident, graph.getIncidentEdges(4));
346 
347         // n5
348         incident.clear();
349         incident.add(1);
350         Assert.assertEquals(incident, graph.getIncidentEdges(5));
351 
352         // n6
353         incident.clear();
354         incident.add(1);
355         Assert.assertEquals(incident, graph.getIncidentEdges(6));
356     }
357 
358     /*@Test
359     public void testReader1Perf() throws Exception {
360         String fileName = "attributes.graphml";                
361         
362         long totalTime = 0;
363         int numTrials = 1000;
364 
365         for( int ix=0; ix<numTrials; ++ix ) {
366             Reader fileReader = new InputStreamReader(getClass().getResourceAsStream(fileName));
367                         
368             GraphMLReader<Hypergraph<DummyVertex, DummyEdge>, DummyVertex, DummyEdge> reader = new GraphMLReader<Hypergraph<DummyVertex, DummyEdge>, DummyVertex, DummyEdge>(new Factory<DummyVertex>() {
369 
370                 public DummyVertex create() {
371                     return new DummyVertex();
372                 }
373                 
374             }, new Factory<DummyEdge>() {
375                 public DummyEdge create() {
376                     return new DummyEdge();
377                 }
378             });   
379             
380             Thread.sleep(10);
381             
382             long start = System.currentTimeMillis();
383             Hypergraph<DummyVertex, DummyEdge> graph = new UndirectedSparseGraph<DummyVertex, DummyEdge>();
384             reader.load(fileReader, graph);
385             long duration = System.currentTimeMillis() - start;
386             totalTime += duration;
387         }
388         
389         double avgTime = ((double)totalTime / (double)numTrials) / 1000.0; 
390         
391         System.out.printf("Reader1: totalTime=%6d, numTrials=%6d, avgTime=%2.6f seconds", totalTime, numTrials, avgTime);
392         System.out.println();
393     }
394 
395     @Test
396     public void testReader2Perf() throws Exception {
397         String fileName = "attributes.graphml";                
398         
399         long totalTime = 0;
400         int numTrials = 1000;
401 
402         // Test reader2
403         for( int ix=0; ix<numTrials; ++ix ) {
404             Reader fileReader = new InputStreamReader(getClass().getResourceAsStream(fileName));       
405             reader = new GraphMLReader2<Hypergraph<DummyVertex, DummyEdge>, DummyVertex, DummyEdge>(
406                     fileReader, new DummyGraphObjectBase.UndirectedSparseGraphFactory(),
407                     new DummyVertex.Factory(), new DummyEdge.EdgeFactory(), new DummyEdge.HyperEdgeFactory());
408             reader.init();
409             
410             Thread.sleep(10);
411             
412             long start = System.currentTimeMillis();
413             reader.readGraph();
414             long duration = System.currentTimeMillis() - start;
415             totalTime += duration;
416             
417             reader.close();
418         }
419         
420         double avgTime = ((double)totalTime / (double)numTrials) / 1000.0; 
421         
422         System.out.printf("Reader2: totalTime=%6d, numTrials=%6d, avgTime=%2.6f seconds", totalTime, numTrials, avgTime);
423         System.out.println();
424     }*/
425 
426     private Hypergraph<DummyVertex, DummyEdge> readGraph(String xml, Function<GraphMetadata, Hypergraph<DummyVertex, DummyEdge>> gf,
427                                                  DummyVertex.Factory nf, DummyEdge.EdgeFactory ef, DummyEdge.HyperEdgeFactory hef)
428             throws GraphIOException {
429         Reader fileReader = new StringReader(xml);
430         reader = new GraphMLReader2<Hypergraph<DummyVertex, DummyEdge>, DummyVertex, DummyEdge>(
431                 fileReader, gf, nf, ef, hef);
432 
433         return reader.readGraph();
434     }
435 
436     private Hypergraph<DummyVertex, DummyEdge> readGraphFromFile(String file, Function<GraphMetadata, Hypergraph<DummyVertex, DummyEdge>> gf,
437             DummyVertex.Factory nf, DummyEdge.EdgeFactory ef, DummyEdge.HyperEdgeFactory hef)
438             throws Exception {
439         InputStream is = getClass().getResourceAsStream(file);
440         Reader fileReader = new InputStreamReader(is);
441         reader = new GraphMLReader2<Hypergraph<DummyVertex, DummyEdge>, DummyVertex, DummyEdge>(
442                 fileReader, gf, nf, ef, hef);
443 
444         return reader.readGraph();
445     }
446 
447 }