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