1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package javax.faces.webapp;
20
21 import java.util.Collections;
22 import java.util.LinkedList;
23 import java.util.Queue;
24 import java.util.logging.Level;
25 import java.util.logging.Logger;
26
27 import javax.el.ELException;
28 import javax.faces.FacesException;
29 import javax.faces.application.FacesMessage;
30 import javax.faces.component.UIComponent;
31 import javax.faces.component.UpdateModelException;
32 import javax.faces.context.ExceptionHandler;
33 import javax.faces.context.ExceptionHandlerFactory;
34 import javax.faces.event.AbortProcessingException;
35 import javax.faces.event.ExceptionQueuedEvent;
36 import javax.faces.event.ExceptionQueuedEventContext;
37 import javax.faces.event.SystemEvent;
38
39 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFWebConfigParam;
40
41
42
43
44 public class PreJsf2ExceptionHandlerFactory extends ExceptionHandlerFactory
45 {
46
47 public PreJsf2ExceptionHandlerFactory()
48 {
49 }
50
51
52
53
54 @Override
55 public ExceptionHandler getExceptionHandler()
56 {
57 return new PreJsf2ExceptionHandlerImpl();
58 }
59
60 private static class PreJsf2ExceptionHandlerImpl extends ExceptionHandler
61 {
62
63
64
65
66
67
68
69
70
71
72
73
74 private static final Logger log = Logger.getLogger(PreJsf2ExceptionHandlerImpl.class.getName());
75
76
77
78
79
80
81
82
83
84
85
86
87
88 @Deprecated
89 @JSFWebConfigParam(since="1.2.4",desc="Deprecated: use JSF 2.0 ExceptionHandler", deprecated=true)
90 private static final String ERROR_HANDLER_PARAMETER = "org.apache.myfaces.ERROR_HANDLER";
91
92 private Queue<ExceptionQueuedEvent> handled;
93 private Queue<ExceptionQueuedEvent> unhandled;
94 private ExceptionQueuedEvent handledAndThrown;
95
96 public PreJsf2ExceptionHandlerImpl()
97 {
98 }
99
100
101
102
103 @Override
104 public ExceptionQueuedEvent getHandledExceptionQueuedEvent()
105 {
106 return handledAndThrown;
107 }
108
109
110
111
112 @Override
113 public Iterable<ExceptionQueuedEvent> getHandledExceptionQueuedEvents()
114 {
115 return handled == null ? Collections.<ExceptionQueuedEvent>emptyList() : handled;
116 }
117
118
119
120
121 @Override
122 public Throwable getRootCause(Throwable t)
123 {
124 if (t == null)
125 {
126 throw new NullPointerException("t");
127 }
128
129 while (t != null)
130 {
131 Class<?> clazz = t.getClass();
132 if (!clazz.equals(FacesException.class) && !clazz.equals(ELException.class))
133 {
134 return t;
135 }
136
137 t = t.getCause();
138 }
139
140 return null;
141 }
142
143
144
145
146 @Override
147 public Iterable<ExceptionQueuedEvent> getUnhandledExceptionQueuedEvents()
148 {
149 return unhandled == null ? Collections.<ExceptionQueuedEvent>emptyList() : unhandled;
150 }
151
152
153
154
155
156
157
158
159
160
161
162
163
164 @Override
165 public void handle() throws FacesException
166 {
167 if (unhandled != null && !unhandled.isEmpty())
168 {
169 if (handled == null)
170 {
171 handled = new LinkedList<ExceptionQueuedEvent>();
172 }
173
174 FacesException toThrow = null;
175
176 do
177 {
178
179
180
181 ExceptionQueuedEvent event = unhandled.peek();
182 try
183 {
184
185 ExceptionQueuedEventContext context = event.getContext();
186
187
188 Throwable exception = context.getException();
189
190
191
192
193 if (exception instanceof UpdateModelException)
194 {
195 FacesMessage message = ((UpdateModelException) exception).getFacesMessage();
196
197 log.log(Level.SEVERE, message.getSummary(), exception.getCause());
198
199 UIComponent component = context.getComponent();
200 String clientId = null;
201 if (component != null)
202 {
203 clientId = component.getClientId(context.getContext());
204 }
205 context.getContext().addMessage(clientId, message);
206 }
207 else if (!shouldSkip(exception) && !context.inBeforePhase() && !context.inAfterPhase())
208 {
209
210 handledAndThrown = event;
211
212
213
214
215
216
217
218 toThrow = wrap(getRethrownException(exception));
219 break;
220 }
221 else
222 {
223
224
225 log.log(Level.SEVERE, exception.getClass().getName() + " occured while processing " +
226 (context.inBeforePhase() ? "beforePhase() of " :
227 (context.inAfterPhase() ? "afterPhase() of " : "")) +
228 "phase " + context.getPhaseId() + ": " +
229 "UIComponent-ClientId=" +
230 (context.getComponent() != null ?
231 context.getComponent().getClientId(context.getContext()) : "") + ", " +
232 "Message=" + exception.getMessage());
233
234 log.log(Level.SEVERE, exception.getMessage(), exception);
235 }
236 }
237 catch (Throwable t)
238 {
239
240
241 throw new FacesException("Could not perform the algorithm to handle the Exception", t);
242 }
243 finally
244 {
245
246
247 handled.add(event);
248 unhandled.remove(event);
249 }
250 } while (!unhandled.isEmpty());
251
252
253 if (toThrow != null)
254 {
255 throw toThrow;
256 }
257 }
258 }
259
260
261
262
263 @Override
264 public boolean isListenerForSource(Object source)
265 {
266 return source instanceof ExceptionQueuedEventContext;
267 }
268
269
270
271
272 @Override
273 public void processEvent(SystemEvent exceptionQueuedEvent) throws AbortProcessingException
274 {
275 if (unhandled == null)
276 {
277 unhandled = new LinkedList<ExceptionQueuedEvent>();
278 }
279
280 unhandled.add((ExceptionQueuedEvent)exceptionQueuedEvent);
281 }
282
283 protected Throwable getRethrownException(Throwable exception)
284 {
285
286
287 Throwable toRethrow = getRootCause(exception);
288 if (toRethrow == null)
289 {
290 toRethrow = exception;
291 }
292
293 return toRethrow;
294 }
295
296 protected FacesException wrap(Throwable exception)
297 {
298 if (exception instanceof FacesException)
299 {
300 return (FacesException) exception;
301 }
302 return new FacesException(exception);
303 }
304
305 protected boolean shouldSkip(Throwable exception)
306 {
307 return exception instanceof AbortProcessingException;
308 }
309 }
310 }