diff options
author | Uwe Stieber | 2013-04-17 09:05:31 +0000 |
---|---|---|
committer | Uwe Stieber | 2013-04-17 09:05:31 +0000 |
commit | b9b1be06adb5d5e7cdc8c41ff5754fab156962c0 (patch) | |
tree | e11704a4a399a04edc7da395e12c53f92c2dc17d /target_explorer/plugins | |
parent | eda8cb286354d02a4eab220bf634022be2a9302f (diff) | |
download | org.eclipse.tcf-b9b1be06adb5d5e7cdc8c41ff5754fab156962c0.tar.gz org.eclipse.tcf-b9b1be06adb5d5e7cdc8c41ff5754fab156962c0.tar.xz org.eclipse.tcf-b9b1be06adb5d5e7cdc8c41ff5754fab156962c0.zip |
Target Explorer: Extended service manager to access a service by id too
Diffstat (limited to 'target_explorer/plugins')
2 files changed, 519 insertions, 464 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 38232e45f..221c0f246 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 @@ -1,458 +1,499 @@ -/*******************************************************************************
- * Copyright (c) 2011, 2012 Wind River Systems, Inc. and others. All rights reserved.
- * This program and the accompanying materials are made available under the terms
- * of the Eclipse Public License v1.0 which accompanies this distribution, and is
- * available at http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Wind River Systems - initial API and implementation
- *******************************************************************************/
-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;
-
-/**
- * Abstract service manager implementation.
- */
-public abstract class AbstractServiceManager {
-
- // 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 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 IService service = null;
- // The list of service types the service is implementing
- private List<Class<? extends IService>> serviceTypes = new ArrayList<Class<? extends IService>>();
- // The converted expression
- private Expression expression;
-
- /**
- * Constructor.
- */
- 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.getAttribute("id"); //$NON-NLS-1$
- if (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 = config.getAttribute("class"); //$NON-NLS-1$
- if (clazz == null) {
- 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$
- }
- }
- if (clazz == null || "".equals(clazz.trim())) { //$NON-NLS-1$
- throw new CoreException(new Status(IStatus.ERROR,
- CoreBundleActivator.getUniqueIdentifier(),
- NLS.bind(Messages.Extension_error_missingRequiredAttribute, "class", config.getContributor().getName()))); //$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]);
- }
- }
-
- /**
- * Add a type to the proxy. Types are used unless the proxy is instantiated to provide lazy
- * loading of services. After instantiated, a service will be identified only by its type
- * and implementing or extending interfaces or super-types.
- *
- * @param serviceType The type to add.
- */
- public void addType(Class<? extends IService> serviceType) {
- Assert.isNotNull(serviceType);
- if (service == null && serviceTypes != null && !serviceTypes.contains(serviceType)) {
- serviceTypes.add(serviceType);
- }
- }
-
- /**
- * Return the real service instance for this proxy.
- */
- protected IService getService(boolean unique) {
- if ((service == null || unique) && configElement != null) {
- try {
- // Create the service class instance via the configuration element
- Object service = configElement.createExecutableExtension("class"); //$NON-NLS-1$
- if (service instanceof IService) {
- if (unique) {
- return (IService)service;
- }
- this.service = (IService)service;
- }
- 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);
- }
- }
- catch (CoreException e) {
- IStatus status = new Status(IStatus.ERROR, CoreBundleActivator.getUniqueIdentifier(), "Cannot create service '" + clazz + "'.", e); //$NON-NLS-1$ //$NON-NLS-2$
- Platform.getLog(CoreBundleActivator.getContext().getBundle()).log(status);
- }
- if (serviceTypes != null) {
- serviceTypes.clear();
- }
- serviceTypes = null;
- }
- return service;
- }
-
- /**
- * Check whether this proxy holds a service that is suitable for the given type.
- *
- * @param serviceType The service type. Must not be <code>null</code>.
- * @return <code>True</code> if the proxy holds a suitable service, <code>false</code> otherwise.
- */
- protected boolean isMatching(Class<? extends IService> serviceType) {
- Assert.isNotNull(serviceType);
-
- if (service != null) {
- return serviceType.isInstance(service);
- }
- else if (configElement != null) {
- if (serviceType.getClass().getName().equals(clazz)) {
- return true;
- }
- if (serviceTypes != null) {
- for (Class<? extends IService> type : serviceTypes) {
- if (type.equals(serviceType)) {
- return true;
- }
- }
- }
- }
- return false;
- }
-
- /**
- * Check whether this proxy holds a service that is suitable for the given type.
- *
- * @param serviceTypeName The service type name. Must not be <code>null</code>.
- * @return <code>True</code> if the proxy holds a suitable service, <code>false</code> otherwise.
- */
- protected boolean isMatching(String serviceTypeName) {
- Assert.isNotNull(serviceTypeName);
-
- if (service != null) {
- Class<?> clazz = service.getClass();
- while (clazz != null) {
- Class<?>[] interfaces = clazz.getInterfaces();
- for (Class<?> interfaze : interfaces) {
- if (serviceTypeName.equals(interfaze.getName())) {
- return true;
- }
- }
- clazz = clazz.getSuperclass();
- }
- }
- else if (configElement != null) {
- if (serviceTypeName.equals(clazz)) {
- return true;
- }
- for (Class<? extends IService> type : serviceTypes) {
- if (serviceTypeName.equals(type.getName())) {
- return true;
- }
- }
- }
- 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);
- // Allow plugin activation
- evalContext.setAllowPluginActivation(true);
- // 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;
- }
-
- /* (non-Javadoc)
- * @see java.lang.Object#equals(java.lang.Object)
- */
- @Override
- public boolean equals(Object obj) {
- if (obj instanceof ServiceProxy) {
- return id != null ? id.equals(((ServiceProxy)obj).id) : ((ServiceProxy)obj).id == null;
- }
- return super.equals(obj);
- }
-
- /* (non-Javadoc)
- * @see java.lang.Object#hashCode()
- */
- @Override
- public int hashCode() {
- return id != null ? id.hashCode() : super.hashCode();
- }
-
- public boolean equals(IService service) {
- Assert.isNotNull(service);
- return clazz != null ? clazz.equals(service.getClass().getCanonicalName()) : false;
- }
-
- public boolean equals(ServiceProxy proxy) {
- Assert.isNotNull(proxy);
- return clazz != null ? clazz.equals(proxy.clazz) : false;
- }
- }
-
- /**
- * Constructor.
- */
- protected AbstractServiceManager() {
- loadServices();
- }
-
- /**
- * Creates a new service proxy instance and initialize it.
- *
- * @param config The configuration element. Must not be <code>null</code>.
- * @return The new service proxy instance.
- */
- 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 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 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 extends IService> V getService(Object context, Class<? extends V> serviceType) {
- return getService(context, serviceType, false);
- }
-
- /**
- * 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 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>.
- */
- @SuppressWarnings("unchecked")
- public <V extends IService> V getService(Object context, Class<? extends V> serviceType, boolean unique) {
- Assert.isNotNull(serviceType);
-
- Collection<ServiceProxy> proxies = services.values();
- if (!proxies.isEmpty()) {
- List<ServiceProxy> candidates = new ArrayList<ServiceProxy>();
- boolean isInterface = serviceType.isInterface();
- for (ServiceProxy proxy : proxies) {
- if (proxy.isMatching(serviceType) && proxy.isEnabled(context)) {
- if (!isInterface) {
- V service = (V)proxy.getService(unique);
- service.setId(proxy.getId());
- return service;
- }
- candidates.add(proxy);
- }
- }
-
- V service = null;
- if (!candidates.isEmpty()) {
- service = (V)candidates.get(0).getService(unique);
- service.setId(candidates.get(0).getId());
- }
-
- return service;
- }
-
- return null;
- }
-
- /**
- * Get a service list for the given service context that implements at least the needed service type.
- *
- * @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(Object context, Class<? extends IService> serviceType, boolean unique) {
- Assert.isNotNull(serviceType);
-
- Collection<ServiceProxy> proxies = services.values();
- List<IService> services = new ArrayList<IService>();
- if (!proxies.isEmpty()) {
- List<ServiceProxy> candidates = new ArrayList<ServiceProxy>();
- for (ServiceProxy proxy : proxies) {
- if (proxy.isMatching(serviceType) && proxy.isEnabled(context)) {
- candidates.add(proxy);
- }
- }
- for (ServiceProxy serviceProxy : candidates) {
- IService service = serviceProxy.getService(unique);
- service.setId(serviceProxy.getId());
- services.add(service);
- }
- }
- return services.toArray(new IService[services.size()]);
- }
-
- /**
- * Adds the given service to the service proxy map.
- */
- protected void addService(ServiceProxy proxy) {
- Assert.isNotNull(services);
- Assert.isNotNull(proxy);
-
- String id = proxy.getId();
- Assert.isNotNull(id);
- services.put(id, proxy);
- }
-
- /**
- * Returns if or if not a service contribution for the given service context, implementing the
- * given service type, exist.
- *
- * @param context The service context or <code>null</code>.
- * @param serviceTypeName The name of a service type the service should at least implement or extend.
- *
- * @return <code>True</code> if a matching service contribution exist, <code>false</code> otherwise.
- */
- public boolean hasService(Object context, String serviceTypeName) {
- Assert.isNotNull(serviceTypeName);
-
- // Get all service contributions
- Collection<ServiceProxy> proxies = services.values();
- if (!proxies.isEmpty()) {
- for (ServiceProxy proxy : proxies) {
- if (proxy.isMatching(serviceTypeName) && proxy.isEnabled(context)) {
- return true;
- }
- }
- }
-
- return false;
- }
-
-
- /**
- * Loads the contributed services into proxies (lazy loading!!) and adds them to this manager;
- */
- protected abstract void loadServices();
-}
+/******************************************************************************* + * Copyright (c) 2011, 2012 Wind River Systems, Inc. and others. All rights reserved. + * This program and the accompanying materials are made available under the terms + * of the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +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; + +/** + * Abstract service manager implementation. + */ +public abstract class AbstractServiceManager { + + // 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 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 IService service = null; + // The list of service types the service is implementing + private List<Class<? extends IService>> serviceTypes = new ArrayList<Class<? extends IService>>(); + // The converted expression + private Expression expression; + + /** + * Constructor. + */ + 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.getAttribute("id"); //$NON-NLS-1$ + if (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 = config.getAttribute("class"); //$NON-NLS-1$ + if (clazz == null) { + 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$ + } + } + if (clazz == null || "".equals(clazz.trim())) { //$NON-NLS-1$ + throw new CoreException(new Status(IStatus.ERROR, + CoreBundleActivator.getUniqueIdentifier(), + NLS.bind(Messages.Extension_error_missingRequiredAttribute, "class", config.getContributor().getName()))); //$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]); + } + } + + /** + * Add a type to the proxy. Types are used unless the proxy is instantiated to provide lazy + * loading of services. After instantiated, a service will be identified only by its type + * and implementing or extending interfaces or super-types. + * + * @param serviceType The type to add. + */ + public void addType(Class<? extends IService> serviceType) { + Assert.isNotNull(serviceType); + if (service == null && serviceTypes != null && !serviceTypes.contains(serviceType)) { + serviceTypes.add(serviceType); + } + } + + /** + * Return the real service instance for this proxy. + */ + protected IService getService(boolean unique) { + if ((service == null || unique) && configElement != null) { + try { + // Create the service class instance via the configuration element + Object service = configElement.createExecutableExtension("class"); //$NON-NLS-1$ + if (service instanceof IService) { + if (unique) { + return (IService)service; + } + this.service = (IService)service; + } + 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); + } + } + catch (CoreException e) { + IStatus status = new Status(IStatus.ERROR, CoreBundleActivator.getUniqueIdentifier(), "Cannot create service '" + clazz + "'.", e); //$NON-NLS-1$ //$NON-NLS-2$ + Platform.getLog(CoreBundleActivator.getContext().getBundle()).log(status); + } + if (serviceTypes != null) { + serviceTypes.clear(); + } + serviceTypes = null; + } + return service; + } + + /** + * Check whether this proxy holds a service that is suitable for the given type. + * + * @param serviceType The service type. Must not be <code>null</code>. + * @return <code>True</code> if the proxy holds a suitable service, <code>false</code> otherwise. + */ + protected boolean isMatching(Class<? extends IService> serviceType) { + Assert.isNotNull(serviceType); + + if (service != null) { + return serviceType.isInstance(service); + } + else if (configElement != null) { + if (serviceType.getClass().getName().equals(clazz)) { + return true; + } + if (serviceTypes != null) { + for (Class<? extends IService> type : serviceTypes) { + if (type.equals(serviceType)) { + return true; + } + } + } + } + return false; + } + + /** + * Check whether this proxy holds a service that is suitable for the given type. + * + * @param serviceTypeName The service type name. Must not be <code>null</code>. + * @return <code>True</code> if the proxy holds a suitable service, <code>false</code> otherwise. + */ + protected boolean isMatching(String serviceTypeName) { + Assert.isNotNull(serviceTypeName); + + if (service != null) { + Class<?> clazz = service.getClass(); + while (clazz != null) { + Class<?>[] interfaces = clazz.getInterfaces(); + for (Class<?> interfaze : interfaces) { + if (serviceTypeName.equals(interfaze.getName())) { + return true; + } + } + clazz = clazz.getSuperclass(); + } + } + else if (configElement != null) { + if (serviceTypeName.equals(clazz)) { + return true; + } + for (Class<? extends IService> type : serviceTypes) { + if (serviceTypeName.equals(type.getName())) { + return true; + } + } + } + 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); + // Allow plugin activation + evalContext.setAllowPluginActivation(true); + // 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; + } + + /* (non-Javadoc) + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + if (obj instanceof ServiceProxy) { + return id != null ? id.equals(((ServiceProxy)obj).id) : ((ServiceProxy)obj).id == null; + } + return super.equals(obj); + } + + /* (non-Javadoc) + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + return id != null ? id.hashCode() : super.hashCode(); + } + + public boolean equals(IService service) { + Assert.isNotNull(service); + return clazz != null ? clazz.equals(service.getClass().getCanonicalName()) : false; + } + + public boolean equals(ServiceProxy proxy) { + Assert.isNotNull(proxy); + return clazz != null ? clazz.equals(proxy.clazz) : false; + } + } + + /** + * Constructor. + */ + protected AbstractServiceManager() { + loadServices(); + } + + /** + * Creates a new service proxy instance and initialize it. + * + * @param config The configuration element. Must not be <code>null</code>. + * @return The new service proxy instance. + */ + 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 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 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 extends IService> V getService(Object context, Class<? extends V> serviceType) { + return getService(context, serviceType, false); + } + + /** + * 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 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>. + */ + @SuppressWarnings("unchecked") + public <V extends IService> V getService(Object context, Class<? extends V> serviceType, boolean unique) { + Assert.isNotNull(serviceType); + + Collection<ServiceProxy> proxies = services.values(); + if (!proxies.isEmpty()) { + List<ServiceProxy> candidates = new ArrayList<ServiceProxy>(); + boolean isInterface = serviceType.isInterface(); + for (ServiceProxy proxy : proxies) { + if (proxy.isMatching(serviceType) && proxy.isEnabled(context)) { + if (!isInterface) { + V service = (V)proxy.getService(unique); + service.setId(proxy.getId()); + return service; + } + candidates.add(proxy); + } + } + + V service = null; + if (!candidates.isEmpty()) { + service = (V)candidates.get(0).getService(unique); + service.setId(candidates.get(0).getId()); + } + + return service; + } + + return null; + } + + /** + * Get the service of the given type and the given id. + * + * @param id The service id 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>. + */ + @SuppressWarnings("unchecked") + public <V extends IService> V getService(String id, Class<? extends V> serviceType, boolean unique) { + Assert.isNotNull(id); + Assert.isNotNull(serviceType); + + Collection<ServiceProxy> proxies = services.values(); + if (!proxies.isEmpty()) { + List<ServiceProxy> candidates = new ArrayList<ServiceProxy>(); + boolean isInterface = serviceType.isInterface(); + for (ServiceProxy proxy : proxies) { + if (proxy.isMatching(serviceType) && id.equals(proxy.getId())) { + if (!isInterface) { + V service = (V)proxy.getService(unique); + service.setId(proxy.getId()); + return service; + } + candidates.add(proxy); + } + } + + V service = null; + if (!candidates.isEmpty()) { + service = (V)candidates.get(0).getService(unique); + service.setId(candidates.get(0).getId()); + } + + return service; + } + + return null; + } + + /** + * Get a service list for the given service context that implements at least the needed service type. + * + * @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(Object context, Class<? extends IService> serviceType, boolean unique) { + Assert.isNotNull(serviceType); + + Collection<ServiceProxy> proxies = services.values(); + List<IService> services = new ArrayList<IService>(); + if (!proxies.isEmpty()) { + List<ServiceProxy> candidates = new ArrayList<ServiceProxy>(); + for (ServiceProxy proxy : proxies) { + if (proxy.isMatching(serviceType) && proxy.isEnabled(context)) { + candidates.add(proxy); + } + } + for (ServiceProxy serviceProxy : candidates) { + IService service = serviceProxy.getService(unique); + service.setId(serviceProxy.getId()); + services.add(service); + } + } + return services.toArray(new IService[services.size()]); + } + + /** + * Adds the given service to the service proxy map. + */ + protected void addService(ServiceProxy proxy) { + Assert.isNotNull(services); + Assert.isNotNull(proxy); + + String id = proxy.getId(); + Assert.isNotNull(id); + services.put(id, proxy); + } + + /** + * Returns if or if not a service contribution for the given service context, implementing the + * given service type, exist. + * + * @param context The service context or <code>null</code>. + * @param serviceTypeName The name of a service type the service should at least implement or extend. + * + * @return <code>True</code> if a matching service contribution exist, <code>false</code> otherwise. + */ + public boolean hasService(Object context, String serviceTypeName) { + Assert.isNotNull(serviceTypeName); + + // Get all service contributions + Collection<ServiceProxy> proxies = services.values(); + if (!proxies.isEmpty()) { + for (ServiceProxy proxy : proxies) { + if (proxy.isMatching(serviceTypeName) && proxy.isEnabled(context)) { + return true; + } + } + } + + return false; + } + + + /** + * Loads the contributed services into proxies (lazy loading!!) and adds them to this manager; + */ + protected abstract void loadServices(); +} diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.ui/src/org/eclipse/tcf/te/tcf/ui/internal/tabbed/PeerGeneralSectionContentProvider.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.ui/src/org/eclipse/tcf/te/tcf/ui/internal/tabbed/PeerGeneralSectionContentProvider.java index 14a54e51b..f0e856917 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.ui/src/org/eclipse/tcf/te/tcf/ui/internal/tabbed/PeerGeneralSectionContentProvider.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.ui/src/org/eclipse/tcf/te/tcf/ui/internal/tabbed/PeerGeneralSectionContentProvider.java @@ -28,6 +28,7 @@ import org.eclipse.tcf.te.runtime.services.ServiceManager; import org.eclipse.tcf.te.runtime.services.interfaces.IUIService; import org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerModel; import org.eclipse.tcf.te.ui.tables.properties.NodePropertiesTableTableNode; +import org.eclipse.tcf.te.ui.views.extensions.LabelProviderDelegateExtensionPointManager; import org.eclipse.ui.forms.widgets.Section; @@ -88,13 +89,26 @@ public class PeerGeneralSectionContentProvider implements IStructuredContentProv if (name.endsWith(".silent") || name.contains(".transient")) continue; //$NON-NLS-1$ //$NON-NLS-2$ // Create the properties node NodePropertiesTableTableNode propertiesNode = new NodePropertiesTableTableNode(name, entry.getValue() != null ? entry.getValue().toString() : ""); //$NON-NLS-1$ - // Check the label provider if the value to show is replaced - if (provider != null) { - String text = provider.getText(propertiesNode); - if (text != null && !"".equals(text)) { //$NON-NLS-1$ - propertiesNode = new NodePropertiesTableTableNode(name, text); - } + + // Possible replacement for the node properties table table node value + String text = null; + + // Get the label provider delegate for the input element + ILabelProvider[] delegates = LabelProviderDelegateExtensionPointManager.getInstance().getDelegates(inputElement, false); + if (delegates != null && delegates.length > 0) { + text = delegates[0].getText(propertiesNode); + } + + // Fallback to the label provider + if (text == null && provider != null) { + text = provider.getText(propertiesNode); + } + + // Replace the node properties table table node value + if (text != null && !"".equals(text)) { //$NON-NLS-1$ + propertiesNode = new NodePropertiesTableTableNode(name, text); } + // Add the properties node nodes.add(propertiesNode); } |