]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.graphviz/src/org/simantics/graphviz/drawable/GraphDrawable.java
Prevent some NPEs in Graphviz plugin
[simantics/platform.git] / bundles / org.simantics.graphviz / src / org / simantics / graphviz / drawable / GraphDrawable.java
1 /*******************************************************************************
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management
3  * in Industry THTH ry.
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * which accompanies this distribution, and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Contributors:
10  *     VTT Technical Research Centre of Finland - initial API and implementation
11  *******************************************************************************/
12 package org.simantics.graphviz.drawable;
13
14 import java.awt.Graphics2D;
15 import java.awt.geom.Rectangle2D;
16 import java.util.concurrent.Semaphore;
17 import java.util.concurrent.TimeUnit;
18
19 import org.simantics.graphviz.Graph;
20 import org.simantics.graphviz.Graphs;
21 import org.simantics.graphviz.continuation.Computation;
22 import org.simantics.graphviz.continuation.Continuation;
23 import org.simantics.graphviz.internal.xdot.DrawCommand;
24 import org.simantics.graphviz.internal.xdot.DrawCommandParser;
25 import org.slf4j.Logger;
26 import org.slf4j.LoggerFactory;
27
28 /**
29  * A drawable that draws a given graph.
30  * 
31  * @author Hannu Niemist�
32  */
33 public class GraphDrawable implements Drawable {
34     private static final Logger LOGGER = LoggerFactory.getLogger(GraphDrawable.class);
35     
36         private static String DEFAULT_ALGORITHM = "dot";
37         
38         DrawCommand[] commands;
39         Rectangle2D bounds;
40         
41         
42         private Graph graph;
43         private String algorithm;
44         
45         public GraphDrawable(Graph graph, String algorithm) {
46                 setGraph(graph, algorithm);
47         }
48         
49         public GraphDrawable(Graph graph) {
50                 setGraph(graph);
51         }
52         
53         public GraphDrawable() {
54                 commands = new DrawCommand[0];
55                 bounds = new Rectangle2D.Double(0, 0, 100, 100);
56         }
57         
58         
59         public Graph getGraph() {
60                 return graph;
61         }
62         
63         public String getAlgorithm() {
64                 return algorithm;
65         }
66         /**
67          * Sets a new graph to be drawn. This operation may take a while. It can
68          * be called from any thread.
69          * @param graph
70          */
71         public void setGraph(Graph graph) {
72                 setGraph(graph, DEFAULT_ALGORITHM);
73         }
74         
75         /**
76          * Sets a new graph to be drawn. This operation may take a while. It can
77          * be called from any thread.
78          * @param graph
79          */
80         public Computation<Graph> setGraph(Graph graph, String algorithm) {
81             this.graph = graph;
82         this.algorithm = algorithm;
83             Computation<Graph> computation = Graphs.createXDot(graph, algorithm);
84             final Semaphore semaphore = new Semaphore(0);
85             computation.addContinuation(new Continuation<Graph>() {
86             @Override
87             public void succeeded(Graph xgraph) {
88                 commands = DrawCommandParser.parse(xgraph);
89                 readBoundingBox(xgraph);
90                 semaphore.release();
91             }
92
93             @Override
94             public void failed(Exception exception) {
95                 exception.printStackTrace();
96                 semaphore.release();
97             }
98             });
99             try {
100                         semaphore.tryAcquire(5L, TimeUnit.SECONDS);
101                 } catch (InterruptedException e) {
102                         e.printStackTrace();
103                 }
104             return computation;
105         }
106         
107         private void readBoundingBox(Graph graph) {
108                 String[] parts = graph.get("bb").split(",");
109                 double minX = Double.parseDouble(parts[0]);
110                 double maxY = -Double.parseDouble(parts[1]);
111                 double maxX = Double.parseDouble(parts[2]);
112                 double minY = -Double.parseDouble(parts[3]);
113                 bounds = new Rectangle2D.Double(minX, minY, maxX-minX, maxY-minY);
114         }
115         
116         @Override
117         public synchronized Rectangle2D getBounds() {
118             if(bounds == null)
119                 LOGGER.warn("bounds == null");
120                 return bounds;
121         }
122         
123         @Override
124         public synchronized void draw(Graphics2D g, Rectangle2D area) {
125                 for(DrawCommand command : commands)
126                         command.draw(g);
127         }
128         
129 }