KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > enhydra > barracuda > core > event > ApplicationGateway


1 /*
2  * Copyright (C) 2003 Christian Cryder [christianc@granitepeaks.com]
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * $Id: ApplicationGateway.java,v 1.51 2004/02/01 05:16:27 christianc Exp $
19  */

20 package org.enhydra.barracuda.core.event;
21
22 import java.io.*;
23 import java.lang.reflect.*;
24 import java.util.*;
25 import javax.servlet.*;
26 import javax.servlet.http.*;
27
28 import org.apache.log4j.*;
29
30 import org.enhydra.barracuda.core.comp.scripting.*;
31 import org.enhydra.barracuda.core.event.events.*;
32 import org.enhydra.barracuda.core.helper.servlet.*;
33 import org.enhydra.barracuda.core.view.*;
34 import org.enhydra.barracuda.plankton.*;
35 import org.enhydra.barracuda.plankton.data.*;
36 import org.enhydra.barracuda.plankton.exceptions.*;
37 import org.enhydra.barracuda.plankton.http.URLRewriter;
38 import org.enhydra.barracuda.plankton.http.ServletUtil;
39
40 /**
41  * <p>The application gateway is responsible for a number of things.
42  *
43  * <ol>
44  * <li>It acts as a gateway servlet for all event handlers in this
45  * application.</li>
46  *
47  * <li>It defines and instantiates a number of entities needed to
48  * dispatch events (EventBroker, EventPool, DispatcherFactory, etc)</li>
49  *
50  * <li>It defines which event extension we are using</li>
51  *
52  * <li>It registers all EventGateways, and any local Event interests</li>
53  *
54  * <li>It performs the initial mapping of HTTPRequests to Events for this
55  * particular domain </li>
56  * </ol>
57  *
58  * <p>Consequently, if you want to use the Barracuda event model, this
59  * is the class that really kicks it all off. You must either extend this
60  * class OR use the DefaultApplicationAssembler in order to specify that
61  * this servlet handles all event requests for an application. This will
62  * allow the system to convert requests to events and dispatch them through
63  * the EventBroker to any listeners within EventGateways that have registered
64  * interest with the broker.
65  *
66  * <p>This class should be the first servlet loaded in your web.xml file.
67  *
68  * <p>For an example of how to do this, look at
69  * <strong>org.enhydra.barracuda.examples.ex1.SampleApplicationGateway</strong>
70  *
71  * <p>You might also want to look at the <a HREF="sm_barracuda_event.gif">UML Class
72  * diagram of the Event model classes.</a>
73  *
74  * @author Christian Cryder <christianc@granitepeaks.com>
75  * @author Diez Roggisch <diez.roggisch@artnology.com>
76  * @author Jacob Kjome <hoju@visi.com>
77  * @version %I%, %G%
78  * @since 1.0
79  */

80 public class ApplicationGateway extends HttpServlet implements EventGateway {
81
82     private static final Class JavaDoc CLASS = ApplicationGateway.class;
83     private static final Logger logger = Logger.getLogger(CLASS);
84     private static final Logger orLogger = Logger.getLogger(CLASS.getName()+"_ORStackTrace");
85
86     //public vars
87
//...configuration constants (set through ObjectRepositoryAssembler)
88
public static boolean USE_EVENT_POOLING = true; //use event pooling?
89
public static boolean RESPOND_WITH_404 = false; //respond with a 404 if the event being dispatched is invalid //csc_100603_1
90
public static RequestWrapper REQUEST_WRAPPER = null; //dbr_021602
91
public static ResponseWrapper RESPONSE_WRAPPER = null; //csc_010404_1
92
public static String JavaDoc LR_OVERRIDE_KEY = "$lr_override"; //(String) - if this key = true in the request, the LongRunning interface will be ignored (makes it easy to override LongRunning with certain URL configurations)
93
public static int LR_DEBUG = 0; //0=normal, 1=allow resize on frames, 2=turn off the check redirect frame (useful for debugging)
94

95     //...configuration constants (set through servlet init params)
96
private static final String JavaDoc APPLICATION_ASSEMBLER = "ApplicationAssembler";
97     private static final String JavaDoc ASSEMBLY_DESCRIPTOR = "AssemblyDescriptor";
98     private static final String JavaDoc SAX_PARSER = "SAXParser";
99
100     //...LocalObjectRepository constants (available for apps to access)
101
public static final String JavaDoc HTTP_SERVLET_REQUEST = CLASS+".HttpServletRequest"; //(HttpServletReques)
102
public static final String JavaDoc HTTP_SERVLET_RESPONSE = CLASS+".HttpServletResponse"; //(HttpServletResponse)
103
public static final String JavaDoc THREAD_POOL = CLASS+".ThreadPool"; //(ThreadPool)
104

105     //...EventContext constants (available for apps to access)
106
public static final String JavaDoc TARGET_EVENT_NAME = CLASS+".TargetEventName"; //(String)
107
public static final String JavaDoc EXTERNAL_CONTEXT_OBJ_NAME = CLASS+".ExternalContextObjName"; //(Object)
108

109
110     //req params
111
public static final String JavaDoc LONG_RUNNING_ID = "$lrid"; //(String)
112

113
114
115
116
117
118
119
120     //private vars
121
private EventBroker masterEventBroker = null;
122     private EventPool masterEventPool = null;
123     private static long uid = System.currentTimeMillis();
124     private static final String JavaDoc LONG_RUNNING_RESPONSE_INDICATOR = "$is_lr_resp"; //csc_010404_1
125
protected EventGateway eventGateway = (EventGateway) Classes.newInstance(A_Classes.DEFAULT_EVENT_GATEWAY); //csc_060903_3
126
protected List gateways = null;
127     protected boolean virgin = true; //true after init before any requests handled - added mostly because log4j stuff in init() method is all going to log, rather than console - csc
128

129
130
131     /**
132      * Public noargs constructor
133      */

134     public ApplicationGateway() {
135         logger.info("Instantiating "+this);
136     }
137
138
139     //--------------- User Configurable Methods ------------------
140
/**
141      * <p>Perform any local initialization (this is where you should
142      * add any other known EventGateways)
143      */

144     public void initializeLocal() {
145     }
146
147     /**
148      * <p>Perform any local initialization (this is where you should
149      * add any other known EventGateways)
150      *
151      * @param iconfig the ServletConfig object used to configure this servlet
152      * @deprecated If your code is still attempting to extend this old method
153      * signature, you need to change it to use initializeLocal() instead.
154      * If you still need to get a reference to the servlet config, just
155      * call 'this.getServletConfig()'. This method is now final so that
156      * code which might still be using it will no longer compile.
157      */

158     public final void initializeLocal(ServletConfig iconfig) throws ServletException {
159     }
160
161     /**
162      * <p>Perform any local cleanup (this is where you should
163      * remove any known EventGateways)
164      */

165     public void destroyLocal() {
166     }
167
168     /**
169      * <p>Provide an instance of the specific EventBroker we want to use.
170      * Override this method if you'd like to use something other than
171      * the DefaultEventBroker.
172      *
173      * @return a new instance of the EventBroker
174      */

175     public EventBroker getNewEventBrokerInstance() {
176         if (logger.isDebugEnabled()) logger.debug("instantiating DefaultEventBroker");
177         return new DefaultEventBroker(getDispatcherFactory(), getEventExtension());
178     }
179
180     /**
181      * <p>Provide an instance of the specific EventPool we want to use.
182      * Override this method if you'd like to use something other than
183      * the DefaultEventPool.
184      *
185      * @return a new instance of the EventPool.
186      */

187 //csc_060903_1_start
188
/*
189     public EventPool getNewEventPoolInstance() {
190         if (logger.isDebugEnabled()) logger.debug("instantiating DefaultEventPool");
191         return new DefaultEventPool();
192     }
193 */

194 //csc_060903_1_end
195

196     /**
197      * <p>Provide an instance of the specific DispatchQueue we want to use.
198      * Override this method if you'd like to use something other than
199      * the DefaultDispatchQueue.
200      *
201      * @return a new instance of the DispatchQueue.
202      */

203     public DispatchQueue getNewDispatchQueueInstance() {
204         if (logger.isDebugEnabled()) logger.debug("instantiating DefaultDispatchQueue");
205         return new DefaultDispatchQueue(true);
206     }
207
208     /**
209      * <p>Provide an instance of the specific EventDispatcher we want to use.
210      * Override this method if you'd like to use something other than
211      * DefaultEventBroker.
212      *
213      * @return a new instance of the DispatcherFactory
214      */

215     public DispatcherFactory getDispatcherFactory() {
216         if (logger.isDebugEnabled()) logger.debug("instantiating DefaultDispatcherFactory");
217         return new DefaultDispatcherFactory();
218     }
219
220     /**
221      * <p>Indicate which event extension we are handling. By default the gateway
222      * handles extensions of <strong>.event</strong>. If you wish to handle
223      * a different function you should override this method to return the
224      * value defined in the web.xml file.
225      *
226      * @return a string defining the event extension handled by this servlet
227      */

228     public String JavaDoc getEventExtension() {
229         return ".event";
230     }
231
232     /**
233      * <p>Handle the default HttpRequest. It will probably be rare for
234      * developers to override this.
235      *
236      * <p>Basically, this method receives a request and attempts to map it
237      * to a valid HttpRequestEvent. If the event is invalid, or if the
238      * event is NOT an instance of HttpRequestEvent, then we simply create
239      * a new instance of HttpRequestEvent and dispatch that instead. This
240      * is a very important feature, because it allows us to define events
241      * which are not accessible to the outside world -- the gateway will
242      * only dispatch HttpRequest events, so you define your publically
243      * accessible API by creating an event hierarchy that extends from
244      * the HttpRequestEvent object.
245      *
246      * <p>Once we have a valid event, we dispatch it. In this case (because this
247      * is an Http gateway) we must have a response, so if we catch an
248      * UnhandledEventException, we will generate a default error message and
249      * return.
250      *
251      * @param req the servlet request
252      * @param resp the servlet response
253      * @throws ServletException
254      * @throws IOException
255      */

256     public void handleDefault(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
257         handleDefaultExt(req, resp, null);
258     }
259
260     /**
261      * <p>Handle the default HttpRequest with the ability to add the provided
262      * object into the context. It will probably be rare for
263      * developers to override this.
264      *
265      * <p>Basically, this method receives a request and attempts to map it
266      * to a valid HttpRequestEvent. If the event is invalid, or if the
267      * event is NOT an instance of HttpRequestEvent, then we simply create
268      * a new instance of HttpRequestEvent and dispatch that instead. This
269      * is a very important feature, because it allows us to define events
270      * which are not accessible to the outside world -- the gateway will
271      * only dispatch HttpRequest events, so you define your publically
272      * accessible API by creating an event hierarchy that extends from
273      * the HttpRequestEvent object.
274      *
275      * <p>Once we have a valid event, we dispatch it. In this case (because this
276      * is an Http gateway) we must have a response, so if we catch an
277      * UnhandledEventException, we will generate a default error message and
278      * return.
279      *
280      * @param req the servlet request
281      * @param resp the servlet response
282      * @param externalContextObj object to put into the context
283      * @throws ServletException
284      * @throws IOException
285      */

286     public void handleDefaultExt(HttpServletRequest req, HttpServletResponse resp, Object JavaDoc externalContextObj) throws ServletException, IOException {
287         String JavaDoc ourl = req.getRequestURL().toString();
288         String JavaDoc oqstr = req.getQueryString();
289         long bmillis = 0;
290         long smillis = 0;
291         long emillis = 0;
292         if (virgin) {
293             if (logger.isInfoEnabled()) {
294                 logger.info("\n\n\n\n\n\n"+
295                             "=======================================\n"+
296                             "ApplicationGateway servlet was reloaded\n"+
297                             "=======================================");
298             }
299             virgin = false;
300         }
301         if (logger.isInfoEnabled()) bmillis = System.currentTimeMillis();
302         if (logger.isInfoEnabled()) {
303             logger.info("\n\n\n"+
304                         "--------------------------------------------------------------------------\n"+
305                         "Handling incoming HTTP request: "+ourl+(oqstr!=null ? "?"+oqstr : "")+"\n"+
306                         "--------------------------------------------------------------------------");
307         }
308         BaseEvent event = null;
309
310
311         //start by getting the event broker and pool. We get local copies so
312
//that if these constant vaules change while we're mid-method, it's not a problem
313
EventBroker eventBroker = getEventBroker();
314         EventPool eventPool = getEventPool();
315         ViewCapabilities vc = new ViewCapabilities(req, resp);
316         DefaultEventContext context = null;
317         HttpServletResponse oresp = null;
318         DeferredResponseWrapper dresp = null;
319 //System.out.println("incoming url:"+ourl);
320
//System.out.println("query string:"+oqstr);
321
String JavaDoc uri = req.getRequestURI();
322         String JavaDoc lrid = req.getParameter(LONG_RUNNING_ID);
323         boolean lrOverride = ("true".equalsIgnoreCase(req.getParameter(LR_OVERRIDE_KEY)));
324         boolean useEventPool = USE_EVENT_POOLING;
325         boolean eventCameFromPool = false;
326         boolean allowEventAliasing = true; //just do it always
327
String JavaDoc target = null;
328
329         try {
330             //set up the Session ObjectRepository
331
ObjectRepository.setupSessionRepository(req); //csc_022101.1
332

333
334
335
336             //csc_010404_1_start
337
//before we do anything else, see if we are dealing with a long running response
338
if (lrid!=null && !lrOverride) {
339                 //now since we have a lrid, there should be an object in the session...
340
ObjectRepository session = ObjectRepository.getSessionRepository();
341                 ObjectRepository softSession = ObjectRepository.getSoftSessionRepository();
342                 dresp = (DeferredResponseWrapper) session.getState(lrid);
343
344
345                 //...if there's not, just clear the lrid value and proceed.
346
if (dresp==null) {
347                     if (logger.isInfoEnabled()) logger.info("DeferredResponseWrapper missing from session - continuing as if $lrid=null (pass ??)");
348                     ((BarracudaServletRequestWrapper) req).removeParameter(LONG_RUNNING_ID);
349                     String JavaDoc lridstr = LONG_RUNNING_ID+"="+lrid;
350                     oqstr = StringUtil.replace(oqstr, lridstr, "");
351                     oqstr = StringUtil.replace(oqstr, "?"+lridstr, "");
352                     lrid = null;
353
354                     //now, check to see if there are any params for this url in the soft session; if so,
355
//we can assume they did a CTRL-R on the page (that's why we're in this particular block) -
356
//in this case, restore the params from the last POST request
357
BarracudaServletRequestWrapper breq = (BarracudaServletRequestWrapper) req;
358                     Map pmap = (Map) softSession.getState(ourl);
359                     if (pmap!=null) {
360                         if (logger.isInfoEnabled()) logger.info("Restoring params from previous POST");
361                         Iterator it = pmap.entrySet().iterator();
362                         while (it.hasNext()) {
363                             Map.Entry me = (Map.Entry) it.next();
364                             String JavaDoc key = (String JavaDoc) me.getKey();
365                             if (key.equals(LONG_RUNNING_ID)) continue;
366                             String JavaDoc[] vals = (String JavaDoc[]) me.getValue();
367                             for (int i=0; i<vals.length; i++) {
368                                 String JavaDoc val = vals[i];
369                                 String JavaDoc oval = breq.getParameter(key);
370                                 if (val==oval || (val!=null && val.equals(oval))) continue; //in certain situations, the url may actually have parameters embedded into it; those should not be reconstituted from the session since they are already there
371
breq.addParameter(key, val);
372                             }
373                         }
374                         breq.setMethod("POST");
375                     }
376
377                 //...if there is, but the response has already been generated, just show it
378
} else if (dresp.isCommitted()) {
379                     try {
380                         //first see if there is any error; if so - resend it
381
Integer JavaDoc error = (Integer JavaDoc) session.getState(lrid+"_error");
382                         if (error!=null) {
383                             resp.sendError(error.intValue());
384                             return;
385                         }
386
387                         //next check and see if we encountered an exception; if so, re-throw it
388
Exception JavaDoc dexcp = (Exception JavaDoc) session.getState(lrid+"_exception");
389                         if (dexcp!=null) {
390                             if (logger.isInfoEnabled()) logger.info("Throwing a deferred EventException (pass 3)");
391                             if (dexcp instanceof EventException) throw (EventException) dexcp;
392                             else if (dexcp instanceof ServletException) throw (ServletException) dexcp;
393                             else if (dexcp instanceof IOException) throw (IOException) dexcp;
394                             else if (dexcp instanceof RuntimeException JavaDoc) throw (RuntimeException JavaDoc) dexcp;
395                             else {
396                                 logger.warn("found unexpected exception in session:"+dexcp);
397                             }
398                         }
399
400                         //otherwise, render
401
if (logger.isInfoEnabled()) logger.info("Actually rendering completed response from DeferredResponseWrapper (pass 3)");
402                         dresp.actuallySendResponse(resp);
403                         return;
404                     } finally {
405                         session.removeState(lrid+"*");
406                         dresp = null;
407                     }
408
409                 //...otherwise, lets set everything up to execute the long running task
410
} else {
411                     if (logger.isInfoEnabled()) logger.info("Writing response to DeferredResponseWrapper in session (pass 2)");
412
413                     //save a reference to our orig response; we'll use the deferred response to actually save the results
414
oresp = resp;
415                     resp = dresp;
416                     dresp.setUnderlyingResponse(oresp);
417
418                     //we also want to reconstitute params from the session (this ensures that
419
//all the params from the orig request are available this second time around)
420
BarracudaServletRequestWrapper breq = (BarracudaServletRequestWrapper) req;
421                     Map pmap = (Map) session.getState(lrid+"_params");
422                     Iterator it = pmap.entrySet().iterator();
423                     while (it.hasNext()) {
424                         Map.Entry me = (Map.Entry) it.next();
425                         String JavaDoc key = (String JavaDoc) me.getKey();
426                         String JavaDoc[] vals = (String JavaDoc[]) me.getValue();
427                         for (int i=0; i<vals.length; i++) {
428                             String JavaDoc val = vals[i];
429                             String JavaDoc oval = breq.getParameter(key);
430                             if (val==oval || (val!=null && val.equals(oval))) continue; //in certain situations, the url may actually have parameters embedded into it; those should not be reconstituted from the session since they are already there
431
breq.addParameter(key, val);
432                         }
433                     }
434                     session.removeState(lrid+"_params");
435
436                     //now, if the original method was post, save the params in the soft session (so in case they hit CTRL-R
437
//later, we at least have a chance of resubmitting properly)
438
if ("POST".equalsIgnoreCase((String JavaDoc) session.getState(lrid+"_orig_method"))) {
439                         softSession.putState(ourl, req.getParameterMap());
440                     } else {
441                         softSession.removeState(ourl);
442                     }
443                 }
444             }
445             //csc_010404_1_end
446

447
448
449
450
451
452             //store the req/resp objects in the local repository
453
ObjectRepository lor = ObjectRepository.getLocalRepository(); //csc_010404_1
454
lor.putState(HTTP_SERVLET_REQUEST, req); //csc_010404_1
455
lor.putState(HTTP_SERVLET_RESPONSE, resp); //csc_010404_1
456

457             //figure out the name of the event handler being requested
458
target = req.getServletPath();
459             if (logger.isDebugEnabled()) {
460                 logger.debug("Incoming URI:"+req.getRequestURI());
461                 logger.debug("ServletPath:"+target);
462 // logger.debug("HTTP Headers..."); //csc_052803.1
463
ServletUtil.showHeader(req, logger); //csc_052803.1
464
}
465             if (logger.isInfoEnabled()) ServletUtil.showParams(req, logger); //csc_010404_1
466

467             // cater for Enhydra's different behaviour if in a PO
468
if (null==target || target.length()==0) {
469                 target = req.getRequestURI();
470                 if (logger.isDebugEnabled()) logger.debug("Setting target to request URI: " + target);
471             }
472
473             //..trim any path info (based on '/')
474
if (target!=null) {
475                 int spos = target.lastIndexOf("/");
476                 if (spos>-1) target = target.substring(spos+1);
477             }
478             //..trim any path info (based on '\')
479
if (target!=null) {
480                 int spos = target.lastIndexOf("\\");
481                 if (spos>-1) target = target.substring(spos+1);
482             }
483
484             //now get the actual name of the event
485
String JavaDoc ext = eventBroker.getEventExtension();
486             String JavaDoc eventName = target;
487             if (eventName.endsWith(ext)) {
488                 eventName = target.substring(0, target.length()-ext.length());
489                 if (logger.isDebugEnabled()) logger.debug("Target Event:"+eventName);
490             }
491
492             //now get the actual event name
493
if (allowEventAliasing) try {
494                 String JavaDoc fullEventName = eventBroker.matchEventClass(eventName);
495                 if (fullEventName!=null) {
496                     eventName = fullEventName;
497                     if (logger.isDebugEnabled()) logger.debug("Fully qualified Event:"+eventName);
498                 }
499             } catch (InvalidClassException e) {}
500
501             //now instantiate an Event (here's where it would make sense to
502
//use an Event pool)
503
if (logger.isDebugEnabled()) logger.debug("Creating Event");
504             try {
505                 //get the class name for the event
506
//csc_060903_3 Class cl = Thread.currentThread().getContextClassLoader().loadClass(eventName);
507
Class JavaDoc cl = Classes.getClass(eventName); //csc_060903_3
508

509                 //get it from the pool if appropriate
510
if (useEventPool) try {
511                     if (logger.isDebugEnabled()) logger.debug("Checking out event from event pool");
512                     event = eventPool.checkoutEvent(cl);
513                     eventCameFromPool = true;
514                 } catch (NoAvailableEventsException e) {
515                     if (logger.isDebugEnabled()) logger.debug("No available events in pool");
516                 }
517
518                 //if that didn't work (or we're not getting it from the
519
//pool in the first place) create it manually
520
if (event==null) {
521                     if (logger.isDebugEnabled()) logger.debug("Creating a new event from scratch");
522                     event = (BaseEvent) cl.newInstance(); //this requires that events being dispatched have a noargs constructor
523
}
524
525             } catch (Exception JavaDoc e) {
526                 //if we can't map the request to an event, we will just
527
//dispatch a generic HttpRequestEvent
528
//csc_100603_1_start
529
// logger.error("Class "+eventName+" not found...Creating a generic HttpRequestEvent");
530
// event = new HttpRequestEvent();
531
if (RESPOND_WITH_404) {
532
533 //csc_010404_1_start
534
// logger.warn("Class "+eventName+" not found...Responding with 404 error");
535
// resp.sendError(HttpServletResponse.SC_NOT_FOUND);
536
if (oresp!=null && dresp!=null) {
537                         ObjectRepository session = ObjectRepository.getSessionRepository();
538                         session.putState(lrid+"_error", new Integer JavaDoc(HttpServletResponse.SC_NOT_FOUND));
539                     } else {
540                         logger.warn("Class "+eventName+" not found...Responding with 404 error");
541                         resp.sendError(HttpServletResponse.SC_NOT_FOUND);
542                     }
543                     return;
544 //csc_010404_1_end
545
} else {
546                     logger.error("Class "+eventName+" not found...Creating a generic HttpRequestEvent");
547                     event = new HttpRequestEvent();
548                 }
549 //csc_100603_1_end
550
}
551
552             //make sure the incoming event implements HttpRequestEvent...if not,
553
//consider it invalid (This is VERY important: it prevents people
554
//from hacking the system by directly invoking events that were
555
//not intended to be invoked directly from teh outside world)
556
if (!(event instanceof HttpRequestEvent)) event = new HttpRequestEvent();
557
558
559
560
561
562
563
564 //csc_010404_1_start
565
//if we encounter a LongRunning event...
566
if (event instanceof LongRunning && !lrOverride) {
567
568                 //if we're dealing with a LongRunning event, make sure the response object implements
569
//BarracudaServletResponseWrapper (else there's no point continuing)
570
if (!(req instanceof BarracudaServletRequestWrapper)) throw new EventException("LongRunning support not enabled - you must use a req wrapper that implements BarracudaServletRequestWrapper");
571                 if (!(resp instanceof BarracudaServletResponseWrapper)) throw new EventException("LongRunning support not enabled - you must use a resp wrapper that implements BarracudaServletResponseWrapper");
572
573                 //if its NOT already running as a long running response (ie. the URL does not include the
574
//$lrid=xxxxx param yet), then we are on the first pass: redirect accordingly
575
if (lrid==null) {
576                     if (logger.isInfoEnabled()) logger.info("Redirecting for CheckLongRunningEvent (pass 1)");
577
578                     //create a new deferred response and place it in the session. We also want
579
//to save a copy of the params so we can reconstitute those on subsquent requests
580
ObjectRepository session = ObjectRepository.getSessionRepository();
581                     lrid = getUID();
582                     session.putState(lrid, new DeferredResponseWrapper());
583                     session.putState(lrid+"_params", new HashMap(req.getParameterMap()));
584                     session.putState(lrid+"_orig_url", ourl+(oqstr!=null ? "?"+oqstr : ""));
585                     session.putState(lrid+"_orig_method", req.getMethod());
586                     session.putState(lrid+"_event", event);
587
588                     //now build the check status url
589
ClientSideRedirectException rdException = new ClientSideRedirectException(new CheckLongRunningEvent());
590                     String JavaDoc rdURL = URLRewriter.encodeRedirectURL(req, resp, rdException.getRedirectURL()+"?"+LongRunningEventGateway.LRG_ID+"="+lrid);
591                     rdURL = ScriptDetector.prepareRedirectURL(rdURL, vc);
592                     if (logger.isInfoEnabled()) logger.info("rdURL: "+rdURL);
593
594                     //now build the long running url
595
String JavaDoc lrURL = ourl+(oqstr!=null ? "?"+oqstr : "")+(oqstr!=null ? "&" : "?")+LONG_RUNNING_ID+"="+lrid;
596                     if (logger.isInfoEnabled()) logger.info("lrURL: "+lrURL);
597
598                     //send the redirect request
599
resp.setContentType("text/html");
600                     StringBuffer JavaDoc sb = new StringBuffer JavaDoc(500);
601                     sb.append("<html>");
602                     sb.append(" <head>");
603                     sb.append(" <title>Redirecting...</title>");
604                     sb.append(" </head>");
605                     sb.append(" <script language=\"javascript\">");
606                     sb.append(" var pageFullyLoaded = false;");
607                     sb.append(" function handleComplete() {");
608                     sb.append(" if (!pageFullyLoaded) {");
609                     sb.append(" window.top.location.replace('CancelLongRunningEvent.event?"+LongRunningEventGateway.LRG_ID+"="+lrid+"');");
610                     sb.append(" alert('In the future, please press the Cancel button to properly stop a long running process');");
611                     sb.append(" }");
612                     sb.append(" }");
613                     sb.append(" </script>");
614                     if (LR_DEBUG==1) { //allow resize
615
sb.append(" <frameset rows=\"100%,200\">");
616                         sb.append(" <frame SRC=\""+rdURL+"\">");
617                         sb.append(" <frame SRC=\""+lrURL+"\">");
618                         sb.append(" </frameset>");
619                     } else if (LR_DEBUG==2) { //don't show the check frame
620
sb.append(" <frameset rows=\"100%,200\">");
621                         sb.append(" <frame SRC=\"foo.html\" >");
622                         sb.append(" <frame SRC=\""+lrURL+"\">");
623                         sb.append(" </frameset>");
624                     } else { //normal
625
sb.append(" <frameset rows=\"100%,1\" onload=\"handleComplete();\">");
626                         sb.append(" <frame SRC=\""+rdURL+"\" frameborder=\"0\" noresize>");
627                         sb.append(" <frame SRC=\""+lrURL+"\" frameborder=\"0\" noresize>");
628                         sb.append(" </frameset>");
629                     }
630                     sb.append(" </frameset>");
631                     sb.append("</html>");
632                     String JavaDoc content = sb.toString();
633                     Writer wr = resp.getWriter();
634                     wr.write(content);
635                     wr.close();
636                     resp.flushBuffer();
637
638                     //once we've done all this, simply return
639
return;
640
641                 //if we are actually running generating the long running response (pass 2),
642
//set the event in the resp object (it will be needed for progress updates)
643
} else {
644                     LongRunning lr = (LongRunning) event;
645                     lr.reset();
646                     dresp.setLongRunning(lr);
647                     dresp.setLongRunningThread(Thread.currentThread());
648                 }
649             }
650 //csc_010404_1_end
651

652
653
654
655
656
657
658             //now set any special paramters
659
event.setSource(this);
660             event.setHandled(false);
661
662             //now figure out if the event targets any specific listener IDs, and
663
//if so add these ids to the event. This info will be used by the
664
//dispatcher to send the event to the specified listeners, rather
665
//doing a general dispatch to all parties interested in this class of
666
//event.
667
String JavaDoc[] ids = req.getParameterValues(BaseEvent.EVENT_ID);
668             if (logger.isDebugEnabled()) logger.debug("Looking for event listener ids:"+ids);
669             if (ids!=null) {
670                 for (int i=0, max=ids.length; i<max; i++) {
671                     String JavaDoc id = ids[i];
672                     if (logger.isDebugEnabled()) logger.debug("Target EventID:"+id);
673                     if (allowEventAliasing) try {
674                         id = eventBroker.matchListenerID(ids[i]);
675                         if (logger.isDebugEnabled()) logger.debug("Fully qualified EventID:"+id);
676                     } catch (InvalidClassException e) {}
677                     event.addListenerID(id);
678                 }
679             }
680
681             //finally, dispatch it to the EventBroker
682
if (logger.isDebugEnabled()) logger.debug("Dispatching event:"+event+" to broker:"+eventBroker);
683             DispatchQueue eventQueue = getNewDispatchQueueInstance();
684             HttpResponseEvent defaultResponseEvent = new HttpResponseEvent();
685             defaultResponseEvent.setSource(event);
686             eventQueue.addEvent(event);
687             context = new DefaultEventContext(eventQueue, vc, this.getServletConfig(), req, resp, defaultResponseEvent);
688             context.putState(TARGET_EVENT_NAME, eventName);
689             if (null!=externalContextObj) {
690                 context.putState(EXTERNAL_CONTEXT_OBJ_NAME, externalContextObj);
691             }
692             if (logger.isInfoEnabled()) smillis = System.currentTimeMillis();
693             eventBroker.dispatchEvent(context);
694             if (logger.isInfoEnabled()) emillis = System.currentTimeMillis();
695             if (logger.isInfoEnabled()) logger.info("Dispatching complete! (handled in "+(emillis-smillis)+" of "+(emillis-bmillis)+" millis)");
696
697
698         } catch (ClientSideRedirectException re) {
699             //save current context to session
700
if (context!=null) {
701                 if (logger.isDebugEnabled()) logger.debug("Saving context");
702                 context.persistContext(re);
703             }
704
705             //if we get a redirect exception, request the browser to redirect accordingly
706
String JavaDoc url = URLRewriter.encodeRedirectURL(req, resp, re.getRedirectURL());
707             url = ScriptDetector.prepareRedirectURL(url, vc); //csc_102501.2
708
if (logger.isInfoEnabled()) logger.info("ClientSideRedirectException...redirecting to "+url);
709             resp.sendRedirect(url);
710
711         } catch (EventException e) {
712             //csc_010404_1_start
713
//if we are dealing with a deferred response, and its been interrupted, just return
714
if (logger.isInfoEnabled()) logger.debug("got EventException: "+e);
715             if (oresp!=null && dresp!=null) {
716                  if (dresp.isInterrupted()) return;
717                  ObjectRepository session = ObjectRepository.getSessionRepository();
718                  session.putState(lrid+"_exception", e);
719                  return;
720             }
721             //csc_010404_1_send
722

723             //if we get an EventException, handle it
724
handleEventException(e, req, resp);
725
726         //csc_010404_1_start
727
} catch (ServletException e) {
728             //if we are dealing with a deferred response, and its been interrupted, just return
729
if (logger.isInfoEnabled()) logger.debug("got ServletException: "+e);
730             if (oresp!=null && dresp!=null) {
731                  if (dresp.isInterrupted()) return;
732                  ObjectRepository session = ObjectRepository.getSessionRepository();
733                  session.putState(lrid+"_exception", e);
734                  return;
735             } else {
736                 throw e;
737             }
738
739         } catch (IOException e) {
740             //if we are dealing with a deferred response, and its been interrupted, just return
741
if (logger.isInfoEnabled()) logger.debug("got IOException: "+e);
742             if (oresp!=null && dresp!=null) {
743                  if (dresp.isInterrupted()) return;
744                  ObjectRepository session = ObjectRepository.getSessionRepository();
745                  session.putState(lrid+"_exception", e);
746                  return;
747             } else {
748                 throw e;
749             }
750
751         } catch (RuntimeException JavaDoc e) {
752             //if we are dealing with a deferred response, and its been interrupted, just return
753
if (logger.isInfoEnabled()) logger.debug("got RuntimeException: "+e);
754             if (oresp!=null && dresp!=null) {
755                  if (dresp.isInterrupted()) return;
756                  ObjectRepository session = ObjectRepository.getSessionRepository();
757                  session.putState(lrid+"_exception", e);
758                  return;
759             } else {
760                 throw e;
761             }
762         //csc_010404_1_send
763

764         } finally {
765             //csc_010404_1_start
766
//now, on a final note - if we redirected the response to session, once we are all finished,
767
//write a response to the original resp object redirecting the client page back to the
768
//result
769
if (oresp!=null && !dresp.isInterrupted()) {
770                 if (logger.isInfoEnabled()) logger.info("Redirecting client to get results from session (finish pass 2)");
771
772                 //mark the resp as committed
773
dresp.setCommitted(true);
774
775                 //reset the response
776
resp = oresp;
777
778                 //request the browser to redirect accordingly
779
// ClientSideRedirectException rdException = new ClientSideRedirectException(new CheckLongRunningEvent());
780
// String rdURL = URLRewriter.encodeRedirectURL(req, resp, rdException.getRedirectURL()+"?"+LongRunningEventGateway.ID+"="+lrid+"&"+LongRunningEventGateway.FINISH+"=true");
781
// String rdURL = req.getRequestURL().toString();
782
ObjectRepository session = ObjectRepository.getSessionRepository();
783                 String JavaDoc rdURL = (String JavaDoc) session.getState(lrid+"_orig_url");
784                 session.removeState(lrid+"_orig_url");
785                 String JavaDoc sep = (rdURL.indexOf("?")>-1 ? "&" : "?");
786                 rdURL = rdURL+sep+LONG_RUNNING_ID+"="+lrid;
787                 if (logger.isInfoEnabled()) logger.info("redirecting to "+rdURL);
788                 resp.setContentType("text/html");
789                 StringBuffer JavaDoc sb = new StringBuffer JavaDoc(500);
790                 sb.append("<html>");
791                 sb.append(" <head>");
792                 sb.append(" <title>Redirecting...</title>");
793                 sb.append(" <script SRC=\"xlib/org/enhydra/barracuda/core/scripts/FormControl.js\" type=\"text/javascript\"></script>");
794                 sb.append(" </head>");
795                 sb.append(" <body onload=\"window.top.pageFullyLoaded=true; window.top.location.replace('"+rdURL+"');\">");
796                 sb.append(" <div style=\"text-align: center\"><a HREF=\""+rdURL+"\" target=\"_top\">Click here</a> if your browser does not automatically redirect...</div>");
797                 sb.append(" </body>");
798 /*
799                 sb.append(" <body onload=\"window.top.pageFullyLoaded=true; doSubmitAndLock(document.forms['RedirectForm']);\">");
800                 sb.append(" <form action=\""+rdURL+"\" target=\"_top\" name=\"RedirectForm\">");
801                 Iterator it = req.getParameterMap().entrySet().iterator();
802                 while (it.hasNext()) {
803                     Map.Entry me = (Map.Entry) it.next();
804                     String key = (String) me.getKey();
805                     String[] vals = (String[]) me.getValue();
806                     for (int i=0; i<vals.length; i++) {
807                         String val = vals[i];
808                         sb.append(" <input type=\"hidden\" name=\""+key+"\" value=\""+val+"\">");
809                     }
810                 }
811 // sb.append(" <input type=\"hidden\" name=\""+LONG_RUNNING_ID+"\" value=\""+lrid+"\">");
812                 sb.append(" </form>");
813                 sb.append(" </body>");
814 */

815                 sb.append("</html>");
816                 String JavaDoc content = sb.toString();
817                 Writer wr = resp.getWriter();
818                 wr.write(content);
819                 wr.close();
820                 resp.flushBuffer();
821             }
822             //csc_010404_1_end
823

824
825
826
827             //make sure we ALWAYS release the event
828
if (event!=null && eventCameFromPool) {
829                 if (logger.isDebugEnabled()) logger.debug("Releasing event");
830                 eventPool.releaseEvent(event);
831                 if (logger.isDebugEnabled()) logger.debug("Released!");
832             }
833
834
835             //make sure we always clean up session/local repository stuff
836
ObjectRepository.removeLocalRepository(); //csc_022101.1
837
if (orLogger.isDebugEnabled() && ourl.indexOf("CheckLongRunningEvent")<0) ObjectRepository.printStackTrace("AFT: "+ourl+(oqstr!=null ? "?"+oqstr : ""));
838             ObjectRepository.removeSessionRepository(); //csc_022101.1
839
if (logger.isInfoEnabled()) logger.info("Finished handling incoming HTTP request in "+this);
840         }
841     }
842
843     /**
844      * <p>Handle an EventException. Basically, this is where we handle the
845      * really bad, unexpected type of event exceptions. Generally, as you code,
846      * if you want to interrupt the dispatch and fire a new event, you should
847      * throw an InterruptDispatchException. Only throw EventExceptions in
848      * truly exceptional circumstances.
849      *
850      * @param e the EventException to handle
851      * @param req the servlet request
852      * @param resp the servlet response
853      * @throws ServletException
854      * @throws IOException
855      */

856     public void handleEventException (EventException e, HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
857         //first see what the base exception is...if it's a servlet exception
858
//or an IOException, rethrow it...
859
Exception JavaDoc rootException = NestableException.getRootException(e);
860         if (rootException instanceof ServletException) throw (ServletException) rootException;
861         if (rootException instanceof IOException) throw (IOException) rootException;
862
863         //if we get an EventException, log it and print the base exception
864
resp.setContentType("text/html");
865         PrintWriter out = resp.getWriter();
866         ExceptionUtil.logExceptionAsHTML(out, e, req);
867         logger.warn("Unexpected event exception: ", e);
868         if (rootException!=e) {
869             logger.warn("Root Exception...", rootException);
870         }
871     }
872
873
874     //-------------------- ApplicationGateway --------------------
875
/**
876      * <p>Specify event gateways. You can call this method with
877      * as many different gateways as you like. When the Application
878      * Gateway initializes, it will load them all. When the gateway
879      * is destroyed, they will be deregistered.
880      *
881      * @param gateway an event gateway we'd like to have registered
882      */

883     public final void specifyEventGateways(EventGateway gateway) {
884         if (gateways==null) gateways = new ArrayList();
885         gateways.add(gateway);
886     }
887
888     /**
889      * <p>Provide a reference to the event broker.
890      *
891      * @return a reference to the master event broker
892      */

893     public final EventBroker getEventBroker() {
894         if (masterEventBroker==null) {
895             masterEventBroker = getNewEventBrokerInstance();
896
897             //this ensures that the App-gateway can successfully route
898
//generic ActionEvents (if we ever add other "well-known"
899
//generic events we should pre-register them here as well
900
//so that they can be used without any special registration
901
//process)
902
try {masterEventBroker.addEventAlias(ActionEvent.class);}
903             catch (InvalidClassException e) {}
904         }
905         return masterEventBroker;
906     }
907
908     /**
909      * <p>Provide a reference to the event pool. May return
910      * null if we're not using event pooling.
911      *
912      * @return a reference to the master event pool
913      */

914     public final EventPool getEventPool() {
915 //csc_060903_1 if (USE_EVENT_POOLING && masterEventPool==null) masterEventPool = getNewEventPoolInstance();
916
if (USE_EVENT_POOLING && masterEventPool==null) masterEventPool = (EventPool) Classes.newInstance(A_Classes.DEFAULT_EVENT_POOL); //csc_060903_1
917
if (!USE_EVENT_POOLING) masterEventPool = null;
918         return masterEventPool;
919     }
920
921     //dbr_021602 - added
922
protected HttpServletRequest wrapRequest(HttpServletRequest req) {
923         if (REQUEST_WRAPPER!=null) {
924             return REQUEST_WRAPPER.wrap(req);
925         } else {
926             return new DefaultServletRequestWrapper(req);
927         }
928     }
929
930     protected HttpServletResponse wrapResponse(HttpServletResponse resp) {
931         if (RESPONSE_WRAPPER!=null) {
932             return RESPONSE_WRAPPER.wrap(resp);
933         } else {
934             return new DefaultServletResponseWrapper(resp);
935         }
936     }
937
938
939
940
941
942
943
944     //-------------------- EventGateway --------------------------
945
/**
946      * <p>Set the parent gateway. Null indicates its the root.
947      * By definition, an ApplicationGateway is always the root.
948      *
949      * @param eg the parent event gateway for this gateway
950      */

951     public final void setParent(EventGateway eg) {
952         eventGateway.setParent(null);
953     }
954
955     /**
956      * <p>Get the parent gateway. Returns null if it's the root.
957      *
958      * @return the parent event gateway
959      */

960     public final EventGateway getParent() {
961         return eventGateway.getParent();
962     }
963
964     /**
965      * <p>Add an event gateway to this one
966      *
967      * @param eg the event gateway to be added
968      */

969     public final void add(EventGateway eg) {
970         eventGateway.add(eg);
971         eg.setParent(this); //do this so the parent points at the ApplicationGateway, not the EventGateway we are using to actually store the values
972
}
973
974     /**
975      * <p>Remove an event gateway from this one
976      *
977      * @param eg the event gateway to be removed
978      */

979     public final void remove(EventGateway eg) {
980         eventGateway.remove(eg);
981     }
982
983     /**
984      * Get a list of child gateways. The list returned is a copy of the
985      * underlying child gateway list.
986      *
987      * @return a list of child gateways
988      */

989     public List getChildren() {
990         return eventGateway.getChildren();
991     }
992
993     /**
994      * <p>Ask all interested parties to register with
995      * the EventBroker
996      *
997      * @param eb the event broker to register with
998      */

999     public final void register(EventBroker eb) {
1000        eventGateway.register(eb);
1001    }
1002
1003    /**
1004     * <p>Ask all interested parties to de-register with
1005     * the EventBroker
1006     *
1007     * @param eb the event broker to de-register with
1008     */

1009    public final void deregister(EventBroker eb) {
1010        eventGateway.deregister(eb);
1011    }
1012
1013    /**
1014     * Register any local interests in the EventBroker
1015     *
1016     * @param eb the event broker this gateway should use to
1017     * register for local events
1018     */

1019    public final void registerLocalEventInterests(EventBroker eb) {
1020        eventGateway.registerLocalEventInterests(eb);
1021    }
1022
1023    /**
1024     * Deregister any local interests in the EventBroker
1025     *
1026     * @param eb the event broker this gateway should use to
1027     * de-register for local events
1028     */

1029    public final void deregisterLocalEventInterests(EventBroker eb) {
1030        eventGateway.deregisterLocalEventInterests(eb);
1031    }
1032
1033    /**
1034     * Register any local event aliases in the EventBroker
1035     *
1036     * @param eb the event broker this gateway should use to
1037     * register aliases for local events
1038     */

1039    public final void registerLocalEventAliases(EventBroker eb) {
1040        eventGateway.registerLocalEventAliases(eb);
1041    }
1042
1043    /**
1044     * Rather than overriding the registerLocalEventInterests
1045     * method, you can just invoke this method instead for each
1046     * interest you'd like to register. The gateway will keep track
1047     * of all factories specified, and register/deregister when
1048     * appropriate (so you don't have to worry about it). Notice that
1049     * this method registers just the listener id (not for a specific
1050     * class of event).
1051     *
1052     * The only real reason for using the registerLocalEventInterests
1053     * method would be if you actually need access to the EventBroker.
1054     *
1055     * Note that if the event class is not an instance of BaseEvent, the
1056     * request is just silently ignored (unlike the event broker, which
1057     * throws an exception).
1058     *
1059     * @param factory the factory we wish to register with the event broker
1060     */

1061    public final void specifyLocalEventInterests(ListenerFactory factory) {
1062        eventGateway.specifyLocalEventInterests(factory);
1063    }
1064
1065    /**
1066     * Rather than overriding the registerLocalEventInterests
1067     * method, you can just invoke this method instead for each
1068     * interest you'd like to register. The gateway will keep track
1069     * of all factories specified, and register/deregister when
1070     * appropriate (so you don't have to worry about it).
1071     *
1072     * The only real reason for using the registerLocalEventInterests
1073     * method would be if you actually need access to the EventBroker.
1074     *
1075     * Note that if the event class is not an instance of BaseEvent, the
1076     * request is just silently ignored (unlike the event broker, which
1077     * throws an exception).
1078     *
1079     * @param factory the factory we wish to register with the event broker
1080     * @param event the class of events we are interested in
1081     */

1082    public final void specifyLocalEventInterests(ListenerFactory factory, Class JavaDoc event) {
1083        eventGateway.specifyLocalEventInterests(factory, event);
1084    }
1085
1086    /**
1087     * Rather than overriding the registerLocalEventAliases
1088     * method, you can just invoke this method instead for type
1089     * of event you want to manually alias.
1090     *
1091     * The only real reason for using the registerLocalEventAliases
1092     * method would be if you actually need access to the EventBroker.
1093     *
1094     * Note that if the event class is not an instance of BaseEvent, the
1095     * request is just silently ignored (unlike the event broker, which
1096     * throws an exception).
1097     *
1098     * @param event the class of events we are interested in registering
1099     * aliases for
1100     */

1101    public final void specifyLocalEventAliases(Class JavaDoc event) {
1102        eventGateway.specifyLocalEventAliases(event);
1103    }
1104
1105
1106
1107
1108
1109
1110    //-------------------- HTTPServlet ---------------------------
1111
/**
1112     * <p>By default the GET request is mapped to the handleDefault method
1113     *
1114     * @param req the servlet request
1115     * @param resp the servlet response
1116     * @throws ServletException
1117     * @throws IOException
1118     */

1119    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
1120//csc_102201.1_start
1121
// handleDefault(new org.enhydra.barracuda.core.helper.servlet.HttpServletRequestWrapper(wrap(req)), resp);
1122
boolean handled = ScriptDetector.checkClientReq(req, resp);
1123        //dbr_021602_start.2
1124
if (!handled) handleDefault(wrapRequest(req), wrapResponse(resp));
1125        //dbr_021602_end.2
1126
//csc_102201.1_end
1127
}
1128
1129    /**
1130     * <p>By default the POST request is mapped to the handleDefault method
1131     *
1132     * @param req the servlet request
1133     * @param resp the servlet response
1134     * @throws ServletException
1135     * @throws IOException
1136     */

1137    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
1138        handleDefault(wrapRequest(req), wrapResponse(resp));
1139    }
1140
1141    /**
1142     * <p>By default the OPTIONS request is mapped to the handleDefault method
1143     *
1144     * @param req the servlet request
1145     * @param resp the servlet response
1146     * @throws ServletException
1147     * @throws IOException
1148     */

1149    protected void doOptions(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
1150        handleDefault(wrapRequest(req), wrapResponse(resp));
1151    }
1152
1153    /**
1154     * <p>By default the DELETE request is mapped to the handleDefault method
1155     *
1156     * @param req the servlet request
1157     * @param resp the servlet response
1158     * @throws ServletException
1159     * @throws IOException
1160     */

1161    protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
1162        handleDefault(wrapRequest(req), wrapResponse(resp));
1163    }
1164
1165    /**
1166     * <p>By default the PUT request is mapped to the handleDefault method
1167     *
1168     * @param req the servlet request
1169     * @param resp the servlet response
1170     * @throws ServletException
1171     * @throws IOException
1172     */

1173    protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
1174        handleDefault(wrapRequest(req), wrapResponse(resp));
1175    }
1176
1177    /**
1178     * <p>By default the TRACE request is mapped to the handleDefault method
1179     *
1180     * @param req the servlet request
1181     * @param resp the servlet response
1182     * @throws ServletException
1183     * @throws IOException
1184     */

1185    protected void doTrace(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
1186        handleDefault(wrapRequest(req), wrapResponse(resp));
1187    }
1188
1189
1190
1191
1192
1193
1194    //-------------------- Servlet -------------------------------
1195
/**
1196     * <p>Here's where we initialize the servlet.
1197     */

1198    public void init() throws ServletException {
1199
1200        try {
1201            logger.info("initializing ApplicationGateway servlet");
1202
1203
1204//csc_060903_3_start - why are we even doing this section??? This seems redundant to me, like its
1205
//something that should be happening via the ObjectRepositoryAssembler, NOT ApplicationGateway
1206
//parameters...Jake seems to think so too, so I'm commenting it out for now
1207
/*
1208            //first and foremost, assign any debug value constants
1209            logger.debug("checking for DebugValues");
1210            Enumeration enum = this.getServletConfig().getInitParameterNames();
1211            while (enum.hasMoreElements()) {
1212                String param = enum.nextElement().toString();
1213                if (param.startsWith(DEBUG_VALUE)) {
1214                    String value = this.getServletConfig().getInitParameter(param);
1215                    logger.debug(param+" = "+value);
1216
1217                    //split it into parts
1218                    try {
1219                        int pos1 = value.lastIndexOf(".");
1220                        int pos2 = value.indexOf("=", pos1);
1221                        String clname = value.substring(0,pos1);
1222                        String var = value.substring(pos1+1, pos2);
1223                        String val = value.substring(pos2+1);
1224                        logger.debug("Class:"+clname+" Variable:"+var+" Value:"+val);
1225
1226                        //figure out what value we're trying to set
1227//csc_060903_3 Class cl = Thread.currentThread().getContextClassLoader().loadClass(clname);
1228                        Class cl = Classes.getClass(clname); //csc_060903_3
1229
1230                        Field field = cl.getDeclaredField(var);
1231                        Object origval = field.get(null);
1232                        Class fieldType = field.getType();
1233                        Object targetval = null;
1234                        //...integer
1235                        if (fieldType==Integer.class || fieldType==int.class) {
1236                            targetval = new Integer(val);
1237                        //...boolean
1238                        } else if (fieldType==Boolean.class || fieldType==boolean.class) {
1239                            targetval = new Boolean(val);
1240                        //...float
1241                        } else if (fieldType==Float.class || fieldType==float.class) {
1242                            targetval = new Float(val);
1243                        //...double
1244                        } else if (fieldType==Double.class || fieldType==double.class) {
1245                            targetval = new Double(val);
1246                        //...long
1247                        } else if (fieldType==Long.class || fieldType==long.class) {
1248                            targetval = new Long(val);
1249                        //...short
1250                        } else if (fieldType==Short.class || fieldType==short.class) {
1251                            targetval = new Short(val);
1252                        //...String (def)
1253                        } else {
1254                            targetval = val;
1255                        }
1256
1257                        //actually try setting it
1258                        field.set(null, targetval);
1259                        Object newval = field.get(null);
1260                        logger.debug("set "+clname+"."+var+" from "+origval+" to "+newval);
1261
1262                    } catch (Exception e) {
1263                        logger.error("err "+e+" setting value:"+value);
1264                        continue;
1265                    }
1266                }
1267            }
1268*/

1269//csc_060903_3_end
1270

1271//csc_060903_2_start - move down below so that EventPool could be scripted via the application assembler
1272
//start by getting a reference to the EventBroker. Also request the
1273
//EventPool, just to make sure they're both instantiated
1274
// logger.debug("creating EventBroker");
1275
// EventBroker eb = this.getEventBroker();
1276
// getEventPool();
1277
//csc_060903_2_end
1278

1279            //before performing automated gateway assembly, first manually add in a reference to
1280
//LongRunningEventGateway (we do this so its always available).
1281
this.add(new LongRunningEventGateway());
1282
1283            //perform any automated assembly if necessary
1284
String JavaDoc assemblerName = this.getServletConfig().getInitParameter(APPLICATION_ASSEMBLER);
1285            String JavaDoc descriptor = this.getServletConfig().getInitParameter(ASSEMBLY_DESCRIPTOR);
1286            if (assemblerName!=null && descriptor!=null) try {
1287                logger.debug("performing automated assembly");
1288                String JavaDoc parser = this.getServletConfig().getInitParameter(SAX_PARSER);
1289//csc_060903_1 ApplicationAssembler assembler = (ApplicationAssembler) Thread.currentThread().getContextClassLoader().loadClass(assemblerName).newInstance();
1290
ApplicationAssembler assembler = (ApplicationAssembler) Classes.newInstance(assemblerName); //csc_060903_1
1291
if (parser!=null) assembler.assemble(this, this.getServletConfig(), descriptor, parser);
1292                else assembler.assemble(this, this.getServletConfig(), descriptor);
1293                logger.debug("automated assembly complete!");
1294            } catch (Exception JavaDoc e) {
1295                throw new RuntimeException JavaDoc ("Error invoking assembler:"+e);
1296            }
1297
1298//csc_060903_2_start
1299
//start by getting a reference to the EventBroker. Also request the
1300
//EventPool, just to make sure they're both instantiated. We do this here
1301
//primarily so that if there is a problem instantiating these, we find
1302
//out about it immediately on startup, rather than waiting until a request
1303
//actually comes through.
1304
logger.debug("creating EventBroker & EventPool");
1305            EventBroker eb = this.getEventBroker();
1306            getEventPool();
1307//csc_060903_2_end
1308

1309            //allow for local initialization
1310
logger.debug("initialize local");
1311            initializeLocal();
1312
1313            //handle any gateways which were specified
1314
if (gateways!=null) {
1315                logger.debug("handle any local gateways");
1316                Iterator it = gateways.iterator();
1317                while (it.hasNext()) {
1318                    EventGateway gateway = (EventGateway) it.next();
1319                    logger.debug("adding specified event gateway:"+gateway);
1320                    this.add(gateway);
1321                }
1322            }
1323
1324            //now register the event gateway (note that we have to set the value to
1325
//false when registering to ensure that all possible combinations get
1326
//registered. If we don't do this we run into problems later)
1327
logger.debug("invoke register");
1328            boolean aliasVal = DefaultBaseEvent.USE_ID_ALIASES;
1329            DefaultBaseEvent.USE_ID_ALIASES = false;
1330            register(eb);
1331            DefaultBaseEvent.USE_ID_ALIASES = aliasVal;
1332
1333            //show the app structure
1334
/*
1335//csc_060903_3 - removed because it is calling methods that are not part of the EventGateway interface (and its not really used anyway)
1336            if (SHOW_APP_STRUCTURE) {
1337                logger.debug("Printing Stack Trace...");
1338                eventGateway.printStackTrace(0, System.out);
1339            }
1340*/

1341            virgin = true;
1342            if (logger.isInfoEnabled()) logger.info("Initialization Complete!");
1343        } catch (RuntimeException JavaDoc e) {
1344            logger.fatal("ALERT!!!!! Fatal err initializing servlet:", e);
1345            throw e;
1346        }
1347    }
1348
1349    /**
1350     * <p>Here's where we destroy the servlet.
1351     */

1352    public void destroy() {
1353        try {
1354            logger.info("destroying servlet");
1355
1356            //start by getting a reference to the EventBroker
1357
EventBroker eb = this.getEventBroker();
1358
1359            //now deregister the event gateway
1360
boolean aliasVal = DefaultBaseEvent.USE_ID_ALIASES;
1361            DefaultBaseEvent.USE_ID_ALIASES = false;
1362            deregister(eb);
1363            DefaultBaseEvent.USE_ID_ALIASES = aliasVal;
1364
1365            //finally allow for any local destruction
1366
destroyLocal();
1367
1368            //remove any gateways which were specified
1369
if (gateways!=null) {
1370                Iterator it = gateways.iterator();
1371                while (it.hasNext()) {
1372                    EventGateway gateway = (EventGateway) it.next();
1373                    this.remove(gateway);
1374                }
1375            }
1376
1377            //lb_032801_start - Patch submitted by Larry Brasfield
1378
//[larry.brasfield@theplatform.com] so JVM can exit once
1379
//the servlet's destroy() method is called. The problem
1380
//is that the event pool cleanup thread will not stop. The
1381
//following code corrects this. You can find related changes
1382
//by searching for lb_032801
1383
//
1384
//Allow finalizer to get rid of this pool object.
1385
//That way, a shutdown can actually be effected.
1386
if (masterEventPool!=null) {
1387                masterEventPool.shutdown();
1388                masterEventPool = null;
1389            }
1390            masterEventBroker = null;
1391            System.gc();
1392            System.runFinalization();
1393            //lb_032801_end
1394

1395        } catch (RuntimeException JavaDoc e) {
1396            logger.fatal("ALERT!!!!! Fatal err destroying servlet:", e);
1397            throw e;
1398        }
1399    }
1400
1401    private synchronized static String JavaDoc getUID() {
1402        return "_"+(++uid);
1403    }
1404
1405}
1406
Popular Tags