diff options
Diffstat (limited to 'archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/utils/ExtensionFactory.java')
-rw-r--r-- | archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/utils/ExtensionFactory.java | 395 |
1 files changed, 395 insertions, 0 deletions
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/utils/ExtensionFactory.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/utils/ExtensionFactory.java new file mode 100644 index 000000000..1ad2882f0 --- /dev/null +++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/utils/ExtensionFactory.java @@ -0,0 +1,395 @@ +/******************************************************************************* +* Copyright (c) 2007 IBM Corporation. +* 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: +* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation + +*******************************************************************************/ + +package org.eclipse.imp.utils; + +import java.net.URL; +import java.util.HashSet; +import java.util.Set; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IContributor; +import org.eclipse.core.runtime.IExtensionPoint; +import org.eclipse.core.runtime.Platform; +import org.eclipse.imp.language.ILanguageService; +import org.eclipse.imp.language.Language; +import org.eclipse.imp.language.LanguageRegistry; +import org.eclipse.imp.runtime.RuntimePlugin; +import org.osgi.framework.Bundle; + +/* + * Licensed Materials - Property of IBM, (c) Copyright IBM Corp. 2005 All Rights + * Reserved + */ + +/** + * @author Claffra + * @author rfuhrer@watson.ibm.com + * @author jurgen@vinju.org + */ +public class ExtensionFactory { + + /** + * Locate the first extension that matches this language and extension point id, + * and load the class that implements it and return a handle to an object of that class. + * + * @param language + * @param extensionPointID + * @return + * @throws ExtensionException + */ + public static ILanguageService createServiceExtension(Language language, + String extensionPointID) throws ExtensionException { + return createServiceExtensionForPlugin(language, RuntimePlugin.IMP_RUNTIME, + extensionPointID); + } + + /** + * Locate all extensions that match the language and extension point id, load their + * classes and collect handles to objects of that class in a set. + * @param language + * @param extensionPointID + * @return + * @throws ExtensionException + */ + public static Set<ILanguageService> createServiceExtensionSet(Language language, + String extensionPointID) throws ExtensionException { + return createServiceExtensionSetForPlugin(language, RuntimePlugin.IMP_RUNTIME, + extensionPointID); + } + + /** + * Find a language name in a language descriptor extension. + * + * @param pluginID + * @return + */ + public static String retrieveLanguageIdFromPlugin(String pluginID) { + IExtensionPoint extensionPoint = Platform.getExtensionRegistry() + .getExtensionPoint(RuntimePlugin.IMP_RUNTIME, + RuntimePlugin.LANGUAGE_DESCRIPTOR); + IConfigurationElement[] configElements = extensionPoint + .getConfigurationElements(); + + for (int i = 0; i < configElements.length; i++) { + IContributor contrib = configElements[i].getContributor(); + + if (contrib.getName().equals(pluginID)) { + return configElements[i] + .getAttribute(Language.LANGUAGE_ID_ATTR); + } + } + + return null; + } + + /** + * Locate the first extension that matches this language, plugin, and extensionpoint id, + * then load a class from the element named 'elementName', and return a handle to an + * object of this class. + * + * @param language + * @param pluginID + * @param extensionPointId + * @param elementName + * @return + * @throws ExtensionException + */ + public static ILanguageService createServiceExtensionForPlugin( + Language language, String pluginID, String extensionPointId, + String elementName) throws ExtensionException { + IExtensionPoint extensionPoint = Platform.getExtensionRegistry() + .getExtensionPoint(pluginID, extensionPointId); + + if (extensionPoint == null) { + throw new ExtensionException( + "No such language service extension point defined: " + + pluginID + "." + extensionPointId); + } + + ILanguageService service = getLanguageServiceForElement( + extensionPoint, language.getName(), elementName); + + if (service == null && languageIsDerived(language)) { + service = createServiceExtensionForPlugin(LanguageRegistry + .findLanguage(language.getDerivedFrom()), pluginID, + extensionPointId, elementName); + } + + return service; + } + + /** + * Detmermine wether a language was declared to be derived from another language, + * and whether this other language actually is registered. + * @param language + * @return + */ + private static boolean languageIsDerived(Language language) { + final boolean hasParent = language.getDerivedFrom() != null + && LanguageRegistry.findLanguage(language.getDerivedFrom()) != null; + return hasParent; + } + + /** + * Finds the first extension that matches this language, plugin and extension point id, + * and then loads the class that implements this extension and returns a handle to it. + * + * @param language + * @param pluginID + * @param extensionPointId + * @return + * @throws ExtensionException + */ + public static ILanguageService createServiceExtensionForPlugin(Language language, + String pluginID, String extensionPointId) throws ExtensionException { + return createServiceExtensionForPlugin(language, pluginID, + extensionPointId, "class"); + } + + /** + * Find all extensions that match this pluginId, language and extension point id, + * then loads the classes that implement these extenstions and returns them as + * a set of ILanguageServices. + * + * @param language + * @param pluginID + * @param extensionPointId + * @return + * @throws ExtensionException + */ + public static Set<ILanguageService> createServiceExtensionSetForPlugin(Language language, + String pluginID, String extensionPointId) throws ExtensionException { + IExtensionPoint extensionPoint = Platform.getExtensionRegistry() + .getExtensionPoint(pluginID, extensionPointId); + + if (extensionPoint == null) { + throw new ExtensionException( + "No such language service extension point defined: " + + pluginID + "." + extensionPointId); + } + + Set<ILanguageService> services = getLanguageServiceSet( + extensionPoint, language.getName()); + + if (services.isEmpty() && languageIsDerived(language)) { + final ILanguageService baseServiceImpl = createServiceExtensionForPlugin( + LanguageRegistry.findLanguage(language.getDerivedFrom()), + pluginID, extensionPointId); + if (baseServiceImpl != null) { + services.add(baseServiceImpl); + } + } + + return services; + } + + /** + * detect whether a certain plugin defines a certain extension for a certain language + * @param pluginID + * @param extensionPointID + * @param language + * @return + */ + @SuppressWarnings("deprecation") + public static boolean languageServiceExists(String pluginID, + String extensionPointID, Language language) { + if (language == null) + return false; + + IExtensionPoint extensionPoint = Platform.getExtensionRegistry() + .getExtensionPoint(pluginID, extensionPointID); + IConfigurationElement[] elements = extensionPoint + .getConfigurationElements(); + String lowerLang = language.getName().toLowerCase(); + + if (elements != null) { + for (int n = 0; n < elements.length; n++) { + IConfigurationElement element = elements[n]; + Bundle bundle = Platform.getBundle(element + .getDeclaringExtension().getNamespace()); + + if (bundle != null) { + final String attrValue = element + .getAttribute(Language.LANGUAGE_ID_ATTR); + + if (attrValue != null + && lowerLang.equals(attrValue.toLowerCase())) { + return true; + } + } + } + } + + if (languageIsDerived(language)) { + return languageServiceExists(pluginID, extensionPointID, + LanguageRegistry.findLanguage(language.getDerivedFrom())); + } + + return false; + } + + /** + * Locates all elements that match the language and the particular extension point id, + * and returns a set of loaded ILanguageServices using these elements. + * @param extensionPoint + * @param language + * @return + * @throws ExtensionException + */ + private static Set<ILanguageService> getLanguageServiceSet( + IExtensionPoint extensionPoint, String language) + throws ExtensionException { + IConfigurationElement[] elements = extensionPoint + .getConfigurationElements(); + Set<ILanguageService> result = new HashSet<ILanguageService>(); + + if (elements != null) { + for (int n = 0; n < elements.length; n++) { + IConfigurationElement element = elements[n]; + ILanguageService service = loadLanguageService(extensionPoint, language, "class", element); + + if (service != null) { + result.add(service); + } + } + } + + return result; + } + + /** + * Locates the first element that matches the ,anguage and the elementName, + * and tries to load a language service from it. + * + * @param extensionPoint + * @param language + * @param elementName + * @return + * @throws ExtensionException + */ + private static ILanguageService getLanguageServiceForElement( + IExtensionPoint extensionPoint, String language, String elementName) + throws ExtensionException { + IConfigurationElement[] elements = extensionPoint + .getConfigurationElements(); + + if (elements != null) { + for (int n = 0; n < elements.length; n++) { + IConfigurationElement element = elements[n]; + ILanguageService service = loadLanguageService(extensionPoint, language, elementName, element); + if (service != null) { + return service; + } + } + } + + return null; + } + + /** + * Convenience method for actuallys creating an object from an element in an + * extension point. Catches common exceptions that may be thrown and tries to + * translate them into ServiceExceptions. + * + * @param extensionPoint + * @param language + * @param elementName + * @param element + * @return + * @throws ExtensionException + */ + @SuppressWarnings("deprecation") + private static ILanguageService loadLanguageService(IExtensionPoint extensionPoint, String language, String elementName, IConfigurationElement element) throws ExtensionException { + Bundle bundle = Platform.getBundle(element + .getDeclaringExtension().getNamespace()); + String lowerLang = language.toLowerCase(); + + if (bundle != null) { + final String attrValue = element + .getAttribute(Language.LANGUAGE_ID_ATTR); + + if (attrValue != null + && lowerLang.equals(attrValue.toLowerCase())) { + try { + return (ILanguageService) element + .createExecutableExtension(elementName); + } catch (ClassCastException e) { + throw new ExtensionException( + "Extension does not point to a class that implements an ILanguageService:" + + element, e); + } catch (IncompatibleClassChangeError e) { + throw new ExtensionException("Unable to instantiate implementation of " + + extensionPoint.getLabel() + + " plugin for language '" + + language + + "' because some class in the plugin is incompatible (out-of-date)", e); + } catch (CoreException e) { + throw new ExtensionException( + "Unable to instantiate implementation of " + + extensionPoint.getLabel() + + " plugin for language '" + + language + + "' because of the following low level exception: " + + e.getStatus().getException(), e); + } catch (NoClassDefFoundError e) { + throw new ExtensionException( + "Unable to instantiate implementation of " + + extensionPoint.getLabel() + + " plugin for language '" + + language + + "' because it may not have a public zero argument constructor, or some class referenced by the plugin could not be found in the class path.", + e); + } + } + } + + return null; + } + + /** + * Retrieves from an extension an attribute that represents a resource URL + * @param language language that the extension is for + * @param extensionPoint extension point identifier + * @param the label of the attribute that contains the resource URL + */ + @SuppressWarnings("deprecation") + public static URL createResourceURL(String language, + IExtensionPoint extensionPoint, String label) { + IConfigurationElement[] elements = extensionPoint + .getConfigurationElements(); + String lowerLabel = label.toLowerCase(); + String lowerLang = language.toLowerCase(); + + if (elements != null) { + for (int n = 0; n < elements.length; n++) { + IConfigurationElement element = elements[n]; + Bundle bundle = Platform.getBundle(element + .getDeclaringExtension().getNamespace()); + + if (bundle != null) { + final String attrValue = element + .getAttribute(Language.LANGUAGE_ID_ATTR); + + if (attrValue != null + && lowerLang.equals(attrValue.toLowerCase())) { + String resourceName = element.getAttribute(lowerLabel); + return bundle.getResource(resourceName); + } + } + } + } + + return null; + } +} |