elements = new ArrayList<>();
+ final IExtensionPoint extensionPoint = mock(IExtensionPoint.class);
+ IExtension extension = mock(IExtension.class);
+ doReturn(new IExtension[] { extension }).when(extensionPoint).getExtensions();
+ elements.add(createConfigElementMockForDescriptorType(launchDescTypeId_no1, descriptor_no1));
+ elements.add(createConfigElementMockForConfigProvider(launchDescTypeId_no1, launchConfigProvider_no1));
+ elements.add(createConfigElementMockForDescriptorType(launchDescTypeId_no2, descriptor_no2));
+ elements.add(createConfigElementMockForConfigProvider(launchDescTypeId_no2, launchConfigProvider_no2));
+ ILaunchManager launchManager = createLaunchManagerMock(launchConfigTypes, preferredMode_no1, preferredMode_no2,
+ runMode, debugMode);
+ ILaunchTargetManager targetManager = createLaunchTargetManagerMock();
+ doReturn(elements.toArray(IConfigurationElement[]::new)).when(extension).getConfigurationElements();
+ // Mock Launch bar manager
+ launchBarManagerMock = createLaunchBarManagerMock(extensionPoint, launchManager, targetManager);
+ // Initial LaunchBarManager
+ launchBarManagerMock.init();
+ }
+
+ @After
+ public void after() {
+ launchBarManagerMock.dispose();
+ }
+
@Test
public void startupTest() throws Exception {
// Make sure the manager starts up and defaults everything to null
@@ -310,6 +392,207 @@ ILaunchTargetManager getLaunchTargetManager() {
assertEquals(launchConfig, manager.getActiveLaunchConfiguration());
}
+ /**
+ *
+ * Test that preferred launch mode is taken into consideration in
+ * {@link LaunchBarManager#syncActiveMode()}.
+ *
+ * Verifies that when stored mode and last active mode is NULL, preferred mode is selected
+ * as active mode.
+ *
+ * Order when choosing active mode for active launch descriptor is:
+ * stored mode -> last active mode -> preferred mode -> "run" -> "debug" -> supportedMode[0]
+ *
+ * @throws CoreException
+ */
+ @Test
+ public void preferredLaunchModeTest_StoredModeAndLastActiveModeIsNull() throws CoreException {
+ launchBarManagerMock.launchObjectAdded(launchObject_no1);
+ // "preferredMode_no1" will be selected as active mode.
+ ILaunchMode activeMode = launchBarManagerMock.getActiveLaunchMode();
+ assertEquals(preferredMode_no1, activeMode.getIdentifier());
+ }
+
+ /**
+ *
+ * Test that preferred launch mode is taken into consideration in
+ * {@link LaunchBarManager#syncActiveMode()}.
+ *
+ * Verifies that when stored mode and last active mode is NULL, and preferred mode is not
+ * supported, "run" mode (fall back mode) is selected as active mode.
+ *
+ * Order when choosing active mode for active launch descriptor is:
+ * stored mode -> last active mode -> preferred mode -> "run" -> "debug" -> supportedMode[0]
+ *
+ * @throws CoreException
+ */
+ @Test
+ public void preferredLaunchModeTest_preferredModeNotSupported() throws CoreException {
+ launchBarManagerMock.launchObjectAdded(launchObject_no2);
+ // When preferred mode not supported, launch bar manager fall back to other hard-coded mode.
+ // In this case, "run" comes after preferred mode, so "run" is selected as active mode.
+ ILaunchMode activeMode = launchBarManagerMock.getActiveLaunchMode();
+ assertEquals(runMode, activeMode.getIdentifier());
+ }
+
+ /**
+ *
+ * Test that preferred launch mode is taken into consideration in
+ * {@link LaunchBarManager#syncActiveMode()}.
+ *
+ * Verifies that when stored mode is NULL and last active mode is Not NULL, last active
+ * mode will be selected as active mode.
+ *
+ * Order when choosing active mode for active launch descriptor is:
+ * stored mode -> last active mode -> preferred mode -> "run" -> "debug" -> supportedMode[0]
+ *
+ * @throws CoreException
+ */
+ @Test
+ public void preferredLaunchModeTest_lastActiveModeNotNull() throws CoreException {
+ // After launch object no2 is added and activated, active mode now is "run" mode.
+ launchBarManagerMock.launchObjectAdded(launchObject_no2);
+ launchBarManagerMock.launchObjectAdded(launchObject_no1);
+ // When launchObject_no1 is added, last active mode now will be "run."
+ // Since preferred mode comes after last active mode, "run" mode is selected for launchObject_no1.
+ ILaunchMode activeMode = launchBarManagerMock.getActiveLaunchMode();
+ assertEquals(runMode, activeMode.getIdentifier());
+ }
+
+ /**
+ *
+ * Test that preferred launch mode is taken into consideration in
+ * {@link LaunchBarManager#syncActiveMode()}.
+ *
+ * Verifies that when stored mode is not NULL, stored mode is selected as active mode.
+ *
+ * Order when choosing active mode for active launch descriptor is:
+ * stored mode -> last active mode -> preferred mode -> "run" -> "debug" -> supportedMode[0]
+ *
+ * @throws CoreException
+ */
+ @Test
+ public void preferredLaunchModeTest_storedModeNotNull() throws CoreException {
+ // Stored mode is saved as "preferredMode_no1" for launchObject_no1
+ launchBarManagerMock.launchObjectAdded(launchObject_no1);
+ launchBarManagerMock.launchObjectRemoved(launchObject_no1);
+ // After launch object no2 is added and activated, active mode now is "run" mode.
+ launchBarManagerMock.launchObjectAdded(launchObject_no2);
+ launchBarManagerMock.launchObjectAdded(launchObject_no1);
+ // After launch object no1 is added and activated, stored mode now is "preferredMode_no1".
+ // Since stored mode comes first, "preferredMode_no1" mode is selected for launchObject_no1
+ // when it is re-activated.
+ ILaunchMode activeMode = launchBarManagerMock.getActiveLaunchMode();
+ assertEquals(preferredMode_no1, activeMode.getIdentifier());
+ }
+
+ private ILaunchDescriptor createLaunchDescriptorMock(Object launchObject) throws CoreException {
+ ILaunchDescriptorType descriptorType = mock(ILaunchDescriptorType.class);
+ ILaunchDescriptor descriptor = mock(ILaunchDescriptor.class);
+ doReturn(true).when(descriptorType).supportsTargets();
+ doReturn(descriptor).when(descriptorType).getDescriptor(launchObject);
+ doReturn(descriptorType).when(descriptor).getType();
+ doReturn(launchObject).when(descriptor).getName();
+ return descriptor;
+ }
+
+ private ILaunchConfigurationType createLaunchConfigType(String launchConfigTypeId, String... supportModes) {
+ ILaunchConfigurationType launchConfigType = mock(ILaunchConfigurationType.class);
+ doReturn(launchConfigTypeId).when(launchConfigType).getIdentifier();
+ for (String mode : supportModes) {
+ doReturn(true).when(launchConfigType).supportsMode(mode);
+ }
+ return launchConfigType;
+ }
+
+ private ILaunchConfigurationProvider creatLaunchConfigProvier(ILaunchConfigurationType launchConfigType,
+ ILaunchDescriptor desc, String preferredMode) throws CoreException {
+ ILaunchConfigurationProvider configProvider = mock(ILaunchConfigurationProvider.class);
+ ILaunchConfiguration launchConfig = mock(ILaunchConfiguration.class);
+ doReturn(launchConfig).when(configProvider).getLaunchConfiguration(eq(desc), any(ILaunchTarget.class));
+ doReturn(launchConfigType).when(configProvider).getLaunchConfigurationType(any(ILaunchDescriptor.class),
+ any(ILaunchTarget.class));
+ doReturn(launchConfig).when(desc).getAdapter(ILaunchConfiguration.class);
+ doAnswer(invocation -> {
+ ILaunchTarget target = (ILaunchTarget) invocation.getArguments()[1];
+ return target.getTypeId().equals(ILaunchTargetManager.localLaunchTargetTypeId);
+ }).when(configProvider).supports(eq(desc), any(ILaunchTarget.class));
+ doReturn(preferredMode).when(configProvider).getPreferredLaunchModeId(eq(desc), any(ILaunchTarget.class));
+ return configProvider;
+ }
+
+ private IConfigurationElement createConfigElementMockForDescriptorType(String descriptorTypeId,
+ ILaunchDescriptor desc) throws CoreException {
+ IConfigurationElement element = mock(IConfigurationElement.class);
+ doReturn("descriptorType").when(element).getName(); //$NON-NLS-1$
+ doReturn(descriptorTypeId).when(element).getAttribute("id"); //$NON-NLS-1$
+ doReturn(desc.getType()).when(element).createExecutableExtension("class"); //$NON-NLS-1$
+ return element;
+ }
+
+ private IConfigurationElement createConfigElementMockForConfigProvider(String descriptorTypeId,
+ ILaunchConfigurationProvider configProvider) throws CoreException {
+ IConfigurationElement element = mock(IConfigurationElement.class);
+ doReturn("configProvider").when(element).getName(); //$NON-NLS-1$
+ doReturn(descriptorTypeId).when(element).getAttribute("descriptorType"); //$NON-NLS-1$
+ doReturn("10").when(element).getAttribute("priority"); //$NON-NLS-1$ $NON-NLS-2$
+ doReturn(configProvider).when(element).createExecutableExtension("class"); //$NON-NLS-1$
+ return element;
+ }
+
+ private ILaunchTargetManager createLaunchTargetManagerMock() {
+ ILaunchTargetManager targetManager = mock(ILaunchTargetManager.class);
+ ILaunchTarget localTarget = mock(ILaunchTarget.class);
+ doReturn(ILaunchTargetManager.localLaunchTargetTypeId).when(localTarget).getTypeId();
+ doReturn("Local").when(localTarget).getId(); //$NON-NLS-1$
+ doReturn(new ILaunchTarget[] { localTarget }).when(targetManager).getLaunchTargets();
+ return targetManager;
+ }
+
+ private ILaunchManager createLaunchManagerMock(Map launchConfigTypes,
+ String... supportModes) throws CoreException {
+ ILaunchManager launchManager = mock(ILaunchManager.class);
+ List modes = new ArrayList<>();
+ for (String supportMode : supportModes) {
+ ILaunchMode mode = createLaunchModeMock(supportMode);
+ doReturn(mode).when(launchManager).getLaunchMode(supportMode);
+ modes.add(mode);
+ }
+ doReturn(modes.toArray(ILaunchMode[]::new)).when(launchManager).getLaunchModes();
+
+ launchConfigTypes.forEach((typeId, type) -> {
+ doReturn(type).when(launchManager).getLaunchConfigurationType(typeId);
+ });
+ doReturn(new ILaunchConfiguration[0]).when(launchManager).getLaunchConfigurations();
+ return launchManager;
+ }
+
+ private LaunchBarManager createLaunchBarManagerMock(IExtensionPoint extensionPoint, ILaunchManager launchManager,
+ ILaunchTargetManager targetManager) {
+ return new LaunchBarManager(false) {
+ @Override
+ IExtensionPoint getExtensionPoint() throws CoreException {
+ return extensionPoint;
+ }
+
+ @Override
+ ILaunchManager getLaunchManager() {
+ return launchManager;
+ }
+
+ @Override
+ ILaunchTargetManager getLaunchTargetManager() {
+ return targetManager;
+ }
+ };
+ }
+
+ private ILaunchMode createLaunchModeMock(String identifier) {
+ ILaunchMode mode = mock(ILaunchMode.class);
+ doReturn(identifier).when(mode).getIdentifier();
+ return mode;
+ }
+
// TODO - test that changing active target type produces a different launch
// config type
// TODO - test that settings are maintained after a restart
diff --git a/launchbar/org.eclipse.launchbar.core/.settings/.api_filters b/launchbar/org.eclipse.launchbar.core/.settings/.api_filters
new file mode 100644
index 00000000000..99a755ba333
--- /dev/null
+++ b/launchbar/org.eclipse.launchbar.core/.settings/.api_filters
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/launchbar/org.eclipse.launchbar.core/META-INF/MANIFEST.MF b/launchbar/org.eclipse.launchbar.core/META-INF/MANIFEST.MF
index 751b3444b41..5f4935e223e 100644
--- a/launchbar/org.eclipse.launchbar.core/META-INF/MANIFEST.MF
+++ b/launchbar/org.eclipse.launchbar.core/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.launchbar.core;singleton:=true
-Bundle-Version: 3.1.0.qualifier
+Bundle-Version: 3.2.0.qualifier
Bundle-Activator: org.eclipse.launchbar.core.internal.Activator
Bundle-Vendor: %providerName
Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.34.0,4.0.0)",
diff --git a/launchbar/org.eclipse.launchbar.core/src/org/eclipse/launchbar/core/ILaunchConfigurationProvider.java b/launchbar/org.eclipse.launchbar.core/src/org/eclipse/launchbar/core/ILaunchConfigurationProvider.java
index 5cabc260af5..a0ab638b8d2 100644
--- a/launchbar/org.eclipse.launchbar.core/src/org/eclipse/launchbar/core/ILaunchConfigurationProvider.java
+++ b/launchbar/org.eclipse.launchbar.core/src/org/eclipse/launchbar/core/ILaunchConfigurationProvider.java
@@ -131,4 +131,26 @@ boolean launchDescriptorMatches(ILaunchDescriptor descriptor, ILaunchConfigurati
*/
void launchTargetRemoved(ILaunchTarget target) throws CoreException;
+ /**
+ * Returns the preferred launch mode id for the given launch descriptor and target.
+ *
+ * Returning {@code null} indicates that this provider has no preferred mode for
+ * the given descriptor/target combination.
+ *
+ *
+ * The returned id is treated as a preference only. If it does not resolve to a
+ * known launch mode, or if that mode is not supported for the active descriptor
+ * and target, Launch Bar continues normal fallback resolution.
+ *
+ *
+ * @param descriptor the launch descriptor
+ * @param target the launch target
+ * @return the preferred launch mode id, or {@code null} if none
+ * @throws CoreException if the preferred mode cannot be determined
+ * @since 3.2
+ */
+ default String getPreferredLaunchModeId(ILaunchDescriptor descriptor, ILaunchTarget target) throws CoreException {
+ return null;
+ }
+
}
diff --git a/launchbar/org.eclipse.launchbar.core/src/org/eclipse/launchbar/core/internal/LaunchBarManager.java b/launchbar/org.eclipse.launchbar.core/src/org/eclipse/launchbar/core/internal/LaunchBarManager.java
index 06f185cfe62..e17b9c63881 100644
--- a/launchbar/org.eclipse.launchbar.core/src/org/eclipse/launchbar/core/internal/LaunchBarManager.java
+++ b/launchbar/org.eclipse.launchbar.core/src/org/eclipse/launchbar/core/internal/LaunchBarManager.java
@@ -569,10 +569,11 @@ private void syncActiveMode() throws CoreException {
// last desc mode id
String storedModeId = getPerDescriptorStore().get(PREF_ACTIVE_LAUNCH_MODE, null);
String lastActiveModeId = activeLaunchMode == null ? null : activeLaunchMode.getIdentifier();
+ String preferredModeId = getPreferredLaunchModeId(activeLaunchDesc, activeLaunchTarget);
// this is based on active desc and target which are already set
ILaunchMode[] supportedModes = getLaunchModes();
if (supportedModes.length > 0) { // mna, what if no modes are supported?
- String modeNames[] = new String[] { storedModeId, lastActiveModeId, "run", //$NON-NLS-1$
+ String modeNames[] = new String[] { storedModeId, lastActiveModeId, preferredModeId, "run", //$NON-NLS-1$
"debug", //$NON-NLS-1$
supportedModes[0].getIdentifier() };
for (int i = 0; i < modeNames.length; i++) {
@@ -1050,4 +1051,24 @@ private boolean launchDescriptorMatches(ILaunchDescriptor desc, ILaunchConfigura
}
return false;
}
+
+ private String getPreferredLaunchModeId(ILaunchDescriptor descriptor, ILaunchTarget target) throws CoreException {
+ if (descriptor == null) {
+ return null;
+ }
+ List providerInfos = configProviders.get(getDescriptorTypeId(descriptor.getType()));
+ if (providerInfos == null) {
+ return null;
+ }
+ for (LaunchConfigProviderInfo providerInfo : providerInfos) {
+ if (providerInfo.enabled(descriptor) && providerInfo.enabled(target)) {
+ ILaunchConfigurationProvider provider = providerInfo.getProvider();
+ if (provider != null && provider.supports(descriptor, target)) {
+ return provider.getPreferredLaunchModeId(descriptor, target);
+ }
+ }
+ }
+ // not found
+ return null;
+ }
}