enhance result tree viewer
authorBruno Sinou <bsinou@argeo.org>
Wed, 7 Nov 2012 23:57:05 +0000 (23:57 +0000)
committerBruno Sinou <bsinou@argeo.org>
Wed, 7 Nov 2012 23:57:05 +0000 (23:57 +0000)
git-svn-id: https://svn.argeo.org/slc/trunk@5739 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc

16 files changed:
plugins/org.argeo.slc.client.ui/icons/rename.png [new file with mode: 0644]
plugins/org.argeo.slc.client.ui/plugin.xml
plugins/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/SlcImages.java
plugins/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/commands/AddResultFolder.java
plugins/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/commands/DeleteResult.java
plugins/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/commands/RenameResultFolder.java [new file with mode: 0644]
plugins/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/commands/RenameResultNode.java [new file with mode: 0644]
plugins/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/decorators/ResultFailedDecorator.java
plugins/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/model/ParentNodeFolder.java
plugins/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/model/ResultFolder.java
plugins/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/model/ResultParent.java
plugins/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/model/ResultParentUtils.java
plugins/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/model/SingleResultNode.java
plugins/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/providers/ResultTreeLabelProvider.java
plugins/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/views/JcrResultTreeView.java
plugins/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/wizards/ConfirmOverwriteWizard.java [new file with mode: 0644]

diff --git a/plugins/org.argeo.slc.client.ui/icons/rename.png b/plugins/org.argeo.slc.client.ui/icons/rename.png
new file mode 100644 (file)
index 0000000..a388417
Binary files /dev/null and b/plugins/org.argeo.slc.client.ui/icons/rename.png differ
index e77f45899a0aec2f70bd19090d18b10d213a77c8..85f5bf4b501e9c5921bb7498d757d00968e3697e 100644 (file)
                id="org.argeo.slc.client.ui.addResultFolder"
                name="Add result folder">
            </command>
+           <command
+               defaultHandler="org.argeo.slc.client.ui.commands.RenameResultFolder"
+               id="org.argeo.slc.client.ui.renameResultFolder"
+               name="Rename folder">
+           </command>
+           <command
+               defaultHandler="org.argeo.slc.client.ui.commands.RenameResultNode"
+               id="org.argeo.slc.client.ui.renameResultNode"
+               name="Rename result">
+           </command>
            <command
                defaultHandler="org.argeo.slc.client.ui.commands.RefreshJcrResultTreeView"
                id="org.argeo.slc.client.ui.refreshJcrResultTreeView"
index 053c1fa2e18dcf380232e55c8a0d420adfd830cf..a76b78d2041eba93a4daa9b623674572a9f25114 100644 (file)
@@ -27,6 +27,7 @@ public class SlcImages {
        public final static Image MODULE_STOPPED = img("icons/module_stopped.gif");
        public final static Image FOLDER = img("icons/folder.gif");
        public final static Image MY_RESULTS_FOLDER = img("icons/myResult.png");
+       public final static Image RENAME = img("icons/rename.png");
        public final static Image FLOW = img("icons/flow.png");
        public final static Image PROCESSES = img("icons/processes.gif");
        public final static Image PASSED = img("icons/passed.gif");
index dc61fc47786f1da0efbe2a63abfc8ed74d6dbc3c..540a30b05a640deb20ae756c5c433683beb2e9d3 100644 (file)
@@ -51,10 +51,8 @@ public class AddResultFolder extends AbstractHandler {
                // menu.
                if (selection != null && selection.size() == 1) {
                        Object obj = selection.getFirstElement();
-
                        try {
                                Node parentNode = null;
-
                                if (obj instanceof ResultFolder) {
                                        ResultFolder rf = (ResultFolder) obj;
                                        parentNode = rf.getNode();
index 012985c3afed763ed6eff9c1b3390c4175f99eb6..5e4636870dcb1f02886f5e4773980b18dc8dfc7b 100644 (file)
@@ -55,7 +55,6 @@ public class DeleteResult extends AbstractHandler {
                Iterator<?> lst = ((IStructuredSelection) selection).iterator();\r
                while (lst.hasNext()) {\r
                        Object obj = lst.next();\r
-\r
                        if (obj instanceof ResultParent) {\r
                                ResultParent rp = ((ResultParent) obj);\r
                                buf.append(rp.getName()).append(", ");\r
diff --git a/plugins/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/commands/RenameResultFolder.java b/plugins/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/commands/RenameResultFolder.java
new file mode 100644 (file)
index 0000000..739c503
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2007-2012 Mathieu Baudier
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.argeo.slc.client.ui.commands;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+
+import org.argeo.eclipse.ui.dialogs.SingleValue;
+import org.argeo.jcr.JcrUtils;
+import org.argeo.slc.SlcException;
+import org.argeo.slc.client.ui.ClientUiPlugin;
+import org.argeo.slc.client.ui.model.ResultFolder;
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.ui.handlers.HandlerUtil;
+
+/**
+ * Rename a node of type SlcType.SLC_RESULT_FOLDER by moving it.
+ */
+
+public class RenameResultFolder extends AbstractHandler {
+       public final static String ID = ClientUiPlugin.ID + ".renameResultFolder";
+       public final static ImageDescriptor DEFAULT_IMG_DESCRIPTOR = ClientUiPlugin
+                       .getImageDescriptor("icons/rename.png");
+       public final static String DEFAULT_LABEL = "Rename folder";
+
+       public Object execute(ExecutionEvent event) throws ExecutionException {
+               IStructuredSelection selection = (IStructuredSelection) HandlerUtil
+                               .getActiveWorkbenchWindow(event).getActivePage().getSelection();
+
+               // Sanity check, already done when populating the corresponding popup
+               // menu.
+               if (selection != null && selection.size() == 1) {
+                       Object obj = selection.getFirstElement();
+                       try {
+                               if (obj instanceof ResultFolder) {
+                                       ResultFolder rf = (ResultFolder) obj;
+                                       Node sourceNode = rf.getNode();
+                                       String folderName = SingleValue.ask("Rename folder",
+                                                       "Enter a new folder name");
+                                       if (folderName != null) {
+                                               String sourcePath = sourceNode.getPath();
+                                               String targetPath = JcrUtils.parentPath(sourcePath)
+                                                               + "/" + folderName;
+                                               Session session = sourceNode.getSession();
+                                               session.move(sourcePath, targetPath);
+                                               session.save();
+                                       }
+                               }
+                       } catch (RepositoryException e) {
+                               throw new SlcException(
+                                               "Unexpected exception while refactoring result folder",
+                                               e);
+                       }
+               }
+               return null;
+       }
+}
\ No newline at end of file
diff --git a/plugins/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/commands/RenameResultNode.java b/plugins/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/commands/RenameResultNode.java
new file mode 100644 (file)
index 0000000..86cbed5
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2007-2012 Mathieu Baudier
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.argeo.slc.client.ui.commands;
+
+import javax.jcr.Node;
+import javax.jcr.Property;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+
+import org.argeo.eclipse.ui.dialogs.SingleValue;
+import org.argeo.jcr.JcrUtils;
+import org.argeo.slc.SlcException;
+import org.argeo.slc.client.ui.ClientUiPlugin;
+import org.argeo.slc.client.ui.model.SingleResultNode;
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.handlers.HandlerUtil;
+
+/**
+ * Rename a node of type SlcType.SLC_RESULT_FOLDER by moving it.
+ */
+
+public class RenameResultNode extends AbstractHandler {
+       public final static String ID = ClientUiPlugin.ID + ".renameResultNode";
+       public final static ImageDescriptor DEFAULT_IMG_DESCRIPTOR = ClientUiPlugin
+                       .getImageDescriptor("icons/rename.png");
+       public final static String DEFAULT_LABEL = "Rename result";
+
+       public Object execute(ExecutionEvent event) throws ExecutionException {
+               IStructuredSelection selection = (IStructuredSelection) HandlerUtil
+                               .getActiveWorkbenchWindow(event).getActivePage().getSelection();
+
+               // Sanity check, already done when populating the corresponding popup
+               // menu.
+               if (selection != null && selection.size() == 1) {
+                       Object obj = selection.getFirstElement();
+                       try {
+                               if (obj instanceof SingleResultNode) {
+                                       SingleResultNode rf = (SingleResultNode) obj;
+                                       Node sourceNode = rf.getNode();
+                                       String folderName = SingleValue.ask("Rename result",
+                                                       "Enter a new result name");
+                                       if (folderName != null) {
+
+                                               if (sourceNode.getParent().hasNode(folderName)) {
+                                                       MessageDialog
+                                                                       .openError(Display.getDefault()
+                                                                                       .getActiveShell(), "Error",
+                                                                                       "Another object with the same name already exists.");
+                                                       return null;
+                                               }
+
+                                               String sourcePath = sourceNode.getPath();
+                                               String targetPath = JcrUtils.parentPath(sourcePath)
+                                                               + "/" + folderName;
+                                               Session session = sourceNode.getSession();
+                                               session.move(sourcePath, targetPath);
+                                               session.getNode(targetPath).setProperty(
+                                                               Property.JCR_TITLE, folderName);
+                                               session.save();
+                                       }
+                               }
+                       } catch (RepositoryException e) {
+                               throw new SlcException(
+                                               "Unexpected exception while refactoring result folder",
+                                               e);
+                       }
+               }
+               return null;
+       }
+}
\ No newline at end of file
index 7878f85a25977a893aeba405dd0c87f28b1f0420..adadabbafd451362c04f056c541b68f459c6442d 100644 (file)
@@ -81,7 +81,7 @@ public class ResultFailedDecorator extends LabelProvider implements
                                                        .getTime());
                        } catch (RepositoryException re) {
                                throw new SlcException(
-                                               "Unexpected defining text decoration for result", re);
+                                               "Unexpected error defining text decoration for result", re);
                        }
                        return label + " [" + decoration + "]";
                } else
index 91163c84248001308df6266cd6267bd2019b2330..93cef51cd30fa9fef36243320217a2e7c600a03e 100644 (file)
@@ -20,18 +20,28 @@ import javax.jcr.NodeIterator;
 import javax.jcr.RepositoryException;
 import javax.jcr.nodetype.NodeType;
 
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
 import org.argeo.slc.SlcException;
 import org.argeo.slc.jcr.SlcJcrResultUtils;
 import org.argeo.slc.jcr.SlcNames;
 import org.argeo.slc.jcr.SlcTypes;
 
 /**
- * UI Tree component that wrap a node of type NT_UNSTRUCTURED. list either
- * result folders, other folders and/or a list of results. keeps a reference to
- * its parent.
+ * UI Tree component that wrap a node of type NT_UNSTRUCTURED.
+ * 
+ * It is used for
+ * <ul>
+ * <li>automatically generated tree structure to store results (typically
+ * Year/Month/Day...)</li>
+ * <li>parent node for user defined tree structure (typically My Results node)</li>
+ * </ul>
+ * It thus lists either result folders, other folders and/or a list of results
+ * and keeps a reference to its parent.
  */
 public class ParentNodeFolder extends ResultParent {
-
+       private final static Log log = LogFactory.getLog(ParentNodeFolder.class);
+       
        private Node node = null;
 
        /**
@@ -65,13 +75,17 @@ public class ParentNodeFolder extends ResultParent {
                                        ResultFolder rf = new ResultFolder(this, currNode,
                                                        currNode.getName());
                                        addChild(rf);
+                               } else if (currNode.isNodeType(SlcTypes.SLC_CHECK)) {
+                                       // FIXME : manually skip node types that are not to be
+                                       // displayed
+                                       // Do nothing
                                } else if (currNode.isNodeType(NodeType.NT_UNSTRUCTURED))
                                        addChild(new ParentNodeFolder(this, currNode,
                                                        currNode.getName()));
                        }
                } catch (RepositoryException re) {
                        throw new SlcException(
-                                       "Unexpected error while initializing simple node folder : "
+                                       "Unexpected error while initializing ParentNodeFolder : "
                                                        + getName(), re);
                }
        }
index a5c43168ec18ce34e518bd379d0ed9faf9606976..f48c5713f4b334d52ba77dea4299f47ff30bea55 100644 (file)
 package org.argeo.slc.client.ui.model;
 
 import javax.jcr.Node;
-import javax.jcr.NodeIterator;
 import javax.jcr.RepositoryException;
 
 import org.argeo.slc.SlcException;
 import org.argeo.slc.jcr.SlcNames;
-import org.argeo.slc.jcr.SlcTypes;
 
 /**
  * UI Tree component that wrap a node of type ResultFolder. list either other
  * folders and/or a list of results. keeps a reference to its parent.
  */
-public class ResultFolder extends ResultParent implements Comparable<ResultFolder> {
-
-       private Node node = null;
+public class ResultFolder extends ParentNodeFolder implements
+               Comparable<ResultFolder> {
 
        /**
         * 
@@ -38,13 +35,9 @@ public class ResultFolder extends ResultParent implements Comparable<ResultFolde
         *            throws an exception if null
         * @param name
         */
-       public ResultFolder(ResultParent parent, Node node, String name) {
-               super(name);
+       public ResultFolder(ParentNodeFolder parent, Node node, String name) {
+               super(parent, node, name);
                try {
-                       if (node == null)
-                               throw new SlcException("Node Object cannot be null");
-                       setParent(parent);
-                       this.node = node;
                        // initialize passed status if possible
                        if (node.hasNode(SlcNames.SLC_STATUS))
                                setPassed(node.getNode(SlcNames.SLC_STATUS)
@@ -54,41 +47,6 @@ public class ResultFolder extends ResultParent implements Comparable<ResultFolde
                                        "Unexpected error while initializing result folder : "
                                                        + getName(), re);
                }
-
-       }
-
-       @Override
-       protected void initialize() {
-               try {
-                       NodeIterator ni = node.getNodes();
-                       while (ni.hasNext()) {
-                               Node currNode = ni.nextNode();
-                               if (currNode.isNodeType(SlcTypes.SLC_TEST_RESULT)) {
-                                       SingleResultNode srn = new SingleResultNode(this, currNode,
-                                                       currNode.getProperty(SlcNames.SLC_TEST_CASE)
-                                                                       .getString());
-                                       addChild(srn);
-                               } else if (currNode.isNodeType(SlcTypes.SLC_RESULT_FOLDER)) {
-                                       // FIXME change label
-                                       ResultFolder rf = new ResultFolder(this, currNode,
-                                                       currNode.getName());
-                                       addChild(rf);
-                               }
-                       }
-               } catch (RepositoryException re) {
-                       throw new SlcException(
-                                       "Unexpected error while initializing result folder : "
-                                                       + getName(), re);
-               }
-       }
-
-       @Override
-       public synchronized void dispose() {
-               super.dispose();
-       }
-
-       public Node getNode() {
-               return node;
        }
 
        /**
index ecbffcae4a863cc0e3c1be5a10154f07d3f28d9a..0e4899c710e379c421fe4c7a5b515d44d6c14f10 100644 (file)
@@ -28,6 +28,7 @@ public abstract class ResultParent extends TreeParent {
        }
 
        private boolean isPassed = true;
+       private boolean isDisposed = false;
 
        protected synchronized void setPassed(boolean isPassed) {
                this.isPassed = isPassed;
@@ -39,16 +40,27 @@ public abstract class ResultParent extends TreeParent {
 
        @Override
        public synchronized boolean hasChildren() {
+               // sometimes in UI, disposed objects are still called.
+               if (isDisposed)
+                       return false;
                if (!isLoaded())
                        initialize();
                return super.hasChildren();
        }
 
        public void forceFullRefresh() {
-               clearChildren();
+               if (isDisposed)
+                       return;
+               if (hasChildren())
+                       clearChildren();
                initialize();
        }
 
+       public synchronized void dispose() {
+               super.dispose();
+               isDisposed = true;
+       }
+
        protected abstract void initialize();
 
 }
index 519dd3aeae337464c712f6ef37d7c6ec9ba1ca4d..e16bdc1954135899d4676aa3563383d5aa956aee 100644 (file)
@@ -38,7 +38,7 @@ public class ResultParentUtils {
                // Comparator<SingleResultNode> second = Collections.reverseOrder();
                Collections.sort(results);
 
-               Object[] orderedChildren = new Object[children.length];
+               Object[] orderedChildren = new Object[folders.size() + results.size()];
                int i = 0;
                Iterator<ResultFolder> it = folders.iterator();
                while (it.hasNext()) {
index aa4acea9c9f3d9e32d83d3eaabbae075b1a0ab74..c557d7ea09dc517a7f31eb792993a509a4bb9f52 100644 (file)
@@ -49,9 +49,15 @@ public class SingleResultNode extends ResultParent implements
 
        public boolean refreshPassedStatus() {
                try {
-                       Node check = node.getNode(SlcNames.SLC_STATUS);
-                       passed = check.getProperty(SlcNames.SLC_SUCCESS).getBoolean();
-                       return passed;
+                       Node check;
+                       if (node.hasNode(SlcNames.SLC_STATUS)) {
+                               check = node.getNode(SlcNames.SLC_STATUS);
+                               passed = check.getProperty(SlcNames.SLC_SUCCESS).getBoolean();
+                               return passed;
+                       } else
+                               // Happens only if the UI triggers a refresh while the execution
+                               // is in progress and the corresponding node is being built
+                               return false;
                } catch (RepositoryException re) {
                        throw new SlcException(
                                        "Unexpected error while checking result status", re);
index bae1c9dc039ede8738eeac43cf492b01700b902a..b901a80976e92ee311a22d4606e765dd34b857bd 100644 (file)
@@ -1,6 +1,12 @@
 package org.argeo.slc.client.ui.providers;
 
+import javax.jcr.Node;
+import javax.jcr.Property;
+import javax.jcr.RepositoryException;
+import javax.jcr.nodetype.NodeType;
+
 import org.argeo.eclipse.ui.TreeParent;
+import org.argeo.slc.SlcException;
 import org.argeo.slc.client.ui.SlcImages;
 import org.argeo.slc.client.ui.SlcUiConstants;
 import org.argeo.slc.client.ui.model.ResultParent;
@@ -15,6 +21,16 @@ public class ResultTreeLabelProvider extends LabelProvider {
 
        @Override
        public String getText(Object element) {
+               if (element instanceof SingleResultNode) {
+                       Node node = ((SingleResultNode) element).getNode();
+                       try {
+                               if (node.isNodeType(NodeType.MIX_TITLE))
+                                       return node.getProperty(Property.JCR_TITLE).getString();
+                       } catch (RepositoryException e) {
+                               throw new SlcException("Unexpected error while getting "
+                                               + "custom result label", e);
+                       }
+               }
                return ((TreeParent) element).getName();
        }
 
@@ -27,7 +43,8 @@ public class ResultTreeLabelProvider extends LabelProvider {
                        return SlcImages.PROCESS_COMPLETED;
                } else if (obj instanceof ResultParent) {
                        ResultParent rParent = (ResultParent) obj;
-                       if (SlcUiConstants.DEFAULT_MY_RESULTS_FOLDER_LABEL.equals(rParent.getName()))
+                       if (SlcUiConstants.DEFAULT_MY_RESULTS_FOLDER_LABEL.equals(rParent
+                                       .getName()))
                                return SlcImages.MY_RESULTS_FOLDER;
                        else
                                return SlcImages.FOLDER;
index bef8f208260e15f48333ff02c5753e6f919df4c4..798e6f25841109af9c4701adf2dbb77a4b09b1d1 100644 (file)
@@ -17,6 +17,8 @@ import javax.jcr.observation.Event;
 import javax.jcr.observation.EventListener;\r
 import javax.jcr.observation.ObservationManager;\r
 \r
+import org.apache.commons.logging.Log;\r
+import org.apache.commons.logging.LogFactory;\r
 import org.argeo.ArgeoException;\r
 import org.argeo.eclipse.ui.jcr.AsyncUiEventListener;\r
 import org.argeo.eclipse.ui.utils.CommandUtils;\r
@@ -26,6 +28,8 @@ import org.argeo.slc.SlcException;
 import org.argeo.slc.client.ui.ClientUiPlugin;\r
 import org.argeo.slc.client.ui.SlcUiConstants;\r
 import org.argeo.slc.client.ui.commands.AddResultFolder;\r
+import org.argeo.slc.client.ui.commands.RenameResultFolder;\r
+import org.argeo.slc.client.ui.commands.RenameResultNode;\r
 import org.argeo.slc.client.ui.editors.ProcessEditor;\r
 import org.argeo.slc.client.ui.editors.ProcessEditorInput;\r
 import org.argeo.slc.client.ui.model.ParentNodeFolder;\r
@@ -36,6 +40,7 @@ import org.argeo.slc.client.ui.model.SingleResultNode;
 import org.argeo.slc.client.ui.model.VirtualFolder;\r
 import org.argeo.slc.client.ui.providers.ResultTreeContentProvider;\r
 import org.argeo.slc.client.ui.providers.ResultTreeLabelProvider;\r
+import org.argeo.slc.client.ui.wizards.ConfirmOverwriteWizard;\r
 import org.argeo.slc.jcr.SlcJcrResultUtils;\r
 import org.argeo.slc.jcr.SlcNames;\r
 import org.argeo.slc.jcr.SlcTypes;\r
@@ -53,9 +58,11 @@ import org.eclipse.jface.viewers.IStructuredSelection;
 import org.eclipse.jface.viewers.SelectionChangedEvent;\r
 import org.eclipse.jface.viewers.TableViewer;\r
 import org.eclipse.jface.viewers.TableViewerColumn;\r
+import org.eclipse.jface.viewers.TreePath;\r
 import org.eclipse.jface.viewers.TreeViewer;\r
 import org.eclipse.jface.viewers.Viewer;\r
 import org.eclipse.jface.viewers.ViewerDropAdapter;\r
+import org.eclipse.jface.wizard.WizardDialog;\r
 import org.eclipse.swt.SWT;\r
 import org.eclipse.swt.custom.SashForm;\r
 import org.eclipse.swt.dnd.DND;\r
@@ -80,8 +87,7 @@ import org.eclipse.ui.part.ViewPart;
 public class JcrResultTreeView extends ViewPart {\r
        public final static String ID = ClientUiPlugin.ID + ".jcrResultTreeView";\r
 \r
-       // private final static Log log =\r
-       // LogFactory.getLog(JcrResultTreeView.class);\r
+       private final static Log log = LogFactory.getLog(JcrResultTreeView.class);\r
 \r
        /* DEPENDENCY INJECTION */\r
        private Session session;\r
@@ -96,10 +102,16 @@ public class JcrResultTreeView extends ViewPart {
                        SlcTypes.SLC_TEST_RESULT, SlcTypes.SLC_RESULT_FOLDER,\r
                        NodeType.NT_UNSTRUCTURED };\r
 \r
-       // FIXME cache to ease refresh after D&D\r
+       // FIXME cache to ease D&D\r
+       private boolean isActionUnderMyResult = false;\r
        private ResultParent lastSelectedTargetElement;\r
-       private ResultParent lastSelectedTargetElementParent;\r
+       private ResultParent lastSelectedSourceElement;\r
        private ResultParent lastSelectedSourceElementParent;\r
+       private boolean isResultFolder = false;\r
+\r
+       // FIXME we cache the fact that we are moving a node to avoid exception\r
+       // triggered by the "Add Node" event while moving\r
+       // boolean isMoveInProgress = false;\r
 \r
        /**\r
         * To be overridden to adapt size of form and result frames.\r
@@ -173,24 +185,7 @@ public class JcrResultTreeView extends ViewPart {
 \r
                // add change listener to display TestResult information in the property\r
                // viewer\r
-               viewer.addSelectionChangedListener(new ISelectionChangedListener() {\r
-                       public void selectionChanged(SelectionChangedEvent event) {\r
-                               if (!event.getSelection().isEmpty()) {\r
-                                       IStructuredSelection sel = (IStructuredSelection) event\r
-                                                       .getSelection();\r
-                                       Object firstItem = sel.getFirstElement();\r
-                                       if (firstItem instanceof SingleResultNode)\r
-                                               propertiesViewer\r
-                                                               .setInput(((SingleResultNode) firstItem)\r
-                                                                               .getNode());\r
-                                       else\r
-                                               propertiesViewer.setInput(null);\r
-                                       lastSelectedTargetElement = (ResultParent) firstItem;\r
-                                       lastSelectedTargetElementParent = (ResultParent) ((ResultParent) firstItem)\r
-                                                       .getParent();\r
-                               }\r
-                       }\r
-               });\r
+               viewer.addSelectionChangedListener(new MySelectionChangedListener());\r
                return viewer;\r
        }\r
 \r
@@ -345,7 +340,8 @@ public class JcrResultTreeView extends ViewPart {
                                        resultsObserver = new ResultObserver(resultTreeViewer\r
                                                        .getTree().getDisplay());\r
                                        observationManager.addEventListener(resultsObserver,\r
-                                                       Event.NODE_ADDED | Event.NODE_REMOVED, UserJcrUtils\r
+                                                       Event.NODE_MOVED | Event.NODE_ADDED\r
+                                                                       | Event.NODE_REMOVED, UserJcrUtils\r
                                                                        .getUserHome(session).getPath(), true,\r
                                                        null, observedNodeTypes, false);\r
                                } catch (RepositoryException e) {\r
@@ -354,13 +350,16 @@ public class JcrResultTreeView extends ViewPart {
                        }\r
 \r
                } else {\r
-                       // FIXME implement refresh for a specific ResultParent object.\r
-                       if (resultParent instanceof ResultFolder) {\r
-                               ResultFolder currFolder = (ResultFolder) resultParent;\r
+                       if (resultParent instanceof ParentNodeFolder) {\r
+                               ParentNodeFolder currFolder = (ParentNodeFolder) resultParent;\r
                                jcrRefresh(currFolder.getNode());\r
                                currFolder.forceFullRefresh();\r
-                               resultTreeViewer.refresh(lastSelectedTargetElement);\r
                        }\r
+                       // FIXME: specific refresh does not work\r
+                       // resultTreeViewer.refresh(currFolder, true);\r
+                       TreePath[] tps = resultTreeViewer.getExpandedTreePaths();\r
+                       resultTreeViewer.setInput(initializeResultTree());\r
+                       resultTreeViewer.setExpandedTreePaths(tps);\r
                }\r
        }\r
 \r
@@ -433,19 +432,24 @@ public class JcrResultTreeView extends ViewPart {
                // Building conditions\r
                IStructuredSelection selection = (IStructuredSelection) resultTreeViewer\r
                                .getSelection();\r
-               boolean isMyResultFolder = false;\r
+               boolean canAddSubfolder = false;\r
+               boolean isSingleResultNode = false;\r
                if (selection.size() == 1) {\r
                        Object obj = selection.getFirstElement();\r
                        try {\r
-                               if (obj instanceof ResultFolder\r
-                                               && (((ResultFolder) obj).getNode())\r
-                                                               .isNodeType(SlcTypes.SLC_RESULT_FOLDER))\r
-                                       isMyResultFolder = true;\r
+                               // if (obj instanceof ResultFolder\r
+                               // && (((ResultFolder) obj).getNode())\r
+                               // .isNodeType(SlcTypes.SLC_RESULT_FOLDER))\r
+                               if (isResultFolder)\r
+                                       canAddSubfolder = true;\r
+                               else if (obj instanceof SingleResultNode)\r
+                                       isSingleResultNode = true;\r
                                else if (obj instanceof ParentNodeFolder\r
                                                && (((ParentNodeFolder) obj).getNode().getPath()\r
                                                                .startsWith(SlcJcrResultUtils\r
                                                                                .getMyResultsBasePath(session))))\r
-                                       isMyResultFolder = true;\r
+                                       canAddSubfolder = true;\r
+\r
                        } catch (RepositoryException re) {\r
                                throw new SlcException(\r
                                                "unexpected error while building condition for context menu",\r
@@ -457,7 +461,15 @@ public class JcrResultTreeView extends ViewPart {
                                AddResultFolder.DEFAULT_LABEL,\r
                                ClientUiPlugin.getDefault().getWorkbench().getSharedImages()\r
                                                .getImageDescriptor(ISharedImages.IMG_OBJ_ADD),\r
-                               isMyResultFolder);\r
+                               canAddSubfolder);\r
+\r
+               CommandUtils.refreshCommand(menuManager, window, RenameResultFolder.ID,\r
+                               RenameResultFolder.DEFAULT_LABEL,\r
+                               RenameResultFolder.DEFAULT_IMG_DESCRIPTOR, canAddSubfolder);\r
+\r
+               CommandUtils.refreshCommand(menuManager, window, RenameResultNode.ID,\r
+                               RenameResultNode.DEFAULT_LABEL,\r
+                               RenameResultNode.DEFAULT_IMG_DESCRIPTOR, isSingleResultNode);\r
        }\r
 \r
        /* INNER CLASSES */\r
@@ -470,25 +482,26 @@ public class JcrResultTreeView extends ViewPart {
                        boolean doIt = false;\r
                        // only one node at a time for the time being.\r
                        if (selection.size() == 1) {\r
-                               Object obj = selection.getFirstElement();\r
-                               if (obj instanceof SingleResultNode) {\r
-                                       Node tNode = ((SingleResultNode) obj).getNode();\r
-                                       try {\r
-                                               // if (tNode.getPrimaryNodeType().isNodeType(\r
-                                               // SlcTypes.SLC_TEST_RESULT)\r
-                                               // && (tNode.getPath()\r
-                                               // .startsWith(SlcJcrResultUtils\r
-                                               // .getSlcResultsBasePath(session))))\r
+                               try {\r
+                                       Object obj = selection.getFirstElement();\r
+                                       if (obj instanceof SingleResultNode) {\r
+                                               Node tNode = ((SingleResultNode) obj).getNode();\r
+                                               if (tNode.getPrimaryNodeType().isNodeType(\r
+                                                               SlcTypes.SLC_TEST_RESULT)) {\r
+                                                       doIt = true;\r
+                                                       isResultFolder = false;\r
+                                               }\r
+                                       } else if (obj instanceof ResultFolder) {\r
+                                               Node tNode = ((ResultFolder) obj).getNode();\r
                                                if (tNode.getPrimaryNodeType().isNodeType(\r
-                                                               SlcTypes.SLC_TEST_RESULT))\r
+                                                               SlcTypes.SLC_RESULT_FOLDER)) {\r
                                                        doIt = true;\r
-                                               lastSelectedSourceElementParent = (ResultParent) ((SingleResultNode) obj)\r
-                                                               .getParent();\r
-                                       } catch (RepositoryException re) {\r
-                                               throw new SlcException(\r
-                                                               "unexpected error while validating drag source",\r
-                                                               re);\r
+                                                       isResultFolder = true;\r
+                                               }\r
                                        }\r
+                               } catch (RepositoryException re) {\r
+                                       throw new SlcException(\r
+                                                       "unexpected error while validating drag source", re);\r
                                }\r
                        }\r
                        event.doit = doIt;\r
@@ -498,28 +511,29 @@ public class JcrResultTreeView extends ViewPart {
                        IStructuredSelection selection = (IStructuredSelection) resultTreeViewer\r
                                        .getSelection();\r
                        Object obj = selection.getFirstElement();\r
-                       if (obj instanceof SingleResultNode) {\r
-                               Node first = ((SingleResultNode) obj).getNode();\r
-                               try {\r
+                       try {\r
+                               Node first;\r
+                               if (obj instanceof SingleResultNode) {\r
+                                       first = ((SingleResultNode) obj).getNode();\r
+                                       event.data = first.getIdentifier();\r
+                               } else if (obj instanceof ResultFolder) {\r
+                                       first = ((ResultFolder) obj).getNode();\r
                                        event.data = first.getIdentifier();\r
-\r
-                               } catch (RepositoryException re) {\r
-                                       throw new SlcException(\r
-                                                       "unexpected error while setting data", re);\r
                                }\r
+                       } catch (RepositoryException re) {\r
+                               throw new SlcException("unexpected error while setting data",\r
+                                               re);\r
                        }\r
                }\r
 \r
                public void dragFinished(DragSourceEvent event) {\r
-                       // implement here tree refresh in case of a move.\r
+                       // refresh is done via observer\r
                }\r
        }\r
 \r
        // Implementation of the Drop Listener\r
        protected class ViewDropListener extends ViewerDropAdapter {\r
-\r
-               private Node currParentNode = null;\r
-               private boolean copyNode = true;\r
+               private Node targetParentNode = null;\r
 \r
                public ViewDropListener(Viewer viewer) {\r
                        super(viewer);\r
@@ -528,18 +542,18 @@ public class JcrResultTreeView extends ViewPart {
                @Override\r
                public boolean validateDrop(Object target, int operation,\r
                                TransferData transferType) {\r
+\r
                        boolean validDrop = false;\r
                        try {\r
                                // We can only drop under myResults\r
-                               Node targetParentNode = null;\r
+                               Node tpNode = null;\r
                                if (target instanceof ResultFolder) {\r
-                                       targetParentNode = ((ResultFolder) target).getNode();\r
+                                       tpNode = ((ResultFolder) target).getNode();\r
                                } else if (target instanceof ParentNodeFolder) {\r
                                        if ((((ParentNodeFolder) target).getNode().getPath()\r
                                                        .startsWith(SlcJcrResultUtils\r
                                                                        .getMyResultsBasePath(session))))\r
-                                               targetParentNode = ((ParentNodeFolder) target)\r
-                                                               .getNode();\r
+                                               tpNode = ((ParentNodeFolder) target).getNode();\r
                                } else if (target instanceof SingleResultNode) {\r
                                        Node currNode = ((SingleResultNode) target).getNode();\r
                                        if (currNode\r
@@ -548,26 +562,28 @@ public class JcrResultTreeView extends ViewPart {
                                                        .startsWith(\r
                                                                        SlcJcrResultUtils\r
                                                                                        .getMyResultsBasePath(session)))\r
-                                               targetParentNode = currNode.getParent();\r
+                                               tpNode = currNode.getParent();\r
                                }\r
-                               if (targetParentNode != null) {\r
-                                       currParentNode = targetParentNode;\r
-                                       validDrop = true;\r
-                                       // FIXME\r
-                                       lastSelectedTargetElement = (ResultParent) target;\r
-                                       lastSelectedTargetElementParent = (ResultParent) ((ResultParent) target)\r
-                                                       .getParent();\r
-                               }\r
-                               // Check if it's a move or a copy\r
-                               if (validDrop) {\r
-                                       String pPath = "";\r
-                                       if (lastSelectedSourceElementParent instanceof ResultFolder)\r
-                                               pPath = ((ResultFolder) lastSelectedSourceElementParent)\r
-                                                               .getNode().getPath();\r
-                                       if ((pPath.startsWith(SlcJcrResultUtils\r
-                                                       .getMyResultsBasePath(session))))\r
-                                               copyNode = false;\r
+\r
+                               if (tpNode != null) {\r
+                                       // Sanity check : we cannot move a folder to one of its sub\r
+                                       // folder\r
+                                       boolean doit = true;\r
+                                       if (isResultFolder) {\r
+                                               Node source = ((ParentNodeFolder) lastSelectedSourceElement)\r
+                                                               .getNode();\r
+                                               String sourcePath = source.getPath();\r
+                                               String targetPath = tpNode.getPath();\r
+                                               if (targetPath.startsWith(sourcePath))\r
+                                                       doit = false;\r
+                                       }\r
+                                       if (doit) {\r
+                                               targetParentNode = tpNode;\r
+                                               validDrop = true;\r
+                                               lastSelectedTargetElement = (ResultParent) target;\r
+                                       }\r
                                }\r
+\r
                        } catch (RepositoryException re) {\r
                                throw new SlcException(\r
                                                "unexpected error while validating drop target", re);\r
@@ -577,34 +593,56 @@ public class JcrResultTreeView extends ViewPart {
 \r
                @Override\r
                public boolean performDrop(Object data) {\r
-\r
+                       // clear selection to prevent unwanted scrolling of the UI\r
+                       resultTreeViewer.setSelection(null);\r
                        try {\r
                                Node source = session.getNodeByIdentifier((String) data);\r
-                               if (copyNode) {\r
-                                       Node target = currParentNode.addNode(source.getName(),\r
-                                                       source.getPrimaryNodeType().getName());\r
+\r
+                               // Check is a node with same name already exists at destination\r
+                               String name;\r
+                               if (source.hasProperty(Property.JCR_TITLE))\r
+                                       name = source.getProperty(Property.JCR_TITLE).getString();\r
+                               else if (source.hasProperty(SlcNames.SLC_TEST_CASE))\r
+                                       name = source.getProperty(SlcNames.SLC_TEST_CASE)\r
+                                                       .getString();\r
+                               else\r
+                                       name = source.getName();\r
+\r
+                               if (targetParentNode.hasNode(name)) {\r
+                                       ConfirmOverwriteWizard wizard = new ConfirmOverwriteWizard(\r
+                                                       name, targetParentNode);\r
+                                       WizardDialog dialog = new WizardDialog(Display.getDefault()\r
+                                                       .getActiveShell(), wizard);\r
+                                       dialog.open();\r
+\r
+                                       if (wizard.overwrite()) {\r
+                                               targetParentNode.getNode(name).remove();\r
+                                               // session.save();\r
+                                       } else\r
+                                               name = wizard.newName();\r
+                               }\r
+\r
+                               Node target;\r
+                               if (!isActionUnderMyResult) {// Copy\r
+                                       target = targetParentNode.addNode(name, source\r
+                                                       .getPrimaryNodeType().getName());\r
                                        JcrUtils.copy(source, target);\r
-                                       ResultParentUtils.updatePassedStatus(\r
-                                                       target,\r
-                                                       target.getNode(SlcNames.SLC_STATUS)\r
-                                                                       .getProperty(SlcNames.SLC_SUCCESS)\r
-                                                                       .getBoolean());\r
-                                       target.getSession().save();\r
-                               } else // move only\r
-                               {\r
+                               } else {// move\r
                                        String sourcePath = source.getPath();\r
-                                       String destPath = currParentNode.getPath() + "/"\r
-                                                       + source.getName();\r
+                                       String destPath = targetParentNode.getPath() + "/" + name;\r
                                        session.move(sourcePath, destPath);\r
-                                       session.save();\r
-                                       Node target = session.getNode(destPath);\r
-                                       ResultParentUtils.updatePassedStatus(\r
-                                                       target,\r
-                                                       target.getNode(SlcNames.SLC_STATUS)\r
-                                                                       .getProperty(SlcNames.SLC_SUCCESS)\r
-                                                                       .getBoolean());\r
-                                       session.save();\r
+                                       // session.save();\r
+                                       target = session.getNode(destPath);\r
                                }\r
+                               if (!target.isNodeType(NodeType.MIX_TITLE))\r
+                                       target.addMixin(NodeType.MIX_TITLE);\r
+                               target.setProperty(Property.JCR_TITLE, name);\r
+                               ResultParentUtils\r
+                                               .updatePassedStatus(target,\r
+                                                               target.getNode(SlcNames.SLC_STATUS)\r
+                                                                               .getProperty(SlcNames.SLC_SUCCESS)\r
+                                                                               .getBoolean());\r
+                               session.save();\r
                        } catch (RepositoryException re) {\r
                                throw new SlcException(\r
                                                "unexpected error while copying dropped node", re);\r
@@ -624,57 +662,43 @@ public class JcrResultTreeView extends ViewPart {
                                throws RepositoryException {\r
                        // unfiltered for the time being\r
                        return true;\r
-                       // for (Event event : events) {\r
-                       // getLog().debug("Received event " + event);\r
-                       // int eventType = event.getType();\r
-                       // if (eventType == Event.NODE_REMOVED)\r
-                       // ;//return true;\r
-                       // String path = event.getPath();\r
-                       // int index = path.lastIndexOf('/');\r
-                       // String propertyName = path.substring(index + 1);\r
-                       // if (propertyName.equals(SlcNames.SLC_COMPLETED)\r
-                       // || propertyName.equals(SlcNames.SLC_UUID)) {\r
-                       // ;//return true;\r
-                       // }\r
-                       // }\r
-                       // return false;\r
                }\r
 \r
                protected void onEventInUiThread(List<Event> events)\r
                                throws RepositoryException {\r
+                       int i = 0;\r
 \r
                        for (Event event : events) {\r
-                               getLog().debug("Received event " + event);\r
+                               i++;\r
+                               // log.debug("Received event " + event);\r
                                int eventType = event.getType();\r
                                if (eventType == Event.NODE_REMOVED) {\r
                                        String path = event.getPath();\r
-                                       int index = path.lastIndexOf('/');\r
-                                       String parPath = path.substring(0, index + 1);\r
+                                       String parPath = JcrUtils.parentPath(path);\r
                                        if (session.nodeExists(parPath)) {\r
                                                Node currNode = session.getNode(parPath);\r
                                                if (currNode.isNodeType(NodeType.NT_UNSTRUCTURED)) {\r
-                                                       refresh(null);\r
-                                                       jcrRefresh(currNode);\r
-                                                       resultTreeViewer.refresh(true);\r
-                                                       resultTreeViewer.expandToLevel(\r
-                                                                       lastSelectedTargetElementParent, 1);\r
-\r
+                                                       // jcrRefresh(currNode);\r
+                                                       refresh(lastSelectedSourceElementParent);\r
                                                }\r
                                        }\r
                                } else if (eventType == Event.NODE_ADDED) {\r
+                                       // refresh(lastSelectedTargetElement);\r
                                        String path = event.getPath();\r
                                        if (session.nodeExists(path)) {\r
                                                Node currNode = session.getNode(path);\r
-                                               if (currNode.isNodeType(SlcTypes.SLC_DIFF_RESULT)\r
+                                               if (currNode.isNodeType(SlcTypes.SLC_TEST_RESULT)\r
                                                                || currNode\r
                                                                                .isNodeType(SlcTypes.SLC_RESULT_FOLDER)) {\r
-                                                       refresh(null);\r
-                                                       resultTreeViewer.expandToLevel(\r
-                                                                       lastSelectedTargetElement, 1);\r
+                                                       refresh(lastSelectedTargetElement);\r
+                                                       // resultTreeViewer.expandToLevel(\r
+                                                       // lastSelectedTargetElement, 1);\r
                                                }\r
                                        }\r
                                }\r
                        }\r
+                       if (log.isDebugEnabled())\r
+                               log.debug("treated events: " + i);\r
                }\r
        }\r
 \r
@@ -704,6 +728,45 @@ public class JcrResultTreeView extends ViewPart {
                }\r
        }\r
 \r
+       class MySelectionChangedListener implements ISelectionChangedListener {\r
+\r
+               public void selectionChanged(SelectionChangedEvent event) {\r
+                       if (!event.getSelection().isEmpty()) {\r
+                               IStructuredSelection sel = (IStructuredSelection) event\r
+                                               .getSelection();\r
+                               ResultParent firstItem = (ResultParent) sel.getFirstElement();\r
+                               if (firstItem instanceof SingleResultNode)\r
+                                       propertiesViewer.setInput(((SingleResultNode) firstItem)\r
+                                                       .getNode());\r
+                               else\r
+                                       propertiesViewer.setInput(null);\r
+                               // update cache for Drag & drop\r
+                               lastSelectedTargetElement = firstItem;\r
+                               lastSelectedSourceElement = firstItem;\r
+                               lastSelectedSourceElementParent = (ResultParent) firstItem\r
+                                               .getParent();\r
+                               String pPath = "";\r
+                               try {\r
+\r
+                                       if (firstItem instanceof ParentNodeFolder)\r
+                                               pPath = ((ParentNodeFolder) firstItem).getNode()\r
+                                                               .getPath();\r
+                                       else if (firstItem instanceof SingleResultNode)\r
+                                               pPath = ((SingleResultNode) firstItem).getNode()\r
+                                                               .getPath();\r
+                               } catch (RepositoryException e) {\r
+                                       throw new SlcException(\r
+                                                       "Unexpected error while checking parent UI tree", e);\r
+                               }\r
+                               if ((pPath.startsWith(SlcJcrResultUtils\r
+                                               .getMyResultsBasePath(session))))\r
+                                       isActionUnderMyResult = true;\r
+                               else\r
+                                       isActionUnderMyResult = false;\r
+                       }\r
+               }\r
+       }\r
+\r
        class ViewDoubleClickListener implements IDoubleClickListener {\r
                public void doubleClick(DoubleClickEvent evt) {\r
                        processDoubleClick(evt);\r
diff --git a/plugins/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/wizards/ConfirmOverwriteWizard.java b/plugins/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/wizards/ConfirmOverwriteWizard.java
new file mode 100644 (file)
index 0000000..3ec3530
--- /dev/null
@@ -0,0 +1,184 @@
+package org.argeo.slc.client.ui.wizards;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+
+import org.argeo.slc.SlcException;
+import org.argeo.slc.client.ui.ClientUiPlugin;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.wizard.Wizard;
+import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.ISharedImages;
+
+public class ConfirmOverwriteWizard extends Wizard {
+
+       // Define widget here to simplify getters
+       private Button overwriteBtn, renameBtn;
+       private Text newNameTxt;
+       private Label newNameLbl;
+
+       // business object
+       private String sourceNodeName;
+       private Node targetParentNode;
+
+       private String newName;
+       private boolean overwrite;
+
+       public ConfirmOverwriteWizard(String sourceNodeName, Node targetParentNode) {
+               setWindowTitle("Confirm overwrite or define a new name");
+               this.sourceNodeName = sourceNodeName;
+               this.targetParentNode = targetParentNode;
+       }
+
+       @Override
+       public void addPages() {
+               try {
+                       addPage(new MyPage());
+               } catch (Exception e) {
+                       throw new SlcException("Cannot add page to wizard ", e);
+               }
+               getShell().setImage(
+                               ClientUiPlugin.getDefault().getWorkbench().getSharedImages()
+                                               .getImageDescriptor(ISharedImages.IMG_LCL_LINKTO_HELP)
+                                               .createImage());
+       }
+
+       // Expose info to the calling view
+       public boolean overwrite() {
+               return overwrite;
+       }
+
+       public String newName() {
+               return newName;
+       }
+
+       @Override
+       public boolean performFinish() {
+               boolean doFinish = false;
+
+               if (canFinish()) {
+                       if (overwriteBtn.getSelection())
+                               doFinish = MessageDialog.openConfirm(Display.getDefault()
+                                               .getActiveShell(), "CAUTION", "All data contained in ["
+                                               + sourceNodeName
+                                               + "] are about to be definitively destroyed. \n "
+                                               + "Are you sure you want to proceed ?");
+                       else
+                               doFinish = true;
+                       // cache values
+               }
+               if (doFinish) {
+                       overwrite = overwriteBtn.getSelection();
+                       newName = newNameTxt.getText();
+               }
+               return doFinish;
+       }
+
+       class MyPage extends WizardPage implements ModifyListener {
+
+               public MyPage() {
+                       super("");
+                       setTitle("An object with same name (" + sourceNodeName
+                                       + ") already exists");
+               }
+
+               public void createControl(Composite parent) {
+                       Composite composite = new Composite(parent, SWT.NONE);
+                       composite.setLayout(new GridLayout(2, false));
+
+                       // choose between overwrite and rename
+                       overwriteBtn = new Button(composite, SWT.RADIO);
+                       overwriteBtn.setText("Overwrite");
+                       GridData gd = new GridData();
+                       gd.horizontalIndent = 30;
+                       gd.horizontalSpan = 2;
+                       overwriteBtn.setLayoutData(gd);
+                       overwriteBtn.setSelection(true);
+
+                       renameBtn = new Button(composite, SWT.RADIO);
+                       renameBtn.setText("Rename");
+                       renameBtn.setSelection(false);
+                       renameBtn.setText("Rename");
+                       gd = new GridData();
+                       gd.horizontalIndent = 30;
+                       gd.horizontalSpan = 2;
+                       renameBtn.setLayoutData(gd);
+
+                       newNameLbl = new Label(composite, SWT.LEAD);
+                       newNameLbl.setText("New name");
+                       newNameLbl.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false,
+                                       false));
+                       newNameLbl.setEnabled(false);
+
+                       newNameTxt = new Text(composite, SWT.LEAD | SWT.BORDER);
+                       newNameTxt.setText(sourceNodeName);
+                       newNameTxt.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true,
+                                       false));
+                       if (newNameTxt != null)
+                               newNameTxt.addModifyListener(this);
+                       newNameTxt.setEnabled(false);
+
+                       SelectionAdapter sa = new SelectionAdapter() {
+                               public void widgetSelected(SelectionEvent e) {
+                                       updateSelection(overwriteBtn.getSelection());
+                               }
+                       };
+                       overwriteBtn.addSelectionListener(sa);
+                       renameBtn.addSelectionListener(sa);
+
+                       // Compulsory
+                       setControl(composite);
+               }
+
+               private void updateSelection(boolean overwrite) {
+                       newNameLbl.setEnabled(!overwrite);
+                       newNameTxt.setEnabled(!overwrite);
+                       if (overwrite)
+                               setPageComplete(true);
+                       else
+                               checkComplete();
+               }
+
+               protected String getTechName() {
+                       return newNameTxt.getText();
+               }
+
+               public void modifyText(ModifyEvent event) {
+                       checkComplete();
+               }
+
+               private void checkComplete() {
+                       try {
+
+                               String newName = newNameTxt.getText();
+                               if (newName == null || "".equals(newName.trim())) {
+                                       setMessage("Name cannot be blank or empty",
+                                                       WizardPage.ERROR);
+                                       setPageComplete(false);
+                               } else if (targetParentNode.hasNode(newName)) {
+                                       setMessage("An object with the same name already exists.",
+                                                       WizardPage.ERROR);
+                                       setPageComplete(false);
+                               } else {
+                                       setMessage("Complete", WizardPage.INFORMATION);
+                                       setPageComplete(true);
+                               }
+                       } catch (RepositoryException e) {
+                               throw new SlcException("Unexpected error while checking "
+                                               + "children node with same name", e);
+                       }
+               }
+       }
+}