1 | |
|
2 | |
|
3 | |
|
4 | |
|
5 | |
|
6 | |
|
7 | |
|
8 | |
|
9 | |
|
10 | |
|
11 | |
|
12 | |
|
13 | |
|
14 | |
|
15 | |
|
16 | |
|
17 | |
|
18 | |
|
19 | |
package org.apache.myfaces.renderkit; |
20 | |
|
21 | |
import java.beans.BeanInfo; |
22 | |
import java.beans.Introspector; |
23 | |
import java.beans.PropertyDescriptor; |
24 | |
import java.io.ByteArrayOutputStream; |
25 | |
import java.io.IOException; |
26 | |
import java.io.InputStream; |
27 | |
import java.io.PrintWriter; |
28 | |
import java.io.Serializable; |
29 | |
import java.io.StringWriter; |
30 | |
import java.io.Writer; |
31 | |
import java.lang.reflect.Method; |
32 | |
import java.text.DateFormat; |
33 | |
import java.util.ArrayList; |
34 | |
import java.util.Arrays; |
35 | |
import java.util.Collection; |
36 | |
import java.util.Date; |
37 | |
import java.util.EnumSet; |
38 | |
import java.util.HashMap; |
39 | |
import java.util.Iterator; |
40 | |
import java.util.List; |
41 | |
import java.util.Map; |
42 | |
import java.util.SortedMap; |
43 | |
import java.util.TreeMap; |
44 | |
import java.util.logging.Level; |
45 | |
import java.util.logging.Logger; |
46 | |
import java.util.regex.Matcher; |
47 | |
import java.util.regex.Pattern; |
48 | |
|
49 | |
import javax.el.Expression; |
50 | |
import javax.el.ValueExpression; |
51 | |
import javax.faces.FacesException; |
52 | |
import javax.faces.component.EditableValueHolder; |
53 | |
import javax.faces.component.UIColumn; |
54 | |
import javax.faces.component.UIComponent; |
55 | |
import javax.faces.component.UIData; |
56 | |
import javax.faces.component.UIViewRoot; |
57 | |
import javax.faces.component.visit.VisitCallback; |
58 | |
import javax.faces.component.visit.VisitContext; |
59 | |
import javax.faces.component.visit.VisitHint; |
60 | |
import javax.faces.component.visit.VisitResult; |
61 | |
import javax.faces.context.ExternalContext; |
62 | |
import javax.faces.context.FacesContext; |
63 | |
import javax.faces.context.PartialResponseWriter; |
64 | |
import javax.faces.context.ResponseWriter; |
65 | |
import javax.faces.el.MethodBinding; |
66 | |
import javax.faces.el.ValueBinding; |
67 | |
import javax.faces.render.Renderer; |
68 | |
import javax.faces.view.Location; |
69 | |
import javax.servlet.http.HttpServletResponse; |
70 | |
|
71 | |
import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFWebConfigParam; |
72 | |
import org.apache.myfaces.lifecycle.ViewNotFoundException; |
73 | |
import org.apache.myfaces.shared.config.MyfacesConfig; |
74 | |
import org.apache.myfaces.shared.renderkit.html.HtmlResponseWriterImpl; |
75 | |
import org.apache.myfaces.shared.util.ClassUtils; |
76 | |
import org.apache.myfaces.shared.util.StateUtils; |
77 | |
import org.apache.myfaces.spi.WebConfigProvider; |
78 | |
import org.apache.myfaces.spi.WebConfigProviderFactory; |
79 | |
import org.apache.myfaces.view.facelets.component.UIRepeat; |
80 | |
import org.apache.myfaces.view.facelets.el.ContextAware; |
81 | |
|
82 | |
|
83 | |
|
84 | |
|
85 | |
|
86 | |
|
87 | |
|
88 | |
|
89 | 0 | public final class ErrorPageWriter |
90 | |
{ |
91 | |
|
92 | |
|
93 | |
|
94 | |
|
95 | |
|
96 | |
|
97 | |
|
98 | |
|
99 | |
|
100 | |
|
101 | 0 | public static class ErrorPageBean implements Serializable |
102 | |
{ |
103 | |
|
104 | |
private static final long serialVersionUID = -79513324193326616L; |
105 | |
|
106 | |
public String getErrorPageHtml() throws IOException |
107 | |
{ |
108 | 0 | FacesContext facesContext = FacesContext.getCurrentInstance(); |
109 | 0 | Map<String, Object> requestMap = facesContext.getExternalContext().getRequestMap(); |
110 | |
|
111 | 0 | Throwable t = (Throwable) requestMap.get(EXCEPTION_KEY); |
112 | 0 | if (t == null) |
113 | |
{ |
114 | 0 | throw new IllegalStateException("No Exception to handle"); |
115 | |
} |
116 | |
|
117 | 0 | UIViewRoot view = (UIViewRoot) requestMap.get(VIEW_KEY); |
118 | |
|
119 | 0 | StringWriter writer = new StringWriter(); |
120 | 0 | ErrorPageWriter.debugHtml(writer, facesContext, view, null, t); |
121 | 0 | String html = writer.toString(); |
122 | |
|
123 | |
|
124 | |
String body; |
125 | |
try |
126 | |
{ |
127 | 0 | body = html.substring(html.indexOf("<body>") + "<body>".length(), html.indexOf("</body>")); |
128 | |
} |
129 | 0 | catch (Exception e) |
130 | |
{ |
131 | |
|
132 | 0 | return html; |
133 | 0 | } |
134 | |
|
135 | |
String head; |
136 | |
try |
137 | |
{ |
138 | 0 | head = html.substring(html.indexOf("<head>") + "<head>".length(), html.indexOf("</head>")); |
139 | |
} |
140 | 0 | catch (Exception e) |
141 | |
{ |
142 | |
|
143 | 0 | return body; |
144 | 0 | } |
145 | |
|
146 | |
|
147 | 0 | StringBuilder builder = new StringBuilder(body); |
148 | |
|
149 | 0 | int startIndex = 0; |
150 | |
while (true) |
151 | |
{ |
152 | |
try |
153 | |
{ |
154 | 0 | int endIndex = head.indexOf("</style>", startIndex) + "</style>".length(); |
155 | 0 | builder.append(head.substring(head.indexOf("<style", startIndex), endIndex)); |
156 | 0 | startIndex = endIndex; |
157 | |
} |
158 | 0 | catch (Exception e) |
159 | |
{ |
160 | |
|
161 | 0 | break; |
162 | 0 | } |
163 | |
} |
164 | |
|
165 | 0 | startIndex = 0; |
166 | |
while (true) |
167 | |
{ |
168 | |
try |
169 | |
{ |
170 | 0 | int endIndex = head.indexOf("</script>", startIndex) + "</script>".length(); |
171 | 0 | builder.append(head.substring(head.indexOf("<script", startIndex), endIndex)); |
172 | 0 | startIndex = endIndex; |
173 | |
} |
174 | 0 | catch (Exception e) |
175 | |
{ |
176 | |
|
177 | 0 | break; |
178 | 0 | } |
179 | |
} |
180 | |
|
181 | 0 | return builder.toString(); |
182 | |
} |
183 | |
|
184 | |
} |
185 | |
|
186 | |
|
187 | |
|
188 | |
|
189 | |
public static final String ERROR_PAGE_BEAN_KEY = "__myFacesErrorPageBean"; |
190 | |
|
191 | |
private static final String EXCEPTION_KEY = "javax.servlet.error.exception"; |
192 | |
public static final String VIEW_KEY = "org.apache.myfaces.error.UIViewRoot"; |
193 | |
|
194 | 0 | private static final Logger log = Logger.getLogger(ErrorPageWriter.class.getName()); |
195 | |
|
196 | |
private final static String TS = "<"; |
197 | |
|
198 | |
private static final String ERROR_TEMPLATE = "META-INF/rsc/myfaces-dev-error.xml"; |
199 | |
|
200 | |
|
201 | |
|
202 | |
|
203 | |
|
204 | |
|
205 | |
|
206 | |
|
207 | |
@JSFWebConfigParam(defaultValue="META-INF/rsc/myfaces-dev-error.xml", since="1.2.4") |
208 | |
private static final String ERROR_TEMPLATE_RESOURCE = "org.apache.myfaces.ERROR_TEMPLATE_RESOURCE"; |
209 | |
|
210 | |
private static String[] errorParts; |
211 | |
|
212 | |
private static final String DEBUG_TEMPLATE = "META-INF/rsc/myfaces-dev-debug.xml"; |
213 | |
|
214 | |
|
215 | |
|
216 | |
|
217 | |
@JSFWebConfigParam(defaultValue="META-INF/rsc/myfaces-dev-debug.xml", since="1.2.4") |
218 | |
private static final String DEBUG_TEMPLATE_RESOURCE = "org.apache.myfaces.DEBUG_TEMPLATE_RESOURCE"; |
219 | |
|
220 | |
private static String[] debugParts; |
221 | |
|
222 | |
private static final String REGEX_PATTERN = ".*?\\Q,Id:\\E\\s*(\\S+)\\s*\\].*?"; |
223 | |
|
224 | 0 | private final static String[] IGNORE = new String[] { "parent", "rendererType" }; |
225 | |
|
226 | 0 | private final static String[] ALWAYS_WRITE = new String[] { "class", "clientId" }; |
227 | |
|
228 | |
|
229 | |
|
230 | |
|
231 | |
|
232 | |
|
233 | |
public static final String DEBUG_INFO_KEY = "org.apache.myfaces.debug.DEBUG_INFO"; |
234 | |
|
235 | |
|
236 | |
|
237 | |
|
238 | |
|
239 | |
|
240 | |
private static final String VISITED_FACET_COUNT_KEY = "org.apache.myfaces.debug.VISITED_FACET_COUNT"; |
241 | |
|
242 | |
|
243 | |
|
244 | |
|
245 | |
|
246 | |
|
247 | |
@JSFWebConfigParam(defaultValue="false, on Development Project stage: true", |
248 | |
expectedValues="true,false", since="1.2.4") |
249 | |
public static final String ERROR_HANDLING_PARAMETER = "org.apache.myfaces.ERROR_HANDLING"; |
250 | |
|
251 | |
public ErrorPageWriter() |
252 | |
{ |
253 | 0 | super(); |
254 | 0 | } |
255 | |
|
256 | |
|
257 | |
|
258 | |
|
259 | |
|
260 | |
|
261 | |
|
262 | |
|
263 | |
|
264 | |
public static void debugHtml(Writer writer, FacesContext faces, Throwable e) throws IOException |
265 | |
{ |
266 | 0 | debugHtml(writer, faces, faces.getViewRoot(), null, e); |
267 | 0 | } |
268 | |
|
269 | |
private static void debugHtml(Writer writer, FacesContext faces, UIViewRoot view, |
270 | |
Collection<UIComponent> components, Throwable... exs) throws IOException |
271 | |
{ |
272 | 0 | _init(faces); |
273 | 0 | Date now = new Date(); |
274 | |
|
275 | 0 | for (int i = 0; i < errorParts.length; i++) |
276 | |
{ |
277 | 0 | if ("view".equals((errorParts[i]))) |
278 | |
{ |
279 | 0 | if (faces.getViewRoot() != null) |
280 | |
{ |
281 | 0 | String viewId = faces.getViewRoot().getViewId(); |
282 | 0 | writer.write("viewId=" + viewId); |
283 | 0 | writer.write("<br/>"); |
284 | 0 | String realPath = null; |
285 | |
try |
286 | |
{ |
287 | |
|
288 | 0 | realPath = faces.getExternalContext().getRealPath(viewId); |
289 | |
} |
290 | 0 | catch(Throwable e) |
291 | |
{ |
292 | |
|
293 | 0 | } |
294 | 0 | if (realPath != null) |
295 | |
{ |
296 | 0 | writer.write("location=" + realPath); |
297 | 0 | writer.write("<br/>"); |
298 | |
} |
299 | 0 | writer.write("phaseId=" + faces.getCurrentPhaseId()); |
300 | 0 | writer.write("<br/>"); |
301 | 0 | writer.write("<br/>"); |
302 | 0 | } |
303 | |
} |
304 | 0 | else if ("message".equals(errorParts[i])) |
305 | |
{ |
306 | 0 | boolean printed = false; |
307 | |
|
308 | |
|
309 | |
|
310 | |
|
311 | |
|
312 | 0 | for (Throwable e : exs) |
313 | |
{ |
314 | 0 | String msg = e.getMessage(); |
315 | 0 | if (printed) |
316 | |
{ |
317 | 0 | writer.write("<br/>"); |
318 | |
} |
319 | 0 | if (msg != null) |
320 | |
{ |
321 | 0 | writer.write(msg.replaceAll("<", TS)); |
322 | |
} |
323 | |
else |
324 | |
{ |
325 | 0 | writer.write(e.getClass().getName()); |
326 | |
} |
327 | 0 | printed = true; |
328 | |
} |
329 | 0 | } |
330 | 0 | else if ("trace".equals(errorParts[i])) |
331 | |
{ |
332 | 0 | boolean printed = false; |
333 | 0 | for (Throwable e : exs) |
334 | |
{ |
335 | 0 | if (printed) |
336 | |
{ |
337 | 0 | writer.write("\n"); |
338 | |
} |
339 | 0 | _writeException(writer, e); |
340 | 0 | printed = true; |
341 | |
} |
342 | 0 | } |
343 | 0 | else if ("now".equals(errorParts[i])) |
344 | |
{ |
345 | 0 | writer.write(DateFormat.getDateTimeInstance().format(now)); |
346 | |
} |
347 | 0 | else if ("tree".equals(errorParts[i])) |
348 | |
{ |
349 | 0 | if (view != null) |
350 | |
{ |
351 | 0 | List<String> errorIds = _getErrorId(components, exs); |
352 | 0 | _writeComponent(faces, writer, view, errorIds, true); |
353 | 0 | } |
354 | |
} |
355 | 0 | else if ("vars".equals(errorParts[i])) |
356 | |
{ |
357 | 0 | _writeVariables(writer, faces, view); |
358 | |
} |
359 | 0 | else if ("cause".equals(errorParts[i])) |
360 | |
{ |
361 | 0 | boolean printed = false; |
362 | 0 | Iterator<UIComponent> iterator = null; |
363 | 0 | if (components != null) |
364 | |
{ |
365 | 0 | iterator = components.iterator(); |
366 | |
} |
367 | 0 | for (Throwable e : exs) |
368 | |
{ |
369 | 0 | if (printed) |
370 | |
{ |
371 | 0 | writer.write("<br/>"); |
372 | |
} |
373 | 0 | _writeCause(writer, e); |
374 | 0 | if (iterator != null) |
375 | |
{ |
376 | 0 | UIComponent uiComponent = iterator.next(); |
377 | 0 | if (uiComponent != null) |
378 | |
{ |
379 | 0 | _writeComponent(faces, writer, uiComponent, null, false); |
380 | |
} |
381 | |
} |
382 | 0 | printed = true; |
383 | |
} |
384 | 0 | } |
385 | |
else |
386 | |
{ |
387 | 0 | writer.write(errorParts[i]); |
388 | |
} |
389 | |
} |
390 | 0 | } |
391 | |
|
392 | |
|
393 | |
|
394 | |
|
395 | |
|
396 | |
|
397 | |
|
398 | |
|
399 | |
public static void debugHtml(Writer writer, FacesContext faces) throws IOException |
400 | |
{ |
401 | 0 | _init(faces); |
402 | 0 | Date now = new Date(); |
403 | 0 | for (int i = 0; i < debugParts.length; i++) |
404 | |
{ |
405 | 0 | if ("message".equals(debugParts[i])) |
406 | |
{ |
407 | 0 | writer.write(faces.getViewRoot().getViewId()); |
408 | |
} |
409 | 0 | else if ("now".equals(debugParts[i])) |
410 | |
{ |
411 | 0 | writer.write(DateFormat.getDateTimeInstance().format(now)); |
412 | |
} |
413 | 0 | else if ("tree".equals(debugParts[i])) |
414 | |
{ |
415 | 0 | _writeComponent(faces, writer, faces.getViewRoot(), null, true); |
416 | |
} |
417 | 0 | else if ("extendedtree".equals(debugParts[i])) |
418 | |
{ |
419 | 0 | _writeExtendedComponentTree(writer, faces); |
420 | |
} |
421 | 0 | else if ("vars".equals(debugParts[i])) |
422 | |
{ |
423 | 0 | _writeVariables(writer, faces, faces.getViewRoot()); |
424 | |
} |
425 | |
else |
426 | |
{ |
427 | 0 | writer.write(debugParts[i]); |
428 | |
} |
429 | |
} |
430 | 0 | } |
431 | |
|
432 | |
public static void handle(FacesContext facesContext, Collection<UIComponent> components, |
433 | |
Throwable... exs) throws FacesException |
434 | |
{ |
435 | 0 | for (Throwable ex : exs) |
436 | |
{ |
437 | 0 | _prepareExceptionStack(ex); |
438 | |
} |
439 | |
|
440 | 0 | if (!facesContext.getExternalContext().isResponseCommitted()) |
441 | |
{ |
442 | 0 | facesContext.getExternalContext().responseReset(); |
443 | |
} |
444 | |
|
445 | 0 | int responseStatus = -1; |
446 | 0 | for (Throwable ex : exs) |
447 | |
{ |
448 | 0 | if (ex instanceof ViewNotFoundException) |
449 | |
{ |
450 | 0 | responseStatus = HttpServletResponse.SC_NOT_FOUND; |
451 | 0 | break; |
452 | |
} |
453 | |
else |
454 | |
{ |
455 | 0 | responseStatus = HttpServletResponse.SC_INTERNAL_SERVER_ERROR; |
456 | |
} |
457 | |
} |
458 | 0 | if (responseStatus != -1) |
459 | |
{ |
460 | 0 | facesContext.getExternalContext().setResponseStatus(responseStatus); |
461 | |
} |
462 | |
|
463 | |
|
464 | 0 | facesContext.getExternalContext().setResponseContentType("text/html"); |
465 | 0 | facesContext.getExternalContext().setResponseCharacterEncoding("UTF-8"); |
466 | |
try |
467 | |
{ |
468 | |
|
469 | |
|
470 | 0 | Writer writer = facesContext.getExternalContext().getResponseOutputWriter(); |
471 | 0 | debugHtml(writer, facesContext, facesContext.getViewRoot(), components, exs); |
472 | |
} |
473 | 0 | catch(IOException ioe) |
474 | |
{ |
475 | 0 | throw new FacesException("Could not write the error page", ioe); |
476 | 0 | } |
477 | |
|
478 | |
|
479 | 0 | facesContext.responseComplete(); |
480 | 0 | } |
481 | |
|
482 | |
|
483 | |
|
484 | |
|
485 | |
|
486 | |
|
487 | |
|
488 | |
|
489 | |
|
490 | |
|
491 | |
|
492 | |
|
493 | |
|
494 | |
@Deprecated |
495 | |
public static void handleThrowable(FacesContext facesContext, Throwable ex) throws FacesException |
496 | |
{ |
497 | 0 | _prepareExceptionStack(ex); |
498 | |
|
499 | 0 | boolean errorPageWritten = false; |
500 | |
|
501 | |
|
502 | |
|
503 | |
|
504 | |
|
505 | 0 | WebConfigProvider webConfigProvider = WebConfigProviderFactory.getWebConfigProviderFactory( |
506 | |
facesContext.getExternalContext()).getWebConfigProvider(facesContext.getExternalContext()); |
507 | |
|
508 | 0 | if(webConfigProvider.isErrorPagePresent(facesContext.getExternalContext())) |
509 | |
{ |
510 | |
|
511 | 0 | facesContext.getExternalContext().getRequestMap().put(VIEW_KEY, facesContext.getViewRoot()); |
512 | |
} |
513 | |
else |
514 | |
{ |
515 | |
|
516 | |
|
517 | 0 | String errorHandling = facesContext.getExternalContext().getInitParameter(ERROR_HANDLING_PARAMETER); |
518 | 0 | boolean errorHandlingDisabled = (errorHandling != null && errorHandling.equalsIgnoreCase("false")); |
519 | 0 | if (!errorHandlingDisabled) |
520 | |
{ |
521 | |
|
522 | 0 | Object response = facesContext.getExternalContext().getResponse(); |
523 | 0 | if (response instanceof HttpServletResponse) |
524 | |
{ |
525 | 0 | HttpServletResponse httpResp = (HttpServletResponse) response; |
526 | 0 | if (!httpResp.isCommitted()) |
527 | |
{ |
528 | 0 | httpResp.reset(); |
529 | 0 | if (facesContext.getPartialViewContext().isAjaxRequest()) |
530 | |
{ |
531 | |
|
532 | 0 | httpResp.setContentType("text/xml; charset=UTF-8"); |
533 | |
try |
534 | |
{ |
535 | 0 | Writer writer = httpResp.getWriter(); |
536 | |
|
537 | 0 | ResponseWriter responseWriter = new HtmlResponseWriterImpl(writer, "text/xml", "utf-8"); |
538 | 0 | PartialResponseWriter partialWriter = new PartialResponseWriter(responseWriter); |
539 | 0 | partialWriter.startDocument(); |
540 | 0 | partialWriter.startError(ex.getClass().getName()); |
541 | 0 | if (ex.getCause() != null) |
542 | |
{ |
543 | 0 | partialWriter.write(ex.getCause().toString()); |
544 | |
} |
545 | 0 | else if (ex.getMessage() != null) |
546 | |
{ |
547 | 0 | partialWriter.write(ex.getMessage()); |
548 | |
} |
549 | 0 | partialWriter.endError(); |
550 | 0 | partialWriter.endDocument(); |
551 | |
} |
552 | 0 | catch(IOException ioe) |
553 | |
{ |
554 | 0 | throw new FacesException("Could not write the error page", ioe); |
555 | 0 | } |
556 | |
} |
557 | |
else |
558 | |
{ |
559 | |
|
560 | 0 | httpResp.setContentType("text/html; charset=UTF-8"); |
561 | |
try |
562 | |
{ |
563 | 0 | Writer writer = httpResp.getWriter(); |
564 | 0 | debugHtml(writer, facesContext, ex); |
565 | |
} |
566 | 0 | catch(IOException ioe) |
567 | |
{ |
568 | 0 | throw new FacesException("Could not write the error page", ioe); |
569 | 0 | } |
570 | |
} |
571 | 0 | log.log(Level.SEVERE, "An exception occurred", ex); |
572 | |
|
573 | |
|
574 | 0 | facesContext.responseComplete(); |
575 | |
|
576 | 0 | errorPageWritten = true; |
577 | |
} |
578 | |
} |
579 | |
} |
580 | |
} |
581 | |
|
582 | |
|
583 | 0 | if (!errorPageWritten) |
584 | |
{ |
585 | 0 | if (ex instanceof FacesException) |
586 | |
{ |
587 | 0 | throw (FacesException) ex; |
588 | |
} |
589 | 0 | if (ex instanceof RuntimeException) |
590 | |
{ |
591 | 0 | throw (RuntimeException) ex; |
592 | |
} |
593 | 0 | throw new FacesException(ex); |
594 | |
} |
595 | |
|
596 | 0 | } |
597 | |
|
598 | |
private static String _getErrorTemplate(FacesContext context) |
599 | |
{ |
600 | 0 | String errorTemplate = context.getExternalContext().getInitParameter(ERROR_TEMPLATE_RESOURCE); |
601 | 0 | if (errorTemplate != null) |
602 | |
{ |
603 | 0 | return errorTemplate; |
604 | |
} |
605 | 0 | return ERROR_TEMPLATE; |
606 | |
} |
607 | |
|
608 | |
private static String _getDebugTemplate(FacesContext context) |
609 | |
{ |
610 | 0 | String debugTemplate = context.getExternalContext().getInitParameter(DEBUG_TEMPLATE_RESOURCE); |
611 | 0 | if (debugTemplate != null) |
612 | |
{ |
613 | 0 | return debugTemplate; |
614 | |
} |
615 | 0 | return DEBUG_TEMPLATE; |
616 | |
} |
617 | |
|
618 | |
private static void _init(FacesContext context) throws IOException |
619 | |
{ |
620 | 0 | if (errorParts == null) |
621 | |
{ |
622 | 0 | errorParts = _splitTemplate(_getErrorTemplate(context)); |
623 | |
} |
624 | |
|
625 | 0 | if (debugParts == null) |
626 | |
{ |
627 | 0 | debugParts = _splitTemplate(_getDebugTemplate(context)); |
628 | |
} |
629 | 0 | } |
630 | |
|
631 | |
private static String[] _splitTemplate(String rsc) throws IOException |
632 | |
{ |
633 | 0 | InputStream is = ClassUtils.getContextClassLoader().getResourceAsStream(rsc); |
634 | 0 | if (is == null) |
635 | |
{ |
636 | |
|
637 | 0 | is = FacesContext.getCurrentInstance().getExternalContext().getResourceAsStream(rsc); |
638 | 0 | if (is == null) |
639 | |
{ |
640 | |
|
641 | 0 | is = ErrorPageWriter.class.getClassLoader().getResourceAsStream(rsc); |
642 | |
} |
643 | |
} |
644 | |
|
645 | 0 | if (is == null) |
646 | |
{ |
647 | |
|
648 | |
|
649 | |
|
650 | |
|
651 | 0 | throw new IllegalArgumentException("Could not find resource " + rsc); |
652 | |
} |
653 | 0 | ByteArrayOutputStream baos = new ByteArrayOutputStream(); |
654 | 0 | byte[] buff = new byte[512]; |
655 | |
int read; |
656 | 0 | while ((read = is.read(buff)) != -1) |
657 | |
{ |
658 | 0 | baos.write(buff, 0, read); |
659 | |
} |
660 | 0 | String str = baos.toString(); |
661 | 0 | return str.split("@@"); |
662 | |
} |
663 | |
|
664 | |
private static List<String> _getErrorId(Collection<UIComponent> components, Throwable... exs) |
665 | |
{ |
666 | 0 | List<String> list = null; |
667 | 0 | for (Throwable e : exs) |
668 | |
{ |
669 | 0 | String message = e.getMessage(); |
670 | |
|
671 | 0 | if (message == null) |
672 | |
{ |
673 | 0 | continue; |
674 | |
} |
675 | |
|
676 | 0 | Pattern pattern = Pattern.compile(REGEX_PATTERN); |
677 | 0 | Matcher matcher = pattern.matcher(message); |
678 | |
|
679 | 0 | while (matcher.find()) |
680 | |
{ |
681 | 0 | if (list == null) |
682 | |
{ |
683 | 0 | list = new ArrayList<String>(); |
684 | |
} |
685 | 0 | list.add(matcher.group(1)); |
686 | |
} |
687 | |
} |
688 | 0 | if (list != null && list.size() > 0) |
689 | |
{ |
690 | 0 | return list; |
691 | |
} |
692 | 0 | else if (components != null) |
693 | |
{ |
694 | 0 | list = new ArrayList<String>(); |
695 | 0 | for (UIComponent uiComponent : components) |
696 | |
{ |
697 | 0 | if (uiComponent != null) |
698 | |
{ |
699 | 0 | list.add(uiComponent.getId()); |
700 | |
} |
701 | 0 | } |
702 | 0 | return list; |
703 | |
} |
704 | 0 | return null; |
705 | |
} |
706 | |
|
707 | |
private static void _writeException(Writer writer, Throwable e) throws IOException |
708 | |
{ |
709 | 0 | StringWriter str = new StringWriter(256); |
710 | 0 | PrintWriter pstr = new PrintWriter(str); |
711 | 0 | e.printStackTrace(pstr); |
712 | 0 | pstr.close(); |
713 | 0 | writer.write(str.toString().replaceAll("<", TS)); |
714 | 0 | } |
715 | |
|
716 | |
private static void _writeCause(Writer writer, Throwable ex) throws IOException |
717 | |
{ |
718 | 0 | String msg = ex.getMessage(); |
719 | 0 | String contextAwareLocation = null; |
720 | 0 | if (ex instanceof ContextAware) |
721 | |
{ |
722 | 0 | ContextAware caex = (ContextAware) ex; |
723 | 0 | contextAwareLocation = caex.getLocation().toString() + " " + |
724 | |
caex.getQName() + "=\"" + |
725 | |
caex.getExpressionString() + "\""; |
726 | |
} |
727 | 0 | while (ex.getCause() != null) |
728 | |
{ |
729 | 0 | ex = ex.getCause(); |
730 | 0 | if (ex instanceof ContextAware) |
731 | |
{ |
732 | 0 | ContextAware caex = (ContextAware) ex; |
733 | 0 | contextAwareLocation = caex.getLocation().toString() + " " + |
734 | |
caex.getQName() + "=\"" + |
735 | |
caex.getExpressionString() + "\""; |
736 | |
} |
737 | 0 | if (ex.getMessage() != null) |
738 | |
{ |
739 | 0 | msg = ex.getMessage(); |
740 | |
} |
741 | |
} |
742 | |
|
743 | 0 | if (msg != null) |
744 | |
{ |
745 | 0 | msg = ex.getClass().getName() + " - " + msg; |
746 | 0 | writer.write(msg.replaceAll("<", TS)); |
747 | |
} |
748 | |
else |
749 | |
{ |
750 | 0 | writer.write(ex.getClass().getName()); |
751 | |
} |
752 | 0 | StackTraceElement stackTraceElement = ex.getStackTrace()[0]; |
753 | 0 | writer.write("<br/> at " + stackTraceElement.toString()); |
754 | |
|
755 | 0 | if (contextAwareLocation != null) |
756 | |
{ |
757 | 0 | writer.write("<br/> <br/>"); |
758 | 0 | writer.write(contextAwareLocation); |
759 | 0 | writer.write("<br/>"); |
760 | |
} |
761 | 0 | } |
762 | |
|
763 | |
private static void _writeVariables(Writer writer, FacesContext faces, UIViewRoot view) throws IOException |
764 | |
{ |
765 | 0 | ExternalContext ctx = faces.getExternalContext(); |
766 | 0 | _writeVariables(writer, ctx.getRequestParameterMap(), "Request Parameters"); |
767 | 0 | _writeVariables(writer, ctx.getRequestMap(), "Request Attributes"); |
768 | 0 | if (view != null) |
769 | |
{ |
770 | 0 | _writeVariables(writer, view.getViewMap(), "View Attributes"); |
771 | |
} |
772 | 0 | if (ctx.getSession(false) != null) |
773 | |
{ |
774 | 0 | _writeVariables(writer, ctx.getSessionMap(), "Session Attributes"); |
775 | |
} |
776 | 0 | MyfacesConfig config = MyfacesConfig.getCurrentInstance(ctx); |
777 | 0 | if(config!=null && !config.isFlashScopeDisabled() && ctx.getFlash() != null) |
778 | |
{ |
779 | 0 | _writeVariables(writer, ctx.getFlash(), "Flash Attributes"); |
780 | |
} |
781 | 0 | _writeVariables(writer, ctx.getApplicationMap(), "Application Attributes"); |
782 | 0 | } |
783 | |
|
784 | |
private static void _writeVariables(Writer writer, Map<String, ? extends Object> vars, String caption) |
785 | |
throws IOException |
786 | |
{ |
787 | 0 | writer.write("<table><caption>"); |
788 | 0 | writer.write(caption); |
789 | 0 | writer.write("</caption><thead><tr><th style=\"width: 10%; \">Name</th>" |
790 | |
+ "<th style=\"width: 90%; \">Value</th></tr></thead><tbody>"); |
791 | 0 | boolean written = false; |
792 | 0 | if (!vars.isEmpty()) |
793 | |
{ |
794 | 0 | SortedMap<String, Object> sortedMap = new TreeMap<String, Object>(vars); |
795 | 0 | for (Map.Entry<String, Object> entry : sortedMap.entrySet()) |
796 | |
{ |
797 | 0 | String key = entry.getKey(); |
798 | 0 | if (key.indexOf('.') == -1) |
799 | |
{ |
800 | 0 | writer.write("<tr><td>"); |
801 | 0 | writer.write(key.replaceAll("<", TS)); |
802 | 0 | writer.write("</td><td>"); |
803 | 0 | Object value = entry.getValue(); |
804 | |
|
805 | |
|
806 | 0 | if (value != null && value.toString() != null) |
807 | |
{ |
808 | 0 | writer.write(value.toString().replaceAll("<", TS)); |
809 | |
} |
810 | |
else |
811 | |
{ |
812 | 0 | writer.write("null"); |
813 | |
} |
814 | 0 | writer.write("</td></tr>"); |
815 | 0 | written = true; |
816 | |
} |
817 | 0 | } |
818 | |
} |
819 | 0 | if (!written) |
820 | |
{ |
821 | 0 | writer.write("<tr><td colspan=\"2\"><em>None</em></td></tr>"); |
822 | |
} |
823 | 0 | writer.write("</tbody></table>"); |
824 | 0 | } |
825 | |
|
826 | |
private static void _writeComponent(FacesContext faces, Writer writer, UIComponent c, List<String> highlightId, |
827 | |
boolean writeChildren) throws IOException |
828 | |
{ |
829 | 0 | writer.write("<dl><dt"); |
830 | 0 | if (_isText(c)) |
831 | |
{ |
832 | 0 | writer.write(" class=\"uicText\""); |
833 | |
} |
834 | 0 | if (highlightId != null) |
835 | |
{ |
836 | 0 | if ((highlightId.size() > 0)) |
837 | |
{ |
838 | 0 | String id = c.getId(); |
839 | 0 | if (highlightId.contains(id)) |
840 | |
{ |
841 | 0 | writer.write(" class=\"highlightComponent\""); |
842 | |
} |
843 | |
} |
844 | |
} |
845 | 0 | writer.write(">"); |
846 | |
|
847 | 0 | boolean hasChildren = (c.getChildCount() > 0 || c.getFacetCount() > 0) && writeChildren; |
848 | |
|
849 | 0 | int stateSize = 0; |
850 | |
|
851 | 0 | Object state = c.saveState(faces); |
852 | 0 | if (state != null) |
853 | |
{ |
854 | |
try |
855 | |
{ |
856 | 0 | byte[] stateBytes = StateUtils.getAsByteArray(state, faces.getExternalContext()); |
857 | 0 | stateSize = stateBytes.length; |
858 | |
} |
859 | 0 | catch (Exception e) |
860 | |
{ |
861 | 0 | stateSize = -1; |
862 | 0 | if (log.isLoggable(Level.FINEST)) |
863 | |
{ |
864 | 0 | log.fine("Could not determine state size: " + e.getMessage()); |
865 | |
} |
866 | 0 | } |
867 | |
} |
868 | 0 | _writeStart(writer, c, hasChildren, true); |
869 | 0 | writer.write(" - State size:" + stateSize + " bytes"); |
870 | 0 | writer.write("</dt>"); |
871 | 0 | if (hasChildren) |
872 | |
{ |
873 | 0 | if (c.getFacetCount() > 0) |
874 | |
{ |
875 | 0 | for (Map.Entry<String, UIComponent> entry : c.getFacets().entrySet()) |
876 | |
{ |
877 | 0 | writer.write("<dd class=\"uicFacet\">"); |
878 | 0 | writer.write("<span>"); |
879 | 0 | writer.write(entry.getKey()); |
880 | 0 | writer.write("</span>"); |
881 | 0 | _writeComponent(faces, writer, entry.getValue(), highlightId, true); |
882 | 0 | writer.write("</dd>"); |
883 | 0 | } |
884 | |
} |
885 | 0 | if (c.getChildCount() > 0) |
886 | |
{ |
887 | 0 | for (int i = 0, childCount = c.getChildCount(); i < childCount; i++) |
888 | |
{ |
889 | 0 | UIComponent child = c.getChildren().get(i); |
890 | 0 | writer.write("<dd>"); |
891 | 0 | _writeComponent(faces, writer, child, highlightId, writeChildren); |
892 | 0 | writer.write("</dd>"); |
893 | |
} |
894 | |
} |
895 | 0 | writer.write("<dt>"); |
896 | 0 | _writeEnd(writer, c); |
897 | 0 | writer.write("</dt>"); |
898 | |
} |
899 | 0 | writer.write("</dl>"); |
900 | 0 | } |
901 | |
|
902 | |
|
903 | |
|
904 | |
|
905 | |
|
906 | |
|
907 | |
|
908 | |
|
909 | |
|
910 | |
private static void _writeExtendedComponentTree(Writer writer, |
911 | |
FacesContext facesContext) throws IOException |
912 | |
{ |
913 | 0 | VisitContext visitContext = VisitContext.createVisitContext( |
914 | |
facesContext, null, EnumSet.of(VisitHint.SKIP_UNRENDERED)); |
915 | 0 | facesContext.getViewRoot().visitTree(visitContext, new ExtendedComponentTreeVisitCallback(writer)); |
916 | 0 | _clearVisitedFacetCountMap(facesContext); |
917 | 0 | } |
918 | |
|
919 | |
|
920 | |
|
921 | |
|
922 | |
|
923 | |
|
924 | |
private static class ExtendedComponentTreeVisitCallback implements VisitCallback |
925 | |
{ |
926 | |
|
927 | |
private Writer _writer; |
928 | |
|
929 | |
public ExtendedComponentTreeVisitCallback(Writer writer) |
930 | 0 | { |
931 | 0 | _writer = writer; |
932 | 0 | } |
933 | |
|
934 | |
@SuppressWarnings("unchecked") |
935 | |
public VisitResult visit(VisitContext context, UIComponent target) |
936 | |
{ |
937 | 0 | final Map<String, Object> requestMap = context.getFacesContext() |
938 | |
.getExternalContext().getRequestMap(); |
939 | |
|
940 | |
try |
941 | |
{ |
942 | 0 | if (!(target instanceof UIViewRoot)) |
943 | |
{ |
944 | 0 | _writer.write("<dd>"); |
945 | |
} |
946 | |
|
947 | 0 | UIComponent parent = target.getParent(); |
948 | 0 | boolean hasChildren = (target.getChildCount() > 0 || target.getFacetCount() > 0); |
949 | 0 | String facetName = _getFacetName(target); |
950 | |
|
951 | 0 | if (!(target instanceof UIColumn)) |
952 | |
{ |
953 | 0 | if (parent instanceof UIColumn |
954 | |
&& ((parent.getChildCount() > 0 && parent.getChildren().get(0) == target) |
955 | |
|| (facetName != null && |
956 | |
_getVisitedFacetCount(context.getFacesContext(), parent) == 0))) |
957 | |
{ |
958 | 0 | if (parent.getParent() instanceof UIData |
959 | |
&& _isFirstUIColumn(parent.getParent(), (UIColumn) parent)) |
960 | |
{ |
961 | 0 | _writer.write("<span>Row: "); |
962 | 0 | int rowIndex = ((UIData) parent.getParent()).getRowIndex(); |
963 | 0 | _writer.write("" + rowIndex); |
964 | 0 | if (rowIndex == -1) |
965 | |
{ |
966 | |
|
967 | 0 | _writer.write(" (all column facets)"); |
968 | |
} |
969 | 0 | _writer.write("</span>"); |
970 | |
} |
971 | 0 | _writer.write("<dl><dt>"); |
972 | 0 | _writeStart(_writer, parent, true, false); |
973 | 0 | _writer.write("</dt><dd>"); |
974 | |
} |
975 | |
|
976 | 0 | if (facetName != null) |
977 | |
{ |
978 | 0 | _writer.write("<span>" + facetName + "</span>"); |
979 | 0 | _incrementVisitedFacetCount(context.getFacesContext(), parent); |
980 | |
} |
981 | 0 | _writer.write("<dl><dt"); |
982 | 0 | if (_isText(target)) |
983 | |
{ |
984 | 0 | _writer.write(" class=\"uicText\""); |
985 | |
} |
986 | 0 | _writer.write(">"); |
987 | |
|
988 | 0 | Map<String, List<Object[]>> debugInfos = null; |
989 | |
|
990 | |
|
991 | 0 | if (target instanceof EditableValueHolder) |
992 | |
{ |
993 | |
|
994 | 0 | debugInfos = (Map<String, List<Object[]>>) requestMap |
995 | |
.get(DEBUG_INFO_KEY + target.getClientId()); |
996 | |
} |
997 | |
|
998 | |
|
999 | |
|
1000 | |
|
1001 | 0 | Renderer renderer = null; |
1002 | |
try |
1003 | |
{ |
1004 | 0 | Method getRenderer = UIComponent.class.getDeclaredMethod( |
1005 | |
"getRenderer", FacesContext.class); |
1006 | |
|
1007 | 0 | getRenderer.setAccessible(true); |
1008 | 0 | renderer = (Renderer) getRenderer.invoke(target, context.getFacesContext()); |
1009 | |
} |
1010 | 0 | catch (Exception e) |
1011 | |
{ |
1012 | |
|
1013 | 0 | } |
1014 | |
|
1015 | |
|
1016 | 0 | _writeStart(_writer, target, (hasChildren || debugInfos != null || renderer != null), false); |
1017 | 0 | _writer.write("</dt>"); |
1018 | |
|
1019 | 0 | if (renderer != null) |
1020 | |
{ |
1021 | |
|
1022 | 0 | _writer.write("<div class=\"renderer\">Rendered by "); |
1023 | 0 | _writer.write(renderer.getClass().getCanonicalName()); |
1024 | 0 | _writer.write("</div>"); |
1025 | |
|
1026 | 0 | if (!hasChildren && debugInfos == null) |
1027 | |
{ |
1028 | |
|
1029 | 0 | _writer.write("<dt>"); |
1030 | 0 | _writeEnd(_writer, target); |
1031 | 0 | _writer.write("</dt>"); |
1032 | |
} |
1033 | |
} |
1034 | |
|
1035 | 0 | if (debugInfos != null) |
1036 | |
{ |
1037 | 0 | final String fieldid = target.getClientId() + "_lifecycle"; |
1038 | 0 | _writer.write("<div class=\"lifecycle_values_wrapper\">"); |
1039 | 0 | _writer.write("<a href=\"#\" onclick=\"toggle('"); |
1040 | 0 | _writer.write(fieldid); |
1041 | 0 | _writer.write("'); return false;\"><span id=\""); |
1042 | 0 | _writer.write(fieldid); |
1043 | 0 | _writer.write("Off\">+</span><span id=\""); |
1044 | 0 | _writer.write(fieldid); |
1045 | 0 | _writer.write("On\" style=\"display: none;\">-</span> Value Lifecycle</a>"); |
1046 | 0 | _writer.write("<div id=\""); |
1047 | 0 | _writer.write(fieldid); |
1048 | 0 | _writer.write("\" class=\"lifecycle_values\">"); |
1049 | |
|
1050 | |
|
1051 | 0 | for (Map.Entry<String, List<Object[]>> entry : debugInfos.entrySet()) |
1052 | |
{ |
1053 | 0 | _writer.write("<span>"); |
1054 | 0 | _writer.write(entry.getKey()); |
1055 | 0 | _writer.write("</span><ol>"); |
1056 | 0 | int i = 0; |
1057 | 0 | for (Object[] debugInfo : entry.getValue()) |
1058 | |
{ |
1059 | |
|
1060 | |
|
1061 | |
|
1062 | |
|
1063 | |
|
1064 | |
|
1065 | |
|
1066 | 0 | String oldValue = debugInfo[1] == null ? "null" : debugInfo[1].toString(); |
1067 | 0 | String newValue = debugInfo[2] == null ? "null" : debugInfo[2].toString(); |
1068 | 0 | _writer.write("<li><b>"); |
1069 | 0 | _writer.write(entry.getKey()); |
1070 | 0 | _writer.write("</b> set from <b>"); |
1071 | 0 | _writer.write(oldValue); |
1072 | 0 | _writer.write("</b> to <b>"); |
1073 | 0 | _writer.write(newValue); |
1074 | 0 | _writer.write("</b> in Phase "); |
1075 | 0 | _writer.write(debugInfo[0].toString()); |
1076 | |
|
1077 | |
|
1078 | 0 | if (debugInfo[3] != null) |
1079 | |
{ |
1080 | 0 | final String stackTraceId = fieldid + "_" + entry.getKey() + "_" + i; |
1081 | 0 | _writer.write("<div class=\"stacktrace_wrapper\">"); |
1082 | 0 | _writer.write("<a href=\"#\" onclick=\"toggle('"); |
1083 | 0 | _writer.write(stackTraceId); |
1084 | 0 | _writer.write("'); return false;\"><span id=\""); |
1085 | 0 | _writer.write(stackTraceId); |
1086 | 0 | _writer.write("Off\">+</span><span id=\""); |
1087 | 0 | _writer.write(stackTraceId); |
1088 | 0 | _writer.write("On\" style=\"display: none;\">-</span> Call Stack</a>"); |
1089 | 0 | _writer.write("<div id=\""); |
1090 | 0 | _writer.write(stackTraceId); |
1091 | 0 | _writer.write("\" class=\"stacktrace_values\">"); |
1092 | 0 | _writer.write("<ul>"); |
1093 | |
for (StackTraceElement stackTraceElement |
1094 | 0 | : (List<StackTraceElement>) debugInfo[3]) |
1095 | |
{ |
1096 | 0 | _writer.write("<li>"); |
1097 | 0 | _writer.write(stackTraceElement.toString()); |
1098 | 0 | _writer.write("</li>"); |
1099 | 0 | } |
1100 | 0 | _writer.write("</ul></div></div>"); |
1101 | |
} |
1102 | |
|
1103 | 0 | _writer.write("</li>"); |
1104 | |
|
1105 | 0 | i++; |
1106 | 0 | } |
1107 | 0 | _writer.write("</ol>"); |
1108 | 0 | } |
1109 | |
|
1110 | 0 | _writer.write("</div></div>"); |
1111 | |
|
1112 | |
|
1113 | |
|
1114 | 0 | requestMap.remove(DEBUG_INFO_KEY + target.getClientId()); |
1115 | |
|
1116 | 0 | if (!hasChildren) |
1117 | |
{ |
1118 | |
|
1119 | 0 | _writer.write("<dt>"); |
1120 | 0 | _writeEnd(_writer, target); |
1121 | 0 | _writer.write("</dt>"); |
1122 | |
} |
1123 | |
} |
1124 | |
} |
1125 | |
|
1126 | 0 | if (!hasChildren) |
1127 | |
{ |
1128 | 0 | _writer.write("</dl>"); |
1129 | |
|
1130 | 0 | while (parent != null && |
1131 | |
((parent.getChildCount()>0 && parent.getChildren().get(parent.getChildCount()-1) == target) |
1132 | |
|| (parent.getFacetCount() != 0 |
1133 | |
&& _getVisitedFacetCount(context.getFacesContext(), parent) == |
1134 | |
parent.getFacetCount()))) |
1135 | |
{ |
1136 | |
|
1137 | |
|
1138 | |
|
1139 | 0 | _removeVisitedFacetCount(context.getFacesContext(), parent); |
1140 | |
|
1141 | |
|
1142 | 0 | if (parent instanceof UIData) |
1143 | |
{ |
1144 | 0 | UIData uidata = (UIData) parent; |
1145 | 0 | if (uidata.getRowIndex() != uidata.getRowCount() - 1) |
1146 | |
{ |
1147 | |
|
1148 | 0 | break; |
1149 | |
} |
1150 | 0 | } |
1151 | 0 | else if (parent instanceof UIRepeat) |
1152 | |
{ |
1153 | 0 | UIRepeat uirepeat = (UIRepeat) parent; |
1154 | 0 | if (uirepeat.getIndex() + uirepeat.getStep() < uirepeat.getRowCount()) |
1155 | |
{ |
1156 | |
|
1157 | 0 | break; |
1158 | |
} |
1159 | |
} |
1160 | |
|
1161 | 0 | _writer.write("</dd><dt>"); |
1162 | 0 | _writeEnd(_writer, parent); |
1163 | 0 | _writer.write("</dt></dl>"); |
1164 | |
|
1165 | 0 | if (!(parent instanceof UIViewRoot)) |
1166 | |
{ |
1167 | 0 | _writer.write("</dd>"); |
1168 | |
} |
1169 | |
|
1170 | 0 | target = parent; |
1171 | 0 | parent = target.getParent(); |
1172 | |
} |
1173 | |
} |
1174 | |
} |
1175 | 0 | catch (IOException ioe) |
1176 | |
{ |
1177 | 0 | throw new FacesException(ioe); |
1178 | 0 | } |
1179 | |
|
1180 | 0 | return VisitResult.ACCEPT; |
1181 | |
} |
1182 | |
|
1183 | |
} |
1184 | |
|
1185 | |
private static boolean _isFirstUIColumn(UIComponent uidata, UIColumn uicolumn) |
1186 | |
{ |
1187 | 0 | for (int i = 0, childCount = uidata.getChildCount(); i < childCount; i++) |
1188 | |
{ |
1189 | 0 | UIComponent child = uidata.getChildren().get(i); |
1190 | 0 | if (child instanceof UIColumn) |
1191 | |
{ |
1192 | 0 | return (child == uicolumn); |
1193 | |
} |
1194 | |
} |
1195 | 0 | return false; |
1196 | |
} |
1197 | |
|
1198 | |
private static String _getFacetName(UIComponent component) |
1199 | |
{ |
1200 | 0 | UIComponent parent = component.getParent(); |
1201 | 0 | if (parent != null) |
1202 | |
{ |
1203 | 0 | if (parent.getFacetCount() > 0) |
1204 | |
{ |
1205 | 0 | for (Map.Entry<String, UIComponent> entry : parent.getFacets().entrySet()) |
1206 | |
{ |
1207 | 0 | if (entry.getValue() == component) |
1208 | |
{ |
1209 | 0 | return entry.getKey(); |
1210 | |
} |
1211 | 0 | } |
1212 | |
} |
1213 | |
} |
1214 | 0 | return null; |
1215 | |
} |
1216 | |
|
1217 | |
private static int _getVisitedFacetCount(FacesContext facesContext, UIComponent component) |
1218 | |
{ |
1219 | 0 | Map<UIComponent, Integer> visitedFacetCount = (Map<UIComponent, Integer>) |
1220 | |
facesContext.getAttributes().get(VISITED_FACET_COUNT_KEY); |
1221 | 0 | if (visitedFacetCount == null) |
1222 | |
{ |
1223 | 0 | return 0; |
1224 | |
} |
1225 | 0 | Integer count = visitedFacetCount.get(component); |
1226 | 0 | if (count != null) |
1227 | |
{ |
1228 | 0 | return count; |
1229 | |
} |
1230 | 0 | return 0; |
1231 | |
} |
1232 | |
|
1233 | |
private static void _incrementVisitedFacetCount(FacesContext facesContext, UIComponent component) |
1234 | |
{ |
1235 | 0 | Map<UIComponent, Integer> visitedFacetCount = (Map<UIComponent, Integer>) |
1236 | |
facesContext.getAttributes().get(VISITED_FACET_COUNT_KEY); |
1237 | 0 | if (visitedFacetCount == null) |
1238 | |
{ |
1239 | 0 | visitedFacetCount = new HashMap<UIComponent, Integer>(); |
1240 | 0 | facesContext.getAttributes().put(VISITED_FACET_COUNT_KEY, visitedFacetCount); |
1241 | |
} |
1242 | 0 | visitedFacetCount.put(component, _getVisitedFacetCount(facesContext, component) + 1); |
1243 | 0 | } |
1244 | |
|
1245 | |
private static void _removeVisitedFacetCount(FacesContext facesContext, UIComponent component) |
1246 | |
{ |
1247 | 0 | Map<UIComponent, Integer> visitedFacetCount = (Map<UIComponent, Integer>) |
1248 | |
facesContext.getAttributes().get(VISITED_FACET_COUNT_KEY); |
1249 | 0 | if (visitedFacetCount == null) |
1250 | |
{ |
1251 | 0 | return; |
1252 | |
} |
1253 | 0 | visitedFacetCount.remove(component); |
1254 | 0 | } |
1255 | |
|
1256 | |
private static void _clearVisitedFacetCountMap(FacesContext facesContext) |
1257 | |
{ |
1258 | 0 | Map<UIComponent, Integer> visitedFacetCount = (Map<UIComponent, Integer>) |
1259 | |
facesContext.getAttributes().get(VISITED_FACET_COUNT_KEY); |
1260 | 0 | if (visitedFacetCount != null) |
1261 | |
{ |
1262 | 0 | visitedFacetCount.clear(); |
1263 | 0 | facesContext.getAttributes().remove(VISITED_FACET_COUNT_KEY); |
1264 | |
} |
1265 | 0 | } |
1266 | |
|
1267 | |
private static void _writeEnd(Writer writer, UIComponent c) throws IOException |
1268 | |
{ |
1269 | 0 | if (!_isText(c)) |
1270 | |
{ |
1271 | 0 | writer.write(TS); |
1272 | 0 | writer.write('/'); |
1273 | 0 | writer.write(_getName(c)); |
1274 | 0 | writer.write('>'); |
1275 | |
} |
1276 | 0 | } |
1277 | |
|
1278 | |
private static void _writeAttributes(Writer writer, UIComponent c, boolean valueExpressionValues) |
1279 | |
{ |
1280 | |
try |
1281 | |
{ |
1282 | 0 | BeanInfo info = Introspector.getBeanInfo(c.getClass()); |
1283 | 0 | PropertyDescriptor[] pd = info.getPropertyDescriptors(); |
1284 | 0 | Method m = null; |
1285 | 0 | Object v = null; |
1286 | 0 | ValueExpression valueExpression = null; |
1287 | 0 | String str = null; |
1288 | 0 | for (int i = 0; i < pd.length; i++) |
1289 | |
{ |
1290 | 0 | if ((pd[i].getWriteMethod() != null || Arrays.binarySearch(ALWAYS_WRITE, pd[i].getName()) > -1) |
1291 | |
&& Arrays.binarySearch(IGNORE, pd[i].getName()) < 0) |
1292 | |
{ |
1293 | 0 | m = pd[i].getReadMethod(); |
1294 | 0 | if (m != null) |
1295 | |
{ |
1296 | |
try |
1297 | |
{ |
1298 | |
|
1299 | 0 | valueExpression = c.getValueExpression(pd[i].getName()); |
1300 | 0 | if (valueExpressionValues && valueExpression != null) |
1301 | |
{ |
1302 | 0 | String expressionString = valueExpression.getExpressionString(); |
1303 | 0 | if (null == expressionString) |
1304 | |
{ |
1305 | 0 | expressionString = ""; |
1306 | |
} |
1307 | 0 | _writeAttribute(writer, pd[i].getName(), expressionString); |
1308 | 0 | } |
1309 | |
else |
1310 | |
{ |
1311 | 0 | v = m.invoke(c, null); |
1312 | 0 | if (v != null) |
1313 | |
{ |
1314 | 0 | if (v instanceof Collection || v instanceof Map || v instanceof Iterator) |
1315 | |
{ |
1316 | 0 | continue; |
1317 | |
} |
1318 | 0 | if (v instanceof Expression) |
1319 | |
{ |
1320 | 0 | str = ((Expression)v).getExpressionString(); |
1321 | |
} |
1322 | 0 | else if (v instanceof ValueBinding) |
1323 | |
{ |
1324 | 0 | str = ((ValueBinding) v).getExpressionString(); |
1325 | |
} |
1326 | 0 | else if (v instanceof MethodBinding) |
1327 | |
{ |
1328 | 0 | str = ((MethodBinding) v).getExpressionString(); |
1329 | |
} |
1330 | |
else |
1331 | |
{ |
1332 | 0 | str = v.toString(); |
1333 | |
} |
1334 | |
|
1335 | 0 | _writeAttribute(writer, pd[i].getName(), str); |
1336 | |
} |
1337 | |
} |
1338 | |
} |
1339 | 0 | catch (Exception e) |
1340 | |
{ |
1341 | |
|
1342 | 0 | } |
1343 | |
} |
1344 | |
} |
1345 | |
} |
1346 | |
|
1347 | 0 | ValueExpression binding = c.getValueExpression("binding"); |
1348 | 0 | if (binding != null) |
1349 | |
{ |
1350 | 0 | _writeAttribute(writer, "binding", binding.getExpressionString()); |
1351 | |
} |
1352 | |
|
1353 | |
|
1354 | 0 | String location = _getComponentLocation(c); |
1355 | 0 | if (location != null) |
1356 | |
{ |
1357 | 0 | _writeAttribute(writer, "location", location); |
1358 | |
} |
1359 | |
} |
1360 | 0 | catch (Exception e) |
1361 | |
{ |
1362 | |
|
1363 | 0 | } |
1364 | 0 | } |
1365 | |
|
1366 | |
private static void _writeAttribute(Writer writer, String name, String value) throws IOException |
1367 | |
{ |
1368 | 0 | writer.write(" "); |
1369 | 0 | writer.write(name); |
1370 | 0 | writer.write("=\""); |
1371 | 0 | writer.write(value.replaceAll("<", TS)); |
1372 | 0 | writer.write("\""); |
1373 | 0 | } |
1374 | |
|
1375 | |
private static void _writeStart(Writer writer, UIComponent c, |
1376 | |
boolean children, boolean valueExpressionValues) throws IOException |
1377 | |
{ |
1378 | 0 | if (_isText(c)) |
1379 | |
{ |
1380 | 0 | String str = c.toString().trim(); |
1381 | 0 | writer.write(str.replaceAll("<", TS)); |
1382 | 0 | } |
1383 | |
else |
1384 | |
{ |
1385 | 0 | writer.write(TS); |
1386 | 0 | writer.write(_getName(c)); |
1387 | 0 | _writeAttributes(writer, c, valueExpressionValues); |
1388 | 0 | if (children) |
1389 | |
{ |
1390 | 0 | writer.write('>'); |
1391 | |
} |
1392 | |
else |
1393 | |
{ |
1394 | 0 | writer.write("/>"); |
1395 | |
} |
1396 | |
} |
1397 | 0 | } |
1398 | |
|
1399 | |
private static String _getName(UIComponent c) |
1400 | |
{ |
1401 | 0 | String nm = c.getClass().getName(); |
1402 | 0 | return nm.substring(nm.lastIndexOf('.') + 1); |
1403 | |
} |
1404 | |
|
1405 | |
private static boolean _isText(UIComponent c) |
1406 | |
{ |
1407 | 0 | return (c.getClass().getName().startsWith("org.apache.myfaces.view.facelets.compiler")); |
1408 | |
} |
1409 | |
|
1410 | |
private static void _prepareExceptionStack(Throwable ex) |
1411 | |
{ |
1412 | |
|
1413 | 0 | if (ex == null) |
1414 | |
{ |
1415 | 0 | return; |
1416 | |
} |
1417 | |
|
1418 | |
|
1419 | 0 | if (!_initCausePerReflection(ex, "getRootCause")) |
1420 | |
{ |
1421 | 0 | _initCausePerReflection(ex, "getCause"); |
1422 | |
} |
1423 | |
|
1424 | 0 | _prepareExceptionStack(ex.getCause()); |
1425 | 0 | } |
1426 | |
|
1427 | |
private static boolean _initCausePerReflection(Throwable ex, String methodName) |
1428 | |
{ |
1429 | |
try |
1430 | |
{ |
1431 | 0 | Method causeGetter = ex.getClass().getMethod(methodName, (Class[])null); |
1432 | 0 | Throwable rootCause = (Throwable)causeGetter.invoke(ex, (Object[])null); |
1433 | 0 | return _initCauseIfAvailable(ex, rootCause); |
1434 | |
} |
1435 | 0 | catch (Exception e1) |
1436 | |
{ |
1437 | 0 | return false; |
1438 | |
} |
1439 | |
} |
1440 | |
|
1441 | |
private static boolean _initCauseIfAvailable(Throwable th, Throwable cause) |
1442 | |
{ |
1443 | 0 | if (cause == null) |
1444 | |
{ |
1445 | 0 | return false; |
1446 | |
} |
1447 | |
|
1448 | |
try |
1449 | |
{ |
1450 | 0 | Method m = Throwable.class.getMethod("initCause", new Class[] { Throwable.class }); |
1451 | 0 | m.invoke(th, new Object[] { cause }); |
1452 | 0 | return true; |
1453 | |
} |
1454 | 0 | catch (Exception e) |
1455 | |
{ |
1456 | 0 | return false; |
1457 | |
} |
1458 | |
} |
1459 | |
|
1460 | |
|
1461 | |
|
1462 | |
|
1463 | |
|
1464 | |
|
1465 | |
private static String _getComponentLocation(UIComponent component) |
1466 | |
{ |
1467 | 0 | Location location = (Location) component.getAttributes() |
1468 | |
.get(UIComponent.VIEW_LOCATION_KEY); |
1469 | 0 | if (location != null) |
1470 | |
{ |
1471 | 0 | return location.toString(); |
1472 | |
} |
1473 | 0 | return null; |
1474 | |
} |
1475 | |
} |