1
2
3
4
5
6
7
8
9
10
11 package edu.uci.ics.jung.io.graphml.parser;
12
13 import java.util.ArrayList;
14 import java.util.Collection;
15 import java.util.HashMap;
16 import java.util.Iterator;
17 import java.util.LinkedList;
18 import java.util.List;
19 import java.util.Map;
20
21 import javax.xml.stream.XMLEventReader;
22 import javax.xml.stream.events.Attribute;
23 import javax.xml.stream.events.EndElement;
24 import javax.xml.stream.events.StartElement;
25 import javax.xml.stream.events.XMLEvent;
26
27 import edu.uci.ics.jung.graph.Graph;
28 import edu.uci.ics.jung.graph.Hypergraph;
29 import edu.uci.ics.jung.graph.util.EdgeType;
30 import edu.uci.ics.jung.graph.util.Pair;
31 import edu.uci.ics.jung.io.GraphIOException;
32 import edu.uci.ics.jung.io.graphml.*;
33 import edu.uci.ics.jung.io.graphml.GraphMetadata.EdgeDefault;
34
35
36
37
38
39
40 public class GraphElementParser<G extends Hypergraph<V,E>,V,E> extends AbstractElementParser<G,V,E> {
41
42 public GraphElementParser(ParserContext<G,V,E> parserContext) {
43 super(parserContext);
44 }
45
46 public GraphMetadata parse(XMLEventReader xmlEventReader, StartElement start)
47 throws GraphIOException {
48
49 try {
50
51 GraphMetadata graphMetadata = new GraphMetadata();
52
53
54 @SuppressWarnings("unchecked")
55 Iterator<Attribute> iterator = start.getAttributes();
56 while (iterator.hasNext()) {
57 Attribute attribute = iterator.next();
58 String name = attribute.getName().getLocalPart();
59 String value = attribute.getValue();
60 if (graphMetadata.getId() == null
61 && GraphMLConstants.ID_NAME.equals(name)) {
62
63 graphMetadata.setId(value);
64 } else if (graphMetadata.getEdgeDefault() == null
65 && GraphMLConstants.EDGEDEFAULT_NAME.equals(name)) {
66
67 graphMetadata.setEdgeDefault(GraphMLConstants.DIRECTED_NAME
68 .equals(value) ? EdgeDefault.DIRECTED
69 : EdgeDefault.UNDIRECTED);
70 } else {
71 graphMetadata.setProperty(name, value);
72 }
73 }
74
75
76 if (graphMetadata.getEdgeDefault() == null) {
77 throw new GraphIOException(
78 "Element 'graph' is missing attribute 'edgedefault'");
79 }
80
81 Map<String, V> idToVertexMap = new HashMap<String, V>();
82 Collection<EdgeMetadata> edgeMetadata = new LinkedList<EdgeMetadata>();
83 Collection<HyperEdgeMetadata> hyperEdgeMetadata = new LinkedList<HyperEdgeMetadata>();
84
85 while (xmlEventReader.hasNext()) {
86
87 XMLEvent event = xmlEventReader.nextEvent();
88 if (event.isStartElement()) {
89 StartElement element = (StartElement) event;
90
91 String name = element.getName().getLocalPart();
92 if (GraphMLConstants.DESC_NAME.equals(name)) {
93
94
95 String desc = (String) getParser(name).parse(
96 xmlEventReader, element);
97 graphMetadata.setDescription(desc);
98
99 } else if (GraphMLConstants.DATA_NAME.equals(name)) {
100
101
102 DataMetadata data = (DataMetadata) getParser(name).parse(
103 xmlEventReader, element);
104 graphMetadata.addData(data);
105
106 } else if (GraphMLConstants.NODE_NAME.equals(name)) {
107
108
109 NodeMetadata metadata = (NodeMetadata) getParser(name).parse(
110 xmlEventReader, element);
111
112
113 V vertex = getParserContext().createVertex(metadata);
114 metadata.setVertex(vertex);
115 idToVertexMap.put(metadata.getId(), vertex);
116
117
118 graphMetadata.addNodeMetadata(vertex, metadata);
119
120 } else if (GraphMLConstants.EDGE_NAME.equals(name)) {
121
122
123 EdgeMetadata metadata = (EdgeMetadata) getParser(name).parse(
124 xmlEventReader, element);
125
126
127 if (metadata.isDirected() == null) {
128 metadata.setDirected(graphMetadata.getEdgeDefault() == EdgeDefault.DIRECTED);
129 }
130
131
132 E edge = getParserContext().createEdge(metadata);
133 edgeMetadata.add(metadata);
134 metadata.setEdge(edge);
135
136
137 graphMetadata.addEdgeMetadata(edge, metadata);
138
139 } else if (GraphMLConstants.HYPEREDGE_NAME.equals(name)) {
140
141
142 HyperEdgeMetadata metadata = (HyperEdgeMetadata) getParser(name).parse(
143 xmlEventReader, element);
144
145
146 E edge = getParserContext().createHyperEdge(metadata);
147 hyperEdgeMetadata.add(metadata);
148 metadata.setEdge(edge);
149
150
151 graphMetadata.addHyperEdgeMetadata(edge, metadata);
152
153 } else {
154
155
156 getUnknownParser().parse(xmlEventReader, element);
157 }
158
159 }
160 if (event.isEndElement()) {
161 EndElement end = (EndElement) event;
162 verifyMatch(start, end);
163 break;
164 }
165 }
166
167
168 applyKeys(graphMetadata);
169
170
171 G graph = getParserContext().createGraph(graphMetadata);
172 graphMetadata.setGraph(graph);
173
174
175 addVerticesToGraph(graph, idToVertexMap.values());
176
177
178 addEdgesToGraph(graph, edgeMetadata, idToVertexMap);
179 addHyperEdgesToGraph(graph, hyperEdgeMetadata, idToVertexMap);
180
181 return graphMetadata;
182
183 } catch (Exception e) {
184 ExceptionConverter.convert(e);
185 }
186
187 return null;
188 }
189
190 private void addVerticesToGraph(G graph, Collection<V> vertices) {
191
192 for (V vertex : vertices) {
193 graph.addVertex(vertex);
194 }
195 }
196
197 @SuppressWarnings("unchecked")
198 private void addEdgesToGraph(G graph, Collection<EdgeMetadata> metadata,
199 Map<String,V> idToVertexMap) throws GraphIOException {
200
201 for (EdgeMetadata emd : metadata) {
202
203
204 E edge = (E)emd.getEdge();
205
206
207 V source = idToVertexMap.get(emd.getSource());
208 V target = idToVertexMap.get(emd.getTarget());
209 if (source == null || target == null) {
210 throw new GraphIOException(
211 "edge references undefined source or target vertex. "
212 + "Source: " + emd.getSource()
213 + ", Target: " + emd.getTarget());
214 }
215
216
217 if (graph instanceof Graph) {
218 ((Graph<V, E>) graph).addEdge(edge, source, target, emd
219 .isDirected() ? EdgeType.DIRECTED
220 : EdgeType.UNDIRECTED);
221 } else {
222 graph.addEdge(edge, new Pair<V>(source, target));
223 }
224 }
225 }
226
227 @SuppressWarnings("unchecked")
228 private void addHyperEdgesToGraph(G graph, Collection<HyperEdgeMetadata> metadata,
229 Map<String,V> idToVertexMap) throws GraphIOException {
230
231 for (HyperEdgeMetadata emd : metadata) {
232
233
234 E edge = (E)emd.getEdge();
235
236
237 List<V> verticies = new ArrayList<V>();
238 List<EndpointMetadata> endpoints = emd.getEndpoints();
239 for (EndpointMetadata ep : endpoints) {
240 V v = idToVertexMap.get(ep.getNode());
241 if (v == null) {
242 throw new GraphIOException(
243 "hyperedge references undefined vertex: "
244 + ep.getNode());
245 }
246 verticies.add(v);
247 }
248
249
250 graph.addEdge(edge, verticies);
251 }
252 }
253 }