1
2
3
4
5
6 package net.kwfgrid.gwui.graphview;
7
8 import net.kwfgrid.gworkflowdl.structure.*;
9 import net.kwfgrid.gwui.graphviz.*;
10 import net.kwfgrid.gwui.graphview.*;
11 import net.kwfgrid.gwui.GWUI;
12
13 import de.fzi.wim.guibase.graphview.layout.*;
14 import de.fzi.wim.guibase.graphview.graph.Node;
15 import de.fzi.wim.guibase.graphview.graph.Graph;
16 import de.fzi.wim.guibase.graphview.view.JGraphPane;
17
18 import java.util.*;
19
20 import org.apache.log4j.Logger;
21
22 /***
23 A layout strategy which uses a remote graphviz instance to layout the graph.
24 */
25 public class DOTLayoutStrategy implements LayoutStrategy {
26 private static final Logger logger = Logger.getLogger(DOTLayoutStrategy.class);
27
28 private static final int MAX_TIMER = 16;
29
30 private WorkflowGraph _graph;
31 private boolean _valid;
32 private JGraphPane _view;
33 private HashMap _knownelements;
34 private String _knownworkflowid;
35 private int _timer;
36
37 public DOTLayoutStrategy(JGraphPane view, WorkflowGraph graph) {
38 logger.debug("Constructed new DOTLayoutStrategy for graph "+graph);
39
40 _timer = MAX_TIMER;
41 _graph = graph;
42 _view = view;
43 _valid = false;
44 _knownelements = new HashMap();
45 _knownworkflowid = null;
46 }
47
48 public boolean shouldExecuteStep() {
49 return !_valid;
50 }
51
52 public void executeGraphLayoutStep() {
53 if (_timer == MAX_TIMER) {
54 Iterator nodes = _graph.getNodes().iterator(); while (nodes.hasNext()) {
55 Node n = (Node)nodes.next();
56 n.setLocation(-20000, -20000);
57 }
58 Iterator edges = _graph.getEdges().iterator(); while (edges.hasNext()) {
59 ArcEdge e = (ArcEdge)edges.next();
60 e.setControlPoints(null);
61 e.setLabelPosition(null);
62 e.setPointOfArrowAtStart(null);
63 e.setPointOfArrowAtEnd(null);
64 }
65 _timer--;
66 } else if (_timer == 0) {
67 if (_graph.getEdges().size() > 0 && _graph.getNodes().size() > 0) {
68 logger.debug("Executing graphviz layouter.");
69
70 _knownworkflowid = new String(_graph.getWorkflow().getID());
71
72 try {
73 GraphViz gviz = GWUI.getInstance().getGraphVizWS(_graph.getWorkflow().getID());
74
75
76 WorkflowGraph2DOTConverter builder = new WorkflowGraph2DOTConverter(_view);
77 ConversionDirector director = new ConversionDirector(_graph, builder, new ElementIterator(_graph));
78 director.build();
79 String dot = builder.getDOT();
80
81 logger.debug("Input dot=\n"+dot);
82
83
84 String annotateddot = new String(gviz.dot("-Tdot", dot));
85
86 logger.debug("Output dot=\n"+annotateddot);
87
88
89 (new DOTLayout2WorkflowGraph(annotateddot, _graph)).run();
90
91
92 _knownelements.clear();
93 Iterator i = _graph.getNodes().iterator(); while (i.hasNext()) {
94 Node node = (Node)i.next();
95 if (node instanceof PlaceNode) {
96 _knownelements.put(((PlaceNode)node).getPlace().getID(), node);
97 } else if (node instanceof TransitionNode) {
98 _knownelements.put(((TransitionNode)node).getTransition().getID(), node);
99 }
100 }
101 i = _graph.getEdges().iterator(); while (i.hasNext()) {
102 ArcEdge edge = (ArcEdge)i.next();
103 _knownelements.put(edgeID(edge), edge);
104 }
105 _valid = true;
106 } catch (GraphVizException x) {
107 logger.error("Could not apply graphviz layout.", x);
108 _timer = MAX_TIMER;
109 }
110 }
111 } else {
112 _timer--;
113 }
114 }
115
116 private String edgeID(ArcEdge edge) {
117 if (edge instanceof ReadEdge) {
118 return edgeID(edge.getPlace(), edge.getTransition());
119 } else if (edge instanceof InEdge) {
120 return edgeID(edge.getPlace(), edge.getTransition());
121 } else {
122 return edgeID(edge.getTransition(), edge.getPlace());
123 }
124 }
125
126 private String edgeID(PlaceNode from, TransitionNode to) {
127 return from.getPlace().getID()+"->"+to.getTransition().getID();
128 }
129
130 private String edgeID(TransitionNode from, PlaceNode to) {
131 return from.getTransition().getID()+"->"+to.getPlace().getID();
132 }
133
134 public Graph getGraph() {
135 return _graph;
136 }
137
138 public void elementsAdded(Collection nodes, Collection edges) {
139 logger.debug("Elements added: "+(nodes!=null?nodes.size():0)+" Nodes and "+(edges!=null?edges.size():0)+" Edges.");
140
141 if (_valid) {
142 Workflow wf = _graph.getWorkflow();
143
144 logger.debug("Workflow is "+wf);
145
146 String ID = wf.getID();
147
148 logger.debug("ID is "+ID+", known ID is "+_knownworkflowid+".");
149
150 _valid = ID.equals(_knownworkflowid);
151
152 logger.debug("After ID check layout is valid? "+_valid);
153
154 if (nodes != null) {
155 Iterator i = nodes.iterator(); while (i.hasNext()) {
156 Node node = (Node)i.next();
157 Node knownnode = null;
158 if (node instanceof PlaceNode) {
159 knownnode = (Node)_knownelements.get(((PlaceNode)node).getPlace().getID());
160 } else if (node instanceof TransitionNode) {
161 knownnode = (Node)_knownelements.get(((TransitionNode)node).getTransition().getID());
162 }
163 if (knownnode!=null) {
164 node.setLocation(knownnode.getX(), knownnode.getY());
165 } else {
166 _valid = false;
167 node.setLocation(-20000, -20000);
168 }
169 }
170 }
171
172 logger.debug("After node check layout is valid? "+_valid);
173
174 if (edges != null) {
175 Iterator i = edges.iterator(); while (i.hasNext() && _valid) {
176 ArcEdge edge = (ArcEdge)i.next();
177 ArcEdge knownedge = (ArcEdge)_knownelements.get(edgeID(edge));
178 if (knownedge!=null) {
179 edge.setControlPoints(knownedge.getControlPoints());
180 edge.setLabelPosition(knownedge.getLabelPosition());
181 edge.setPointOfArrowAtStart(knownedge.getPointOfArrowAtStart());
182 edge.setPointOfArrowAtEnd(knownedge.getPointOfArrowAtEnd());
183 } else {
184 _valid = false;
185 }
186 }
187 }
188
189 logger.debug("After edge check layout is valid? "+_valid);
190 }
191
192 if (!_valid) _timer = MAX_TIMER;
193 }
194
195 public void elementsRemoved(Collection nodes, Collection edges) {
196
197 }
198
199 public void graphContentsChanged() {
200
201 }
202
203 public void notifyGraphLayoutUpdated() {
204
205 }
206 }