1 package org
.argeo
.slc
.client
.ui
.views
;
3 import java
.util
.ArrayList
;
4 import java
.util
.Arrays
;
5 import java
.util
.Comparator
;
6 import java
.util
.Iterator
;
8 import java
.util
.SortedSet
;
9 import java
.util
.TreeSet
;
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
;
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
;
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);
62 public static final String ID
= ClientUiPlugin
.ID
+ ".jcrExecutionModulesView";
64 private TreeViewer viewer
;
66 private ServerPushSession pushSession
;
68 /* DEPENDENCY INJECTION */
69 private Repository repository
;
70 private Session session
;
71 private ExecutionModulesManager modulesManager
;
73 public void createPartControl(Composite parent
) {
74 pushSession
= new ServerPushSession();
78 session
= repository
.login();
79 } catch (RepositoryException e1
) {
80 throw new SlcException("Cannot log in to repository");
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());
93 // addContextMenu(viewer);
95 getViewSite().setSelectionProvider(viewer
);
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());
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
);
113 public void setFocus() {
114 viewer
.getControl().setFocus();
117 public TreeViewer
getViewer() {
121 public void refreshView() {
122 viewer
.setInput(getViewSite());
126 class ViewContentProvider
extends SimpleNodeContentProvider
{
127 private static final long serialVersionUID
= 5117887833174813672L;
129 public ViewContentProvider(Session session
) {
130 super(session
, new String
[] { SlcJcrConstants
.VM_AGENT_FACTORY_PATH
});
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());
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
))
149 else if (node
.getParent().isNodeType(SlcTypes
.SLC_EXECUTION_FLOW
))
152 return super.filterChildren(children
);
156 public boolean hasChildren(Object element
) {
157 if (element
instanceof Node
) {
158 Node node
= (Node
) element
;
160 if (node
.isNodeType(SlcTypes
.SLC_EXECUTION_FLOW
))
162 } catch (RepositoryException e
) {
163 throw new SlcException("Cannot check has children", e
);
166 return super.hasChildren(element
);
170 static class ViewComparator
implements Comparator
<Object
> {
172 public int compare(Object o1
, Object o2
) {
174 if (o1
instanceof Node
&& o2
instanceof Node
) {
175 Node node1
= (Node
) o1
;
176 Node node2
= (Node
) o2
;
178 if (node1
.getName().equals(SLC_EXECUTION_SPECS
))
180 if (node2
.getName().equals(SLC_EXECUTION_SPECS
))
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
)) {
187 } else if (!node1
.isNodeType(SLC_EXECUTION_FLOW
) && node2
.isNodeType(SLC_EXECUTION_FLOW
)) {
191 return node1
.getName().compareTo(node2
.getName());
194 } catch (RepositoryException e
) {
195 throw new SlcException("Cannot compare " + o1
+ " and " + o2
, e
);
202 // private void addContextMenu(TreeViewer flowsViewer) {
204 // final MenuManager menuMgr = new MenuManager();
205 // menuMgr.setRemoveAllWhenShown(true);
206 // menuMgr.addMenuListener(new IMenuListener() {
208 // public void menuAboutToShow(IMenuManager manager) {
209 // menuMgr.add(new Action("Test") {
210 // public void run() {
211 // log.debug("do something");
216 // Menu menu = menuMgr.createContextMenu(flowsViewer.getControl());
217 // flowsViewer.getTree().setMenu(menu);
218 // getSite().registerContextMenu(menuMgr, flowsViewer);
221 class VmAgentObserver
extends AsyncUiEventListener
{
223 public VmAgentObserver(Display display
) {
227 protected void onEventInUiThread(List
<Event
> events
) {
228 for (Event event
: events
) {
230 String path
= event
.getPath();
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
);
238 } catch (RepositoryException e
) {
239 log
.warn("Cannot process event " + event
+ ": " + e
);
243 // TODO: optimize based on event
248 class ViewLabelProvider
extends DefaultNodeLabelProvider
implements ITableLabelProvider
{
249 private static final long serialVersionUID
= 2410754425574656399L;
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
);
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
;
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
;
285 return SlcImages
.FOLDER
;
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
);
294 public String
getColumnText(Object obj
, int index
) {
298 public Image
getColumnImage(Object obj
, int index
) {
299 return getImage(obj
);
304 class ViewDoubleClickListener
implements IDoubleClickListener
{
305 public void doubleClick(DoubleClickEvent evt
) {
306 Object obj
= ((IStructuredSelection
) evt
.getSelection()).getFirstElement();
308 if (obj
instanceof Node
) {
309 Node node
= (Node
) obj
;
310 if (node
.isNodeType(SLC_EXECUTION_MODULE
)) {
311 ClientUiPlugin
.startStopExecutionModule(modulesManager
, node
);
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
);
322 SortedSet
<String
> paths
= new TreeSet
<String
>();
323 for (NodeIterator nit
= query
.execute().getNodes(); nit
.hasNext();) {
324 paths
.add(nit
.nextNode().getPath());
327 IWorkbenchPage activePage
= PlatformUI
.getWorkbench().getActiveWorkbenchWindow()
329 activePage
.openEditor(new ProcessEditorInput(new ArrayList
<String
>(paths
), true),
333 } catch (Exception e
) {
334 throw new SlcException("Cannot open " + obj
, e
);
340 /** Listen to drags */
341 class ViewDragListener
extends DragSourceAdapter
{
342 private static final long serialVersionUID
= 250270504802674171L;
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
348 boolean doIt
= false;
349 IStructuredSelection selection
= (IStructuredSelection
) viewer
.getSelection();
350 @SuppressWarnings("rawtypes")
351 Iterator it
= selection
.iterator();
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
)) {
363 } catch (RepositoryException e
) {
364 throw new SlcException("Cannot read node to set drag data", e
);
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();
376 while (it
.hasNext()) {
377 Object obj
= it
.next();
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');
388 } catch (RepositoryException e
) {
389 throw new SlcException("Cannot read node to set drag data", e
);
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());
401 public void dispose() {
402 JcrUtils
.logoutQuietly(session
);
403 if (pushSession
!= null)
408 // DEPENDENCY INJECTION
410 public void setModulesManager(ExecutionModulesManager modulesManager
) {
411 this.modulesManager
= modulesManager
;
414 public void setRepository(Repository repository
) {
415 this.repository
= repository
;