mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-20 15:35:24 +02:00
launchbar: enablement expressions for desc. type
added ability to define enablement for descriptor type, to allow lazy loading of plugins Change-Id: I9a9f494d0720f752c0cfebf20316f9f8274ee23f
This commit is contained in:
parent
b46cc02560
commit
f4944e5e27
7 changed files with 93 additions and 16 deletions
|
@ -8,7 +8,8 @@ Bundle-Vendor: Eclipse CDT
|
||||||
Require-Bundle: org.eclipse.core.runtime,
|
Require-Bundle: org.eclipse.core.runtime,
|
||||||
org.eclipse.debug.core,
|
org.eclipse.debug.core,
|
||||||
org.eclipse.core.filesystem,
|
org.eclipse.core.filesystem,
|
||||||
org.eclipse.remote.core;bundle-version="2.0.0"
|
org.eclipse.remote.core;bundle-version="2.0.0",
|
||||||
|
org.eclipse.core.expressions
|
||||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
|
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
|
||||||
Bundle-ActivationPolicy: lazy
|
Bundle-ActivationPolicy: lazy
|
||||||
Export-Package: org.eclipse.launchbar.core,
|
Export-Package: org.eclipse.launchbar.core,
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
class="org.eclipse.launchbar.core.internal.DefaultLaunchDescriptorType"
|
class="org.eclipse.launchbar.core.internal.DefaultLaunchDescriptorType"
|
||||||
id="org.eclipse.launchbar.core.descriptorType.default"
|
id="org.eclipse.launchbar.core.descriptorType.default"
|
||||||
priority="0">
|
priority="0">
|
||||||
|
<enablement></enablement>
|
||||||
</descriptorType>
|
</descriptorType>
|
||||||
<configProvider
|
<configProvider
|
||||||
class="org.eclipse.launchbar.core.DefaultLaunchConfigProvider"
|
class="org.eclipse.launchbar.core.DefaultLaunchConfigProvider"
|
||||||
|
|
|
@ -10,6 +10,8 @@
|
||||||
</documentation>
|
</documentation>
|
||||||
</annotation>
|
</annotation>
|
||||||
|
|
||||||
|
<include schemaLocation="schema://org.eclipse.core.expressions/schema/expressionLanguage.exsd"/>
|
||||||
|
|
||||||
<element name="extension">
|
<element name="extension">
|
||||||
<annotation>
|
<annotation>
|
||||||
<appinfo>
|
<appinfo>
|
||||||
|
@ -56,6 +58,9 @@
|
||||||
</documentation>
|
</documentation>
|
||||||
</annotation>
|
</annotation>
|
||||||
<complexType>
|
<complexType>
|
||||||
|
<sequence>
|
||||||
|
<element ref="enablement"/>
|
||||||
|
</sequence>
|
||||||
<attribute name="id" type="string" use="required">
|
<attribute name="id" type="string" use="required">
|
||||||
<annotation>
|
<annotation>
|
||||||
<documentation>
|
<documentation>
|
||||||
|
|
|
@ -18,11 +18,13 @@ import org.eclipse.core.runtime.CoreException;
|
||||||
* It is strongly recommended to extend AbstarctLaunchDescriptorType instead of implementing this directly
|
* It is strongly recommended to extend AbstarctLaunchDescriptorType instead of implementing this directly
|
||||||
*/
|
*/
|
||||||
public interface ILaunchDescriptorType {
|
public interface ILaunchDescriptorType {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Does this type own this launch object?
|
* Does this type own this launch object?
|
||||||
*
|
*
|
||||||
* @deprecated this needs to be replaced by enablement to avoid plug-in loading.
|
* The main checking should be done in enablement expression of extension declaring the type,
|
||||||
|
* if enablement expression if defined this method can return true.
|
||||||
|
* This also can used for fine-tuning of ownership
|
||||||
|
* which is hard to declared in xml.
|
||||||
*
|
*
|
||||||
* @param element
|
* @param element
|
||||||
* @return owns element
|
* @return owns element
|
||||||
|
|
|
@ -76,7 +76,6 @@ public class LaunchBarManager implements ILaunchBarManager, ILaunchConfiguration
|
||||||
|
|
||||||
// the extended info for loaded descriptor types
|
// the extended info for loaded descriptor types
|
||||||
private final Map<ILaunchDescriptorType, LaunchDescriptorTypeInfo> descriptorTypeInfo = new HashMap<>();
|
private final Map<ILaunchDescriptorType, LaunchDescriptorTypeInfo> descriptorTypeInfo = new HashMap<>();
|
||||||
|
|
||||||
private final Map<String, List<LaunchConfigProviderInfo>> configProviders = new HashMap<>();
|
private final Map<String, List<LaunchConfigProviderInfo>> configProviders = new HashMap<>();
|
||||||
|
|
||||||
// Descriptors in MRU order, key is desc type id and desc name.
|
// Descriptors in MRU order, key is desc type id and desc name.
|
||||||
|
@ -194,9 +193,7 @@ public class LaunchBarManager implements ILaunchBarManager, ILaunchConfiguration
|
||||||
LaunchDescriptorTypeInfo typeInfo = new LaunchDescriptorTypeInfo(element);
|
LaunchDescriptorTypeInfo typeInfo = new LaunchDescriptorTypeInfo(element);
|
||||||
|
|
||||||
descriptorTypes.put(typeInfo.getId(), typeInfo);
|
descriptorTypes.put(typeInfo.getId(), typeInfo);
|
||||||
// TODO figure out a better place to set the id so we don't load the type object
|
|
||||||
// until needed
|
|
||||||
descriptorTypeInfo.put(typeInfo.getType(), typeInfo);
|
|
||||||
|
|
||||||
if (configProviders.get(typeInfo.getId()) == null) {
|
if (configProviders.get(typeInfo.getId()) == null) {
|
||||||
// Make sure we initialize the list
|
// Make sure we initialize the list
|
||||||
|
@ -211,8 +208,8 @@ public class LaunchBarManager implements ILaunchBarManager, ILaunchConfiguration
|
||||||
}
|
}
|
||||||
providers.add(info);
|
providers.add(info);
|
||||||
}
|
}
|
||||||
} catch (CoreException e) {
|
} catch (Exception e) {
|
||||||
Activator.log(e.getStatus());
|
Activator.log(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -329,13 +326,14 @@ public class LaunchBarManager implements ILaunchBarManager, ILaunchConfiguration
|
||||||
}
|
}
|
||||||
|
|
||||||
private ILaunchDescriptorType ownsLaunchObject(Object launchObject) throws CoreException {
|
private ILaunchDescriptorType ownsLaunchObject(Object launchObject) throws CoreException {
|
||||||
// TODO use enablement to find out what descriptor types to ask
|
|
||||||
// to prevent unnecessary plug-in loading
|
|
||||||
for (LaunchDescriptorTypeInfo descriptorInfo : orderedDescriptorTypes) {
|
for (LaunchDescriptorTypeInfo descriptorInfo : orderedDescriptorTypes) {
|
||||||
ILaunchDescriptorType descriptorType = descriptorInfo.getType();
|
|
||||||
try {
|
try {
|
||||||
if (descriptorType.ownsLaunchObject(launchObject)) {
|
if (descriptorInfo.ownsLaunchObject(launchObject)) {
|
||||||
return descriptorType;
|
ILaunchDescriptorType type = descriptorInfo.getType();
|
||||||
|
descriptorTypeInfo.put(type, descriptorInfo);
|
||||||
|
if (type.ownsLaunchObject(launchObject)) {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
Activator.log(e); // one of used defined launch types is misbehaving
|
Activator.log(e); // one of used defined launch types is misbehaving
|
||||||
|
|
|
@ -1,7 +1,12 @@
|
||||||
package org.eclipse.launchbar.core.internal;
|
package org.eclipse.launchbar.core.internal;
|
||||||
|
|
||||||
|
import org.eclipse.core.expressions.EvaluationContext;
|
||||||
|
import org.eclipse.core.expressions.EvaluationResult;
|
||||||
|
import org.eclipse.core.expressions.Expression;
|
||||||
|
import org.eclipse.core.expressions.ExpressionConverter;
|
||||||
import org.eclipse.core.runtime.CoreException;
|
import org.eclipse.core.runtime.CoreException;
|
||||||
import org.eclipse.core.runtime.IConfigurationElement;
|
import org.eclipse.core.runtime.IConfigurationElement;
|
||||||
|
import org.eclipse.core.runtime.Status;
|
||||||
import org.eclipse.launchbar.core.ILaunchDescriptorType;
|
import org.eclipse.launchbar.core.ILaunchDescriptorType;
|
||||||
|
|
||||||
public class LaunchDescriptorTypeInfo {
|
public class LaunchDescriptorTypeInfo {
|
||||||
|
@ -9,6 +14,7 @@ public class LaunchDescriptorTypeInfo {
|
||||||
private int priority;
|
private int priority;
|
||||||
private IConfigurationElement element;
|
private IConfigurationElement element;
|
||||||
private ILaunchDescriptorType type;
|
private ILaunchDescriptorType type;
|
||||||
|
private Expression expression;
|
||||||
|
|
||||||
public LaunchDescriptorTypeInfo(IConfigurationElement element) {
|
public LaunchDescriptorTypeInfo(IConfigurationElement element) {
|
||||||
this.id = element.getAttribute("id"); //$NON-NLS-1$
|
this.id = element.getAttribute("id"); //$NON-NLS-1$
|
||||||
|
@ -23,6 +29,25 @@ public class LaunchDescriptorTypeInfo {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.element = element;
|
this.element = element;
|
||||||
|
IConfigurationElement[] enabledExpressions = element.getChildren("enablement");//$NON-NLS-1$
|
||||||
|
if (enabledExpressions == null || enabledExpressions.length == 0) {
|
||||||
|
Activator.log(new Status(Status.WARNING, Activator.PLUGIN_ID,
|
||||||
|
"Enablement expression is missing for descriptor type " + id));//$NON-NLS-1$
|
||||||
|
} else if (enabledExpressions.length > 1) {
|
||||||
|
Activator.log(new Status(Status.WARNING, Activator.PLUGIN_ID,
|
||||||
|
"Multiple enablement expressions are detected for descriptor type "//$NON-NLS-1$
|
||||||
|
+ id));
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
expression = ExpressionConverter.getDefault().perform(enabledExpressions[0]);
|
||||||
|
} catch (CoreException e) {
|
||||||
|
Activator.log(e);
|
||||||
|
}
|
||||||
|
if (expression == null) {
|
||||||
|
Activator.log(new Status(Status.ERROR, Activator.PLUGIN_ID,
|
||||||
|
"Cannot parse enablement expression defined in descriptor type " + id)); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Used for testing
|
// Used for testing
|
||||||
|
@ -47,4 +72,11 @@ public class LaunchDescriptorTypeInfo {
|
||||||
}
|
}
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean ownsLaunchObject(Object object) throws CoreException {
|
||||||
|
if (expression == null)
|
||||||
|
return true;
|
||||||
|
EvaluationResult result = expression.evaluate(new EvaluationContext(null, object));
|
||||||
|
return (result == EvaluationResult.TRUE);
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -80,7 +80,7 @@ public class LaunchBarManager2Test {
|
||||||
private ArrayList<ILaunchMode> globalmodes = new ArrayList<>();
|
private ArrayList<ILaunchMode> globalmodes = new ArrayList<>();
|
||||||
IExtensionPoint point;
|
IExtensionPoint point;
|
||||||
IEclipsePreferences store = new EclipsePreferences();
|
IEclipsePreferences store = new EclipsePreferences();
|
||||||
private ArrayList<Object> elements;
|
private ArrayList<IConfigurationElement> elements;
|
||||||
private IExtension extension;
|
private IExtension extension;
|
||||||
private static final String localTargetTypeId = "org.eclipse.remote.LocalServices";
|
private static final String localTargetTypeId = "org.eclipse.remote.LocalServices";
|
||||||
private String descriptorTypeId;
|
private String descriptorTypeId;
|
||||||
|
@ -148,9 +148,23 @@ public class LaunchBarManager2Test {
|
||||||
doReturn(descriptorTypeId).when(element).getAttribute("id");
|
doReturn(descriptorTypeId).when(element).getAttribute("id");
|
||||||
doReturn(Integer.toString(priority)).when(element).getAttribute("priority");
|
doReturn(Integer.toString(priority)).when(element).getAttribute("priority");
|
||||||
doReturn(descriptorType).when(element).createExecutableExtension("class");
|
doReturn(descriptorType).when(element).createExecutableExtension("class");
|
||||||
|
mockEnablementElement(element);
|
||||||
return element;
|
return element;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void mockSubElement(IConfigurationElement parent, IConfigurationElement... elements) {
|
||||||
|
doReturn(elements).when(parent).getChildren();
|
||||||
|
String name = elements[0].getName();
|
||||||
|
doReturn(elements).when(parent).getChildren(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
private IConfigurationElement mockEnablementElement(IConfigurationElement parent) {
|
||||||
|
IConfigurationElement enablement = mock(IConfigurationElement.class);
|
||||||
|
doReturn("enablement").when(enablement).getName();
|
||||||
|
mockSubElement(parent, new IConfigurationElement[] { enablement });
|
||||||
|
return enablement;
|
||||||
|
}
|
||||||
|
|
||||||
protected void init() throws CoreException {
|
protected void init() throws CoreException {
|
||||||
doReturn(elements.toArray(new IConfigurationElement[0])).when(extension).getConfigurationElements();
|
doReturn(elements.toArray(new IConfigurationElement[0])).when(extension).getConfigurationElements();
|
||||||
doReturn(targets).when(remoteServiceManager).getAllRemoteConnections();
|
doReturn(targets).when(remoteServiceManager).getAllRemoteConnections();
|
||||||
|
@ -331,6 +345,7 @@ public class LaunchBarManager2Test {
|
||||||
ConfigBasedLaunchDescriptor desc2 = new ConfigBasedLaunchDescriptor(descriptorType, lc2);
|
ConfigBasedLaunchDescriptor desc2 = new ConfigBasedLaunchDescriptor(descriptorType, lc2);
|
||||||
mockProviderElement(descriptorTypeId, 10, desc2, target, lc2, lc2);
|
mockProviderElement(descriptorTypeId, 10, desc2, target, lc2, lc2);
|
||||||
init();
|
init();
|
||||||
|
manager.launchObjectAdded(launchObject);
|
||||||
// it return original lctype because we did not associate this dynmaically
|
// it return original lctype because we did not associate this dynmaically
|
||||||
assertEquals(launchConfigType, manager.getLaunchConfigurationType(descriptor, target));
|
assertEquals(launchConfigType, manager.getLaunchConfigurationType(descriptor, target));
|
||||||
}
|
}
|
||||||
|
@ -344,6 +359,7 @@ public class LaunchBarManager2Test {
|
||||||
ILaunchConfiguration lc2 = mockLC("lc2", lctype2);
|
ILaunchConfiguration lc2 = mockLC("lc2", lctype2);
|
||||||
mockProviderElement(descriptorTypeId, 20, descriptor, target, lc2, launchObject);
|
mockProviderElement(descriptorTypeId, 20, descriptor, target, lc2, launchObject);
|
||||||
init();
|
init();
|
||||||
|
manager.launchObjectAdded(launchObject);
|
||||||
assertEquals(lctype2, manager.getLaunchConfigurationType(descriptor, target));
|
assertEquals(lctype2, manager.getLaunchConfigurationType(descriptor, target));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -820,6 +836,7 @@ public class LaunchBarManager2Test {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetLaunchConfigurationType() throws CoreException {
|
public void testGetLaunchConfigurationType() throws CoreException {
|
||||||
|
manager.launchObjectAdded(launchObject);
|
||||||
assertNotNull(manager.getLaunchConfigurationType(descriptor, otherTarget));
|
assertNotNull(manager.getLaunchConfigurationType(descriptor, otherTarget));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -830,12 +847,14 @@ public class LaunchBarManager2Test {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetLaunchConfigurationNull2() throws CoreException {
|
public void testGetLaunchConfigurationNull2() throws CoreException {
|
||||||
|
manager.launchObjectAdded(launchObject);
|
||||||
assertNull(manager.getLaunchConfiguration(descriptor, null));
|
assertNull(manager.getLaunchConfiguration(descriptor, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetLaunchConfiguration() throws CoreException {
|
public void testGetLaunchConfiguration() throws CoreException {
|
||||||
basicSetup();
|
basicSetup();
|
||||||
|
manager.launchObjectAdded(launchObject);
|
||||||
assertTrue(manager.supportsTarget(descriptor, otherTarget));
|
assertTrue(manager.supportsTarget(descriptor, otherTarget));
|
||||||
assertNotNull(manager.getLaunchConfiguration(descriptor, otherTarget));
|
assertNotNull(manager.getLaunchConfiguration(descriptor, otherTarget));
|
||||||
}
|
}
|
||||||
|
@ -926,4 +945,23 @@ public class LaunchBarManager2Test {
|
||||||
manager.launchConfigurationRemoved(launchConfig);
|
manager.launchConfigurationRemoved(launchConfig);
|
||||||
verify(provider).launchConfigurationRemoved(launchConfig);
|
verify(provider).launchConfigurationRemoved(launchConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDescriptorEnablement() throws CoreException {
|
||||||
|
basicSetupOnly();
|
||||||
|
elements.clear();
|
||||||
|
|
||||||
|
IConfigurationElement element = mockDescriptorTypeElement("type2", 10, descriptorType);
|
||||||
|
IConfigurationElement enablement = mockEnablementElement(element);
|
||||||
|
IConfigurationElement instance = mock(IConfigurationElement.class);
|
||||||
|
doReturn("instanceof").when(instance).getName();
|
||||||
|
mockSubElement(enablement, new IConfigurationElement[] { instance });
|
||||||
|
doReturn("java.lang.Integer").when(instance).getAttribute("value");
|
||||||
|
init();
|
||||||
|
assertNull(manager.launchObjectAdded(launchObject)); // this will be refused by enablement expression
|
||||||
|
assertNull(manager.launchObjectAdded(1)); // we programmatically refuse this
|
||||||
|
mockLaunchObjectOnDescriptor(1);
|
||||||
|
assertNotNull(manager.launchObjectAdded(1)); // now we both good programmatically and in expression in extension
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue