]> git.argeo.org Git - gpl/argeo-slc.git/blob - plugins/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/views/JcrResultTreeView.java
+ Fix some bugs on ResultTree Observer
[gpl/argeo-slc.git] / plugins / org.argeo.slc.client.ui / src / main / java / org / argeo / slc / client / ui / views / JcrResultTreeView.java
1 package org.argeo.slc.client.ui.views;
2
3 import java.util.ArrayList;
4 import java.util.Calendar;
5 import java.util.List;
6
7 import javax.jcr.Node;
8 import javax.jcr.NodeIterator;
9 import javax.jcr.Property;
10 import javax.jcr.PropertyIterator;
11 import javax.jcr.PropertyType;
12 import javax.jcr.RepositoryException;
13 import javax.jcr.Session;
14 import javax.jcr.Value;
15 import javax.jcr.nodetype.NodeType;
16 import javax.jcr.observation.Event;
17 import javax.jcr.observation.EventListener;
18 import javax.jcr.observation.ObservationManager;
19
20 import org.apache.commons.logging.Log;
21 import org.apache.commons.logging.LogFactory;
22 import org.argeo.ArgeoException;
23 import org.argeo.eclipse.ui.jcr.AsyncUiEventListener;
24 import org.argeo.eclipse.ui.utils.CommandUtils;
25 import org.argeo.jcr.JcrUtils;
26 import org.argeo.jcr.UserJcrUtils;
27 import org.argeo.slc.SlcException;
28 import org.argeo.slc.client.ui.ClientUiPlugin;
29 import org.argeo.slc.client.ui.SlcUiConstants;
30 import org.argeo.slc.client.ui.commands.AddResultFolder;
31 import org.argeo.slc.client.ui.commands.RenameResultFolder;
32 import org.argeo.slc.client.ui.commands.RenameResultNode;
33 import org.argeo.slc.client.ui.editors.ProcessEditor;
34 import org.argeo.slc.client.ui.editors.ProcessEditorInput;
35 import org.argeo.slc.client.ui.model.ParentNodeFolder;
36 import org.argeo.slc.client.ui.model.ResultFolder;
37 import org.argeo.slc.client.ui.model.ResultParent;
38 import org.argeo.slc.client.ui.model.ResultParentUtils;
39 import org.argeo.slc.client.ui.model.SingleResultNode;
40 import org.argeo.slc.client.ui.model.VirtualFolder;
41 import org.argeo.slc.client.ui.providers.ResultTreeContentProvider;
42 import org.argeo.slc.client.ui.providers.ResultTreeLabelProvider;
43 import org.argeo.slc.client.ui.wizards.ConfirmOverwriteWizard;
44 import org.argeo.slc.jcr.SlcJcrResultUtils;
45 import org.argeo.slc.jcr.SlcNames;
46 import org.argeo.slc.jcr.SlcTypes;
47 import org.eclipse.jface.action.IMenuListener;
48 import org.eclipse.jface.action.IMenuManager;
49 import org.eclipse.jface.action.MenuManager;
50 import org.eclipse.jface.viewers.ColumnLabelProvider;
51 import org.eclipse.jface.viewers.DecoratingLabelProvider;
52 import org.eclipse.jface.viewers.DoubleClickEvent;
53 import org.eclipse.jface.viewers.IDoubleClickListener;
54 import org.eclipse.jface.viewers.ILabelDecorator;
55 import org.eclipse.jface.viewers.ISelectionChangedListener;
56 import org.eclipse.jface.viewers.IStructuredContentProvider;
57 import org.eclipse.jface.viewers.IStructuredSelection;
58 import org.eclipse.jface.viewers.SelectionChangedEvent;
59 import org.eclipse.jface.viewers.TableViewer;
60 import org.eclipse.jface.viewers.TableViewerColumn;
61 import org.eclipse.jface.viewers.TreePath;
62 import org.eclipse.jface.viewers.TreeViewer;
63 import org.eclipse.jface.viewers.Viewer;
64 import org.eclipse.jface.viewers.ViewerDropAdapter;
65 import org.eclipse.jface.wizard.WizardDialog;
66 import org.eclipse.swt.SWT;
67 import org.eclipse.swt.custom.SashForm;
68 import org.eclipse.swt.dnd.DND;
69 import org.eclipse.swt.dnd.DragSourceEvent;
70 import org.eclipse.swt.dnd.DragSourceListener;
71 import org.eclipse.swt.dnd.TextTransfer;
72 import org.eclipse.swt.dnd.Transfer;
73 import org.eclipse.swt.dnd.TransferData;
74 import org.eclipse.swt.layout.FillLayout;
75 import org.eclipse.swt.layout.GridData;
76 import org.eclipse.swt.layout.GridLayout;
77 import org.eclipse.swt.widgets.Composite;
78 import org.eclipse.swt.widgets.Display;
79 import org.eclipse.swt.widgets.Menu;
80 import org.eclipse.ui.ISharedImages;
81 import org.eclipse.ui.IWorkbenchPage;
82 import org.eclipse.ui.IWorkbenchWindow;
83 import org.eclipse.ui.PlatformUI;
84 import org.eclipse.ui.part.ViewPart;
85
86 /** SLC generic JCR Result tree view. */
87 public class JcrResultTreeView extends ViewPart {
88 public final static String ID = ClientUiPlugin.ID + ".jcrResultTreeView";
89
90 private final static Log log = LogFactory.getLog(JcrResultTreeView.class);
91
92 /* DEPENDENCY INJECTION */
93 private Session session;
94
95 // This page widgets
96 private TreeViewer resultTreeViewer;
97 private TableViewer propertiesViewer;
98
99 private EventListener resultsObserver = null;
100
101 private final static String[] observedNodeTypes = {
102 SlcTypes.SLC_TEST_RESULT, SlcTypes.SLC_RESULT_FOLDER,
103 NodeType.NT_UNSTRUCTURED };
104
105 // FIXME cache to ease D&D
106 private boolean isActionUnderMyResult = false;
107 private ResultParent lastSelectedTargetElement;
108 private ResultParent lastSelectedSourceElement;
109 private ResultParent lastSelectedSourceElementParent;
110 private boolean isResultFolder = false;
111
112 // FIXME we cache the fact that we are moving a node to avoid exception
113 // triggered by the "Add Node" event while moving
114 // boolean isMoveInProgress = false;
115
116 /**
117 * To be overridden to adapt size of form and result frames.
118 */
119 protected int[] getWeights() {
120 return new int[] { 70, 30 };
121 }
122
123 @Override
124 public void createPartControl(Composite parent) {
125 parent.setLayout(new FillLayout());
126 // Main layout
127 SashForm sashForm = new SashForm(parent, SWT.VERTICAL);
128 sashForm.setSashWidth(4);
129 sashForm.setLayout(new FillLayout());
130
131 // Create the tree on top of the view
132 Composite top = new Composite(sashForm, SWT.NONE);
133 GridLayout gl = new GridLayout(1, false);
134 top.setLayout(gl);
135 resultTreeViewer = createResultsTreeViewer(top);
136
137 // Create the property viewer on the bottom
138 Composite bottom = new Composite(sashForm, SWT.NONE);
139 bottom.setLayout(new GridLayout(1, false));
140 propertiesViewer = createPropertiesViewer(bottom);
141
142 sashForm.setWeights(getWeights());
143
144 resultTreeViewer.setInput(initializeResultTree());
145 // Initialize observer
146 try {
147 ObservationManager observationManager = session.getWorkspace()
148 .getObservationManager();
149 resultsObserver = new ResultObserver(resultTreeViewer.getTree()
150 .getDisplay());
151 observationManager.addEventListener(resultsObserver,
152 Event.NODE_MOVED | Event.NODE_ADDED | Event.NODE_REMOVED,
153 UserJcrUtils.getUserHome(session).getPath(), true, null,
154 observedNodeTypes, false);
155 } catch (RepositoryException e) {
156 throw new SlcException("Cannot register listeners", e);
157 }
158 }
159
160 // The main tree viewer
161 protected TreeViewer createResultsTreeViewer(Composite parent) {
162 int style = SWT.BORDER | SWT.MULTI;
163
164 TreeViewer viewer = new TreeViewer(parent, style);
165 viewer.getTree().setLayoutData(
166 new GridData(SWT.FILL, SWT.FILL, true, true));
167
168 viewer.setContentProvider(new ResultTreeContentProvider());
169
170 // Add label provider with label decorator
171 ResultTreeLabelProvider rtLblProvider = new ResultTreeLabelProvider();
172 ILabelDecorator decorator = ClientUiPlugin.getDefault().getWorkbench()
173 .getDecoratorManager().getLabelDecorator();
174 viewer.setLabelProvider(new DecoratingLabelProvider(rtLblProvider,
175 decorator));
176 viewer.addDoubleClickListener(new ViewDoubleClickListener());
177
178 // viewer.setLabelProvider(rtLblProvider);
179 getSite().setSelectionProvider(viewer);
180
181 // add drag & drop support
182 int operations = DND.DROP_COPY | DND.DROP_MOVE;
183 Transfer[] tt = new Transfer[] { TextTransfer.getInstance() };
184 viewer.addDragSupport(operations, tt, new ViewDragListener());
185 viewer.addDropSupport(operations, tt, new ViewDropListener(viewer));
186
187 // add context menu
188 MenuManager menuManager = new MenuManager();
189 Menu menu = menuManager.createContextMenu(viewer.getTree());
190 menuManager.addMenuListener(new IMenuListener() {
191 public void menuAboutToShow(IMenuManager manager) {
192 contextMenuAboutToShow(manager);
193 }
194 });
195 viewer.getTree().setMenu(menu);
196 getSite().registerContextMenu(menuManager, viewer);
197
198 // add change listener to display TestResult information in the property
199 // viewer
200 viewer.addSelectionChangedListener(new MySelectionChangedListener());
201 return viewer;
202 }
203
204 // Detailed property viewer
205 protected TableViewer createPropertiesViewer(Composite parent) {
206 propertiesViewer = new TableViewer(parent);
207 propertiesViewer.getTable().setLayoutData(
208 new GridData(SWT.FILL, SWT.FILL, true, true));
209 propertiesViewer.getTable().setHeaderVisible(true);
210 propertiesViewer.setContentProvider(new PropertiesContentProvider());
211 TableViewerColumn col = new TableViewerColumn(propertiesViewer,
212 SWT.NONE);
213 col.getColumn().setText("Name");
214 col.getColumn().setWidth(200);
215 col.setLabelProvider(new ColumnLabelProvider() {
216 public String getText(Object element) {
217 try {
218 return ((Property) element).getName();
219 } catch (RepositoryException e) {
220 throw new ArgeoException(
221 "Unexpected exception in label provider", e);
222 }
223 }
224 });
225 col = new TableViewerColumn(propertiesViewer, SWT.NONE);
226 col.getColumn().setText("Value");
227 col.getColumn().setWidth(400);
228 col.setLabelProvider(new ColumnLabelProvider() {
229 public String getText(Object element) {
230 try {
231 Property property = (Property) element;
232 if (property.getType() == PropertyType.BINARY)
233 return "<binary>";
234 else if (property.isMultiple()) {
235 StringBuffer buf = new StringBuffer("[");
236 Value[] values = property.getValues();
237 for (int i = 0; i < values.length; i++) {
238 if (i != 0)
239 buf.append(", ");
240 buf.append(values[i].getString());
241 }
242 buf.append(']');
243 return buf.toString();
244 } else
245 return property.getValue().getString();
246 } catch (RepositoryException e) {
247 throw new ArgeoException(
248 "Unexpected exception in label provider", e);
249 }
250 }
251 });
252 col = new TableViewerColumn(propertiesViewer, SWT.NONE);
253 col.getColumn().setText("Type");
254 col.getColumn().setWidth(200);
255 col.setLabelProvider(new ColumnLabelProvider() {
256 public String getText(Object element) {
257 try {
258 return PropertyType.nameFromValue(((Property) element)
259 .getType());
260 } catch (RepositoryException e) {
261 throw new ArgeoException(
262 "Unexpected exception in label provider", e);
263 }
264 }
265 });
266 propertiesViewer.setInput(getViewSite());
267 return propertiesViewer;
268 }
269
270 /**
271 * Override to provide specific behaviour. Typically to enable the display
272 * of a result file.
273 *
274 * @param evt
275 */
276 protected void processDoubleClick(DoubleClickEvent evt) {
277 Object obj = ((IStructuredSelection) evt.getSelection())
278 .getFirstElement();
279 try {
280 if (obj instanceof SingleResultNode) {
281 SingleResultNode srNode = (SingleResultNode) obj;
282 Node node = srNode.getNode();
283 // FIXME: open a default result editor
284 if (node.isNodeType(SlcTypes.SLC_PROCESS)) {
285 IWorkbenchPage activePage = PlatformUI.getWorkbench()
286 .getActiveWorkbenchWindow().getActivePage();
287 activePage.openEditor(
288 new ProcessEditorInput(node.getPath()),
289 ProcessEditor.ID);
290 }
291 }
292 } catch (Exception e) {
293 throw new SlcException("Cannot open " + obj, e);
294 }
295 }
296
297 @Override
298 public void setFocus() {
299 }
300
301 /**
302 * refreshes the passed resultParent and its corresponding subtree. It
303 * refreshes the whole viewer if null is passed.
304 *
305 * @param ResultParent
306 *
307 */
308 public void refresh(ResultParent resultParent) {
309 // if (log.isDebugEnabled())
310 // log.debug("Refreshing '" + resultParent + "'...");
311 // Thread.dumpStack();
312 if (resultParent == null) {
313 resultTreeViewer.setInput(initializeResultTree());
314 } else {
315 if (resultParent instanceof ParentNodeFolder) {
316 ParentNodeFolder currFolder = (ParentNodeFolder) resultParent;
317 jcrRefresh(currFolder.getNode());
318 currFolder.forceFullRefresh();
319 }
320 // FIXME: specific refresh does not work
321 // resultTreeViewer.refresh(currFolder, true);
322 TreePath[] tps = resultTreeViewer.getExpandedTreePaths();
323 resultTreeViewer.setInput(initializeResultTree());
324 resultTreeViewer.setExpandedTreePaths(tps);
325 }
326 }
327
328 /**
329 * refreshes the passed node and its corresponding subtree.
330 *
331 * @param node
332 * cannot be null
333 *
334 */
335 public boolean jcrRefresh(Node node) {
336 // if (log.isDebugEnabled())
337 // log.debug(" JCR refreshing " + node + "...");
338 // Thread.dumpStack();
339 boolean isPassed = true;
340 try {
341 if (node.isNodeType(SlcTypes.SLC_TEST_RESULT)) {
342 isPassed = node.getNode(SlcNames.SLC_STATUS)
343 .getProperty(SlcNames.SLC_SUCCESS).getBoolean();
344 } else if (node.isNodeType(SlcTypes.SLC_RESULT_FOLDER)) {
345 NodeIterator ni = node.getNodes();
346 // quicker but wrong : refresh will stop as soon as a failed
347 // test is found and the whole tree won't be refreshed
348 // while (isPassed && ni.hasNext()){
349 while (ni.hasNext()) {
350 Node currChild = ni.nextNode();
351 isPassed = isPassed & jcrRefresh(currChild);
352 }
353 if (isPassed != node.getNode(SlcNames.SLC_STATUS)
354 .getProperty(SlcNames.SLC_SUCCESS).getBoolean()) {
355 node.getNode(SlcNames.SLC_STATUS).setProperty(
356 SlcNames.SLC_SUCCESS, isPassed);
357 node.getSession().save();
358 return isPassed;
359 }
360 } else
361 ; // do nothing
362 } catch (RepositoryException e) {
363 throw new SlcException("Cannot register listeners", e);
364 }
365 return isPassed;
366 }
367
368 private ResultParent[] initializeResultTree() {
369 try {
370 // Force initialization of the tree structure if needed
371 SlcJcrResultUtils.getSlcResultsParentNode(session);
372 SlcJcrResultUtils.getMyResultParentNode(session);
373 ResultParent[] roots = new ResultParent[5];
374
375 // My results
376 roots[0] = new ParentNodeFolder(null,
377 SlcJcrResultUtils.getMyResultParentNode(session),
378 SlcUiConstants.DEFAULT_MY_RESULTS_FOLDER_LABEL);
379
380 // today
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, datePathes),
387 "Today");
388
389 // Yesterday
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, datePathes),
397 "Yesterday");
398 // Last 7 days
399
400 cal = Calendar.getInstance();
401 datePathes = new ArrayList<String>();
402
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);
407 }
408 roots[3] = new VirtualFolder(null,
409 ResultParentUtils.getResultsForDates(session, datePathes),
410 "Last 7 days");
411
412 // All results
413 Node otherResultsPar = session.getNode(SlcJcrResultUtils
414 .getSlcResultsBasePath(session));
415 roots[4] = new ParentNodeFolder(null, otherResultsPar,
416 "All results");
417 return roots;
418 } catch (RepositoryException re) {
419 throw new ArgeoException(
420 "Unexpected error while initializing ResultTree.", re);
421 }
422 }
423
424 // Manage context menu
425 /**
426 * Defines the commands that will pop up in the context menu.
427 **/
428 protected void contextMenuAboutToShow(IMenuManager menuManager) {
429 IWorkbenchWindow window = ClientUiPlugin.getDefault().getWorkbench()
430 .getActiveWorkbenchWindow();
431
432 IStructuredSelection selection = (IStructuredSelection) resultTreeViewer
433 .getSelection();
434 boolean canAddSubfolder = false;
435 boolean canRenamefolder = false;
436 boolean isSingleResultNode = false;
437 // Building conditions
438 if (selection.size() == 1) {
439 Object obj = selection.getFirstElement();
440 try {
441 if (obj instanceof SingleResultNode)
442 isSingleResultNode = true;
443 else if (obj instanceof ParentNodeFolder) {
444 Node cNode = ((ParentNodeFolder) obj).getNode();
445 if (cNode.isNodeType(SlcTypes.SLC_RESULT_FOLDER)) {
446 canAddSubfolder = true;
447 canRenamefolder = true;
448 } else if (cNode
449 .isNodeType(SlcTypes.SLC_MY_RESULT_ROOT_FOLDER)) {
450 canAddSubfolder = true;
451 }
452 }
453 } catch (RepositoryException re) {
454 throw new SlcException(
455 "unexpected error while building condition for context menu",
456 re);
457 }
458 }
459 // Effective Refresh
460 CommandUtils.refreshCommand(menuManager, window, AddResultFolder.ID,
461 AddResultFolder.DEFAULT_LABEL,
462 ClientUiPlugin.getDefault().getWorkbench().getSharedImages()
463 .getImageDescriptor(ISharedImages.IMG_OBJ_ADD),
464 canAddSubfolder);
465
466 CommandUtils.refreshCommand(menuManager, window, RenameResultFolder.ID,
467 RenameResultFolder.DEFAULT_LABEL,
468 RenameResultFolder.DEFAULT_IMG_DESCRIPTOR, canRenamefolder);
469
470 CommandUtils.refreshCommand(menuManager, window, RenameResultNode.ID,
471 RenameResultNode.DEFAULT_LABEL,
472 RenameResultNode.DEFAULT_IMG_DESCRIPTOR, isSingleResultNode);
473 }
474
475 /* INNER CLASSES */
476 class ViewDragListener implements DragSourceListener {
477
478 public void dragStart(DragSourceEvent event) {
479 // Check if the drag action should start.
480 IStructuredSelection selection = (IStructuredSelection) resultTreeViewer
481 .getSelection();
482 boolean doIt = false;
483 // only one node at a time for the time being.
484 if (selection.size() == 1) {
485 try {
486 Object obj = selection.getFirstElement();
487 if (obj instanceof SingleResultNode) {
488 Node tNode = ((SingleResultNode) obj).getNode();
489 if (tNode.getPrimaryNodeType().isNodeType(
490 SlcTypes.SLC_TEST_RESULT)) {
491 doIt = true;
492 isResultFolder = false;
493 }
494 } else if (obj instanceof ResultFolder) {
495 Node tNode = ((ResultFolder) obj).getNode();
496 if (tNode.getPrimaryNodeType().isNodeType(
497 SlcTypes.SLC_RESULT_FOLDER)) {
498 doIt = true;
499 isResultFolder = true;
500 }
501 }
502 } catch (RepositoryException re) {
503 throw new SlcException(
504 "unexpected error while validating drag source", re);
505 }
506 }
507 event.doit = doIt;
508 }
509
510 public void dragSetData(DragSourceEvent event) {
511 IStructuredSelection selection = (IStructuredSelection) resultTreeViewer
512 .getSelection();
513 Object obj = selection.getFirstElement();
514 try {
515 Node first;
516 if (obj instanceof SingleResultNode) {
517 first = ((SingleResultNode) obj).getNode();
518 event.data = first.getIdentifier();
519 } else if (obj instanceof ResultFolder) {
520 first = ((ResultFolder) obj).getNode();
521 event.data = first.getIdentifier();
522 }
523 } catch (RepositoryException re) {
524 throw new SlcException("unexpected error while setting data",
525 re);
526 }
527 }
528
529 public void dragFinished(DragSourceEvent event) {
530 // refresh is done via observer
531 }
532 }
533
534 // Implementation of the Drop Listener
535 protected class ViewDropListener extends ViewerDropAdapter {
536 private Node targetParentNode = null;
537
538 public ViewDropListener(Viewer viewer) {
539 super(viewer);
540 }
541
542 @Override
543 public boolean validateDrop(Object target, int operation,
544 TransferData transferType) {
545 boolean validDrop = false;
546 try {
547 // We can only drop under myResults
548 Node tpNode = null;
549 if (target instanceof SingleResultNode) {
550 Node currNode = ((SingleResultNode) target).getNode();
551 String pPath = currNode.getParent().getPath();
552 if (pPath.startsWith(SlcJcrResultUtils
553 .getMyResultsBasePath(session)))
554 tpNode = currNode.getParent();
555 } else if (target instanceof ResultFolder) {
556 tpNode = ((ResultFolder) target).getNode();
557 } else if (target instanceof ParentNodeFolder) {
558 Node node = ((ParentNodeFolder) target).getNode();
559 if (node.isNodeType(SlcTypes.SLC_MY_RESULT_ROOT_FOLDER))
560 tpNode = ((ParentNodeFolder) target).getNode();
561 }
562
563 if (tpNode != null) {
564 // Sanity check : we cannot move a folder to one of its sub
565 // folder or neither move an object in the same parent
566 // folder
567 boolean doit = true;
568 Node source = null;
569 if (isResultFolder) {
570 source = ((ParentNodeFolder) lastSelectedSourceElement)
571 .getNode();
572 if (tpNode.getPath().startsWith(source.getPath()))
573 doit = false;
574 } else if (lastSelectedSourceElement instanceof SingleResultNode) {
575 source = ((SingleResultNode) lastSelectedSourceElement)
576 .getNode();
577 String sourceParentPath = JcrUtils.parentPath(source
578 .getPath());
579 if (tpNode.getPath().equals(sourceParentPath))
580 doit = false;
581 }
582 if (doit) {
583 targetParentNode = tpNode;
584 validDrop = true;
585 lastSelectedTargetElement = (ResultParent) target;
586 }
587 }
588 } catch (RepositoryException re) {
589 throw new SlcException(
590 "unexpected error while validating drop target", re);
591 }
592 return validDrop;
593 }
594
595 @Override
596 public boolean performDrop(Object data) {
597 // clear selection to prevent unwanted scrolling of the UI
598 resultTreeViewer.setSelection(null);
599 try {
600 Node source = session.getNodeByIdentifier((String) data);
601
602 // Check is a node with same name already exists at destination
603 String name;
604 if (source.hasProperty(Property.JCR_TITLE))
605 name = source.getProperty(Property.JCR_TITLE).getString();
606 else if (source.hasProperty(SlcNames.SLC_TEST_CASE))
607 name = source.getProperty(SlcNames.SLC_TEST_CASE)
608 .getString();
609 else
610 name = source.getName();
611
612 if (targetParentNode.hasNode(name)) {
613 ConfirmOverwriteWizard wizard = new ConfirmOverwriteWizard(
614 name, targetParentNode);
615 WizardDialog dialog = new WizardDialog(Display.getDefault()
616 .getActiveShell(), wizard);
617
618 if (dialog.open() == WizardDialog.CANCEL)
619 return true;
620
621 if (wizard.overwrite()) {
622 targetParentNode.getNode(name).remove();
623 // session.save();
624 } else
625 name = wizard.newName();
626 }
627
628 Node target;
629 if (!isActionUnderMyResult) {// Copy
630 target = targetParentNode.addNode(name, source
631 .getPrimaryNodeType().getName());
632 JcrUtils.copy(source, target);
633 } else {// move
634 String sourcePath = source.getPath();
635 String destPath = targetParentNode.getPath() + "/" + name;
636 session.move(sourcePath, destPath);
637 // session.save();
638 target = session.getNode(destPath);
639 }
640 if (!target.isNodeType(NodeType.MIX_TITLE))
641 target.addMixin(NodeType.MIX_TITLE);
642 target.setProperty(Property.JCR_TITLE, name);
643 ResultParentUtils
644 .updatePassedStatus(target,
645 target.getNode(SlcNames.SLC_STATUS)
646 .getProperty(SlcNames.SLC_SUCCESS)
647 .getBoolean());
648 session.save();
649 } catch (RepositoryException re) {
650 throw new SlcException(
651 "unexpected error while copying dropped node", re);
652 }
653 return true;
654 }
655 }
656
657 class ResultObserver extends AsyncUiEventListener {
658
659 public ResultObserver(Display display) {
660 super(display);
661 }
662
663 @Override
664 protected Boolean willProcessInUiThread(List<Event> events)
665 throws RepositoryException {
666 // unfiltered for the time being
667 return true;
668 }
669
670 protected void onEventInUiThread(List<Event> events)
671 throws RepositoryException {
672 refresh(lastSelectedSourceElementParent);
673
674 // boolean wasRemoved = false;
675 // boolean wasAdded = false;
676 //
677 // 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 // wasRemoved = true;
689 // }
690 // }
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)
697 // || currNode
698 // .isNodeType(SlcTypes.SLC_RESULT_FOLDER)) {
699 // // refresh(lastSelectedTargetElement);
700 // wasAdded = true;
701 // // resultTreeViewer.expandToLevel(
702 // // lastSelectedTargetElement, 1);
703 // }
704 // }
705 // }
706 // }
707 // if (wasRemoved || wasAdded)
708 // refresh(lastSelectedSourceElementParent);
709 }
710 }
711
712 class PropertiesContentProvider implements IStructuredContentProvider {
713
714 public void dispose() {
715 }
716
717 public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
718 }
719
720 public Object[] getElements(Object inputElement) {
721 try {
722 if (inputElement instanceof Node) {
723 List<Property> props = new ArrayList<Property>();
724 PropertyIterator pit = ((Node) inputElement)
725 .getProperties();
726 while (pit.hasNext())
727 props.add(pit.nextProperty());
728 return props.toArray();
729 }
730 return new Object[] {};
731 } catch (RepositoryException e) {
732 throw new ArgeoException("Cannot get element for "
733 + inputElement, e);
734 }
735 }
736 }
737
738 class MySelectionChangedListener implements ISelectionChangedListener {
739
740 public void selectionChanged(SelectionChangedEvent event) {
741 if (!event.getSelection().isEmpty()) {
742 IStructuredSelection sel = (IStructuredSelection) event
743 .getSelection();
744 ResultParent firstItem = (ResultParent) sel.getFirstElement();
745 if (firstItem instanceof SingleResultNode)
746 propertiesViewer.setInput(((SingleResultNode) firstItem)
747 .getNode());
748 else
749 propertiesViewer.setInput(null);
750 // update cache for Drag & drop
751 lastSelectedTargetElement = firstItem;
752 lastSelectedSourceElement = firstItem;
753 lastSelectedSourceElementParent = (ResultParent) firstItem
754 .getParent();
755 String pPath = "";
756 try {
757
758 if (firstItem instanceof ParentNodeFolder)
759 pPath = ((ParentNodeFolder) firstItem).getNode()
760 .getPath();
761 else if (firstItem instanceof SingleResultNode)
762 pPath = ((SingleResultNode) firstItem).getNode()
763 .getPath();
764 } catch (RepositoryException e) {
765 throw new SlcException(
766 "Unexpected error while checking parent UI tree", e);
767 }
768 if ((pPath.startsWith(SlcJcrResultUtils
769 .getMyResultsBasePath(session))))
770 isActionUnderMyResult = true;
771 else
772 isActionUnderMyResult = false;
773 }
774 }
775 }
776
777 class ViewDoubleClickListener implements IDoubleClickListener {
778 public void doubleClick(DoubleClickEvent evt) {
779 processDoubleClick(evt);
780 }
781
782 }
783
784 /* DEPENDENCY INJECTION */
785 public void setSession(Session session) {
786 this.session = session;
787 }
788
789 }