package hep.aida.ref.event;
import java.util.ArrayList;
import java.util.EventObject;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* A basic implementation of isObservable.
* Although this class implements all the methods of IsObservable, it does
* not explicitly implement the IsObservable interface. This is so that
* ManagedObject can extend AIDAObservable, although not all ManagedObjects
* implement IsObservable.
*
* @author tonyj
* @version $Id: AIDAObservable.java 8584 2006-08-10 23:06:37Z duns $
*/
public abstract class AIDAObservable
{
private List listeners;
private Map hash;
protected boolean isConnected = true;
protected boolean connectionDidChange = false;
private ConnectEvent connectEvent = new ConnectEvent(this, true);
protected boolean isValid = false;
private boolean isValidAfterNotify = false;
private EventObject theEvent;
protected AIDAObservable()
{
}
protected void setIsValidAfterNotify(boolean value)
{
isValidAfterNotify = value;
}
public synchronized void addListener(AIDAListener l)
{
if (listeners == null) listeners = new ArrayList();
listeners.add(l);
if (theEvent == null) theEvent = createEvent();
if (hash == null) hash = new HashMap();
hash.put(l, new Boolean(true));
isValid = true;
}
public synchronized void removeListener(AIDAListener l)
{
if (listeners != null) listeners.remove(l);
if (listeners != null) hash.remove(l);
if (listeners.isEmpty()) isValid = false;
}
public synchronized void removeAllListeners()
{
if (listeners != null) listeners.clear();
if (hash != null) hash.clear();
isValid = false;
}
public void setValid(AIDAListener l) {
boolean fireConnectionEvent = false;
synchronized (this) {
if (connectionDidChange) {
fireConnectionEvent = true;
connectionDidChange = false;
}
if (listeners != null) {
hash.put(l, new Boolean(true));
isValid = true;
}
}
if (fireConnectionEvent) fireStateChanged(connectEvent, false);
}
public void setValidForAll() {
boolean fireConnectionEvent = false;
synchronized (this) {
if (connectionDidChange) {
fireConnectionEvent = true;
connectionDidChange = false;
}
if (listeners != null) {
for (int i = listeners.size(); i-->0; ) {
AIDAListener l = (AIDAListener) listeners.get(i);
hash.put(l, new Boolean(true));
}
isValid = true;
}
}
if (fireConnectionEvent) fireStateChanged(connectEvent, false);
}
protected EventObject createEvent()
{
return new EventObject(this);
}
public void setConnected(boolean isConnected) {
boolean fireConnectionEvent = false;
synchronized (this) {
//if (this.isConnected == isConnected) return;
this.isConnected = isConnected;
connectEvent.setConnected(isConnected);
if (isValid) {
fireConnectionEvent = true;
connectionDidChange = false;
} else {
connectionDidChange = true;
}
}
if (fireConnectionEvent) fireStateChanged(connectEvent, false);
}
public boolean isConnected() {return isConnected; }
/**
* Method to be used by subclass that only fire a single event (theEvent)
*/
protected void fireStateChanged()
{
fireStateChanged(theEvent);
}
protected synchronized void fireStateChanged(EventObject event)
{
fireStateChanged(event, true);
}
protected synchronized void fireStateChanged(EventObject event, boolean checkValid)
{
isValid = isValidAfterNotify;
if (listeners != null)
{
for (int i = listeners.size(); i-->0; )
{
AIDAListener l = (AIDAListener) listeners.get(i);
boolean listenerValid = ((Boolean) hash.get(l)).booleanValue();
if (!checkValid) {
l.stateChanged(event);
} else if (listenerValid) {
l.stateChanged(event);
hash.put(l, new Boolean(isValidAfterNotify));
}
}
}
}
}