/* * Copyright (c) 2005, 2007 Borland Software 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: * Radek Dvorak (Borland) - initial API and implementation */ package org.eclipse.gmf.internal.validate.expressions; import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.Set; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.InvalidRegistryObjectException; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Status; import org.eclipse.gmf.internal.validate.GMFValidationPlugin; import org.eclipse.osgi.util.NLS; /** * This class maintains all contribution to * <code>org.eclipse.gmf.validate.expressions</code> extension point. * <p> * It collects all contributions of all providers at this class initialization * time. It only creates and caches only descriptors of provider implementations. * A provider itself is initialized lazily on demand. */ public class ExpressionProviderRegistry { private static final ExpressionProviderRegistry INSTANCE = new ExpressionProviderRegistry(); private Map<String, Descriptor> registry; private ExpressionProviderRegistry() { registry = new HashMap<String, Descriptor>(); initialiaze(); } /** * Gets the instance of providers registry. */ public static ExpressionProviderRegistry getInstance() { return INSTANCE; } /** * Gets the provider for the given language. * * @param language * the identifier of the language * @return the provider supporting expressions in the given language or * <code>null</code> if no such provider is found */ public IModelExpressionProvider getProvider(String language) { Descriptor descriptor = getDescriptor(language); if(descriptor != null && descriptor.getStatus().isOK()) { return descriptor.getProvider(); } return null; } /** * Gets supported expression languages by providers in this registry. * @return set of language identifiers strings, never <code>null</code> */ public Set<String> getLanguages() { return registry.keySet(); } /** * Gets descriptor of the provider supporting the given language. * * @param language * the identifier of the expression language whose provider is to * be retrieved * @return corresponding provider descriptor or <code>null</code> if no * such provider is found. */ public Descriptor getDescriptor(String language) { return registry.get(language); } private void initialiaze() { IConfigurationElement[] configs = Platform.getExtensionRegistry().getConfigurationElementsFor( Descriptor.GLOBAL_EXTENSION_ID); for (int i = 0; i < configs.length; i++) { IConfigurationElement element = configs[i]; Descriptor descriptor = new Descriptor(element); if(descriptor.getStatus().isOK()) { String lang = descriptor.getLanguage(); assert lang != null; Descriptor currentDsc = registry.get(lang); if(currentDsc == null) { registry.put(lang, descriptor); } else { String message = NLS.bind(Messages.providerAlreadyExistsIgnore, new Object[] { currentDsc.getProviderClassName(), lang, descriptor.getProviderClassName() }); GMFValidationPlugin.log(GMFValidationPlugin.createStatus(IStatus.ERROR, 0, message, null)); } } } registry = Collections.unmodifiableMap(registry); } static class Descriptor { static final String EXTENSION_ID = "expressionProviders"; //$NON-NLS-1$ static final String GLOBAL_EXTENSION_ID = GMFValidationPlugin.getPluginId() + "." + EXTENSION_ID; //$NON-NLS-1$ public static final String ATTR_CLASS = "class"; //$NON-NLS-1$ public static final String ATTR_LANGUAGE = "language"; //$NON-NLS-1$ public static final String ATTR_REQUIRES_MODEL_CLASS = "requiresModelClass"; //$NON-NLS-1$ public static final String ATTR_NAME = "name"; //$NON-NLS-1$ public static final String ATTR_DESCRIPTION = "description"; //$NON-NLS-1$ public static final String ATTR_LOOSELY_TYPED = "isLooselyTyped"; //$NON-NLS-1$ private IConfigurationElement configElement; private String language; private String className; private boolean modelReflection; private boolean isLooselyTyped; private String name; private String description; private IStatus status; private IModelExpressionProvider provider; Descriptor(IConfigurationElement config) { this.status = Status.OK_STATUS; try { configure(config); } catch (InvalidRegistryObjectException e) { GMFValidationPlugin.log(IStatus.ERROR, Messages.initDescriptorFailure, e); } } public IStatus getStatus() { return status; } public String getLanguage() { return language; } public boolean supportsModelReflection() { return modelReflection; } public boolean isLooselyTyped() { return isLooselyTyped; } public String getProviderClassName() { return className; } public String getName() { return name; } public String getDescription() { return description; } IModelExpressionProvider getProvider() { if(provider == null && getStatus().isOK()) { try { provider = (IModelExpressionProvider)configElement.createExecutableExtension(ATTR_CLASS); } catch(CoreException e) { String message = NLS.bind(Messages.providerCreationFailure, getProviderClassName()); GMFValidationPlugin.log(IStatus.ERROR, message, e); } } return provider; } private void configure(IConfigurationElement config) { this.configElement = config; language = configElement.getAttribute(ATTR_LANGUAGE); if(language == null || language.trim().length() == 0) { this.status = GMFValidationPlugin.createStatus(IStatus.ERROR, 0, Messages.missingProviderLanguage, null); } className = config.getAttribute(ATTR_CLASS); if(className == null || className.trim().length() == 0) { this.status = GMFValidationPlugin.createStatus(IStatus.ERROR, 0, Messages.missingProviderClass, null); } modelReflection = "true".equals(config.getAttribute(ATTR_REQUIRES_MODEL_CLASS)); //$NON-NLS-1$ isLooselyTyped = "true".equals(config.getAttribute(ATTR_LOOSELY_TYPED)); //$NON-NLS-1$ name = config.getAttribute(ATTR_NAME); description = config.getAttribute(ATTR_DESCRIPTION); } } }