KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > prefuse > data > io > GraphMLReader


1 package prefuse.data.io;
2
3 import java.io.InputStream JavaDoc;
4 import java.util.Date JavaDoc;
5 import java.util.HashMap JavaDoc;
6
7 import javax.xml.parsers.SAXParser JavaDoc;
8 import javax.xml.parsers.SAXParserFactory JavaDoc;
9
10 import org.xml.sax.Attributes JavaDoc;
11 import org.xml.sax.SAXException JavaDoc;
12 import org.xml.sax.helpers.DefaultHandler JavaDoc;
13
14 import prefuse.data.Graph;
15 import prefuse.data.Schema;
16 import prefuse.data.Table;
17 import prefuse.data.parser.DataParseException;
18 import prefuse.data.parser.DataParser;
19 import prefuse.data.parser.ParserFactory;
20 import prefuse.util.collections.IntIterator;
21
22
23 /**
24  * GraphReader instance that reads in graph file formatted using the
25  * GraphML file format. GraphML is an XML format supporting graph
26  * structure and typed data schemas for both nodes and edges. For more
27  * information about the format, please see the
28  * <a HREF="http://graphml.graphdrawing.org/">GraphML home page</a>.
29  *
30  * @author <a HREF="http://jheer.org">jeffrey heer</a>
31  */

32 public class GraphMLReader extends AbstractGraphReader implements GraphReader {
33     
34     /**
35      * @see prefuse.data.io.GraphReader#readGraph(java.io.InputStream)
36      */

37     public Graph readGraph(InputStream JavaDoc is) throws DataIOException {
38         try {
39             SAXParserFactory JavaDoc factory = SAXParserFactory.newInstance();
40             SAXParser JavaDoc saxParser = factory.newSAXParser();
41             
42             GraphMLHandler handler = new GraphMLHandler();
43             saxParser.parse(is, handler);
44             return handler.getGraph();
45         } catch ( Exception JavaDoc e ) {
46             if ( e instanceof DataIOException ) {
47                 throw (DataIOException)e;
48             } else {
49                 throw new DataIOException(e);
50             }
51         }
52     }
53     
54     /**
55      * String tokens used in the GraphML format.
56      */

57     public interface Tokens {
58         public static final String JavaDoc ID = "id";
59         public static final String JavaDoc GRAPH = "graph";
60         public static final String JavaDoc EDGEDEF = "edgedefault";
61         public static final String JavaDoc DIRECTED = "directed";
62         public static final String JavaDoc UNDIRECTED = "undirected";
63         
64         public static final String JavaDoc KEY = "key";
65         public static final String JavaDoc FOR = "for";
66         public static final String JavaDoc ALL = "all";
67         public static final String JavaDoc ATTRNAME = "attr.name";
68         public static final String JavaDoc ATTRTYPE = "attr.type";
69         public static final String JavaDoc DEFAULT = "default";
70         
71         public static final String JavaDoc NODE = "node";
72         public static final String JavaDoc EDGE = "edge";
73         public static final String JavaDoc SOURCE = "source";
74         public static final String JavaDoc TARGET = "target";
75         public static final String JavaDoc DATA = "data";
76         public static final String JavaDoc TYPE = "type";
77         
78         public static final String JavaDoc INT = "int";
79         public static final String JavaDoc INTEGER = "integer";
80         public static final String JavaDoc LONG = "long";
81         public static final String JavaDoc FLOAT = "float";
82         public static final String JavaDoc DOUBLE = "double";
83         public static final String JavaDoc REAL = "real";
84         public static final String JavaDoc BOOLEAN = "boolean";
85         public static final String JavaDoc STRING = "string";
86         public static final String JavaDoc DATE = "date";
87     }
88     
89     /**
90      * A SAX Parser for GraphML data files.
91      */

92     public static class GraphMLHandler extends DefaultHandler JavaDoc implements Tokens
93     {
94         protected ParserFactory JavaDoc m_pf = ParserFactory.getDefaultFactory();
95         
96         protected static final String JavaDoc SRC = Graph.DEFAULT_SOURCE_KEY;
97         protected static final String JavaDoc TRG = Graph.DEFAULT_TARGET_KEY;
98         protected static final String JavaDoc SRCID = SRC+'_'+ID;
99         protected static final String JavaDoc TRGID = TRG+'_'+ID;
100         
101         protected Schema m_nsch = new Schema();
102         protected Schema m_esch = new Schema();
103         
104         protected String JavaDoc m_graphid;
105         protected Graph m_graph = null;
106         protected Table m_nodes;
107         protected Table m_edges;
108         
109         // schema parsing
110
protected String JavaDoc m_id;
111         protected String JavaDoc m_for;
112         protected String JavaDoc m_name;
113         protected String JavaDoc m_type;
114         protected String JavaDoc m_dflt;
115         
116         protected StringBuffer JavaDoc m_sbuf = new StringBuffer JavaDoc();
117         
118         // node,edge,data parsing
119
private String JavaDoc m_key;
120         private int m_row = -1;
121         private Table m_table = null;
122         protected HashMap JavaDoc m_nodeMap = new HashMap JavaDoc();
123         protected HashMap JavaDoc m_idMap = new HashMap JavaDoc();
124         
125         private boolean m_directed = false;
126         private boolean inSchema;
127         
128         public void startDocument() {
129             m_nodeMap.clear();
130             inSchema = true;
131             
132             m_esch.addColumn(SRC, int.class);
133             m_esch.addColumn(TRG, int.class);
134             m_esch.addColumn(SRCID, String JavaDoc.class);
135             m_esch.addColumn(TRGID, String JavaDoc.class);
136         }
137         
138         public void endDocument() throws SAXException JavaDoc {
139             // time to actually set up the edges
140
IntIterator rows = m_edges.rows();
141             while (rows.hasNext()) {
142                 int r = rows.nextInt();
143
144                 String JavaDoc src = m_edges.getString(r, SRCID);
145                 if (!m_nodeMap.containsKey(src)) {
146                     throw new SAXException JavaDoc(
147                         "Tried to create edge with source node id=" + src
148                         + " which does not exist.");
149                 }
150                 int s = ((Integer JavaDoc) m_nodeMap.get(src)).intValue();
151                 m_edges.setInt(r, SRC, s);
152
153                 String JavaDoc trg = m_edges.getString(r, TRGID);
154                 if (!m_nodeMap.containsKey(trg)) {
155                     throw new SAXException JavaDoc(
156                         "Tried to create edge with target node id=" + trg
157                         + " which does not exist.");
158                 }
159                 int t = ((Integer JavaDoc) m_nodeMap.get(trg)).intValue();
160                 m_edges.setInt(r, TRG, t);
161             }
162             m_edges.removeColumn(SRCID);
163             m_edges.removeColumn(TRGID);
164
165             // now create the graph
166
m_graph = new Graph(m_nodes, m_edges, m_directed);
167             if (m_graphid != null)
168                 m_graph.putClientProperty(ID, m_graphid);
169         }
170         
171         public void startElement(String JavaDoc namespaceURI, String JavaDoc localName,
172                                  String JavaDoc qName, Attributes JavaDoc atts)
173         {
174             // first clear the character buffer
175
m_sbuf.delete(0, m_sbuf.length());
176             
177             if ( qName.equals(GRAPH) )
178             {
179                 // parse directedness default
180
String JavaDoc edef = atts.getValue(EDGEDEF);
181                 m_directed = DIRECTED.equalsIgnoreCase(edef);
182                 m_graphid = atts.getValue(ID);
183             }
184             else if ( qName.equals(KEY) )
185             {
186                 if ( !inSchema ) {
187                     error("\""+KEY+"\" elements can not"
188                         + " occur after the first node or edge declaration.");
189                 }
190                 m_for = atts.getValue(FOR);
191                 m_id = atts.getValue(ID);
192                 m_name = atts.getValue(ATTRNAME);
193                 m_type = atts.getValue(ATTRTYPE);
194             }
195             else if ( qName.equals(NODE) )
196             {
197                 schemaCheck();
198                 
199                 m_row = m_nodes.addRow();
200                 
201                 String JavaDoc id = atts.getValue(ID);
202                 m_nodeMap.put(id, new Integer JavaDoc(m_row));
203                 m_table = m_nodes;
204             }
205             else if ( qName.equals(EDGE) )
206             {
207                 schemaCheck();
208                 
209                 m_row = m_edges.addRow();
210                 
211                 // do not use the id value
212
// String id = atts.getValue(ID);
213
// if ( id != null ) {
214
// if ( !m_edges.canGetString(ID) )
215
// m_edges.addColumn(ID, String.class);
216
// m_edges.setString(m_row, ID, id);
217
// }
218
m_edges.setString(m_row, SRCID, atts.getValue(SRC));
219                 m_edges.setString(m_row, TRGID, atts.getValue(TRG));
220                 
221                 // currently only global directedness is used
222
// ignore directed edge value for now
223
// String dir = atts.getValue(DIRECTED);
224
// boolean d = m_directed;
225
// if ( dir != null ) {
226
// d = dir.equalsIgnoreCase("false");
227
// }
228
// m_edges.setBoolean(m_row, DIRECTED, d);
229
m_table = m_edges;
230             }
231             else if ( qName.equals(DATA) )
232             {
233                 m_key = atts.getValue(KEY);
234             }
235         }
236
237         public void endElement(String JavaDoc namespaceURI,
238                 String JavaDoc localName, String JavaDoc qName)
239         {
240             if ( qName.equals(DEFAULT) ) {
241                 // value is in the buffer
242
m_dflt = m_sbuf.toString();
243             }
244             else if ( qName.equals(KEY) ) {
245                 // time to add to the proper schema(s)
246
addToSchema();
247             }
248             else if ( qName.equals(DATA) ) {
249                 // value is in the buffer
250
String JavaDoc value = m_sbuf.toString();
251                 String JavaDoc name = (String JavaDoc)m_idMap.get(m_key);
252                 Class JavaDoc type = m_table.getColumnType(name);
253                 try {
254                     Object JavaDoc val = parse(value, type);
255                     m_table.set(m_row, name, val);
256                 } catch ( DataParseException dpe ) {
257                     error(dpe);
258                 }
259             }
260             else if ( qName.equals(NODE) || qName.equals(EDGE) ) {
261                 m_row = -1;
262                 m_table = null;
263             }
264         }
265         
266         public void characters(char[] ch, int start, int length) throws SAXException JavaDoc {
267             m_sbuf.append(ch, start, length);
268         }
269
270         // --------------------------------------------------------------------
271

272         protected void schemaCheck() {
273             if ( inSchema ) {
274                 m_nsch.lockSchema();
275                 m_esch.lockSchema();
276                 m_nodes = m_nsch.instantiate();
277                 m_edges = m_esch.instantiate();
278                 inSchema = false;
279             }
280         }
281         
282         protected void addToSchema() {
283             if ( m_name == null || m_name.length() == 0 )
284                 error("Empty "+KEY+" name.");
285             if ( m_type == null || m_type.length() == 0 )
286                 error("Empty "+KEY+" type.");
287             
288             try {
289                 Class JavaDoc type = parseType(m_type);
290                 Object JavaDoc dflt = m_dflt==null ? null : parse(m_dflt, type);
291                 
292                 if ( m_for == null || m_for.equals(ALL) ) {
293                     m_nsch.addColumn(m_name, type, dflt);
294                     m_esch.addColumn(m_name, type, dflt);
295                 } else if ( m_for.equals(NODE) ) {
296                     m_nsch.addColumn(m_name, type, dflt);
297                 } else if ( m_for.equals(EDGE) ) {
298                     m_esch.addColumn(m_name, type, dflt);
299                 } else {
300                     error("Unrecognized \""+FOR+"\" value: "+ m_for);
301                 }
302                 m_idMap.put(m_id, m_name);
303                 
304                 m_dflt = null;
305             } catch ( DataParseException dpe ) {
306                 error(dpe);
307             }
308         }
309         
310         protected Class JavaDoc parseType(String JavaDoc type) {
311             type = type.toLowerCase();
312             if ( type.equals(INT) || type.equals(INTEGER) ) {
313                 return int.class;
314             } else if ( type.equals(LONG) ) {
315                 return long.class;
316             } else if ( type.equals(FLOAT) ) {
317                 return float.class;
318             } else if ( type.equals(DOUBLE) || type.equals(REAL)) {
319                 return double.class;
320             } else if ( type.equals(BOOLEAN) ) {
321                 return boolean.class;
322             } else if ( type.equals(STRING) ) {
323                 return String JavaDoc.class;
324             } else if ( type.equals(DATE) ) {
325                 return Date JavaDoc.class;
326             } else {
327                 error("Unrecognized data type: "+type);
328                 return null;
329             }
330         }
331         
332         protected Object JavaDoc parse(String JavaDoc s, Class JavaDoc type)
333             throws DataParseException
334         {
335             DataParser dp = m_pf.getParser(type);
336             return dp.parse(s);
337         }
338         
339         public Graph getGraph() {
340             return m_graph;
341         }
342         
343         protected void error(String JavaDoc s) {
344             throw new RuntimeException JavaDoc(s);
345         }
346         
347         protected void error(Exception JavaDoc e) {
348             throw new RuntimeException JavaDoc(e);
349         }
350         
351     } // end of inner class GraphMLHandler
352

353 } // end of class XMLGraphReader
354
Popular Tags