001: /*
002:
003: This software is OSI Certified Open Source Software.
004: OSI Certified is a certification mark of the Open Source Initiative.
005:
006: The license (Mozilla version 1.0) can be read at the MMBase site.
007: See http://www.MMBase.org/license
008:
009: */
010: package org.mmbase.framework;
011:
012: import java.util.*;
013:
014: import javax.servlet.http.*;
015: import javax.servlet.jsp.*;
016: import javax.servlet.*;
017: import java.io.*;
018: import org.mmbase.bridge.NotFoundException;
019: import org.mmbase.util.functions.*;
020: import org.mmbase.util.transformers.*;
021: import org.mmbase.util.logging.Logger;
022: import org.mmbase.util.logging.Logging;
023:
024: /**
025: * If rendering of a block fails, for some reason, then this renderer can be used in stead, to
026: * present the error.
027: *
028: * @todo Its workings are similar to /mmbase/errorpages/500.jsp, and we should consider that these two
029: * share code.
030: *
031: * @author Michiel Meeuwissen
032: * @version $Id: ErrorRenderer.java,v 1.11 2008/02/23 12:44:03 michiel Exp $
033: * @since MMBase-1.9
034: */
035:
036: public class ErrorRenderer extends AbstractRenderer {
037: private static final Logger log = Logging
038: .getLoggerInstance(ErrorRenderer.class);
039:
040: protected final Error error;
041: protected final String url;
042:
043: public ErrorRenderer(Type t, Block parent, String u, int status,
044: String m) {
045: super (t, parent);
046: error = new Error(status, new Exception(m));
047: url = u;
048: }
049:
050: public ErrorRenderer(Type t, Block parent, String u, int status,
051: Throwable e) {
052: super (t, parent);
053: error = new Error(status, e);
054: url = u;
055: }
056:
057: public Parameter[] getParameters() {
058: return new Parameter[] { Parameter.RESPONSE, Parameter.REQUEST,
059: Parameter.LOCALE };
060: }
061:
062: public void render(Parameters blockParameters,
063: Parameters frameworkParameters, Writer w,
064: Renderer.WindowState state) throws FrameworkException {
065: switch (getType()) {
066: case BODY:
067: try {
068: HttpServletRequest request = blockParameters
069: .get(Parameter.REQUEST);
070: HttpServletResponse response = blockParameters
071: .get(Parameter.RESPONSE);
072: Locale locale = blockParameters.get(Parameter.LOCALE);
073: decorateIntro(request, w, "error");
074: w.write("<h1>" + error.status);
075: w.write(": ");
076: CharTransformer escape = new Xml(Xml.ESCAPE);
077: w.write(escape.transform(error.exception.getMessage()));
078: w.write(" ");
079: w.write(escape.transform(url));
080: w.write("</h1>");
081: w.write("<pre>");
082: error.getErrorReport(w, request, escape);
083: w.write("</pre>");
084: decorateOutro(request, w);
085: } catch (IOException eio) {
086: throw new FrameworkException(eio.getMessage(), eio);
087: }
088: break;
089: default:
090: }
091: }
092:
093: public String toString() {
094: return "ERROR " + error;
095: }
096:
097: public java.net.URI getUri() {
098: try {
099: return new java.net.URL(url).toURI();
100: } catch (Exception e) {
101: return null;
102: }
103: }
104:
105: public static class Error {
106: public int status;
107: public final Throwable exception;
108:
109: public Error(int s, Throwable e) {
110: status = s;
111: exception = e;
112: }
113:
114: public Writer getErrorReport(Writer msg,
115: final HttpServletRequest request, CharTransformer escape)
116: throws IOException {
117:
118: String ticket = new Date().toString();
119: Throwable e = exception;
120: Stack stack = new Stack();
121: while (e != null) {
122: stack.push(e);
123: if (e instanceof NotFoundException) {
124: status = HttpServletResponse.SC_NOT_FOUND;
125: }
126: if (e instanceof ServletException) {
127: Throwable t = ((ServletException) e).getRootCause();
128: if (t == null)
129: t = e.getCause();
130: e = t;
131: } else if (e instanceof javax.servlet.jsp.JspException) {
132: Throwable t = ((JspException) e).getRootCause();
133: if (t == null)
134: t = e.getCause();
135: e = t;
136: } else {
137: e = e.getCause();
138: }
139: }
140:
141: msg.append("Headers\n----------\n");
142: // request properties
143: Enumeration en = request.getHeaderNames();
144: while (en.hasMoreElements()) {
145: String name = (String) en.nextElement();
146: msg.append(escape.transform(name + ": "
147: + request.getHeader(name) + "\n"));
148: }
149:
150: msg.append("\nAttributes\n----------\n");
151: Enumeration en2 = request.getAttributeNames();
152: while (en2.hasMoreElements()) {
153: String name = (String) en2.nextElement();
154: msg.append(escape.transform(name + ": "
155: + request.getAttribute(name) + "\n"));
156: }
157: msg.append("\n");
158: msg.append("Misc. properties\n----------\n");
159:
160: msg.append("method: ").append(
161: escape.transform(request.getMethod())).append("\n");
162: msg.append("querystring: ").append(
163: escape.transform(request.getQueryString())).append(
164: "\n");
165: msg.append("requesturl: ").append(
166: escape
167: .transform(request.getRequestURL()
168: .toString())).append("\n");
169: msg.append("mmbase version: ").append(
170: org.mmbase.Version.get()).append("\n");
171: msg.append("status: ").append("" + status).append("\n\n");
172:
173: msg.append("Parameters\n----------\n");
174: // request parameters
175: en = request.getParameterNames();
176: while (en.hasMoreElements()) {
177: String name = (String) en.nextElement();
178: msg.append(name).append(": ").append(
179: escape.transform(request.getParameter(name)))
180: .append("\n");
181: }
182: msg.append("\nException\n----------\n\n"
183: + (exception != null ? (escape.transform(exception
184: .getClass().getName())) : "NO EXCEPTION")
185: + ": ");
186:
187: while (!stack.isEmpty()) {
188:
189: Throwable t = (Throwable) stack.pop();
190: // add stack stacktraces
191: if (t != null) {
192: String message = t.getMessage();
193: String title = message;
194: if (title == null) {
195: StackTraceElement el = t.getStackTrace()[0];
196: title = t.getClass().getName().substring(
197: t.getClass().getPackage().getName()
198: .length() + 1)
199: + " "
200: + el.getFileName()
201: + ":"
202: + el.getLineNumber();
203: }
204: msg.append(escape.transform(message)).append("\n");
205: msg.append(escape
206: .transform(org.mmbase.util.logging.Logging
207: .stackTrace(t)));
208: if (!stack.isEmpty()) {
209: msg.append("\n-------caused:\n");
210: }
211: }
212: }
213: // write errors to mmbase log
214: if (status == 500) {
215: log.error(ticket + ":\n" + msg);
216: }
217: return msg;
218: }
219: }
220:
221: }
|