/** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Copyright (C) 2007 Matthias Braeuer (braeuer.matthias@web.de). * * All rights reserved. * * * * This work was done as a project at the Chair for Software Technology, * * Dresden University Of Technology, Germany (http://st.inf.tu-dresden.de). * * It is understood that any modification not identified as such is not * * covered by the preceding statement. * * * * This work is free software; you can redistribute it and/or modify it * * under the terms of the GNU Library General Public License as published * * by the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This work is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public * * License for more details. * * * * You should have received a copy of the GNU Library General Public License * * along with this library; if not, you can view it online at * * http://www.fsf.org/licensing/licenses/gpl.html. * * * * To submit a bug report, send a comment, or get the latest news on this * * project, please visit the website: http://dresden-ocl.sourceforge.net. * * For more information on OCL and related projects visit the OCL Portal: * * http://st.inf.tu-dresden.de/ocl * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * $Id$ */ package org.dresdenocl.modelbus.metamodel.internal; import java.util.HashMap; import java.util.Map; import org.apache.commons.lang.IllegalClassException; import org.apache.log4j.Logger; 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.IRegistryEventListener; import org.eclipse.core.runtime.Platform; import org.dresdenocl.model.metamodel.IMetamodel; import org.dresdenocl.model.metamodel.IMetamodelRegistry; import org.dresdenocl.modelbus.IModelBusConstants; import org.dresdenocl.modelbus.ModelBusPlugin; import org.dresdenocl.modelbus.descriptor.IDescriptor; import org.dresdenocl.modelbus.descriptor.InvalidDescriptorException; /** * <p> * A default implementation of the {@link IMetamodelRegistry} interface to be * used in an Eclipse workbench. * </p> * * @author Matthias Braeuer */ public final class MetamodelRegistry implements IMetamodelRegistry, IRegistryEventListener { /** Logger for this class. */ private static final Logger LOGGER = ModelBusPlugin .getLogger(MetamodelRegistry.class); /** The full identifier of the {@link IMetamodel}s' extension point. */ private static final String METAMODEL_EXTENSION_POINT_ID = ModelBusPlugin.ID + '.' + IModelBusConstants.EXT_METAMODELS; /** * A helper class to read the {@link IMetamodel} configuration from the * {@link IExtensionRegistry}. */ private MetamodelRegistryReader metaModelReader; /** A map for caching the {@link IMetamodel}s. */ private Map<String, IMetamodel> metaModels; /** * <p> * Creates a new {@link MetamodelRegistry} instance. * </p> */ public MetamodelRegistry() { if (LOGGER.isDebugEnabled()) { LOGGER.debug("MetamodelRegistry() - enter"); //$NON-NLS-1$ } // no else. // create a new reader and read in the configuration metaModelReader = new MetamodelRegistryReader(); IExtensionPoint extensionPoint = this.getExtensionPoint(); if (extensionPoint != null) { metaModelReader.read(this.getExtensionPoint(), this); /* Register this registry as a listener for plug-in events. */ Platform.getExtensionRegistry().addListener(this, METAMODEL_EXTENSION_POINT_ID); } else { LOGGER.warn("Platform is not running. Metamodels must be registered manually."); } if (LOGGER.isDebugEnabled()) { LOGGER.debug("MetamodelRegistry() - exit"); //$NON-NLS-1$ } // no else. } /* * (non-Javadoc) * * @see * org.eclipse.core.runtime.IRegistryEventListener#added(org.eclipse.core. * runtime.IExtension[]) */ public void added(IExtension[] extensions) { if (LOGGER.isDebugEnabled()) { LOGGER.debug("added(extensions=" + extensions + ") - enter"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } // no else. /* Use the registry reader to read in the new extension. */ for (IExtension extension : extensions) { this.metaModelReader.read(extension, this); } // no else. if (LOGGER.isDebugEnabled()) { LOGGER.debug("added(IExtension[]) - exit"); //$NON-NLS-1$ } // no else. } /* * (non-Javadoc) * * @see * org.eclipse.core.runtime.IRegistryEventListener#added(org.eclipse.core. * runtime.IExtensionPoint[]) */ public void added(IExtensionPoint[] extensionPoints) { /* Do nothing. Only listen for extensions. */ } /* * (non-Javadoc) * * @see * org.dresdenocl.modelbus.IMetamodelRegistry#addMetamodel(tudresden * .ocl20.pivot.modelbus.IMetamodel) */ public void addMetamodel(IMetamodel metamodel) { if (LOGGER.isDebugEnabled()) { LOGGER.debug("addMetamodel(metamodel=" + metamodel + ") - enter"); //$NON-NLS-1$ //$NON-NLS-2$ } // no else. /* Precondition check. */ if (metamodel == null) { throw new IllegalArgumentException( "The parameter 'metamodel' was null."); //$NON-NLS-1$ } // no else. /* Lazily create the meta-models cache. */ if (this.metaModels == null) { this.metaModels = new HashMap<String, IMetamodel>(); } // no else. /* Add the meta-model to the cache. */ this.metaModels.put(metamodel.getId(), metamodel); if (LOGGER.isDebugEnabled()) { LOGGER.debug("addMetamodel() - exit"); //$NON-NLS-1$ } // no else. } /* * (non-Javadoc) * * @see org.dresdenocl.modelbus.IMetamodelRegistry#dispose() */ public void dispose() { /* Remove from the extension tracker. */ Platform.getExtensionRegistry().removeListener(this); /* Clear meta-model cache. */ if (this.metaModels != null) { this.metaModels.clear(); this.metaModels = null; } // no else. } /* * (non-Javadoc) * * @see * org.dresdenocl.modelbus.IMetamodelRegistry#getMetamodel(java.lang * .String) */ public IMetamodel getMetamodel(String id) { IMetamodel result; if (this.metaModels == null) { result = null; } else { result = this.metaModels.get(id); } return result; } /* * (non-Javadoc) * * @see org.dresdenocl.modelbus.IMetamodelRegistry#getMetamodels() */ public IMetamodel[] getMetamodels() { IMetamodel[] result; if (this.metaModels == null) { result = new IMetamodel[0]; } else { result = metaModels.values().toArray( new IMetamodel[metaModels.size()]); } return result; } /* * (non-Javadoc) * * @see * org.eclipse.core.runtime.IRegistryEventListener#removed(org.eclipse.core * .runtime.IExtension[]) */ public void removed(IExtension[] extensions) { if (LOGGER.isDebugEnabled()) { LOGGER.debug("removed(extensions=" + extensions + ") - enter"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } // no else. /* Remove all registered objects from the meta-model cache. */ if (this.metaModels != null) { for (IExtension extension : extensions) { for (IConfigurationElement configurationElement : extension .getConfigurationElements()) { String metaModelID; metaModelID = this.getAttribute(IDescriptor.ATT_ID, configurationElement); if (metaModelID != null) { this.metaModels.remove(metaModelID); } // no else. } // end for (configurationElements). } // end for (extensions). } // no else. if (LOGGER.isDebugEnabled()) { LOGGER.debug("removed(IExtension[]) - exit"); //$NON-NLS-1$ } // no else. } /* * (non-Javadoc) * * @see * org.eclipse.core.runtime.IRegistryEventListener#removed(org.eclipse.core * .runtime.IExtensionPoint[]) */ public void removed(IExtensionPoint[] extensionPoints) { /* Do nothing. Only listen for extensions. */ } /** * <p> * Helper method that returns the value of an attribute of the given * {@link IConfigurationElement}. Throws an * {@link InvalidDescriptorException} if the attribute is empty and * required. * </p> * * @param attributeName * The name of the extension point attribute. * @param configurationElement * The {@link IllegalClassException} whose attribute shall be * returned. * * @throws InvalidDescriptorException * If the value of the attribute is invalid. */ private String getAttribute(String attributeName, IConfigurationElement configurationElement) { if (LOGGER.isDebugEnabled()) { LOGGER.debug("getAttribute(attributeName=" + attributeName + ", configurationElement=" + configurationElement //$NON-NLS-1$ //$NON-NLS-2$ + ") - enter"); //$NON-NLS-1$ } // no else. String value = configurationElement.getAttribute(attributeName); if (LOGGER.isDebugEnabled()) { LOGGER.debug("getAttribute() - exit - return value=" + value); //$NON-NLS-1$ } // no else. return value; } /** * <p> * A helper method to get the worklist task {@link IExtensionPoint}. * </p> * * @return The {@link IMetamodel} {@link IExtensionPoint}. */ private IExtensionPoint getExtensionPoint() { IExtensionPoint result; if (Platform.getExtensionRegistry() != null) { /* Get the point from the registry. */ result = Platform.getExtensionRegistry().getExtensionPoint( METAMODEL_EXTENSION_POINT_ID); /* This should not happen unless the id changes. */ if (result == null) { throw new IllegalStateException( "The extension point for new metamodels could not be found under the id " //$NON-NLS-1$ + METAMODEL_EXTENSION_POINT_ID); } // no else. } else result = null; return result; } }