1 20 package org.enhydra.barracuda.core.event; 21 22 import java.io.*; 23 import java.util.*; 24 import javax.servlet.http.*; 25 26 import org.apache.log4j.*; 27 28 import org.enhydra.barracuda.core.event.events.*; 29 import org.enhydra.barracuda.core.helper.servlet.*; 30 import org.enhydra.barracuda.plankton.data.*; 31 import org.enhydra.barracuda.plankton.http.*; 32 33 60 public class DefaultEventDispatcher implements EventDispatcher { 61 62 public final static String DEFAULT_RESPONSE_EVENT = "DefaultEventDispatcher.DefaultResponseEvent"; public static int MAX_POLY_CHAIN_DEPTH = 15; 65 public static int MAX_DISPATCH_QUEUE_DEPTH = 35; protected static final Logger logger = Logger.getLogger(DefaultEventDispatcher.class.getName()); 67 68 private static int REQ_PHASE = 0; 70 private static int RESP_PHASE = 1; 71 72 88 public void dispatchEvent(EventBroker eb, EventContext context) throws EventException { 89 if (logger.isInfoEnabled()) logger.info("Attempting to dispatch context:"+context); 90 91 DispatchQueue ieventQueue = context.getQueue(); 93 if (!(ieventQueue instanceof DefaultDispatchQueue)) throw new EventException("DispatchQueue is not an instance of DefaultDispatchQueue"); 94 DefaultDispatchQueue eventQueue = (DefaultDispatchQueue) ieventQueue; 95 eventQueue.setResponseHandled(false); 96 if (logger.isDebugEnabled()) { 97 logger.debug("Dumping DispatchQueue prior to dispatch..."); 98 eventQueue.dumpEventQueueToConsole(1); 99 } 100 101 while (eventQueue.hasNextControlEvent() || eventQueue.hasNextViewEvent()) { 103 if (logger.isInfoEnabled()) logger.info("Dispatching REQ Phase"); 105 dispatch(REQ_PHASE, eb, context, eventQueue); 106 107 if (eventQueue.requiresResponse() && 109 !eventQueue.responseHandled() && 110 eventQueue.peekNextViewEvent()==null) { 111 if (logger.isInfoEnabled()) logger.info("Using Default Response"); 112 BaseEvent defaultResponseEvent = (BaseEvent) context.getState(DEFAULT_RESPONSE_EVENT); 113 eventQueue.addEvent(defaultResponseEvent); 114 } 115 if (logger.isDebugEnabled()) { 116 logger.debug("Dumping DispatchQueue after REQ phase..."); 117 eventQueue.dumpEventQueueToConsole(1); 118 } 119 120 if (logger.isInfoEnabled()) logger.info("Dispatching RESP Phase"); 122 dispatch(RESP_PHASE, eb, context, eventQueue); 123 if (logger.isDebugEnabled()) { 124 logger.debug("Dumping DispatchQueue after RESP phase..."); 125 eventQueue.dumpEventQueueToConsole(1); 126 } 127 128 if (eventQueue.requiresResponse() && !eventQueue.responseHandled()) { 131 if (logger.isInfoEnabled()) logger.info("No response event handled - throwing UnhandledEventException"); 132 throw new UnhandledEventException("Unhandled Event - a reponse was required but no response event was handled!", context); 133 } 134 } 135 } 136 137 146 protected void dispatch(int dispatchPhase, EventBroker eb, EventContext context, DefaultDispatchQueue eventQueue) throws EventException { 147 String ext = eb.getEventExtension(); 148 String phaseStr = (dispatchPhase==RESP_PHASE ? "[Resp Phase] " : "[Req Phase] "); 149 150 iterateQueue: while (dispatchPhase==RESP_PHASE ? eventQueue.hasNextViewEvent() : eventQueue.hasNextControlEvent()) { 156 BaseEvent event = (dispatchPhase==RESP_PHASE ? eventQueue.getNextViewEvent() : eventQueue.getNextControlEvent()); 158 event.setEventExtension(ext); 159 if (logger.isDebugEnabled()) logger.debug(phaseStr+"Next event in queue:"+event); 160 161 List eventChain = getEventChain(event); 163 if (logger.isDebugEnabled()) logger.debug(phaseStr+"Getting event chain: ("+eventChain.size()+" events in chain)"); 164 165 Iterator it = eventChain.iterator(); 167 int cntr = -1; 168 iterateChain: while (it.hasNext()) { 169 BaseEvent nextEvent = (BaseEvent) it.next(); 171 if (logger.isDebugEnabled()) logger.debug("Chain element "+(++cntr)+": "+nextEvent); 172 173 if (logger.isDebugEnabled()) logger.debug("Looking for event listeners..."); 175 List factoryList = findListeners(nextEvent, eb); 176 if (factoryList==null || factoryList.size()<1) { 177 if (logger.isDebugEnabled()) logger.debug("No listeners for this event, moving on to next event"); 178 continue; 179 } 180 if (logger.isDebugEnabled()) logger.debug("Found "+factoryList.size()); 181 182 if (logger.isDebugEnabled()) logger.debug("Dispatching to listeners..."); 184 try { 185 notifyListeners(nextEvent, factoryList, context); 186 if (logger.isDebugEnabled()) logger.debug("Handled:"+nextEvent.isHandled()); 187 188 200 } catch (InterruptDispatchException e) { 202 if (logger.isDebugEnabled()) logger.debug("Dispatch interrupted!"); 203 204 eventQueue.markEventsHandled(); 206 if (logger.isDebugEnabled()) logger.debug("All events in queue marked as handled"); 207 208 BaseEvent newEvent = e.getNewEvent(); 210 eventQueue.addEvent(newEvent); 211 if (logger.isDebugEnabled()) logger.debug("New event added to queue: "+newEvent); 212 213 break iterateChain; 224 } 225 } 227 if (dispatchPhase==RESP_PHASE && event.isHandled()) eventQueue.setResponseHandled(true); 230 231 if (!event.isHandled() && event instanceof Exceptional) { 234 try { 235 BaseEvent newEvent = (BaseEvent) event.getClass().getSuperclass().newInstance(); 236 newEvent.setSource(event); 237 eventQueue.addEvent(newEvent); 238 if (logger.isDebugEnabled()) logger.debug("Exceptional event not handled...adding parent event to queue: "+newEvent); 239 } catch (InstantiationException ie) { 240 throw new EventException ("Error instantiating parent event:"+ie, ie); 241 } catch (IllegalAccessException iae) { 242 throw new EventException ("Error instantiating parent event:"+iae, iae); 243 } 244 } 245 246 if (eventQueue.numberOfEventsProcessed()>MAX_DISPATCH_QUEUE_DEPTH) { 250 throw new UnhandledEventException("Max Dispatch Queue Depth exceeded...could indicate a recursive dispatch problem", context); 251 } 252 253 } } 255 256 270 protected List getEventChain(BaseEvent event) throws EventException { 271 if (logger.isDebugEnabled()) logger.debug("Getting event chain for event:"+event); 272 if (event==null) return null; 273 List list = new ArrayList(); 274 275 list.add(event); 277 if (event.isHandled()) return list; 279 BaseEvent curEvent = event; 281 BaseEvent parentEvent = null; 282 int cntr = 0; 283 while ((curEvent instanceof Polymorphic) && 284 (++cntr<MAX_POLY_CHAIN_DEPTH)) { 285 try { 287 parentEvent = (BaseEvent) curEvent.getClass().getSuperclass().newInstance(); 288 parentEvent.setSource(curEvent); 289 } catch (InstantiationException ie) { 290 throw new EventException ("Error instantiating parent event:"+ie, ie); 291 } catch (IllegalAccessException iae) { 292 throw new EventException ("Error instantiating parent event:"+iae, iae); 293 } 294 295 if (parentEvent==null) break; 296 if (logger.isDebugEnabled()) logger.debug("Parent event:"+parentEvent); 297 298 list.add(0,parentEvent); 300 301 curEvent = parentEvent; 303 } 304 if (logger.isDebugEnabled()) { 305 logger.debug("Dumping Event chain..."); 306 CollectionsUtil.printStackTrace(list, 1, logger, null); 307 } 308 309 return list; 311 } 312 313 319 protected List findListeners(BaseEvent event, EventBroker eb) { 320 List factoryList = null; 322 List idList = event.getListenerIDs(); 323 if (logger.isDebugEnabled()) logger.debug("Checking for specific listeners:"+idList); 324 if (idList!=null && idList.size()>0) { 325 factoryList = new ArrayList(); 326 Iterator it = idList.iterator(); 327 while (it.hasNext()) { 328 Object id = it.next(); 329 Object factory = eb.getEventListener(id); 330 if (logger.isDebugEnabled()) logger.debug("Target id:"+id+" Target listener:"+factory); 331 if (factory!=null) { 332 factoryList.add(factory); 333 if (logger.isDebugEnabled()) logger.debug("Targeting listener:"+factory); 334 } 335 } 336 } 337 338 if (factoryList==null || factoryList.size()<1) { 340 try {factoryList = eb.getEventListeners(event.getClass());} 341 catch (InvalidClassException e) {} 342 if (logger.isDebugEnabled()) logger.debug("Checking for generic listeners:"+factoryList); 343 } 344 345 return factoryList; 346 } 347 348 349 358 protected void notifyListeners(BaseEvent event, List list, EventContext context) throws EventException { 359 if (list==null || list.size()<1) { 361 if (logger.isDebugEnabled()) logger.debug("List is empty, returning"); 362 return; 363 } 364 365 if (context instanceof ControlEventContext) { 367 HttpServletRequest req = ((ControlEventContext) context).getRequest(); 368 Map params = event.getParams(); 369 370 375 if (req!=null && params!=null && req instanceof BarracudaServletRequestWrapper) { 376 BarracudaServletRequestWrapper wreq = (BarracudaServletRequestWrapper) req; 377 Iterator eventKeys = params.keySet().iterator(); 379 while (eventKeys.hasNext()) { 380 String key = (String ) eventKeys.next(); 381 Object val = params.get(key); 382 if (val instanceof String []) { 383 String [] s = (String []) val; 384 for (int i=0; i<s.length; i++) { 385 wreq.addParameter(key, s[i]); 386 } 387 } else { 388 wreq.addParameter(key, val.toString()); 389 } 390 } 391 } 392 } 393 395 396 397 398 399 context.putState(EventContext.BASE_EVENT, event); 402 403 Iterator it = list.iterator(); 404 while (it.hasNext()) { 405 Object o = it.next(); 407 if (logger.isDebugEnabled()) logger.debug("Got Next factory:"+o); 408 ListenerFactory factory = (ListenerFactory) o; 409 410 if (event.isHandled() && !factory.notifyAlways()) { 412 if (logger.isDebugEnabled()) logger.debug("Skipping notification because event is already handled"); 413 continue; 414 } 415 416 BaseEventListener listener = factory.getInstance(); 418 419 if (logger.isDebugEnabled()) logger.debug("Notifying listener:"+listener); 421 listener.handleEvent(context); 422 } 423 } 424 } 425 | Popular Tags |