1 10 package org.mmbase.core.event; 11 12 import java.io.IOException ; 13 import java.util.*; 14 import java.net.URL ; 15 16 import org.mmbase.util.*; 17 import org.mmbase.util.logging.Logger; 18 import org.mmbase.util.logging.Logging; 19 import org.mmbase.util.xml.DocumentReader; 20 import org.w3c.dom.Document ; 21 import org.w3c.dom.Element ; 22 import org.xml.sax.SAXException ; 23 24 import edu.emory.mathcs.backport.java.util.concurrent.CopyOnWriteArraySet; 25 26 34 public class EventManager { 35 36 private static final Logger log = Logging.getLoggerInstance(EventManager.class); 37 38 public static final String PUBLIC_ID_EVENTMANAGER = "-//MMBase//DTD eventmanager config 1.0//EN"; 39 public static final String DTD_EVENTMANAGER = "eventmanager_1_0.dtd"; 40 41 42 static { 43 org.mmbase.util.XMLEntityResolver.registerPublicID(PUBLIC_ID_EVENTMANAGER, DTD_EVENTMANAGER, EventManager.class); 44 } 45 46 49 private static final EventManager eventManager = new EventManager(); 50 51 54 private final Set eventBrokers = new CopyOnWriteArraySet(); 55 56 private long numberOfPropagatedEvents = 0; 57 private long duration = 0; 58 59 62 public static EventManager getInstance() { 63 return eventManager; 64 } 65 66 private static AbstractEventBroker findInstance(String className) { 67 if (className == null || "".equals(className)) return null; 68 try { 69 Class aClass = Class.forName(className); 70 return (AbstractEventBroker) aClass.newInstance(); 71 } catch (ClassNotFoundException e) { 72 log.error("could not find class with name " + className, e); 73 } catch (InstantiationException e) { 74 log.error("could not instantiate class with name" + className, e); 75 } catch (IllegalAccessException e) { 76 log.error("the constructor of " + className + " is not accessible", e); 77 } catch (ClassCastException e) { 78 log.error("" + className + " is not a AbstratEventBroker"); 79 } 80 return null; 81 } 82 83 protected ResourceWatcher watcher = new ResourceWatcher() { 84 public void onChange(String w) { 85 configure(w); 86 } 87 }; 88 89 private EventManager() { 90 watcher.add("eventmanager.xml"); 91 watcher.onChange(); 92 watcher.start(); 93 } 94 95 96 protected void configure(String resource) { 97 log.service("Configuring the event manager"); 98 eventBrokers.clear(); 99 Iterator i = ResourceLoader.getConfigurationRoot().getResourceList(resource).iterator(); 100 while (i.hasNext()) { 101 URL url = (URL ) i.next(); 102 try { 103 if (url.openConnection().getDoInput()) { 104 105 Document config = ResourceLoader.getDocument(url, true, EventManager.class); 106 DocumentReader configReader = new DocumentReader(config); 107 108 Iterator e = configReader.getChildElements("eventmanager.brokers", "broker"); 110 while (e.hasNext()) { 111 Element element = (Element ) e.next(); 112 String className = element.getAttribute("class"); 113 AbstractEventBroker broker = (AbstractEventBroker) findInstance(className); 114 if (broker != null) { 115 if (log.isDebugEnabled()) { 116 log.debug("adding event broker: " + broker); 117 } 118 addEventBroker(broker); 119 } 120 } 121 } 122 } catch (SAXException e1) { 123 log.error("Something went wrong configuring the event system (" + url + "): " + e1.getMessage(), e1); 124 } catch (IOException e1) { 125 log.error("something went wrong configuring the event system (" + url + "): " + e1.getMessage(), e1); 126 127 } 128 } 129 if (eventBrokers.size() == 0) { 130 log.fatal("No event brokers could not be found. This means that query-invalidation does not work correctly now. Proceeding anyway."); 131 return; 132 } 133 } 134 138 public void addEventBroker(AbstractEventBroker broker) { 139 if(! eventBrokers.contains(broker)){ 141 if (log.isDebugEnabled()) { 142 log.debug("adding broker " + broker.toString()); 143 } 144 eventBrokers.add(broker); 145 } else { 146 if (log.isDebugEnabled()) { 147 log.debug("broker " + broker.toString() + "was already registered: rejected."); 148 } 149 } 150 } 151 152 156 public void removeEventBroker(AbstractEventBroker broker) { 157 eventBrokers.remove(broker); 158 } 159 160 163 public void addEventListener(EventListener listener) { 164 BrokerIterator i = findBrokers(listener); 165 while (i.hasNext()) { 166 AbstractEventBroker broker = i.nextBroker(); 167 if (broker.addListener(listener)) { 168 if (log.isDebugEnabled()) { 169 log.debug("listener " + listener + " added to broker " + broker ); 170 } 171 } 172 } 173 } 174 175 176 179 public void removeEventListener(EventListener listener) { 180 if (log.isDebugEnabled()) { 181 log.debug("removing listener of type: " + listener.getClass().getName()); 182 } 183 BrokerIterator i = findBrokers(listener); 184 while (i.hasNext()) { 185 i.nextBroker().removeListener(listener); 186 } 187 } 188 189 196 public void propagateEvent(Event event) { 197 if (log.isTraceEnabled()) { 198 log.trace("Propagating events to " + eventBrokers); 199 } 200 long startTime = System.currentTimeMillis(); 201 for (Iterator i = eventBrokers.iterator(); i.hasNext();) { 202 AbstractEventBroker broker = (AbstractEventBroker) i.next(); 203 if (broker.canBrokerForEvent(event)) { 204 broker.notifyForEvent(event); 205 if (log.isDebugEnabled()) { 206 if (log.isTraceEnabled()) { 207 log.trace("event: " + event + " has been accepted by broker " + broker); 208 } else { 209 log.debug("event has been accepted by broker " + broker); 210 } 211 } 212 } else { 213 if (log.isDebugEnabled()) { 214 if (log.isTraceEnabled()) { 215 log.trace("event: " + event + " has been rejected by broker " + broker); 216 } else { 217 log.debug("event has been rejected by broker " + broker); 218 } 219 } 220 } 221 } 222 numberOfPropagatedEvents++; 223 duration += (System.currentTimeMillis() - startTime); 224 } 225 226 229 public long getNumberOfPropagatedEvents() { 230 return numberOfPropagatedEvents; 231 } 232 235 public long getPropagationCost() { 236 return duration; 237 } 238 239 240 243 private BrokerIterator findBrokers(final EventListener listener) { 244 if (log.isDebugEnabled()) { 245 log.debug("try to find broker for " + listener.getClass().getName()); 246 } 247 return new BrokerIterator(eventBrokers.iterator(), listener); 248 } 249 250 private static class BrokerIterator implements Iterator { 251 AbstractEventBroker next; 252 final Iterator i; 253 final EventListener listener; 254 255 BrokerIterator(final Iterator i, final EventListener listener) { 256 this.i = i; 257 this.listener = listener; 258 findNext(); 259 } 260 public void remove() { 261 throw new UnsupportedOperationException (); 262 } 263 public Object next() { 264 return nextBroker(); 265 } 266 public boolean hasNext() { 267 return next != null; 268 } 269 public AbstractEventBroker nextBroker() { 270 if (next == null) throw new NoSuchElementException(); 271 AbstractEventBroker n = next; 272 findNext(); 273 return n; 274 } 275 protected void findNext() { 276 while(i.hasNext()) { 277 AbstractEventBroker broker = (AbstractEventBroker) i.next(); 278 if (broker.canBrokerForListener(listener)) { 279 if (log.isDebugEnabled()) { 280 log.debug("broker " + broker + " can broker for eventlistener " + listener.getClass().getName()); 281 } 282 next = broker; 283 return; 284 } else if (log.isDebugEnabled()) { 285 log.debug("broker " + broker + " cannot boker for eventlistener." + listener.getClass().getName()); 286 } 287 } 288 next = null; 289 } 290 291 } 292 293 294 295 } 296 | Popular Tags |