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