/** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 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.model.internal; import java.util.HashSet; import java.util.Set; import org.apache.log4j.Logger; import org.eclipse.core.runtime.ListenerList; import org.eclipse.osgi.util.NLS; import org.dresdenocl.model.IModel; import org.dresdenocl.model.IModelRegistry; import org.dresdenocl.model.event.IModelRegistryListener; import org.dresdenocl.model.event.ModelRegistryEvent; import org.dresdenocl.modelbus.ModelBusPlugin; import org.dresdenocl.modelbus.internal.ModelBusMessages; /** * <p> * Standard implementation of the {@link IModelRegistry} interface that uses a * simple list for storing references to {@link IModel models}. * </p> * * @author Matthias Braeuer */ public class ModelRegistry implements IModelRegistry { /** {@link Logger} for this class. */ private static final Logger LOGGER = ModelBusPlugin.getLogger(ModelRegistry.class); /** Keeps track of the active {@link IModel}. */ private IModel activeModel; /** The list of registered {@link IModel}s. */ private Set<IModel> models; /** A list of listeners. */ private ListenerList listeners; /* * (non-Javadoc) * @see * org.dresdenocl.modelbus.IModelRegistry#addMetamodel(org.dresdenocl * .pivot.modelbus.IModel) */ public void addModel(IModel model) { if (LOGGER.isDebugEnabled()) { LOGGER.debug("addModel(model=" + model + ") - enter"); //$NON-NLS-1$ //$NON-NLS-2$ } // no else. if (model == null) { throw new IllegalArgumentException( "The parameter 'model' must not be null."); //$NON-NLS-1$ } // no else. /* Lazily create the list of models. */ if (this.models == null) { this.models = new HashSet<IModel>(); } // no else. /* * Check if model is already contained in the registry; this is meant to be * captured and dealt with on the UI, e.g., by showing an error message; * this is better than silently do nothing. */ if (this.models.contains(model)) { LOGGER .warn("Model '" + model.getDisplayName() + "' is already loaded. The model will be replaced."); //$NON-NLS-1$//$NON-NLS-2$ } // no else. /* Add the model. */ this.models.add(model); /* Inform listeners. */ this.fireModelAdded(model); /* If no model has been active, make this the active one. */ if (this.activeModel == null) { this.setActiveModel(model); } // no else. if (LOGGER.isDebugEnabled()) { LOGGER.debug("addModel() - exit"); //$NON-NLS-1$ } // no else. } /* * (non-Javadoc) * @see * org.dresdenocl.modelbus.IModelRegistry#addModelBusListener(tudresden * .ocl20.pivot.modelbus.event.IModelRegistryListener) */ public void addModelRegistryListener(IModelRegistryListener listener) { this.getListeners().add(listener); } /* * (non-Javadoc) * @see org.dresdenocl.modelbus.IModelRegistry#dispose() */ public void dispose() { this.activeModel = null; if (this.models != null) { this.models.clear(); this.models = null; } // no else. } /* * (non-Javadoc) * @see org.dresdenocl.modelbus.IModelRegistry#getActiveModel() */ public IModel getActiveModel() { return this.activeModel; } /* * (non-Javadoc) * @see org.dresdenocl.modelbus.IModelRegistry#getModels() */ public IModel[] getModels() { IModel[] result; if (this.models == null) { result = new IModel[] {}; } else { result = this.models.toArray(new IModel[this.models.size()]); } return result; } /* * (non-Javadoc) * @see * org.dresdenocl.modelbus.model.IModelRegistry#removeModel(tudresden * .ocl20.pivot.modelbus.model.IModel) */ public boolean removeModel(IModel model) { if (model == null) { throw new IllegalArgumentException("Parameter model must not be null"); } // no else. boolean result; if (this.models != null) { result = this.models.remove(model); model.dispose(); this.fireModelRemoved(model); /* Probably update the active model. */ if (model.equals(this.getActiveModel())) { this.activeModel = null; if (this.models.size() == 1) { this.activeModel = this.models.iterator().next(); } // no else. this.fireActiveModelChanged(this.getActiveModel()); } // no else. } else { result = false; } return result; } /* * (non-Javadoc) * @see * org.dresdenocl.modelbus.model.IModelRegistry#removeModel(java.lang * .String) */ public IModel removeModel(String displayName) { if (displayName == null) { throw new IllegalArgumentException( "The parameter displayName must not be null."); } // no else. IModel result; result = null; if (this.models != null) { for (IModel model : this.models) { if (model.getDisplayName().equals(displayName)) { result = model; this.removeModel(model); break; } // no else. } // end for. } // no else. return result; } /* * (non-Javadoc) * @see * org.dresdenocl.modelbus.IModelRegistry#removeModelBusListener(tudresden * .ocl20.pivot.modelbus.event.IModelRegistryListener) */ public void removeModelRegistryListener(IModelRegistryListener listener) { if (this.listeners != null) { this.listeners.remove(listener); } // no else. } /* * (non-Javadoc) * @see * org.dresdenocl.modelbus.IModelRegistry#setActiveModel(tudresden. * ocl20.pivot.modelbus.IModel) */ public void setActiveModel(IModel model) { if (LOGGER.isDebugEnabled()) { LOGGER.debug("setActiveModel(model=" + model + ") - enter"); //$NON-NLS-1$ //$NON-NLS-2$ } // no else. if (model == null) { throw new IllegalArgumentException("The active model must not be null."); //$NON-NLS-1$ } // no else. /* Check that the new active model is managed by this registry. */ if (this.models == null || !this.models.contains(model)) { throw new IllegalArgumentException( "The model '" + model.getDisplayName() //$NON-NLS-1$ + "' must be added to the model registry first before it can be set active."); //$NON-NLS-1$ } // no else. /* Only update if the active model has changed. */ if (this.activeModel == null || !this.activeModel.equals(model)) { if (LOGGER.isInfoEnabled()) { LOGGER.info(NLS.bind(ModelBusMessages.ModelRegistry_SettingActiveModel, model.getDisplayName())); } // no else. this.activeModel = model; this.fireActiveModelChanged(model); } // no else. if (LOGGER.isDebugEnabled()) { LOGGER.debug("setActiveModel() - exit"); //$NON-NLS-1$ } // no else. } /** * <p> * A helper method that informs all listeners about a a new active * {@link IModel}. * </p> * * @param model * The {@link IModel} that has been set active. */ private void fireActiveModelChanged(IModel model) { ModelRegistryEvent event; event = null; if (this.listeners != null) { Object[] listeners; listeners = this.listeners.getListeners(); for (int index = 0; index < listeners.length; index++) { /* Lazily create the event. */ if (event == null) { event = new ModelRegistryEvent(this, model); } // no else. ((IModelRegistryListener) listeners[index]).activeModelChanged(event); } // end for. } // no else. } /** * <p> * A helper method that informs all listeners about an added {@link IModel}. * </p> * * @param model * The {@link IModel} that has been added. */ private void fireModelAdded(IModel model) { ModelRegistryEvent event; event = null; if (this.listeners != null) { Object[] listeners; listeners = this.listeners.getListeners(); for (int index = 0; index < listeners.length; index++) { /* Lazily create the event. */ if (event == null) { event = new ModelRegistryEvent(this, model); } // no else. ((IModelRegistryListener) listeners[index]).modelAdded(event); } // end for. } // no else. } /** * <p> * A helper method that informs all listeners about a removed {@link IModel}. * </p> * * @param model * The {@link IModel} that has been removed. */ private void fireModelRemoved(IModel model) { ModelRegistryEvent event; event = null; if (this.listeners != null) { Object[] listeners; listeners = this.listeners.getListeners(); for (int index = 0; index < listeners.length; index++) { /* Lazily create the event. */ if (event == null) { event = new ModelRegistryEvent(this, model); } // no else. ((IModelRegistryListener) listeners[index]).modelRemoved(event); } // end for. } // no else. } /** * <p> * A helper method that lazily creates the {@link ListenerList}. * </p> */ private ListenerList getListeners() { if (this.listeners == null) { this.listeners = new ListenerList(ListenerList.IDENTITY); } // no else. return this.listeners; } }