| /******************************************************************************* |
| * Copyright (c) 2010, 2011 Obeo. |
| * 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: |
| * Obeo - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.mylyn.docs.intent.collab.cdo.adapters; |
| |
| import java.util.Iterator; |
| import java.util.LinkedHashSet; |
| import java.util.Set; |
| |
| import org.eclipse.emf.cdo.common.revision.CDORevisionKey; |
| import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDelta; |
| import org.eclipse.emf.cdo.common.revision.delta.CDORevisionDelta; |
| import org.eclipse.emf.cdo.session.CDOSessionInvalidationEvent; |
| import org.eclipse.emf.ecore.EClass; |
| import org.eclipse.emf.ecore.ENamedElement; |
| import org.eclipse.emf.ecore.EStructuralFeature; |
| import org.eclipse.mylyn.docs.intent.collab.handlers.notification.Notificator; |
| import org.eclipse.mylyn.docs.intent.collab.handlers.notification.RepositoryChangeNotification; |
| import org.eclipse.mylyn.docs.intent.collab.handlers.notification.RepositoryChangeNotificationFactoryHolder; |
| import org.eclipse.net4j.util.event.IEvent; |
| import org.eclipse.net4j.util.event.IListener; |
| |
| /** |
| * Listens for any change that occur on an instance of the given types, an notify the associated |
| * TypeNotificator. |
| * |
| * @author <a href="mailto:alex.lagarde@obeo.fr">Alex Lagarde</a> |
| */ |
| public class CDOTypeListener implements IListener { |
| |
| /** |
| * The type notificator to notify if changes are detected. |
| */ |
| private final Notificator listeningTypeNotificator; |
| |
| /** |
| * List of the types to listen. |
| */ |
| private final Set<EStructuralFeature> listennedTypes; |
| |
| /** |
| * CDOTypeListener constructor. |
| * |
| * @param typeNotificator |
| * The TypeNotificator to notify if changes are detected. |
| * @param types |
| * List of the types to listen |
| */ |
| public CDOTypeListener(Notificator typeNotificator, Set<EStructuralFeature> types) { |
| this.listeningTypeNotificator = typeNotificator; |
| this.listennedTypes = new LinkedHashSet<EStructuralFeature>(); |
| this.listennedTypes.addAll(types); |
| } |
| |
| /** |
| * {@inheritDoc} |
| * |
| * @see org.eclipse.net4j.util.event.IListener#notifyEvent(org.eclipse.net4j.util.event.IEvent) |
| */ |
| public void notifyEvent(IEvent event) { |
| |
| // For each CDOSessionInvalidationEvent sent by the session whenever a "invalidate" message is |
| // received (see CDO documentation). |
| if (event instanceof CDOSessionInvalidationEvent) { |
| CDOSessionInvalidationEvent invalidationEvent = (CDOSessionInvalidationEvent)event; |
| boolean changesDetected = false; |
| |
| // We determine if this event concerns a type it listens. |
| for (CDORevisionKey key : invalidationEvent.getChangedObjects()) { |
| if (changesDetected) { |
| break; |
| } |
| CDORevisionDelta revisionDelta = (CDORevisionDelta)key; |
| |
| for (CDOFeatureDelta delta : revisionDelta.getFeatureDeltas()) { |
| |
| if (isListenedTypeModification(delta.getFeature())) { |
| changesDetected = true; |
| break; |
| } |
| } |
| } |
| |
| // If relevant changes have been detected, we send a notification to the typeNotificator |
| if (changesDetected) { |
| RepositoryChangeNotification newNotification = RepositoryChangeNotificationFactoryHolder |
| .getChangeNotificationFactory().createRepositoryChangeNotification(invalidationEvent); |
| if (newNotification != null) { |
| this.listeningTypeNotificator.notifyHandlers(newNotification); |
| } |
| } |
| |
| } |
| } |
| |
| /** |
| * Returns true if the given feature matches any listened types of this typeListener. |
| * |
| * @param feature |
| * the feature to test. |
| * @return true if the given feature matches any listened types of this typeListener, false otherwise. |
| */ |
| private boolean isListenedTypeModification(EStructuralFeature feature) { |
| boolean isListennedType = false; |
| |
| for (Iterator<EStructuralFeature> iterator = listennedTypes.iterator(); iterator.hasNext() |
| && !isListennedType;) { |
| ENamedElement listennedtype = iterator.next(); |
| if (listennedtype instanceof EStructuralFeature) { |
| isListennedType = listennedtype.equals(feature); |
| } |
| if (listennedtype instanceof EClass) { |
| isListennedType = ((EClass)listennedtype).getEAllStructuralFeatures().contains(feature); |
| } |
| } |
| |
| return isListennedType; |
| } |
| } |