| /******************************************************************************* |
| * Copyright (c) 2000, 2013 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.launchConfigurations; |
| |
| |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.HashSet; |
| import java.util.Hashtable; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IConfigurationElement; |
| import org.eclipse.core.runtime.IExtensionPoint; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.Platform; |
| import org.eclipse.core.runtime.Status; |
| import org.eclipse.debug.core.DebugPlugin; |
| 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.ILaunchMode; |
| import org.eclipse.debug.internal.core.IConfigurationElementConstants; |
| import org.eclipse.debug.internal.ui.DebugUIPlugin; |
| import org.eclipse.debug.internal.ui.LaunchConfigurationTabExtension; |
| import org.eclipse.debug.ui.IDebugUIConstants; |
| import org.eclipse.debug.ui.ILaunchConfigurationTabGroup; |
| import org.eclipse.osgi.util.NLS; |
| import org.eclipse.ui.PlatformUI; |
| import org.eclipse.ui.activities.IWorkbenchActivitySupport; |
| import org.eclipse.ui.activities.WorkbenchActivityHelper; |
| |
| /** |
| * Manages contributed launch configuration tabs |
| * |
| * @see LaunchConfigurationTabGroupWrapper |
| * @see LaunchConfigurationTabExtension |
| * @see LaunchConfigurationTabGroupExtension |
| */ |
| public class LaunchConfigurationPresentationManager { |
| |
| /** |
| * The singleton launch configuration presentation manager |
| */ |
| private static LaunchConfigurationPresentationManager fgDefault; |
| |
| /** |
| * Collection of launch configuration tab group extensions |
| * defined in plug-in xml. Entries are keyed by launch |
| * configuration type identifier (<code>String</code>), |
| * and entries are tables of launch modes (<code>String</code>) |
| * to <code>LaunchConfigurationTabGroupExtension</code>. "*" is |
| * used to represent the default tab group (i.e. unspecified mode). |
| */ |
| private Hashtable<String, Map<Set<String>, LaunchConfigurationTabGroupExtension>> fTabGroupExtensions; |
| |
| /** |
| * contributed tabs are stored by the tab group id that they contribute to. |
| * each entry is a <code>Hashtable</code> consisting of the corresponding |
| * <code>LaunchConfigurationTabExtension</code> objects for each contributed tab stored by their |
| * id |
| * |
| * @since 3.3 |
| */ |
| private Hashtable<String, Hashtable<String, LaunchConfigurationTabExtension>> fContributedTabs; |
| |
| private static Set<String> ALL_MODES = new HashSet<>(1); |
| |
| static { |
| ALL_MODES.add("*"); //$NON-NLS-1$ |
| } |
| |
| /** |
| * Constructs the singleton launch configuration presentation |
| * manager. |
| */ |
| private LaunchConfigurationPresentationManager() { |
| fgDefault = this; |
| } |
| |
| /** |
| * Returns the launch configuration presentation manager |
| */ |
| public static LaunchConfigurationPresentationManager getDefault() { |
| if (fgDefault == null) { |
| fgDefault = new LaunchConfigurationPresentationManager(); |
| } |
| return fgDefault; |
| } |
| |
| /** |
| * Creates launch configuration tab group extensions for each extension |
| * defined in XML, and adds them to the table of tab group extensions. |
| */ |
| private void initializeTabGroupExtensions() { |
| if(fTabGroupExtensions == null) { |
| fTabGroupExtensions = new Hashtable<>(); |
| IExtensionPoint extensionPoint = Platform.getExtensionRegistry().getExtensionPoint(DebugUIPlugin.getUniqueIdentifier(), IDebugUIConstants.EXTENSION_POINT_LAUNCH_CONFIGURATION_TAB_GROUPS); |
| IConfigurationElement[] groups = extensionPoint.getConfigurationElements(); |
| LaunchConfigurationTabGroupExtension group = null; |
| String typeId = null; |
| Map<Set<String>, LaunchConfigurationTabGroupExtension> map = null; |
| List<Set<String>> modes = null; |
| for (int i = 0; i < groups.length; i++) { |
| group = new LaunchConfigurationTabGroupExtension(groups[i]); |
| typeId = group.getTypeIdentifier(); |
| map = fTabGroupExtensions.get(typeId); |
| if (map == null) { |
| map = new Hashtable<>(); |
| fTabGroupExtensions.put(typeId, map); |
| } |
| modes = group.getModes(); |
| if(modes.isEmpty()) { |
| reportReplacement(map.put(ALL_MODES, group), group, ALL_MODES); |
| } |
| for (Set<String> ms : modes) { |
| reportReplacement(map.put(ms, group), group, ms); |
| } |
| } |
| } |
| } |
| |
| /** |
| * Reports if a tab group extension has been replaced by another contribution |
| * @param oldext the old tab group extension from the cache |
| * @param newext the new one being cached |
| * @param mode the mode(s) the group applies to |
| * |
| * @since 3.6 |
| */ |
| void reportReplacement(LaunchConfigurationTabGroupExtension oldext, LaunchConfigurationTabGroupExtension newext, Object mode) { |
| if(oldext != null) { |
| Status status = new Status(IStatus.ERROR, |
| DebugUIPlugin.getUniqueIdentifier(), |
| NLS.bind(LaunchConfigurationsMessages.LaunchConfigurationPresentationManager_0, |
| new String[]{oldext.getIdentifier(), oldext.getTypeIdentifier(), mode.toString(), newext.getIdentifier()})); |
| DebugUIPlugin.log(status); |
| } |
| } |
| |
| /** |
| * This method is used to collect all of the contributed tabs defined by the <code>launchConfigurationTabs</code> |
| * extension point |
| * |
| * @since 3.3 |
| */ |
| private void initializeContributedTabExtensions() { |
| fContributedTabs = new Hashtable<>(); |
| IExtensionPoint epoint = Platform.getExtensionRegistry().getExtensionPoint(DebugUIPlugin.getUniqueIdentifier(), IDebugUIConstants.EXTENSION_POINT_LAUNCH_TABS); |
| IConfigurationElement[] elements = epoint.getConfigurationElements(); |
| LaunchConfigurationTabExtension tab = null; |
| Hashtable<String, LaunchConfigurationTabExtension> element = null; |
| for(int i = 0; i < elements.length; i++) { |
| tab = new LaunchConfigurationTabExtension(elements[i]); |
| element = fContributedTabs.get(tab.getTabGroupId()); |
| if(element == null) { |
| element = new Hashtable<>(); |
| element.put(tab.getIdentifier(), tab); |
| fContributedTabs.put(tab.getTabGroupId(), element); |
| } |
| element.put(tab.getIdentifier(), tab); |
| } |
| } |
| |
| /** |
| * Returns the tab group for the given launch configuration type and mode. |
| * |
| * @param type launch configuration type |
| * @param mode launch mode |
| * @return the tab group for the given type of launch configuration, or <code>null</code> if none |
| * @exception CoreException if an exception occurs creating the group |
| */ |
| public ILaunchConfigurationTabGroup getTabGroup(ILaunchConfigurationType type, String mode) throws CoreException { |
| HashSet<String> modes = new HashSet<>(); |
| modes.add(mode); |
| LaunchConfigurationTabGroupExtension ext = getExtension(type.getIdentifier(), modes); |
| if (ext == null) { |
| IStatus status = new Status(IStatus.ERROR, IDebugUIConstants.PLUGIN_ID, IDebugUIConstants.INTERNAL_ERROR, "No tab group defined for launch configuration type " + type.getIdentifier(), null); //$NON-NLS-1$ |
| throw new CoreException(status); |
| } |
| return new LaunchConfigurationTabGroupWrapper(ext.newTabGroup(), ext.getIdentifier(), null); |
| } |
| |
| /** |
| * Returns the tab group for the given launch configuration and the mode the dialog opened in |
| * @param type the type of the configuration |
| * @param config |
| * @param mode |
| * @return |
| * @throws CoreException |
| */ |
| public ILaunchConfigurationTabGroup getTabGroup(ILaunchConfiguration config, String mode) throws CoreException { |
| HashSet<String> modes = new HashSet<>(); |
| modes.add(mode); |
| LaunchConfigurationTabGroupExtension ext = getExtension(config.getType().getIdentifier(), modes); |
| if (ext == null) { |
| IStatus status = new Status(IStatus.ERROR, IDebugUIConstants.PLUGIN_ID, IDebugUIConstants.INTERNAL_ERROR, "No tab group defined for launch configuration type " + config.getType().getIdentifier(), null); //$NON-NLS-1$ |
| throw new CoreException(status); |
| } |
| return new LaunchConfigurationTabGroupWrapper(ext.newTabGroup(), ext.getIdentifier(), config); |
| } |
| |
| /** |
| * Returns the proxy elements for all contributed tabs for the specified tab group id |
| * @param groupid the id of the tab group |
| * @param config the config the tab group is opened on |
| * @param mode the mode the associated launch dialog is opened on |
| * @return the listing of all of the tab extensions or an empty array, never <code>null</code> |
| * |
| * @since 3.3 |
| */ |
| protected LaunchConfigurationTabExtension[] getTabExtensions(String groupid, ILaunchConfiguration config, String mode) throws CoreException { |
| initializeContributedTabExtensions(); |
| Hashtable<String, LaunchConfigurationTabExtension> tabs = fContributedTabs.get(groupid); |
| if(tabs != null) { |
| return filterLaunchTabExtensions(tabs.values().toArray(new LaunchConfigurationTabExtension[tabs.size()]), config, mode); |
| } |
| return new LaunchConfigurationTabExtension[0]; |
| } |
| |
| /** |
| * Returns a listing of <code>LaunchConfiguraitonTabExtension</code>s that does not contain any tabs |
| * from disabled activities |
| * <p> |
| * There are thre ways that tabs can be filtered form the launch dialog: |
| * <ol> |
| * <li>The tabs can belong to tooling that is contributed via a specific type of workbench activity, and is therefore filtered with capabilities</li> |
| * <li>The tabs can be filtered via the associatedDelegate extension point, if a tab is said to apply only to certain tooling, only show it in the instance when that tooling is used</li> |
| * <li>A tab is not part of a workbench activity, nor specifies an associated launch delegate -- show the tab</li> |
| * </ol> |
| * </p> |
| * @param tabs the raw listing of tabs to filter |
| * @return the listing of filtered <code>LaunchConfigurationTabExtension</code>s or an empty array, never <code>null</code> |
| * |
| * @since 3.3 |
| */ |
| protected LaunchConfigurationTabExtension[] filterLaunchTabExtensions(LaunchConfigurationTabExtension[] tabs, ILaunchConfiguration config, String mode) throws CoreException { |
| IWorkbenchActivitySupport as = PlatformUI.getWorkbench().getActivitySupport(); |
| if(as == null || config == null) { |
| return tabs; |
| } |
| HashSet<LaunchConfigurationTabExtension> set = new HashSet<>(); |
| for(int i = 0; i < tabs.length; i ++) { |
| //filter capabilities |
| if(!WorkbenchActivityHelper.filterItem(new LaunchTabContribution(tabs[i]))) { |
| //filter to preferred delegate (if there is one) |
| Set<String> modes = config.getModes(); |
| modes.add(mode); |
| ILaunchDelegate delegate = config.getPreferredDelegate(modes); |
| if(delegate == null) { |
| delegate = config.getType().getPreferredDelegate(modes); |
| } |
| Set<String> delegateSet = tabs[i].getDelegateSet(); |
| if(delegate != null) { |
| if(delegateSet.isEmpty() || delegateSet.contains(delegate.getId())) { |
| set.add(tabs[i]); |
| } |
| } |
| else { |
| //otherwise filter based on the collection of delegates for the modes |
| ILaunchDelegate[] delegates = config.getType().getDelegates(modes); |
| for(int j = 0; j < delegates.length; j++) { |
| if(delegateSet.size() == 0 || delegateSet.contains(delegates[j].getId())) { |
| //associated with all modes and tab groups or only specific ones if indicated |
| set.add(tabs[i]); |
| } |
| } |
| } |
| } |
| } |
| return set.toArray(new LaunchConfigurationTabExtension[set.size()]); |
| } |
| |
| /** |
| * Returns the launch tab group extension for the given type and mode, or |
| * <code>null</code> if none |
| * |
| * @param type launch configuration type identifier |
| * @param mode launch mode identifier |
| * @return launch tab group extension or <code>null</code> |
| */ |
| protected LaunchConfigurationTabGroupExtension getExtension(String type, Set<String> modes) { |
| initializeTabGroupExtensions(); |
| Map<Set<String>, LaunchConfigurationTabGroupExtension> map = fTabGroupExtensions.get(type); |
| if (map != null) { |
| LaunchConfigurationTabGroupExtension extension = map.get(modes); |
| if (extension == null) { |
| // get the default tabs |
| extension = map.get(ALL_MODES); |
| } |
| return extension; |
| } |
| return null; |
| } |
| |
| /** |
| * Returns the identifier of the help context that is associated with the |
| * specified launch configuration type and mode, or <code>null</code> if none. |
| * |
| * @param type launch config type |
| * @param mode launch mode |
| * @return the identifier for the help context associated with the given |
| * type of launch configuration, or <code>null</code> |
| * @exception CoreException if an exception occurs creating the group |
| * @since 2.1 |
| */ |
| public String getHelpContext(ILaunchConfigurationType type, String mode) throws CoreException { |
| HashSet<String> modes = new HashSet<>(); |
| modes.add(mode); |
| LaunchConfigurationTabGroupExtension ext = getExtension(type.getIdentifier(), modes); |
| if (ext == null) { |
| IStatus status = new Status(IStatus.ERROR, IDebugUIConstants.PLUGIN_ID, IDebugUIConstants.INTERNAL_ERROR, "No tab group defined for launch configuration type " + type.getIdentifier(), null); //$NON-NLS-1$ |
| throw new CoreException(status); |
| } |
| return ext.getHelpContextId(); |
| } |
| |
| /** |
| * Returns the description of the given configuration type |
| * in the specified mode or <code>null</code> if none. |
| * |
| * @param configType the config type |
| * @param mode the launch mode |
| * @return the description of the given configuration type, possible <code>null</code> |
| */ |
| public String getDescription(ILaunchConfigurationType configType, String mode) { |
| HashSet<String> modes = new HashSet<>(); |
| modes.add(mode); |
| LaunchConfigurationTabGroupExtension extension = getExtension(configType.getAttribute(IConfigurationElementConstants.ID), modes); |
| return (extension != null ? extension.getDescription(modes) : null); |
| } |
| |
| /** |
| * Returns a sorted list of launch mode names corresponding to the given identifiers. |
| * |
| * @param modes set of launch mode identifiers |
| * @return sorted list of launch mode names |
| */ |
| public List<String> getLaunchModeNames(Set<String> modes) { |
| List<String> names = new ArrayList<>(); |
| ILaunchManager manager = DebugPlugin.getDefault().getLaunchManager(); |
| for (String id : modes) { |
| ILaunchMode mode = manager.getLaunchMode(id); |
| if (mode == null) { |
| names.add(id); |
| } else { |
| names.add(DebugUIPlugin.removeAccelerators(mode.getLabel())); |
| } |
| } |
| Collections.sort(names); |
| return names; |
| } |
| |
| /** |
| * Returns the label of the mode id with all accelerators removed |
| * @param modeid the id of the mode i.e. 'run' |
| * @return the formatted label of the specified mode id with all accelerators removed, or <code>null</code> if no label is available |
| * @since 3.3 |
| */ |
| public String getLaunchModeLabel(String modeid) { |
| String mode = null; |
| ILaunchManager manager = DebugPlugin.getDefault().getLaunchManager(); |
| ILaunchMode lmode = manager.getLaunchMode(modeid); |
| if(lmode != null) { |
| return lmode.getLabel(); |
| } |
| return mode; |
| } |
| |
| } |
| |