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