package org.jactr.eclipse.execution.internal;
/*
* default logging
*/
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.concurrent.Executor;
public class GeneralEventManager<L, E>
{
private final INotifier<L, E> _notifier;
private Collection<Pair> _listeners;
private ThreadLocal<Collection<Pair>> _recycledContainer;
public GeneralEventManager(INotifier<L, E> notifier)
{
if (notifier == null)
throw new NullPointerException("INotifier cannot be null");
_notifier = notifier;
_recycledContainer = new ThreadLocal<Collection<Pair>>();
}
synchronized public boolean hasListeners()
{
return _listeners != null && _listeners.size() > 0;
}
synchronized public void clear()
{
if (_listeners != null) _listeners.clear();
_listeners = null;
_recycledContainer.remove();
}
public void addListener(L listener)
{
addListener(listener, null);
}
synchronized public void addListener(L listener, Executor executor)
{
if (_listeners == null) _listeners = new ArrayList<Pair>();
_listeners.add(new Pair(listener, executor));
}
synchronized public void removeListener(L listener)
{
Iterator<Pair> itr = _listeners.iterator();
while (itr.hasNext())
{
Pair pair = itr.next();
if (pair._listener == listener)
{
itr.remove();
break;
}
}
}
private Collection<Pair> getListenerPairs()
{
Collection<Pair> container = _recycledContainer.get();
if (container == null)
{
container = new ArrayList<Pair>();
_recycledContainer.set(container);
}
synchronized (this)
{
if (_listeners != null) container.addAll(_listeners);
}
return container;
}
public void notify(final E event)
{
for (Pair pair : getListenerPairs())
{
Executor executor = pair._executor;
final L listener = pair._listener;
if (executor == null)
_notifier.notify(listener, event);
else
executor.execute(new Runnable() {
public void run()
{
_notifier.notify(listener, event);
}
});
}
}
static public interface INotifier<L, E>
{
public void notify(L listener, E event);
}
private class Pair
{
public Executor _executor;
public L _listener;
public Pair(L listener, Executor executor)
{
_listener = listener;
_executor = executor;
}
@Override
public boolean equals(Object o)
{
return _listener.equals(o);
}
@Override
public int hashCode()
{
return _listener.hashCode();
}
}
}