Skip to content

Commit acd4556

Browse files
DangMinhTam382betamaxbandit
authored andcommitted
Added API allows ISV to specify preferred launch mode
Added API to ILaunchConfigurationProvider that provide preferred launch mode ID for specified launch descriptor and launch target. Preferred mode is considered when LaunchBarManger call syncActiveMode(). Preferred mode comes after storedMode, lastActiveMode and comes before hard-coded run, debug, first supported mode.
1 parent 1ad625e commit acd4556

5 files changed

Lines changed: 339 additions & 2 deletions

File tree

launchbar/org.eclipse.launchbar.core.tests/src/org/eclipse/launchbar/core/internal/LaunchBarManagerTest.java

Lines changed: 283 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@
2424
import static org.mockito.Mockito.mock;
2525

2626
import java.util.ArrayList;
27+
import java.util.HashMap;
2728
import java.util.List;
29+
import java.util.Map;
2830

2931
import org.eclipse.core.runtime.CoreException;
3032
import org.eclipse.core.runtime.IConfigurationElement;
@@ -40,9 +42,89 @@
4042
import org.eclipse.launchbar.core.ILaunchDescriptorType;
4143
import org.eclipse.launchbar.core.target.ILaunchTarget;
4244
import org.eclipse.launchbar.core.target.ILaunchTargetManager;
45+
import org.junit.After;
46+
import org.junit.Before;
4347
import org.junit.Test;
4448

4549
public class LaunchBarManagerTest {
50+
51+
/**
52+
* <p>This is a dummy launch object</p>
53+
*
54+
* Object's data: <b>launchObject_no1</b>
55+
* <ul>
56+
* <li>launchConfigTypeId = "fakeLaunchConfigType_no1";
57+
* <li>launchDescTypeId = "fakeDescriptorType_no1";
58+
* <li>preferredMode = "preferredMode_no1";
59+
* </ul>
60+
*/
61+
private static final String launchObject_no1 = "launchObject_no1";
62+
private static final String launchConfigTypeId_no1 = "fakeLaunchConfigType_no1"; //$NON-NLS-1$
63+
private static final String launchDescTypeId_no1 = "fakeDescriptorType_no1"; //$NON-NLS-1$
64+
private static final String preferredMode_no1 = "preferredMode_no1"; //$NON-NLS-1$
65+
/**
66+
* <p>This is a dummy launch object</p>
67+
*
68+
* Object's data: <b>launchObject_no2</b>
69+
* <ul>
70+
* <li>launchConfigTypeId = "fakeLaunchConfigType_no2";
71+
* <li>launchDescTypeId = "fakeDescriptorType_no2";
72+
* <li>preferredMode = "preferredMode_no2"; // Not supported launch Mode
73+
* </ul>
74+
*/
75+
private static final String launchObject_no2 = "launchObject_no2";
76+
private static final String launchConfigTypeId_no2 = "fakeLaunchConfigType_no2"; //$NON-NLS-1$
77+
private static final String launchDescTypeId_no2 = "fakeDescriptorType_no2"; //$NON-NLS-1$
78+
private static final String preferredMode_no2 = "preferredMode_no2"; //$NON-NLS-1$
79+
80+
private static final String runMode = "run"; //$NON-NLS-1$
81+
private static final String debugMode = "debug"; //$NON-NLS-1$
82+
83+
private LaunchBarManager launchBarManagerMock = null;
84+
85+
@Before
86+
public void before() throws CoreException {
87+
Map<String, ILaunchConfigurationType> launchConfigTypes = new HashMap<>();
88+
// Create mocked Object no1
89+
ILaunchDescriptor descriptor_no1 = createLaunchDescriptorMock(launchObject_no1);
90+
ILaunchConfigurationType launchConfigType_no1 = createLaunchConfigType(launchConfigTypeId_no1,
91+
preferredMode_no1, runMode, debugMode);
92+
ILaunchConfigurationProvider launchConfigProvider_no1 = creatLaunchConfigProvier(launchConfigType_no1,
93+
descriptor_no1, preferredMode_no1);
94+
launchConfigTypes.put(launchConfigTypeId_no1, launchConfigType_no1);
95+
// Create mocked Object no2
96+
ILaunchDescriptor descriptor_no2 = createLaunchDescriptorMock(launchObject_no2);
97+
ILaunchConfigurationType launchConfigType_no2 = createLaunchConfigType(launchConfigTypeId_no2, runMode,
98+
debugMode);
99+
// preferredMode_no2 not supported
100+
doReturn(false).when(launchConfigType_no2).supportsMode(preferredMode_no2);
101+
ILaunchConfigurationProvider launchConfigProvider_no2 = creatLaunchConfigProvier(launchConfigType_no2,
102+
descriptor_no2, preferredMode_no2);
103+
launchConfigTypes.put(launchConfigTypeId_no2, launchConfigType_no2);
104+
// Mock Launch bar manager
105+
List<IConfigurationElement> elements = new ArrayList<>();
106+
final IExtensionPoint extensionPoint = mock(IExtensionPoint.class);
107+
IExtension extension = mock(IExtension.class);
108+
doReturn(new IExtension[] { extension }).when(extensionPoint).getExtensions();
109+
elements.add(createConfigElementMockForDescriptorType(launchDescTypeId_no1, descriptor_no1));
110+
elements.add(createConfigElementMockForConfigProvider(launchDescTypeId_no1, launchConfigProvider_no1));
111+
elements.add(createConfigElementMockForDescriptorType(launchDescTypeId_no2, descriptor_no2));
112+
elements.add(createConfigElementMockForConfigProvider(launchDescTypeId_no2, launchConfigProvider_no2));
113+
ILaunchManager launchManager = createLaunchManagerMock(launchConfigTypes, preferredMode_no1, preferredMode_no2,
114+
runMode, debugMode);
115+
ILaunchTargetManager targetManager = createLaunchTargetManagerMock();
116+
doReturn(elements.toArray(IConfigurationElement[]::new)).when(extension).getConfigurationElements();
117+
// Mock Launch bar manager
118+
launchBarManagerMock = createLaunchBarManagerMock(extensionPoint, launchManager, targetManager);
119+
// Initial LaunchBarManager
120+
launchBarManagerMock.init();
121+
}
122+
123+
@After
124+
public void after() {
125+
launchBarManagerMock.dispose();
126+
}
127+
46128
@Test
47129
public void startupTest() throws Exception {
48130
// Make sure the manager starts up and defaults everything to null
@@ -310,6 +392,207 @@ ILaunchTargetManager getLaunchTargetManager() {
310392
assertEquals(launchConfig, manager.getActiveLaunchConfiguration());
311393
}
312394

395+
/**
396+
* <p>
397+
* Test that preferred launch mode is taken into consideration in
398+
* {@link LaunchBarManager#syncActiveMode()}.
399+
* <p>
400+
* Verifies that when stored mode and last active mode is NULL, preferred mode is selected
401+
* as active mode.</p>
402+
*
403+
* Order when choosing active mode for active launch descriptor is:
404+
* <ul>stored mode -> last active mode -> preferred mode -> "run" -> "debug" -> supportedMode[0]</ul>
405+
*
406+
* @throws CoreException
407+
*/
408+
@Test
409+
public void preferredLaunchModeTest_StoredModeAndLastActiveModeIsNull() throws CoreException {
410+
launchBarManagerMock.launchObjectAdded(launchObject_no1);
411+
// "preferredMode_no1" will be selected as active mode.
412+
ILaunchMode activeMode = launchBarManagerMock.getActiveLaunchMode();
413+
assertEquals(preferredMode_no1, activeMode.getIdentifier());
414+
}
415+
416+
/**
417+
* <p>
418+
* Test that preferred launch mode is taken into consideration in
419+
* {@link LaunchBarManager#syncActiveMode()}.
420+
* <p>
421+
* Verifies that when stored mode and last active mode is NULL, and preferred mode is not
422+
* supported, "run" mode (fall back mode) is selected as active mode.</p>
423+
*
424+
* Order when choosing active mode for active launch descriptor is:
425+
* <ul>stored mode -> last active mode -> preferred mode -> "run" -> "debug" -> supportedMode[0]</ul>
426+
*
427+
* @throws CoreException
428+
*/
429+
@Test
430+
public void preferredLaunchModeTest_preferredModeNotSupported() throws CoreException {
431+
launchBarManagerMock.launchObjectAdded(launchObject_no2);
432+
// When preferred mode not supported, launch bar manager fall back to other hard-coded mode.
433+
// In this case, "run" comes after preferred mode, so "run" is selected as active mode.
434+
ILaunchMode activeMode = launchBarManagerMock.getActiveLaunchMode();
435+
assertEquals(runMode, activeMode.getIdentifier());
436+
}
437+
438+
/**
439+
* <p>
440+
* Test that preferred launch mode is taken into consideration in
441+
* {@link LaunchBarManager#syncActiveMode()}.
442+
* <p>
443+
* Verifies that when stored mode is NULL and last active mode is Not NULL, last active
444+
* mode will be selected as active mode.</p>
445+
*
446+
* Order when choosing active mode for active launch descriptor is:
447+
* <ul>stored mode -> last active mode -> preferred mode -> "run" -> "debug" -> supportedMode[0]</ul>
448+
*
449+
* @throws CoreException
450+
*/
451+
@Test
452+
public void preferredLaunchModeTest_lastActiveModeNotNull() throws CoreException {
453+
// After launch object no2 is added and activated, active mode now is "run" mode.
454+
launchBarManagerMock.launchObjectAdded(launchObject_no2);
455+
launchBarManagerMock.launchObjectAdded(launchObject_no1);
456+
// When launchObject_no1 is added, last active mode now will be "run."
457+
// Since preferred mode comes after last active mode, "run" mode is selected for launchObject_no1.
458+
ILaunchMode activeMode = launchBarManagerMock.getActiveLaunchMode();
459+
assertEquals(runMode, activeMode.getIdentifier());
460+
}
461+
462+
/**
463+
* <p>
464+
* Test that preferred launch mode is taken into consideration in
465+
* {@link LaunchBarManager#syncActiveMode()}.
466+
* <p>
467+
* Verifies that when stored mode is not NULL, stored mode is selected as active mode.</p>
468+
*
469+
* Order when choosing active mode for active launch descriptor is:
470+
* <ul>stored mode -> last active mode -> preferred mode -> "run" -> "debug" -> supportedMode[0]</ul>
471+
*
472+
* @throws CoreException
473+
*/
474+
@Test
475+
public void preferredLaunchModeTest_storedModeNotNull() throws CoreException {
476+
// Stored mode is saved as "preferredMode_no1" for launchObject_no1
477+
launchBarManagerMock.launchObjectAdded(launchObject_no1);
478+
launchBarManagerMock.launchObjectRemoved(launchObject_no1);
479+
// After launch object no2 is added and activated, active mode now is "run" mode.
480+
launchBarManagerMock.launchObjectAdded(launchObject_no2);
481+
launchBarManagerMock.launchObjectAdded(launchObject_no1);
482+
// After launch object no1 is added and activated, stored mode now is "preferredMode_no1".
483+
// Since stored mode comes first, "preferredMode_no1" mode is selected for launchObject_no1
484+
// when it is re-activated.
485+
ILaunchMode activeMode = launchBarManagerMock.getActiveLaunchMode();
486+
assertEquals(preferredMode_no1, activeMode.getIdentifier());
487+
}
488+
489+
private ILaunchDescriptor createLaunchDescriptorMock(Object launchObject) throws CoreException {
490+
ILaunchDescriptorType descriptorType = mock(ILaunchDescriptorType.class);
491+
ILaunchDescriptor descriptor = mock(ILaunchDescriptor.class);
492+
doReturn(true).when(descriptorType).supportsTargets();
493+
doReturn(descriptor).when(descriptorType).getDescriptor(launchObject);
494+
doReturn(descriptorType).when(descriptor).getType();
495+
doReturn(launchObject).when(descriptor).getName();
496+
return descriptor;
497+
}
498+
499+
private ILaunchConfigurationType createLaunchConfigType(String launchConfigTypeId, String... supportModes) {
500+
ILaunchConfigurationType launchConfigType = mock(ILaunchConfigurationType.class);
501+
doReturn(launchConfigTypeId).when(launchConfigType).getIdentifier();
502+
for (String mode : supportModes) {
503+
doReturn(true).when(launchConfigType).supportsMode(mode);
504+
}
505+
return launchConfigType;
506+
}
507+
508+
private ILaunchConfigurationProvider creatLaunchConfigProvier(ILaunchConfigurationType launchConfigType,
509+
ILaunchDescriptor desc, String preferredMode) throws CoreException {
510+
ILaunchConfigurationProvider configProvider = mock(ILaunchConfigurationProvider.class);
511+
ILaunchConfiguration launchConfig = mock(ILaunchConfiguration.class);
512+
doReturn(launchConfig).when(configProvider).getLaunchConfiguration(eq(desc), any(ILaunchTarget.class));
513+
doReturn(launchConfigType).when(configProvider).getLaunchConfigurationType(any(ILaunchDescriptor.class),
514+
any(ILaunchTarget.class));
515+
doReturn(launchConfig).when(desc).getAdapter(ILaunchConfiguration.class);
516+
doAnswer(invocation -> {
517+
ILaunchTarget target = (ILaunchTarget) invocation.getArguments()[1];
518+
return target.getTypeId().equals(ILaunchTargetManager.localLaunchTargetTypeId);
519+
}).when(configProvider).supports(eq(desc), any(ILaunchTarget.class));
520+
doReturn(preferredMode).when(configProvider).getPreferredLaunchModeId(eq(desc), any(ILaunchTarget.class));
521+
return configProvider;
522+
}
523+
524+
private IConfigurationElement createConfigElementMockForDescriptorType(String descriptorTypeId,
525+
ILaunchDescriptor desc) throws CoreException {
526+
IConfigurationElement element = mock(IConfigurationElement.class);
527+
doReturn("descriptorType").when(element).getName(); //$NON-NLS-1$
528+
doReturn(descriptorTypeId).when(element).getAttribute("id"); //$NON-NLS-1$
529+
doReturn(desc.getType()).when(element).createExecutableExtension("class"); //$NON-NLS-1$
530+
return element;
531+
}
532+
533+
private IConfigurationElement createConfigElementMockForConfigProvider(String descriptorTypeId,
534+
ILaunchConfigurationProvider configProvider) throws CoreException {
535+
IConfigurationElement element = mock(IConfigurationElement.class);
536+
doReturn("configProvider").when(element).getName(); //$NON-NLS-1$
537+
doReturn(descriptorTypeId).when(element).getAttribute("descriptorType"); //$NON-NLS-1$
538+
doReturn("10").when(element).getAttribute("priority"); //$NON-NLS-1$ $NON-NLS-2$
539+
doReturn(configProvider).when(element).createExecutableExtension("class"); //$NON-NLS-1$
540+
return element;
541+
}
542+
543+
private ILaunchTargetManager createLaunchTargetManagerMock() {
544+
ILaunchTargetManager targetManager = mock(ILaunchTargetManager.class);
545+
ILaunchTarget localTarget = mock(ILaunchTarget.class);
546+
doReturn(ILaunchTargetManager.localLaunchTargetTypeId).when(localTarget).getTypeId();
547+
doReturn("Local").when(localTarget).getId(); //$NON-NLS-1$
548+
doReturn(new ILaunchTarget[] { localTarget }).when(targetManager).getLaunchTargets();
549+
return targetManager;
550+
}
551+
552+
private ILaunchManager createLaunchManagerMock(Map<String, ILaunchConfigurationType> launchConfigTypes,
553+
String... supportModes) throws CoreException {
554+
ILaunchManager launchManager = mock(ILaunchManager.class);
555+
List<ILaunchMode> modes = new ArrayList<>();
556+
for (String supportMode : supportModes) {
557+
ILaunchMode mode = createLaunchModeMock(supportMode);
558+
doReturn(mode).when(launchManager).getLaunchMode(supportMode);
559+
modes.add(mode);
560+
}
561+
doReturn(modes.toArray(ILaunchMode[]::new)).when(launchManager).getLaunchModes();
562+
563+
launchConfigTypes.forEach((typeId, type) -> {
564+
doReturn(type).when(launchManager).getLaunchConfigurationType(typeId);
565+
});
566+
doReturn(new ILaunchConfiguration[0]).when(launchManager).getLaunchConfigurations();
567+
return launchManager;
568+
}
569+
570+
private LaunchBarManager createLaunchBarManagerMock(IExtensionPoint extensionPoint, ILaunchManager launchManager,
571+
ILaunchTargetManager targetManager) {
572+
return new LaunchBarManager(false) {
573+
@Override
574+
IExtensionPoint getExtensionPoint() throws CoreException {
575+
return extensionPoint;
576+
}
577+
578+
@Override
579+
ILaunchManager getLaunchManager() {
580+
return launchManager;
581+
}
582+
583+
@Override
584+
ILaunchTargetManager getLaunchTargetManager() {
585+
return targetManager;
586+
}
587+
};
588+
}
589+
590+
private ILaunchMode createLaunchModeMock(String identifier) {
591+
ILaunchMode mode = mock(ILaunchMode.class);
592+
doReturn(identifier).when(mode).getIdentifier();
593+
return mode;
594+
}
595+
313596
// TODO - test that changing active target type produces a different launch
314597
// config type
315598
// TODO - test that settings are maintained after a restart
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2+
<component id="org.eclipse.launchbar.core" version="2">
3+
<resource path="src/org/eclipse/launchbar/core/ILaunchConfigurationProvider.java" type="org.eclipse.launchbar.core.ILaunchConfigurationProvider">
4+
<filter id="404000815">
5+
<message_arguments>
6+
<message_argument value="org.eclipse.launchbar.core.ILaunchConfigurationProvider"/>
7+
<message_argument value="getPreferredLaunchModeId(ILaunchDescriptor, ILaunchTarget)"/>
8+
</message_arguments>
9+
</filter>
10+
</resource>
11+
</component>

launchbar/org.eclipse.launchbar.core/META-INF/MANIFEST.MF

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
22
Bundle-ManifestVersion: 2
33
Bundle-Name: %pluginName
44
Bundle-SymbolicName: org.eclipse.launchbar.core;singleton:=true
5-
Bundle-Version: 3.1.0.qualifier
5+
Bundle-Version: 3.2.0.qualifier
66
Bundle-Activator: org.eclipse.launchbar.core.internal.Activator
77
Bundle-Vendor: %providerName
88
Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.34.0,4.0.0)",

launchbar/org.eclipse.launchbar.core/src/org/eclipse/launchbar/core/ILaunchConfigurationProvider.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,4 +131,26 @@ boolean launchDescriptorMatches(ILaunchDescriptor descriptor, ILaunchConfigurati
131131
*/
132132
void launchTargetRemoved(ILaunchTarget target) throws CoreException;
133133

134+
/**
135+
* Returns the preferred launch mode id for the given launch descriptor and target.
136+
* <p>
137+
* Returning {@code null} indicates that this provider has no preferred mode for
138+
* the given descriptor/target combination.
139+
* </p>
140+
* <p>
141+
* The returned id is treated as a preference only. If it does not resolve to a
142+
* known launch mode, or if that mode is not supported for the active descriptor
143+
* and target, Launch Bar continues normal fallback resolution.
144+
* </p>
145+
*
146+
* @param descriptor the launch descriptor
147+
* @param target the launch target
148+
* @return the preferred launch mode id, or {@code null} if none
149+
* @throws CoreException if the preferred mode cannot be determined
150+
* @since 3.2
151+
*/
152+
default String getPreferredLaunchModeId(ILaunchDescriptor descriptor, ILaunchTarget target) throws CoreException {
153+
return null;
154+
}
155+
134156
}

launchbar/org.eclipse.launchbar.core/src/org/eclipse/launchbar/core/internal/LaunchBarManager.java

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -569,10 +569,11 @@ private void syncActiveMode() throws CoreException {
569569
// last desc mode id
570570
String storedModeId = getPerDescriptorStore().get(PREF_ACTIVE_LAUNCH_MODE, null);
571571
String lastActiveModeId = activeLaunchMode == null ? null : activeLaunchMode.getIdentifier();
572+
String preferredModeId = getPreferredLaunchModeId(activeLaunchDesc, activeLaunchTarget);
572573
// this is based on active desc and target which are already set
573574
ILaunchMode[] supportedModes = getLaunchModes();
574575
if (supportedModes.length > 0) { // mna, what if no modes are supported?
575-
String modeNames[] = new String[] { storedModeId, lastActiveModeId, "run", //$NON-NLS-1$
576+
String modeNames[] = new String[] { storedModeId, lastActiveModeId, preferredModeId, "run", //$NON-NLS-1$
576577
"debug", //$NON-NLS-1$
577578
supportedModes[0].getIdentifier() };
578579
for (int i = 0; i < modeNames.length; i++) {
@@ -1050,4 +1051,24 @@ private boolean launchDescriptorMatches(ILaunchDescriptor desc, ILaunchConfigura
10501051
}
10511052
return false;
10521053
}
1054+
1055+
private String getPreferredLaunchModeId(ILaunchDescriptor descriptor, ILaunchTarget target) throws CoreException {
1056+
if (descriptor == null) {
1057+
return null;
1058+
}
1059+
List<LaunchConfigProviderInfo> providerInfos = configProviders.get(getDescriptorTypeId(descriptor.getType()));
1060+
if (providerInfos == null) {
1061+
return null;
1062+
}
1063+
for (LaunchConfigProviderInfo providerInfo : providerInfos) {
1064+
if (providerInfo.enabled(descriptor) && providerInfo.enabled(target)) {
1065+
ILaunchConfigurationProvider provider = providerInfo.getProvider();
1066+
if (provider != null && provider.supports(descriptor, target)) {
1067+
return provider.getPreferredLaunchModeId(descriptor, target);
1068+
}
1069+
}
1070+
}
1071+
// not found
1072+
return null;
1073+
}
10531074
}

0 commit comments

Comments
 (0)