1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-03 07:05: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:
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,
org.eclipse.debug.core,
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-ActivationPolicy: lazy
Export-Package: org.eclipse.launchbar.core,

View file

@ -10,8 +10,9 @@
</objectProvider>
<descriptorType
class="org.eclipse.launchbar.core.internal.DefaultLaunchDescriptorType"
id="org.eclipse.launchbar.core.descriptorType.default"
id="org.eclipse.launchbar.core.descriptorType.default"
priority="0">
<enablement></enablement>
</descriptorType>
<configProvider
class="org.eclipse.launchbar.core.DefaultLaunchConfigProvider"

View file

@ -10,6 +10,8 @@
</documentation>
</annotation>
<include schemaLocation="schema://org.eclipse.core.expressions/schema/expressionLanguage.exsd"/>
<element name="extension">
<annotation>
<appinfo>
@ -56,6 +58,9 @@
</documentation>
</annotation>
<complexType>
<sequence>
<element ref="enablement"/>
</sequence>
<attribute name="id" type="string" use="required">
<annotation>
<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
*/
public interface ILaunchDescriptorType {
/**
* 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
* @return owns element

View file

@ -76,7 +76,6 @@ public class LaunchBarManager implements ILaunchBarManager, ILaunchConfiguration
// the extended info for loaded descriptor types
private final Map<ILaunchDescriptorType, LaunchDescriptorTypeInfo> descriptorTypeInfo = new HashMap<>();
private final Map<String, List<LaunchConfigProviderInfo>> configProviders = new HashMap<>();
// 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);
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) {
// Make sure we initialize the list
@ -211,8 +208,8 @@ public class LaunchBarManager implements ILaunchBarManager, ILaunchConfiguration
}
providers.add(info);
}
} catch (CoreException e) {
Activator.log(e.getStatus());
} catch (Exception e) {
Activator.log(e);
}
}
}
@ -329,13 +326,14 @@ public class LaunchBarManager implements ILaunchBarManager, ILaunchConfiguration
}
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) {
ILaunchDescriptorType descriptorType = descriptorInfo.getType();
try {
if (descriptorType.ownsLaunchObject(launchObject)) {
return descriptorType;
if (descriptorInfo.ownsLaunchObject(launchObject)) {
ILaunchDescriptorType type = descriptorInfo.getType();
descriptorTypeInfo.put(type, descriptorInfo);
if (type.ownsLaunchObject(launchObject)) {
return type;
}
}
} catch (Throwable e) {
Activator.log(e); // one of used defined launch types is misbehaving

View file

@ -1,7 +1,12 @@
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.IConfigurationElement;
import org.eclipse.core.runtime.Status;
import org.eclipse.launchbar.core.ILaunchDescriptorType;
public class LaunchDescriptorTypeInfo {
@ -9,6 +14,7 @@ public class LaunchDescriptorTypeInfo {
private int priority;
private IConfigurationElement element;
private ILaunchDescriptorType type;
private Expression expression;
public LaunchDescriptorTypeInfo(IConfigurationElement element) {
this.id = element.getAttribute("id"); //$NON-NLS-1$
@ -23,6 +29,25 @@ public class LaunchDescriptorTypeInfo {
}
}
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
@ -47,4 +72,11 @@ public class LaunchDescriptorTypeInfo {
}
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<>();
IExtensionPoint point;
IEclipsePreferences store = new EclipsePreferences();
private ArrayList<Object> elements;
private ArrayList<IConfigurationElement> elements;
private IExtension extension;
private static final String localTargetTypeId = "org.eclipse.remote.LocalServices";
private String descriptorTypeId;
@ -148,9 +148,23 @@ public class LaunchBarManager2Test {
doReturn(descriptorTypeId).when(element).getAttribute("id");
doReturn(Integer.toString(priority)).when(element).getAttribute("priority");
doReturn(descriptorType).when(element).createExecutableExtension("class");
mockEnablementElement(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 {
doReturn(elements.toArray(new IConfigurationElement[0])).when(extension).getConfigurationElements();
doReturn(targets).when(remoteServiceManager).getAllRemoteConnections();
@ -331,6 +345,7 @@ public class LaunchBarManager2Test {
ConfigBasedLaunchDescriptor desc2 = new ConfigBasedLaunchDescriptor(descriptorType, lc2);
mockProviderElement(descriptorTypeId, 10, desc2, target, lc2, lc2);
init();
manager.launchObjectAdded(launchObject);
// it return original lctype because we did not associate this dynmaically
assertEquals(launchConfigType, manager.getLaunchConfigurationType(descriptor, target));
}
@ -344,6 +359,7 @@ public class LaunchBarManager2Test {
ILaunchConfiguration lc2 = mockLC("lc2", lctype2);
mockProviderElement(descriptorTypeId, 20, descriptor, target, lc2, launchObject);
init();
manager.launchObjectAdded(launchObject);
assertEquals(lctype2, manager.getLaunchConfigurationType(descriptor, target));
}
@ -820,6 +836,7 @@ public class LaunchBarManager2Test {
@Test
public void testGetLaunchConfigurationType() throws CoreException {
manager.launchObjectAdded(launchObject);
assertNotNull(manager.getLaunchConfigurationType(descriptor, otherTarget));
}
@ -830,12 +847,14 @@ public class LaunchBarManager2Test {
@Test
public void testGetLaunchConfigurationNull2() throws CoreException {
manager.launchObjectAdded(launchObject);
assertNull(manager.getLaunchConfiguration(descriptor, null));
}
@Test
public void testGetLaunchConfiguration() throws CoreException {
basicSetup();
manager.launchObjectAdded(launchObject);
assertTrue(manager.supportsTarget(descriptor, otherTarget));
assertNotNull(manager.getLaunchConfiguration(descriptor, otherTarget));
}
@ -926,4 +945,23 @@ public class LaunchBarManager2Test {
manager.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
}
}