| /******************************************************************************* |
| * Copyright (c) 2013 CEA LIST. |
| * 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: |
| * Cedric Dumoulin - cedric.dumoulin@lifl.fr |
| ******************************************************************************/ |
| package org.eclipse.papyrus.internal.infra.gmfdiag.layers.runtime; |
| |
| import static org.eclipse.papyrus.internal.infra.gmfdiag.layers.runtime.Activator.log; |
| |
| import java.util.ArrayList; |
| import java.util.List; |
| |
| import org.eclipse.emf.common.notify.Adapter; |
| import org.eclipse.emf.common.notify.Notification; |
| import org.eclipse.emf.ecore.EObject; |
| import org.eclipse.emf.ecore.util.EContentAdapter; |
| import org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.NotFoundException; |
| import org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.AbstractLayer; |
| import org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.LayersPackage; |
| import org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.LayersStack; |
| import org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.TypeInstance; |
| import org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.impl.StringToTypeInstanceMapImpl; |
| import org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.util.ECoreUtils; |
| |
| /** |
| * This class listen to a {@link LayersStack} and send event to listeners. |
| * |
| * @author cedric dumoulin |
| * |
| */ |
| public class LayersModelEventNotifier { |
| |
| /** |
| * The observed {@link LayersStack}. |
| */ |
| protected LayersStack layersStack; |
| |
| /** |
| * List of listener to notify. |
| */ |
| protected List<ILayersModelEventListener> listeners = new ArrayList<ILayersModelEventListener>(); |
| |
| /** |
| * listener on layers changes. |
| * |
| */ |
| protected Adapter layersListener = new EContentAdapter() { |
| |
| @Override |
| public void notifyChanged(Notification notification) { |
| if (log.isDebugEnabled()) { |
| log.debug(this.getClass().getSimpleName() + ".event received " + notification.getFeature()); |
| } |
| |
| // Self atttach |
| super.notifyChanged(notification); |
| |
| // Check layers modification |
| // There is two sources: LayerOperator::layers and LayersStack::layers |
| if (notification.getFeature() == LayersPackage.eINSTANCE.getLayerOperator_Layers() |
| || notification.getFeature() == LayersPackage.eINSTANCE.getLayersStack_Layers()) { |
| // LayerOperator::layers || LayersStack::layers |
| // check the event type. |
| switch (notification.getEventType()) { |
| case Notification.SET: |
| fireLayerSet(notification); |
| break; |
| case Notification.ADD: |
| // A layer is added |
| fireLayerAdded(notification); |
| break; |
| case Notification.REMOVE: |
| // A layer is removed |
| fireLayerRemoved(notification); |
| break; |
| case Notification.MOVE: |
| // A layer is moved |
| fireLayerMoved(notification); |
| break; |
| } |
| } |
| // Check view event |
| // View event can by fired by: AbstractLayer::views |
| else if (notification.getFeature() == LayersPackage.eINSTANCE.getAbstractLayer_Views()) { |
| |
| // check the event type. |
| switch (notification.getEventType()) { |
| case Notification.ADD: |
| // A layer is added |
| // the concerned view |
| // View view = (View)notification.getNewValue(); |
| // AbstractLayer layer = (AbstractLayer)notification.getNotifier() |
| |
| fireViewAddedToLayer(notification); |
| break; |
| case Notification.ADD_MANY: |
| // A layer is added |
| // the concerned view |
| // View view = (View)notification.getNewValue(); |
| // AbstractLayer layer = (AbstractLayer)notification.getNotifier() |
| |
| fireMultiViewsAddedToLayer(notification); |
| break; |
| case Notification.REMOVE: |
| // A layer is removed |
| // the concerned view |
| // View view = (View)notification.getOldValue(); |
| // AbstractLayer layer = (AbstractLayer)notification.getNotifier() |
| |
| fireViewRemovedFromLayer(notification); |
| break; |
| case Notification.REMOVE_MANY: |
| // A layer is removed |
| // the concerned view |
| // View view = (View)notification.getOldValue(); |
| // AbstractLayer layer = (AbstractLayer)notification.getNotifier() |
| |
| fireMultiViewsRemovedFromLayer(notification); |
| break; |
| } |
| |
| } |
| // Check instance addition/deletion |
| // instance event can by fired by: AbstractLayer::propertyValuesMap |
| else if (notification.getFeature() == LayersPackage.eINSTANCE.getAbstractLayer_PropertyValueMap()) { |
| // check the event type. |
| switch (notification.getEventType()) { |
| // case Notification.SET: |
| // { |
| // // A key is added |
| // break; |
| // } |
| // case Notification.UNSET: |
| // // A key is added |
| // break; |
| case Notification.ADD: { |
| // An entry is added |
| StringToTypeInstanceMapImpl entry = (StringToTypeInstanceMapImpl) notification.getNewValue(); |
| // System.out.println("ADD" + entry.getValue() |
| // + ", key=" + entry.getKey()); |
| // Add the corresponding instance to propertyValues |
| // Layer layer = (Layer)notification.getNotifier(); |
| // String propertyName = entry.getKey(); |
| // TypeInstance propertyValue = (TypeInstance)entry.getValue(); |
| firePropertyValueAddedEvent(notification); |
| break; |
| } |
| case Notification.REMOVE: { |
| // An entry is removed |
| StringToTypeInstanceMapImpl entry = (StringToTypeInstanceMapImpl) notification.getOldValue(); |
| // System.out.println("REMOVE" + entry.getValue() |
| // + ", key=" + entry.getKey()); |
| // Add the corresponding instance to propertyValues |
| // Layer layer = (Layer)notification.getNotifier(); |
| // String propertyName = entry.getKey(); |
| // TypeInstance propertyValue = (TypeInstance)entry.getValue(); |
| firePropertyValueRemoved(notification); |
| break; |
| } |
| default: |
| break; |
| } |
| |
| } |
| // Check if the isLayerEnabled is modified |
| // sources: LayerExpression::IsLayerEnabled |
| else if (notification.getFeature() == LayersPackage.eINSTANCE.getLayerExpression_IsLayerEnabled()) { |
| firePropertyValueChanged(notification); |
| } |
| |
| // Check property instance modification event |
| // instance change event can by fired by: any modification in a subclass of TypeInstance |
| else { |
| try { |
| // Lookup if the event comes from a type instance |
| TypeInstance ancestor = (TypeInstance) ECoreUtils.lookupAncestorOfType((EObject) notification.getNotifier(), LayersPackage.eINSTANCE.getTypeInstance()); |
| // originating layer |
| AbstractLayer layer = (AbstractLayer) ECoreUtils.lookupAncestorOfType((EObject) notification.getNotifier(), LayersPackage.eINSTANCE.getAbstractLayer()); |
| // or: layer = (AbstractLayer)ancestor.eContainer().eContainer().eContainer(); |
| // StringToTypeInstanceMapImpl entry = (StringToTypeInstanceMapImpl)ancestor.eContainer(); |
| // String propertyName = entry.getKey(); |
| // TypeInstance propertyValue = (TypeInstance)entry.getValue(); |
| // |
| // String propertyName |
| // check the event type. |
| switch (notification.getEventType()) { |
| case Notification.SET: |
| // An instance value is set |
| firePropertyValueChanged(notification); |
| break; |
| case Notification.ADD: |
| // An instance value is set |
| firePropertyValueChanged(notification); |
| break; |
| case Notification.REMOVE: |
| // An instance value is set |
| firePropertyValueChanged(notification); |
| break; |
| } |
| } catch (NotFoundException e) { |
| // lookupAncestorOfType() found nothing |
| // silently fail |
| } |
| |
| |
| |
| } |
| |
| } |
| }; |
| |
| /** |
| * Constructor. |
| * |
| * @param layersStack |
| * The observed {@link LayersStack}. |
| */ |
| public LayersModelEventNotifier(LayersStack layersStack) { |
| this.layersStack = layersStack; |
| activate(); |
| } |
| |
| /** |
| * |
| * @return the listeners |
| */ |
| public List<ILayersModelEventListener> getListeners() { |
| return listeners; |
| } |
| |
| /** |
| * setup the listeners. |
| */ |
| protected void activate() { |
| layersStack.eAdapters().add(layersListener); |
| |
| } |
| |
| /** |
| * remove the listeners. |
| */ |
| protected void deactivate() { |
| layersStack.eAdapters().remove(layersListener); |
| |
| } |
| |
| /** |
| * Dispose this object. |
| */ |
| public void dispose() { |
| |
| deactivate(); |
| listeners.clear(); |
| layersListener = null; |
| } |
| |
| /** |
| * Return true if the object is disposed. |
| * |
| * @return |
| */ |
| public boolean isDisposed() { |
| return layersListener == null; |
| } |
| |
| /** |
| * Add the specified listener to the list of listener. |
| * Do not add it if the listener is already in the list. |
| * |
| * @param listener |
| */ |
| public void addLayersModelEventListener(ILayersModelEventListener listener) { |
| |
| if (listener == null) { |
| return; |
| } |
| |
| // Check if exist |
| if (listeners.contains(listener)) { |
| return; |
| } |
| |
| listeners.add(listener); |
| } |
| |
| /** |
| * Remove the specified listener from the list of listeners. |
| * |
| * @param listener |
| */ |
| public void removeLayersModelEventListener(ILayersModelEventListener listener) { |
| |
| listeners.remove(listener); |
| } |
| |
| /** |
| * Method called when a value is added to one layer. |
| * The vent contains: the layer, the property name, the new value. |
| * |
| * @param notification |
| */ |
| public void firePropertyValueAddedEvent(Notification notification) { |
| |
| for (ILayersModelEventListener listener : listeners) { |
| listener.propertyValueAdded(notification); |
| } |
| } |
| |
| /** |
| * Method called when a value is removed from one layer. |
| * The vent contains: the layer, the property name, the new value. |
| * |
| * @param notification |
| */ |
| public void firePropertyValueRemoved(Notification notification) { |
| |
| for (ILayersModelEventListener listener : listeners) { |
| listener.propertyValueRemoved(notification); |
| } |
| } |
| |
| /** |
| * Method called when a value is changed in one layer. |
| * The vent contains: the layer, the property name, the new value. |
| * |
| * @param notification |
| */ |
| public void firePropertyValueChanged(Notification notification) { |
| |
| for (ILayersModelEventListener listener : listeners) { |
| listener.propertyValueChanged(notification); |
| } |
| } |
| |
| /** |
| * Method called when a layer is added to one layer. |
| * The event contains: the layer. |
| * |
| * @param notification |
| */ |
| public void fireLayerSet(Notification notification) { |
| |
| for (ILayersModelEventListener listener : listeners) { |
| listener.layerSet(notification); |
| } |
| } |
| |
| /** |
| * Method called when a layer is added to one layer. |
| * The event contains: the layer. |
| * |
| * @param notification |
| */ |
| public void fireLayerAdded(Notification notification) { |
| |
| for (ILayersModelEventListener listener : listeners) { |
| listener.layerAdded(notification); |
| } |
| } |
| |
| /** |
| * Method called when a layer is removed from one layer. |
| * The event contains: the layer. |
| * |
| * @param notification |
| */ |
| public void fireLayerRemoved(Notification notification) { |
| |
| for (ILayersModelEventListener listener : listeners) { |
| listener.layerRemoved(notification); |
| } |
| } |
| |
| /** |
| * Method called when a layer is moved in LayerStack. |
| * The event contains: the layer. |
| * |
| * @param notification |
| */ |
| public void fireLayerMoved(Notification notification) { |
| |
| for (ILayersModelEventListener listener : listeners) { |
| listener.layerMoved(notification); |
| } |
| } |
| |
| |
| /** |
| * Method called when a view is added to one layer. |
| * The event contains: the layer, the view. |
| * |
| * @param notification |
| */ |
| public void fireViewAddedToLayer(Notification notification) { |
| |
| for (ILayersModelEventListener listener : listeners) { |
| listener.viewAddedToLayer(notification); |
| } |
| } |
| |
| /** |
| * Method called when a view is added to one layer. |
| * The event contains: the layer, the view. |
| * |
| * @param notification |
| */ |
| public void fireMultiViewsAddedToLayer(Notification notification) { |
| |
| for (ILayersModelEventListener listener : listeners) { |
| listener.multiViewsAddedToLayer(notification); |
| } |
| } |
| |
| /** |
| * Method called when a view is removed from one layer. |
| * The event contains: the layer, the view. |
| * |
| * @param notification |
| */ |
| public void fireViewRemovedFromLayer(Notification notification) { |
| |
| for (ILayersModelEventListener listener : listeners) { |
| listener.viewRemovedFromLayer(notification); |
| } |
| } |
| |
| /** |
| * Method called when a view is removed from one layer. |
| * The event contains: the layer, the view. |
| * |
| * @param notification |
| */ |
| public void fireMultiViewsRemovedFromLayer(Notification notification) { |
| |
| for (ILayersModelEventListener listener : listeners) { |
| listener.multiViewsRemovedFromLayer(notification); |
| } |
| } |
| |
| /** |
| * Method called when a view is moved from one layer to another layer. |
| * The event contains: the layer, the view. |
| * |
| * @param notification |
| */ |
| public void fireViewMovedBetweenLayer(Notification notification) { |
| |
| for (ILayersModelEventListener listener : listeners) { |
| listener.viewMovedBetweenLayer(notification); |
| } |
| } |
| |
| } |