package pl.net.bluesoft.util.eventbus.listenables; import pl.net.bluesoft.util.eventbus.EventListener; import pl.net.bluesoft.util.lang.Collections; import pl.net.bluesoft.util.lang.Transformer; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashSet; import java.util.Set; /** * @author: amichalak@bluesoft.net.pl */ public class ListenableSupport<L extends EventListener> implements Listenable<L> { protected final Set<ListenerReference<L>> listeners = new LinkedHashSet<ListenerReference<L>>(); protected final ListenableStrategy<L> listenableStrategy; public ListenableSupport() { this(null); } public ListenableSupport(ListenableStrategy<L> listenableStrategy) { this.listenableStrategy = listenableStrategy != null ? listenableStrategy : ListenableStrategy.<L>weakListenableStrategy(); } public static <L extends EventListener> ListenableSupport<L> weakListenable() { return new ListenableSupport<L>(ListenableStrategy.<L>weakListenableStrategy()); } public static <L extends EventListener> ListenableSupport<L> strongListenable() { return new ListenableSupport<L>(ListenableStrategy.<L>strongListenableStrategy()); } protected void checkReferences(L listener) { for (Iterator<ListenerReference<L>> it = listeners.iterator(); it.hasNext(); ) { ListenerReference<L> ref = it.next(); if (!ref.hasReference() || (listener != null && ref.hasReference(listener))) { it.remove(); } } } @Override public void addListener(L listener) { checkReferences(listener); listeners.add(listenableStrategy.create(listener)); } @Override public void removeListener(L listener) { checkReferences(listener); } public boolean containsListener(L listener) { return getListeners().contains(listener); } public Set<L> getListeners() { return java.util.Collections.unmodifiableSet(Collections.collect(listeners, new Transformer<ListenerReference<L>, L>() { @Override public L transform(ListenerReference<L> ref) { return ref.hasReference() ? ref.getListener() : null; } }, new HashSet<L>())); } public void fireEvent(Object event) { if (event != null) { for (Iterator<ListenerReference<L>> it = listeners.iterator(); it.hasNext(); ) { ListenerReference<L> ref = it.next(); if (ref.hasReference()) { ref.onEvent(event); } else { it.remove(); } } } } public boolean hasListeners() { return !listeners.isEmpty(); } }