KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > tapestry > portlet > PortletExceptionPresenter


1 // Copyright 2005 The Apache Software Foundation
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
// http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14

15 package org.apache.tapestry.portlet;
16
17 import java.io.CharArrayWriter JavaDoc;
18 import java.io.IOException JavaDoc;
19 import java.io.PrintWriter JavaDoc;
20
21 import javax.portlet.ActionResponse;
22
23 import org.apache.hivemind.ApplicationRuntimeException;
24 import org.apache.tapestry.IMarkupWriter;
25 import org.apache.tapestry.IRequestCycle;
26 import org.apache.tapestry.describe.RenderStrategy;
27 import org.apache.tapestry.error.ErrorMessages;
28 import org.apache.tapestry.error.ExceptionPresenter;
29 import org.apache.tapestry.error.RequestExceptionReporter;
30 import org.apache.tapestry.markup.MarkupWriterSource;
31 import org.apache.tapestry.services.ServiceConstants;
32 import org.apache.tapestry.util.ContentType;
33 import org.apache.tapestry.util.exception.ExceptionAnalyzer;
34 import org.apache.tapestry.util.exception.ExceptionDescription;
35 import org.apache.tapestry.util.exception.ExceptionProperty;
36 import org.apache.tapestry.web.WebRequest;
37 import org.apache.tapestry.web.WebResponse;
38
39 /**
40  * Service used to present a runtime exception to the user. This is very tricky in the Portlet world
41  * because of the split between the action and render requests (much more likely to get an error
42  * during the action request than during the render request, but both are possible).
43  * <p>
44  * During an action request, this code will render the HTML markup for the exception into a buffer
45  * that is stored as persistent attribute in the portal session.
46  *
47  * @author Howard M. Lewis Ship
48  * @since 4.0
49  */

50 public class PortletExceptionPresenter implements ExceptionPresenter
51 {
52     private PortletRequestGlobals _globals;
53
54     private RenderStrategy _renderStrategy;
55
56     private WebRequest _request;
57
58     private RequestExceptionReporter _requestExceptionReporter;
59
60     private WebResponse _response;
61
62     private MarkupWriterSource _markupWriterSource;
63
64     public void presentException(IRequestCycle cycle, Throwable JavaDoc cause)
65     {
66         try
67         {
68             if (_globals.isRenderRequest())
69                 reportRenderRequestException(cycle, cause);
70             else
71                 reportActionRequestException(cycle, cause);
72         }
73         catch (Exception JavaDoc ex)
74         {
75             // Worst case scenario. The exception page itself is broken, leaving
76
// us with no option but to write the cause to the output.
77

78             // Also, write the exception thrown when redendering the exception
79
// page, so that can get fixed as well.
80

81             _requestExceptionReporter.reportRequestException(PortletMessages
82                     .errorReportingException(ex), ex);
83
84             // And throw the exception.
85

86             throw new ApplicationRuntimeException(ex.getMessage(), ex);
87         }
88
89         _requestExceptionReporter.reportRequestException(ErrorMessages
90                 .unableToProcessClientRequest(cause), cause);
91     }
92
93     private void reportActionRequestException(IRequestCycle cycle, Throwable JavaDoc cause)
94     {
95         CharArrayWriter JavaDoc caw = new CharArrayWriter JavaDoc();
96         PrintWriter JavaDoc pw = new PrintWriter JavaDoc(caw);
97
98         IMarkupWriter writer = _markupWriterSource
99                 .newMarkupWriter(pw, new ContentType("text/html"));
100
101         writeException(writer, cycle, cause);
102
103         writer.close();
104
105         String JavaDoc markup = caw.toString();
106
107         _request.getSession(true).setAttribute(
108                 PortletConstants.PORTLET_EXCEPTION_MARKUP_ATTRIBUTE,
109                 markup);
110
111         ActionResponse response = _globals.getActionResponse();
112
113         response.setRenderParameter(ServiceConstants.SERVICE, PortletConstants.EXCEPTION_SERVICE);
114     }
115
116     private void reportRenderRequestException(IRequestCycle cycle, Throwable JavaDoc cause)
117             throws IOException JavaDoc
118     {
119         PrintWriter JavaDoc pw = _response.getPrintWriter(new ContentType("text/html"));
120
121         IMarkupWriter writer = _markupWriterSource
122                 .newMarkupWriter(pw, new ContentType("text/html"));
123
124         writeException(writer, cycle, cause);
125     }
126
127     public void setGlobals(PortletRequestGlobals globals)
128     {
129         _globals = globals;
130     }
131
132     public void setRenderStrategy(RenderStrategy renderStrategy)
133     {
134         _renderStrategy = renderStrategy;
135     }
136
137     public void setRequest(WebRequest request)
138     {
139         _request = request;
140     }
141
142     public void setRequestExceptionReporter(RequestExceptionReporter requestExceptionReporter)
143     {
144         _requestExceptionReporter = requestExceptionReporter;
145     }
146
147     public void setResponse(WebResponse response)
148     {
149         _response = response;
150     }
151
152     public void setMarkupWriterSource(MarkupWriterSource markupWriterSource)
153     {
154         _markupWriterSource = markupWriterSource;
155     }
156
157     private void writeException(IMarkupWriter writer, IRequestCycle cycle,
158             ExceptionDescription exception, boolean showStackTrace)
159     {
160         writer.begin("div");
161         writer.attribute("class", "portlet-section-header");
162         writer.print(exception.getExceptionClassName());
163         writer.end();
164         writer.println();
165
166         writer.begin("div");
167         writer.attribute("class", "portlet-msg-error");
168         writer.print(exception.getMessage());
169         writer.end();
170         writer.println();
171
172         ExceptionProperty[] properties = exception.getProperties();
173
174         if (properties.length > 0)
175         {
176
177             writer.begin("table");
178             writer.attribute("class", "portlet-section-subheader");
179
180             for (int i = 0; i < properties.length; i++)
181             {
182                 writer.begin("tr");
183
184                 writer.attribute("class", i % 2 == 0 ? "portlet-section-body"
185                         : "portlet-section-alternate");
186
187                 writer.begin("th");
188                 writer.print(properties[i].getName());
189                 writer.end();
190                 writer.println();
191
192                 writer.begin("td");
193
194                 _renderStrategy.renderObject(properties[i].getValue(), writer, cycle);
195                 writer.end("tr");
196                 writer.println();
197             }
198
199             writer.end();
200             writer.println();
201         }
202
203         if (!showStackTrace)
204             return;
205
206         writer.begin("ul");
207
208         String JavaDoc[] trace = exception.getStackTrace();
209
210         for (int i = 0; i < trace.length; i++)
211         {
212             writer.begin("li");
213             writer.print(trace[i]);
214             writer.end();
215             writer.println();
216         }
217
218         writer.end();
219         writer.println();
220
221     }
222
223     private void writeException(IMarkupWriter writer, IRequestCycle cycle, Throwable JavaDoc cause)
224     {
225         ExceptionDescription[] exceptions = new ExceptionAnalyzer().analyze(cause);
226
227         for (int i = 0; i < exceptions.length; i++)
228             writeException(writer, cycle, exceptions[i], i + 1 == exceptions.length);
229     }
230
231 }
Popular Tags