]> git.argeo.org Git - gpl/argeo-slc.git/blob - legacy/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/views/JcrExecutionModulesView.java
Massive Argeo APIs refactoring
[gpl/argeo-slc.git] / legacy / org.argeo.slc.client.ui / src / 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.Repository;
15 import javax.jcr.RepositoryException;
16 import javax.jcr.Session;
17 import javax.jcr.nodetype.NodeType;
18 import javax.jcr.observation.Event;
19 import javax.jcr.query.Query;
20 import javax.jcr.query.QueryManager;
21
22 import org.argeo.api.cms.CmsLog;
23 import org.argeo.eclipse.ui.jcr.AsyncUiEventListener;
24 import org.argeo.eclipse.ui.jcr.DefaultNodeLabelProvider;
25 import org.argeo.eclipse.ui.jcr.NodeElementComparer;
26 import org.argeo.eclipse.ui.jcr.SimpleNodeContentProvider;
27 import org.argeo.eclipse.ui.specific.EclipseUiSpecificUtils;
28 import org.argeo.jcr.JcrUtils;
29 import org.argeo.slc.SlcException;
30 import org.argeo.slc.SlcNames;
31 import org.argeo.slc.SlcTypes;
32 import org.argeo.slc.client.ui.ClientUiPlugin;
33 import org.argeo.slc.client.ui.SlcImages;
34 import org.argeo.slc.client.ui.editors.ProcessEditor;
35 import org.argeo.slc.client.ui.editors.ProcessEditorInput;
36 import org.argeo.slc.execution.ExecutionModulesManager;
37 import org.argeo.slc.jcr.SlcJcrConstants;
38 import org.eclipse.jface.viewers.DoubleClickEvent;
39 import org.eclipse.jface.viewers.IDoubleClickListener;
40 import org.eclipse.jface.viewers.IStructuredSelection;
41 import org.eclipse.jface.viewers.ITableLabelProvider;
42 import org.eclipse.jface.viewers.TreeViewer;
43 import org.eclipse.rap.rwt.service.ServerPushSession;
44 import org.eclipse.swt.SWT;
45 import org.eclipse.swt.dnd.DND;
46 import org.eclipse.swt.dnd.DragSourceAdapter;
47 import org.eclipse.swt.dnd.DragSourceEvent;
48 import org.eclipse.swt.dnd.TextTransfer;
49 import org.eclipse.swt.dnd.Transfer;
50 import org.eclipse.swt.graphics.Image;
51 import org.eclipse.swt.widgets.Composite;
52 import org.eclipse.swt.widgets.Display;
53 import org.eclipse.ui.IWorkbenchPage;
54 import org.eclipse.ui.PlatformUI;
55 import org.eclipse.ui.part.ViewPart;
56
57 /** JCR based view of the execution modules. */
58 public class JcrExecutionModulesView extends ViewPart implements SlcTypes, SlcNames {
59 private final static CmsLog log = CmsLog.getLog(JcrExecutionModulesView.class);
60
61 public static final String ID = ClientUiPlugin.ID + ".jcrExecutionModulesView";
62
63 private TreeViewer viewer;
64
65 private ServerPushSession pushSession;
66
67 /* DEPENDENCY INJECTION */
68 private Repository repository;
69 private Session session;
70 private ExecutionModulesManager modulesManager;
71
72 public void createPartControl(Composite parent) {
73 pushSession = new ServerPushSession();
74 pushSession.start();
75
76 try {
77 session = repository.login();
78 } catch (RepositoryException e1) {
79 throw new SlcException("Cannot log in to repository");
80 }
81
82 viewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
83 EclipseUiSpecificUtils.enableToolTipSupport(viewer);
84 ViewContentProvider contentProvider = new ViewContentProvider(session);
85 viewer.setContentProvider(contentProvider);
86 viewer.setComparer(new NodeElementComparer());
87 final ViewLabelProvider viewLabelProvider = new ViewLabelProvider();
88 viewer.setLabelProvider(viewLabelProvider);
89 viewer.setInput(getViewSite());
90 viewer.addDoubleClickListener(new ViewDoubleClickListener());
91 // context menu
92 // addContextMenu(viewer);
93
94 getViewSite().setSelectionProvider(viewer);
95
96 Transfer[] tt = new Transfer[] { TextTransfer.getInstance() };
97 // Transfer[] tt = new Transfer[] { EditorInputTransfer.getInstance() };
98 int operations = DND.DROP_COPY | DND.DROP_MOVE;
99 viewer.addDragSupport(operations, tt, new ViewDragListener());
100
101 try {
102 String[] nodeTypes = { SlcTypes.SLC_AGENT, SlcTypes.SLC_AGENT_FACTORY, SlcTypes.SLC_EXECUTION_MODULE };
103 session.getWorkspace().getObservationManager().addEventListener(
104 new VmAgentObserver(viewer.getTree().getDisplay()),
105 Event.NODE_ADDED | Event.NODE_REMOVED | Event.NODE_MOVED, SlcJcrConstants.VM_AGENT_FACTORY_PATH,
106 true, null, 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 // Controllers
125 class ViewContentProvider extends SimpleNodeContentProvider {
126 private static final long serialVersionUID = 5117887833174813672L;
127
128 public ViewContentProvider(Session session) {
129 super(session, new String[] { SlcJcrConstants.VM_AGENT_FACTORY_PATH });
130 }
131
132 @Override
133 protected Object[] sort(Object parent, Object[] children) {
134 Object[] sorted = new Object[children.length];
135 System.arraycopy(children, 0, sorted, 0, children.length);
136 Arrays.sort(sorted, new ViewComparator());
137 return sorted;
138 }
139
140 @Override
141 protected List<Node> filterChildren(List<Node> children) throws RepositoryException {
142 for (Iterator<Node> it = children.iterator(); it.hasNext();) {
143 Node node = it.next();
144 // execution spec definitions
145 if (node.getName().equals(SLC_EXECUTION_SPECS))
146 it.remove();
147 // flow values
148 else if (node.getParent().isNodeType(SlcTypes.SLC_EXECUTION_FLOW))
149 it.remove();
150 }
151 return super.filterChildren(children);
152 }
153
154 @Override
155 public boolean hasChildren(Object element) {
156 if (element instanceof Node) {
157 Node node = (Node) element;
158 try {
159 if (node.isNodeType(SlcTypes.SLC_EXECUTION_FLOW))
160 return false;
161 } catch (RepositoryException e) {
162 throw new SlcException("Cannot check has children", e);
163 }
164 }
165 return super.hasChildren(element);
166 }
167 }
168
169 static class ViewComparator implements Comparator<Object> {
170
171 public int compare(Object o1, Object o2) {
172 try {
173 if (o1 instanceof Node && o2 instanceof Node) {
174 Node node1 = (Node) o1;
175 Node node2 = (Node) o2;
176
177 if (node1.getName().equals(SLC_EXECUTION_SPECS))
178 return -100;
179 if (node2.getName().equals(SLC_EXECUTION_SPECS))
180 return 100;
181
182 if (node1.isNodeType(SLC_EXECUTION_FLOW) && node2.isNodeType(SLC_EXECUTION_FLOW)) {
183 return node1.getName().compareTo(node2.getName());
184 } else if (node1.isNodeType(SLC_EXECUTION_FLOW) && !node2.isNodeType(SLC_EXECUTION_FLOW)) {
185 return 1;
186 } else if (!node1.isNodeType(SLC_EXECUTION_FLOW) && node2.isNodeType(SLC_EXECUTION_FLOW)) {
187 return -1;
188 } else {
189 // TODO: check title
190 return node1.getName().compareTo(node2.getName());
191 }
192 }
193 } catch (RepositoryException e) {
194 throw new SlcException("Cannot compare " + o1 + " and " + o2, e);
195 }
196 return 0;
197 }
198
199 }
200
201 // private void addContextMenu(TreeViewer flowsViewer) {
202 //
203 // final MenuManager menuMgr = new MenuManager();
204 // menuMgr.setRemoveAllWhenShown(true);
205 // menuMgr.addMenuListener(new IMenuListener() {
206 //
207 // public void menuAboutToShow(IMenuManager manager) {
208 // menuMgr.add(new Action("Test") {
209 // public void run() {
210 // log.debug("do something");
211 // }
212 // });
213 // }
214 // });
215 // Menu menu = menuMgr.createContextMenu(flowsViewer.getControl());
216 // flowsViewer.getTree().setMenu(menu);
217 // getSite().registerContextMenu(menuMgr, flowsViewer);
218 // }
219
220 class VmAgentObserver extends AsyncUiEventListener {
221
222 public VmAgentObserver(Display display) {
223 super(display);
224 }
225
226 protected void onEventInUiThread(List<Event> events) {
227 for (Event event : events) {
228 try {
229 String path = event.getPath();
230
231 if (session.itemExists(path)) {
232 Node parentNode = session.getNode(path);// .getParent();
233 if (log.isTraceEnabled())
234 log.trace("Refresh " + parentNode + " after event " + event);
235 viewer.refresh(parentNode);
236 }
237 } catch (RepositoryException e) {
238 log.warn("Cannot process event " + event + ": " + e);
239 }
240 }
241
242 // TODO: optimize based on event
243 viewer.refresh();
244 }
245 }
246
247 class ViewLabelProvider extends DefaultNodeLabelProvider implements ITableLabelProvider {
248 private static final long serialVersionUID = 2410754425574656399L;
249
250 @Override
251 protected String getText(Node node) throws RepositoryException {
252 if (node.isNodeType(NodeType.MIX_TITLE) && node.hasProperty(Property.JCR_TITLE))
253 return node.getProperty(Property.JCR_TITLE).getString();
254 else if (node.getName().equals(SLC_EXECUTION_SPECS))
255 return "Execution Specifications";
256 else if (node.getPath().equals(SlcJcrConstants.VM_AGENT_FACTORY_PATH))
257 return "Internal Agents";
258 return super.getText(node);
259 }
260
261 @Override
262 public Image getImage(Node node) throws RepositoryException {
263 // we try to optimize a bit by putting deeper nodes first
264 if (node.getParent().isNodeType(SlcTypes.SLC_EXECUTION_SPEC_ATTRIBUTE))
265 return SlcImages.CHOICES;
266 else if (node.isNodeType(SlcTypes.SLC_EXECUTION_SPEC_ATTRIBUTE))
267 return SlcImages.EXECUTION_SPEC_ATTRIBUTE;
268 else if (node.isNodeType(SlcTypes.SLC_EXECUTION_SPEC))
269 return SlcImages.EXECUTION_SPEC;
270 else if (node.getName().equals(SLC_EXECUTION_SPECS))
271 return SlcImages.EXECUTION_SPECS;
272 else if (node.isNodeType(SlcTypes.SLC_EXECUTION_FLOW))
273 return SlcImages.FLOW;
274 else if (node.isNodeType(SlcTypes.SLC_MODULE)) {
275 if (node.getProperty(SLC_STARTED).getBoolean())
276 return SlcImages.MODULE;
277 else
278 return SlcImages.MODULE_STOPPED;
279 } else if (node.isNodeType(SlcTypes.SLC_AGENT))
280 return SlcImages.AGENT;
281 else if (node.isNodeType(SlcTypes.SLC_AGENT_FACTORY))
282 return SlcImages.AGENT_FACTORY;
283 else
284 return SlcImages.FOLDER;
285 }
286
287 public String getToolTipText(Node node) throws RepositoryException {
288 if (node.isNodeType(NodeType.MIX_TITLE) && node.hasProperty(Property.JCR_DESCRIPTION))
289 return node.getProperty(Property.JCR_DESCRIPTION).getString();
290 return super.getToolTipText(node);
291 }
292
293 public String getColumnText(Object obj, int index) {
294 return getText(obj);
295 }
296
297 public Image getColumnImage(Object obj, int index) {
298 return getImage(obj);
299 }
300
301 }
302
303 class ViewDoubleClickListener implements IDoubleClickListener {
304 public void doubleClick(DoubleClickEvent evt) {
305 Object obj = ((IStructuredSelection) evt.getSelection()).getFirstElement();
306 try {
307 if (obj instanceof Node) {
308 Node node = (Node) obj;
309 if (node.isNodeType(SLC_EXECUTION_MODULE)) {
310 ClientUiPlugin.startStopExecutionModule(modulesManager, node);
311 } else {
312 String path = node.getPath();
313 // TODO factorize with editor
314 QueryManager qm = node.getSession().getWorkspace().getQueryManager();
315 String statement = "SELECT * FROM [" + SlcTypes.SLC_EXECUTION_FLOW
316 + "] WHERE ISDESCENDANTNODE(['" + path + "']) OR ISSAMENODE(['" + path + "'])";
317 // log.debug(statement);
318 Query query = qm.createQuery(statement, Query.JCR_SQL2);
319
320 // order paths
321 SortedSet<String> paths = new TreeSet<String>();
322 for (NodeIterator nit = query.execute().getNodes(); nit.hasNext();) {
323 paths.add(nit.nextNode().getPath());
324 }
325
326 IWorkbenchPage activePage = PlatformUI.getWorkbench().getActiveWorkbenchWindow()
327 .getActivePage();
328 activePage.openEditor(new ProcessEditorInput(new ArrayList<String>(paths), true),
329 ProcessEditor.ID);
330 }
331 }
332 } catch (Exception e) {
333 throw new SlcException("Cannot open " + obj, e);
334 }
335 }
336
337 }
338
339 /** Listen to drags */
340 class ViewDragListener extends DragSourceAdapter {
341 private static final long serialVersionUID = 250270504802674171L;
342
343 // Check if the drag action should start.
344 public void dragStart(DragSourceEvent event) {
345 // we only start drag if at least one of the selected elements is
346 // valid
347 boolean doIt = false;
348 IStructuredSelection selection = (IStructuredSelection) viewer.getSelection();
349 @SuppressWarnings("rawtypes")
350 Iterator it = selection.iterator();
351 try {
352 while (it.hasNext()) {
353 Object obj = it.next();
354 if (obj instanceof Node) {
355 Node node = (Node) obj;
356 if (node.isNodeType(SlcTypes.SLC_EXECUTION_FLOW)
357 || node.isNodeType(SlcTypes.SLC_EXECUTION_MODULE)) {
358 doIt = true;
359 }
360 }
361 }
362 } catch (RepositoryException e) {
363 throw new SlcException("Cannot read node to set drag data", e);
364 }
365 event.doit = doIt;
366 }
367
368 public void dragSetData(DragSourceEvent event) {
369 IStructuredSelection selection = (IStructuredSelection) viewer.getSelection();
370 StringBuilder buf = new StringBuilder();
371 @SuppressWarnings("rawtypes")
372 Iterator it = selection.iterator();
373 try {
374
375 while (it.hasNext()) {
376 Object obj = it.next();
377
378 if (obj instanceof Node) {
379 Node node = (Node) obj;
380 if ((node.isNodeType(SlcTypes.SLC_EXECUTION_FLOW)
381 || node.isNodeType(SlcTypes.SLC_EXECUTION_MODULE))
382 && TextTransfer.getInstance().isSupportedType(event.dataType)) {
383 buf.append(node.getPath()).append('\n');
384 }
385 }
386 }
387 } catch (RepositoryException e) {
388 throw new SlcException("Cannot read node to set drag data", e);
389 }
390
391 if (buf.length() > 0) {
392 if (buf.charAt(buf.length() - 1) == '\n')
393 buf.deleteCharAt(buf.length() - 1);
394 event.data = buf.toString();
395 log.debug("data set to : " + buf.toString());
396 }
397 }
398 }
399
400 public void dispose() {
401 JcrUtils.logoutQuietly(session);
402 if (pushSession != null)
403 pushSession.stop();
404 super.dispose();
405 }
406
407 // DEPENDENCY INJECTION
408
409 public void setModulesManager(ExecutionModulesManager modulesManager) {
410 this.modulesManager = modulesManager;
411 }
412
413 public void setRepository(Repository repository) {
414 this.repository = repository;
415 }
416 }