KickJava   Java API By Example, From Geeks To Geeks.

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


1 /**
2  * Copyright (c) 2004-2006 Regents of the University of California.
3  * See "license-prefuse.txt" for licensing terms.
4  */

5 package prefuse.data.io;
6
7 import java.io.OutputStream JavaDoc;
8 import java.io.PrintWriter JavaDoc;
9 import java.util.Date JavaDoc;
10 import java.util.HashMap JavaDoc;
11 import java.util.Iterator JavaDoc;
12
13 import prefuse.data.Edge;
14 import prefuse.data.Graph;
15 import prefuse.data.Node;
16 import prefuse.data.Schema;
17 import prefuse.util.io.XMLWriter;
18
19 /**
20  * GraphWriter instance that writes a graph file formatted using the
21  * GraphML file format. GraphML is an XML format supporting graph
22  * structure and typed data schemas for both nodes and edges. For more
23  * information about the format, please see the
24  * <a HREF="http://graphml.graphdrawing.org/">GraphML home page</a>.
25  *
26  * <p>The GraphML spec only supports the data types <code>int</code>,
27  * <code>long</code>, <code>float</code>, <code>double</code>,
28  * <code>boolean</code>, and <code>string</code>. An exception will
29  * be thrown if a data type outside these allowed types is
30  * encountered.</p>
31  *
32  * @author <a HREF="http://jheer.org">jeffrey heer</a>
33  */

34 public class GraphMLWriter extends AbstractGraphWriter {
35
36     /**
37      * String tokens used in the GraphML format.
38      */

39     public interface Tokens extends GraphMLReader.Tokens {
40         public static final String JavaDoc GRAPHML = "graphml";
41         
42         public static final String JavaDoc GRAPHML_HEADER =
43             "<graphml xmlns=\"http://graphml.graphdrawing.org/xmlns\"\n"
44             +" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n"
45             +" xsi:schemaLocation=\"http://graphml.graphdrawing.org/xmlns\n"
46             +" http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd\">\n\n";
47     }
48     
49     /**
50      * Map containing legal data types and their names in the GraphML spec
51      */

52     private static final HashMap JavaDoc TYPES = new HashMap JavaDoc();
53     static {
54         TYPES.put(int.class, Tokens.INT);
55         TYPES.put(long.class, Tokens.LONG);
56         TYPES.put(float.class, Tokens.FLOAT);
57         TYPES.put(double.class, Tokens.DOUBLE);
58         TYPES.put(boolean.class, Tokens.BOOLEAN);
59         TYPES.put(String JavaDoc.class, Tokens.STRING);
60     }
61     
62     /**
63      * @see prefuse.data.io.GraphWriter#writeGraph(prefuse.data.Graph, java.io.OutputStream)
64      */

65     public void writeGraph(Graph graph, OutputStream JavaDoc os) throws DataIOException
66     {
67         // first, check the schemas to ensure GraphML compatibility
68
Schema ns = graph.getNodeTable().getSchema();
69         Schema es = graph.getEdgeTable().getSchema();
70         checkGraphMLSchema(ns);
71         checkGraphMLSchema(es);
72         
73         XMLWriter xml = new XMLWriter(new PrintWriter JavaDoc(os));
74         xml.begin(Tokens.GRAPHML_HEADER, 2);
75         
76         xml.comment("prefuse GraphML Writer | "
77                 + new Date JavaDoc(System.currentTimeMillis()));
78         
79         // print the graph schema
80
printSchema(xml, Tokens.NODE, ns, null);
81         printSchema(xml, Tokens.EDGE, es, new String JavaDoc[] {
82             graph.getEdgeSourceField(), graph.getEdgeTargetField()
83         });
84         xml.println();
85         
86         // print graph contents
87
xml.start(Tokens.GRAPH, Tokens.EDGEDEF,
88             graph.isDirected() ? Tokens.DIRECTED : Tokens.UNDIRECTED);
89         
90         // print the nodes
91
xml.comment("nodes");
92         Iterator JavaDoc nodes = graph.nodes();
93         while ( nodes.hasNext() ) {
94             Node n = (Node)nodes.next();
95             
96             if ( ns.getColumnCount() > 0 ) {
97                 xml.start(Tokens.NODE, Tokens.ID, String.valueOf(n.getRow()));
98                 for ( int i=0; i<ns.getColumnCount(); ++i ) {
99                     String JavaDoc field = ns.getColumnName(i);
100                     xml.contentTag(Tokens.DATA, Tokens.KEY, field,
101                                    n.getString(field));
102                 }
103                 xml.end();
104             } else {
105                 xml.tag(Tokens.NODE, Tokens.ID, String.valueOf(n.getRow()));
106             }
107         }
108         
109         // add a blank line
110
xml.println();
111         
112         // print the edges
113
String JavaDoc[] attr = new String JavaDoc[]{Tokens.ID, Tokens.SOURCE, Tokens.TARGET};
114         String JavaDoc[] vals = new String JavaDoc[3];
115         
116         xml.comment("edges");
117         Iterator JavaDoc edges = graph.edges();
118         while ( edges.hasNext() ) {
119             Edge e = (Edge)edges.next();
120             vals[0] = String.valueOf(e.getRow());
121             vals[1] = String.valueOf(e.getSourceNode().getRow());
122             vals[2] = String.valueOf(e.getTargetNode().getRow());
123             
124             if ( es.getColumnCount() > 2 ) {
125                 xml.start(Tokens.EDGE, attr, vals, 3);
126                 for ( int i=0; i<es.getColumnCount(); ++i ) {
127                     String JavaDoc field = es.getColumnName(i);
128                     if ( field.equals(graph.getEdgeSourceField()) ||
129                          field.equals(graph.getEdgeTargetField()) )
130                         continue;
131                     
132                     xml.contentTag(Tokens.DATA, Tokens.KEY, field,
133                                    e.getString(field));
134                 }
135                 xml.end();
136             } else {
137                 xml.tag(Tokens.EDGE, attr, vals, 3);
138             }
139         }
140         xml.end();
141         
142         // finish writing file
143
xml.finish("</"+Tokens.GRAPHML+">\n");
144     }
145     
146     /**
147      * Print a table schema to a GraphML file
148      * @param xml the XMLWriter to write to
149      * @param group the data group (node or edge) for the schema
150      * @param s the schema
151      */

152     private void printSchema(XMLWriter xml, String JavaDoc group, Schema s,
153                              String JavaDoc[] ignore)
154     {
155         String JavaDoc[] attr = new String JavaDoc[] {Tokens.ID, Tokens.FOR,
156                 Tokens.ATTRNAME, Tokens.ATTRTYPE };
157         String JavaDoc[] vals = new String JavaDoc[4];
158
159 OUTER:
160         for ( int i=0; i<s.getColumnCount(); ++i ) {
161             vals[0] = s.getColumnName(i);
162             
163             for ( int j=0; ignore!=null && j<ignore.length; ++j ) {
164                 if ( vals[0].equals(ignore[j]) )
165                     continue OUTER;
166             }
167             
168             vals[1] = group;
169             vals[2] = vals[0];
170             vals[3] = (String JavaDoc)TYPES.get(s.getColumnType(i));
171             Object JavaDoc dflt = s.getDefault(i);
172             
173             if ( dflt == null ) {
174                 xml.tag(Tokens.KEY, attr, vals, 4);
175             } else {
176                 xml.start(Tokens.KEY, attr, vals, 4);
177                 xml.contentTag(Tokens.DEFAULT, dflt.toString());
178                 xml.end();
179             }
180         }
181     }
182     
183     /**
184      * Checks if all Schema types are compatible with the GraphML specification.
185      * The GraphML spec only allows the types <code>int</code>,
186      * <code>long</code>, <code>float</code>, <code>double</code>,
187      * <code>boolean</code>, and <code>string</code>.
188      * @param s the Schema to check
189      */

190     private void checkGraphMLSchema(Schema s) throws DataIOException {
191         for ( int i=0; i<s.getColumnCount(); ++i ) {
192             Class JavaDoc type = s.getColumnType(i);
193             if ( TYPES.get(type) == null ) {
194                 throw new DataIOException("Data type unsupported by the "
195                     + "GraphML format: " + type.getName());
196             }
197         }
198     }
199     
200 } // end of class GraphMLWriter
Popular Tags