1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-20 07:25:23 +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:
Alena Laskavaia 2015-05-29 13:16:15 -04:00
parent b46cc02560
commit f4944e5e27
7 changed files with 93 additions and 16 deletions

View file

@ -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,

View file

@ -10,8 +10,9 @@
</objectProvider> </objectProvider>
<descriptorType <descriptorType
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"

View file

@ -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>

View file

@ -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

View file

@ -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

View file

@ -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);
}
} }

View file

@ -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
}
} }