Bug 492182 - Add Terminate and Relaunch from Configurations, Relaunch
actions and Context based launch

Change-Id: Ic2fc123555e45655bce496db47e122d00eb3c8e8
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/TerminateToggleValue.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/TerminateToggleValue.java
new file mode 100644
index 0000000..f1bb6d5
--- /dev/null
+++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/TerminateToggleValue.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2016 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.debug.internal.ui;
+
+import org.eclipse.debug.internal.ui.launchConfigurations.LaunchShortcutExtension;
+
+/**
+ * Class stores the data for shortcut and if Shift was pressed with shortcut
+ * This is used to store that data for selected selection and later used at the
+ * launching of the shortcut
+ * 
+ * @since 3.12
+ */
+public class TerminateToggleValue {
+	private boolean fIsShift;
+	private LaunchShortcutExtension fShortcut;
+
+	public TerminateToggleValue(boolean isShift, LaunchShortcutExtension shortcut) {
+		fIsShift = isShift;
+		fShortcut = shortcut;
+	}
+
+	public boolean isShift() {
+		return fIsShift;
+	}
+
+	public LaunchShortcutExtension getShortcut() {
+		return fShortcut;
+	}
+
+}
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/LaunchShortcutAction.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/LaunchShortcutAction.java
index c0c3d1c..41a264a 100644
--- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/LaunchShortcutAction.java
+++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/LaunchShortcutAction.java
@@ -23,6 +23,7 @@
 import org.eclipse.debug.core.ILaunchConfiguration;
 import org.eclipse.debug.core.ILaunchConfigurationType;
 import org.eclipse.debug.internal.ui.DebugUIPlugin;
+import org.eclipse.debug.internal.ui.TerminateToggleValue;
 import org.eclipse.debug.internal.ui.contextlaunching.LaunchingResourceManager;
 import org.eclipse.debug.internal.ui.launchConfigurations.LaunchConfigurationManager;
 import org.eclipse.debug.internal.ui.launchConfigurations.LaunchShortcutExtension;
@@ -77,10 +78,12 @@
 		if(o instanceof IEditorPart) {
 			DebugUITools.storeLaunchToggleTerminate(o, isShift);
 			fShortcut.launch((IEditorPart) o, fMode);
+			DebugUITools.removeLaunchToggleTerminate(o);
 		}
 		else {
-			DebugUITools.storeLaunchToggleTerminate(ss, isShift);
+			DebugUITools.storeLaunchToggleTerminate(ss, new TerminateToggleValue(isShift, fShortcut));
 			fShortcut.launch(ss, fMode);
+			DebugUITools.removeLaunchToggleTerminate(ss);
 		}
 	}
 	
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/contextlaunching/ContextRunner.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/contextlaunching/ContextRunner.java
index 70e1bb4..7fded39 100644
--- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/contextlaunching/ContextRunner.java
+++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/contextlaunching/ContextRunner.java
@@ -21,6 +21,7 @@
 import org.eclipse.debug.core.ILaunchMode;
 import org.eclipse.debug.internal.ui.DebugUIPlugin;
 import org.eclipse.debug.internal.ui.IInternalDebugUIConstants;
+import org.eclipse.debug.internal.ui.TerminateToggleValue;
 import org.eclipse.debug.internal.ui.launchConfigurations.LaunchConfigurationManager;
 import org.eclipse.debug.internal.ui.launchConfigurations.LaunchConfigurationSelectionDialog;
 import org.eclipse.debug.internal.ui.launchConfigurations.LaunchShortcutExtension;
@@ -257,10 +258,12 @@
 		if(o instanceof IEditorPart) {
 			DebugUITools.storeLaunchToggleTerminate(o, isShift);
 			shortcut.launch((IEditorPart) o, mode);
+			DebugUITools.removeLaunchToggleTerminate(o);
 		}
 		else {
-			DebugUITools.storeLaunchToggleTerminate(selection, isShift);
+			DebugUITools.storeLaunchToggleTerminate(selection, new TerminateToggleValue(isShift, shortcut));
 			shortcut.launch(selection, mode);
+			DebugUITools.removeLaunchToggleTerminate(selection);
 		}
 	}
 	
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/DebugUITools.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/DebugUITools.java
index e0474df..6b80485 100644
--- a/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/DebugUITools.java
+++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/DebugUITools.java
@@ -11,9 +11,11 @@
 package org.eclipse.debug.ui;
 
 
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.LinkedHashSet;
+import java.util.List;
 import java.util.Set;
 
 import org.eclipse.core.commands.ExecutionEvent;
@@ -52,14 +54,17 @@
 import org.eclipse.debug.internal.ui.DelegatingModelPresentation;
 import org.eclipse.debug.internal.ui.IInternalDebugUIConstants;
 import org.eclipse.debug.internal.ui.LazyModelPresentation;
+import org.eclipse.debug.internal.ui.TerminateToggleValue;
 import org.eclipse.debug.internal.ui.actions.ActionMessages;
 import org.eclipse.debug.internal.ui.actions.ToggleBreakpointsTargetManager;
+import org.eclipse.debug.internal.ui.contextlaunching.LaunchingResourceManager;
 import org.eclipse.debug.internal.ui.contexts.DebugContextManager;
 import org.eclipse.debug.internal.ui.launchConfigurations.LaunchConfigurationDialog;
 import org.eclipse.debug.internal.ui.launchConfigurations.LaunchConfigurationManager;
 import org.eclipse.debug.internal.ui.launchConfigurations.LaunchConfigurationPropertiesDialog;
 import org.eclipse.debug.internal.ui.launchConfigurations.LaunchConfigurationsDialog;
 import org.eclipse.debug.internal.ui.launchConfigurations.LaunchGroupExtension;
+import org.eclipse.debug.internal.ui.launchConfigurations.LaunchShortcutExtension;
 import org.eclipse.debug.internal.ui.memory.MemoryRenderingManager;
 import org.eclipse.debug.internal.ui.sourcelookup.SourceLookupFacility;
 import org.eclipse.debug.internal.ui.sourcelookup.SourceLookupUIUtils;
@@ -772,10 +777,10 @@
 	 * @since 2.1
 	 */
 	public static void launch(final ILaunchConfiguration configuration, final String mode) {
-		launch(configuration, mode, DebugUITools.findTogglelaunchForConfig(configuration));
+		launch(configuration, mode, DebugUITools.findToggleLaunchForConfig(configuration, mode));
 	}
 
-	private static HashMap<Object, Boolean> fgLaunchToggleTerminateMap = new HashMap<>();
+	private static HashMap<Object, Object> fgLaunchToggleTerminateMap = new HashMap<>();
 
 	/**
 	 * Stores the toggle data for launch in a Map to be used while launching to
@@ -786,26 +791,39 @@
 	 *            Shift)
 	 * @since 3.12
 	 */
-	public static void storeLaunchToggleTerminate(Object data, Boolean isShift) {
+	public static void storeLaunchToggleTerminate(Object data, Object isShift) {
 		synchronized (fgLaunchToggleTerminateMap) {
 			fgLaunchToggleTerminateMap.put(data, isShift);
 		}
 	}
 
 	/**
+	 * Stores the toggle data for launch in a Map to be used while launching to
+	 * decide if previous launch for same configuration can be terminated.
+	 * 
+	 * @param data the editor or selected tree node
 	 * @since 3.12
 	 */
-	private static boolean getAndRemoveLaunchToggleTerminate(Object data) {
-
-		Boolean isShift;
+	public static void removeLaunchToggleTerminate(Object data) {
 		synchronized (fgLaunchToggleTerminateMap) {
-			isShift = fgLaunchToggleTerminateMap.get(data);
-		}
-		if (isShift != null) {
-			synchronized (fgLaunchToggleTerminateMap) {
+			if (fgLaunchToggleTerminateMap.containsKey(data)) {
 				fgLaunchToggleTerminateMap.remove(data);
 			}
-			return isShift.booleanValue();
+		}
+	}
+
+	/**
+	 * @since 3.12
+	 */
+	private static boolean isShiftTerminateLaunch(Object data) {
+		Object value;
+		synchronized (fgLaunchToggleTerminateMap) {
+			value = fgLaunchToggleTerminateMap.get(data);
+		}
+		if (value instanceof TerminateToggleValue) {
+			return ((TerminateToggleValue) value).isShift();
+		} else if (value instanceof Boolean) {
+			return ((Boolean) value).booleanValue();
 		}
 		return Boolean.FALSE;
 	}
@@ -813,7 +831,19 @@
 	/**
 	 * @since 3.12
 	 */
-	private static boolean findTogglelaunchForConfig(ILaunchConfiguration configuration) {
+
+	private static Object getToggleTerminateValue(Object data) {
+		Object value;
+		synchronized (fgLaunchToggleTerminateMap) {
+			value = fgLaunchToggleTerminateMap.get(data);
+		}
+		return value;
+	}
+
+	/**
+	 * @since 3.12
+	 */
+	private static boolean findToggleLaunchForConfig(ILaunchConfiguration configuration, String mode) {
 		ILaunchManager launchManager = DebugPlugin.getDefault().getLaunchManager();
 		ILaunch[] launches = launchManager.getLaunches();
 		for (ILaunch iLaunch : launches) {
@@ -826,7 +856,7 @@
 							if (key instanceof IEditorPart) {
 								IEditorInput input = ((IEditorPart) key).getEditorInput();
 								if (input.getAdapter(IResource.class).equals(configResource[0])) {
-									return getAndRemoveLaunchToggleTerminate(key);
+									return isShiftTerminateLaunch(key);
 								}
 							} else if (key instanceof TreeSelection) {
 								TreeSelection selection = (TreeSelection) key;
@@ -835,7 +865,28 @@
 									Object lastSegmentObj = treePath[0].getLastSegment();
 									IResource selectedResource = ((IAdaptable) lastSegmentObj).getAdapter(IResource.class);
 									if (selectedResource!= null && selectedResource.equals(configResource[0])) {
-										return getAndRemoveLaunchToggleTerminate(key);
+										return isShiftTerminateLaunch(key);
+									}
+								}
+							}
+						}
+					} else {
+						for (Iterator<Object> iter = fgLaunchToggleTerminateMap.keySet().iterator(); iter.hasNext();) {
+							Object key = iter.next();
+							if (key instanceof IStructuredSelection) {
+								Object toggleValue = getToggleTerminateValue(key);
+								if (toggleValue instanceof TerminateToggleValue) {
+									LaunchingResourceManager lrm = DebugUIPlugin.getDefault().getLaunchingResourceManager();
+									ArrayList<LaunchShortcutExtension> shortcuts = new ArrayList<LaunchShortcutExtension>();
+									LaunchShortcutExtension shortcut = ((TerminateToggleValue) toggleValue).getShortcut();
+									shortcuts.add(shortcut);
+									IResource resource = SelectedResourceManager.getDefault().getSelectedResource();
+									if (resource == null) {
+										resource = lrm.getLaunchableResource(shortcuts, (IStructuredSelection) key);
+									}
+									List<ILaunchConfiguration> configs = lrm.getParticipatingLaunchConfigurations((IStructuredSelection) key, resource, shortcuts, mode);
+									if (configs.contains(configuration)) {
+										return ((TerminateToggleValue) toggleValue).isShift();
 									}
 								}
 							}
@@ -843,7 +894,7 @@
 					}
 
 				} catch (CoreException e) {
-					e.printStackTrace();
+					DebugUIPlugin.log(e);
 				}
 			}
 		}