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

LineHitsSource
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      */
8518    public GraphMLFile() {
8618        mFileHandler = new GraphMLFileHandler();
8718    }
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      */
930    public GraphMLFile(GraphMLFileHandler handler) {
940        mFileHandler = handler;
950    }
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
1053        SAXParserFactory factory = SAXParserFactory.newInstance();
106         try {
107             // Parse the input
1083            SAXParser saxParser = factory.newSAXParser();
1093            saxParser.parse(new File(filename), mFileHandler);
110  
1110        } catch (Exception e) {
1120            throw new FatalException("Error loading graphml file: " + filename, e);
1133        }
114  
1153        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
1270        SAXParserFactory factory = SAXParserFactory.newInstance();
128         try {
129             // Parse the input
1300            SAXParser saxParser = factory.newSAXParser();
1310            saxParser.parse(stream, mFileHandler);
132  
1330        } catch (Exception e) {
1340            throw new FatalException("Error loading graphml file", e);
1350        }
136  
1370        return mFileHandler.getGraph();
138     }
139     
140     public Graph load( Reader reader ) {
141  
142         // Use the default (non-validating) parser
14315        SAXParserFactory factory = SAXParserFactory.newInstance();
144         try {
145             // Parse the input
14615            SAXParser saxParser = factory.newSAXParser();
14715            InputSource is = new InputSource( reader );
14815            saxParser.parse(is, mFileHandler);
149  
1500        } catch (Exception e) {
1510            throw new FatalException("Error loading graphml file", e);
15215        }
153  
15415        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) {
1660        File dir = new File(dirName);
1670        if (!dir.isDirectory()) {
1680            throw new FatalException("Parameter dirName must be a directory");
169         }
170  
1710        String[] files = dir.list(filter);
172  
1730        List graphCollection = new ArrayList();
1740        for (int i = 0; i < files.length; i++) {
1750            String currentFile = dirName + File.separatorChar + files[i];
1760            GraphMLFile graphmlFile = new GraphMLFile(mFileHandler);
1770            Graph graph = graphmlFile.load(currentFile);
178             //System.out.println("Graph loaded with " + graph.numVertices() + " nodes and " + graph.numEdges() + " edges.");
1790            graphCollection.add(graph);
180         }
181  
1820        return graphCollection;
183     }
184  
185     public void save(Graph g, String filename) {
186         PrintStream out;
187         try {
1881            out = new PrintStream(new FileOutputStream(filename, false));
1890        } catch (Exception e) {
1900            throw new FatalException("Could not open file \"" + filename + "\" for writing. " + e);
1911        }
1921        save(g, out);
1931        out.close();
1941    }
195     
196  
197  
198     public void save(Graph g, PrintStream out) {
1991        out.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
2001        out.println("<graphml xmlns=\"http://graphml.graphdrawing.org/xmlns/graphml\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ");
2011        out.println("xsi:schemaLocation=\"http://graphml.graphdrawing.org/xmlns/graphml\">");
2021        out.print("<graph edgedefault=\"");
2031        boolean directed = PredicateUtils.enforcesEdgeConstraint(g, Graph.DIRECTED_EDGE);
2041        boolean undirected = PredicateUtils.enforcesEdgeConstraint(g, Graph.UNDIRECTED_EDGE);
2051        if (directed)
2060            out.print("directed\" ");
2071        else if (undirected)
2080            out.print("undirected\" ");
209         else // default for mixed graphs
210         {
2111            directed = true;
2121            out.print("directed\" ");
213         }
214 // throw new IllegalArgumentException("Mixed (directed/undirected) " +
215 // "graphs not currently supported");
216  
2171        saveUserData(g, out);
2181        out.println(" >");
2191        saveVerticesSection(out, g);
2201        saveEdgesSection(out, g);
2211        out.println("</graph>");
2221        out.println("</graphml>");
223  
2241    }
225  
226     private void saveVerticesSection(PrintStream out, Graph g) {
2271        int numVertices = g.getVertices().size();
2281        Indexer id = Indexer.getIndexer(g);
2294        for (int i = 0; i < numVertices; i++) {
2303            Vertex v = (Vertex) id.getVertex(i);
2313            int vId = i+1;
2323            out.print("<node id=\"" + vId + "\" ");
233  
2343            saveUserData(v, out);
2353            out.println("/>");
236         }
2371    }
238  
239     private void saveEdgesSection(PrintStream out, Graph g) {
2401        Indexer id = Indexer.getIndexer(g);
2411        for (Iterator edgeIterator = g.getEdges().iterator(); edgeIterator.hasNext();) {
2423            Edge e = (Edge) edgeIterator.next();
2433            Pair p = e.getEndpoints();
2443            Vertex src = (Vertex) p.getFirst();
2453            Vertex dest = (Vertex) p.getSecond();
2463            int srcId = id.getIndex(src)+1;
2473            out.print("<edge source=\"" + srcId + "\" ");
2483            int destId = id.getIndex(dest)+1;
2493            out.print("target=\"" + destId + "\" ");
250  
251             // tag the edges that don't match the default
2523            if (directed)
253             {
2540                if (e instanceof UndirectedEdge)
2550                    out.print("directed=\"false\" ");
256             }
257             else // undirected
2583                if (e instanceof DirectedEdge)
2593                    out.print("directed=\"true\" ");
260             
2613            saveUserData(e, out);
2623            out.println("/>");
263         }
2641    }
265  
266     private void saveUserData(UserDataContainer udc, PrintStream out) {
2677        Iterator udki = udc.getUserDatumKeyIterator();
26811        while (udki.hasNext()) {
2694            Object key_obj = udki.next();
2704            if (udc.getUserDatumCopyAction(key_obj) == UserData.REMOVE)
2711                continue;
2723            String key = key_obj.toString();
2733            if (invalidXMLData(key)) continue;
2743            Object o = udc.getUserDatum(key);
2753            if (o == null)
2760                continue;
2773            String datum = o.toString();
2783            if (invalidXMLData(datum)) continue;
2793            out.print(key + "=\"" + datum + "\" ");
280         }
2817    }
282     
283     private boolean invalidXMLData(String str) {
2846        if (str.indexOf("&") >= 0) return true;
2856        if (str.indexOf("<") >= 0) return true;
2866        if (str.indexOf(">") >= 0) return true;
2876        if (str.indexOf("\'") >= 0) return true;
2886        if (str.indexOf("\"") >= 0) return true;
2896        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) {
2970        mFileHandler = fileHandler;
2980    }
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.