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