/******************************************************************************* * 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 (String), * and entries are tables of launch modes (String) * to LaunchConfigurationTabGroupExtension. "*" is * used to represent the default tab group (i.e. unspecified mode). */ private Hashtable, LaunchConfigurationTabGroupExtension>> fTabGroupExtensions; /** * contributed tabs are stored by the tab group id that they contribute to. * each entry is a Hashtable consisting of the corresponding * LaunchConfigurationTabExtension objects for each contributed tab stored by their * id * * @since 3.3 */ private Hashtable> fContributedTabs; private static Set 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, LaunchConfigurationTabGroupExtension> map = null; List> 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 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 launchConfigurationTabs * 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 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 null if none * @exception CoreException if an exception occurs creating the group */ public ILaunchConfigurationTabGroup getTabGroup(ILaunchConfigurationType type, String mode) throws CoreException { HashSet 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 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 null * * @since 3.3 */ protected LaunchConfigurationTabExtension[] getTabExtensions(String groupid, ILaunchConfiguration config, String mode) throws CoreException { initializeContributedTabExtensions(); Hashtable 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 LaunchConfiguraitonTabExtensions that does not contain any tabs * from disabled activities *

* There are thre ways that tabs can be filtered form the launch dialog: *

    *
  1. The tabs can belong to tooling that is contributed via a specific type of workbench activity, and is therefore filtered with capabilities
  2. *
  3. 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
  4. *
  5. A tab is not part of a workbench activity, nor specifies an associated launch delegate -- show the tab
  6. *
*

* @param tabs the raw listing of tabs to filter * @return the listing of filtered LaunchConfigurationTabExtensions or an empty array, never null * * @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 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 modes = config.getModes(); modes.add(mode); ILaunchDelegate delegate = config.getPreferredDelegate(modes); if(delegate == null) { delegate = config.getType().getPreferredDelegate(modes); } Set 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 * null if none * * @param type launch configuration type identifier * @param mode launch mode identifier * @return launch tab group extension or null */ protected LaunchConfigurationTabGroupExtension getExtension(String type, Set modes) { initializeTabGroupExtensions(); Map, 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 null 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 null * @exception CoreException if an exception occurs creating the group * @since 2.1 */ public String getHelpContext(ILaunchConfigurationType type, String mode) throws CoreException { HashSet 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 null if none. * * @param configType the config type * @param mode the launch mode * @return the description of the given configuration type, possible null */ public String getDescription(ILaunchConfigurationType configType, String mode) { HashSet 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 getLaunchModeNames(Set modes) { List 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 null 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; } }