diff options
Diffstat (limited to 'target_explorer/plugins/org.eclipse.tcf.te.runtime/src/org/eclipse/tcf/te/runtime/extensions/AbstractExtensionPointManager.java')
-rw-r--r-- | target_explorer/plugins/org.eclipse.tcf.te.runtime/src/org/eclipse/tcf/te/runtime/extensions/AbstractExtensionPointManager.java | 220 |
1 files changed, 220 insertions, 0 deletions
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.runtime/src/org/eclipse/tcf/te/runtime/extensions/AbstractExtensionPointManager.java b/target_explorer/plugins/org.eclipse.tcf.te.runtime/src/org/eclipse/tcf/te/runtime/extensions/AbstractExtensionPointManager.java new file mode 100644 index 000000000..336f3b0c5 --- /dev/null +++ b/target_explorer/plugins/org.eclipse.tcf.te.runtime/src/org/eclipse/tcf/te/runtime/extensions/AbstractExtensionPointManager.java @@ -0,0 +1,220 @@ +/******************************************************************************* + * Copyright (c) 2011 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.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.Assert; +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.tcf.te.runtime.activator.CoreBundleActivator; +import org.eclipse.tcf.te.runtime.nls.Messages; + +/** + * Abstract extension point manager implementation. + */ +public abstract class AbstractExtensionPointManager<V> { + // Flag to mark the extension point manager initialized (extensions loaded). + private boolean initialized = false; + // The map of loaded extension listed by their unique id's + private Map<String, ExecutableExtensionProxy<V>> extensionsMap = new LinkedHashMap<String, ExecutableExtensionProxy<V>>(); + // The extension point comparator + private ExtensionPointComparator comparator = null; + + /** + * Constructor. + */ + public AbstractExtensionPointManager() { + } + + /** + * Returns if or if not the extension point manager got initialized already. + * <p> + * Initialized means that the manager read the extensions for the managed extension point. + * + * @return <code>True</code> if already initialized, <code>false</code> otherwise. + */ + protected boolean isInitialized() { + return initialized; + } + + /** + * Sets if or if not the extension point manager is initialized. + * <p> + * Initialized means that the manager has read the extensions 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) { + this.initialized = 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 extensions. + */ + protected Map<String, ExecutableExtensionProxy<V>> getExtensions() { + // Load and store the extensions thread-safe! + synchronized (extensionsMap) { + if (!isInitialized()) { loadExtensions(); setInitialized(true); } + } + return extensionsMap; + } + + /** + * Returns the extensions of the specified extension point sorted. + * <p> + * For the order of the extensions, see {@link ExtensionPointComparator}. + * + * @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 ExtensionPointComparator getExtensionPointComparator() { + if (comparator == null) { + comparator = doCreateExtensionPointComparator(); + } + return comparator; + } + + /** + * Creates a new extension point comparator instance. + * + * @return The extension point comparator instance. + */ + protected ExtensionPointComparator doCreateExtensionPointComparator() { + return new ExtensionPointComparator(); + } + + /** + * 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 not be <code>null</code>. + * @return The extension proxy instance. + * + * @throws CoreException If the extension proxy instantiation failed. + */ + protected ExecutableExtensionProxy<V> doCreateExtensionProxy(IConfigurationElement element) throws CoreException { + Assert.isNotNull(element); + return new ExecutableExtensionProxy<V>(element); + } + + /** + * Store the given extension to the given extensions store. Checks if an extension with the same id does exist + * already and throws an exception in this case. + * + * @param extensions The extensions store. Must not be <code>null</code>. + * @param candidate The extension. Must not be <code>null</code>. + * @param element The configuration element. Must not be <code>null</code>. + * + * @throws CoreException In case a extension with the same id as the given extension already exist. + */ + protected void doStoreExtensionTo(Map<String, ExecutableExtensionProxy<V>> extensions, ExecutableExtensionProxy<V> candidate, IConfigurationElement element) throws CoreException { + Assert.isNotNull(extensions); + Assert.isNotNull(candidate); + Assert.isNotNull(element); + + // If no extension with this id had been registered before, register now. + if (!extensions.containsKey(candidate.getId())) { + extensions.put(candidate.getId(), candidate); + } + else { + throw new CoreException(new Status(IStatus.ERROR, + CoreBundleActivator.getUniqueIdentifier(), + 0, + NLS.bind(Messages.Extension_error_duplicateExtension, candidate.getId(), element.getContributor().getName()), + null)); + } + } + + /** + * Loads the extensions for the managed extension 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 { + ExecutableExtensionProxy<V> candidate = doCreateExtensionProxy(element); + if (candidate.getId() != null) { + doStoreExtensionTo(extensionsMap, candidate, element); + } else { + throw new CoreException(new Status(IStatus.ERROR, + CoreBundleActivator.getUniqueIdentifier(), + 0, + NLS.bind(Messages.Extension_error_missingRequiredAttribute, "id", element.getAttribute("label")), //$NON-NLS-1$ //$NON-NLS-2$ + null)); + } + } catch (CoreException e) { + Platform.getLog(CoreBundleActivator.getContext().getBundle()).log(new Status(IStatus.ERROR, + CoreBundleActivator.getUniqueIdentifier(), + NLS.bind(Messages.Extension_error_invalidExtensionPoint, element.getDeclaringExtension().getUniqueIdentifier()), e)); + } + } + } + } + } + } +} |