001: /*
002: * This software is OSI Certified Open Source Software.
003: * OSI Certified is a certification mark of the Open Source Initiative. The
004: * license (Mozilla version 1.0) can be read at the MMBase site. See
005: * http://www.MMBase.org/license
006: */
007: package org.mmbase.core.event;
008:
009: import java.util.*;
010: import org.mmbase.util.logging.Logger;
011: import org.mmbase.util.logging.Logging;
012:
013: /**
014: * This is the base class for all event brokers in mmbase. the function of an
015: * event broker is to know about a specific kind of event, as well as a specific
016: * kind of event listener. All events should be derived from the
017: * org.mmbase.core.event.Event class, and all listeners from the
018: * org.mmbase.core.event.EventListener interface.<br/> Allthough event
019: * listeners have to implement the EventListener interface, the actual method
020: * that will be called to pass on the event is not part of this interface, as it
021: * is specific for the kind of event you want to listen for. This is a contract
022: * between the broker implementation and the event listerer interface.<br/>
023: * This class dous most of the work of keeping references to all the listeners
024: * and allowing for adding/removing them. Only a fiew type specific actions are
025: * delegated to the super class.<br/> The EventListener also provides a method
026: * for passing on constraint properties to a event broker. If you want to create
027: * your own event type you can use this feature to accomplish that not all
028: * events of your type are propagated to the listener.
029: *
030: * @author Ernst Bunders
031: * @since MMBase-1.8
032: * @version $Id: EventBroker.java,v 1.4 2008/02/03 17:33:58 nklasens Exp $
033: */
034: public abstract class EventBroker {
035:
036: private static final Logger log = Logging
037: .getLoggerInstance(EventBroker.class);
038:
039: /**
040: * this method should return true if this broker can accept and propagate
041: * events to the listener of this type. There are no fixed criteria for this.
042:
043: * Most implementions do <code>event instanceof <EventListener associated with this broker></code>
044: *
045: * @param listener
046: */
047: public abstract boolean canBrokerForListener(EventListener listener);
048:
049: /**
050: * this method should return true if this event broker can broker for
051: * events of this type. There are no fixed criteria for this.
052: *
053: * Most implementions do <code>event instanceof <EvenType associated with this broker></code>
054: *
055: * @param event
056: */
057: public abstract boolean canBrokerForEvent(Event event);
058:
059: /**
060: * This method has two functions. It must cast both event and listener to
061: * the proper type and invoke the event on the listener. But it must allso
062: * check if the listener has constraint properties set. if so it must use
063: * them to decide if the event should be invoked on this listener.
064: *
065: * @param event
066: * @param listener
067: * @throws ClassCastException
068: */
069: protected abstract void notifyEventListener(Event event,
070: EventListener listener) throws ClassCastException;
071:
072: public abstract boolean addListener(EventListener listener);
073:
074: public abstract void removeListener(EventListener listener);
075:
076: /**
077: * @since MMBase-1.8.5
078: */
079: protected abstract Collection<EventListener> backing();
080:
081: /**
082: * @since MMBase-1.8.5
083: */
084: public Collection<EventListener> getListeners() {
085: return Collections.unmodifiableCollection(backing());
086: }
087:
088: public void notifyForEvent(Event event) {
089: for (EventListener listener : backing()) {
090: assert canBrokerForListener(listener);
091: notifyEventListener(event, listener);
092: }
093: }
094:
095: public String toString() {
096: return "Event Broker";
097: }
098:
099: public boolean equals(Object o) {
100: // we can only have one instance so this will do to prevent adding more instances of an envent broker
101: return o != null && this .getClass().equals(o.getClass());
102: }
103:
104: public int hashCode() {
105: return this.getClass().hashCode();
106: }
107: }
|