]> git.argeo.org Git - gpl/argeo-slc.git/blob - eclipse/plugins/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/views/JcrExecutionModulesView.java
Minimal Hello World execution module
[gpl/argeo-slc.git] / eclipse / plugins / org.argeo.slc.client.ui / src / main / java / org / argeo / slc / client / ui / views / JcrExecutionModulesView.java
1 package org.argeo.slc.client.ui.views;
2
3 import java.util.ArrayList;
4 import java.util.Arrays;
5 import java.util.Comparator;
6 import java.util.Iterator;
7 import java.util.List;
8 import java.util.SortedSet;
9 import java.util.TreeSet;
10
11 import javax.jcr.Node;
12 import javax.jcr.NodeIterator;
13 import javax.jcr.Property;
14 import javax.jcr.RepositoryException;
15 import javax.jcr.Session;
16 import javax.jcr.nodetype.NodeType;
17 import javax.jcr.observation.Event;
18 import javax.jcr.query.Query;
19 import javax.jcr.query.QueryManager;
20
21 import org.apache.commons.logging.Log;
22 import org.apache.commons.logging.LogFactory;
23 import org.argeo.ArgeoException;
24 import org.argeo.eclipse.ui.jcr.AsyncUiEventListener;
25 import org.argeo.eclipse.ui.jcr.DefaultNodeLabelProvider;
26 import org.argeo.eclipse.ui.jcr.NodeElementComparer;
27 import org.argeo.eclipse.ui.jcr.SimpleNodeContentProvider;
28 import org.argeo.slc.BasicNameVersion;
29 import org.argeo.slc.NameVersion;
30 import org.argeo.slc.SlcException;
31 import org.argeo.slc.client.ui.SlcImages;
32 import org.argeo.slc.client.ui.editors.ProcessEditor;
33 import org.argeo.slc.client.ui.editors.ProcessEditorInput;
34 import org.argeo.slc.execution.ExecutionModulesManager;
35 import org.argeo.slc.jcr.SlcJcrConstants;
36 import org.argeo.slc.jcr.SlcNames;
37 import org.argeo.slc.jcr.SlcTypes;
38 import org.eclipse.core.runtime.IProgressMonitor;
39 import org.eclipse.core.runtime.IStatus;
40 import org.eclipse.core.runtime.Status;
41 import org.eclipse.core.runtime.jobs.Job;
42 import org.eclipse.jface.viewers.ColumnViewerToolTipSupport;
43 import org.eclipse.jface.viewers.DoubleClickEvent;
44 import org.eclipse.jface.viewers.IDoubleClickListener;
45 import org.eclipse.jface.viewers.IStructuredSelection;
46 import org.eclipse.jface.viewers.ITableLabelProvider;
47 import org.eclipse.jface.viewers.TreeViewer;
48 import org.eclipse.swt.SWT;
49 import org.eclipse.swt.dnd.DND;
50 import org.eclipse.swt.dnd.DragSourceAdapter;
51 import org.eclipse.swt.dnd.DragSourceEvent;
52 import org.eclipse.swt.dnd.TextTransfer;
53 import org.eclipse.swt.dnd.Transfer;
54 import org.eclipse.swt.graphics.Image;
55 import org.eclipse.swt.widgets.Composite;
56 import org.eclipse.swt.widgets.Display;
57 import org.eclipse.ui.IWorkbenchPage;
58 import org.eclipse.ui.PlatformUI;
59 import org.eclipse.ui.part.ViewPart;
60
61 /** JCR based view of the execution modules. */
62 public class JcrExecutionModulesView extends ViewPart implements SlcTypes,
63 SlcNames {
64 private final static Log log = LogFactory
65 .getLog(JcrExecutionModulesView.class);
66
67 public static final String ID = "org.argeo.slc.client.ui.jcrExecutionModulesView";
68
69 private TreeViewer viewer;
70
71 private Session session;
72
73 private ExecutionModulesManager modulesManager;
74
75 public void createPartControl(Composite parent) {
76 viewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
77
78 // FIXME : does not work in RAP, find a way to have it for RCP only
79 // ColumnViewerToolTipSupport.enableFor(viewer);
80
81 ViewContentProvider contentProvider = new ViewContentProvider(session);
82
83 viewer.setContentProvider(contentProvider);
84 viewer.setComparer(new NodeElementComparer());
85 final ViewLabelProvider viewLabelProvider = new ViewLabelProvider();
86 viewer.setLabelProvider(viewLabelProvider);
87 ColumnViewerToolTipSupport.enableFor(viewer);
88 viewer.setInput(getViewSite());
89 viewer.addDoubleClickListener(new ViewDoubleClickListener());
90 getViewSite().setSelectionProvider(viewer);
91
92 Transfer[] tt = new Transfer[] { TextTransfer.getInstance() };
93 // Transfer[] tt = new Transfer[] { EditorInputTransfer.getInstance() };
94 int operations = DND.DROP_COPY | DND.DROP_MOVE;
95 viewer.addDragSupport(operations, tt, new ViewDragListener());
96
97 try {
98 String[] nodeTypes = { SlcTypes.SLC_AGENT,
99 SlcTypes.SLC_AGENT_FACTORY, SlcTypes.SLC_EXECUTION_MODULE };
100 session.getWorkspace()
101 .getObservationManager()
102 .addEventListener(
103 new VmAgentObserver(viewer.getTree().getDisplay()),
104 Event.NODE_ADDED | Event.NODE_REMOVED
105 | Event.NODE_MOVED,
106 SlcJcrConstants.VM_AGENT_FACTORY_PATH, true, null,
107 nodeTypes, false);
108 } catch (RepositoryException e) {
109 throw new SlcException("Cannot add observer", e);
110 }
111 }
112
113 public void setFocus() {
114 viewer.getControl().setFocus();
115 }
116
117 public TreeViewer getViewer() {
118 return viewer;
119 }
120
121 public void refreshView() {
122 viewer.setInput(getViewSite());
123 }
124
125 class ViewContentProvider extends SimpleNodeContentProvider {
126
127 public ViewContentProvider(Session session) {
128 super(session,
129 new String[] { SlcJcrConstants.VM_AGENT_FACTORY_PATH });
130 }
131
132 // @Override
133 // protected Object[] getChildren(Node node) throws RepositoryException
134 // {
135 // if (node.isNodeType(SlcTypes.SLC_AGENT_FACTORY)) {
136 // List<AgentNodesWrapper> wrappers = new
137 // ArrayList<AgentNodesWrapper>();
138 // for (NodeIterator nit = node.getNodes(); nit.hasNext();) {
139 // wrappers.add(new AgentNodesWrapper(nit.nextNode()));
140 // }
141 // return wrappers.toArray();
142 // }
143 // return super.getChildren(node);
144 // }
145
146 @Override
147 protected Object[] sort(Object parent, Object[] children) {
148 Object[] sorted = new Object[children.length];
149 System.arraycopy(children, 0, sorted, 0, children.length);
150 Arrays.sort(sorted, new ViewComparator());
151 return sorted;
152 }
153
154 @Override
155 protected List<Node> filterChildren(List<Node> children)
156 throws RepositoryException {
157 for (Iterator<Node> it = children.iterator(); it.hasNext();) {
158 Node node = it.next();
159 // execution spec definitions
160 if (node.getName().equals(SLC_EXECUTION_SPECS))
161 it.remove();
162 // flow values
163 else if (node.getParent().isNodeType(
164 SlcTypes.SLC_EXECUTION_FLOW))
165 it.remove();
166 }
167 return super.filterChildren(children);
168 }
169
170 @Override
171 public boolean hasChildren(Object element) {
172 if (element instanceof Node) {
173 Node node = (Node) element;
174 try {
175 if (node.isNodeType(SlcTypes.SLC_EXECUTION_FLOW))
176 return false;
177 } catch (RepositoryException e) {
178 throw new SlcException("Cannot check has children", e);
179 }
180 }
181 return super.hasChildren(element);
182 }
183 }
184
185 static class ViewComparator implements Comparator<Object> {
186
187 public int compare(Object o1, Object o2) {
188 try {
189 if (o1 instanceof Node && o2 instanceof Node) {
190 Node node1 = (Node) o1;
191 Node node2 = (Node) o2;
192
193 if (node1.getName().equals(SLC_EXECUTION_SPECS))
194 return -100;
195 if (node2.getName().equals(SLC_EXECUTION_SPECS))
196 return 100;
197
198 if (node1.isNodeType(SLC_EXECUTION_FLOW)
199 && node2.isNodeType(SLC_EXECUTION_FLOW)) {
200 return node1.getName().compareTo(node2.getName());
201 } else if (node1.isNodeType(SLC_EXECUTION_FLOW)
202 && !node2.isNodeType(SLC_EXECUTION_FLOW)) {
203 return 1;
204 } else if (!node1.isNodeType(SLC_EXECUTION_FLOW)
205 && node2.isNodeType(SLC_EXECUTION_FLOW)) {
206 return -1;
207 } else {
208 // TODO: check title
209 return node1.getName().compareTo(node2.getName());
210 }
211 }
212 } catch (RepositoryException e) {
213 throw new ArgeoException("Cannot compare " + o1 + " and " + o2,
214 e);
215 }
216 return 0;
217 }
218
219 }
220
221 // /** Wraps the execution modules of an agent. */
222 // static class AgentNodesWrapper extends NodesWrapper {
223 //
224 // public AgentNodesWrapper(Node node) {
225 // super(node);
226 // }
227 //
228 // protected List<WrappedNode> getWrappedNodes()
229 // throws RepositoryException {
230 // List<WrappedNode> children = new ArrayList<WrappedNode>();
231 // Node executionModules = getNode();
232 // for (NodeIterator nit = executionModules.getNodes(); nit.hasNext();) {
233 // for (NodeIterator nitVersions = nit.nextNode().getNodes(); nitVersions
234 // .hasNext();) {
235 // children.add(new WrappedNode(this, nitVersions.nextNode()));
236 // }
237 // }
238 // return children;
239 // }
240 //
241 // }
242
243 class VmAgentObserver extends AsyncUiEventListener {
244
245 public VmAgentObserver(Display display) {
246 super(display);
247 }
248
249 protected void onEventInUiThread(List<Event> events) {
250 for (Event event : events) {
251 try {
252 String path = event.getPath();
253
254 if (session.itemExists(path)) {
255 Node parentNode = session.getNode(path);// .getParent();
256 if (log.isDebugEnabled())
257 log.debug("Refresh " + parentNode + " after event "
258 + event);
259 viewer.refresh(parentNode);
260 }
261 } catch (RepositoryException e) {
262 log.warn("Cannot process event " + event + ": " + e);
263 }
264 }
265
266 // try {
267 // Node vmAgentNode = session
268 // .getNode(SlcJcrConstants.VM_AGENT_FACTORY_PATH);
269 // viewer.refresh(vmAgentNode);
270 // } catch (RepositoryException e) {
271 // log.warn("Cannot process event : " + e);
272 // }
273 // TODO: optimize based on event
274 viewer.refresh();
275 }
276 }
277
278 class ViewLabelProvider extends DefaultNodeLabelProvider implements
279 ITableLabelProvider {
280
281 @Override
282 protected String getText(Node node) throws RepositoryException {
283 if (node.isNodeType(NodeType.MIX_TITLE)
284 && node.hasProperty(Property.JCR_TITLE))
285 return node.getProperty(Property.JCR_TITLE).getString();
286 else if (node.getName().equals(SLC_EXECUTION_SPECS))
287 return "Execution Specifications";
288 else if (node.getPath().equals(
289 SlcJcrConstants.VM_AGENT_FACTORY_PATH))
290 return "Internal Agents";
291 return super.getText(node);
292 }
293
294 @Override
295 public Image getImage(Node node) throws RepositoryException {
296 // we try to optimize a bit by putting deeper nodes first
297 if (node.getParent().isNodeType(
298 SlcTypes.SLC_EXECUTION_SPEC_ATTRIBUTE))
299 return SlcImages.CHOICES;
300 else if (node.isNodeType(SlcTypes.SLC_EXECUTION_SPEC_ATTRIBUTE))
301 return SlcImages.EXECUTION_SPEC_ATTRIBUTE;
302 else if (node.isNodeType(SlcTypes.SLC_EXECUTION_SPEC))
303 return SlcImages.EXECUTION_SPEC;
304 else if (node.getName().equals(SLC_EXECUTION_SPECS))
305 return SlcImages.EXECUTION_SPECS;
306 else if (node.isNodeType(SlcTypes.SLC_EXECUTION_FLOW))
307 return SlcImages.FLOW;
308 else if (node.isNodeType(SlcTypes.SLC_MODULE)) {
309 if (node.getProperty(SLC_STARTED).getBoolean())
310 return SlcImages.MODULE;
311 else
312 return SlcImages.MODULE_STOPPED;
313 } else if (node.isNodeType(SlcTypes.SLC_AGENT))
314 return SlcImages.AGENT;
315 else if (node.isNodeType(SlcTypes.SLC_AGENT_FACTORY))
316 return SlcImages.AGENT_FACTORY;
317 else
318 return SlcImages.FOLDER;
319 }
320
321 public String getToolTipText(Node node) throws RepositoryException {
322 if (node.isNodeType(NodeType.MIX_TITLE)
323 && node.hasProperty(Property.JCR_DESCRIPTION))
324 return node.getProperty(Property.JCR_DESCRIPTION).getString();
325 return super.getToolTipText(node);
326 }
327
328 public String getColumnText(Object obj, int index) {
329 return getText(obj);
330 }
331
332 public Image getColumnImage(Object obj, int index) {
333 return getImage(obj);
334 }
335
336 }
337
338 class ViewDoubleClickListener implements IDoubleClickListener {
339 public void doubleClick(DoubleClickEvent evt) {
340 Object obj = ((IStructuredSelection) evt.getSelection())
341 .getFirstElement();
342 try {
343 if (obj instanceof Node) {
344 Node node = (Node) obj;
345 if (node.isNodeType(SLC_EXECUTION_MODULE)) {
346 String name = node.getProperty(SLC_NAME).getString();
347 String version = node.getProperty(SLC_VERSION)
348 .getString();
349 final NameVersion nameVersion = new BasicNameVersion(
350 name, version);
351 Boolean started = node.getProperty(SLC_STARTED)
352 .getBoolean();
353
354 Job job;
355 if (started) {
356 job = new Job("Stop " + nameVersion) {
357 protected IStatus run(IProgressMonitor monitor) {
358 monitor.beginTask("Stop " + nameVersion, 1);
359 modulesManager.stop(nameVersion);
360 monitor.worked(1);
361 return Status.OK_STATUS;
362 }
363 };
364 } else {
365 job = new Job("Start " + nameVersion) {
366 protected IStatus run(IProgressMonitor monitor) {
367 monitor.beginTask("Start " + nameVersion, 1);
368 modulesManager.start(nameVersion);
369 monitor.worked(1);
370 return Status.OK_STATUS;
371 }
372 };
373 }
374 job.setUser(true);
375 job.schedule();
376 } else {
377 String path = node.getPath();
378 // TODO factorize with editor
379 QueryManager qm = node.getSession().getWorkspace()
380 .getQueryManager();
381 String statement = "SELECT * FROM ["
382 + SlcTypes.SLC_EXECUTION_FLOW
383 + "] WHERE ISDESCENDANTNODE(['" + path
384 + "']) OR ISSAMENODE(['" + path + "'])";
385 // log.debug(statement);
386 Query query = qm.createQuery(statement, Query.JCR_SQL2);
387
388 // order paths
389 SortedSet<String> paths = new TreeSet<String>();
390 for (NodeIterator nit = query.execute().getNodes(); nit
391 .hasNext();) {
392 paths.add(nit.nextNode().getPath());
393 }
394
395 // List<String> paths = new ArrayList<String>();
396 // paths.add(node.getPath());
397 IWorkbenchPage activePage = PlatformUI.getWorkbench()
398 .getActiveWorkbenchWindow().getActivePage();
399 activePage.openEditor(new ProcessEditorInput(
400 new ArrayList<String>(paths), true),
401 ProcessEditor.ID);
402 }
403 }
404 } catch (Exception e) {
405 throw new SlcException("Cannot open " + obj, e);
406 }
407 }
408
409 }
410
411 class ViewDragListener extends DragSourceAdapter {
412 public void dragSetData(DragSourceEvent event) {
413 IStructuredSelection selection = (IStructuredSelection) viewer
414 .getSelection();
415 if (selection.getFirstElement() instanceof Node) {
416 Node node = (Node) selection.getFirstElement();
417 // try {
418 // if (node.isNodeType(SLC_EXECUTION_FLOW)) {
419 // if (EditorInputTransfer.getInstance().isSupportedType(
420 // event.dataType)) {
421 // ProcessEditorInput pei = new ProcessEditorInput(
422 // node.getPath());
423 // EditorInputData eid = EditorInputTransfer
424 // .createEditorInputData(ProcessEditor.ID,
425 // pei);
426 // event.data = new EditorInputTransfer.EditorInputData[] { eid
427 // };
428 //
429 // }
430 // }
431 // } catch (RepositoryException e1) {
432 // throw new SlcException("Cannot drag " + node, e1);
433 // }
434
435 if (TextTransfer.getInstance().isSupportedType(event.dataType)) {
436 try {
437 event.data = node.getPath();
438 } catch (RepositoryException e1) {
439 // TODO Auto-generated catch block
440 e1.printStackTrace();
441 }
442 }
443 }
444 }
445 }
446
447 public void setSession(Session session) {
448 this.session = session;
449 }
450
451 public void setModulesManager(ExecutionModulesManager modulesManager) {
452 this.modulesManager = modulesManager;
453 }
454
455 }