blob: 61ac533a8809b9b305402b7f03f4737bd3744efb [file] [log] [blame]
/*******************************************************************************
* 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;
}
}