/******************************************************************************* * Copyright (c) 2000, 2018 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.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; import org.eclipse.core.commands.ExecutionException; import org.eclipse.core.commands.operations.IOperationHistory; import org.eclipse.core.commands.operations.IUndoContext; import org.eclipse.core.commands.operations.IUndoableOperation; import org.eclipse.core.commands.operations.ObjectUndoContext; import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IExtension; import org.eclipse.core.runtime.IExtensionPoint; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Status; import org.eclipse.debug.core.DebugException; import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.ILaunch; import org.eclipse.debug.core.ILaunchConfiguration; import org.eclipse.debug.core.ILaunchConfigurationType; import org.eclipse.debug.core.ILaunchDelegate; import org.eclipse.debug.core.ILaunchManager; import org.eclipse.debug.core.model.IBreakpoint; import org.eclipse.debug.core.model.IDebugElement; import org.eclipse.debug.core.model.IDebugTarget; import org.eclipse.debug.core.model.IProcess; import org.eclipse.debug.core.model.ISourceLocator; import org.eclipse.debug.internal.core.IConfigurationElementConstants; import org.eclipse.debug.internal.ui.DebugPluginImages; import org.eclipse.debug.internal.ui.DebugUIPlugin; import org.eclipse.debug.internal.ui.DefaultLabelProvider; 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.LaunchConfigurationTabGroupViewer; 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; import org.eclipse.debug.internal.ui.stringsubstitution.SelectedResourceManager; import org.eclipse.debug.ui.actions.IToggleBreakpointsTargetManager; import org.eclipse.debug.ui.contexts.IDebugContextListener; import org.eclipse.debug.ui.contexts.IDebugContextManager; import org.eclipse.debug.ui.contexts.IDebugContextService; import org.eclipse.debug.ui.memory.IMemoryRenderingManager; import org.eclipse.debug.ui.sourcelookup.ISourceContainerBrowser; import org.eclipse.debug.ui.sourcelookup.ISourceLookupResult; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.TreePath; import org.eclipse.jface.viewers.TreeSelection; import org.eclipse.jface.window.Window; import org.eclipse.osgi.util.NLS; import org.eclipse.swt.custom.BusyIndicator; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IViewSite; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.IWorkbenchPartSite; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.console.IConsole; import org.eclipse.ui.handlers.HandlerUtil; import org.eclipse.ui.ide.undo.DeleteMarkersOperation; import org.eclipse.ui.ide.undo.WorkspaceUndoUtil; /** * This class provides utilities for clients of the debug UI. *

* Images retrieved from this facility should not be disposed. * The images will be disposed when this plug-in is shutdown. *

*

* Note: all methods in this class are expected to be called * on the Display thread unless otherwise noted. *

* @noinstantiate This class is not intended to be instantiated by clients. * @noextend This class is not intended to be subclassed by clients. */ public class DebugUITools { /** * The undo context for breakpoints. * * @since 3.7 */ private static ObjectUndoContext fgBreakpointsUndoContext; /** * Returns the shared image managed under the given key, or null * if none. *

* Note that clients MUST NOT dispose the image returned by this method. *

*

* See IDebugUIConstants for available images. *

* * @param key the image key * @return the image, or null if none * @see IDebugUIConstants */ public static Image getImage(String key) { return DebugPluginImages.getImage(key); } /** * Returns the shared image descriptor managed under the given key, or * null if none. *

* See IDebugUIConstants for available image descriptors. *

* * @param key the image descriptor key * @return the image descriptor, or null if none * @see IDebugUIConstants */ public static ImageDescriptor getImageDescriptor(String key) { return DebugPluginImages.getImageDescriptor(key); } /** * Returns the default image descriptor for the given element. * * @param element the element * @return the image descriptor or null if none */ public static ImageDescriptor getDefaultImageDescriptor(Object element) { String imageKey= getDefaultImageKey(element); if (imageKey == null) { return null; } return DebugPluginImages.getImageDescriptor(imageKey); } private static String getDefaultImageKey(Object element) { return ((DefaultLabelProvider)DebugUIPlugin.getDefaultLabelProvider()).getImageKey(element); } /** * Returns the preference store for the debug UI plug-in. * * @return preference store */ public static IPreferenceStore getPreferenceStore() { return DebugUIPlugin.getDefault().getPreferenceStore(); } /** * Returns a new debug model presentation that delegates to * appropriate debug models. *

* It is the client's responsibility dispose the presentation. *

* * @see org.eclipse.jface.viewers.IBaseLabelProvider#dispose() * @return a debug model presentation * @since 2.0 */ public static IDebugModelPresentation newDebugModelPresentation() { return new DelegatingModelPresentation(); } /** * Returns a new debug model presentation for specified * debug model, or null if a presentation does * not exist. *

* It is the client's responsibility dispose the presentation. *

* * @param identifier debug model identifier * @see org.eclipse.jface.viewers.IBaseLabelProvider#dispose() * @return a debug model presentation, or null * @since 2.0 */ public static IDebugModelPresentation newDebugModelPresentation(String identifier) { IExtensionPoint point= Platform.getExtensionRegistry().getExtensionPoint(DebugUIPlugin.getUniqueIdentifier(), IDebugUIConstants.ID_DEBUG_MODEL_PRESENTATION); if (point != null) { IExtension[] extensions= point.getExtensions(); for (int i= 0; i < extensions.length; i++) { IExtension extension= extensions[i]; IConfigurationElement[] configElements= extension.getConfigurationElements(); for (int j= 0; j < configElements.length; j++) { IConfigurationElement elt= configElements[j]; String id= elt.getAttribute("id"); //$NON-NLS-1$ if (id != null && id.equals(identifier)) { return new LazyModelPresentation(elt); } } } } return null; } /** * Returns the element of the currently selected context in the * active workbench window. Returns null if there is no * current debug context. *

* This method used to return null when called from a non-UI thread, * but since 3.1, this methods also works when called from a non-UI thread. *

* @return the currently selected debug context, or null * @since 2.0 */ public static IAdaptable getDebugContext() { IWorkbenchWindow activeWindow = SelectedResourceManager.getDefault().getActiveWindow(); if (activeWindow != null) { ISelection activeContext = DebugUITools.getDebugContextManager().getContextService(activeWindow).getActiveContext(); return getDebugContextElementForSelection(activeContext); } return null; } /** * Returns the currently selected context in the given part or part's * workbench window. Returns null if there is no current * debug context. * @param part workbench part where the active context is to be evaluated * @return the currently selected debug context in the given workbench part, * or null * @since 3.8 * @see IDebugContextService#getActiveContext(String) * @see IDebugContextService#getActiveContext(String, String) */ public static ISelection getDebugContextForPart(IWorkbenchPart part) { IWorkbenchPartSite site = part.getSite(); IWorkbenchWindow partWindow = site.getWorkbenchWindow(); if (partWindow != null) { IDebugContextService contextService = DebugUITools.getDebugContextManager().getContextService(partWindow); if (site instanceof IViewSite) { return contextService.getActiveContext(site.getId(), ((IViewSite)site).getSecondaryId()); } else { return contextService.getActiveContext(site.getId()); } } return null; } /** * Return the undo context that should be used for operations involving breakpoints. * * @return the undo context for breakpoints * @since 3.7 */ public static synchronized IUndoContext getBreakpointsUndoContext() { if (fgBreakpointsUndoContext == null) { fgBreakpointsUndoContext= new ObjectUndoContext(new Object(), "Breakpoints Context"); //$NON-NLS-1$ fgBreakpointsUndoContext.addMatch(WorkspaceUndoUtil.getWorkspaceUndoContext()); } return fgBreakpointsUndoContext; } /** * Deletes the given breakpoints using the operation history, which allows to undo the deletion. * * @param breakpoints the breakpoints to delete * @param shell the shell used for potential user interactions, or null if unknown * @param progressMonitor the progress monitor * @throws CoreException if the deletion fails * @since 3.7 */ public static void deleteBreakpoints(IBreakpoint[] breakpoints, final Shell shell, IProgressMonitor progressMonitor) throws CoreException { IMarker[] markers= new IMarker[breakpoints.length]; int markerCount; for (markerCount= 0; markerCount < breakpoints.length; markerCount++) { if (!breakpoints[markerCount].isRegistered()) { break; } markers[markerCount]= breakpoints[markerCount].getMarker(); if (markers[markerCount] == null) { break; } } // We only offer undo support if all breakpoints are registered and have associated markers boolean allowUndo= markerCount == breakpoints.length; DebugPlugin.getDefault().getBreakpointManager().removeBreakpoints(breakpoints, !allowUndo); if (allowUndo) { for (int i= 0; i < markers.length; i++) { markers[i].setAttribute(DebugPlugin.ATTR_BREAKPOINT_IS_DELETED, true); } IAdaptable context= null; if (shell != null) { context= new IAdaptable() { @SuppressWarnings("unchecked") @Override public T getAdapter(Class adapter) { if (adapter == Shell.class) { return (T) shell; } return null; } }; } String operationName= markers.length == 1 ? ActionMessages.DeleteBreakpointOperationName : ActionMessages.DeleteBreakpointsOperationName; IUndoableOperation deleteMarkerOperation= new DeleteMarkersOperation(markers, operationName); deleteMarkerOperation.removeContext(WorkspaceUndoUtil.getWorkspaceUndoContext()); deleteMarkerOperation.addContext(DebugUITools.getBreakpointsUndoContext()); IOperationHistory operationHistory= PlatformUI.getWorkbench().getOperationSupport().getOperationHistory(); try { operationHistory.execute(deleteMarkerOperation, progressMonitor, context); } catch (ExecutionException e) { throw new CoreException(DebugUIPlugin.newErrorStatus("Exception while deleting breakpoint markers", e)); //$NON-NLS-1$ } } } /** * Returns the currently active context for the given workbench part. Returns null * if there is no current debug context.

* * @param site the part's site where to look up the active context * @return the currently active debug context in the given part, or null * @since 3.7 */ public static IAdaptable getPartDebugContext(IWorkbenchPartSite site) { IDebugContextService service = DebugUITools.getDebugContextManager().getContextService(site.getWorkbenchWindow()); String id = null; String secondaryId = null; id = site.getId(); if (site instanceof IViewSite) { secondaryId = ((IViewSite)site).getSecondaryId(); } ISelection activeContext = service.getActiveContext(id, secondaryId); return getDebugContextElementForSelection(activeContext); } /** * Adds the given debug context listener as a listener to the debug context changed events, in * the context of the given workbench part. *

* This method is a utility method which ultimately calls * {@link IDebugContextService#addDebugContextListener(IDebugContextListener, String, String)} * using the part id parameters extracted from the given part parameter. *

* * @param site the part's site to get the part ID and part secondary ID from * @param listener Debug context listener to add * * @see IDebugContextService#addDebugContextListener(IDebugContextListener, String, String) * @see IDebugContextManager#addDebugContextListener(IDebugContextListener) * @since 3.7 */ public static void addPartDebugContextListener(IWorkbenchPartSite site, IDebugContextListener listener) { IDebugContextService service = DebugUITools.getDebugContextManager().getContextService(site.getWorkbenchWindow()); String id = site.getId(); String secondaryId = null; if (site instanceof IViewSite) { secondaryId = ((IViewSite)site).getSecondaryId(); } service.addDebugContextListener(listener, id, secondaryId); } /** * Removes the given debug context listener as a listener to the debug context changed events, * in the context of the given workbench part. *

* This method is a utility method which ultimately calls * {@link IDebugContextService#removeDebugContextListener(IDebugContextListener, String, String)} * using the part id parameters extracted from the given part parameter. *

* * @param site the part's site to get the part ID and part secondary ID from * @param listener Debug context listener to remove * * @see IDebugContextService#removeDebugContextListener(IDebugContextListener, String, String) * @see IDebugContextManager#removeDebugContextListener(IDebugContextListener) * @since 3.7 */ public static void removePartDebugContextListener(IWorkbenchPartSite site, IDebugContextListener listener) { IDebugContextService service = DebugUITools.getDebugContextManager().getContextService(site.getWorkbenchWindow()); String id = site.getId(); String secondaryId = null; if (site instanceof IViewSite) { secondaryId = ((IViewSite)site).getSecondaryId(); } service.removeDebugContextListener(listener, id, secondaryId); } /** * Extracts the first element from the given selection and casts it to IAdaptable. * * @param activeContext the selection * @return an adaptable */ private static IAdaptable getDebugContextElementForSelection(ISelection activeContext) { if (activeContext instanceof IStructuredSelection) { IStructuredSelection selection = (IStructuredSelection) activeContext; if (!selection.isEmpty()) { Object firstElement = selection.getFirstElement(); if (firstElement instanceof IAdaptable) { return (IAdaptable) firstElement; } } } return null; } /** * Returns the currently selected resource in the active workbench window, * or null if none. If an editor is active, the resource adapter * associated with the editor is returned, if any. * * @return selected resource or null * @since 3.0 */ public static IResource getSelectedResource() { return SelectedResourceManager.getDefault().getSelectedResource(); } /** * Returns the process associated with the current debug context. * If there is no debug context currently, the most recently * launched process is returned. If there is no current process * null is returned. * * @return the current process, or null * @since 2.0 */ public static IProcess getCurrentProcess() { IAdaptable context = getDebugContext(); if (context == null) { ILaunch[] launches = DebugPlugin.getDefault().getLaunchManager().getLaunches(); if (launches.length > 0) { context = launches[launches.length - 1]; } } if (context instanceof IDebugElement) { return ((IDebugElement)context).getDebugTarget().getProcess(); } if (context instanceof IProcess) { return (IProcess)context; } if (context instanceof ILaunch) { ILaunch launch= (ILaunch)context; IDebugTarget target= launch.getDebugTarget(); if (target != null) { IProcess process = target.getProcess(); if (process != null) { return process; } } IProcess[] ps = launch.getProcesses(); if (ps.length > 0) { return ps[ps.length - 1]; } } if (context != null) { return context.getAdapter(IProcess.class); } return null; } /** * Open the launch configuration dialog with the specified initial selection. * The selection may be null, or contain any mix of * ILaunchConfiguration or ILaunchConfigurationType * elements. *

* Before opening a new dialog, this method checks if there is an existing open * launch configuration dialog. If there is, this dialog is used with the * specified selection. If there is no existing dialog, a new one is created. *

*

* Note that if an existing dialog is reused, the mode argument is ignored * and the existing dialog keeps its original mode. *

* * @param shell the parent shell for the launch configuration dialog * @param selection the initial selection for the dialog * @param mode the mode (run or debug) in which to open the launch configuration dialog. * This should be one of the constants defined in ILaunchManager. * @return the return code from opening the launch configuration dialog - * one of Window.OK or Window.CANCEL. Window.CANCEL * is returned if an invalid launch group identifier is provided. * @see ILaunchGroup * @since 2.0 * @deprecated use openLaunchConfigurationDialogOnGroup(Shell, IStructuredSelection, String) * to specify the launch group that the dialog should be opened on. This method will open * on the launch group with the specified mode and a null category */ @Deprecated public static int openLaunchConfigurationDialog(Shell shell, IStructuredSelection selection, String mode) { ILaunchGroup[] groups = getLaunchGroups(); for (int i = 0; i < groups.length; i++) { ILaunchGroup group = groups[i]; if (group.getMode().equals(mode) && group.getCategory() == null) { return openLaunchConfigurationDialogOnGroup(shell, selection, group.getIdentifier()); } } return Window.CANCEL; } /** * Open the launch configuration dialog with the specified initial selection. * The selection may be null, or contain any mix of * ILaunchConfiguration or ILaunchConfigurationType * elements. *

* Before opening a new dialog, this method checks if there is an existing open * launch configuration dialog. If there is, this dialog is used with the * specified selection. If there is no existing dialog, a new one is created. *

*

* Note that if an existing dialog is reused, the mode argument is ignored * and the existing dialog keeps its original mode. *

* * @param shell the parent shell for the launch configuration dialog * @param selection the initial selection for the dialog * @param groupIdentifier the identifier of the launch group to display (corresponds to * the identifier of a launch group extension) * @return The return code from opening the launch configuration dialog - * one of Window.OK or Window.CANCEL. Window.CANCEL * is returned if an invalid launch group identifier is provided. * @see ILaunchGroup * @since 2.1 */ public static int openLaunchConfigurationDialogOnGroup(Shell shell, IStructuredSelection selection, String groupIdentifier) { return openLaunchConfigurationDialogOnGroup(shell, selection, groupIdentifier, null); } /** * Open the launch configuration dialog with the specified initial selection. * The selection may be null, or contain any mix of * ILaunchConfiguration or ILaunchConfigurationType * elements. *

* Before opening a new dialog, this method checks if there is an existing open * launch configuration dialog. If there is, this dialog is used with the * specified selection. If there is no existing dialog, a new one is created. *

*

* Note that if an existing dialog is reused, the mode argument is ignored * and the existing dialog keeps its original mode. *

*

* If a status is specified, a status handler is consulted to handle the * status. The status handler is passed the instance of the launch * configuration dialog that is opened. This gives the status handler an * opportunity to perform error handling/initialization as required. *

* @param shell the parent shell for the launch configuration dialog * @param selection the initial selection for the dialog * @param groupIdentifier the identifier of the launch group to display (corresponds to * the identifier of a launch group extension) * @param status the status to display in the dialog, or null * if none * @return the return code from opening the launch configuration dialog - * one of Window.OK or Window.CANCEL. Window.CANCEL * is returned if an invalid launch group identifier is provided. * @see org.eclipse.debug.core.IStatusHandler * @see ILaunchGroup * @since 2.1 */ public static int openLaunchConfigurationDialogOnGroup(final Shell shell, final IStructuredSelection selection, final String groupIdentifier, final IStatus status) { final int[] result = new int[1]; Runnable r = () -> { LaunchConfigurationsDialog dialog = (LaunchConfigurationsDialog) LaunchConfigurationsDialog .getCurrentlyVisibleLaunchConfigurationDialog(); if (dialog != null) { dialog.setInitialSelection(selection); dialog.doInitialTreeSelection(); if (status != null) { dialog.handleStatus(status); } result[0] = Window.OK; } else { LaunchGroupExtension ext = DebugUIPlugin.getDefault().getLaunchConfigurationManager() .getLaunchGroup(groupIdentifier); if (ext != null) { dialog = new LaunchConfigurationsDialog(shell, ext); dialog.setOpenMode(LaunchConfigurationsDialog.LAUNCH_CONFIGURATION_DIALOG_OPEN_ON_SELECTION); dialog.setInitialSelection(selection); dialog.setInitialStatus(status); result[0] = dialog.open(); } else { result[0] = Window.CANCEL; } } }; BusyIndicator.showWhile(DebugUIPlugin.getStandardDisplay(), r); return result[0]; } /** * Open the launch configuration properties dialog on the specified launch * configuration. * * @param shell the parent shell for the launch configuration dialog * @param configuration the configuration to display * @param groupIdentifier group identifier of the launch group the launch configuration * belongs to * @return the return code from opening the launch configuration dialog - * one of Window.OK or Window.CANCEL. Window.CANCEL * is returned if an invalid launch group identifier is provided. * @see ILaunchGroup * @since 2.1 */ public static int openLaunchConfigurationPropertiesDialog(Shell shell, ILaunchConfiguration configuration, String groupIdentifier) { return openLaunchConfigurationPropertiesDialog(shell, configuration, groupIdentifier, null); } /** * Open the launch configuration properties dialog on the specified launch * configuration. * * @param shell the parent shell for the launch configuration dialog * @param configuration the configuration to display * @param groupIdentifier group identifier of the launch group the launch configuration * belongs to * @param status the status to display, or null if none * @return the return code from opening the launch configuration dialog - * one of Window.OK or Window.CANCEL. Window.CANCEL * is returned if an invalid launch group identifier is provided. * @see ILaunchGroup * @since 3.0 */ public static int openLaunchConfigurationPropertiesDialog(Shell shell, ILaunchConfiguration configuration, String groupIdentifier, IStatus status) { LaunchGroupExtension group = DebugUIPlugin.getDefault().getLaunchConfigurationManager().getLaunchGroup(groupIdentifier); if (group != null) { LaunchConfigurationPropertiesDialog dialog = new LaunchConfigurationPropertiesDialog(shell, configuration, group); dialog.setInitialStatus(status); return dialog.open(); } return Window.CANCEL; } /** * Open the launch configuration dialog on the specified launch * configuration. The dialog displays the tabs for a single configuration * only (a tree of launch configuration is not displayed), and provides a * launch (run or debug) button. *

* If a status is specified, a status handler is consulted to handle the * status. The status handler is passed the instance of the launch * configuration dialog that is opened. This gives the status handler an * opportunity to perform error handling/initialization as required. *

* @param shell the parent shell for the launch configuration dialog * @param configuration the configuration to display * @param groupIdentifier group identifier of the launch group the launch configuration * belongs to * @param status the status to display, or null if none * @return the return code from opening the launch configuration dialog - * one of Window.OK or Window.CANCEL. Window.CANCEL * is returned if an invalid launch group identifier is provided. * @see ILaunchGroup * @since 2.1 */ public static int openLaunchConfigurationDialog(Shell shell, ILaunchConfiguration configuration, String groupIdentifier, IStatus status) { LaunchGroupExtension group = DebugUIPlugin.getDefault().getLaunchConfigurationManager().getLaunchGroup(groupIdentifier); if (group != null) { LaunchConfigurationDialog dialog = new LaunchConfigurationDialog(shell, configuration, group); dialog.setInitialStatus(status); return dialog.open(); } return Window.CANCEL; } /** * Saves all dirty editors and builds the workspace according to current * preference settings, and returns whether a launch should proceed. *

* The following preferences affect whether dirty editors are saved, * and/or if the user is prompted to save dirty editors:

* The following preference affects whether a build is performed before * launching (if required): *

* * @return whether a launch should proceed * @since 2.0 * @deprecated Saving has been moved to the launch delegate LaunchConfigurationDelegate to allow for scoped saving * of resources that are only involved in the current launch, no longer the entire workspace */ @Deprecated public static boolean saveAndBuildBeforeLaunch() { return DebugUIPlugin.saveAndBuild(); } /** * Saves all dirty editors according to current * preference settings, and returns whether a launch should proceed. *

* The following preferences affect whether dirty editors are saved, * and/or if the user is prompted to save dirty editors:

*

* * @return whether a launch should proceed * @since 2.1 * @deprecated Saving has been moved to the launch delegate LaunchConfigurationDelegate to allow for scoped saving * of resources that are only involved in the current launch, no longer the entire workspace */ @Deprecated public static boolean saveBeforeLaunch() { return DebugUIPlugin.preLaunchSave(); } /** * Saves and builds the workspace according to current preference settings, * and launches the given launch configuration in the specified mode. It * terminates the current launch for the same configuration if it was * specified via Preferences or toggled by Shift. *

* This method must be called in the UI thread. *

* * @param configuration the configuration to launch * @param mode launch mode - run or debug * @since 2.1 */ public static void launch(final ILaunchConfiguration configuration, final String mode) { launch(configuration, mode, DebugUITools.findToggleLaunchForConfig(configuration, mode)); } private static HashMap fgLaunchToggleTerminateMap = new HashMap<>(); /** * 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 * @param isShift is Shift pressed (use false if no support for * Shift) * @since 3.12 */ 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 */ public static void removeLaunchToggleTerminate(Object data) { synchronized (fgLaunchToggleTerminateMap) { if (fgLaunchToggleTerminateMap.containsKey(data)) { fgLaunchToggleTerminateMap.remove(data); } } } /** * @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; } /** * @since 3.12 */ 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) { if (configuration.contentsEqual(iLaunch.getLaunchConfiguration())) { try { IResource[] configResource = iLaunch.getLaunchConfiguration().getMappedResources(); if (configResource != null && configResource.length == 1) { for (Iterator iter = fgLaunchToggleTerminateMap.keySet().iterator(); iter.hasNext();) { Object key = iter.next(); if (key instanceof IEditorPart) { IEditorInput input = ((IEditorPart) key).getEditorInput(); if (input.getAdapter(IResource.class).equals(configResource[0])) { return isShiftTerminateLaunch(key); } } else if (key instanceof TreeSelection) { TreeSelection selection = (TreeSelection) key; TreePath[] treePath = selection.getPaths(); if (treePath != null && treePath.length == 1) { Object lastSegmentObj = treePath[0].getLastSegment(); IResource selectedResource = ((IAdaptable) lastSegmentObj).getAdapter(IResource.class); if (selectedResource!= null && selectedResource.equals(configResource[0])) { return isShiftTerminateLaunch(key); } } } } } else { for (Iterator 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 shortcuts = new ArrayList<>(); LaunchShortcutExtension shortcut = ((TerminateToggleValue) toggleValue).getShortcut(); shortcuts.add(shortcut); IResource resource = SelectedResourceManager.getDefault().getSelectedResource(); if (resource == null) { resource = lrm.getLaunchableResource(shortcuts, (IStructuredSelection) key); } List configs = lrm.getParticipatingLaunchConfigurations((IStructuredSelection) key, resource, shortcuts, mode); if (configs.contains(configuration)) { return ((TerminateToggleValue) toggleValue).isShift(); } } } } } } catch (CoreException e) { DebugUIPlugin.log(e); } } } return false; } /** * Saves and builds the workspace according to current preference settings, * and launches the given launch configuration in the specified mode. *

* This method must be called in the UI thread. *

* * @param configuration the configuration to launch * @param mode launch mode - run or debug * @since 3.12 */ public static void reLaunch(final ILaunchConfiguration configuration, final String mode) { boolean launchInBackground = true; try { launchInBackground = configuration.getAttribute(IDebugUIConstants.ATTR_LAUNCH_IN_BACKGROUND, true); } catch (CoreException e) { DebugUIPlugin.log(e); } if (launchInBackground) { DebugUIPlugin.launchInBackground(configuration, mode); } else { DebugUIPlugin.launchInForeground(configuration, mode); } } /** * Saves and builds the workspace according to current preference settings, * and launches the given launch configuration in the specified mode. It * terminates the current launch for the same configuration if it was * specified via Preferences or toggled by Shift *

* This method must be called in the UI thread. *

* * @param configuration the configuration to launch * @param mode launch mode - run or debug * @param isShift is Shift pressed (use false if no support for * Shift) * @since 3.12 */ public static void launch(final ILaunchConfiguration configuration, final String mode, boolean isShift) { if (DebugUIPlugin.getDefault().getPreferenceStore().getBoolean(IInternalDebugUIConstants.PREF_TERMINATE_AND_RELAUNCH_LAUNCH_ACTION) != isShift) { ILaunchManager launchManager = DebugPlugin.getDefault().getLaunchManager(); ILaunch[] launches = launchManager.getLaunches(); for (ILaunch iLaunch : launches) { if (configuration.contentsEqual(iLaunch.getLaunchConfiguration())) { synchronized (fgLaunchList) { fgLaunchList.add(iLaunch); } } } } if (!fgLaunchList.isEmpty()) { Thread t = new Thread(fgLaunchTerminate); t.start(); try { t.join(); } catch (InterruptedException e1) { DebugUIPlugin.log(e1); return; } } boolean launchInBackground = true; try { launchInBackground = configuration.getAttribute(IDebugUIConstants.ATTR_LAUNCH_IN_BACKGROUND, true); } catch (CoreException e) { DebugUIPlugin.log(e); } if (launchInBackground) { DebugUIPlugin.launchInBackground(configuration, mode); } else { DebugUIPlugin.launchInForeground(configuration, mode); } } private static Set fgLaunchList = new LinkedHashSet<>(); private static Runnable fgLaunchTerminate = () -> { String launchConfigName = null; Set launchList; try { synchronized (fgLaunchList) { launchList = new LinkedHashSet<>(fgLaunchList); fgLaunchList.clear(); } for (ILaunch iLaunch : launchList) { launchConfigName = iLaunch.getLaunchConfiguration().getName(); iLaunch.terminate(); } } catch (DebugException e) { DebugUIPlugin.log(new Status(IStatus.ERROR, DebugUIPlugin.getUniqueIdentifier(), NLS.bind(ActionMessages.TerminateAndLaunchFailure, launchConfigName), e)); } }; /** * Builds the workspace according to current preference settings, and launches * the given configuration in the specified mode, returning the resulting launch * object. *

* The following preference affects whether a build is performed before * launching (if required):

    *
  • PREF_BUILD_BEFORE_LAUNCH
  • *
*

* * @param configuration the configuration to launch * @param mode the mode to launch in * @param monitor progress monitor * @return the resulting launch object * @throws CoreException if building or launching fails * @since 2.1 */ public static ILaunch buildAndLaunch(ILaunchConfiguration configuration, String mode, IProgressMonitor monitor) throws CoreException { return DebugUIPlugin.buildAndLaunch(configuration, mode, monitor); } /** * Returns the perspective to switch to when a configuration of the given type * is launched in the given mode, or null if no switch should take * place. * * In 3.3 this method is equivalent to calling getLaunchPerspective(ILaunchConfigurationType type, Set modes, ILaunchDelegate delegate), * with the 'mode' parameter comprising a single element set and passing null as the launch delegate. * * @param type launch configuration type * @param mode launch mode identifier * @return perspective identifier or null * @since 3.0 */ public static String getLaunchPerspective(ILaunchConfigurationType type, String mode) { return DebugUIPlugin.getDefault().getPerspectiveManager().getLaunchPerspective(type, mode); } /** * Returns the perspective id to switch to when a configuration of the given type launched with the specified delegate * is launched in the given mode set, or null if no switch should occurr. * @param type the configuration type * @param delegate the launch delegate * @param modes the set of modes * @return the perspective id or null if no switch should occur * * @since 3.3 */ public static String getLaunchPerspective(ILaunchConfigurationType type, ILaunchDelegate delegate, Set modes) { return DebugUIPlugin.getDefault().getPerspectiveManager().getLaunchPerspective(type, modes, delegate); } /** * Sets the perspective to switch to when a configuration of the given type * is launched in the given mode. PERSPECTIVE_NONE indicates no * perspective switch should take place. PERSPECTIVE_DEFAULT indicates * a default perspective switch should take place, as defined by the associated * launch tab group extension. * * In 3.3 this method is equivalent to calling setLaunchPerspective(ILaunchConfigurationType type, Set modes, ILaunchDelegate delegate, String perspectiveid), * with the parameter 'mode' used in the set modes, and null passed as the delegate * * @param type launch configuration type * @param mode launch mode identifier * @param perspective identifier, PERSPECTIVE_NONE, or * PERSPECTIVE_DEFAULT * @since 3.0 */ public static void setLaunchPerspective(ILaunchConfigurationType type, String mode, String perspective) { DebugUIPlugin.getDefault().getPerspectiveManager().setLaunchPerspective(type, mode, perspective); } /** * Sets the perspective to switch to when a configuration of the specified type and launched using the * specified launch delegate is launched in the specified modeset. PERSPECTIVE_NONE indicates no * perspective switch should take place. * * Passing null for the launch delegate is quivalent to using the default perspective for the specified * type. * @param type the configuration type * @param delegate the launch delegate * @param modes the set of modes * @param perspectiveid identifier or PERSPECTIVE_NONE * * @since 3.3 */ public static void setLaunchPerspective(ILaunchConfigurationType type, ILaunchDelegate delegate, Set modes, String perspectiveid) { DebugUIPlugin.getDefault().getPerspectiveManager().setLaunchPerspective(type, modes, delegate, perspectiveid); } /** * Returns whether the given launch configuration is private. Generally, * private launch configurations should not be displayed to the user. The * private status of a launch configuration is determined by the * IDebugUIConstants.ATTR_PRIVATE attribute. * * @param configuration launch configuration * @return whether the given launch configuration is private * @since 3.0 */ public static boolean isPrivate(ILaunchConfiguration configuration) { return !LaunchConfigurationManager.isVisible(configuration); } /** * Sets whether step filters should be applied to step commands. This * setting is a global option applied to all registered debug targets. *

* Since 3.3, this is equivalent to calling DebugPlugin.setUseStepFilters(boolean). *

* @param useStepFilters whether step filters should be applied to step * commands * @since 3.0 * @see org.eclipse.debug.core.model.IStepFilters */ public static void setUseStepFilters(boolean useStepFilters) { DebugPlugin.setUseStepFilters(useStepFilters); } /** * Returns whether step filters are applied to step commands. *

* Since 3.3, this is equivalent to calling DebugPlugin.isUseStepFilters(). *

* @return whether step filters are applied to step commands * @since 3.0 * @see org.eclipse.debug.core.model.IStepFilters */ public static boolean isUseStepFilters() { return DebugPlugin.isUseStepFilters(); } /** * Returns the console associated with the given process, or * null if none. * * @param process a process * @return console associated with the given process, or * null if none * @since 3.0 */ public static IConsole getConsole(IProcess process) { return DebugUIPlugin.getDefault().getProcessConsoleManager().getConsole(process); } /** * Returns the console associated with the given debug element, or * null if none. * * @param element a debug model element * @return console associated with the given element, or * null if none * @since 3.0 */ public static IConsole getConsole(IDebugElement element) { IProcess process = element.getDebugTarget().getProcess(); if (process != null) { return getConsole(process); } return null; } /** * Returns all registered launch group extensions. * * @return all registered launch group extensions * @since 3.0 */ public static ILaunchGroup[] getLaunchGroups() { return DebugUIPlugin.getDefault().getLaunchConfigurationManager().getLaunchGroups(); } /** * Returns the last configuration that was launched for specified launch group or * null, if there is not one. This method does not provide any form of * filtering on the returned launch configurations. * * @param groupId the unique identifier of a launch group * @return the last launched configuration for the specified group or null. * @see DebugUITools#getLaunchGroups() * @since 3.3 */ public static ILaunchConfiguration getLastLaunch(String groupId) { return DebugUIPlugin.getDefault().getLaunchConfigurationManager().getLastLaunch(groupId); } /** * Returns the launch group that the given launch configuration belongs to, for the specified * mode, or null if none. * * @param configuration the launch configuration * @param mode the mode * @return the launch group the given launch configuration belongs to, for the specified mode, * or null if none * @since 3.0 */ public static ILaunchGroup getLaunchGroup(ILaunchConfiguration configuration, String mode) { try { return DebugUIPlugin.getDefault().getLaunchConfigurationManager().getLaunchGroup(configuration.getType(), mode); } catch(CoreException ce) { return null; } } /** * Performs source lookup on the given artifact and returns the result. * Optionally, a source locator may be specified. * * @param artifact object for which source is to be resolved * @param locator the source locator to use, or null. When null * a source locator is determined from the artifact, if possible. If the artifact * is a debug element, the source locator from its associated launch is used. * @return a source lookup result * @since 3.1 */ public static ISourceLookupResult lookupSource(Object artifact, ISourceLocator locator) { return SourceLookupFacility.getDefault().lookup(artifact, locator, false); } /** * Displays the given source lookup result in an editor in the given workbench * page. Has no effect if the result has an unknown editor id or editor input. * The editor is opened, positioned, and annotated. *

* Honors user preference for editors re-use. *

* @param result source lookup result to display * @param page the page to display the result in * @since 3.1 */ public static void displaySource(ISourceLookupResult result, IWorkbenchPage page) { SourceLookupFacility.getDefault().display(result, page); } /** * Returns the memory rendering manager. * * @return the memory rendering manager * @since 3.1 */ public static IMemoryRenderingManager getMemoryRenderingManager() { return MemoryRenderingManager.getDefault(); } /** * Returns the image associated with the specified type of source container * or null if none. * * @param id unique identifier for a source container type * @return image associated with the specified type of source container * or null if none * @since 3.2 * @see org.eclipse.debug.core.sourcelookup.ISourceContainerType */ public static Image getSourceContainerImage(String id){ return SourceLookupUIUtils.getSourceContainerImage(id); } /** * Returns a new source container browser for the specified type of source container * or null if a browser has not been registered. * * @param id unique identifier for a source container type * @return source container browser or null if none * @since 3.2 * @see org.eclipse.debug.ui.sourcelookup.ISourceContainerBrowser */ public static ISourceContainerBrowser getSourceContainerBrowser(String id) { return SourceLookupUIUtils.getSourceContainerBrowser(id); } /** * Returns the color associated with the specified preference identifier or * null if none. * * @param id preference identifier of the color * @return the color associated with the specified preference identifier * or null if none * @since 3.2 * @see IDebugUIConstants */ public static Color getPreferenceColor(String id) { return DebugUIPlugin.getPreferenceColor(id); } /** * Returns the debug context manager. * * @return debug context manager * @since 3.3 */ public static IDebugContextManager getDebugContextManager() { return DebugContextManager.getDefault(); } /** * Return the debug context for the given executionEvent or null if none. * * @param event The execution event that contains the application context * @return the current debug context, or null. * * @since 3.5 */ public static ISelection getDebugContextForEvent(ExecutionEvent event) { Object o = HandlerUtil.getVariable(event, IConfigurationElementConstants.DEBUG_CONTEXT); if (o instanceof ISelection) { return (ISelection) o; } return null; } /** * Return the debug context for the given executionEvent. * * @param event The execution event that contains the application context * @return the debug context. Will not return null. * @throws ExecutionException If the current selection variable is not found. * * @since 3.5 */ public static ISelection getDebugContextForEventChecked(ExecutionEvent event) throws ExecutionException { Object o = HandlerUtil.getVariableChecked(event, IConfigurationElementConstants.DEBUG_CONTEXT); if (!(o instanceof ISelection)) { throw new ExecutionException("Incorrect type for " //$NON-NLS-1$ + IConfigurationElementConstants.DEBUG_CONTEXT + " found while executing " //$NON-NLS-1$ + event.getCommand().getId() + ", expected " + ISelection.class.getName() //$NON-NLS-1$ + " found " + o.getClass().getName()); //$NON-NLS-1$ } return (ISelection) o; } /** * Returns the global instance of toggle breakpoints target manager. * * @return toggle breakpoints target manager * * @since 3.8 */ public static IToggleBreakpointsTargetManager getToggleBreakpointsTargetManager() { return ToggleBreakpointsTargetManager.getDefault(); } /** * Returns the ILaunchConfiguration corresponding to * ILaunchConfigurationDialog * * @param dialog The input launch configuration dialog * @return {@link ILaunchConfiguration} Corresponding launch configuration * @since 3.13 */ public static ILaunchConfiguration getLaunchConfiguration(ILaunchConfigurationDialog dialog) { if (dialog instanceof LaunchConfigurationsDialog) { LaunchConfigurationTabGroupViewer tabViewer = ((LaunchConfigurationsDialog) dialog).getTabViewer(); if (tabViewer != null) { Object input = tabViewer.getInput(); if (input instanceof ILaunchConfiguration) { ILaunchConfiguration configuration = (ILaunchConfiguration) input; return configuration; } } } return null; } }