KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > soot > util > dot > DotGraph


1 /* Soot - a J*va Optimization Framework
2  * Copyright (C) 2002 Sable Research Group
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */

19
20 /*
21  * Modified by the Sable Research Group and others 1997-1999.
22  * See the 'credits' file distributed with Soot for the complete list of
23  * contributors. (Soot is distributed at http://www.sable.mcgill.ca/soot)
24  */

25
26
27 /**
28  * DotGraph provides an interface to SOOT for generating DOT language
29  * for graphviz from ATT research lab.
30  *
31  * Intended usage: virtualize CFG, graphes, etc...
32  *
33  * @author Feng Qian
34  */

35
36 package soot.util.dot;
37 import soot.*;
38
39 import java.io.*;
40 import java.util.*;
41
42 public class DotGraph implements Renderable{
43   
44   /* allow a serialized drawing, following steps:
45    * 1. new DotGraph
46    * 2. draw(Directed)Edge / drawUndirectedEdge
47    * attachAttributes, addNode
48    * 3. plot
49    */

50   private String JavaDoc graphname;
51   private boolean isSubGraph;
52
53   private HashMap nodes;
54   /* draw elements are sub graphs, edges, commands */
55   private List drawElements;
56  
57   private List attributes;
58
59   /**
60    * The extension added to output files, exported so that
61    * clients can search for the filenames.
62    */

63   public final static String JavaDoc DOT_EXTENSION = ".dot";
64
65   /**
66    * Creates a new graph for drawing.
67    * @param graphname, the name used to identify the graph in the dot source.
68    */

69   public DotGraph(String JavaDoc graphname) {
70     this.graphname = graphname;
71     this.isSubGraph = false;
72     this.nodes = new HashMap(100);
73     this.drawElements = new LinkedList();
74     this.attributes = new LinkedList();
75   }
76   
77   /**
78    * Generates the drawing on canvas to the dot file.
79    * @param filename the name for the output file. By convention, it should
80    * end with DOT_EXTENSION, but this is not enforced.
81    */

82   public void plot(String JavaDoc filename) {
83     try {
84       BufferedOutputStream out =
85     new BufferedOutputStream(new FileOutputStream(filename));
86                               
87       render(out, 0);
88       out.close();
89     } catch (IOException ioe) {
90     }
91   }
92
93   /**
94    * Draws a directed edge (including the source and end nodes,
95    * if they have not already been drawn).
96    * @param from, the source node
97    * @param to, the end node
98    * @return a graph edge
99    */

100   public DotGraphEdge drawEdge(String JavaDoc from, String JavaDoc to) {
101
102     DotGraphNode src = drawNode(from);
103     DotGraphNode dst = drawNode(to);
104     DotGraphEdge edge = new DotGraphEdge(src, dst);
105     
106     this.drawElements.add(edge);
107     
108     return edge;
109   }
110
111   /**
112    * Draws a node.
113    * @param name, the node to draw.
114    * @return the {@link DotGraphNode} corresponding to the
115    * specified name.
116    */

117   public DotGraphNode drawNode(String JavaDoc name){
118       DotGraphNode node = getNode(name);
119
120       if(node == null)
121           throw new RuntimeException JavaDoc("Assertion failed.");
122
123       if(!this.drawElements.contains(node))
124           this.drawElements.add(node);
125
126       return node;
127   }
128
129   /**
130    * Gets the graph node by name.
131    * @param name, unique name of the node.
132    * @return the node with the specified name, or <code>null</code>
133    * if there is no such node.
134    */

135   public DotGraphNode getNode(String JavaDoc name){
136       DotGraphNode node = (DotGraphNode)nodes.get(name);
137       if (node == null) {
138           node = new DotGraphNode(name);
139           nodes.put(name, node);
140       }
141       return node;
142   }
143
144   /**
145    * Sets all node shapes, see the list of node shapes in DotGraphConstants.
146    * @param shape, the node shape
147    */

148   public void setNodeShape(String JavaDoc shape){
149     StringBuffer JavaDoc command = new StringBuffer JavaDoc("node [shape=");
150     command.append(shape);
151     command.append("];");
152     this.drawElements.add(new DotGraphCommand(new String JavaDoc(command)));
153   }
154
155   /**
156    * Sets all node styles
157    * @param style, the node style
158    */

159   public void setNodeStyle(String JavaDoc style){
160     StringBuffer JavaDoc command = new StringBuffer JavaDoc("node [style=");
161     command.append(style);
162     command.append("];");
163     this.drawElements.add(new DotGraphCommand(new String JavaDoc(command)));
164   }
165
166   /**
167    * sets the size of drawing area, in inches
168    */

169   public void setGraphSize(double width, double height){
170     String JavaDoc size = "\""+width+","+height+"\"";
171     this.setGraphAttribute("size", size);
172   }
173
174   /**
175    * sets the pages size, once this is set, the generated graph
176    * will be broken into several pages.
177    */

178   public void setPageSize(double width, double height){
179     String JavaDoc size = "\""+width+", "+height+"\"";
180     this.setGraphAttribute("page", size);
181   }
182
183   /**
184    * sets the graph rotation angles
185    */

186   public void setOrientation(String JavaDoc orientation){
187     this.setGraphAttribute("orientation", orientation);
188   }
189
190   /**
191    * sets the graph label
192    */

193   public void setGraphLabel(String JavaDoc label){
194     label = DotGraphUtility.replaceQuotes(label);
195     label = DotGraphUtility.replaceReturns(label);
196     this.setGraphAttribute("label", "\""+label+"\"");
197   }
198
199   /**
200    * sets any general attributes
201    * @param id is the attribute name.
202    * @param value is the attribute value.
203    */

204   public void setGraphAttribute(String JavaDoc id, String JavaDoc value){
205     this.setGraphAttribute(new DotGraphAttribute(id, value));
206   }
207
208   /**
209    * sets any general attributes
210    * @param attr a {@link DotGraphAttribute} specifying the
211    * attribute name and value.
212    */

213   public void setGraphAttribute(DotGraphAttribute attr){
214     this.attributes.add(attr);
215   }
216
217   /**
218    * draws an undirected edge
219    * @param label1, label2
220    */

221   public void drawUndirectedEdge(String JavaDoc label1, String JavaDoc label2) {
222   }
223
224   /**
225    * creates a sub graph.
226    * @return the newly created sub graph.
227    */

228   public DotGraph createSubGraph(String JavaDoc label){
229     // file name is used as label of sub graph.
230
DotGraph subgraph = new DotGraph(label);
231     subgraph.isSubGraph = true;
232
233     this.drawElements.add(subgraph);
234
235     return subgraph;
236   }
237
238   /* implements renderable interface. */
239   public void render(OutputStream out, int indent) throws IOException{
240     // header
241
String JavaDoc graphname = this.graphname;
242
243     if (!isSubGraph) {
244       DotGraphUtility.renderLine(out, "digraph \""+graphname+"\" {", indent);
245     } else {
246       DotGraphUtility.renderLine(out, "subgraph \""+graphname+"\" {", indent);
247     }
248
249     /* render graph attributes */
250     Iterator attrIt = this.attributes.iterator();
251     while (attrIt.hasNext()) {
252       DotGraphAttribute attr = (DotGraphAttribute)attrIt.next();
253       DotGraphUtility.renderLine(out, attr.toString()+";", indent+4);
254     }
255
256     /* render elements */
257     Iterator elmntsIt = this.drawElements.iterator();
258     while (elmntsIt.hasNext()) {
259       Renderable element = (Renderable)elmntsIt.next();
260       element.render(out, indent+4);
261     }
262
263     // close the description
264
DotGraphUtility.renderLine(out, "}", indent);
265   }
266 }
267
Popular Tags