2 * Copyright (C) 2007-2012 Argeo GmbH
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 package org
.argeo
.slc
.client
.ui
.views
;
18 import java
.util
.ArrayList
;
19 import java
.util
.Calendar
;
20 import java
.util
.List
;
22 import javax
.jcr
.Node
;
23 import javax
.jcr
.NodeIterator
;
24 import javax
.jcr
.Property
;
25 import javax
.jcr
.PropertyIterator
;
26 import javax
.jcr
.PropertyType
;
27 import javax
.jcr
.RepositoryException
;
28 import javax
.jcr
.Session
;
29 import javax
.jcr
.Value
;
30 import javax
.jcr
.nodetype
.NodeType
;
31 import javax
.jcr
.observation
.Event
;
32 import javax
.jcr
.observation
.EventListener
;
33 import javax
.jcr
.observation
.ObservationManager
;
35 import org
.apache
.commons
.logging
.Log
;
36 import org
.apache
.commons
.logging
.LogFactory
;
37 import org
.argeo
.ArgeoException
;
38 import org
.argeo
.eclipse
.ui
.jcr
.AsyncUiEventListener
;
39 import org
.argeo
.eclipse
.ui
.utils
.CommandUtils
;
40 import org
.argeo
.jcr
.JcrUtils
;
41 import org
.argeo
.jcr
.UserJcrUtils
;
42 import org
.argeo
.slc
.SlcException
;
43 import org
.argeo
.slc
.client
.ui
.ClientUiPlugin
;
44 import org
.argeo
.slc
.client
.ui
.SlcUiConstants
;
45 import org
.argeo
.slc
.client
.ui
.commands
.AddResultFolder
;
46 import org
.argeo
.slc
.client
.ui
.commands
.RenameResultFolder
;
47 import org
.argeo
.slc
.client
.ui
.commands
.RenameResultNode
;
48 import org
.argeo
.slc
.client
.ui
.editors
.ProcessEditor
;
49 import org
.argeo
.slc
.client
.ui
.editors
.ProcessEditorInput
;
50 import org
.argeo
.slc
.client
.ui
.model
.ParentNodeFolder
;
51 import org
.argeo
.slc
.client
.ui
.model
.ResultFolder
;
52 import org
.argeo
.slc
.client
.ui
.model
.ResultParent
;
53 import org
.argeo
.slc
.client
.ui
.model
.ResultParentUtils
;
54 import org
.argeo
.slc
.client
.ui
.model
.SingleResultNode
;
55 import org
.argeo
.slc
.client
.ui
.model
.VirtualFolder
;
56 import org
.argeo
.slc
.client
.ui
.providers
.ResultTreeContentProvider
;
57 import org
.argeo
.slc
.client
.ui
.providers
.ResultTreeLabelProvider
;
58 import org
.argeo
.slc
.client
.ui
.wizards
.ConfirmOverwriteWizard
;
59 import org
.argeo
.slc
.jcr
.SlcJcrResultUtils
;
60 import org
.argeo
.slc
.jcr
.SlcNames
;
61 import org
.argeo
.slc
.jcr
.SlcTypes
;
62 import org
.eclipse
.jface
.action
.IMenuListener
;
63 import org
.eclipse
.jface
.action
.IMenuManager
;
64 import org
.eclipse
.jface
.action
.MenuManager
;
65 import org
.eclipse
.jface
.viewers
.ColumnLabelProvider
;
66 import org
.eclipse
.jface
.viewers
.DecoratingLabelProvider
;
67 import org
.eclipse
.jface
.viewers
.DoubleClickEvent
;
68 import org
.eclipse
.jface
.viewers
.IDoubleClickListener
;
69 import org
.eclipse
.jface
.viewers
.ILabelDecorator
;
70 import org
.eclipse
.jface
.viewers
.ISelectionChangedListener
;
71 import org
.eclipse
.jface
.viewers
.IStructuredContentProvider
;
72 import org
.eclipse
.jface
.viewers
.IStructuredSelection
;
73 import org
.eclipse
.jface
.viewers
.SelectionChangedEvent
;
74 import org
.eclipse
.jface
.viewers
.TableViewer
;
75 import org
.eclipse
.jface
.viewers
.TableViewerColumn
;
76 import org
.eclipse
.jface
.viewers
.TreePath
;
77 import org
.eclipse
.jface
.viewers
.TreeViewer
;
78 import org
.eclipse
.jface
.viewers
.Viewer
;
79 import org
.eclipse
.jface
.viewers
.ViewerDropAdapter
;
80 import org
.eclipse
.jface
.wizard
.WizardDialog
;
81 import org
.eclipse
.swt
.SWT
;
82 import org
.eclipse
.swt
.custom
.SashForm
;
83 import org
.eclipse
.swt
.dnd
.DND
;
84 import org
.eclipse
.swt
.dnd
.DragSourceEvent
;
85 import org
.eclipse
.swt
.dnd
.DragSourceListener
;
86 import org
.eclipse
.swt
.dnd
.TextTransfer
;
87 import org
.eclipse
.swt
.dnd
.Transfer
;
88 import org
.eclipse
.swt
.dnd
.TransferData
;
89 import org
.eclipse
.swt
.layout
.FillLayout
;
90 import org
.eclipse
.swt
.layout
.GridData
;
91 import org
.eclipse
.swt
.layout
.GridLayout
;
92 import org
.eclipse
.swt
.widgets
.Composite
;
93 import org
.eclipse
.swt
.widgets
.Display
;
94 import org
.eclipse
.swt
.widgets
.Menu
;
95 import org
.eclipse
.ui
.ISharedImages
;
96 import org
.eclipse
.ui
.IWorkbenchPage
;
97 import org
.eclipse
.ui
.IWorkbenchWindow
;
98 import org
.eclipse
.ui
.PlatformUI
;
99 import org
.eclipse
.ui
.part
.ViewPart
;
101 /** SLC generic JCR Result tree view. */
102 public class JcrResultTreeView
extends ViewPart
{
103 public final static String ID
= ClientUiPlugin
.ID
+ ".jcrResultTreeView";
105 private final static Log log
= LogFactory
.getLog(JcrResultTreeView
.class);
107 /* DEPENDENCY INJECTION */
108 private Session session
;
111 private TreeViewer resultTreeViewer
;
112 private TableViewer propertiesViewer
;
114 private EventListener resultsObserver
= null;
116 private final static String
[] observedNodeTypes
= {
117 SlcTypes
.SLC_TEST_RESULT
, SlcTypes
.SLC_RESULT_FOLDER
,
118 NodeType
.NT_UNSTRUCTURED
};
120 // FIXME cache to ease D&D
121 private boolean isActionUnderMyResult
= false;
122 private ResultParent lastSelectedTargetElement
;
123 private ResultParent lastSelectedSourceElement
;
124 private ResultParent lastSelectedSourceElementParent
;
125 private boolean isResultFolder
= false;
127 // FIXME we cache the fact that we are moving a node to avoid exception
128 // triggered by the "Add Node" event while moving
129 // boolean isMoveInProgress = false;
132 * To be overridden to adapt size of form and result frames.
134 protected int[] getWeights() {
135 return new int[] { 70, 30 };
139 public void createPartControl(Composite parent
) {
140 parent
.setLayout(new FillLayout());
142 SashForm sashForm
= new SashForm(parent
, SWT
.VERTICAL
);
143 sashForm
.setSashWidth(4);
144 sashForm
.setLayout(new FillLayout());
146 // Create the tree on top of the view
147 Composite top
= new Composite(sashForm
, SWT
.NONE
);
148 GridLayout gl
= new GridLayout(1, false);
150 resultTreeViewer
= createResultsTreeViewer(top
);
152 // Create the property viewer on the bottom
153 Composite bottom
= new Composite(sashForm
, SWT
.NONE
);
154 bottom
.setLayout(new GridLayout(1, false));
155 propertiesViewer
= createPropertiesViewer(bottom
);
157 sashForm
.setWeights(getWeights());
159 resultTreeViewer
.setInput(initializeResultTree());
160 // Initialize observer
162 ObservationManager observationManager
= session
.getWorkspace()
163 .getObservationManager();
164 resultsObserver
= new ResultObserver(resultTreeViewer
.getTree()
166 observationManager
.addEventListener(resultsObserver
,
167 Event
.NODE_MOVED
| Event
.NODE_ADDED
| Event
.NODE_REMOVED
,
168 UserJcrUtils
.getUserHome(session
).getPath(), true, null,
169 observedNodeTypes
, false);
170 } catch (RepositoryException e
) {
171 throw new SlcException("Cannot register listeners", e
);
175 // The main tree viewer
176 protected TreeViewer
createResultsTreeViewer(Composite parent
) {
177 int style
= SWT
.BORDER
| SWT
.MULTI
;
179 TreeViewer viewer
= new TreeViewer(parent
, style
);
180 viewer
.getTree().setLayoutData(
181 new GridData(SWT
.FILL
, SWT
.FILL
, true, true));
183 viewer
.setContentProvider(new ResultTreeContentProvider());
185 // Add label provider with label decorator
186 ResultTreeLabelProvider rtLblProvider
= new ResultTreeLabelProvider();
187 ILabelDecorator decorator
= ClientUiPlugin
.getDefault().getWorkbench()
188 .getDecoratorManager().getLabelDecorator();
189 viewer
.setLabelProvider(new DecoratingLabelProvider(rtLblProvider
,
191 viewer
.addDoubleClickListener(new ViewDoubleClickListener());
193 // viewer.setLabelProvider(rtLblProvider);
194 getSite().setSelectionProvider(viewer
);
196 // add drag & drop support
197 int operations
= DND
.DROP_COPY
| DND
.DROP_MOVE
;
198 Transfer
[] tt
= new Transfer
[] { TextTransfer
.getInstance() };
199 viewer
.addDragSupport(operations
, tt
, new ViewDragListener());
200 viewer
.addDropSupport(operations
, tt
, new ViewDropListener(viewer
));
203 MenuManager menuManager
= new MenuManager();
204 Menu menu
= menuManager
.createContextMenu(viewer
.getTree());
205 menuManager
.addMenuListener(new IMenuListener() {
206 public void menuAboutToShow(IMenuManager manager
) {
207 contextMenuAboutToShow(manager
);
210 viewer
.getTree().setMenu(menu
);
211 getSite().registerContextMenu(menuManager
, viewer
);
213 // add change listener to display TestResult information in the property
215 viewer
.addSelectionChangedListener(new MySelectionChangedListener());
219 // Detailed property viewer
220 protected TableViewer
createPropertiesViewer(Composite parent
) {
221 propertiesViewer
= new TableViewer(parent
);
222 propertiesViewer
.getTable().setLayoutData(
223 new GridData(SWT
.FILL
, SWT
.FILL
, true, true));
224 propertiesViewer
.getTable().setHeaderVisible(true);
225 propertiesViewer
.setContentProvider(new PropertiesContentProvider());
226 TableViewerColumn col
= new TableViewerColumn(propertiesViewer
,
228 col
.getColumn().setText("Name");
229 col
.getColumn().setWidth(200);
230 col
.setLabelProvider(new ColumnLabelProvider() {
231 public String
getText(Object element
) {
233 return ((Property
) element
).getName();
234 } catch (RepositoryException e
) {
235 throw new ArgeoException(
236 "Unexpected exception in label provider", e
);
240 col
= new TableViewerColumn(propertiesViewer
, SWT
.NONE
);
241 col
.getColumn().setText("Value");
242 col
.getColumn().setWidth(400);
243 col
.setLabelProvider(new ColumnLabelProvider() {
244 public String
getText(Object element
) {
246 Property property
= (Property
) element
;
247 if (property
.getType() == PropertyType
.BINARY
)
249 else if (property
.isMultiple()) {
250 StringBuffer buf
= new StringBuffer("[");
251 Value
[] values
= property
.getValues();
252 for (int i
= 0; i
< values
.length
; i
++) {
255 buf
.append(values
[i
].getString());
258 return buf
.toString();
260 return property
.getValue().getString();
261 } catch (RepositoryException e
) {
262 throw new ArgeoException(
263 "Unexpected exception in label provider", e
);
267 col
= new TableViewerColumn(propertiesViewer
, SWT
.NONE
);
268 col
.getColumn().setText("Type");
269 col
.getColumn().setWidth(200);
270 col
.setLabelProvider(new ColumnLabelProvider() {
271 public String
getText(Object element
) {
273 return PropertyType
.nameFromValue(((Property
) element
)
275 } catch (RepositoryException e
) {
276 throw new ArgeoException(
277 "Unexpected exception in label provider", e
);
281 propertiesViewer
.setInput(getViewSite());
282 return propertiesViewer
;
286 * Override to provide specific behaviour. Typically to enable the display
291 protected void processDoubleClick(DoubleClickEvent evt
) {
292 Object obj
= ((IStructuredSelection
) evt
.getSelection())
295 if (obj
instanceof SingleResultNode
) {
296 SingleResultNode srNode
= (SingleResultNode
) obj
;
297 Node node
= srNode
.getNode();
298 // FIXME: open a default result editor
299 if (node
.isNodeType(SlcTypes
.SLC_PROCESS
)) {
300 IWorkbenchPage activePage
= PlatformUI
.getWorkbench()
301 .getActiveWorkbenchWindow().getActivePage();
302 activePage
.openEditor(
303 new ProcessEditorInput(node
.getPath()),
307 } catch (Exception e
) {
308 throw new SlcException("Cannot open " + obj
, e
);
313 public void setFocus() {
317 * refreshes the passed resultParent and its corresponding subtree. It
318 * refreshes the whole viewer if null is passed.
320 * @param ResultParent
323 public void refresh(ResultParent resultParent
) {
324 // if (log.isDebugEnabled())
325 // log.debug("Refreshing '" + resultParent + "'...");
326 // Thread.dumpStack();
327 if (resultParent
== null) {
328 resultTreeViewer
.setInput(initializeResultTree());
330 if (resultParent
instanceof ParentNodeFolder
) {
331 ParentNodeFolder currFolder
= (ParentNodeFolder
) resultParent
;
332 jcrRefresh(currFolder
.getNode());
333 currFolder
.forceFullRefresh();
335 // FIXME: specific refresh does not work
336 // resultTreeViewer.refresh(currFolder, true);
337 TreePath
[] tps
= resultTreeViewer
.getExpandedTreePaths();
338 resultTreeViewer
.setInput(initializeResultTree());
339 resultTreeViewer
.setExpandedTreePaths(tps
);
344 * refreshes the passed node and its corresponding subtree.
350 public boolean jcrRefresh(Node node
) {
351 // if (log.isDebugEnabled())
352 // log.debug(" JCR refreshing " + node + "...");
353 // Thread.dumpStack();
354 boolean isPassed
= true;
356 if (node
.isNodeType(SlcTypes
.SLC_TEST_RESULT
)) {
357 isPassed
= node
.getNode(SlcNames
.SLC_STATUS
)
358 .getProperty(SlcNames
.SLC_SUCCESS
).getBoolean();
359 } else if (node
.isNodeType(SlcTypes
.SLC_RESULT_FOLDER
)) {
360 NodeIterator ni
= node
.getNodes();
361 // quicker but wrong : refresh will stop as soon as a failed
362 // test is found and the whole tree won't be refreshed
363 // while (isPassed && ni.hasNext()){
364 while (ni
.hasNext()) {
365 Node currChild
= ni
.nextNode();
366 isPassed
= isPassed
& jcrRefresh(currChild
);
368 if (isPassed
!= node
.getNode(SlcNames
.SLC_STATUS
)
369 .getProperty(SlcNames
.SLC_SUCCESS
).getBoolean()) {
370 node
.getNode(SlcNames
.SLC_STATUS
).setProperty(
371 SlcNames
.SLC_SUCCESS
, isPassed
);
372 node
.getSession().save();
377 } catch (RepositoryException e
) {
378 throw new SlcException("Cannot register listeners", e
);
383 private ResultParent
[] initializeResultTree() {
385 // Force initialization of the tree structure if needed
386 SlcJcrResultUtils
.getSlcResultsParentNode(session
);
387 SlcJcrResultUtils
.getMyResultParentNode(session
);
388 // Remove yesterday and last 7 days virtual folders
389 // ResultParent[] roots = new ResultParent[5];
390 ResultParent
[] roots
= new ResultParent
[3];
393 roots
[0] = new ParentNodeFolder(null,
394 SlcJcrResultUtils
.getMyResultParentNode(session
),
395 SlcUiConstants
.DEFAULT_MY_RESULTS_FOLDER_LABEL
);
398 Calendar cal
= Calendar
.getInstance();
399 String relPath
= JcrUtils
.dateAsPath(cal
);
400 List
<String
> datePathes
= new ArrayList
<String
>();
401 datePathes
.add(relPath
);
402 roots
[1] = new VirtualFolder(null,
403 ResultParentUtils
.getResultsForDates(session
, datePathes
),
407 // cal = Calendar.getInstance();
408 // cal.add(Calendar.DAY_OF_YEAR, -1);
409 // relPath = JcrUtils.dateAsPath(cal);
410 // datePathes = new ArrayList<String>();
411 // datePathes.add(relPath);
412 // roots[2] = new VirtualFolder(null,
413 // ResultParentUtils.getResultsForDates(session, datePathes),
417 // cal = Calendar.getInstance();
418 // datePathes = new ArrayList<String>();
420 // for (int i = 0; i < 7; i++) {
421 // cal.add(Calendar.DAY_OF_YEAR, -i);
422 // relPath = JcrUtils.dateAsPath(cal);
423 // datePathes.add(relPath);
425 // roots[3] = new VirtualFolder(null,
426 // ResultParentUtils.getResultsForDates(session, datePathes),
430 Node otherResultsPar
= session
.getNode(SlcJcrResultUtils
431 .getSlcResultsBasePath(session
));
432 // roots[4] = new ParentNodeFolder(null, otherResultsPar,
434 roots
[2] = new ParentNodeFolder(null, otherResultsPar
,
437 } catch (RepositoryException re
) {
438 throw new ArgeoException(
439 "Unexpected error while initializing ResultTree.", re
);
443 // Manage context menu
445 * Defines the commands that will pop up in the context menu.
447 protected void contextMenuAboutToShow(IMenuManager menuManager
) {
448 IWorkbenchWindow window
= ClientUiPlugin
.getDefault().getWorkbench()
449 .getActiveWorkbenchWindow();
451 IStructuredSelection selection
= (IStructuredSelection
) resultTreeViewer
453 boolean canAddSubfolder
= false;
454 boolean canRenamefolder
= false;
455 boolean isSingleResultNode
= false;
456 // Building conditions
457 if (selection
.size() == 1) {
458 Object obj
= selection
.getFirstElement();
460 if (obj
instanceof SingleResultNode
)
461 isSingleResultNode
= true;
462 else if (obj
instanceof ParentNodeFolder
) {
463 Node cNode
= ((ParentNodeFolder
) obj
).getNode();
464 if (cNode
.isNodeType(SlcTypes
.SLC_RESULT_FOLDER
)) {
465 canAddSubfolder
= true;
466 canRenamefolder
= true;
468 .isNodeType(SlcTypes
.SLC_MY_RESULT_ROOT_FOLDER
)) {
469 canAddSubfolder
= true;
472 } catch (RepositoryException re
) {
473 throw new SlcException(
474 "unexpected error while building condition for context menu",
479 CommandUtils
.refreshCommand(menuManager
, window
, AddResultFolder
.ID
,
480 AddResultFolder
.DEFAULT_LABEL
,
481 ClientUiPlugin
.getDefault().getWorkbench().getSharedImages()
482 .getImageDescriptor(ISharedImages
.IMG_OBJ_ADD
),
485 CommandUtils
.refreshCommand(menuManager
, window
, RenameResultFolder
.ID
,
486 RenameResultFolder
.DEFAULT_LABEL
,
487 RenameResultFolder
.DEFAULT_IMG_DESCRIPTOR
, canRenamefolder
);
489 CommandUtils
.refreshCommand(menuManager
, window
, RenameResultNode
.ID
,
490 RenameResultNode
.DEFAULT_LABEL
,
491 RenameResultNode
.DEFAULT_IMG_DESCRIPTOR
, isSingleResultNode
);
495 class ViewDragListener
implements DragSourceListener
{
497 public void dragStart(DragSourceEvent event
) {
498 // Check if the drag action should start.
499 IStructuredSelection selection
= (IStructuredSelection
) resultTreeViewer
501 boolean doIt
= false;
502 // only one node at a time for the time being.
503 if (selection
.size() == 1) {
505 Object obj
= selection
.getFirstElement();
506 if (obj
instanceof SingleResultNode
) {
507 Node tNode
= ((SingleResultNode
) obj
).getNode();
508 if (tNode
.getPrimaryNodeType().isNodeType(
509 SlcTypes
.SLC_TEST_RESULT
)) {
511 isResultFolder
= false;
513 } else if (obj
instanceof ResultFolder
) {
514 Node tNode
= ((ResultFolder
) obj
).getNode();
515 if (tNode
.getPrimaryNodeType().isNodeType(
516 SlcTypes
.SLC_RESULT_FOLDER
)) {
518 isResultFolder
= true;
521 } catch (RepositoryException re
) {
522 throw new SlcException(
523 "unexpected error while validating drag source", re
);
529 public void dragSetData(DragSourceEvent event
) {
530 IStructuredSelection selection
= (IStructuredSelection
) resultTreeViewer
532 Object obj
= selection
.getFirstElement();
535 if (obj
instanceof SingleResultNode
) {
536 first
= ((SingleResultNode
) obj
).getNode();
537 event
.data
= first
.getIdentifier();
538 } else if (obj
instanceof ResultFolder
) {
539 first
= ((ResultFolder
) obj
).getNode();
540 event
.data
= first
.getIdentifier();
542 } catch (RepositoryException re
) {
543 throw new SlcException("unexpected error while setting data",
548 public void dragFinished(DragSourceEvent event
) {
549 // refresh is done via observer
553 // Implementation of the Drop Listener
554 protected class ViewDropListener
extends ViewerDropAdapter
{
555 private Node targetParentNode
= null;
557 public ViewDropListener(Viewer viewer
) {
562 public boolean validateDrop(Object target
, int operation
,
563 TransferData transferType
) {
564 boolean validDrop
= false;
566 // We can only drop under myResults
568 if (target
instanceof SingleResultNode
) {
569 Node currNode
= ((SingleResultNode
) target
).getNode();
570 String pPath
= currNode
.getParent().getPath();
571 if (pPath
.startsWith(SlcJcrResultUtils
572 .getMyResultsBasePath(session
)))
573 tpNode
= currNode
.getParent();
574 } else if (target
instanceof ResultFolder
) {
575 tpNode
= ((ResultFolder
) target
).getNode();
576 } else if (target
instanceof ParentNodeFolder
) {
577 Node node
= ((ParentNodeFolder
) target
).getNode();
578 if (node
.isNodeType(SlcTypes
.SLC_MY_RESULT_ROOT_FOLDER
))
579 tpNode
= ((ParentNodeFolder
) target
).getNode();
582 if (tpNode
!= null) {
583 // Sanity check : we cannot move a folder to one of its sub
584 // folder or neither move an object in the same parent
588 if (isResultFolder
) {
589 source
= ((ParentNodeFolder
) lastSelectedSourceElement
)
591 if (tpNode
.getPath().startsWith(source
.getPath()))
593 } else if (lastSelectedSourceElement
instanceof SingleResultNode
) {
594 source
= ((SingleResultNode
) lastSelectedSourceElement
)
596 String sourceParentPath
= JcrUtils
.parentPath(source
598 if (tpNode
.getPath().equals(sourceParentPath
))
602 targetParentNode
= tpNode
;
604 lastSelectedTargetElement
= (ResultParent
) target
;
607 } catch (RepositoryException re
) {
608 throw new SlcException(
609 "unexpected error while validating drop target", re
);
615 public boolean performDrop(Object data
) {
616 // clear selection to prevent unwanted scrolling of the UI
617 resultTreeViewer
.setSelection(null);
619 Node source
= session
.getNodeByIdentifier((String
) data
);
621 // Check is a node with same name already exists at destination
623 if (source
.hasProperty(Property
.JCR_TITLE
))
624 name
= source
.getProperty(Property
.JCR_TITLE
).getString();
625 else if (source
.hasProperty(SlcNames
.SLC_TEST_CASE
))
626 name
= source
.getProperty(SlcNames
.SLC_TEST_CASE
)
629 name
= source
.getName();
631 if (targetParentNode
.hasNode(name
)) {
632 ConfirmOverwriteWizard wizard
= new ConfirmOverwriteWizard(
633 name
, targetParentNode
);
634 WizardDialog dialog
= new WizardDialog(Display
.getDefault()
635 .getActiveShell(), wizard
);
637 if (dialog
.open() == WizardDialog
.CANCEL
)
640 if (wizard
.overwrite()) {
641 targetParentNode
.getNode(name
).remove();
644 name
= wizard
.newName();
648 if (!isActionUnderMyResult
) {// Copy
649 target
= targetParentNode
.addNode(name
, source
650 .getPrimaryNodeType().getName());
651 JcrUtils
.copy(source
, target
);
653 String sourcePath
= source
.getPath();
654 String destPath
= targetParentNode
.getPath() + "/" + name
;
655 session
.move(sourcePath
, destPath
);
657 target
= session
.getNode(destPath
);
659 if (!target
.isNodeType(NodeType
.MIX_TITLE
))
660 target
.addMixin(NodeType
.MIX_TITLE
);
661 target
.setProperty(Property
.JCR_TITLE
, name
);
663 .updatePassedStatus(target
,
664 target
.getNode(SlcNames
.SLC_STATUS
)
665 .getProperty(SlcNames
.SLC_SUCCESS
)
668 } catch (RepositoryException re
) {
669 throw new SlcException(
670 "unexpected error while copying dropped node", re
);
676 class ResultObserver
extends AsyncUiEventListener
{
678 public ResultObserver(Display display
) {
683 protected Boolean
willProcessInUiThread(List
<Event
> events
)
684 throws RepositoryException
{
685 // unfiltered for the time being
689 protected void onEventInUiThread(List
<Event
> events
)
690 throws RepositoryException
{
691 refresh(lastSelectedSourceElementParent
);
693 // boolean wasRemoved = false;
694 // boolean wasAdded = false;
696 // for (Event event : events) {
697 // // if (log.isDebugEnabled())
698 // // log.debug("Received event " + event);
699 // int eventType = event.getType();
700 // if (eventType == Event.NODE_REMOVED) {
701 // String path = event.getPath();
702 // String parPath = JcrUtils.parentPath(path);
703 // if (session.nodeExists(parPath)) {
704 // Node currNode = session.getNode(parPath);
705 // if (currNode.isNodeType(NodeType.NT_UNSTRUCTURED)) {
706 // // jcrRefresh(currNode);
707 // wasRemoved = true;
710 // } else if (eventType == Event.NODE_ADDED) {
711 // // refresh(lastSelectedTargetElement);
712 // String path = event.getPath();
713 // if (session.nodeExists(path)) {
714 // Node currNode = session.getNode(path);
715 // if (currNode.isNodeType(SlcTypes.SLC_TEST_RESULT)
717 // .isNodeType(SlcTypes.SLC_RESULT_FOLDER)) {
718 // // refresh(lastSelectedTargetElement);
720 // // resultTreeViewer.expandToLevel(
721 // // lastSelectedTargetElement, 1);
726 // if (wasRemoved || wasAdded)
727 // refresh(lastSelectedSourceElementParent);
731 class PropertiesContentProvider
implements IStructuredContentProvider
{
733 public void dispose() {
736 public void inputChanged(Viewer viewer
, Object oldInput
, Object newInput
) {
739 public Object
[] getElements(Object inputElement
) {
741 if (inputElement
instanceof Node
) {
742 List
<Property
> props
= new ArrayList
<Property
>();
743 PropertyIterator pit
= ((Node
) inputElement
)
745 while (pit
.hasNext())
746 props
.add(pit
.nextProperty());
747 return props
.toArray();
749 return new Object
[] {};
750 } catch (RepositoryException e
) {
751 throw new ArgeoException("Cannot get element for "
757 class MySelectionChangedListener
implements ISelectionChangedListener
{
759 public void selectionChanged(SelectionChangedEvent event
) {
760 if (!event
.getSelection().isEmpty()) {
761 IStructuredSelection sel
= (IStructuredSelection
) event
763 ResultParent firstItem
= (ResultParent
) sel
.getFirstElement();
764 if (firstItem
instanceof SingleResultNode
)
765 propertiesViewer
.setInput(((SingleResultNode
) firstItem
)
768 propertiesViewer
.setInput(null);
769 // update cache for Drag & drop
770 lastSelectedTargetElement
= firstItem
;
771 lastSelectedSourceElement
= firstItem
;
772 lastSelectedSourceElementParent
= (ResultParent
) firstItem
777 if (firstItem
instanceof ParentNodeFolder
)
778 pPath
= ((ParentNodeFolder
) firstItem
).getNode()
780 else if (firstItem
instanceof SingleResultNode
)
781 pPath
= ((SingleResultNode
) firstItem
).getNode()
783 } catch (RepositoryException e
) {
784 throw new SlcException(
785 "Unexpected error while checking parent UI tree", e
);
787 if ((pPath
.startsWith(SlcJcrResultUtils
788 .getMyResultsBasePath(session
))))
789 isActionUnderMyResult
= true;
791 isActionUnderMyResult
= false;
796 class ViewDoubleClickListener
implements IDoubleClickListener
{
797 public void doubleClick(DoubleClickEvent evt
) {
798 processDoubleClick(evt
);
803 /* DEPENDENCY INJECTION */
804 public void setSession(Session session
) {
805 this.session
= session
;