blob: f0a61c005eda3f3470a6a225d1b56ca5ad35b5b2 [file] [log] [blame]
/******************************************************************************
* Copyright (c) 2002, 2003 IBM Corporation and others.
* 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:
* IBM Corporation - initial API and implementation
****************************************************************************/
package org.eclipse.gmf.runtime.emf.core.internal.notifications;
import java.util.Collection;
import java.util.Iterator;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.Notifier;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.util.EContentAdapter;
import org.eclipse.gmf.runtime.emf.core.internal.domain.MSLEditingDomain;
import org.eclipse.gmf.runtime.emf.core.internal.resources.MResource;
/**
* This class overrides EMF content adapter class by disabling the automatic
* removal of the content adapter from the object's adapter list when the object
* it self is removed from its container. This is required since the MSL
* requires events on detached objects.
*
* @author rafikj
*/
public class MSLContentAdapter
extends EContentAdapter {
private MSLEditingDomain domain = null;
/**
* Constructor.
*/
public MSLContentAdapter(MSLEditingDomain domain) {
super();
this.domain = domain;
}
/**
* Attaches adapter to notifier.
*/
public void listenToModifications(Notifier notifier) {
if (notifier.eAdapters().contains(this))
return;
addAdapter(notifier);
}
/**
* @see org.eclipse.emf.common.notify.Adapter#notifyChanged(org.eclipse.emf.common.notify.Notification)
*/
public void notifyChanged(Notification notification) {
super.notifyChanged(notification);
Object notifier = notification.getNotifier();
if (notifier instanceof EObject)
domain.getObjectListener().handleEvent(notification);
else if (notifier instanceof Resource)
domain.getResouceListener().handleEvent(notification);
else if (notifier instanceof ResourceSet)
domain.getResouceSetListener().handleEvent(notification);
}
/**
* @see org.eclipse.emf.ecore.util.EContentAdapter#selfAdapt(org.eclipse.emf.common.notify.Notification)
*/
protected void selfAdapt(Notification notification) {
Object notifier = notification.getNotifier();
if (notifier instanceof ResourceSet) {
if (notification.getFeatureID(ResourceSet.class) == ResourceSet.RESOURCE_SET__RESOURCES)
handleContainment(notification);
} else if (notifier instanceof Resource) {
if (notification.getFeatureID(Resource.class) == Resource.RESOURCE__CONTENTS)
handleContainment(notification);
} else if (notifier instanceof EObject) {
Object feature = notification.getFeature();
if (feature instanceof EReference
&& ((EReference) feature).isContainment())
handleContainment(notification);
}
}
/**
* @see org.eclipse.emf.ecore.util.EContentAdapter#handleContainment(org.eclipse.emf.common.notify.Notification)
*/
protected void handleContainment(Notification notification) {
switch (notification.getEventType()) {
case Notification.SET:
case Notification.UNSET: {
Notifier newValue = (Notifier) notification.getNewValue();
if (newValue != null)
addAdapter(newValue);
break;
}
case Notification.ADD: {
Notifier newValue = (Notifier) notification.getNewValue();
if (newValue != null)
addAdapter(newValue);
break;
}
case Notification.ADD_MANY: {
Collection newValues = (Collection) notification.getNewValue();
for (Iterator i = newValues.iterator(); i.hasNext();) {
Notifier newValue = (Notifier) i.next();
addAdapter(newValue);
}
break;
}
}
}
/**
* @see org.eclipse.emf.common.notify.Adapter#setTarget(org.eclipse.emf.common.notify.Notifier)
*/
public void setTarget(Notifier object) {
// do not set "this.target" to "object" as it will cause a memory leak.
Collection contents = getContents(object);
if (contents != null)
for (Iterator i = contents.iterator(); i.hasNext();)
addAdapter((Notifier) i.next());
}
/**
* @see org.eclipse.emf.ecore.util.EContentAdapter#unsetTarget(java.lang.Object)
*/
protected void unsetTarget(Object object) {
this.target = null;
Collection contents = getContents(object);
if (contents != null)
for (Iterator i = contents.iterator(); i.hasNext();)
removeAdapter((Notifier) i.next());
}
/**
* Attaches adapter to notifier.
*/
protected void addAdapter(Notifier notifier) {
MSLContentAdapter foundAdapter = null;
for (Iterator i = notifier.eAdapters().iterator(); (i.hasNext())
&& (foundAdapter == null);) {
Object adapter = i.next();
if (adapter instanceof MSLContentAdapter)
foundAdapter = (MSLContentAdapter) adapter;
}
if (foundAdapter != null)
notifier.eAdapters().remove(foundAdapter);
notifier.eAdapters().add(this);
}
/**
* detaches adapter from notifier.
*/
protected void removeAdapter(Notifier notifier) {
notifier.eAdapters().remove(this);
}
/**
* Gets contents of object.
*/
private static Collection getContents(Object object) {
Collection contents = null;
if (object instanceof EObject) {
EObject eObject = (EObject) object;
Resource resource = eObject.eResource();
if ((resource != null) && (resource instanceof MResource))
contents = ((MResource) resource).getHelper().getContents(
eObject);
else
contents = eObject.eContents();
} else if (object instanceof Resource)
contents = ((Resource) object).getContents();
else if (object instanceof ResourceSet)
contents = ((ResourceSet) object).getResources();
return contents;
}
}