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

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.BufferedReader;
13 import java.io.BufferedWriter;
14 import java.io.FileReader;
15 import java.io.FileWriter;
16 import java.io.IOException;
17 import java.io.Reader;
18 import java.text.ParseException;
19 import java.util.HashSet;
20 import java.util.Iterator;
21 import java.util.Set;
22 import java.util.StringTokenizer;
23  
24 import edu.uci.ics.jung.exceptions.FatalException;
25 import edu.uci.ics.jung.graph.DirectedEdge;
26 import edu.uci.ics.jung.graph.Edge;
27 import edu.uci.ics.jung.graph.Graph;
28 import edu.uci.ics.jung.graph.UndirectedEdge;
29 import edu.uci.ics.jung.graph.Vertex;
30 import edu.uci.ics.jung.graph.decorators.Indexer;
31 import edu.uci.ics.jung.graph.decorators.StringLabeller;
32 import edu.uci.ics.jung.graph.impl.DirectedSparseGraph;
33 import edu.uci.ics.jung.graph.impl.UndirectedSparseGraph;
34 import edu.uci.ics.jung.utils.GraphUtils;
35 import edu.uci.ics.jung.utils.MutableDouble;
36 import edu.uci.ics.jung.utils.Pair;
37 import edu.uci.ics.jung.utils.PredicateUtils;
38 import edu.uci.ics.jung.utils.UserData;
39  
40 /**
41  * A file reader for Pajek .net files. At the moment, only supports the
42  * part of the specification that defines:
43  * <ul>
44  * <li> node ids (must be ordered from 1 to n)
45  * <li> node labels (must be in quotes)
46  * <li> directed edge connections (single or list)
47  * <li> undirected edge connections (single or list)
48  * <li> edge weights (1 or more can be specified; not compatible with
49  * edges specified in list form)
50  * </ul> <p>
51  *
52  * Here is an example format for a directed graph without edge weights
53  * and edges specified in list form: <br>
54  * <pre>
55  * *vertices <# of vertices>
56  * 1 "a"
57  * 2 "b"
58  * 3 "c"
59  * *arcslist
60  * 1 2 3
61  * 2 3
62  * </pre>
63  *
64  * Here is an example format for an undirected graph with edge weights
65  * and edges specified in non-list form: <br>
66  * <pre>
67  * *vertices <# of vertices>
68  * 1 "a"
69  * 2 "b"
70  * 3 "c"
71  * *edges
72  * 1 2 0.1
73  * 1 3 0.9
74  * 2 3 1.0
75  * </pre>
76  * @author Scott White, Joshua O'Madadhain
77  * @deprecated As of version 1.4, replaced by {@link PajekNetReader} and {@link PajekNetWriter}
78  * @see "'Pajek - Program for Large Network Analysis', Vladimir Batagelj and Andrej Mrvar, www.ucm.es/info/pecar/pajek.pdf"
79  */
80 public class PajekNetFile implements GraphFile {
81     public final static String EDGE_WEIGHT = "jung.io.PajekNetFile.EdgeWeight";
82     private String[] mEdgeKeys;
83     private boolean mCreateDirectedOnly;
84  
85     /**
86      * Default constructor for pajek graph reader
87      */
884    public PajekNetFile() {
894        mCreateDirectedOnly = false;
904    }
91  
92     /**
93      * Constructor which takes in the user datum keys for the edge weights
94      * @param edgeKeys the user datum keys the algorithm should use to store the edge weights (as MutableDoubles)
95      */
960    public PajekNetFile(String[] edgeKeys) {
970        mEdgeKeys = edgeKeys;
980        mCreateDirectedOnly = false;
990    }
100  
101     /**
102      * retrieves the set of edge keys the algorithm will use to store the edge weights
103      * @return the user datum keys the algorithm should is using to store the edge weights (as MutableDoubles)
104      */
105     public String[] getEdgeKeys() {
10630        return mEdgeKeys;
107     }
108  
109     /**
110      * set the edge the algorithm will use to store the edge weights
111      * @param edgeKeys the user datum keys the algorithm should use to store the edge weights (as MutableDoubles)
112      */
113     public void setEdgeKeys(String[] edgeKeys) {
1140        this.mEdgeKeys = edgeKeys;
1150    }
116  
117     /**
118      * Loads a graph from disk for the given .net file
119      * If the edges are directed then a directed graph will be created, otherwise an undirected graph will be created
120      * @param filename the fully specified file name of the pajek .net file
121      * @return the corresponding graph
122      */
123     public Graph load(String filename) {
124         try {
1256            Reader reader = new FileReader(filename);
1265            Graph graph = load(reader);
1275            reader.close();
1285            return graph;
1291        } catch (IOException ioe) {
1301            throw new FatalException("Error in loading file " + filename, ioe);
131         }
132     }
133  
134     /**
135      * Forces a graph that is normally undirected to be loaded in as its directed equivalent
136      * @param createDirectedOnly if true, force graph to be directed, false to not force this constraint
137      */
138     public void setCreateDirectedOnly(boolean createDirectedOnly) {
1390        mCreateDirectedOnly = createDirectedOnly;
1400    }
141  
142     /**
143      * Loads a graph for the given BufferedReader (where the data is assumed to be in Pajek NET format).
144      * If the edges are directed then a directed graph will be created, otherwise an undirected
145      * graph will be created.
146      * @param read the data stream that contains the graph data in .net format
147      * @return the corresponding graph
148      */
149     public Graph load(Reader read) {
150  
151         /*
152          * Current running buglist:
153          * * Crashes on *Network tag
154          * * unique label exception is possible
155          * * doesn't handle *PArtition, e.g.
156 // * * only one tag of "arc" or "edge"
157          */
1585        BufferedReader reader = new BufferedReader( read );
1595        int currentSourceId = -1;
1605        String currentLine = null;
161         try {
1625            StringTokenizer tokenizer = null;
1635            currentLine = reader.readLine();
1645            tokenizer = new StringTokenizer(currentLine);
1655            if (!tokenizer.nextToken().toLowerCase().startsWith("*vertices")) {
1660                throw new ParseException("Pajek file parse error: '*vertices' not first token", 0);
167             }
1685            int numVertices = Integer.parseInt(tokenizer.nextToken());
1695            Graph directedGraph = new DirectedSparseGraph();
1705            GraphUtils.addVertices( directedGraph, numVertices );
1715            Indexer directedGraphIndexer = Indexer.newIndexer( directedGraph , 1);
172  
1735            Graph undirectedGraph = null;
1745            Indexer undirectedGraphIndexer = null;
1755            StringLabeller undirectedLabeler = null;
176  
1775            if (!mCreateDirectedOnly) {
1785                undirectedGraph = new UndirectedSparseGraph();
1795                GraphUtils.addVertices(undirectedGraph,numVertices);
1805                undirectedGraphIndexer = Indexer.newIndexer( undirectedGraph , 1);
1815                undirectedLabeler = StringLabeller.getLabeller(undirectedGraph);
182             }
183  
1845            StringLabeller directedLabeler = StringLabeller.getLabeller(directedGraph);
185  
1865            String currentVertexLabel = null;
1875            Vertex currentVertex = null;
188  
189 // currentLine = reader.readLine().trim();
19030            while (!(currentLine = reader.readLine().trim()).startsWith("*")) {
19125                tokenizer = new StringTokenizer(currentLine);
19225                currentSourceId = Integer.parseInt(tokenizer.nextToken());
193  
19425                int openQuotePos = currentLine.indexOf("\"");
19525                int closeQuotePos = currentLine.lastIndexOf("\"");
196  
19725                if ((openQuotePos > 0) && (openQuotePos != closeQuotePos)) {
1980                    currentVertexLabel = currentLine.substring(openQuotePos+1,closeQuotePos);
1990                    currentVertex = (Vertex)directedGraphIndexer.getVertex(currentSourceId);
2000                    directedLabeler.setLabel(currentVertex,currentVertexLabel);
201  
2020                    if (!mCreateDirectedOnly) {
2030                        currentVertex = (Vertex)undirectedGraphIndexer.getVertex(currentSourceId);
2040                        undirectedLabeler.setLabel(currentVertex,currentVertexLabel);
205                     }
20625                    continue;
207                 }
208             }
209  
2105            int currentTargetId = -1;
2115            boolean directed = false;
2125            boolean isList = false;
2135            Graph graph = null;
2145            Indexer id = null;
2155            if (currentLine.toLowerCase().indexOf("list") >= 0) {
2160                isList = true;
217             }
2185            if (currentLine.toLowerCase().indexOf("arc") >= 0) {
2193                directed = true;
2203                graph = directedGraph;
2213                undirectedGraph = null;
2223                undirectedLabeler = null;
2233                id = directedGraphIndexer;
224             } else {
2252                if (mCreateDirectedOnly) {
2260                    graph = directedGraph;
2270                    undirectedGraph = null;
2280                    undirectedGraphIndexer = null;
2290                    directedLabeler = null;
2300                    id = directedGraphIndexer;
231                 } else {
2322                    graph = undirectedGraph;
2332                    directedGraph = null;
2342                    directedGraphIndexer = null;
2352                    id = undirectedGraphIndexer;
236                 }
237             }
238  
23936            while ((currentLine = reader.readLine()) != null)
240             {
24131                currentLine = currentLine.trim();
24231                if (currentLine.length() == 0) {
2430                    break;
244                 }
245                 // right now we only support strictly directed or strictly undirected graphs
246                 
24731                if (currentLine.startsWith("*" ))
2481                    continue;
249 // else if (currentLine.startsWith("*")) {
250 // throw new FatalException("*edge/arcs(list) can only appear once.");
251 // }
25230                tokenizer = new StringTokenizer(currentLine);
25330                currentSourceId = Integer.parseInt(tokenizer.nextToken());
25430                Edge currentEdge1 = null;
25530                Edge currentEdge2 = null;
256                 
25730                while (tokenizer.hasMoreTokens()) {
25830                    currentTargetId = Integer.parseInt(tokenizer.nextToken());
259                     
26030                    if (currentSourceId == currentTargetId) {
2610                        break;
262                     }
263                     
26430                    Vertex source = (Vertex)id.getVertex(currentSourceId);
26530                    Vertex target = (Vertex)id.getVertex(currentTargetId);
26630                    if(!source.isPredecessorOf(target)) {
26730                        currentEdge1 = GraphUtils.addEdge( graph, source,target);
268                     }
269                     
27030                    if (mCreateDirectedOnly && !directed) {
2710                        if(!target.isPredecessorOf(source)) {
2720                            currentEdge2 = GraphUtils.addEdge( graph, target,source);
273                         }
274                     }
275                     
27630                    String[] edgeKeys = getEdgeKeys();
27730                    if (!isList && edgeKeys != null) {
2780                        int numTokens = tokenizer.countTokens();
2790                        numTokens = Math.min(numTokens,edgeKeys.length);
2800                        for (int edgeDescIdx=0;edgeDescIdx<numTokens;edgeDescIdx++) {
2810                            double val = Double.parseDouble(tokenizer.nextToken());
2820                            currentEdge1.setUserDatum(edgeKeys[edgeDescIdx],new MutableDouble(val),UserData.SHARED);
2830                            if (currentEdge2 != null) {
2840                                currentEdge2.setUserDatum(edgeKeys[edgeDescIdx],new MutableDouble(val),UserData.SHARED);
285                             }
286                             
287                         }
28830                    } else if (isList) {
2890                        continue;
290                     }
291                     break;
292                 }
293             }
2945            return graph;
295         }
2960        catch (IOException ioe)
297         {
2980            throw new FatalException("I/O error in reading file: ", ioe);
299         }
3000        catch (ParseException pe)
301         {
3020            throw new FatalException("Parse exception in reading graph", pe);
303         }
3040        catch (StringLabeller.UniqueLabelException sle)
305         {
3060            throw new FatalException("Repeated vertex label in graph", sle);
307         }
308 // catch (Exception re) {
309 // throw new FatalException("Fatal exception calling PajekNetFile.load(...)", re);
310 // }
311     }
312  
313     /**
314      * Writes <code>graph</code> to the file specified by <code>filename</code>
315      * in the Pajek NET format.
316      * @param graph the graph to save
317      * @param filename the fully specified file name where the graph is to be saved to disk
318      */
319     public void save(Graph graph,String filename) {
320         
321         /*
322          * TODO: Changes we might want to make:
323          * - convert to writing out with a Writer, not a String filename spec
324          * - optionally writing out in list form
325          */
326         
327         try {
3285            BufferedWriter writer = new BufferedWriter( new FileWriter(filename));
3295            writer.write("*Vertices " + graph.getVertices().size() + "\n");
3305            Vertex currentVertex = null;
331  
3325            Indexer id = Indexer.newIndexer( graph ,1 ) ;
3335            StringLabeller labeller = StringLabeller.getLabeller(graph);
3345            for (Iterator i = graph.getVertices().iterator(); i.hasNext();) {
33525                currentVertex = (Vertex) i.next();
33625                if (labeller.getLabel(currentVertex) != null) {
3370                    writer.write(id.getIndex(currentVertex) + " \"" + labeller.getLabel(currentVertex) + "\"\n");
338                 } else {
33925                    writer.write(id.getIndex(currentVertex) + "\n");
340                 }
341             }
342  
3435            Set d_set = new HashSet();
3445            Set u_set = new HashSet();
345  
3465            boolean directed = PredicateUtils.enforcesDirected(graph);
3475            boolean undirected = PredicateUtils.enforcesUndirected(graph);
348             // if it's strictly one or the other, no need to create extra sets
3495            if (directed)
3502                d_set = graph.getEdges();
3515            if (undirected)
3522                u_set = graph.getEdges();
3535            if (!directed && !undirected) // mixed-mode graph
354             {
3551                d_set = PredicateUtils.getEdges(graph, Graph.DIRECTED_EDGE);
3561                u_set = PredicateUtils.getEdges(graph, Graph.UNDIRECTED_EDGE);
357             }
358             
359             // write out directed edges
3605            if (! d_set.isEmpty())
3613                writer.write("*Arcs\n");
3625            for (Iterator eIt = d_set.iterator(); eIt.hasNext();)
363             {
36415                DirectedEdge currentEdge = (DirectedEdge) eIt.next();
36515                Vertex source = currentEdge.getSource();
36615                Vertex target = currentEdge.getDest();
36715                writer.write(id.getIndex(source) + " " + id.getIndex(target) + "\n");
368             }
369  
370             // write out undirected edges
3715            if (! u_set.isEmpty())
3723                writer.write("*Edges\n");
3735            for (Iterator eIt = u_set.iterator(); eIt.hasNext();)
374             {
37515                UndirectedEdge e = (UndirectedEdge)eIt.next();
37615                Pair endpoints = e.getEndpoints();
37715                Vertex v1 = (Vertex)endpoints.getFirst();
37815                Vertex v2 = (Vertex)endpoints.getSecond();
37915                writer.write(id.getIndex(v1) + " " + id.getIndex(v2) + "\n");
380             }
381             
3825            writer.close();
383             
3840        } catch (Exception e) {
3850            throw new FatalException("Error saving file: " + filename,e);
3865        }
3875    }
388  
389 }

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.