blob: 09afc774aebf7931f8bfaf980bae9188001833ca [file] [log] [blame]
/**
* <copyright>
*
* Copyright (c) 2006, 2007 IBM Corporation 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:
* IBM - Initial API and implementation
*
* </copyright>
*
* $Id: EnvironmentRegistryImpl.java,v 1.2 2011/04/25 09:49:15 ewillink Exp $
*/
package org.eclipse.ocl.examples.pivot.utilities;
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.IExtension;
import org.eclipse.core.runtime.IExtensionDelta;
import org.eclipse.core.runtime.IExtensionRegistry;
import org.eclipse.core.runtime.IRegistryChangeEvent;
import org.eclipse.core.runtime.IRegistryChangeListener;
import org.eclipse.core.runtime.Platform;
import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.ocl.examples.pivot.Environment;
import org.eclipse.ocl.examples.pivot.EnvironmentFactory;
import org.eclipse.ocl.examples.pivot.OclExpression;
import org.eclipse.ocl.examples.pivot.Operation;
import org.eclipse.ocl.examples.pivot.Property;
import org.eclipse.ocl.examples.pivot.Type;
import org.eclipse.ocl.examples.pivot.TypedElement;
import org.eclipse.ocl.examples.pivot.messages.OCLMessages;
import org.eclipse.ocl.examples.pivot.util.PivotPlugin;
import org.eclipse.osgi.util.NLS;
/**
* Implementation of the environment registry.
*
* @author cdamus
*/
public class EnvironmentRegistryImpl implements Environment.Registry {
private final EList<Object> environments = new BasicEList<Object>();
private static final String PT_ENVIRONMENTS = "environments"; //$NON-NLS-1$
private static final String E_ENVIRONMENT_FACTORY = "environmentFactory"; //$NON-NLS-1$
private static final String A_CLASS = "class"; //$NON-NLS-1$
private static final String E_PACKAGE = "package"; //$NON-NLS-1$
private static final String A_NS_URI = "nsURI"; //$NON-NLS-1$
public Environment getEnvironmentFor(OclExpression expression) {
return getEnvironmentFor(expression.getType());
}
public Environment getEnvironmentFor(Object abstractSyntaxElement) {
if (abstractSyntaxElement instanceof TypedElement) {
return getEnvironmentFor(((TypedElement) abstractSyntaxElement).getType());
}
for (int i = 0; i < environments.size(); i++) {
Object next = environments.get(i);
if (next instanceof EnvironmentDescriptor) {
EnvironmentDescriptor descriptor = (EnvironmentDescriptor) next;
if (descriptor.matches(abstractSyntaxElement)) {
// instantiate the descriptor now
next = descriptor.instantiate();
environments.set(i, next);
}
}
if (next instanceof Environment) {
if ((abstractSyntaxElement instanceof Type)
|| (abstractSyntaxElement instanceof Operation)
|| (abstractSyntaxElement instanceof Property)) {
return (Environment) next;
}
}
}
return null;
}
public void registerEnvironment(Environment environment) {
if (!environments.contains(environment)) {
environments.add(environment);
}
}
public void deregisterEnvironment(Environment environment) {
environments.remove(environment);
}
/**
* Utility class that reads the Eclipse extension registry to find registered
* OCL environments.
*
* @author cdamus
*/
class RegistryReader implements IRegistryChangeListener {
private final String namespace;
private IExtensionRegistry extensionRegistry;
private final Map<String, EnvironmentDescriptor> descriptors =
new java.util.HashMap<String, EnvironmentDescriptor>();
RegistryReader(PivotPlugin plugin) {
// FIXME
namespace = "org.eclipse.ocl"; //$NON-NLS-1$ //plugin.getSymbolicName();
}
void readRegistry() {
if (extensionRegistry == null) {
extensionRegistry = Platform.getExtensionRegistry();
readRegistryImpl();
}
}
private void readRegistryImpl() {
extensionRegistry.addRegistryChangeListener(this, namespace);
IExtension[] extensions = extensionRegistry.getExtensionPoint(
namespace, PT_ENVIRONMENTS).getExtensions();
for (IExtension extension : extensions) {
read(extension);
}
}
private void read(IExtension extension) {
IConfigurationElement[] elements = extension.getConfigurationElements();
for (IConfigurationElement element : elements) {
if (E_ENVIRONMENT_FACTORY.equals(element.getName())) {
readEnvironmentFactory(element);
} else {
PivotPlugin.log(Diagnostic.ERROR, 1,
NLS.bind(
OCLMessages.EnvRegistry_unknownElement_ERROR_,
getExtensionID(extension),
element.getName()),
null);
}
}
}
private void readEnvironmentFactory(final IConfigurationElement element) {
String className = element.getAttribute(A_CLASS);
if (className != null) {
EnvironmentDescriptor descriptor = new EnvironmentDescriptor() {
@Override
EnvironmentFactory createFactory() {
try {
return (EnvironmentFactory)
element.createExecutableExtension(A_CLASS);
} catch (CoreException e) {
PivotPlugin.getPlugin().log(e);
return null;
}
}};
descriptors.put(className, descriptor);
environments.add(descriptor);
for (IConfigurationElement pkg : element.getChildren(E_PACKAGE)) {
readPackage(descriptor, pkg);
}
} else {
PivotPlugin.log(Diagnostic.ERROR, 1,
NLS.bind(
OCLMessages.EnvRegistry_missingClass_ERROR_,
getExtensionID(element)),
null);
}
}
private void readPackage(EnvironmentDescriptor descriptor,
IConfigurationElement element) {
String nsURI = element.getAttribute(A_NS_URI);
if (nsURI != null) {
descriptor.addPackageURI(nsURI);
} else {
PivotPlugin.log(Diagnostic.ERROR, 1,
NLS.bind(
OCLMessages.EnvRegistry_missingNsURI_ERROR_,
getExtensionID(element)),
null);
}
}
private void remove(IExtension extension) {
IConfigurationElement[] elements = extension.getConfigurationElements();
for (IConfigurationElement element : elements) {
if (E_ENVIRONMENT_FACTORY.equals(element.getName())) {
removeEnvironmentFactory(element);
}
}
}
private void removeEnvironmentFactory(IConfigurationElement element) {
String className = element.getAttribute(A_CLASS);
if (className != null) {
EnvironmentDescriptor descriptor = descriptors.get(className);
if (descriptor != null) {
descriptor.dispose();
}
}
}
public void registryChanged(IRegistryChangeEvent event) {
for (IExtensionDelta delta : event.getExtensionDeltas(
namespace, PT_ENVIRONMENTS)) {
switch (delta.getKind()) {
case IExtensionDelta.ADDED:
read(delta.getExtension());
break;
case IExtensionDelta.REMOVED:
remove(delta.getExtension());
break;
}
}
}
}
/**
* Descriptor for a lazily-instantiated OCL environment, loaded from the
* Eclipse extension registry.
*
* @author cdamus
*/
private abstract class EnvironmentDescriptor {
private final Set<String> packageURIs = new java.util.HashSet<String>();
private Environment env;
EnvironmentDescriptor() {
super();
}
void addPackageURI(String packageURI) {
packageURIs.add(packageURI);
}
boolean matches(Object object) {
boolean result = object instanceof EObject;
if (result) {
EPackage epackage = ((EObject) object).eClass().getEPackage();
result = (epackage != null) && packageURIs.contains(epackage.getNsURI());
}
return result;
}
Environment instantiate() {
if (env == null) {
EnvironmentFactory factory = createFactory();
env = factory.createEnvironment();
}
return env;
}
void dispose() {
if (env != null) {
// I have been instantiated, so remove my environment from
// the list
environments.remove(env);
}
// make sure that I'm not in the environments list, either
environments.remove(this);
}
abstract EnvironmentFactory createFactory();
}
/**
* Obtains the ID of the extension defining the specified element,
* or the defining plug-in ID if the extension has none.
*
* @param element an element
* @return an identifier for the extension
*/
private String getExtensionID(IConfigurationElement element) {
return getExtensionID(element.getDeclaringExtension());
}
/**
* Obtains the ID of the specified extension,
* or the defining plug-in ID if the extension has none.
*
* @param extension an extension
* @return an identifier for the extension
*/
private String getExtensionID(IExtension extension) {
String result = extension.getUniqueIdentifier();
if (result == null) {
result = extension.getNamespaceIdentifier();
}
return result;
}
}