001 package de.deepamehta.core.impl; 002 003 import de.deepamehta.core.service.Listener; 004 005 import javax.ws.rs.WebApplicationException; 006 007 import java.util.ArrayList; 008 import java.util.HashMap; 009 import java.util.List; 010 import java.util.Map; 011 012 013 014 class EventManager { 015 016 // ---------------------------------------------------------------------------------------------- Instance Variables 017 018 /** 019 * The registered listeners, hashed by event name (name of CoreEvent enum constant, e.g. "POST_CREATE_TOPIC"). 020 */ 021 private Map<String, List<Listener>> listenerRegistry = new HashMap(); 022 023 // ----------------------------------------------------------------------------------------- Package Private Methods 024 025 void addListener(CoreEvent event, Listener listener) { 026 List<Listener> listeners = getListeners(event); 027 if (listeners == null) { 028 listeners = new ArrayList(); 029 putListeners(event, listeners); 030 } 031 listeners.add(listener); 032 } 033 034 void removeListener(CoreEvent event, Listener listener) { 035 List<Listener> listeners = getListeners(event); 036 if (!listeners.remove(listener)) { 037 throw new RuntimeException("Removing " + listener + " from " + 038 event + " listeners failed: not found in " + listeners); 039 } 040 } 041 042 // --- 043 044 void fireEvent(CoreEvent event, Object... params) { 045 List<Listener> listeners = getListeners(event); 046 if (listeners != null) { 047 // ### FIXME: ConcurrentModificationException might occur. Still true? 048 for (Listener listener : listeners) { 049 deliverEvent(listener, event, params); 050 } 051 } 052 } 053 054 void deliverEvent(Listener listener, CoreEvent event, Object... params) { 055 try { 056 event.deliver(listener, params); 057 } catch (WebApplicationException e) { 058 // Note: a WebApplicationException thrown by a event listener must reach Jersey. So we re-throw here. 059 // This allow plugins to produce specific HTTP responses by throwing a WebApplicationException. 060 // Consider the Caching plugin: it produces a possible 304 (Not Modified) response this way. 061 throw e; 062 } catch (Exception e) { 063 throw new RuntimeException("Processing event " + event + " by " + listener + " failed", e); 064 } 065 } 066 067 // ------------------------------------------------------------------------------------------------- Private Methods 068 069 private List<Listener> getListeners(CoreEvent event) { 070 return listenerRegistry.get(event.name()); 071 } 072 073 private void putListeners(CoreEvent event, List<Listener> listeners) { 074 listenerRegistry.put(event.name(), listeners); 075 } 076 }