/*******************************************************************************
* Copyright (c) 2005, 2012 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.bpel.ui.util;
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.common.notify.Notifier;
/**
* An adapter which automatically keeps track of the notifiers it has been added to
* (so it may be conveniently removed).
*/
public abstract class MultiObjectAdapter implements Adapter {
// TODO: this was a Set before, I changed it to a List to work around unexpected
// behavior (eAdapter() lists can contain the same adapter more than once).
//
List<Notifier> addedTo = new ArrayList<Notifier>();
/**
* Subclasses must override this.
* @param n Notification
*/
public abstract void notify(Notification n);
/**
* Subclasses may override this (e.g. to add other adapters)
* @param target the target
*/
public void addedTo(Object target) { }
/**
* Subclasses may override this (e.g. to remove other adapters)
* @param target removed from target
*/
public void removedFrom(Object target) { }
/**
* Subclasses may use this helper to add themselves as a listener to a target object.
* addToObject() only adds this adapter if it has not already been added to target.
*
* @param target
*/
public void addToObject (Notifier target) {
if (addedTo.contains(target)) {
return ;
}
target.eAdapters().add(this);
}
static Notifier [] EMPTY = {};
/**
* Removes this adapter from all notifiers it has been added to.
*/
public final void removeFromAll() {
for(Notifier n : addedTo.toArray( EMPTY )) {
n.eAdapters().remove(this);
}
if (addedTo.isEmpty() == false) {
throw new IllegalStateException();
}
}
/* Adapter */
// this is meant for implementation use (i.e. BatchedMultiObjectAdapter).
// if you override in a subclass, call the super implementation.
protected void doNotify(Notification n) {
notify(n);
}
/** (non-Javadoc)
* @see org.eclipse.emf.common.notify.Adapter#notifyChanged(org.eclipse.emf.common.notify.Notification)
*/
public final void notifyChanged (Notification n) {
if (n == null) {
throw new IllegalStateException();
}
if (n.getEventType() == Notification.REMOVING_ADAPTER) {
Object notifier = n.getNotifier();
addedTo.remove(notifier);
removedFrom(notifier);
} else {
doNotify(n);
}
}
/**
* @see org.eclipse.emf.common.notify.Adapter#isAdapterForType(java.lang.Object)
*/
public final boolean isAdapterForType (Object type) {
return false;
}
/**
* @see org.eclipse.emf.common.notify.Adapter#getTarget()
*/
public final Notifier getTarget() {
return null;
}
/**
* @see org.eclipse.emf.common.notify.Adapter#setTarget(org.eclipse.emf.common.notify.Notifier)
*/
public final void setTarget(Notifier newTarget) {
addedTo.add(newTarget); // <--- hack
addedTo(newTarget);
}
}