1 package org
.argeo
.slc
.client
.ui
.views
;
3 import java
.awt
.Window
;
4 import java
.util
.ArrayList
;
5 import java
.util
.Calendar
;
9 import javax
.jcr
.NodeIterator
;
10 import javax
.jcr
.Property
;
11 import javax
.jcr
.PropertyIterator
;
12 import javax
.jcr
.PropertyType
;
13 import javax
.jcr
.RepositoryException
;
14 import javax
.jcr
.Session
;
15 import javax
.jcr
.Value
;
16 import javax
.jcr
.nodetype
.NodeType
;
17 import javax
.jcr
.observation
.Event
;
18 import javax
.jcr
.observation
.EventListener
;
19 import javax
.jcr
.observation
.ObservationManager
;
21 import org
.apache
.commons
.logging
.Log
;
22 import org
.apache
.commons
.logging
.LogFactory
;
23 import org
.argeo
.ArgeoException
;
24 import org
.argeo
.eclipse
.ui
.jcr
.AsyncUiEventListener
;
25 import org
.argeo
.eclipse
.ui
.utils
.CommandUtils
;
26 import org
.argeo
.jcr
.JcrUtils
;
27 import org
.argeo
.jcr
.UserJcrUtils
;
28 import org
.argeo
.slc
.SlcException
;
29 import org
.argeo
.slc
.client
.ui
.ClientUiPlugin
;
30 import org
.argeo
.slc
.client
.ui
.SlcUiConstants
;
31 import org
.argeo
.slc
.client
.ui
.commands
.AddResultFolder
;
32 import org
.argeo
.slc
.client
.ui
.commands
.RenameResultFolder
;
33 import org
.argeo
.slc
.client
.ui
.commands
.RenameResultNode
;
34 import org
.argeo
.slc
.client
.ui
.editors
.ProcessEditor
;
35 import org
.argeo
.slc
.client
.ui
.editors
.ProcessEditorInput
;
36 import org
.argeo
.slc
.client
.ui
.model
.ParentNodeFolder
;
37 import org
.argeo
.slc
.client
.ui
.model
.ResultFolder
;
38 import org
.argeo
.slc
.client
.ui
.model
.ResultParent
;
39 import org
.argeo
.slc
.client
.ui
.model
.ResultParentUtils
;
40 import org
.argeo
.slc
.client
.ui
.model
.SingleResultNode
;
41 import org
.argeo
.slc
.client
.ui
.model
.VirtualFolder
;
42 import org
.argeo
.slc
.client
.ui
.providers
.ResultTreeContentProvider
;
43 import org
.argeo
.slc
.client
.ui
.providers
.ResultTreeLabelProvider
;
44 import org
.argeo
.slc
.client
.ui
.wizards
.ConfirmOverwriteWizard
;
45 import org
.argeo
.slc
.jcr
.SlcJcrResultUtils
;
46 import org
.argeo
.slc
.jcr
.SlcNames
;
47 import org
.argeo
.slc
.jcr
.SlcTypes
;
48 import org
.eclipse
.jface
.action
.IMenuListener
;
49 import org
.eclipse
.jface
.action
.IMenuManager
;
50 import org
.eclipse
.jface
.action
.MenuManager
;
51 import org
.eclipse
.jface
.viewers
.ColumnLabelProvider
;
52 import org
.eclipse
.jface
.viewers
.DecoratingLabelProvider
;
53 import org
.eclipse
.jface
.viewers
.DoubleClickEvent
;
54 import org
.eclipse
.jface
.viewers
.IDoubleClickListener
;
55 import org
.eclipse
.jface
.viewers
.ILabelDecorator
;
56 import org
.eclipse
.jface
.viewers
.ISelectionChangedListener
;
57 import org
.eclipse
.jface
.viewers
.IStructuredContentProvider
;
58 import org
.eclipse
.jface
.viewers
.IStructuredSelection
;
59 import org
.eclipse
.jface
.viewers
.SelectionChangedEvent
;
60 import org
.eclipse
.jface
.viewers
.TableViewer
;
61 import org
.eclipse
.jface
.viewers
.TableViewerColumn
;
62 import org
.eclipse
.jface
.viewers
.TreePath
;
63 import org
.eclipse
.jface
.viewers
.TreeViewer
;
64 import org
.eclipse
.jface
.viewers
.Viewer
;
65 import org
.eclipse
.jface
.viewers
.ViewerDropAdapter
;
66 import org
.eclipse
.jface
.wizard
.WizardDialog
;
67 import org
.eclipse
.swt
.SWT
;
68 import org
.eclipse
.swt
.custom
.SashForm
;
69 import org
.eclipse
.swt
.dnd
.DND
;
70 import org
.eclipse
.swt
.dnd
.DragSourceEvent
;
71 import org
.eclipse
.swt
.dnd
.DragSourceListener
;
72 import org
.eclipse
.swt
.dnd
.TextTransfer
;
73 import org
.eclipse
.swt
.dnd
.Transfer
;
74 import org
.eclipse
.swt
.dnd
.TransferData
;
75 import org
.eclipse
.swt
.layout
.FillLayout
;
76 import org
.eclipse
.swt
.layout
.GridData
;
77 import org
.eclipse
.swt
.layout
.GridLayout
;
78 import org
.eclipse
.swt
.widgets
.Composite
;
79 import org
.eclipse
.swt
.widgets
.Display
;
80 import org
.eclipse
.swt
.widgets
.Menu
;
81 import org
.eclipse
.ui
.ISharedImages
;
82 import org
.eclipse
.ui
.IWorkbenchPage
;
83 import org
.eclipse
.ui
.IWorkbenchWindow
;
84 import org
.eclipse
.ui
.PlatformUI
;
85 import org
.eclipse
.ui
.part
.ViewPart
;
87 /** SLC generic JCR Result tree view. */
88 public class JcrResultTreeView
extends ViewPart
{
89 public final static String ID
= ClientUiPlugin
.ID
+ ".jcrResultTreeView";
91 private final static Log log
= LogFactory
.getLog(JcrResultTreeView
.class);
93 /* DEPENDENCY INJECTION */
94 private Session session
;
97 private TreeViewer resultTreeViewer
;
98 private TableViewer propertiesViewer
;
100 private EventListener resultsObserver
= null;
102 private final static String
[] observedNodeTypes
= {
103 SlcTypes
.SLC_TEST_RESULT
, SlcTypes
.SLC_RESULT_FOLDER
,
104 NodeType
.NT_UNSTRUCTURED
};
106 // FIXME cache to ease D&D
107 private boolean isActionUnderMyResult
= false;
108 private ResultParent lastSelectedTargetElement
;
109 private ResultParent lastSelectedSourceElement
;
110 private ResultParent lastSelectedSourceElementParent
;
111 private boolean isResultFolder
= false;
113 // FIXME we cache the fact that we are moving a node to avoid exception
114 // triggered by the "Add Node" event while moving
115 // boolean isMoveInProgress = false;
118 * To be overridden to adapt size of form and result frames.
120 protected int[] getWeights() {
121 return new int[] { 70, 30 };
125 public void createPartControl(Composite parent
) {
126 parent
.setLayout(new FillLayout());
128 SashForm sashForm
= new SashForm(parent
, SWT
.VERTICAL
);
129 sashForm
.setSashWidth(4);
130 sashForm
.setLayout(new FillLayout());
132 // Create the tree on top of the view
133 Composite top
= new Composite(sashForm
, SWT
.NONE
);
134 GridLayout gl
= new GridLayout(1, false);
136 resultTreeViewer
= createResultsTreeViewer(top
);
138 // Create the property viewer on the bottom
139 Composite bottom
= new Composite(sashForm
, SWT
.NONE
);
140 bottom
.setLayout(new GridLayout(1, false));
141 propertiesViewer
= createPropertiesViewer(bottom
);
143 sashForm
.setWeights(getWeights());
146 ObservationManager observationManager
= session
.getWorkspace()
147 .getObservationManager();
148 resultsObserver
= new ResultObserver(resultTreeViewer
.getTree()
150 observationManager
.addEventListener(resultsObserver
,
151 Event
.NODE_MOVED
| Event
.NODE_ADDED
| Event
.NODE_REMOVED
,
152 UserJcrUtils
.getUserHome(session
).getPath(), true, null,
153 observedNodeTypes
, false);
154 } catch (RepositoryException e
) {
155 throw new SlcException("Cannot register listeners", e
);
158 // Refresh the view to initialize it
162 // The main tree viewer
163 protected TreeViewer
createResultsTreeViewer(Composite parent
) {
164 int style
= SWT
.BORDER
| SWT
.MULTI
;
166 TreeViewer viewer
= new TreeViewer(parent
, style
);
167 viewer
.getTree().setLayoutData(
168 new GridData(SWT
.FILL
, SWT
.FILL
, true, true));
170 viewer
.setContentProvider(new ResultTreeContentProvider());
172 // Add label provider with label decorator
173 ResultTreeLabelProvider rtLblProvider
= new ResultTreeLabelProvider();
174 ILabelDecorator decorator
= ClientUiPlugin
.getDefault().getWorkbench()
175 .getDecoratorManager().getLabelDecorator();
176 viewer
.setLabelProvider(new DecoratingLabelProvider(rtLblProvider
,
178 viewer
.addDoubleClickListener(new ViewDoubleClickListener());
180 // viewer.setLabelProvider(rtLblProvider);
181 getSite().setSelectionProvider(viewer
);
183 // add drag & drop support
184 int operations
= DND
.DROP_COPY
| DND
.DROP_MOVE
;
185 Transfer
[] tt
= new Transfer
[] { TextTransfer
.getInstance() };
186 viewer
.addDragSupport(operations
, tt
, new ViewDragListener());
187 viewer
.addDropSupport(operations
, tt
, new ViewDropListener(viewer
));
190 MenuManager menuManager
= new MenuManager();
191 Menu menu
= menuManager
.createContextMenu(viewer
.getTree());
192 menuManager
.addMenuListener(new IMenuListener() {
193 public void menuAboutToShow(IMenuManager manager
) {
194 contextMenuAboutToShow(manager
);
197 viewer
.getTree().setMenu(menu
);
198 getSite().registerContextMenu(menuManager
, viewer
);
200 // add change listener to display TestResult information in the property
202 viewer
.addSelectionChangedListener(new MySelectionChangedListener());
206 // Detailed property viewer
207 protected TableViewer
createPropertiesViewer(Composite parent
) {
208 propertiesViewer
= new TableViewer(parent
);
209 propertiesViewer
.getTable().setLayoutData(
210 new GridData(SWT
.FILL
, SWT
.FILL
, true, true));
211 propertiesViewer
.getTable().setHeaderVisible(true);
212 propertiesViewer
.setContentProvider(new PropertiesContentProvider());
213 TableViewerColumn col
= new TableViewerColumn(propertiesViewer
,
215 col
.getColumn().setText("Name");
216 col
.getColumn().setWidth(200);
217 col
.setLabelProvider(new ColumnLabelProvider() {
218 public String
getText(Object element
) {
220 return ((Property
) element
).getName();
221 } catch (RepositoryException e
) {
222 throw new ArgeoException(
223 "Unexpected exception in label provider", e
);
227 col
= new TableViewerColumn(propertiesViewer
, SWT
.NONE
);
228 col
.getColumn().setText("Value");
229 col
.getColumn().setWidth(400);
230 col
.setLabelProvider(new ColumnLabelProvider() {
231 public String
getText(Object element
) {
233 Property property
= (Property
) element
;
234 if (property
.getType() == PropertyType
.BINARY
)
236 else if (property
.isMultiple()) {
237 StringBuffer buf
= new StringBuffer("[");
238 Value
[] values
= property
.getValues();
239 for (int i
= 0; i
< values
.length
; i
++) {
242 buf
.append(values
[i
].getString());
245 return buf
.toString();
247 return property
.getValue().getString();
248 } catch (RepositoryException e
) {
249 throw new ArgeoException(
250 "Unexpected exception in label provider", e
);
254 col
= new TableViewerColumn(propertiesViewer
, SWT
.NONE
);
255 col
.getColumn().setText("Type");
256 col
.getColumn().setWidth(200);
257 col
.setLabelProvider(new ColumnLabelProvider() {
258 public String
getText(Object element
) {
260 return PropertyType
.nameFromValue(((Property
) element
)
262 } catch (RepositoryException e
) {
263 throw new ArgeoException(
264 "Unexpected exception in label provider", e
);
268 propertiesViewer
.setInput(getViewSite());
269 return propertiesViewer
;
273 * Override to provide specific behaviour. Typically to enable the display
278 protected void processDoubleClick(DoubleClickEvent evt
) {
279 Object obj
= ((IStructuredSelection
) evt
.getSelection())
282 if (obj
instanceof SingleResultNode
) {
283 SingleResultNode srNode
= (SingleResultNode
) obj
;
284 Node node
= srNode
.getNode();
285 // FIXME: open a default result editor
286 if (node
.isNodeType(SlcTypes
.SLC_PROCESS
)) {
287 IWorkbenchPage activePage
= PlatformUI
.getWorkbench()
288 .getActiveWorkbenchWindow().getActivePage();
289 activePage
.openEditor(
290 new ProcessEditorInput(node
.getPath()),
294 } catch (Exception e
) {
295 throw new SlcException("Cannot open " + obj
, e
);
300 public void setFocus() {
304 * refreshes the passed resultParent and its corresponding subtree. It
305 * refreshes the whole viewer if null is passed.
307 * @param ResultParent
310 public void refresh(ResultParent resultParent
) {
311 if (log
.isDebugEnabled())
312 log
.debug("Refreshing '" + resultParent
+ "'...");
313 // Thread.dumpStack();
314 if (resultParent
== null) {
315 resultTreeViewer
.setInput(initializeResultTree());
317 if (resultParent
instanceof ParentNodeFolder
) {
318 ParentNodeFolder currFolder
= (ParentNodeFolder
) resultParent
;
319 jcrRefresh(currFolder
.getNode());
320 currFolder
.forceFullRefresh();
322 // FIXME: specific refresh does not work
323 // resultTreeViewer.refresh(currFolder, true);
324 TreePath
[] tps
= resultTreeViewer
.getExpandedTreePaths();
325 resultTreeViewer
.setInput(initializeResultTree());
326 resultTreeViewer
.setExpandedTreePaths(tps
);
331 * refreshes the passed node and its corresponding subtree.
337 public boolean jcrRefresh(Node node
) {
338 if (log
.isDebugEnabled())
339 log
.debug(" JCR refreshing " + node
+ "...");
340 boolean isPassed
= true;
342 if (node
.isNodeType(SlcTypes
.SLC_TEST_RESULT
)) {
343 isPassed
= node
.getNode(SlcNames
.SLC_STATUS
)
344 .getProperty(SlcNames
.SLC_SUCCESS
).getBoolean();
345 } else if (node
.isNodeType(SlcTypes
.SLC_RESULT_FOLDER
)) {
346 NodeIterator ni
= node
.getNodes();
347 // quicker but wrong : refresh will stop as soon as a failed
348 // test is found and the whole tree won't be refreshed
349 // while (isPassed && ni.hasNext()){
350 while (ni
.hasNext()) {
351 Node currChild
= ni
.nextNode();
352 isPassed
= isPassed
& jcrRefresh(currChild
);
354 if (isPassed
!= node
.getNode(SlcNames
.SLC_STATUS
)
355 .getProperty(SlcNames
.SLC_SUCCESS
).getBoolean()) {
356 node
.getNode(SlcNames
.SLC_STATUS
).setProperty(
357 SlcNames
.SLC_SUCCESS
, isPassed
);
358 node
.getSession().save();
363 } catch (RepositoryException e
) {
364 throw new SlcException("Cannot register listeners", e
);
369 private ResultParent
[] initializeResultTree() {
371 if (session
.nodeExists(SlcJcrResultUtils
372 .getSlcResultsBasePath(session
))) {
373 ResultParent
[] roots
= new ResultParent
[5];
376 roots
[0] = new ParentNodeFolder(null,
377 SlcJcrResultUtils
.getMyResultParentNode(session
),
378 SlcUiConstants
.DEFAULT_MY_RESULTS_FOLDER_LABEL
);
381 Calendar cal
= Calendar
.getInstance();
382 String relPath
= JcrUtils
.dateAsPath(cal
);
383 List
<String
> datePathes
= new ArrayList
<String
>();
384 datePathes
.add(relPath
);
385 roots
[1] = new VirtualFolder(null,
386 ResultParentUtils
.getResultsForDates(session
,
387 datePathes
), "Today");
390 cal
= Calendar
.getInstance();
391 cal
.add(Calendar
.DAY_OF_YEAR
, -1);
392 relPath
= JcrUtils
.dateAsPath(cal
);
393 datePathes
= new ArrayList
<String
>();
394 datePathes
.add(relPath
);
395 roots
[2] = new VirtualFolder(null,
396 ResultParentUtils
.getResultsForDates(session
,
397 datePathes
), "Yesterday");
400 cal
= Calendar
.getInstance();
401 datePathes
= new ArrayList
<String
>();
403 for (int i
= 0; i
< 7; i
++) {
404 cal
.add(Calendar
.DAY_OF_YEAR
, -i
);
405 relPath
= JcrUtils
.dateAsPath(cal
);
406 datePathes
.add(relPath
);
408 roots
[3] = new VirtualFolder(null,
409 ResultParentUtils
.getResultsForDates(session
,
410 datePathes
), "Last 7 days");
413 Node otherResultsPar
= session
.getNode(SlcJcrResultUtils
414 .getSlcResultsBasePath(session
));
415 roots
[4] = new ParentNodeFolder(null, otherResultsPar
,
419 // no test has yet been processed, we leave the viewer blank
421 } catch (RepositoryException re
) {
422 throw new ArgeoException(
423 "Unexpected error while initializing ResultTree.", re
);
427 // Manage context menu
429 * Defines the commands that will pop up in the context menu.
431 protected void contextMenuAboutToShow(IMenuManager menuManager
) {
432 IWorkbenchWindow window
= ClientUiPlugin
.getDefault().getWorkbench()
433 .getActiveWorkbenchWindow();
435 // Building conditions
436 IStructuredSelection selection
= (IStructuredSelection
) resultTreeViewer
438 boolean canAddSubfolder
= false;
439 boolean isSingleResultNode
= false;
440 if (selection
.size() == 1) {
441 Object obj
= selection
.getFirstElement();
443 // if (obj instanceof ResultFolder
444 // && (((ResultFolder) obj).getNode())
445 // .isNodeType(SlcTypes.SLC_RESULT_FOLDER))
447 canAddSubfolder
= true;
448 else if (obj
instanceof SingleResultNode
)
449 isSingleResultNode
= true;
450 else if (obj
instanceof ParentNodeFolder
451 && (((ParentNodeFolder
) obj
).getNode().getPath()
452 .startsWith(SlcJcrResultUtils
453 .getMyResultsBasePath(session
))))
454 canAddSubfolder
= true;
456 } catch (RepositoryException re
) {
457 throw new SlcException(
458 "unexpected error while building condition for context menu",
463 CommandUtils
.refreshCommand(menuManager
, window
, AddResultFolder
.ID
,
464 AddResultFolder
.DEFAULT_LABEL
,
465 ClientUiPlugin
.getDefault().getWorkbench().getSharedImages()
466 .getImageDescriptor(ISharedImages
.IMG_OBJ_ADD
),
469 CommandUtils
.refreshCommand(menuManager
, window
, RenameResultFolder
.ID
,
470 RenameResultFolder
.DEFAULT_LABEL
,
471 RenameResultFolder
.DEFAULT_IMG_DESCRIPTOR
, canAddSubfolder
);
473 CommandUtils
.refreshCommand(menuManager
, window
, RenameResultNode
.ID
,
474 RenameResultNode
.DEFAULT_LABEL
,
475 RenameResultNode
.DEFAULT_IMG_DESCRIPTOR
, isSingleResultNode
);
479 class ViewDragListener
implements DragSourceListener
{
481 public void dragStart(DragSourceEvent event
) {
482 // Check if the drag action should start.
483 IStructuredSelection selection
= (IStructuredSelection
) resultTreeViewer
485 boolean doIt
= false;
486 // only one node at a time for the time being.
487 if (selection
.size() == 1) {
489 Object obj
= selection
.getFirstElement();
490 if (obj
instanceof SingleResultNode
) {
491 Node tNode
= ((SingleResultNode
) obj
).getNode();
492 if (tNode
.getPrimaryNodeType().isNodeType(
493 SlcTypes
.SLC_TEST_RESULT
)) {
495 isResultFolder
= false;
497 } else if (obj
instanceof ResultFolder
) {
498 Node tNode
= ((ResultFolder
) obj
).getNode();
499 if (tNode
.getPrimaryNodeType().isNodeType(
500 SlcTypes
.SLC_RESULT_FOLDER
)) {
502 isResultFolder
= true;
505 } catch (RepositoryException re
) {
506 throw new SlcException(
507 "unexpected error while validating drag source", re
);
513 public void dragSetData(DragSourceEvent event
) {
514 IStructuredSelection selection
= (IStructuredSelection
) resultTreeViewer
516 Object obj
= selection
.getFirstElement();
519 if (obj
instanceof SingleResultNode
) {
520 first
= ((SingleResultNode
) obj
).getNode();
521 event
.data
= first
.getIdentifier();
522 } else if (obj
instanceof ResultFolder
) {
523 first
= ((ResultFolder
) obj
).getNode();
524 event
.data
= first
.getIdentifier();
526 } catch (RepositoryException re
) {
527 throw new SlcException("unexpected error while setting data",
532 public void dragFinished(DragSourceEvent event
) {
533 // refresh is done via observer
537 // Implementation of the Drop Listener
538 protected class ViewDropListener
extends ViewerDropAdapter
{
539 private Node targetParentNode
= null;
541 public ViewDropListener(Viewer viewer
) {
546 public boolean validateDrop(Object target
, int operation
,
547 TransferData transferType
) {
549 boolean validDrop
= false;
551 // We can only drop under myResults
553 if (target
instanceof ResultFolder
) {
554 tpNode
= ((ResultFolder
) target
).getNode();
555 } else if (target
instanceof ParentNodeFolder
) {
556 if ((((ParentNodeFolder
) target
).getNode().getPath()
557 .startsWith(SlcJcrResultUtils
558 .getMyResultsBasePath(session
))))
559 tpNode
= ((ParentNodeFolder
) target
).getNode();
560 } else if (target
instanceof SingleResultNode
) {
561 Node currNode
= ((SingleResultNode
) target
).getNode();
567 .getMyResultsBasePath(session
)))
568 tpNode
= currNode
.getParent();
571 if (tpNode
!= null) {
572 // Sanity check : we cannot move a folder to one of its sub
575 if (isResultFolder
) {
576 Node source
= ((ParentNodeFolder
) lastSelectedSourceElement
)
578 String sourcePath
= source
.getPath();
579 String targetPath
= tpNode
.getPath();
580 if (targetPath
.startsWith(sourcePath
))
584 targetParentNode
= tpNode
;
586 lastSelectedTargetElement
= (ResultParent
) target
;
590 } catch (RepositoryException re
) {
591 throw new SlcException(
592 "unexpected error while validating drop target", re
);
598 public boolean performDrop(Object data
) {
599 // clear selection to prevent unwanted scrolling of the UI
600 resultTreeViewer
.setSelection(null);
602 Node source
= session
.getNodeByIdentifier((String
) data
);
604 // Check is a node with same name already exists at destination
606 if (source
.hasProperty(Property
.JCR_TITLE
))
607 name
= source
.getProperty(Property
.JCR_TITLE
).getString();
608 else if (source
.hasProperty(SlcNames
.SLC_TEST_CASE
))
609 name
= source
.getProperty(SlcNames
.SLC_TEST_CASE
)
612 name
= source
.getName();
614 if (targetParentNode
.hasNode(name
)) {
615 ConfirmOverwriteWizard wizard
= new ConfirmOverwriteWizard(
616 name
, targetParentNode
);
617 WizardDialog dialog
= new WizardDialog(Display
.getDefault()
618 .getActiveShell(), wizard
);
620 if (dialog
.open() == WizardDialog
.CANCEL
)
623 if (wizard
.overwrite()) {
624 targetParentNode
.getNode(name
).remove();
627 name
= wizard
.newName();
631 if (!isActionUnderMyResult
) {// Copy
632 target
= targetParentNode
.addNode(name
, source
633 .getPrimaryNodeType().getName());
634 JcrUtils
.copy(source
, target
);
636 String sourcePath
= source
.getPath();
637 String destPath
= targetParentNode
.getPath() + "/" + name
;
638 session
.move(sourcePath
, destPath
);
640 target
= session
.getNode(destPath
);
642 if (!target
.isNodeType(NodeType
.MIX_TITLE
))
643 target
.addMixin(NodeType
.MIX_TITLE
);
644 target
.setProperty(Property
.JCR_TITLE
, name
);
646 .updatePassedStatus(target
,
647 target
.getNode(SlcNames
.SLC_STATUS
)
648 .getProperty(SlcNames
.SLC_SUCCESS
)
651 } catch (RepositoryException re
) {
652 throw new SlcException(
653 "unexpected error while copying dropped node", re
);
659 class ResultObserver
extends AsyncUiEventListener
{
661 public ResultObserver(Display display
) {
666 protected Boolean
willProcessInUiThread(List
<Event
> events
)
667 throws RepositoryException
{
668 // unfiltered for the time being
672 protected void onEventInUiThread(List
<Event
> events
)
673 throws RepositoryException
{
676 for (Event event
: events
) {
678 // if (log.isDebugEnabled())
679 // log.debug("Received event " + event);
680 int eventType
= event
.getType();
681 if (eventType
== Event
.NODE_REMOVED
) {
682 String path
= event
.getPath();
683 String parPath
= JcrUtils
.parentPath(path
);
684 if (session
.nodeExists(parPath
)) {
685 Node currNode
= session
.getNode(parPath
);
686 if (currNode
.isNodeType(NodeType
.NT_UNSTRUCTURED
)) {
687 // jcrRefresh(currNode);
688 refresh(lastSelectedSourceElementParent
);
691 } else if (eventType
== Event
.NODE_ADDED
) {
692 // refresh(lastSelectedTargetElement);
693 String path
= event
.getPath();
694 if (session
.nodeExists(path
)) {
695 Node currNode
= session
.getNode(path
);
696 if (currNode
.isNodeType(SlcTypes
.SLC_TEST_RESULT
)
698 .isNodeType(SlcTypes
.SLC_RESULT_FOLDER
)) {
699 refresh(lastSelectedTargetElement
);
700 // resultTreeViewer.expandToLevel(
701 // lastSelectedTargetElement, 1);
706 if (log
.isDebugEnabled())
707 log
.debug("treated events: " + i
);
711 class PropertiesContentProvider
implements IStructuredContentProvider
{
713 public void dispose() {
716 public void inputChanged(Viewer viewer
, Object oldInput
, Object newInput
) {
719 public Object
[] getElements(Object inputElement
) {
721 if (inputElement
instanceof Node
) {
722 List
<Property
> props
= new ArrayList
<Property
>();
723 PropertyIterator pit
= ((Node
) inputElement
)
725 while (pit
.hasNext())
726 props
.add(pit
.nextProperty());
727 return props
.toArray();
729 return new Object
[] {};
730 } catch (RepositoryException e
) {
731 throw new ArgeoException("Cannot get element for "
737 class MySelectionChangedListener
implements ISelectionChangedListener
{
739 public void selectionChanged(SelectionChangedEvent event
) {
740 if (!event
.getSelection().isEmpty()) {
741 IStructuredSelection sel
= (IStructuredSelection
) event
743 ResultParent firstItem
= (ResultParent
) sel
.getFirstElement();
744 if (firstItem
instanceof SingleResultNode
)
745 propertiesViewer
.setInput(((SingleResultNode
) firstItem
)
748 propertiesViewer
.setInput(null);
749 // update cache for Drag & drop
750 lastSelectedTargetElement
= firstItem
;
751 lastSelectedSourceElement
= firstItem
;
752 lastSelectedSourceElementParent
= (ResultParent
) firstItem
757 if (firstItem
instanceof ParentNodeFolder
)
758 pPath
= ((ParentNodeFolder
) firstItem
).getNode()
760 else if (firstItem
instanceof SingleResultNode
)
761 pPath
= ((SingleResultNode
) firstItem
).getNode()
763 } catch (RepositoryException e
) {
764 throw new SlcException(
765 "Unexpected error while checking parent UI tree", e
);
767 if ((pPath
.startsWith(SlcJcrResultUtils
768 .getMyResultsBasePath(session
))))
769 isActionUnderMyResult
= true;
771 isActionUnderMyResult
= false;
776 class ViewDoubleClickListener
implements IDoubleClickListener
{
777 public void doubleClick(DoubleClickEvent evt
) {
778 processDoubleClick(evt
);
783 /* DEPENDENCY INJECTION */
784 public void setSession(Session session
) {
785 this.session
= session
;