Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorustieber2009-05-28 10:48:31 -0400
committerustieber2009-05-28 10:48:31 -0400
commit4e7268f5f281a8f2b35cd3378c36ced462e59d76 (patch)
tree2d20316f924574f4f8610f270fc93c6bd17a58f4 /plugins/org.eclipse.tm.tcf
parentf77572bc3acfdda3121c288f7f0660d22c2589fe (diff)
downloadorg.eclipse.tcf-4e7268f5f281a8f2b35cd3378c36ced462e59d76.tar.gz
org.eclipse.tcf-4e7268f5f281a8f2b35cd3378c36ced462e59d76.tar.xz
org.eclipse.tcf-4e7268f5f281a8f2b35cd3378c36ced462e59d76.zip
[277993] [tcf][eclipse] Provide infrastructure to contribute additonal service via Eclipse extension point
Diffstat (limited to 'plugins/org.eclipse.tm.tcf')
-rw-r--r--plugins/org.eclipse.tm.tcf/META-INF/MANIFEST.MF5
-rw-r--r--plugins/org.eclipse.tm.tcf/plugin.xml3
-rw-r--r--plugins/org.eclipse.tm.tcf/schema/serviceProviders.exsd114
-rw-r--r--plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/Activator.java16
-rw-r--r--plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/extensions/TcfAbstractExtensionPointManager.java200
-rw-r--r--plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/extensions/TcfExtensionPointComparator.java68
-rw-r--r--plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/extensions/TcfExtensionProxy.java123
-rw-r--r--plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/internal/extensions/TcfServiceProvidersExtensionPointManager.java67
-rw-r--r--plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/internal/nls/TcfPluginMessages.java37
-rw-r--r--plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/internal/nls/TcfPluginMessages.properties8
10 files changed, 637 insertions, 4 deletions
diff --git a/plugins/org.eclipse.tm.tcf/META-INF/MANIFEST.MF b/plugins/org.eclipse.tm.tcf/META-INF/MANIFEST.MF
index 95068868b..2df3adb2a 100644
--- a/plugins/org.eclipse.tm.tcf/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.tm.tcf/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.tm.tcf;singleton:=true
-Bundle-Version: 0.2.0.qualifier
+Bundle-Version: 0.3.0.qualifier
Bundle-Activator: org.eclipse.tm.tcf.Activator
Bundle-Vendor: %providerName
Require-Bundle: org.eclipse.core.runtime
@@ -10,4 +10,5 @@ Bundle-RequiredExecutionEnvironment: J2SE-1.5
Bundle-ActivationPolicy: lazy
Eclipse-LazyStart: true
Eclipse-ExtensibleAPI: true
-Export-Package: org.eclipse.tm.tcf.ssl;version="0.2.0"
+Export-Package: org.eclipse.tm.tcf.extensions,
+ org.eclipse.tm.tcf.ssl
diff --git a/plugins/org.eclipse.tm.tcf/plugin.xml b/plugins/org.eclipse.tm.tcf/plugin.xml
index a3ab7c70e..9b7ec1e7f 100644
--- a/plugins/org.eclipse.tm.tcf/plugin.xml
+++ b/plugins/org.eclipse.tm.tcf/plugin.xml
@@ -2,6 +2,7 @@
<?eclipse version="3.2"?>
<plugin>
- <extension-point id="startup" name="TCF Startup" schema="schema/startup.exsd"/>
+ <extension-point id="startup" name="TCF Startup" schema="schema/startup.exsd"/>
+ <extension-point id="serviceProviders" name="TCF Service Providers" schema="schema/serviceProviders.exsd"/>
</plugin>
diff --git a/plugins/org.eclipse.tm.tcf/schema/serviceProviders.exsd b/plugins/org.eclipse.tm.tcf/schema/serviceProviders.exsd
new file mode 100644
index 000000000..ca2c71a84
--- /dev/null
+++ b/plugins/org.eclipse.tm.tcf/schema/serviceProviders.exsd
@@ -0,0 +1,114 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.tm.tcf" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+ <appInfo>
+ <meta.schema plugin="org.eclipse.tm.tcf" id="serviceProviders" name="TCF Service Providers"/>
+ </appInfo>
+ <documentation>
+ This extension point is used to allow the contribution of new TCF service providers.
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <annotation>
+ <appInfo>
+ <meta.element />
+ </appInfo>
+ </annotation>
+ <complexType>
+ <sequence>
+ <element ref="serviceProvider" minOccurs="1" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appInfo>
+ <meta.attribute translatable="true"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="serviceProvider">
+ <annotation>
+ <documentation>
+ Declares a new service provider extension.
+ </documentation>
+ </annotation>
+ <complexType>
+ <attribute name="id" type="string" use="required">
+ <annotation>
+ <documentation>
+ The unique id of the service provider.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+ The fully qualified name of the service provider class. Must implement &lt;samp&gt;org.eclipse.tm.tcf.protocol.IServiceProvider&lt;/samp&gt;
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java" basedOn=":org.eclipse.tm.tcf.protocol.IServiceProvider"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="since"/>
+ </appInfo>
+ <documentation>
+ 0.3.0
+ </documentation>
+ </annotation>
+
+
+ <annotation>
+ <appInfo>
+ <meta.section type="apiinfo"/>
+ </appInfo>
+ <documentation>
+ Plug-ins that want to extend this extension point, the referenced class must implement the &lt;samp&gt;org.eclipse.tm.tcf.protocol.IServiceProvider&lt;/samp&gt; interface.
+ </documentation>
+ </annotation>
+
+
+ <annotation>
+ <appInfo>
+ <meta.section type="copyright"/>
+ </appInfo>
+ <documentation>
+ Copyright (c) 2009 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
+ </documentation>
+ </annotation>
+
+</schema>
diff --git a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/Activator.java b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/Activator.java
index af00e7c60..fbbfb4a11 100644
--- a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/Activator.java
+++ b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/Activator.java
@@ -17,6 +17,7 @@ import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Plugin;
import org.eclipse.core.runtime.Status;
+import org.eclipse.tm.tcf.internal.extensions.TcfServiceProvidersExtensionPointManager;
import org.eclipse.tm.tcf.core.ChannelTCP;
import org.eclipse.tm.tcf.protocol.ILogger;
import org.eclipse.tm.tcf.protocol.Protocol;
@@ -48,19 +49,26 @@ public class Activator extends Plugin {
}
};
+ /**
+ * Constructor.
+ */
public Activator() {
plugin = this;
}
+
/**
* Returns the shared instance
*
* @return the shared instance
*/
public static Activator getDefault() {
- return plugin;
+ return plugin;
}
+ /* (non-Javadoc)
+ * @see org.eclipse.core.runtime.Plugin#start(org.osgi.framework.BundleContext)
+ */
@Override
public void start(BundleContext context) throws Exception {
super.start(context);
@@ -88,6 +96,9 @@ public class Activator extends Plugin {
context.addBundleListener(bundle_listener);
}
+ /* (non-Javadoc)
+ * @see org.eclipse.core.runtime.Plugin#stop(org.osgi.framework.BundleContext)
+ */
@Override
public void stop(BundleContext context) throws Exception {
context.removeBundleListener(bundle_listener);
@@ -122,5 +133,8 @@ public class Activator extends Plugin {
catch (Exception x) {
Protocol.log("TCF startup error", x); //$NON-NLS-1$
}
+
+ // Register service providers contributed via Eclipse extension point
+ TcfServiceProvidersExtensionPointManager.getInstance().registerServiceProviders();
}
}
diff --git a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/extensions/TcfAbstractExtensionPointManager.java b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/extensions/TcfAbstractExtensionPointManager.java
new file mode 100644
index 000000000..a6c0ddb6d
--- /dev/null
+++ b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/extensions/TcfAbstractExtensionPointManager.java
@@ -0,0 +1,200 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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.tm.tcf.extensions;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtension;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.IExtensionRegistry;
+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.tm.tcf.Activator;
+import org.eclipse.tm.tcf.internal.nls.TcfPluginMessages;
+
+
+/**
+ * Abstract extension point manager base implementation.
+ */
+public abstract class TcfAbstractExtensionPointManager<V> {
+ // Flag to mark the extension point manager initialized (extensions loaded).
+ private boolean fInitialized = false;
+ // The map of loaded extension listed by their unique ids
+ private Map<String, TcfExtensionProxy<V>> fExtensions = new LinkedHashMap<String, TcfExtensionProxy<V>>();
+ // The extension point comparator
+ private TcfExtensionPointComparator fComparator = null;
+
+ /**
+ * Constructor.
+ */
+ public TcfAbstractExtensionPointManager() {
+ }
+
+ /**
+ * Returns if or if not the service provider extension point manager
+ * got initialized. Initialized means that the manager read the
+ * contributitions for the managed extension point.
+ *
+ * @return <code>True</code> if already initialized, <code>false</code> otherwise.
+ */
+ protected boolean isInitialized() {
+ return fInitialized;
+ }
+
+ /**
+ * Sets if or if not the service provider extension point manager
+ * is initialized. Initialized means that the manager has read
+ * the contributitions for the managed extension point.
+ *
+ * @return <code>True</code> to set the extension point manager is initialized, <code>false</code> otherwise.
+ */
+ protected void setInitialized(boolean initialized) {
+ fInitialized = initialized;
+ }
+
+ /**
+ * Returns the map of managed extensions. If not loaded before,
+ * this methods trigger the loading of the extensions to the managed
+ * extension point.
+ *
+ * @return The map of contributables.
+ */
+ protected Map<String, TcfExtensionProxy<V>> getExtensions() {
+ if (!isInitialized()) { loadExtensions(); setInitialized(true); }
+ return fExtensions;
+ }
+
+ /**
+ * Returns the extensions of the specified extension point sorted.
+ * For the order of the extensions, see {@link WRLaunchExtensionPointComparator}.
+ *
+ * @param point The extension point. Must be not <code>null</code>.
+ * @return The extensions in sorted order or an empty array if the extension point has no extensions.
+ */
+ protected IExtension[] getExtensionsSorted(IExtensionPoint point) {
+ assert point != null;
+
+ List<IExtension> extensions = new ArrayList<IExtension>(Arrays.asList(point.getExtensions()));
+ if (extensions.size() > 0) {
+ Collections.sort(extensions, getExtensionPointComparator());
+ }
+
+ return extensions.toArray(new IExtension[extensions.size()]);
+ }
+
+ /**
+ * Returns the extension point comparator instance. If not available,
+ * {@link #doCreateExtensionPointComparator()} is called to create a new instance.
+ *
+ * @return The extension point comparator or <code>null</code> if the instance creation fails.
+ */
+ protected final TcfExtensionPointComparator getExtensionPointComparator() {
+ if (fComparator == null) {
+ fComparator = doCreateExtensionPointComparator();
+ }
+ return fComparator;
+ }
+
+ /**
+ * Creates a new extension point comparator instance.
+ *
+ * @return The extension point comparator instance. Must never be <code>null</code>.
+ */
+ protected TcfExtensionPointComparator doCreateExtensionPointComparator() {
+ return new TcfExtensionPointComparator();
+ }
+
+ /**
+ * Returns the extension point id to read. The method
+ * must return never <code>null</code>.
+ *
+ * @return The extension point id.
+ */
+ protected abstract String getExtensionPointId();
+
+ /**
+ * Returns the configuration element name. The method
+ * must return never <code>null</code>.
+ *
+ * @return The configuration element name.
+ */
+ protected abstract String getConfigurationElementName();
+
+ /**
+ * Creates the extension proxy instance.
+ *
+ * @param element The configuration element of the extension. Must be not <code>null</code>.
+ * @return The extension proxy instance.
+ *
+ * @throws CoreException If the extension proxy instanciation failed.
+ */
+ protected TcfExtensionProxy<V> doCreateExtensionProxy(IConfigurationElement element) throws CoreException {
+ assert element != null;
+ return new TcfExtensionProxy<V>(element);
+ }
+
+ /**
+ * Loads the extensions for the managed extenions point.
+ */
+ protected void loadExtensions() {
+ // If already initialized, this method will do nothing.
+ if (isInitialized()) return;
+
+ IExtensionRegistry registry = Platform.getExtensionRegistry();
+ IExtensionPoint point = registry.getExtensionPoint(getExtensionPointId());
+ if (point != null) {
+ IExtension[] extensions = getExtensionsSorted(point);
+ for (IExtension extension : extensions) {
+ IConfigurationElement[] elements = extension.getConfigurationElements();
+ for (IConfigurationElement element : elements) {
+ if (getConfigurationElementName().equals(element.getName())) {
+ try {
+ TcfExtensionProxy<V> candidate = doCreateExtensionProxy(element);
+ if (candidate.getId() != null) {
+ // If no contributable with this id had been registered before, register now.
+ if (!fExtensions.containsKey(candidate.getId())) {
+ fExtensions.put(candidate.getId(), candidate);
+ }
+ else {
+ throw new CoreException(new Status(IStatus.ERROR,
+ Activator.PLUGIN_ID,
+ 0,
+ NLS.bind(TcfPluginMessages.Extension_error_duplicateExtension, candidate.getId(), element.getContributor().getName()),
+ null));
+ }
+ } else {
+ throw new CoreException(new Status(IStatus.ERROR,
+ Activator.PLUGIN_ID,
+ 0,
+ NLS.bind(TcfPluginMessages.Extension_error_missingRequiredAttribute, "id", element.getAttribute("label")), //$NON-NLS-1$ //$NON-NLS-2$
+ null));
+ }
+ } catch (CoreException e) {
+ IStatus status = new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ NLS.bind(TcfPluginMessages.Extension_error_invalidExtensionPoint, element.getDeclaringExtension().getUniqueIdentifier()),
+ e);
+ Activator.getDefault().getLog().log(status);
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/extensions/TcfExtensionPointComparator.java b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/extensions/TcfExtensionPointComparator.java
new file mode 100644
index 000000000..7544e2d40
--- /dev/null
+++ b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/extensions/TcfExtensionPointComparator.java
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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.tm.tcf.extensions;
+
+import java.util.Comparator;
+
+import org.eclipse.core.runtime.IExtension;
+
+/**
+ * TCF extension point comparator. Used to asure that extension are
+ * always read in the same order.
+ * <p>
+ * The order of the extensions is definded as following:<br>
+ * <ul><li>Extensions contributed by the TCF core plug-ins (<code>org.eclipse.tm.tcf.*</code>)
+ * in ascending alphabetic order and</li>
+ * <li>Extensions contributed by any other plug-in in ascending alphabetic order.</li>
+ * <li>Extensions contributed by the same plug-in in ascending alphabetic order by the
+ * extensions unique id</li>
+ * </ul>
+ */
+public class TcfExtensionPointComparator implements Comparator<IExtension> {
+ private final static String TCF_PLUGIN_PATTERN = "org.eclipse.tm.tcf.*"; //$NON-NLS-1$
+
+ /* (non-Javadoc)
+ * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
+ */
+ public int compare(IExtension o1, IExtension o2) {
+ // We ignore any comparisation with null and
+ if (o1 == null || o2 == null) return 0;
+ // Check if it is the exact same element
+ if (o1 == o2) return 0;
+
+ // The extensions are compared by the unique id of the contributing plugin first
+ String contributor1 = o1.getContributor().getName();
+ String contributor2 = o2.getContributor().getName();
+
+ // Contributions from TCF core plugins comes before 3rdParty Plugins
+ if (contributor1.startsWith(TCF_PLUGIN_PATTERN) && !contributor2.startsWith(TCF_PLUGIN_PATTERN))
+ return -1;
+ if (!contributor1.startsWith(TCF_PLUGIN_PATTERN) && contributor2.startsWith(TCF_PLUGIN_PATTERN))
+ return 1;
+ if (contributor1.startsWith(TCF_PLUGIN_PATTERN) && contributor2.startsWith(TCF_PLUGIN_PATTERN)) {
+ int value = contributor1.compareTo(contributor2);
+ // Within the same plugins, the extension are sorted by thier unique id (if available)
+ if (value == 0 && o1.getUniqueIdentifier() != null && o2.getUniqueIdentifier() != null)
+ return o1.getUniqueIdentifier().compareTo(o2.getUniqueIdentifier());
+ // Otherwise, just return the comparisation result from the contributors
+ return value;
+ }
+
+ // Contributions from all other plugins are sorted alphabetical
+ int value = contributor1.compareTo(contributor2);
+ // Within the same plugins, the extension are sorted by thier unique id (if available)
+ if (value == 0 && o1.getUniqueIdentifier() != null && o2.getUniqueIdentifier() != null)
+ return o1.getUniqueIdentifier().compareTo(o2.getUniqueIdentifier());
+ // Otherwise, just return the comparisation result from the contributors
+ return value;
+ }
+
+}
diff --git a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/extensions/TcfExtensionProxy.java b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/extensions/TcfExtensionProxy.java
new file mode 100644
index 000000000..d84489343
--- /dev/null
+++ b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/extensions/TcfExtensionProxy.java
@@ -0,0 +1,123 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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.tm.tcf.extensions;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.tm.tcf.Activator;
+import org.eclipse.tm.tcf.internal.nls.TcfPluginMessages;
+
+/**
+ * TCF extension proxy implementation. The use of the proxy asures the
+ * lazy plug-in activation policy for the contributing plug-in.
+ */
+public class TcfExtensionProxy<V> {
+ // The extension instance. Create on first access
+ private V fInstance;
+ // The configuration element
+ private final IConfigurationElement fElement;
+ // The unique id of the extension.
+ private String fId;
+
+ /**
+ * Constructor.
+ *
+ * @param element The configuration element. Must be not <code>null</code>.
+ *
+ * @throws CoreException In case the configuration element attribute <i>id</i> is <code>null</code> or empty.
+ */
+ public TcfExtensionProxy(IConfigurationElement element) throws CoreException {
+ assert element != null;
+ fElement = element;
+
+ // The <id> attribute is mandatory.
+ fId = element.getAttribute("id"); //$NON-NLS-1$
+ if (fId == null || fId.trim().length() == 0) {
+ throw new CoreException(new Status(IStatus.ERROR,
+ Activator.PLUGIN_ID,
+ 0,
+ NLS.bind(TcfPluginMessages.Extension_error_missingRequiredAttribute, "id", element.getContributor().getName()), //$NON-NLS-1$
+ null));
+ }
+
+ fInstance = null;
+ }
+
+ /**
+ * Returns the extensions unique id.
+ *
+ * @return The unique id.
+ */
+ public String getId() {
+ return fId;
+ }
+
+ /**
+ * Returns the configuration element for this extension.
+ *
+ * @return The configuration element.
+ */
+ protected IConfigurationElement getConfigurationElement() {
+ return fElement;
+ }
+
+ /**
+ * Returns the extension class instance. The contributing
+ * plug-in will be activated if not yet activated anyway.
+ *
+ * @return The extension class instance. Might be <code>null</code> if the instanciation fails.
+ */
+ @SuppressWarnings("unchecked")
+ public V getInstance() {
+ if (fInstance == null) {
+ IConfigurationElement element = getConfigurationElement();
+ assert element != null;
+ if (element != null && element.getAttribute("class") != null) { //$NON-NLS-1$
+ try {
+ fInstance = (V)element.createExecutableExtension("class"); //$NON-NLS-1$
+ } catch (Exception e) {
+ // Possible exceptions: CoreException, ClassCastException.
+ IStatus status = new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ NLS.bind(TcfPluginMessages.Extension_error_invalidExtensionPoint, element.getDeclaringExtension().getUniqueIdentifier()),
+ e);
+ Activator.getDefault().getLog().log(status);
+ }
+ }
+ }
+ return fInstance;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(Object obj) {
+ // Proxies are equal if they have encapsulate an element
+ // with the same unique id
+ if (obj instanceof TcfExtensionProxy<?>) {
+ return getId().equals(((TcfExtensionProxy<?>)obj).getId());
+ }
+ return super.equals(obj);
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ // The hash code of a proxy is the one from the id
+ return getId().hashCode();
+ }
+
+}
diff --git a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/internal/extensions/TcfServiceProvidersExtensionPointManager.java b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/internal/extensions/TcfServiceProvidersExtensionPointManager.java
new file mode 100644
index 000000000..14dd87f9b
--- /dev/null
+++ b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/internal/extensions/TcfServiceProvidersExtensionPointManager.java
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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.tm.tcf.internal.extensions;
+
+import java.util.Map;
+
+import org.eclipse.tm.tcf.extensions.TcfAbstractExtensionPointManager;
+import org.eclipse.tm.tcf.extensions.TcfExtensionProxy;
+import org.eclipse.tm.tcf.protocol.IServiceProvider;
+import org.eclipse.tm.tcf.protocol.Protocol;
+
+/**
+ * Extension point manager implementation for "org.eclipse.tm.tcf.serviceProviders".
+ */
+public class TcfServiceProvidersExtensionPointManager extends TcfAbstractExtensionPointManager<IServiceProvider> {
+ /*
+ * Thread save singleton instance creation.
+ */
+ private static class LazyInstanceHolder {
+ public static TcfServiceProvidersExtensionPointManager fInstance = new TcfServiceProvidersExtensionPointManager();
+ }
+
+ /**
+ * Returns the singleton instance for the manager.
+ */
+ public static TcfServiceProvidersExtensionPointManager getInstance() {
+ return LazyInstanceHolder.fInstance;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.tcf.extensions.TcfAbstractExtensionPointManager#getExtensionPointId()
+ */
+ @Override
+ protected String getExtensionPointId() {
+ return "org.eclipse.tm.tcf.serviceProviders"; //$NON-NLS-1$
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.tcf.extensions.TcfAbstractExtensionPointManager#getConfigurationElementName()
+ */
+ @Override
+ protected String getConfigurationElementName() {
+ return "serviceProvider"; //$NON-NLS-1$
+ }
+
+ /**
+ * Register the contributed service provider extensions with the framework.
+ */
+ public void registerServiceProviders() {
+ // Load the extensions
+ Map<String, TcfExtensionProxy<IServiceProvider>> extensions = getExtensions();
+ // Loop the extensions and get the service provider instance.
+ // This will activate the contributing plugin.
+ for (TcfExtensionProxy<IServiceProvider> proxy : extensions.values()) {
+ IServiceProvider provider = proxy.getInstance();
+ if (provider != null) Protocol.addServiceProvider(provider);
+ }
+ }
+}
diff --git a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/internal/nls/TcfPluginMessages.java b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/internal/nls/TcfPluginMessages.java
new file mode 100644
index 000000000..299f05e45
--- /dev/null
+++ b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/internal/nls/TcfPluginMessages.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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.tm.tcf.internal.nls;
+
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * TCF plugin externalized strings management.
+ */
+public class TcfPluginMessages extends NLS {
+
+ // The plug-in resouce bundle name
+ private static final String BUNDLE_NAME = "org.eclipse.tm.tcf.internal.tcf.TcfPluginMessages"; //$NON-NLS-1$
+
+ /**
+ * Static constructor.
+ */
+ static {
+ // Load message values from bundle file
+ NLS.initializeMessages(BUNDLE_NAME, TcfPluginMessages.class);
+ }
+
+ // **** Declare externalized string id's down here *****
+
+ public static String Extension_error_missingRequiredAttribute;
+ public static String Extension_error_duplicateExtension;
+ public static String Extension_error_invalidExtensionPoint;
+
+}
diff --git a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/internal/nls/TcfPluginMessages.properties b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/internal/nls/TcfPluginMessages.properties
new file mode 100644
index 000000000..4945e1861
--- /dev/null
+++ b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/internal/nls/TcfPluginMessages.properties
@@ -0,0 +1,8 @@
+#
+# org.eclipse.tm.tcf
+# Externalized Strings.
+#
+
+Extension_error_missingRequiredAttribute=Required attribute "{0}" missing for extension "{1}"!
+Extension_error_duplicateExtension=Duplicate extension with id ''{0}''. Ignoring duplicated contribution from contributor ''{1}''!
+Extension_error_invalidExtensionPoint=Failed to instanciate the executable extension from extension point ''{0}''.

Back to the top