package org.jactr.core.slot; /* * default logging */ import java.util.concurrent.Executor; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.jactr.core.event.ACTREventDispatcher; import org.jactr.core.slot.event.ISlotContainerListener; import org.jactr.core.slot.event.SlotEvent; /** * generic unique slot container that can be listened to * * @author harrison */ public class NotifyingSlotContainer extends UniqueSlotContainer implements INotifyingSlotContainer { /** * Logger definition */ static private final transient Log LOGGER = LogFactory .getLog(NotifyingSlotContainer.class); private ACTREventDispatcher<INotifyingSlotContainer, ISlotContainerListener> _dispatcher = new ACTREventDispatcher<INotifyingSlotContainer, ISlotContainerListener>(); // who do we say is the owner, in case we want to use this as a delegate private INotifyingSlotContainer _delegateContainer; public NotifyingSlotContainer() { super(true); _delegateContainer = this; } /** * if you want to use this class as a delegate for another class, you can * retarget the source of the events to use this container * * @param container */ public void setDelegateContainer(INotifyingSlotContainer container) { _delegateContainer = container; } public void addListener(ISlotContainerListener listener, Executor executor) { _dispatcher.addListener(listener, executor); } public void removeListener(ISlotContainerListener listener) { _dispatcher.removeListener(listener); } public void valueChanged(ISlot slot, Object oldValue, Object newValue) { if (_dispatcher.hasListeners()) _dispatcher.fire(new SlotEvent(_delegateContainer, slot, oldValue)); } @Override protected ISlot createSlot(ISlot slot) { if (_useMutable) return new NotifyingSlot(slot.getName(), slot.getValue(), this); return new BasicSlot(slot.getName(), slot.getValue()); } @Override public void addSlot(ISlot slot) { boolean shouldFire = true; try { shouldFire = getSlot(slot.getName()) == null; } catch (Exception e) { // chunks can throw an exception here } super.addSlot(slot); if (shouldFire && _dispatcher.hasListeners()) _dispatcher.fire(new SlotEvent(_delegateContainer, slot, SlotEvent.Type.ADDED)); } @Override public void removeSlot(ISlot slot) { boolean shouldFire = getSlot(slot.getName()) != null; if (shouldFire) { super.removeSlot(slot); if (_dispatcher.hasListeners()) _dispatcher.fire(new SlotEvent(_delegateContainer, slot, SlotEvent.Type.REMOVED)); } } public void dispose() { clear(); _dispatcher.clear(); } }