package za.org.coefficient.events;
import java.util.*;
import java.util.HashMap;
import java.util.Map;
import org.apache.log4j.Logger;
/**
* Class: EventHandlerRegistry
* Description: EventHandlerRegistry maintains a registry of event handlers. It is used to determine which
* handlers should receive event notifications.
* NOTE: This class is implemented using the singleton patttern, which doesn't really work too well in a
* distributed EJB environment. It is assumed, therefore, that the app is not running in a clustered
* environment - i.e. this is a singleton for the entire app. Alternative approaches include storing this stuff in the
* database, and reading from there, or using an external RMI interface via JNDI.
* @author tfogwill
*/
public class EventHandlerRegistry {
/**
* Logger
*/
private static final Logger log = org.apache.log4j.Logger.getLogger(EventHandlerRegistry.class);
/**
* Singleton instance
*/
private static EventHandlerRegistry instance;
/**
* Map to hold the registry data
*/
private Map registry = new HashMap();
/**
* Private constructor to prevent instantiation.
*/
private EventHandlerRegistry(){}
/**
* Get the singleton instance
* @return the EventHandlerRegistry instance
*/
public static EventHandlerRegistry getInstance(){
if (instance == null) instance = new EventHandlerRegistry();
return instance;
}
/**
* Get the handlers for the spercified event type
* @param eventType The event type
* @return the appropriate handlers
*/
public synchronized CoefficientEventHandler[] getHandlers(String eventType){
try {
return getHandlers(Class.forName(eventType));
} catch (ClassNotFoundException e) {
e.printStackTrace();
return new CoefficientEventHandler[]{};
}
}
/**
* Get the handlers for the spercified event type
* @param eventType The event type
* @return the appropriate handlers
*/
public synchronized CoefficientEventHandler[] getHandlers(Class eventType){
log.info("REGISTRY: getting handlers for class " + eventType.getName());
Set handlers = new HashSet();
Object obj = registry.get(eventType);
if (obj != null && obj instanceof List) handlers.addAll((List)obj);
Class cls = eventType;
while (!Object.class.equals(cls)){
obj = registry.get(cls);
if (obj != null && obj instanceof List) handlers.addAll((List)obj);
cls = cls.getSuperclass();
}
log.info("REGISTRY: found " + handlers.size() + " handlers for class " + eventType.getName());
log.debug("REGISTRY: Handlers for " + eventType.getName() + ":");
for (Iterator iter = handlers.iterator(); iter.hasNext();) {
CoefficientEventHandler h = (CoefficientEventHandler) iter.next();
log.debug("\t" + h.getClass().getName() + " : " + h);
}
return (CoefficientEventHandler[]) handlers.toArray(new CoefficientEventHandler[handlers.size()]);
}
/**
* Register a handler with the registry. This will cause it to be notified when an event occurs
* that matches the specified event type. Matching is done down the class hierarchy, so a handler will
* be notified if events occur that are subclasses of the type it's registered to handle.
* @param eventType The base event type(class) to receive notifications about
* @param handler The handler which will be notified.
*/
public synchronized void registerEventHandler(Class eventType, CoefficientEventHandler handler){
if (eventType == null || handler == null) return;
List handlers = (List) registry.get(eventType);
if (handlers == null){
handlers = new ArrayList();
registry.put(eventType, handlers);
}
handlers.add(handler);
}
}
|