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