View Javadoc

1   /*
2    * Copyright (c) 2005, The K-Wf Grid Consortium
3    * Fraunhofer Institute for Computer Architecture and Software Technology
4    * See http://www.kwfgrid.eu and http://www.first.fraunhofer.de for more details.
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  import net.kwfgrid.gwui.LensManager;
13  import net.kwfgrid.gwui.SwingFactory2;
14  
15  import de.fzi.wim.guibase.graphview.layout.*;
16  import de.fzi.wim.guibase.graphview.graph.Node;
17  import de.fzi.wim.guibase.graphview.graph.Graph;
18  import de.fzi.wim.guibase.graphview.view.JGraphPane;
19  
20  import org.glassbox.Theme;
21  import org.glassbox.SwingFactory;
22  import org.glassbox.widgets.VisibleExecutor;
23  import org.glassbox.widgets.StatusBarExecutor;
24  import org.glassbox.executor.Executor;
25  
26  import java.awt.Dimension;
27  import java.util.*;
28  import javax.swing.*;
29  
30  import org.apache.log4j.Logger;
31  
32  /***
33     A layout strategy which uses a remote graphviz instance to layout the graph.
34   */
35  public class DOTLayoutStrategy2 implements LayoutStrategy {
36      protected static final String TASK_THEME_PREFIX = "kwfgrid.WorkflowLoader.task";
37      protected static final String T_SIZE_KEY = "kwfgrid.TransitionNodePainter.size";
38      protected static final Dimension T_SIZE = Theme.getSize(T_SIZE_KEY);
39      protected static final String P_SIZE_KEY = "kwfgrid.PlaceNodePainter.size";
40      protected static final Dimension P_SIZE = Theme.getSize(P_SIZE_KEY);
41  
42      private static final Logger logger = Logger.getLogger(DOTLayoutStrategy2.class);
43  
44      private static class LayoutTask implements VisibleExecutor.VisibleTask, StatusBarExecutor.Task {
45  	private DOTLayoutStrategy2 _strategy;
46  	private WorkflowGraph _graph;
47  	private LensManager _lensmanager;
48  	private JComponent _view;
49  	private String _message;
50  
51  	public LayoutTask(DOTLayoutStrategy2 strategy, WorkflowGraph graph, LensManager lensmanager) {
52  	    _strategy = strategy;
53  	    _graph = graph;
54  	    _lensmanager = lensmanager;
55  	    _message = "Layouting workflow ...";
56  	    _view = null;
57  	}
58  
59  	public void run() {
60  	    try {
61  		_strategy.layout();
62  		_lensmanager.focusWholeGraph();
63  	    } catch (GraphVizException x) {
64  		logger.error("Could not layout workflow.", x);
65  		JDialog e = SwingFactory2.createErrorDialog("Error", "Could layout workflow.", x);
66  		e.show();		
67  		_strategy.setValid(true); // FIXME... could retry
68  	    }
69  	    _strategy.setLayouting(false);    
70  	}
71  
72  	public String getMessage() {
73  	    return _message;
74  	}
75  
76  	public JComponent getView() {
77  	    if (_view == null) {
78  		_view = SwingFactory.createLabel(_message, TASK_THEME_PREFIX);
79  	    }
80  	    return _view;
81  	}
82      }
83  
84      private WorkflowGraph _graph;
85      private boolean _valid;
86      private HashMap _knownelements;
87      private String _knownworkflowid;
88      private Executor _executor;
89      private LensManager _lensmanager;
90      private boolean _layouting;
91      
92      public DOTLayoutStrategy2(WorkflowGraph graph, Executor executor, LensManager lensmanager) {
93  	logger.debug("Constructed new DOTLayoutStrategy2 for graph "+graph);
94  
95  	_lensmanager = lensmanager;
96  	_executor = _executor;
97  	_graph = graph;
98  	_valid = false;
99  	_layouting = false;
100 	_knownelements = new HashMap();
101 	_knownworkflowid = null;
102 	_executor = executor;
103     }
104     
105     private void layout() throws GraphVizException {
106 	if (_graph.getEdges().size() > 0 && _graph.getNodes().size() > 0) {
107 	    logger.debug("Executing graphviz layouter.");
108 	    
109 	    GraphViz gviz = GWUI.getInstance().getGraphVizWS(_graph.getWorkflow().getID());
110 	    
111 	    // construct converter for gworkflowdl and create input dot
112 	    WorkflowGraph2DOTConverter builder = new WorkflowGraph2DOTConverter2(T_SIZE, P_SIZE);
113 	    ConversionDirector director = new ConversionDirector(_graph, builder, new ElementIterator(_graph));
114 	    director.build();
115 	    String dot = builder.getDOT();
116 	    
117 	    logger.debug("Input dot=\n"+dot);
118 	    
119 	    // run graphviz
120 	    String annotateddot = new String(gviz.dot("-Tdot", dot));
121 	    
122 	    logger.debug("Output dot=\n"+annotateddot);
123 	    
124 	    // apply layout to graph
125 	    (new DOTLayout2WorkflowGraph(annotateddot, _graph)).run();
126 	    
127 	    _valid = true;				    
128 	} else {
129 	    _valid = true;		
130 	}
131     }
132 
133     protected void setLayouting(boolean layouting) {
134 	_layouting = layouting;
135     }
136     
137     protected void setValid(boolean valid) {
138 	_valid = valid;
139     }
140 
141     public boolean shouldExecuteStep() {
142 	return !_valid;
143     }
144 
145     public void executeGraphLayoutStep() {
146 	if (!_layouting) {
147 	    setLayouting(true);
148 	    _executor.execute(new LayoutTask(this, _graph, _lensmanager));
149 	}
150     }
151 
152     public Graph getGraph() {
153 	return _graph;
154     }
155 
156     public void elementsAdded(Collection nodes, Collection edges) {
157 	logger.debug("Elements added: "+(nodes!=null?nodes.size():0)+" Nodes and "+(edges!=null?edges.size():0)+" Edges.");
158 
159 	if ((nodes != null && nodes.size() > 0) ||
160 	    (edges != null && edges.size() > 0)) {
161 	    _valid = false;
162 	}
163     }
164 
165     public void elementsRemoved(Collection nodes, Collection edges) {
166 	// _valid = false;
167     }
168 
169     public void graphContentsChanged() {
170 	// _valid = false;
171     }
172 
173     public void notifyGraphLayoutUpdated() {
174 	// _valid = false;
175     }
176 }