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