001: package za.org.coefficient.events;
002:
003: import java.util.*;
004: import java.util.HashMap;
005: import java.util.Map;
006:
007: import org.apache.log4j.Logger;
008:
009: /**
010: * Class: EventHandlerRegistry
011: * Description: EventHandlerRegistry maintains a registry of event handlers. It is used to determine which
012: * handlers should receive event notifications.
013: * NOTE: This class is implemented using the singleton patttern, which doesn't really work too well in a
014: * distributed EJB environment. It is assumed, therefore, that the app is not running in a clustered
015: * environment - i.e. this is a singleton for the entire app. Alternative approaches include storing this stuff in the
016: * database, and reading from there, or using an external RMI interface via JNDI.
017: * @author tfogwill
018: */
019: public class EventHandlerRegistry {
020:
021: /**
022: * Logger
023: */
024: private static final Logger log = org.apache.log4j.Logger
025: .getLogger(EventHandlerRegistry.class);
026:
027: /**
028: * Singleton instance
029: */
030: private static EventHandlerRegistry instance;
031:
032: /**
033: * Map to hold the registry data
034: */
035: private Map registry = new HashMap();
036:
037: /**
038: * Private constructor to prevent instantiation.
039: */
040: private EventHandlerRegistry() {
041: }
042:
043: /**
044: * Get the singleton instance
045: * @return the EventHandlerRegistry instance
046: */
047: public static EventHandlerRegistry getInstance() {
048: if (instance == null)
049: instance = new EventHandlerRegistry();
050: return instance;
051: }
052:
053: /**
054: * Get the handlers for the spercified event type
055: * @param eventType The event type
056: * @return the appropriate handlers
057: */
058: public synchronized CoefficientEventHandler[] getHandlers(
059: String eventType) {
060: try {
061: return getHandlers(Class.forName(eventType));
062: } catch (ClassNotFoundException e) {
063: e.printStackTrace();
064: return new CoefficientEventHandler[] {};
065: }
066: }
067:
068: /**
069: * Get the handlers for the spercified event type
070: * @param eventType The event type
071: * @return the appropriate handlers
072: */
073: public synchronized CoefficientEventHandler[] getHandlers(
074: Class eventType) {
075: log.info("REGISTRY: getting handlers for class "
076: + eventType.getName());
077: Set handlers = new HashSet();
078: Object obj = registry.get(eventType);
079: if (obj != null && obj instanceof List)
080: handlers.addAll((List) obj);
081: Class cls = eventType;
082: while (!Object.class.equals(cls)) {
083: obj = registry.get(cls);
084: if (obj != null && obj instanceof List)
085: handlers.addAll((List) obj);
086: cls = cls.getSuperclass();
087: }
088: log.info("REGISTRY: found " + handlers.size()
089: + " handlers for class " + eventType.getName());
090: log
091: .debug("REGISTRY: Handlers for " + eventType.getName()
092: + ":");
093: for (Iterator iter = handlers.iterator(); iter.hasNext();) {
094: CoefficientEventHandler h = (CoefficientEventHandler) iter
095: .next();
096: log.debug("\t" + h.getClass().getName() + " : " + h);
097: }
098: return (CoefficientEventHandler[]) handlers
099: .toArray(new CoefficientEventHandler[handlers.size()]);
100: }
101:
102: /**
103: * Register a handler with the registry. This will cause it to be notified when an event occurs
104: * that matches the specified event type. Matching is done down the class hierarchy, so a handler will
105: * be notified if events occur that are subclasses of the type it's registered to handle.
106: * @param eventType The base event type(class) to receive notifications about
107: * @param handler The handler which will be notified.
108: */
109: public synchronized void registerEventHandler(Class eventType,
110: CoefficientEventHandler handler) {
111: if (eventType == null || handler == null)
112: return;
113: List handlers = (List) registry.get(eventType);
114: if (handlers == null) {
115: handlers = new ArrayList();
116: registry.put(eventType, handlers);
117: }
118: handlers.add(handler);
119: }
120:
121: }
|