Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'target_explorer/plugins/org.eclipse.tcf.te.runtime.services/src/org/eclipse/tcf/te/runtime')
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.runtime.services/src/org/eclipse/tcf/te/runtime/services/AbstractServiceManager.java228
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.runtime.services/src/org/eclipse/tcf/te/runtime/services/ServiceManager.java44
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.runtime.services/src/org/eclipse/tcf/te/runtime/services/interfaces/IService.java4
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.runtime.services/src/org/eclipse/tcf/te/runtime/services/nls/Messages.java1
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.runtime.services/src/org/eclipse/tcf/te/runtime/services/nls/Messages.properties1
5 files changed, 167 insertions, 111 deletions
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.runtime.services/src/org/eclipse/tcf/te/runtime/services/AbstractServiceManager.java b/target_explorer/plugins/org.eclipse.tcf.te.runtime.services/src/org/eclipse/tcf/te/runtime/services/AbstractServiceManager.java
index b84f99c20..03b0dd5ae 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.runtime.services/src/org/eclipse/tcf/te/runtime/services/AbstractServiceManager.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.runtime.services/src/org/eclipse/tcf/te/runtime/services/AbstractServiceManager.java
@@ -10,53 +10,91 @@
package org.eclipse.tcf.te.runtime.services;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+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.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExecutableExtension;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.tcf.te.runtime.nls.Messages;
+import org.eclipse.tcf.te.runtime.services.activator.CoreBundleActivator;
import org.eclipse.tcf.te.runtime.services.interfaces.IService;
-import org.eclipse.tcf.te.runtime.activator.CoreBundleActivator;
/**
* Abstract service manager implementation.
*/
public abstract class AbstractServiceManager<V extends IService> {
- // map for all services per id
- private Map<String, List<ServiceProxy>> services = new HashMap<String, List<ServiceProxy>>();
+ // Map for all contributed services stored by their respective unique id
+ private Map<String, ServiceProxy> services = new HashMap<String, ServiceProxy>();
/**
* Proxy to provide lazy loading of contributing plug-ins.
*/
- protected class ServiceProxy {
-
+ protected class ServiceProxy implements IExecutableExtension {
+ // Reference to the configuration element
private IConfigurationElement configElement = null;
+ // The id of the service contribution
+ public String id;
+ // The class implementing the service
public String clazz;
+ // The service instance
private V service = null;
+ // The list of service types the service is implementing
private List<Class<? extends V>> serviceTypes = new ArrayList<Class<? extends V>>();
+ // The converted expression
+ private Expression expression;
/**
* Constructor.
*/
- protected ServiceProxy(IConfigurationElement configElement) {
- Assert.isNotNull(configElement);
- this.configElement = configElement;
+ protected ServiceProxy() {
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.runtime.IExecutableExtension#setInitializationData(org.eclipse.core.runtime.IConfigurationElement, java.lang.String, java.lang.Object)
+ */
+ @Override
+ public void setInitializationData(IConfigurationElement config, String propertyName, Object data) throws CoreException {
+ Assert.isNotNull(config);
+ this.configElement = config;
+
+ // Initialize the id field by reading the <id> extension attribute.
+ // Throws an exception if the id is empty or null.
+ id = config != null ? config.getAttribute("id") : null; //$NON-NLS-1$
+ if (id == null || (id != null && "".equals(id.trim()))) { //$NON-NLS-1$
+ throw new CoreException(new Status(IStatus.ERROR,
+ CoreBundleActivator.getUniqueIdentifier(),
+ NLS.bind(Messages.Extension_error_missingRequiredAttribute, "id", config.getContributor().getName()))); //$NON-NLS-1$
+ }
// Read the class attribute. If null, check for the class sub element
- clazz = configElement.getAttribute("class"); //$NON-NLS-1$
+ clazz = config.getAttribute("class"); //$NON-NLS-1$
if (clazz == null) {
- IConfigurationElement[] children = configElement.getChildren("class"); //$NON-NLS-1$
+ IConfigurationElement[] children = config.getChildren("class"); //$NON-NLS-1$
// Single element definition assumed (see extension point schema)
if (children.length > 0) {
clazz = children[0].getAttribute("class"); //$NON-NLS-1$
}
}
+
+ // Read the "enablement" sub element of the extension
+ IConfigurationElement[] children = configElement.getChildren("enablement"); //$NON-NLS-1$
+ // Only one "enablement" element is expected
+ if (children != null && children.length > 0) {
+ expression = ExpressionConverter.getDefault().perform(children[0]);
+ }
}
/**
@@ -91,8 +129,7 @@ public abstract class AbstractServiceManager<V extends IService> {
}
else {
IStatus status = new Status(IStatus.ERROR, CoreBundleActivator.getUniqueIdentifier(), "Service '" + service.getClass().getName() + "' not of type IService."); //$NON-NLS-1$ //$NON-NLS-2$
- Platform.getLog(CoreBundleActivator.getContext().getBundle())
- .log(status);
+ Platform.getLog(CoreBundleActivator.getContext().getBundle()).log(status);
}
}
}
@@ -131,6 +168,59 @@ public abstract class AbstractServiceManager<V extends IService> {
return false;
}
+ /**
+ * Returns if or if not the service contribution is enabled for the given service context.
+ * <p>
+ * If the given service context is <code>null</code>, only globally unbound services are
+ * enabled.
+ *
+ * @param context The service context or <code>null</code>.
+ * @return <code>True</code> if the service contribution is enabled for the given service
+ * context, <code>false</code> otherwise.
+ */
+ protected boolean isEnabled(Object context) {
+ if (context == null) {
+ return getEnablement() == null;
+ }
+
+ Expression enablement = getEnablement();
+
+ // The service contribution is enabled by default if no expression is specified.
+ boolean enabled = enablement == null;
+
+ if (enablement != null) {
+ // Set the default variable to the service context.
+ EvaluationContext evalContext = new EvaluationContext(null, context);
+ // Evaluate the expression
+ try {
+ enabled = enablement.evaluate(evalContext).equals(EvaluationResult.TRUE);
+ } catch (CoreException e) {
+ IStatus status = new Status(IStatus.ERROR, CoreBundleActivator.getUniqueIdentifier(), e.getLocalizedMessage(), e);
+ Platform.getLog(CoreBundleActivator.getContext().getBundle()).log(status);
+ }
+ }
+
+ return enabled;
+ }
+
+ /**
+ * Returns the id of the service contribution.
+ *
+ * @return The service contribution id.
+ */
+ protected String getId() {
+ return id;
+ }
+
+ /**
+ * Returns the enablement expression.
+ *
+ * @return The enablement expression or <code>null</code>.
+ */
+ protected Expression getEnablement() {
+ return expression;
+ }
+
public boolean equals(V service) {
return clazz.equals(service.getClass());
}
@@ -148,131 +238,127 @@ public abstract class AbstractServiceManager<V extends IService> {
}
/**
- * @param element
- * @return
- */
- protected ServiceProxy getServiceProxy(IConfigurationElement element) {
- return new ServiceProxy(element);
- }
-
- /**
- * Returns all id's of the registered services.
+ * Creates a new service proxy instance and initialize it.
*
- * @return The list of id's of the registered services.
+ * @param config The configuration element. Must not be <code>null</code>.
+ * @return The new service proxy instance.
*/
- public String[] getIds() {
- return services.keySet().toArray(new String[services.keySet().size()]);
+ protected ServiceProxy getServiceProxy(IConfigurationElement config) {
+ Assert.isNotNull(config);
+ ServiceProxy proxy = new ServiceProxy();
+ try {
+ proxy.setInitializationData(config, null, null);
+ } catch (CoreException e) {
+ if (Platform.inDebugMode()) {
+ Platform.getLog(CoreBundleActivator.getContext().getBundle()).log(e.getStatus());
+ }
+ }
+ return proxy;
}
/**
- * Get a service for the id that implements at least the needed service type. If an interface
- * type is given, the service with the highest implementation is returned. This may result in a
- * random selection depending on the extension registration order, especially when a service
- * interface is implemented two times in different hierarchy paths. If a class type is given, if
- * available, the service of exactly that class is returned. Otherwise the highest
- * implementation is returned.
+ * Get a service for the given service context that implements at least the needed service type.
+ * <p>
+ * If an interface type is given, the service with the highest implementation is returned. This
+ * may result in a random selection depending on the extension registration order, especially
+ * when a service interface is implemented two times in different hierarchy paths. If a class
+ * type is given, if available, the service of exactly that class is returned. Otherwise the
+ * highest implementation is returned.
*
- * @param id The id for which a service is needed.
+ * @param context The service context or <code>null</code>.
* @param serviceType The service type the service should at least implement or extend.
+ *
* @return The service or <code>null</code>.
*/
- public V getService(String id, Class<? extends V> serviceType) {
- return getService(id, serviceType, false);
+ public V getService(Object context, Class<? extends V> serviceType) {
+ return getService(context, serviceType, false);
}
/**
- * Get a service for the id that implements at least the needed service type. If an interface
- * type is given, the service with the highest implementation is returned. This may result in a
- * random selection depending on the extension registration order, especially when a service
- * interface is implemented two times in different hierarchy paths. If a class type is given, if
- * available, the service of exactly that class is returned. Otherwise the highest
- * implementation is returned.
+ * Get a service for the given service context that implements at least the needed service type.
+ * <p>
+ * If an interface type is given, the service with the highest implementation is returned. This
+ * may result in a random selection depending on the extension registration order, especially
+ * when a service interface is implemented two times in different hierarchy paths. If a class
+ * type is given, if available, the service of exactly that class is returned. Otherwise the
+ * highest implementation is returned.
*
- * @param id The id for which a service is needed.
+ * @param context The service context or <code>null</code>.
* @param serviceType The service type the service should at least implement or extend.
* @param unique <code>true</code> if a new instance of the service is needed.
*
* @return The service or <code>null</code>.
*/
- public V getService(String id, Class<? extends V> serviceType, boolean unique) {
+ public V getService(Object context, Class<? extends V> serviceType, boolean unique) {
Assert.isNotNull(serviceType);
- if (id == null) {
- id = ""; //$NON-NLS-1$
- }
- List<ServiceProxy> proxies = services.get(id);
+
+ Collection<ServiceProxy> proxies = services.values();
if (proxies != null && !proxies.isEmpty()) {
List<ServiceProxy> candidates = new ArrayList<ServiceProxy>();
boolean isInterface = serviceType.isInterface();
for (ServiceProxy proxy : proxies) {
- if (proxy.isMatching(serviceType)) {
+ if (proxy.isMatching(serviceType) && proxy.isEnabled(context)) {
if (!isInterface && proxy.equals(serviceType)) {
V service = proxy.getService(unique);
- service.setId(id);
+ service.setId(proxy.getId());
return service;
}
candidates.add(proxy);
}
}
+
V service = null;
if (!candidates.isEmpty()) {
service = candidates.get(0).getService(unique);
- service.setId(id);
+ service.setId(candidates.get(0).getId());
}
return service;
}
+
return null;
}
/**
- * Get a service list for the id that implements at least the needed service type.
+ * Get a service list for the given service context that implements at least the needed service type.
*
- * @param id The id for which a service is needed.
+ * @param context The service context or <code>null</code>.
* @param serviceType The service type the service should at least implement or extend.
* @param unique <code>true</code> if a new instance of the service is needed.
+ *
* @return The service list or empty list.
*/
- public IService[] getServices(String id, Class<? extends V> serviceType, boolean unique) {
+ public IService[] getServices(Object context, Class<? extends V> serviceType, boolean unique) {
Assert.isNotNull(serviceType);
- if (id == null) {
- id = ""; //$NON-NLS-1$
- }
- List<ServiceProxy> proxies = services.get(id);
+
+ Collection<ServiceProxy> proxies = services.values();
List<IService> services = new ArrayList<IService>();
if (proxies != null && !proxies.isEmpty()) {
List<ServiceProxy> candidates = new ArrayList<ServiceProxy>();
for (ServiceProxy proxy : proxies) {
- if (proxy.isMatching(serviceType)) {
+ if (proxy.isMatching(serviceType) && proxy.isEnabled(context)) {
candidates.add(proxy);
}
}
for (ServiceProxy serviceProxy : candidates) {
IService service = serviceProxy.getService(unique);
- service.setId(id);
+ service.setId(serviceProxy.getId());
services.add(service);
}
}
return services.toArray(new IService[services.size()]);
}
- /*
- * Add a service proxy to the list of available services.
+ /**
+ * Adds the given service to the service proxy map.
*/
- protected boolean addService(String id, ServiceProxy proxy) {
+ protected void addService(ServiceProxy proxy) {
Assert.isNotNull(services);
- Assert.isNotNull(id);
Assert.isNotNull(proxy);
- List<ServiceProxy> proxies = services.get(id);
- if (proxies == null) {
- proxies = new ArrayList<ServiceProxy>();
- services.put(id, proxies);
- }
- Assert.isNotNull(proxies);
- if (proxies.isEmpty() || !proxies.contains(proxy)) {
- return proxies.add(proxy);
- }
- return false;
+ String id = proxy.getId();
+ Assert.isNotNull(id);
+ services.put(id, proxy);
}
/**
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.runtime.services/src/org/eclipse/tcf/te/runtime/services/ServiceManager.java b/target_explorer/plugins/org.eclipse.tcf.te.runtime.services/src/org/eclipse/tcf/te/runtime/services/ServiceManager.java
index 6ae90980a..d0210c0c4 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.runtime.services/src/org/eclipse/tcf/te/runtime/services/ServiceManager.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.runtime.services/src/org/eclipse/tcf/te/runtime/services/ServiceManager.java
@@ -16,9 +16,9 @@ import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.osgi.util.NLS;
+import org.eclipse.tcf.te.runtime.activator.CoreBundleActivator;
import org.eclipse.tcf.te.runtime.services.interfaces.IService;
import org.eclipse.tcf.te.runtime.services.nls.Messages;
-import org.eclipse.tcf.te.runtime.activator.CoreBundleActivator;
import org.osgi.framework.Bundle;
/**
@@ -61,7 +61,7 @@ public class ServiceManager extends AbstractServiceManager<IService> {
* @return The service or <code>null</code>.
*/
public <V extends IService> V getService(Class<V> serviceType, boolean unique) {
- return (V)super.getService("", serviceType, unique); //$NON-NLS-1$
+ return (V)super.getService(null, serviceType, unique);
}
/**
@@ -78,7 +78,7 @@ public class ServiceManager extends AbstractServiceManager<IService> {
* @return The service or <code>null</code>.
*/
public <V extends IService> V getService(Class<V> serviceType) {
- return (V)super.getService("", serviceType); //$NON-NLS-1$
+ return (V)super.getService(null, serviceType);
}
/* (non-Javadoc)
@@ -95,33 +95,9 @@ public class ServiceManager extends AbstractServiceManager<IService> {
IConfigurationElement[] configElements = extension.getConfigurationElements();
if (configElements != null) {
for (IConfigurationElement configElement : configElements) {
- // Determine the unique id to bind the service contributions to.
- String id = null;
-
- if ("connectionTypeServices".equals(configElement.getName())) { //$NON-NLS-1$
- id = configElement.getAttribute("connectionTypeId"); //$NON-NLS-1$
-
- // For a connection type service declaration, the connection type id is mandatory
- if (id == null || "".equals(id)) { //$NON-NLS-1$
- IStatus status = new Status(IStatus.WARNING, CoreBundleActivator.getUniqueIdentifier(),
- NLS.bind(Messages.ServiceManager_warning_skippedConnectionTypeService, configElement.getDeclaringExtension().getNamespaceIdentifier()));
- Platform.getLog(CoreBundleActivator.getContext().getBundle()).log(status);
- continue;
- }
- }
- else if ("genericServices".equals(configElement.getName())) { //$NON-NLS-1$
- id = configElement.getAttribute("id"); //$NON-NLS-1$
- }
-
- // Normalize the id
- if (id == null) id = ""; //$NON-NLS-1$
-
- // Get the service contributions
- IConfigurationElement[] services = configElement.getChildren("service"); //$NON-NLS-1$
- // Process the service contributions
- for (IConfigurationElement service : services) {
- ServiceProxy proxy = getServiceProxy(service);
- IConfigurationElement[] serviceTypes = service.getChildren("serviceType"); //$NON-NLS-1$
+ if ("service".equals(configElement.getName())) { //$NON-NLS-1$
+ ServiceProxy proxy = getServiceProxy(configElement);
+ IConfigurationElement[] serviceTypes = configElement.getChildren("serviceType"); //$NON-NLS-1$
if (serviceTypes != null && serviceTypes.length > 0) {
for (IConfigurationElement serviceType : serviceTypes) {
try {
@@ -142,16 +118,12 @@ public class ServiceManager extends AbstractServiceManager<IService> {
}
catch (Exception e) {
IStatus status = new Status(IStatus.WARNING, CoreBundleActivator.getUniqueIdentifier(),
- NLS.bind(Messages.ServiceManager_warning_failedToLoadServiceType, serviceType.getAttribute("class"), service.getAttribute("class")), e); //$NON-NLS-1$ //$NON-NLS-2$
+ NLS.bind(Messages.ServiceManager_warning_failedToLoadServiceType, serviceType.getAttribute("class"), configElement.getAttribute("class")), e); //$NON-NLS-1$ //$NON-NLS-2$
Platform.getLog(CoreBundleActivator.getContext().getBundle()).log(status);
}
}
}
- if (!addService(id, proxy)) {
- IStatus status = new Status(IStatus.WARNING, CoreBundleActivator.getUniqueIdentifier(),
- NLS.bind(Messages.ServiceManager_warning_failedToBindService, proxy.clazz, id), null);
- Platform.getLog(CoreBundleActivator.getContext().getBundle()).log(status);
- }
+ addService(proxy);
}
}
}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.runtime.services/src/org/eclipse/tcf/te/runtime/services/interfaces/IService.java b/target_explorer/plugins/org.eclipse.tcf.te.runtime.services/src/org/eclipse/tcf/te/runtime/services/interfaces/IService.java
index a68031498..1250dd518 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.runtime.services/src/org/eclipse/tcf/te/runtime/services/interfaces/IService.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.runtime.services/src/org/eclipse/tcf/te/runtime/services/interfaces/IService.java
@@ -15,7 +15,7 @@ package org.eclipse.tcf.te.runtime.services.interfaces;
public interface IService {
/**
- * Sets the id this service is registered to.
+ * Sets the service contribution id.
* <p>
* <b>Note:</b> Once set to a non-null value, the service id cannot be changed anymore.
*
@@ -24,7 +24,7 @@ public interface IService {
public void setId(String id);
/**
- * Returns the id this service is registered to.
+ * Returns the service contribution id.
*
* @return The id or <code>null</code> if the service id is not yet set.
*/
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.runtime.services/src/org/eclipse/tcf/te/runtime/services/nls/Messages.java b/target_explorer/plugins/org.eclipse.tcf.te.runtime.services/src/org/eclipse/tcf/te/runtime/services/nls/Messages.java
index afd9dc9f4..c9d7cf8de 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.runtime.services/src/org/eclipse/tcf/te/runtime/services/nls/Messages.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.runtime.services/src/org/eclipse/tcf/te/runtime/services/nls/Messages.java
@@ -31,5 +31,4 @@ public class Messages extends NLS {
public static String ServiceManager_warning_skippedConnectionTypeService;
public static String ServiceManager_warning_failedToLoadServiceType;
- public static String ServiceManager_warning_failedToBindService;
}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.runtime.services/src/org/eclipse/tcf/te/runtime/services/nls/Messages.properties b/target_explorer/plugins/org.eclipse.tcf.te.runtime.services/src/org/eclipse/tcf/te/runtime/services/nls/Messages.properties
index e0711a0bd..4ac999203 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.runtime.services/src/org/eclipse/tcf/te/runtime/services/nls/Messages.properties
+++ b/target_explorer/plugins/org.eclipse.tcf.te.runtime.services/src/org/eclipse/tcf/te/runtime/services/nls/Messages.properties
@@ -6,4 +6,3 @@
ServiceManager_warning_skippedConnectionTypeService=Skipped connection type service contributions from contributor ''{0}''. \
Reason: Missing mandatory connection type id.
ServiceManager_warning_failedToLoadServiceType=Cannot create service type ''{0}'' for service ''{1}''.
-ServiceManager_warning_failedToBindService=Failed to bind service ''{0}'' to id ''{1}''.

Back to the top