]> git.argeo.org Git - gpl/argeo-slc.git/blob - eclipse/plugins/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/editors/ProcessBuilderPage.java
6a217808924c2969c3ebc11bd34a9e399eb0d080
[gpl/argeo-slc.git] / eclipse / plugins / org.argeo.slc.client.ui / src / main / java / org / argeo / slc / client / ui / editors / ProcessBuilderPage.java
1 package org.argeo.slc.client.ui.editors;
2
3 import java.util.ArrayList;
4 import java.util.Iterator;
5 import java.util.List;
6
7 import javax.jcr.Node;
8 import javax.jcr.NodeIterator;
9 import javax.jcr.Property;
10 import javax.jcr.RepositoryException;
11 import javax.jcr.nodetype.NodeType;
12 import javax.jcr.observation.Event;
13 import javax.jcr.observation.EventIterator;
14 import javax.jcr.observation.EventListener;
15 import javax.jcr.observation.ObservationManager;
16
17 import org.argeo.ArgeoException;
18 import org.argeo.jcr.JcrUtils;
19 import org.argeo.slc.SlcException;
20 import org.argeo.slc.client.ui.SlcImages;
21 import org.argeo.slc.execution.ExecutionProcess;
22 import org.argeo.slc.jcr.SlcJcrUtils;
23 import org.argeo.slc.jcr.SlcNames;
24 import org.argeo.slc.jcr.SlcTypes;
25 import org.argeo.slc.process.RealizedFlow;
26 import org.eclipse.jface.viewers.ColumnLabelProvider;
27 import org.eclipse.jface.viewers.ISelectionChangedListener;
28 import org.eclipse.jface.viewers.IStructuredSelection;
29 import org.eclipse.jface.viewers.ITreeContentProvider;
30 import org.eclipse.jface.viewers.SelectionChangedEvent;
31 import org.eclipse.jface.viewers.StructuredSelection;
32 import org.eclipse.jface.viewers.TreeViewer;
33 import org.eclipse.jface.viewers.Viewer;
34 import org.eclipse.jface.viewers.ViewerDropAdapter;
35 import org.eclipse.swt.SWT;
36 import org.eclipse.swt.custom.SashForm;
37 import org.eclipse.swt.dnd.DND;
38 import org.eclipse.swt.dnd.TextTransfer;
39 import org.eclipse.swt.dnd.Transfer;
40 import org.eclipse.swt.dnd.TransferData;
41 import org.eclipse.swt.events.SelectionEvent;
42 import org.eclipse.swt.events.SelectionListener;
43 import org.eclipse.swt.graphics.Image;
44 import org.eclipse.swt.layout.FillLayout;
45 import org.eclipse.swt.layout.GridData;
46 import org.eclipse.swt.layout.GridLayout;
47 import org.eclipse.swt.layout.RowLayout;
48 import org.eclipse.swt.widgets.Button;
49 import org.eclipse.swt.widgets.Composite;
50 import org.eclipse.swt.widgets.Label;
51 import org.eclipse.ui.PlatformUI;
52 import org.eclipse.ui.forms.AbstractFormPart;
53 import org.eclipse.ui.forms.IManagedForm;
54 import org.eclipse.ui.forms.editor.FormPage;
55 import org.eclipse.ui.forms.widgets.FormToolkit;
56 import org.eclipse.ui.forms.widgets.ScrolledForm;
57
58 public class ProcessBuilderPage extends FormPage implements SlcNames, SlcTypes {
59 public final static String ID = "processBuilderPage";
60 //private final static Log log = LogFactory.getLog(ProcessBuilderPage.class);
61
62 private Node processNode;
63
64 private TreeViewer flowsViewer;
65 private Label status;
66
67 private AbstractFormPart formPart;
68 private StatusObserver statusObserver;
69
70 public ProcessBuilderPage(ProcessEditor editor, Node processNode) {
71 super(editor, ID, "Definition");
72 this.processNode = processNode;
73
74 }
75
76 @Override
77 protected void createFormContent(IManagedForm mf) {
78 try {
79 ScrolledForm form = mf.getForm();
80 form.setText("Process " + processNode.getName());
81 GridLayout mainLayout = new GridLayout(1, true);
82 form.getBody().setLayout(mainLayout);
83
84 createControls(form.getBody());
85 createBuilder(form.getBody());
86
87 // form
88 formPart = new AbstractFormPart() {
89
90 };
91 getManagedForm().addPart(formPart);
92 if (getProcessStatus().equals(ExecutionProcess.UNINITIALIZED))
93 formPart.markDirty();
94
95 // observation
96 statusObserver = new StatusObserver();
97 ObservationManager observationManager = processNode.getSession()
98 .getWorkspace().getObservationManager();
99 observationManager.addEventListener(statusObserver,
100 Event.PROPERTY_CHANGED, processNode.getPath(), true, null,
101 null, false);
102
103 } catch (RepositoryException e) {
104 throw new ArgeoException("Cannot create form content", e);
105 }
106 }
107
108 protected void createControls(Composite parent) {
109 FormToolkit tk = getManagedForm().getToolkit();
110
111 Composite controls = tk.createComposite(parent);
112 controls.setLayout(new RowLayout());
113 controls.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
114
115 Button run = tk.createButton(controls, null, SWT.PUSH);
116 run.setToolTipText("Run");
117 run.setImage(SlcImages.LAUNCH);
118 run.addSelectionListener(new SelectionListener() {
119 public void widgetSelected(SelectionEvent e) {
120 ((ProcessEditor) getEditor()).process();
121 }
122
123 public void widgetDefaultSelected(SelectionEvent e) {
124 widgetSelected(e);
125 }
126 });
127
128 Button remove = tk.createButton(controls, null, SWT.PUSH);
129 remove.setImage(SlcImages.REMOVE_ONE);
130 remove.setToolTipText("Remove selected flows");
131 remove.addSelectionListener(new SelectionListener() {
132 public void widgetSelected(SelectionEvent e) {
133 removeSelectedFlows();
134 }
135
136 public void widgetDefaultSelected(SelectionEvent e) {
137 widgetSelected(e);
138 }
139 });
140
141 Button clear = tk.createButton(controls, null, SWT.PUSH);
142 clear.setImage(SlcImages.REMOVE_ALL);
143 clear.setToolTipText("Clear all flows");
144 clear.addSelectionListener(new SelectionListener() {
145 public void widgetSelected(SelectionEvent e) {
146 removeAllFlows();
147 }
148
149 public void widgetDefaultSelected(SelectionEvent e) {
150 widgetSelected(e);
151 }
152 });
153
154 status = tk.createLabel(controls, getProcessStatus());
155 }
156
157 protected String getProcessStatus() {
158 try {
159 return processNode.getProperty(SLC_STATUS).getString();
160 } catch (RepositoryException e) {
161 throw new SlcException("Cannot retrieve status for " + processNode,
162 e);
163 }
164 }
165
166 protected void createBuilder(Composite parent) {
167 FormToolkit tk = getManagedForm().getToolkit();
168 SashForm sashForm = new SashForm(parent, SWT.HORIZONTAL);
169 sashForm.setSashWidth(4);
170 sashForm.setLayout(new FillLayout());
171 sashForm.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
172
173 Composite top = tk.createComposite(sashForm);
174 GridLayout gl = new GridLayout(1, false);
175 top.setLayout(gl);
176
177 flowsViewer = new TreeViewer(top);
178 flowsViewer.getTree().setLayoutData(
179 new GridData(SWT.FILL, SWT.FILL, true, true));
180 flowsViewer.setLabelProvider(new ViewLabelProvider());
181 flowsViewer.setContentProvider(new ViewContentProvider());
182 flowsViewer.addSelectionChangedListener(new SelectionChangedListener());
183
184 int operations = DND.DROP_COPY | DND.DROP_MOVE;
185 Transfer[] tt = new Transfer[] { TextTransfer.getInstance() };
186 flowsViewer.addDropSupport(operations, tt, new ViewDropListener(
187 flowsViewer));
188
189 flowsViewer.setInput(getEditorSite());
190 flowsViewer.setInput(processNode);
191
192 Composite bottom = tk.createComposite(sashForm);
193 bottom.setLayout(new GridLayout(1, false));
194 sashForm.setWeights(getWeights());
195 }
196
197 protected int[] getWeights() {
198 return new int[] { 70, 30 };
199 }
200
201 /*
202 * CONTROLLERS
203 */
204 protected void addFlow(String path) {
205 try {
206 Node flowNode = processNode.getNode(SLC_FLOW).addNode(SLC_FLOW);
207 flowNode.addMixin(SLC_REALIZED_FLOW);
208 Node address = flowNode.addNode(SLC_ADDRESS, NodeType.NT_ADDRESS);
209 address.setProperty(Property.JCR_PATH, path);
210 flowsViewer.refresh();
211 formPart.markDirty();
212 } catch (RepositoryException e) {
213 throw new SlcException("Cannot drop " + path, e);
214 }
215 }
216
217 @SuppressWarnings("unchecked")
218 protected void removeSelectedFlows() {
219 if (!flowsViewer.getSelection().isEmpty()) {
220 Iterator<Object> it = ((StructuredSelection) flowsViewer
221 .getSelection()).iterator();
222 while (it.hasNext()) {
223 Node node = (Node) it.next();
224 try {
225 node.remove();
226 } catch (RepositoryException e) {
227 throw new ArgeoException("Cannot remove " + node, e);
228 }
229 }
230 flowsViewer.refresh();
231 formPart.markDirty();
232 }
233 }
234
235 protected void removeAllFlows() {
236 try {
237 for (NodeIterator nit = processNode.getNode(SLC_FLOW).getNodes(); nit
238 .hasNext();) {
239 nit.nextNode().remove();
240 }
241 flowsViewer.refresh();
242 formPart.markDirty();
243 } catch (RepositoryException e) {
244 throw new ArgeoException("Cannot remove flows from " + processNode,
245 e);
246 }
247 }
248
249 public void commit(Boolean onSave) {
250 formPart.commit(onSave);
251 }
252
253 @Override
254 public void setFocus() {
255 flowsViewer.getTree().setFocus();
256 }
257
258 @Override
259 public void dispose() {
260 JcrUtils.unregisterQuietly(processNode, statusObserver);
261 super.dispose();
262 }
263
264 // Specific Providers for the current view.
265 protected class ViewContentProvider implements ITreeContentProvider {
266 public void inputChanged(Viewer arg0, Object arg1, Object arg2) {
267 }
268
269 public void dispose() {
270 }
271
272 public Object[] getElements(Object obj) {
273 if (!(obj instanceof Node))
274 return new Object[0];
275
276 try {
277 Node node = (Node) obj;
278 List<Node> children = new ArrayList<Node>();
279 for (NodeIterator nit = node.getNode(SLC_FLOW).getNodes(); nit
280 .hasNext();)
281 children.add(nit.nextNode());
282 return children.toArray();
283 } catch (RepositoryException e) {
284 throw new SlcException("Cannot list children of " + obj, e);
285 }
286 }
287
288 public Object[] getChildren(Object parentElement) {
289 return null;
290 }
291
292 public Object getParent(Object element) {
293 return null;
294 }
295
296 public boolean hasChildren(Object element) {
297 return false;
298 }
299
300 }
301
302 protected class ViewLabelProvider extends ColumnLabelProvider {
303
304 @Override
305 public String getText(Object element) {
306 Node node = (Node) element;
307 try {
308 if (node.isNodeType(SLC_REALIZED_FLOW)) {
309 if (node.hasNode(SLC_ADDRESS)) {
310 String path = node.getNode(SLC_ADDRESS)
311 .getProperty(Property.JCR_PATH).getString();
312 return SlcJcrUtils.flowExecutionModuleName(path) + ":"
313 + SlcJcrUtils.flowRelativePath(path);
314 }
315 }
316 } catch (RepositoryException e) {
317 throw new SlcException("Cannot display " + element, e);
318 }
319 return super.getText(element);
320 }
321
322 @Override
323 public Image getImage(Object element) {
324 Node node = (Node) element;
325 try {
326 if (node.isNodeType(SLC_REALIZED_FLOW)) {
327 return SlcImages.FLOW;
328 }
329 } catch (RepositoryException e) {
330 throw new SlcException("Cannot display " + element, e);
331 }
332 return super.getImage(element);
333 }
334
335 }
336
337 // Parameter view is updated each time a new line is selected
338 class SelectionChangedListener implements ISelectionChangedListener {
339 public void selectionChanged(SelectionChangedEvent evt) {
340
341 IStructuredSelection curSelection = (IStructuredSelection) evt
342 .getSelection();
343 Object obj = curSelection.getFirstElement();
344
345 if (obj instanceof RealizedFlow) {
346 // RealizedFlow rf = (RealizedFlow) obj;
347 // curSelectedRow = realizedFlows.indexOf(rf);
348 // refreshParameterview();
349 // setFocus();
350 }
351 }
352 }
353
354 protected class ViewDropListener extends ViewerDropAdapter {
355
356 public ViewDropListener(Viewer viewer) {
357 super(viewer);
358 }
359
360 @Override
361 public boolean performDrop(Object data) {
362 String path = data.toString();
363 addFlow(path);
364 return true;
365 }
366
367 @Override
368 public boolean validateDrop(Object target, int operation,
369 TransferData transferType) {
370 return true;
371 }
372 }
373
374 class StatusObserver implements EventListener {
375
376 public void onEvent(EventIterator events) {
377 PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
378 public void run() {
379 status.setText(getProcessStatus());
380 }
381 });
382 // flowsViewer.refresh();
383 }
384
385 }
386 }