1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.tomahawk.util;
20
21 import java.io.IOException;
22 import java.lang.reflect.InvocationTargetException;
23 import java.lang.reflect.Method;
24 import java.util.Iterator;
25 import java.util.List;
26
27 import javax.faces.FacesException;
28 import javax.faces.FactoryFinder;
29 import javax.faces.application.NavigationHandler;
30 import javax.faces.context.FacesContext;
31 import javax.faces.el.ValueBinding;
32 import javax.faces.lifecycle.Lifecycle;
33 import javax.faces.lifecycle.LifecycleFactory;
34 import javax.faces.webapp.FacesServlet;
35 import javax.servlet.ServletException;
36
37 import org.apache.commons.logging.Log;
38 import org.apache.commons.logging.LogFactory;
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68 public class ErrorRedirectJSFPageHandler
69 {
70 private static final Log log = LogFactory
71 .getLog(ErrorRedirectJSFPageHandler.class);
72
73
74
75
76
77
78
79 private static final String ERROR_HANDLING_IGNORE_BASE_ERROR_REDIRECT = "org.apache.myfaces.ERROR_HANDLING_IGNORE_BASE_ERROR_REDIRECT";
80
81 private static final String ERROR_REDIRECT_ALTERNATE_HANDLER_PARAMETER = "org.apache.myfaces.ERROR_REDIRECT_ALTERNATE_HANDLER";
82
83 private static String getErrorRedirectAlternateHandler(FacesContext context)
84 {
85 String errorHandlerClass = context.getExternalContext().getInitParameter(ERROR_REDIRECT_ALTERNATE_HANDLER_PARAMETER);
86 return errorHandlerClass;
87 }
88
89 private static boolean isIgnoreBaseErrorRedirect(FacesContext context)
90 {
91 return getBooleanValue(context.getExternalContext().getInitParameter(
92 ERROR_HANDLING_IGNORE_BASE_ERROR_REDIRECT), false);
93 }
94
95 private static boolean getBooleanValue(String initParameter,
96 boolean defaultVal)
97 {
98 if (initParameter == null || initParameter.trim().length() == 0)
99 return defaultVal;
100
101 return (initParameter.equalsIgnoreCase("on")
102 || initParameter.equals("1") || initParameter
103 .equalsIgnoreCase("true"));
104 }
105
106 public static void handleException(FacesContext facesContext, Exception e)
107 throws ServletException, IOException
108 {
109 boolean oldRenderResponse = facesContext.getRenderResponse();
110 ExceptionContext exceptionContext = new ExceptionContext(e,
111 facesContext.getViewRoot());
112
113 if (!handleCauseOrThrowable(facesContext, exceptionContext, e,
114 oldRenderResponse, isIgnoreBaseErrorRedirect(facesContext)))
115 {
116
117 String errorHandlerClass = getErrorRedirectAlternateHandler(facesContext);
118 if (errorHandlerClass == null)
119 {
120
121 try
122 {
123 Class clazz = Class.forName(errorHandlerClass);
124
125 Object errorHandler = clazz.newInstance();
126
127 Method m = clazz.getMethod("handleException", new Class[]{FacesContext.class,Exception.class});
128 m.invoke(errorHandler, new Object[]{facesContext, e});
129 }
130 catch(ClassNotFoundException ex)
131 {
132 throw new ServletException("Error-Handler : "
133 +errorHandlerClass
134 + " was not found. Fix your web.xml-parameter : "+ERROR_REDIRECT_ALTERNATE_HANDLER_PARAMETER,ex);
135 }
136 catch (IllegalAccessException ex)
137 {
138 throw new ServletException("Constructor of error-Handler : "
139 +errorHandlerClass+ " is not accessible. Error-Handler is specified in web.xml-parameter : "
140 +ERROR_REDIRECT_ALTERNATE_HANDLER_PARAMETER,ex);
141 }
142 catch (InstantiationException ex)
143 {
144 throw new ServletException("Error-Handler : "
145 +errorHandlerClass
146 + " could not be instantiated. Error-Handler is specified in web.xml-parameter : "
147 +ERROR_REDIRECT_ALTERNATE_HANDLER_PARAMETER,ex);
148 }
149 catch (NoSuchMethodException ex)
150 {
151 log.error("Error-Handler : "
152 +errorHandlerClass
153 + " did not have a method with name : handleException and parameters : javax.faces.context.FacesContext, java.lang.Exception. Error-Handler is specified in web.xml-parameter : "
154 +ERROR_REDIRECT_ALTERNATE_HANDLER_PARAMETER,ex);
155
156 handleThrowable(facesContext, ex);
157 }
158 catch (InvocationTargetException ex)
159 {
160 throw new ServletException("Excecution of method handleException in Error-Handler : "
161 +errorHandlerClass
162 + " caused an exception. Error-Handler is specified in web.xml-parameter : "
163 +ERROR_REDIRECT_ALTERNATE_HANDLER_PARAMETER,ex);
164 }
165 }
166 else
167 {
168
169
170 ErrorPageWriter.throwException(e);
171 }
172 }
173 }
174
175 public static void handleThrowable(FacesContext facesContext, Throwable e)
176 throws ServletException, IOException
177 {
178 boolean oldRenderResponse = facesContext.getRenderResponse();
179 ExceptionContext exceptionContext = new ExceptionContext(e,
180 facesContext.getViewRoot());
181
182 if (!handleCauseOrThrowable(facesContext, exceptionContext, e,
183 oldRenderResponse, isIgnoreBaseErrorRedirect(facesContext)))
184 {
185
186 String errorHandlerClass = getErrorRedirectAlternateHandler(facesContext);
187 if (errorHandlerClass == null)
188 {
189 try {
190 Class clazz = Class.forName(errorHandlerClass);
191
192 Object errorHandler = clazz.newInstance();
193
194 Method m = clazz.getMethod("handleThrowable", new Class[]{FacesContext.class,Throwable.class});
195 m.invoke(errorHandler, new Object[]{facesContext, e});
196 }
197 catch(ClassNotFoundException ex) {
198 throw new ServletException("Error-Handler : "
199 +errorHandlerClass
200 + " was not found. Fix your web.xml-parameter : "+ERROR_REDIRECT_ALTERNATE_HANDLER_PARAMETER,ex);
201 } catch (IllegalAccessException ex) {
202 throw new ServletException("Constructor of error-Handler : "
203 +errorHandlerClass
204 + " is not accessible. Error-Handler is specified in web.xml-parameter : "
205 +ERROR_REDIRECT_ALTERNATE_HANDLER_PARAMETER,ex);
206 } catch (InstantiationException ex) {
207 throw new ServletException("Error-Handler : "
208 +errorHandlerClass
209 + " could not be instantiated. Error-Handler is specified in web.xml-parameter : "
210 +ERROR_REDIRECT_ALTERNATE_HANDLER_PARAMETER,ex);
211 } catch (NoSuchMethodException ex) {
212 throw new ServletException("Error-Handler : "
213 +errorHandlerClass
214 + " did not have a method with name : handleException and parameters : javax.faces.context.FacesContext, java.lang.Exception. Error-Handler is specified in web.xml-parameter : "
215 +ERROR_REDIRECT_ALTERNATE_HANDLER_PARAMETER,ex);
216 } catch (InvocationTargetException ex) {
217 throw new ServletException("Excecution of method handleException in Error-Handler : "
218 +errorHandlerClass
219 + " threw an exception. Error-Handler is specified in web.xml-parameter : "
220 +ERROR_REDIRECT_ALTERNATE_HANDLER_PARAMETER,ex);
221 }
222 }
223 else
224 {
225
226
227 ErrorPageWriter.throwException(e);
228 }
229 }
230 }
231
232 public static void handleExceptionList(FacesContext facesContext,
233 List exceptionList) throws ServletException, IOException
234 {
235 boolean isHandleCauseOrThrowable = false;
236
237
238
239 for (Iterator it = exceptionList.iterator(); it.hasNext();)
240 {
241 Exception ex = (Exception) it.next();
242
243 boolean oldRenderResponse = facesContext.getRenderResponse();
244 ExceptionContext exceptionContext = new ExceptionContext(ex,
245 facesContext.getViewRoot());
246
247 isHandleCauseOrThrowable = handleCauseOrThrowable(facesContext,
248 exceptionContext, ex, oldRenderResponse,
249 isIgnoreBaseErrorRedirect(facesContext));
250
251 if (isHandleCauseOrThrowable)
252 break;
253 }
254
255 if (!isHandleCauseOrThrowable)
256 {
257
258
259
260
261 String errorHandlerClass = getErrorRedirectAlternateHandler(facesContext);
262 if(errorHandlerClass != null) {
263 try {
264 Class clazz = Class.forName(errorHandlerClass);
265
266 Object errorHandler = clazz.newInstance();
267
268 Method m = clazz.getMethod("handleExceptionList", new Class[]{FacesContext.class,Exception.class});
269 m.invoke(errorHandler, new Object[]{facesContext, exceptionList});
270 }
271 catch(ClassNotFoundException ex) {
272 throw new ServletException("Error-Handler : "
273 +errorHandlerClass
274 + " was not found. Fix your web.xml-parameter : "
275 +ERROR_REDIRECT_ALTERNATE_HANDLER_PARAMETER,ex);
276 } catch (IllegalAccessException ex) {
277 throw new ServletException("Constructor of error-Handler : "
278 +errorHandlerClass
279 + " is not accessible. Error-Handler is specified in web.xml-parameter : "
280 +ERROR_REDIRECT_ALTERNATE_HANDLER_PARAMETER,ex);
281 } catch (InstantiationException ex) {
282 throw new ServletException("Error-Handler : "
283 +errorHandlerClass
284 + " could not be instantiated. Error-Handler is specified in web.xml-parameter : "
285 +ERROR_REDIRECT_ALTERNATE_HANDLER_PARAMETER,ex);
286 } catch (NoSuchMethodException ex) {
287
288
289 throw (FacesException) exceptionList.get(0);
290 } catch (InvocationTargetException ex) {
291 throw new ServletException("Excecution of method handleException in Error-Handler : "
292 +errorHandlerClass
293 + " threw an exception. Error-Handler is specified in web.xml-parameter : "
294 +ERROR_REDIRECT_ALTERNATE_HANDLER_PARAMETER,ex);
295 }
296 }
297 else
298 {
299 ErrorPageWriter.throwException((Exception) exceptionList.get(0));
300 }
301 }
302 }
303
304 private static String getLifecycleId(FacesContext context)
305 {
306 String lifecycleId = context.getExternalContext().getInitParameter(
307 FacesServlet.LIFECYCLE_ID_ATTR);
308 return lifecycleId != null ? lifecycleId
309 : LifecycleFactory.DEFAULT_LIFECYCLE;
310 }
311
312 private static boolean handleCauseOrThrowable(FacesContext context,
313 ExceptionContext exceptionContext, Throwable th,
314 boolean oldRenderResponse, boolean ignoreBaseException)
315 {
316
317 boolean throwableHandled = false;
318
319 if (th.getCause() != null)
320 {
321 throwableHandled = handleCauseOrThrowable(context,
322 exceptionContext, th.getCause(), oldRenderResponse,
323 ignoreBaseException);
324 }
325
326 if (throwableHandled == false)
327 {
328 Class thClass = th.getClass();
329 while (thClass != null)
330 {
331
332 if (ignoreBaseException
333 && thClass.getName().startsWith("java.lang."))
334 {
335 return false;
336 }
337 log.info("Trying to redirect to jsf page:" + thClass.getName());
338 NavigationHandler nh = context.getApplication()
339 .getNavigationHandler();
340 nh.handleNavigation(context, null, thClass.getName());
341
342
343
344 if (context.getRenderResponse())
345 {
346
347 log.error("an error occurred : ", th);
348
349 ValueBinding vb = context.getApplication()
350 .createValueBinding("#{exceptionContext}");
351
352 vb.setValue(context, exceptionContext);
353
354 LifecycleFactory lifecycleFactory = (LifecycleFactory) FactoryFinder
355 .getFactory(FactoryFinder.LIFECYCLE_FACTORY);
356 Lifecycle _lifecycle = lifecycleFactory
357 .getLifecycle(getLifecycleId(context));
358 _lifecycle.render(context);
359
360 vb.setValue(context, null);
361
362 context.responseComplete();
363 return true;
364 }
365 thClass = thClass.getSuperclass();
366 }
367 }
368 return throwableHandled;
369 }
370 }