KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > tomcat > internal > EclipseErrorReportValve


1 /* ====================================================================
2  *
3  * The Apache Software License, Version 1.1
4  *
5  * Copyright (c) 1999-2001 The Apache Software Foundation. All rights
6  * reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  * notice, this list of conditions and the following disclaimer in
17  * the documentation and/or other materials provided with the
18  * distribution.
19  *
20  * 3. The end-user documentation included with the redistribution, if
21  * any, must include the following acknowlegement:
22  * "This product includes software developed by the
23  * Apache Software Foundation (http://www.apache.org/)."
24  * Alternately, this acknowlegement may appear in the software itself,
25  * if and wherever such third-party acknowlegements normally appear.
26  *
27  * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
28  * Foundation" must not be used to endorse or promote products derived
29  * from this software without prior written permission. For written
30  * permission, please contact apache@apache.org.
31  *
32  * 5. Products derived from this software may not be called "Apache"
33  * nor may "Apache" appear in their names without prior written
34  * permission of the Apache Group.
35  *
36  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39  * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
40  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47  * SUCH DAMAGE.
48  * ====================================================================
49  *
50  * This software consists of voluntary contributions made by many
51  * individuals on behalf of the Apache Software Foundation. For more
52  * information on the Apache Software Foundation, please see
53  * <http://www.apache.org/>.
54  *
55  * Portion of this source code are:
56  *
57  * Copyright (c) 2003, 2004 IBM Corp.
58  * All rights reserved.
59  *
60  * Contributors:
61  * Remy Maucherat
62  * Craig R. McClanahan
63  * <a HREF="mailto:nicolaken@supereva.it">Nicola Ken Barozzi</a> Aisa
64  * <a HREF="mailto:stefano@apache.org">Stefano Mazzocchi</a>
65  * Konrad Kolosowski, IBM - friendly 404 message, no exception printed
66  */

67
68
69 package org.eclipse.tomcat.internal;
70
71
72 import java.io.*;
73 import java.util.*;
74
75 import javax.servlet.*;
76 import javax.servlet.http.*;
77
78 import org.apache.catalina.*;
79 import org.apache.catalina.util.*;
80 import org.apache.catalina.valves.*;
81 import org.eclipse.core.runtime.Platform;
82
83
84 /**
85  * <p>Implementation of a Valve that outputs HTML error pages.</p>
86  *
87  * <p>This Valve should be attached at the Host level, although it will work
88  * if attached to a Context.</p>
89  *
90  * <p>HTML code from the Cocoon 2 project.</p>
91  */

92
93 public class EclipseErrorReportValve
94     extends ValveBase {
95
96
97     // ----------------------------------------------------- Instance Variables
98

99
100     /**
101      * The debugging detail level for this component.
102      */

103     private int debug = 0;
104
105
106     /**
107      * The descriptive information related to this implementation.
108      */

109     private static final String JavaDoc info =
110     "org.eclipse.tomcat.internal.EclipseErrorReportValve"; //$NON-NLS-1$
111

112
113     /**
114      * The StringManager for this package.
115      */

116     protected static StringManager sm =
117         StringManager.getManager(Constants.Package);
118
119
120     // ------------------------------------------------------------- Properties
121

122
123     /**
124      * Return descriptive information about this Valve implementation.
125      */

126     public String JavaDoc getInfo() {
127
128         return (info);
129
130     }
131
132
133     // --------------------------------------------------------- Public Methods
134

135
136     /**
137      * Invoke the next Valve in the sequence. When the invoke returns, check
138      * the response state, and output an error report is necessary.
139      *
140      * @param request The servlet request to be processed
141      * @param response The servlet response to be created
142      * @param context The valve context used to invoke the next valve
143      * in the current processing pipeline
144      *
145      * @exception IOException if an input/output error occurs
146      * @exception ServletException if a servlet error occurs
147      */

148     public void invoke(Request request, Response response,
149                        ValveContext context)
150         throws IOException, ServletException {
151
152         // Perform the request
153
context.invokeNext(request, response);
154
155         ServletRequest sreq = (ServletRequest) request;
156         Throwable JavaDoc throwable =
157             (Throwable JavaDoc) sreq.getAttribute(Globals.EXCEPTION_ATTR);
158
159         ServletResponse sresp = (ServletResponse) response;
160         if (sresp.isCommitted()) {
161             return;
162         }
163
164         if (throwable != null) {
165
166             // The response is an error
167
response.setError();
168
169             // Reset the response (if possible)
170
try {
171                 sresp.reset();
172             } catch (IllegalStateException JavaDoc e) {
173                 ;
174             }
175
176             ServletResponse sresponse = (ServletResponse) response;
177             if (sresponse instanceof HttpServletResponse)
178                 ((HttpServletResponse) sresponse).sendError
179                     (HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
180
181         }
182
183         response.setSuspended(false);
184
185         try {
186             report(request, response, throwable);
187         } catch (Throwable JavaDoc tt) {
188             // tt.printStackTrace();
189
}
190
191     }
192
193
194     /**
195      * Return a String rendering of this object.
196      */

197     public String JavaDoc toString() {
198
199         StringBuffer JavaDoc sb = new StringBuffer JavaDoc("EclipseErrorReportValve["); //$NON-NLS-1$
200
sb.append(container.getName());
201         sb.append("]"); //$NON-NLS-1$
202
return (sb.toString());
203
204     }
205
206
207     // ------------------------------------------------------ Protected Methods
208

209
210     /**
211      * Prints out an error report.
212      *
213      * @param request The request being processed
214      * @param response The response being generated
215      * @param exception The exception that occurred (which possibly wraps
216      * a root cause exception
217      */

218     protected void report(Request request, Response response,
219                           Throwable JavaDoc throwable)
220         throws IOException {
221
222         // Do nothing on non-HTTP responses
223
if (!(response instanceof HttpResponse))
224             return;
225         HttpResponse hresponse = (HttpResponse) response;
226         if (!(response instanceof HttpServletResponse))
227             return;
228         HttpServletResponse hres = (HttpServletResponse) response;
229         int statusCode = hresponse.getStatus();
230         String JavaDoc message = RequestUtil.filter(hresponse.getMessage());
231         if (message == null)
232             message = ""; //$NON-NLS-1$
233

234         // Do nothing on a 1xx, 2xx and 3xx status
235
if (statusCode < 400)
236             return;
237
238         // FIXME: Reset part of the request
239
/*
240         try {
241             if (hresponse.isError())
242                 hresponse.reset(statusCode, message);
243         } catch (IllegalStateException e) {
244             ;
245         }
246 */

247
248         Throwable JavaDoc rootCause = null;
249
250         if (throwable != null) {
251
252             if (throwable instanceof ServletException)
253                 rootCause = ((ServletException) throwable).getRootCause();
254
255         }
256
257         // Do nothing if there is no report for the specified status code
258
String JavaDoc report = null;
259         try {
260             report = sm.getString("http." + statusCode, message); //$NON-NLS-1$
261
} catch (Throwable JavaDoc t) {
262             ;
263         }
264         if (report == null)
265             return;
266
267         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
268
269         sb.append("<html><head><title>"); //$NON-NLS-1$
270
sb.append(sm.getString("errorReportValve.errorReport")); //$NON-NLS-1$
271
sb.append("</title>"); //$NON-NLS-1$
272
if (statusCode == 404) {
273             sb.append("</head><body>"); //$NON-NLS-1$
274
sb.append(TomcatResources.noDocument);
275         } else {
276         sb.append("<STYLE><!--"); //$NON-NLS-1$
277
sb.append("H1{font-family : sans-serif,Arial,Tahoma;color : white;background-color : black;} "); //$NON-NLS-1$
278
sb.append("H3{font-family : sans-serif,Arial,Tahoma;color : white;background-color : black;} "); //$NON-NLS-1$
279
sb.append("BODY{font-family : sans-serif,Arial,Tahoma;color : black;background-color : white;} "); //$NON-NLS-1$
280
sb.append("B{color : white;background-color : black;} "); //$NON-NLS-1$
281
sb.append("HR{color : black;} "); //$NON-NLS-1$
282
sb.append("--></STYLE> "); //$NON-NLS-1$
283
sb.append("</head><body>"); //$NON-NLS-1$
284
sb.append("<h1>"); //$NON-NLS-1$
285
sb.append(sm.getString("errorReportValve.statusHeader", //$NON-NLS-1$
286
"" + statusCode, message)).append("</h1>"); //$NON-NLS-1$ //$NON-NLS-2$
287
sb.append("<HR size=\"1\" noshade>"); //$NON-NLS-1$
288
sb.append("<p><b>type</b> "); //$NON-NLS-1$
289
if (throwable != null) {
290             sb.append(sm.getString("errorReportValve.exceptionReport")); //$NON-NLS-1$
291
} else {
292             sb.append(sm.getString("errorReportValve.statusReport")); //$NON-NLS-1$
293
}
294         sb.append("</p>"); //$NON-NLS-1$
295
sb.append("<p><b>"); //$NON-NLS-1$
296
sb.append(sm.getString("errorReportValve.message")); //$NON-NLS-1$
297
sb.append("</b> <u>"); //$NON-NLS-1$
298
sb.append(message).append("</u></p>"); //$NON-NLS-1$
299
sb.append("<p><b>"); //$NON-NLS-1$
300
sb.append(sm.getString("errorReportValve.description")); //$NON-NLS-1$
301
sb.append("</b> <u>"); //$NON-NLS-1$
302
sb.append(report);
303         sb.append("</u></p>"); //$NON-NLS-1$
304

305         if (throwable != null) {
306             boolean selfHostingMode = false;
307             String JavaDoc[] args = Platform.getCommandLineArgs();
308             for (int i = 0; i < args.length; i++) {
309                 if ("-pdelaunch".equals(args[i])) { //$NON-NLS-1$
310
selfHostingMode = true;
311                     break;
312                 }
313             }
314             if (selfHostingMode) {
315             StringWriter stackTrace = new StringWriter();
316             throwable.printStackTrace(new PrintWriter(stackTrace));
317             sb.append("<p><b>"); //$NON-NLS-1$
318
sb.append(sm.getString("errorReportValve.exception")); //$NON-NLS-1$
319
sb.append("</b> <pre>"); //$NON-NLS-1$
320
sb.append(RequestUtil.filter(stackTrace.toString()));
321             sb.append("</pre></p>"); //$NON-NLS-1$
322
if (rootCause != null) {
323                 stackTrace = new StringWriter();
324                 rootCause.printStackTrace(new PrintWriter(stackTrace));
325                 sb.append("<p><b>"); //$NON-NLS-1$
326
sb.append(sm.getString("errorReportValve.rootCause")); //$NON-NLS-1$
327
sb.append("</b> <pre>"); //$NON-NLS-1$
328
sb.append(RequestUtil.filter(stackTrace.toString()));
329                 sb.append("</pre></p>"); //$NON-NLS-1$
330
}
331             }
332         }
333
334         }
335         sb.append("</body></html>"); //$NON-NLS-1$
336

337         try {
338
339             Writer writer = response.getReporter();
340
341             if (writer != null) {
342
343                 Locale locale = Locale.getDefault();
344
345                 try {
346                     hres.setContentType("text/html"); //$NON-NLS-1$
347
hres.setLocale(locale);
348                 } catch (Throwable JavaDoc t) {
349                     if (debug >= 1)
350                         log("status.setContentType", t); //$NON-NLS-1$
351
}
352
353                 // If writer is null, it's an indication that the response has
354
// been hard committed already, which should never happen
355
writer.write(sb.toString());
356                 writer.flush();
357
358             }
359
360         } catch (IOException e) {
361             ;
362         } catch (IllegalStateException JavaDoc e) {
363             ;
364         }
365
366     }
367
368
369     /**
370      * Log a message on the Logger associated with our Container (if any).
371      *
372      * @param message Message to be logged
373      */

374     protected void log(String JavaDoc message) {
375
376         Logger logger = container.getLogger();
377         if (logger != null)
378             logger.log(this.toString() + ": " + message); //$NON-NLS-1$
379
else
380             System.out.println(this.toString() + ": " + message); //$NON-NLS-1$
381

382     }
383
384
385     /**
386      * Log a message on the Logger associated with our Container (if any).
387      *
388      * @param message Message to be logged
389      * @param throwable Associated exception
390      */

391     protected void log(String JavaDoc message, Throwable JavaDoc throwable) {
392
393         Logger logger = container.getLogger();
394         if (logger != null)
395             logger.log(this.toString() + ": " + message, throwable); //$NON-NLS-1$
396
else {
397             System.out.println(this.toString() + ": " + message); //$NON-NLS-1$
398
throwable.printStackTrace(System.out);
399         }
400
401     }
402
403
404 }
405
Popular Tags