Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: fbb86f71d90d307f77cd7c0adff955bb88801d62 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
/*******************************************************************************
 * 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;
	}

}

Back to the top