package org.jboss.mx.notification;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.NoSuchElementException;
import javax.management.JMException;
import javax.management.ListenerNotFoundException;
import javax.management.NotificationFilter;
import javax.management.NotificationListener;
public class ListenerRegistry
{
private HashMap listeners = new HashMap();
private ListenerRegistrationFactory factory;
public ListenerRegistry()
{
this(null);
}
public ListenerRegistry(ListenerRegistrationFactory factory)
{
if (factory == null)
this.factory = new DefaultListenerRegistrationFactory();
else
this.factory = factory;
}
public void add(NotificationListener listener, NotificationFilter filter, Object handback)
throws JMException
{
if (listener == null)
throw new IllegalArgumentException("Null listener");
synchronized(listeners)
{
HashMap newListeners = (HashMap) listeners.clone();
ArrayList registrations = (ArrayList) newListeners.get(listener);
if (registrations == null)
{
registrations = new ArrayList();
newListeners.put(listener, registrations);
}
else
{
registrations = (ArrayList) registrations.clone();
newListeners.put(listener, registrations);
}
registrations.add(factory.create(listener, filter, handback));
listeners = newListeners;
}
}
public void remove(NotificationListener listener)
throws ListenerNotFoundException
{
ArrayList registrations = null;
synchronized(listeners)
{
if (listeners.containsKey(listener) == false)
throw new ListenerNotFoundException("Listener not found " + listener);
HashMap newListeners = (HashMap) listeners.clone();
registrations = (ArrayList) newListeners.remove(listener);
listeners = newListeners;
}
for (Iterator iterator = registrations.iterator(); iterator.hasNext();)
{
ListenerRegistration registration = (ListenerRegistration) iterator.next();
registration.removed();
}
}
public void remove(NotificationListener listener, NotificationFilter filter, Object handback)
throws ListenerNotFoundException
{
ListenerRegistration registration = null;
synchronized(listeners)
{
ArrayList registrations = (ArrayList) listeners.get(listener);
if (registrations == null)
throw new ListenerNotFoundException("No registristrations for listener not listener=" + listener +
" filter=" + filter + " handback=" + handback);
registration = new DefaultListenerRegistration(listener, filter, handback);
int index = registrations.indexOf(registration);
if (index == -1)
throw new ListenerNotFoundException("Listener not found listener=" + listener +
" filter=" + filter + " handback=" + handback);
HashMap newListeners = (HashMap) listeners.clone();
registrations = (ArrayList) registrations.clone();
registration = (ListenerRegistration) registrations.remove(index);
if (registrations.isEmpty())
newListeners.remove(listener);
else
newListeners.put(listener, registrations);
listeners = newListeners;
}
registration.removed();
}
public void removeAll()
{
synchronized (listeners)
{
listeners.clear();
}
}
public ListenerRegistrationIterator iterator()
{
return new ListenerRegistrationIterator();
}
public boolean isEmpty()
{
return listeners.isEmpty();
}
public class ListenerRegistrationIterator
implements Iterator
{
private Iterator listenerIterator;
private Iterator registrationIterator;
public ListenerRegistrationIterator()
{
listenerIterator = listeners.values().iterator();
}
public boolean hasNext()
{
if (registrationIterator == null || registrationIterator.hasNext() == false)
{
do
{
if (listenerIterator.hasNext() == false)
return false;
registrationIterator = ((ArrayList) listenerIterator.next()).iterator();
}
while (registrationIterator.hasNext() == false);
}
return true;
}
public Object next()
{
if (hasNext() == false)
throw new NoSuchElementException("Use hasNext before next");
return registrationIterator.next();
}
public ListenerRegistration nextRegistration()
{
return (ListenerRegistration) next();
}
public void remove()
{
throw new UnsupportedOperationException("remove is not supported");
}
}
}