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