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