Bug 313171 - [sfs] Improve error handling for SFS Team UI actions
diff --git a/bundles/org.eclipse.ui.resources.semantic/src/org/eclipse/core/internal/resources/semantic/ui/SemanticResourcesUIPlugin.java b/bundles/org.eclipse.ui.resources.semantic/src/org/eclipse/core/internal/resources/semantic/ui/SemanticResourcesUIPlugin.java
index 9dc9151..7c832d1 100644
--- a/bundles/org.eclipse.ui.resources.semantic/src/org/eclipse/core/internal/resources/semantic/ui/SemanticResourcesUIPlugin.java
+++ b/bundles/org.eclipse.ui.resources.semantic/src/org/eclipse/core/internal/resources/semantic/ui/SemanticResourcesUIPlugin.java
@@ -11,7 +11,9 @@
  *******************************************************************************/
 package org.eclipse.core.internal.resources.semantic.ui;
 
+import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.MultiStatus;
 import org.eclipse.core.runtime.Plugin;
 import org.eclipse.core.runtime.Status;
 import org.eclipse.ui.statushandlers.StatusManager;
@@ -34,7 +36,30 @@
 	 * @param show
 	 */
 	public static void handleError(String message, Throwable throwable, boolean show) {
-		IStatus status = new Status(IStatus.ERROR, PLUGIN_ID, message, throwable);
+		if (throwable instanceof CoreException) {
+			IStatus causeStatus = ((CoreException) throwable).getStatus();
+			IStatus statusToShow;
+			if (causeStatus.isMultiStatus()) {
+				statusToShow = causeStatus;
+			} else {
+				MultiStatus status = new MultiStatus(PLUGIN_ID, 0, message, throwable);
+				status.add(((CoreException) throwable).getStatus());
+				statusToShow = status;
+			}
+			int style = StatusManager.LOG;
+			if (show)
+				style |= StatusManager.SHOW;
+			StatusManager.getManager().handle(statusToShow, style);
+		} else {
+			IStatus status = new Status(IStatus.ERROR, PLUGIN_ID, message, throwable);
+			int style = StatusManager.LOG;
+			if (show)
+				style |= StatusManager.SHOW;
+			StatusManager.getManager().handle(status, style);
+		}
+	}
+
+	public static void handleError(IStatus status, boolean show) {
 		int style = StatusManager.LOG;
 		if (show)
 			style |= StatusManager.SHOW;
diff --git a/bundles/org.eclipse.ui.resources.semantic/src/org/eclipse/core/internal/resources/semantic/ui/actions/ActionBase.java b/bundles/org.eclipse.ui.resources.semantic/src/org/eclipse/core/internal/resources/semantic/ui/actions/ActionBase.java
index 31c1486..6524249 100644
--- a/bundles/org.eclipse.ui.resources.semantic/src/org/eclipse/core/internal/resources/semantic/ui/actions/ActionBase.java
+++ b/bundles/org.eclipse.ui.resources.semantic/src/org/eclipse/core/internal/resources/semantic/ui/actions/ActionBase.java
@@ -25,7 +25,6 @@
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Status;
 import org.eclipse.jface.action.IAction;
-import org.eclipse.jface.dialogs.ErrorDialog;
 import org.eclipse.jface.dialogs.MessageDialog;
 import org.eclipse.jface.operation.IRunnableWithProgress;
 import org.eclipse.jface.viewers.ISelection;
@@ -62,7 +61,7 @@
 		return this.mySelection;
 	}
 
-	@SuppressWarnings({"rawtypes"})
+	@SuppressWarnings( {"rawtypes"})
 	protected boolean checkSelectionNonLocalOnly() {
 
 		boolean shouldEnable = true;
@@ -101,7 +100,7 @@
 		return shouldEnable;
 	}
 
-	@SuppressWarnings({"rawtypes"})
+	@SuppressWarnings( {"rawtypes"})
 	protected boolean checkSelectionSemanticResource() {
 
 		boolean shouldEnable = true;
@@ -121,7 +120,7 @@
 		return shouldEnable;
 	}
 
-	@SuppressWarnings({"rawtypes"})
+	@SuppressWarnings( {"rawtypes"})
 	protected boolean checkFilesWithReadOnlyFlagOnly(boolean readOnly) {
 
 		boolean shouldEnable = true;
@@ -157,7 +156,7 @@
 		return shouldEnable;
 	}
 
-	@SuppressWarnings({"rawtypes"})
+	@SuppressWarnings( {"rawtypes"})
 	protected boolean checkSelectionLockingSupportedOnly() {
 
 		boolean shouldEnable = true;
@@ -200,14 +199,15 @@
 		try {
 			srv.busyCursorWhile(runnable);
 		} catch (InvocationTargetException e) {
-			// we don't try to unpack a status from a causing CoreException,
-			// since the status code might
-			// be CANCEL, which would not be shown in the error dialog below
-			IStatus error = new Status(IStatus.ERROR, SemanticResourcesUIPlugin.PLUGIN_ID, e.getCause().getMessage(), e.getCause());
-			ErrorDialog.openError(getShell(), Messages.RemoveAction_Remove_XGRP, null, error);
+			String popupText = e.getMessage();
+			if (popupText == null)
+				// fall back solution
+				popupText = Messages.ActionBase_ActionNotCompleted_XMSG;
+			IStatus errorStatus = new Status(IStatus.ERROR, SemanticResourcesUIPlugin.PLUGIN_ID, popupText, e.getCause());
+			SemanticResourcesUIPlugin.handleError(errorStatus, true);
 		} catch (InterruptedException e) {
 			// $JL-EXC$ ignore here
-			MessageDialog.openInformation(getShell(), Messages.ActionBase_ActionCancelded_XGRP, Messages.ActionBase_ActionCanceled_XMSG);
+			MessageDialog.openInformation(getShell(), Messages.ActionBase_ActionCancelled_XGRP, Messages.ActionBase_ActionCancelled_XMSG);
 		}
 	}
 
diff --git a/bundles/org.eclipse.ui.resources.semantic/src/org/eclipse/core/internal/resources/semantic/ui/actions/DeleteAction.java b/bundles/org.eclipse.ui.resources.semantic/src/org/eclipse/core/internal/resources/semantic/ui/actions/DeleteAction.java
index d81e07b..56620a6 100644
--- a/bundles/org.eclipse.ui.resources.semantic/src/org/eclipse/core/internal/resources/semantic/ui/actions/DeleteAction.java
+++ b/bundles/org.eclipse.ui.resources.semantic/src/org/eclipse/core/internal/resources/semantic/ui/actions/DeleteAction.java
@@ -44,7 +44,7 @@
 
 		IRunnableWithProgress outerRunnable = new IRunnableWithProgress() {
 
-			@SuppressWarnings({"rawtypes"})
+			@SuppressWarnings( {"rawtypes"})
 			public void run(IProgressMonitor outerMonitor) throws InvocationTargetException, InterruptedException {
 
 				for (Iterator it = getSelection().iterator(); it.hasNext();) {
@@ -73,7 +73,8 @@
 							throw new InvocationTargetException(e);
 						}
 					} else {
-						throw new InvocationTargetException(new CoreException(validationResult));
+						throw new InvocationTargetException(new CoreException(validationResult), NLS.bind(
+								Messages.DeleteAction_CouldNotDeleteResource_XMSG, resource.getAdaptedResource().getFullPath().toString()));
 					}
 
 				}
diff --git a/bundles/org.eclipse.ui.resources.semantic/src/org/eclipse/core/internal/resources/semantic/ui/actions/DiffAction.java b/bundles/org.eclipse.ui.resources.semantic/src/org/eclipse/core/internal/resources/semantic/ui/actions/DiffAction.java
index b3b2af6..29ad529 100644
--- a/bundles/org.eclipse.ui.resources.semantic/src/org/eclipse/core/internal/resources/semantic/ui/actions/DiffAction.java
+++ b/bundles/org.eclipse.ui.resources.semantic/src/org/eclipse/core/internal/resources/semantic/ui/actions/DiffAction.java
@@ -26,6 +26,7 @@
 import org.eclipse.jface.dialogs.MessageDialog;
 import org.eclipse.jface.operation.IRunnableWithProgress;
 import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.osgi.util.NLS;
 import org.eclipse.swt.widgets.Display;
 import org.eclipse.team.core.history.IFileRevision;
 import org.eclipse.team.core.synchronize.SyncInfo;
@@ -57,8 +58,8 @@
 			 */
 			public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
 
+				ISemanticFile file = (ISemanticFile) getSelection().getFirstElement();
 				try {
-					ISemanticFile file = (ISemanticFile) getSelection().getFirstElement();
 					ISemanticFileStore sfs = (ISemanticFileStore) EFS.getStore(file.getAdaptedFile().getLocationURI());
 					ISemanticFileHistoryProvider fhp = (ISemanticFileHistoryProvider) sfs.getEffectiveContentProvider().getAdapter(
 							ISemanticFileHistoryProvider.class);
@@ -103,7 +104,8 @@
 					CompareUI.openCompareEditor(input);
 
 				} catch (CoreException e) {
-					throw new InvocationTargetException(e);
+					throw new InvocationTargetException(e, NLS.bind(Messages.DiffAction_DiffFailedForFile_XMSG, file.getAdaptedFile()
+							.getFullPath().toFile()));
 				}
 
 			}
diff --git a/bundles/org.eclipse.ui.resources.semantic/src/org/eclipse/core/internal/resources/semantic/ui/actions/EditAction.java b/bundles/org.eclipse.ui.resources.semantic/src/org/eclipse/core/internal/resources/semantic/ui/actions/EditAction.java
index 87b1d16..979e3d0 100644
--- a/bundles/org.eclipse.ui.resources.semantic/src/org/eclipse/core/internal/resources/semantic/ui/actions/EditAction.java
+++ b/bundles/org.eclipse.ui.resources.semantic/src/org/eclipse/core/internal/resources/semantic/ui/actions/EditAction.java
@@ -46,7 +46,7 @@
 
 		IRunnableWithProgress outerRunnable = new IRunnableWithProgress() {
 
-			@SuppressWarnings({"rawtypes"})
+			@SuppressWarnings( {"rawtypes"})
 			public void run(IProgressMonitor outerMonitor) throws InvocationTargetException, InterruptedException {
 
 				for (Iterator it = getSelection().iterator(); it.hasNext();) {
@@ -64,7 +64,9 @@
 						public void run(IProgressMonitor monitor) throws CoreException {
 
 							IStatus validationResult = file.validateEdit(getShell());
-							if (!validationResult.isOK()) {
+							// in case of cancel, we don't want to see any error
+							// handling UI
+							if (!validationResult.isOK() && validationResult.getSeverity() != IStatus.CANCEL) {
 								throw new CoreException(validationResult);
 							}
 						}
@@ -76,7 +78,8 @@
 						ISchedulingRule rule = ws.getRuleFactory().validateEditRule(new IResource[] {file.getAdaptedResource()});
 						ResourcesPlugin.getWorkspace().run(wsRunnable, rule, IWorkspace.AVOID_UPDATE, outerMonitor);
 					} catch (CoreException ce) {
-						throw new InvocationTargetException(ce);
+						throw new InvocationTargetException(ce, NLS.bind(Messages.EditAction_CouldNotOpenForEdit_XMSG, file
+								.getAdaptedFile().getFullPath().toString()));
 					}
 
 				}
diff --git a/bundles/org.eclipse.ui.resources.semantic/src/org/eclipse/core/internal/resources/semantic/ui/actions/LockAction.java b/bundles/org.eclipse.ui.resources.semantic/src/org/eclipse/core/internal/resources/semantic/ui/actions/LockAction.java
index ca1367b..2ddaa68 100644
--- a/bundles/org.eclipse.ui.resources.semantic/src/org/eclipse/core/internal/resources/semantic/ui/actions/LockAction.java
+++ b/bundles/org.eclipse.ui.resources.semantic/src/org/eclipse/core/internal/resources/semantic/ui/actions/LockAction.java
@@ -45,7 +45,7 @@
 
 		IRunnableWithProgress outerRunnable = new IRunnableWithProgress() {
 
-			@SuppressWarnings({"rawtypes"})
+			@SuppressWarnings( {"rawtypes"})
 			public void run(IProgressMonitor outerMonitor) throws InvocationTargetException, InterruptedException {
 
 				for (Iterator it = getSelection().iterator(); it.hasNext();) {
@@ -75,7 +75,8 @@
 						ISchedulingRule rule = ws.getRuleFactory().refreshRule(resource.getAdaptedResource());
 						ResourcesPlugin.getWorkspace().run(wsRunnable, rule, IWorkspace.AVOID_UPDATE, outerMonitor);
 					} catch (CoreException ce) {
-						throw new InvocationTargetException(ce);
+						throw new InvocationTargetException(ce, NLS.bind(Messages.LockAction_CouldNotLockResource_XMSG, resource
+								.getAdaptedResource().getFullPath().toString()));
 					}
 
 				}
diff --git a/bundles/org.eclipse.ui.resources.semantic/src/org/eclipse/core/internal/resources/semantic/ui/actions/Messages.java b/bundles/org.eclipse.ui.resources.semantic/src/org/eclipse/core/internal/resources/semantic/ui/actions/Messages.java
index 6500e0e..a2fbd70 100644
--- a/bundles/org.eclipse.ui.resources.semantic/src/org/eclipse/core/internal/resources/semantic/ui/actions/Messages.java
+++ b/bundles/org.eclipse.ui.resources.semantic/src/org/eclipse/core/internal/resources/semantic/ui/actions/Messages.java
@@ -15,19 +15,28 @@
 
 public class Messages extends NLS {
 	private static final String BUNDLE_NAME = "org.eclipse.core.internal.resources.semantic.ui.actions.messages"; //$NON-NLS-1$
-	public static String ActionBase_ActionCancelded_XGRP;
-	public static String ActionBase_ActionCanceled_XMSG;
+	public static String ActionBase_ActionCancelled_XGRP;
+	public static String ActionBase_ActionCancelled_XMSG;
+	public static String ActionBase_ActionNotCompleted_XMSG;
+	public static String DeleteAction_CouldNotDeleteResource_XMSG;
 	public static String DeleteAction_Deleting_XMSG;
 	public static String DiffAction_CompareAction_XGRP;
+	public static String DiffAction_DiffFailedForFile_XMSG;
 	public static String DiffAction_NoHistory_XMSG;
+	public static String EditAction_CouldNotOpenForEdit_XMSG;
 	public static String EditAction_Editing_XMSG;
+	public static String LockAction_CouldNotLockResource_XMSG;
 	public static String LockAction_LockingRes_XMSG;
 	public static String RemoveAction_ConfirmResourceRemoval_XGRP;
+	public static String RemoveAction_CouldNotRemoveResource_XMSG;
 	public static String RemoveAction_DoYouWantToRemove_XMSG;
 	public static String RemoveAction_Remove_XGRP;
 	public static String RemoveAction_Removing_XMSG;
+	public static String RevertAction_RevertFailed_XMSG;
 	public static String RevertAction_Reverting_XMSG;
+	public static String SynchronizeAction_SyncFailedForResource_XMSG;
 	public static String SynchronizeAction_Synchronizing_XMSG;
+	public static String UnlockAction_UnlockFailed_XMSG;
 	public static String UnlockAction_Unlocking_XMSG;
 	public static String UnmapAction_Unmap_XGRP;
 	static {
diff --git a/bundles/org.eclipse.ui.resources.semantic/src/org/eclipse/core/internal/resources/semantic/ui/actions/RemoveAction.java b/bundles/org.eclipse.ui.resources.semantic/src/org/eclipse/core/internal/resources/semantic/ui/actions/RemoveAction.java
index 0c4b576..33036b7 100644
--- a/bundles/org.eclipse.ui.resources.semantic/src/org/eclipse/core/internal/resources/semantic/ui/actions/RemoveAction.java
+++ b/bundles/org.eclipse.ui.resources.semantic/src/org/eclipse/core/internal/resources/semantic/ui/actions/RemoveAction.java
@@ -43,7 +43,7 @@
 		action.setEnabled(checkSelectionSemanticResource());
 	}
 
-	@SuppressWarnings({"rawtypes"})
+	@SuppressWarnings( {"rawtypes"})
 	public void run(IAction action) {
 		boolean askForForceRemoval = false;
 
@@ -91,7 +91,8 @@
 					try {
 						workspace.run(myRunnable, workspace.getRuleFactory().refreshRule(resource.getAdaptedResource()), 0, null);
 					} catch (CoreException e) {
-						throw new InvocationTargetException(e);
+						throw new InvocationTargetException(e, NLS.bind(Messages.RemoveAction_CouldNotRemoveResource_XMSG, resource
+								.getAdaptedResource().getFullPath().toString()));
 					}
 
 				}
diff --git a/bundles/org.eclipse.ui.resources.semantic/src/org/eclipse/core/internal/resources/semantic/ui/actions/RevertAction.java b/bundles/org.eclipse.ui.resources.semantic/src/org/eclipse/core/internal/resources/semantic/ui/actions/RevertAction.java
index 90fd455..115879c 100644
--- a/bundles/org.eclipse.ui.resources.semantic/src/org/eclipse/core/internal/resources/semantic/ui/actions/RevertAction.java
+++ b/bundles/org.eclipse.ui.resources.semantic/src/org/eclipse/core/internal/resources/semantic/ui/actions/RevertAction.java
@@ -43,7 +43,7 @@
 
 		IRunnableWithProgress outerRunnable = new IRunnableWithProgress() {
 
-			@SuppressWarnings({"rawtypes"})
+			@SuppressWarnings( {"rawtypes"})
 			public void run(IProgressMonitor outerMonitor) throws InvocationTargetException, InterruptedException {
 
 				for (Iterator it = getSelection().iterator(); it.hasNext();) {
@@ -68,7 +68,8 @@
 					try {
 						workspace.run(myRunnable, workspace.getRuleFactory().refreshRule(file.getAdaptedResource()), 0, null);
 					} catch (CoreException e) {
-						throw new InvocationTargetException(e);
+						throw new InvocationTargetException(e, NLS.bind(Messages.RevertAction_RevertFailed_XMSG, file.getAdaptedFile()
+								.getFullPath().toString()));
 					}
 
 				}
diff --git a/bundles/org.eclipse.ui.resources.semantic/src/org/eclipse/core/internal/resources/semantic/ui/actions/SynchronizeAction.java b/bundles/org.eclipse.ui.resources.semantic/src/org/eclipse/core/internal/resources/semantic/ui/actions/SynchronizeAction.java
index a4ab271..0317bd6 100644
--- a/bundles/org.eclipse.ui.resources.semantic/src/org/eclipse/core/internal/resources/semantic/ui/actions/SynchronizeAction.java
+++ b/bundles/org.eclipse.ui.resources.semantic/src/org/eclipse/core/internal/resources/semantic/ui/actions/SynchronizeAction.java
@@ -45,7 +45,7 @@
 
 		IRunnableWithProgress outerRunnable = new IRunnableWithProgress() {
 
-			@SuppressWarnings({"rawtypes"})
+			@SuppressWarnings( {"rawtypes"})
 			public void run(IProgressMonitor outerMonitor) throws InvocationTargetException, InterruptedException {
 
 				for (Iterator it = getSelection().iterator(); it.hasNext();) {
@@ -70,7 +70,10 @@
 						ISchedulingRule rule = ws.getRuleFactory().refreshRule(resource.getAdaptedResource());
 						ResourcesPlugin.getWorkspace().run(wsRunnable, rule, IWorkspace.AVOID_UPDATE, outerMonitor);
 					} catch (CoreException ce) {
-						throw new InvocationTargetException(ce);
+						// pack the error text into the
+						// InvocationTargetException
+						throw new InvocationTargetException(ce, NLS.bind(Messages.SynchronizeAction_SyncFailedForResource_XMSG,
+								resource.getAdaptedResource().getFullPath().toString()));
 					}
 
 				}
diff --git a/bundles/org.eclipse.ui.resources.semantic/src/org/eclipse/core/internal/resources/semantic/ui/actions/UnlockAction.java b/bundles/org.eclipse.ui.resources.semantic/src/org/eclipse/core/internal/resources/semantic/ui/actions/UnlockAction.java
index 211caff..aa8604e 100644
--- a/bundles/org.eclipse.ui.resources.semantic/src/org/eclipse/core/internal/resources/semantic/ui/actions/UnlockAction.java
+++ b/bundles/org.eclipse.ui.resources.semantic/src/org/eclipse/core/internal/resources/semantic/ui/actions/UnlockAction.java
@@ -45,7 +45,7 @@
 
 		IRunnableWithProgress outerRunnable = new IRunnableWithProgress() {
 
-			@SuppressWarnings({"rawtypes"})
+			@SuppressWarnings( {"rawtypes"})
 			public void run(IProgressMonitor outerMonitor) throws InvocationTargetException, InterruptedException {
 
 				for (Iterator it = getSelection().iterator(); it.hasNext();) {
@@ -75,7 +75,8 @@
 						ISchedulingRule rule = ws.getRuleFactory().refreshRule(resource.getAdaptedResource());
 						ResourcesPlugin.getWorkspace().run(wsRunnable, rule, IWorkspace.AVOID_UPDATE, outerMonitor);
 					} catch (CoreException ce) {
-						throw new InvocationTargetException(ce);
+						throw new InvocationTargetException(ce, NLS.bind(Messages.UnlockAction_UnlockFailed_XMSG, resource
+								.getAdaptedResource().getFullPath().toString()));
 					}
 
 				}
diff --git a/bundles/org.eclipse.ui.resources.semantic/src/org/eclipse/core/internal/resources/semantic/ui/actions/messages.properties b/bundles/org.eclipse.ui.resources.semantic/src/org/eclipse/core/internal/resources/semantic/ui/actions/messages.properties
index 0ed1db5..11a1248 100644
--- a/bundles/org.eclipse.ui.resources.semantic/src/org/eclipse/core/internal/resources/semantic/ui/actions/messages.properties
+++ b/bundles/org.eclipse.ui.resources.semantic/src/org/eclipse/core/internal/resources/semantic/ui/actions/messages.properties
@@ -9,18 +9,27 @@
 #     Eduard Bartsch (SAP AG) - initial API and implementation
 #     Mathias Kinzler (SAP AG) - initial API and implementation
 ###############################################################################
-ActionBase_ActionCancelded_XGRP=Action Canceled
-ActionBase_ActionCanceled_XMSG=The action was canceled
+ActionBase_ActionCancelled_XGRP=Action Cancelled
+ActionBase_ActionCancelled_XMSG=The action was cancelled
+ActionBase_ActionNotCompleted_XMSG=Action could not be completed
+DeleteAction_CouldNotDeleteResource_XMSG=Could not delete resource {0}
 DeleteAction_Deleting_XMSG=Deleting resource {0}
 DiffAction_CompareAction_XGRP=Compare with Remote Version
+DiffAction_DiffFailedForFile_XMSG=Diff could not be performed for file {0}
 DiffAction_NoHistory_XMSG=The content provider does not provider revision history support
+EditAction_CouldNotOpenForEdit_XMSG=Resource {0} could not be opened for edit
 EditAction_Editing_XMSG=Opening file {0} for editing
+LockAction_CouldNotLockResource_XMSG=Could not lock resource {0}
 LockAction_LockingRes_XMSG=Locking resource {0}
 RemoveAction_ConfirmResourceRemoval_XGRP=Confirm Resource Removal
+RemoveAction_CouldNotRemoveResource_XMSG=Resource {0} could not be removed
 RemoveAction_DoYouWantToRemove_XMSG=Removal of some of selected resources may result in data loss. Do you want to remove the resources?
 RemoveAction_Remove_XGRP=Remove Action
 RemoveAction_Removing_XMSG=Removing resource {0}
+RevertAction_RevertFailed_XMSG=Could not revert file {0}
 RevertAction_Reverting_XMSG=Reverting file {0}
+SynchronizeAction_SyncFailedForResource_XMSG=Synchronization could not be completed for resource {0}
 SynchronizeAction_Synchronizing_XMSG=Synchronizing resource {0}
+UnlockAction_UnlockFailed_XMSG=Could not unlock resource {0}
 UnlockAction_Unlocking_XMSG=Unlocking resource {0}
 UnmapAction_Unmap_XGRP=Unmap Action