KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > enterprise > tools > guiframework > view > BaseServlet


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23
24 package com.sun.enterprise.tools.guiframework.view;
25
26 import com.iplanet.jato.ApplicationServletBase;
27 import com.iplanet.jato.RequestContext;
28 import com.iplanet.jato.RequestContextImpl;
29 import com.iplanet.jato.RequestManager;
30 import com.iplanet.jato.view.View;
31 import com.iplanet.jato.view.ViewBean;
32 import com.iplanet.jato.NavigationException;
33 import com.iplanet.jato.util.RootCauseException;
34
35 import com.sun.enterprise.tools.guiframework.event.descriptors.EventDescriptor;
36 import com.sun.enterprise.tools.guiframework.exception.FrameworkError;
37 import com.sun.enterprise.tools.guiframework.exception.FrameworkException;
38 import com.sun.enterprise.tools.guiframework.exception.ViewDescriptorHolder;
39 import com.sun.enterprise.tools.guiframework.util.LogUtil;
40 import com.sun.enterprise.tools.guiframework.view.descriptors.ViewDescriptor;
41 import com.sun.enterprise.tools.guiframework.view.event.ErrorEvent;
42
43 import java.io.IOException JavaDoc;
44 import java.io.PrintWriter JavaDoc;
45 import java.io.StringWriter JavaDoc;
46 import java.net.URL JavaDoc;
47 import java.util.EventObject JavaDoc;
48
49 import javax.servlet.ServletConfig JavaDoc;
50 import javax.servlet.ServletContext JavaDoc;
51 import javax.servlet.ServletException JavaDoc;
52 import javax.servlet.ServletRequest JavaDoc;
53 import javax.servlet.http.HttpServletRequest JavaDoc;
54 import javax.servlet.http.HttpServletResponse JavaDoc;
55
56 import org.xml.sax.EntityResolver JavaDoc;
57
58
59 public abstract class BaseServlet extends ApplicationServletBase {
60
61     /**
62      * This method provides a last resort spot to handle any uncaught
63      * exceptions or errors. The preferred way to handle exceptions or errors
64      * is to register and "error" event to dispatch the handling to the
65      * designated handler, however, if that fails or you do not do this, this
66      * method will be invoked. The ErrorEvent that is passed in will contain
67      * information about what went wrong. The View and ViewDescriptor
68      * contained in the Error event may be null as there was no handler
69      * defined to take care of this exception.
70      *
71      * @param errorEvent The ErrorEvent object describing the exception
72      */

73     protected abstract void handleUncaughtException(ErrorEvent errorEvent);
74
75
76     /**
77      * This method should return a String URL pointing to the location of the
78      * XML file containing the ViewDescriptor definitions.
79      */

80     protected abstract URL JavaDoc getViewXMLURL();
81
82
83     /**
84      * This method should return a String to prefix before all JSP paths.
85      * This method may soon be deprecated, I recommend returning "" from this
86      * method to avoid problems later.
87      */

88     protected abstract String JavaDoc getJSPRoot();
89
90
91     /**
92      * @return The package name of the Servlet.
93      */

94     protected abstract String JavaDoc getPackageName();
95
96
97     /**
98      * This method provides access to the DTD_URL_BASE location. By default,
99      * this method will look for a Servlet init parameter named DTD_URL_BASE
100      * ("dtdURLBase"), however, sub-classes may override this and provide a
101      * different means to resolve this URL path.
102      */

103     protected String JavaDoc getDTDURLBase(ServletConfig JavaDoc config) {
104     // Get the dtd base URL
105
String JavaDoc base = config.getInitParameter(DTD_URL_BASE);
106     if ((base == null) && LogUtil.isLoggable(LogUtil.FINER)) {
107         LogUtil.log(LogUtil.FINER,
108         "framework.servletInitNotFound", DTD_URL_BASE);
109     }
110     return base;
111     }
112
113
114     /**
115      * This method provides returns the entity resolver that can be used to look
116      * up view xml files. By default no entityresolver is specfied. sub-classes
117      * may chose to provide their own entityresolver. An example is
118      * com.sun.enterprise.tools.guiframework.view.ViewXMLEntityResolver
119      */

120     
121     protected EntityResolver JavaDoc getViewXMLEntityResolver() {
122         return null;
123     }
124     
125     /**
126      * Set up the ViewDescriptorManager
127      */

128     public void init(ServletConfig JavaDoc config) throws ServletException JavaDoc {
129     super.init(config);
130
131     // Setup the ViewDescriptorManager
132
ViewDescriptorManager mgr = ViewDescriptorManager.getInstance();
133     mgr.setDTDURLBase(getDTDURLBase(config));
134     mgr.setViewDescriptorURL(getViewXMLURL());
135         mgr.setViewXMLEntityResolver(getViewXMLEntityResolver());
136 // FIXME: Consider removing jsp root concept
137
mgr.setJSPRoot(getJSPRoot());
138     }
139
140
141     /**
142      * This method creates a new DescriptorViewManager. If you want to use
143      * your own sub-class, you can override this method. The default
144      * implementation of DescriptorViewManager uses ViewDescriptorManager for
145      * creating new instances of DescriptorViews.
146      *
147      * @param rc The RequestContext
148      *
149      * @return The DescriptorViewManager used to manage DescriptorViews
150      */

151     protected DescriptorViewManager newViewManagerInstance(RequestContext rc) {
152     return new DescriptorViewManager(rc, getPackageName());
153     }
154
155
156     /**
157      * This method sets the DescriptorViewManager as the ViewBeanManager.
158      */

159     protected void initializeRequestContext(RequestContext rc) {
160     super.initializeRequestContext(rc);
161
162         // Set a view bean manager in the request context. This must be
163
// done at the module level because the view bean manager is
164
// module specifc.
165
DescriptorViewManager vm = newViewManagerInstance(rc);
166     ((RequestContextImpl)rc).setViewBeanManager(vm);
167     }
168
169
170     /**
171      * This method attempts to figure out the "pageName"
172      */

173     protected String JavaDoc getPageName(RequestContext rc) {
174     HttpServletRequest JavaDoc request = rc.getRequest();
175     String JavaDoc pageName = request.getParameter(PARAM_HANDLER_BEAN);
176     if (pageName == null) {
177         pageName = getPageName(request, request.getPathInfo());
178     }
179     return pageName;
180     }
181
182     /**
183      *
184      */

185     protected String JavaDoc getPageName(HttpServletRequest JavaDoc request, String JavaDoc pathInfo) {
186     String JavaDoc pageName = null;
187     if (pathInfo != null) {
188         pageName = parsePathInfo(pathInfo);
189     }
190
191     // Nothing specified, use default
192
if (pageName == null) {
193         pageName = getDefaultHandlerName(request);
194     }
195     return pageName;
196     }
197
198
199     /**
200      * This method is overriden to catch errors and handle them.
201      */

202     protected void processRequest(String JavaDoc pageName, HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response) throws ServletException JavaDoc, IOException JavaDoc {
203     try {
204         super.processRequest(pageName, request, response);
205     } catch (Throwable JavaDoc ex) {
206         try {
207         handleException(RequestManager.getRequestContext(), ex);
208         } catch (Throwable JavaDoc ex2) {
209         handleException(RequestManager.getRequestContext(), ex2);
210         }
211     }
212     }
213
214
215     /**
216      *
217      */

218     protected void onUncaughtException(RequestContext rc, Exception JavaDoc ex) throws ServletException JavaDoc, IOException JavaDoc {
219     try {
220         handleException(rc, ex);
221     } catch (Throwable JavaDoc ex2) {
222         handleException(rc, ex2);
223     }
224     }
225
226
227     /**
228      * This method exists to deal with the known exceptions that don't do
229      * things right (they have their own way of chaining exceptions and don't
230      * support the standard mechanism of exception chaining.
231      *
232      * @param ex The exception to attempt to get the cause for
233      */

234     protected Throwable JavaDoc getRootCause(Throwable JavaDoc ex) {
235     if (ex instanceof RootCauseException) {
236         // JATO doesn't use getCause(),
237
// they use their own: getRootCause()
238
Throwable JavaDoc jatoRoot = ((RootCauseException)ex).getRootCause();
239         try {
240         ex.initCause(jatoRoot);
241         } catch (Exception JavaDoc ignore) {
242         // We're just doing our best to do what JATO didn't
243
}
244         ex = jatoRoot;
245     } if (ex instanceof ServletException JavaDoc) {
246         // Servlet Exception doesn't do things right either
247
Throwable JavaDoc servletRoot = ((ServletException JavaDoc)ex).getRootCause();
248         try {
249         ex.initCause(servletRoot);
250         } catch (Exception JavaDoc ignore) {
251         // We're just doing our best to do what ServletException didn't
252
}
253         ex = servletRoot;
254     } else {
255         ex = ex.getCause();
256     }
257     return ex;
258     }
259
260
261     /**
262      *
263      */

264     protected void handleException(RequestContext rc, Throwable JavaDoc ex) {
265     // Hopefully we have a FrameworkException that has info we need
266
// If a forward was called, JATO may have wrapped our exception... may
267
// be possible to wrap in other ways as well.
268
View view = null;
269     ViewDescriptor desc = null;
270     Throwable JavaDoc tmpEx = ex;
271     while (tmpEx != null) {
272         if (tmpEx instanceof ViewDescriptorHolder) {
273         ViewDescriptorHolder vdh = (ViewDescriptorHolder)tmpEx;
274         desc = vdh.getResponsibleViewDescriptor();
275         view = vdh.getResponsibleView();
276         break;
277         }
278         tmpEx = getRootCause(tmpEx);
279     }
280
281     // The view might be null (even if we have a FrameworkException)
282
if (view == null) {
283         String JavaDoc pageName = getPageName(rc);
284         if (pageName != null) {
285         try {
286             view = rc.getViewBeanManager().getViewBean(pageName);
287         } catch (Exception JavaDoc ex2) {
288             // Ignore, b/c we are already trying to show an exception
289
}
290         }
291     }
292
293     // The desc might be null (even if we have a FrameworkException)
294
if ((desc == null) && (view != null)) {
295         if (view instanceof DescriptorContainerView) {
296         desc = ((DescriptorContainerView)view).getViewDescriptor();
297         }
298     }
299
300     // Handle the exception
301
handleException(rc, ex, desc, view);
302     }
303
304
305     /**
306      * <P>This method gathers important information having to do with the
307      * exception that was thrown. This information is then stored in an
308      * ErrorEvent to be passed to a handler designed to handle ErrorEvents.
309      * This information is also sent to the log.</P>
310      *
311      * <P>After this method gathers the exception information, it then
312      * dispatches to an error handler, if found. If no error handler is found
313      * it will invoke the method 'handleUncaughtException' on the Servlet.</P>
314      *
315      * @param ex The Exception / Error
316      * @param desc The ViewDescriptor responsible for the Exception/Error
317      * @param view The View responsible for the Exception / Error
318      */

319     public void handleException(RequestContext rc, Throwable JavaDoc ex, ViewDescriptor desc, View view) {
320         // First find the ViewBean (may not be view & view may be null)
321
View vb = view;
322     HttpServletRequest JavaDoc request = rc.getRequest();
323     if (vb == null) {
324         if (desc != null) {
325         ViewDescriptor topDesc = desc;
326         while (topDesc.getParent() != null) {
327             topDesc = topDesc.getParent();
328         }
329         try {
330             vb = topDesc.getView(rc);
331         } catch (Exception JavaDoc ignoreEx) {
332             // Ignore, b/c we're just trying another way to get the VB
333
}
334         }
335     }
336
337     // Try to get the top-most View (above code is not enough)
338
while ((vb != null) && !(vb instanceof ViewBean)) {
339         vb = vb.getParent();
340     }
341     if (vb == null) {
342         // This checks for a special case where include() has been
343
// called... this means there is NO ViewBean for a parent
344
// we attempt to find the ViewBean by...
345
String JavaDoc pageName = getPageName(request, request.getPathInfo());
346 // (String)request.getAttribute(PATH_INFO_ATTRIBUTE));
347
try {
348         vb = rc.getViewBeanManager().getViewBean(pageName);
349         } catch (Exception JavaDoc notFoundException) {
350         // ignore
351
}
352     }
353     if (vb == null) {
354         // ViewBean not in view tree!!!!
355
String JavaDoc msg = "Top View was not a ViewBean!";
356         if (desc != null) {
357         // We have a ViewDescriptor, give top ViewDescriptor name
358
ViewDescriptor topDesc = desc;
359         while (topDesc.getParent() != null) {
360             topDesc = topDesc.getParent();
361         }
362         msg = "Top View (as described by ViewDescriptor: '"+
363             topDesc.getName()+"') was not a ViewBean!";
364         }
365         ex = new FrameworkError(msg, ex);
366     }
367
368     // Get the root cause
369
Throwable JavaDoc root = ex;
370     Throwable JavaDoc next = ex;
371     while (next != null) {
372         root = next; // root will be non-null at the end
373
next = getRootCause(next);
374     }
375
376     // Get the root cause message / class name
377
// Don't show a root message if it is the same as the top
378
String JavaDoc rootMessage = (root == ex) ? null : root.getMessage();
379     String JavaDoc rootClass = (root == null) ? null : root.getClass().getName();
380
381     // Create/save the full stack trace
382
StackTraceElement JavaDoc elts[] = root.getStackTrace();
383     int len = elts.length;
384     StringBuffer JavaDoc fullTrace = new StringBuffer JavaDoc();
385     for (int count=0; count<len; count++) {
386         fullTrace.append("\t"+elts[count].toString()+"\n");
387     }
388
389     // Get/set the regular stack trace
390
StringWriter JavaDoc writer = new StringWriter JavaDoc();
391     ex.printStackTrace(new PrintWriter JavaDoc(writer));
392     String JavaDoc regTrace = writer.toString();
393
394     // Look for Error Handler, first find ViewDescriptor
395
if (desc == null) {
396         View tmpView = view;
397         String JavaDoc childName = null;
398         while ((tmpView != null) && !(tmpView instanceof DescriptorContainerView)) {
399         childName = tmpView.getName();
400         tmpView = tmpView.getParent();
401         }
402         if (tmpView != null) {
403         desc = ((DescriptorContainerView)tmpView).getViewDescriptor();
404         if (childName != null) {
405             // Try to walk back down the hierachy (one level only, b/c
406
// this is the first DescriptorContainerView -- any other
407
// containers below will not work)
408
if (desc.getChildDescriptor(childName) != null) {
409             desc = desc.getChildDescriptor(childName);
410             }
411         }
412         }
413     }
414     if (desc != null) {
415         // Ok, at this point we have a ViewDescriptor... find the nearest
416
// error handler
417
ViewDescriptor handlerDesc = desc;
418         ViewDescriptor tmpDesc = desc;
419         while ((handlerDesc != null) && (handlerDesc.getEventDescriptor(EventDescriptor.TYPES.ERROR) == null)) {
420             // No error handler for this view descriptor, look at parent
421
tmpDesc = handlerDesc.getParent();
422         if ((tmpDesc == null) && (vb != null) && (vb instanceof DescriptorContainerView)) {
423             // If we don't find one, check the ViewBean (we might not
424
// have access via the ViewDescriptors... such is the case
425
// when dealing with pagelets).
426
tmpDesc = ((DescriptorContainerView)vb).getViewDescriptor();
427         }
428         handlerDesc = tmpDesc;
429         }
430         if (handlerDesc != null) {
431         View descView = null;
432         // We found the nearest Error Event Handler! Use it.
433
try {
434             descView = handlerDesc.getView(rc);
435         } catch (Throwable JavaDoc ignoreThis) {
436             ex = new FrameworkError(
437             "Unable to get View for ViewDescriptor '"+
438             handlerDesc.getName()+"'", ex);
439         }
440         ErrorEvent errorEvent = new ErrorEvent(
441             descView, handlerDesc, (ViewBean)vb, ex, view, desc,
442             ex.getMessage(), ex.getClass().getName(), rootMessage,
443             rootClass, fullTrace.toString(), regTrace);
444         DescriptorViewHelper.dispatchEvent(
445             rc, descView, handlerDesc,
446             handlerDesc.getEventDescriptor(
447             EventDescriptor.TYPES.ERROR),
448             errorEvent);
449         return;
450         }
451     }
452
453     // No Error handlers defined. :(
454
// We'll try to use a default method on the Servlet
455
ErrorEvent errorEvent = new ErrorEvent(
456         null, null, (ViewBean)vb, ex, view, desc,
457         ex.getMessage(), ex.getClass().getName(), rootMessage,
458         rootClass, fullTrace.toString(), regTrace);
459     handleUncaughtException(errorEvent);
460     }
461
462     /**
463      * <p> This method is the "last chance" to invoke anything before
464      * processing stops. This implementation delegates to "afterRequest"
465      * handlers that are registered to the ViewBean (top-level
466      * ViewDescriptor).</p>
467      *
468      * This doesn't work, I can't get the VB that was forwardTo()'d. I can
469      * override this method in DescriptorViewBeanBase (and other base
470      * classes), but that defeats the point of putting this code here. I can
471      * also make ViewBeans RequestCompletionListeners and invoke this code.
472      * Since there currently isn't a requirement for page-level "afterRequest"
473      * events, I'm not going to implement this. This functionality does work
474      * at the command (button / href) level, this seems more desirable anyway.
475     protected void onAfterRequest(RequestContext rc) {
476     View vb = (View) rc.getRequest().getAttribute("viewBean");
477     if (vb instanceof DescriptorContainerView) {
478         ViewDescriptor desc =
479         ((DescriptorContainerView) vb).getViewDescriptor();
480         if (desc != null) {
481         // Fire After Request Event
482 // FIXME: Consider providing an EventObject, FYI: JATO does not
483         DescriptorViewHelper.dispatchEvent(rc, vb, desc,
484             desc.getEventDescriptor(EventDescriptor.TYPES.AFTER_REQUEST),
485             (EventObject) null);
486         }
487     }
488     }
489      */

490
491     /**
492      * "dtdURLBase" is a servlet init parameter that must be defined so that
493      * relative paths to dtds (the view.dtd) can be resolved. This does not
494      * have any effect on dtds used by other systems such as Lockhart.
495      */

496     public static final String JavaDoc DTD_URL_BASE = "dtdURLBase";
497
498     /**
499      * When an include() is called the PATH_INFO is set via a Request
500      * attribute named "javax.servlet.include.path_info". This constant is
501      * set to this name.
502      */

503     public static final String JavaDoc PATH_INFO_ATTRIBUTE =
504     "javax.servlet.include.path_info";
505 }
506
Popular Tags