1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.shared.renderkit.html;
20
21 import java.io.IOException;
22 import java.util.HashSet;
23 import java.util.Iterator;
24 import java.util.List;
25 import java.util.Map;
26 import java.util.Set;
27 import java.util.logging.Logger;
28
29 import javax.faces.application.FacesMessage;
30 import javax.faces.component.UIComponent;
31 import javax.faces.component.UIMessage;
32 import javax.faces.component.UIViewRoot;
33 import javax.faces.component.behavior.ClientBehavior;
34 import javax.faces.component.behavior.ClientBehaviorHolder;
35 import javax.faces.component.html.HtmlMessage;
36 import javax.faces.component.search.SearchExpressionContext;
37 import javax.faces.component.search.SearchExpressionHandler;
38 import javax.faces.component.search.SearchExpressionHint;
39 import javax.faces.context.FacesContext;
40 import javax.faces.context.ResponseWriter;
41
42 import org.apache.myfaces.shared.renderkit.JSFAttr;
43 import org.apache.myfaces.shared.renderkit.RendererUtils;
44
45 public abstract class HtmlMessageRendererBase
46 extends HtmlRenderer
47 {
48
49 private static final Logger log = Logger.getLogger(HtmlMessageRendererBase.class.getName());
50
51 protected abstract String getSummary(FacesContext facesContext,
52 UIComponent message,
53 FacesMessage facesMessage,
54 String msgClientId);
55
56 protected abstract String getDetail(FacesContext facesContext,
57 UIComponent message,
58 FacesMessage facesMessage,
59 String msgClientId);
60
61
62 protected void renderMessage(FacesContext facesContext,
63 UIComponent message)
64 throws IOException
65 {
66 renderMessage(facesContext, message, false);
67 }
68
69 protected void renderMessage(FacesContext facesContext, UIComponent message,
70 boolean alwaysRenderSpan) throws IOException
71 {
72 renderMessage(facesContext, message, alwaysRenderSpan, false);
73 }
74
75
76
77
78
79
80 protected void renderMessage(FacesContext facesContext, UIComponent message,
81 boolean alwaysRenderSpan, boolean renderDivWhenNoMessagesAndIdSet) throws IOException
82 {
83 String forAttr = getFor(message);
84 if (forAttr == null)
85 {
86 log.severe("Attribute 'for' of UIMessage must not be null");
87 return;
88 }
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103 SearchExpressionHandler searchExpressionHandler = facesContext.getApplication().getSearchExpressionHandler();
104 Set<SearchExpressionHint> expressionHints = new HashSet<SearchExpressionHint>();
105 expressionHints.add(SearchExpressionHint.IGNORE_NO_RESULT);
106 String clientId = searchExpressionHandler.resolveClientId(
107 SearchExpressionContext.createSearchExpressionContext(
108 facesContext, message, expressionHints, null), forAttr);
109 if (clientId == null)
110 {
111 log.severe("Could not render Message. Unable to find component '"
112 + forAttr + "' (calling findComponent on component '"
113 + message.getClientId(facesContext)
114 + "'). If the provided id was correct, wrap the message and its "
115 + "component into an h:panelGroup or h:panelGrid.");
116 return;
117 }
118
119 Iterator<FacesMessage> messageIterator = facesContext.getMessages(clientId);
120 if (!messageIterator.hasNext())
121 {
122
123 if (alwaysRenderSpan)
124 {
125 ResponseWriter writer = facesContext.getResponseWriter();
126 writer.startElement(HTML.SPAN_ELEM, message);
127 writer.writeAttribute(HTML.ID_ATTR, clientId + "_msgFor", null);
128 HtmlRendererUtils.renderHTMLStringAttribute(writer, message, JSFAttr.STYLE_ATTR, HTML.STYLE_ATTR);
129 HtmlRendererUtils.renderHTMLStringAttribute(writer, message, JSFAttr.STYLE_CLASS_ATTR, HTML.CLASS_ATTR);
130 writer.endElement(HTML.SPAN_ELEM);
131 }
132 else if (renderDivWhenNoMessagesAndIdSet && message.getId() != null &&
133 !message.getId().startsWith(UIViewRoot.UNIQUE_ID_PREFIX))
134 {
135
136 ResponseWriter writer = facesContext.getResponseWriter();
137 writer.startElement(HTML.SPAN_ELEM, message);
138 writer.writeAttribute(HTML.ID_ATTR, message.getClientId(facesContext), null);
139 writer.endElement(HTML.SPAN_ELEM);
140 }
141 return;
142 }
143
144
145 FacesMessage facesMessage = (FacesMessage) messageIterator.next();
146
147
148 if(!isRedisplay(message))
149 {
150 while(facesMessage.isRendered())
151 {
152 if(messageIterator.hasNext())
153 {
154
155 facesMessage = (FacesMessage) messageIterator.next();
156 }
157 else
158 {
159
160 return;
161 }
162 }
163 }
164
165
166 renderSingleFacesMessage(facesContext, message, facesMessage, clientId);
167 }
168
169
170 protected void renderSingleFacesMessage(FacesContext facesContext,
171 UIComponent message,
172 FacesMessage facesMessage,
173 String messageClientId)
174 throws IOException
175 {
176 renderSingleFacesMessage(facesContext, message, facesMessage, messageClientId,true);
177 }
178
179 protected void renderSingleFacesMessage(FacesContext facesContext,
180 UIComponent message,
181 FacesMessage facesMessage,
182 String messageClientId,
183 boolean renderId)
184 throws IOException
185 {
186 renderSingleFacesMessage(facesContext, message, facesMessage, messageClientId, renderId, true);
187 }
188
189 protected void renderSingleFacesMessage(FacesContext facesContext,
190 UIComponent message,
191 FacesMessage facesMessage,
192 String messageClientId,
193 boolean renderId,
194 boolean renderStyleAndStyleClass)
195 throws IOException
196 {
197 Map<String, List<ClientBehavior>> behaviors = null;
198 if (message instanceof ClientBehaviorHolder)
199 {
200 behaviors = ((ClientBehaviorHolder) message).getClientBehaviors();
201 }
202 boolean wrapSpan = (message.getId() != null && !message.getId().startsWith(UIViewRoot.UNIQUE_ID_PREFIX))
203 || (behaviors != null && !behaviors.isEmpty());
204
205 renderSingleFacesMessage(facesContext, message, facesMessage, messageClientId,
206 renderId, renderStyleAndStyleClass, wrapSpan);
207 }
208
209 protected void renderSingleFacesMessage(FacesContext facesContext,
210 UIComponent message,
211 FacesMessage facesMessage,
212 String messageClientId,
213 boolean renderId,
214 boolean renderStyleAndStyleClass,
215 boolean wrapSpan)
216 throws IOException
217 {
218
219 String[] styleAndClass = HtmlMessageRendererBase.getStyleAndStyleClass(
220 message, facesMessage.getSeverity());
221 String style = styleAndClass[0];
222 String styleClass = styleAndClass[1];
223
224 String summary = getSummary(facesContext, message, facesMessage, messageClientId);
225 String detail = getDetail(facesContext, message, facesMessage, messageClientId);
226
227 String title = getTitle(message);
228 boolean tooltip = isTooltip(message);
229
230 boolean showSummary = isShowSummary(message) && (summary != null);
231 boolean showDetail = isShowDetail(message) && (detail != null);
232
233 if (title == null && tooltip)
234 {
235 if (showDetail)
236 {
237 title = detail;
238 }
239 else if (detail != null)
240 {
241 title = detail;
242 }
243 else
244 {
245 title = summary;
246 }
247 }
248
249 ResponseWriter writer = facesContext.getResponseWriter();
250
251 boolean span = false;
252
253 Map<String, List<ClientBehavior>> behaviors = null;
254 if (message instanceof ClientBehaviorHolder)
255 {
256 behaviors = ((ClientBehaviorHolder) message).getClientBehaviors();
257
258 wrapSpan = wrapSpan || !behaviors.isEmpty();
259 }
260
261 if ( wrapSpan )
262 {
263 span = true;
264
265 writer.startElement(HTML.SPAN_ELEM, message);
266
267 if (behaviors != null && !behaviors.isEmpty())
268 {
269
270 writer.writeAttribute(HTML.ID_ATTR, message.getClientId(facesContext),null);
271 }
272 else if (renderId)
273 {
274 HtmlRendererUtils.writeIdIfNecessary(writer, message, facesContext);
275 }
276 if (message instanceof ClientBehaviorHolder)
277 {
278 behaviors = ((ClientBehaviorHolder) message).getClientBehaviors();
279 if (behaviors.isEmpty() && isCommonPropertiesOptimizationEnabled(facesContext))
280 {
281 CommonPropertyUtils.renderEventProperties(writer,
282 CommonPropertyUtils.getCommonPropertiesMarked(message), message);
283 }
284 else
285 {
286 if (isCommonEventsOptimizationEnabled(facesContext))
287 {
288 CommonEventUtils.renderBehaviorizedEventHandlers(facesContext, writer,
289 CommonPropertyUtils.getCommonPropertiesMarked(message),
290 CommonEventUtils.getCommonEventsMarked(message), message, behaviors);
291 }
292 else
293 {
294 HtmlRendererUtils.renderBehaviorizedEventHandlers(facesContext, writer, message, behaviors);
295 }
296 }
297 HtmlRendererUtils.renderHTMLAttributes(writer, message,
298 HTML.UNIVERSAL_ATTRIBUTES_WITHOUT_STYLE_AND_TITLE);
299 }
300 else
301 {
302 HtmlRendererUtils.renderHTMLAttributes(writer, message,
303 HTML.MESSAGE_PASSTHROUGH_ATTRIBUTES_WITHOUT_TITLE_STYLE_AND_STYLE_CLASS);
304 }
305 }
306 else
307 {
308 span = HtmlRendererUtils.renderHTMLAttributesWithOptionalStartElement(
309 writer, message, HTML.SPAN_ELEM,
310 HTML.MESSAGE_PASSTHROUGH_ATTRIBUTES_WITHOUT_TITLE_STYLE_AND_STYLE_CLASS);
311 }
312
313 span |= HtmlRendererUtils.renderHTMLAttributeWithOptionalStartElement(
314 writer, message, HTML.SPAN_ELEM, HTML.TITLE_ATTR, title, span);
315 if (renderStyleAndStyleClass)
316 {
317 span |= HtmlRendererUtils.renderHTMLAttributeWithOptionalStartElement(
318 writer, message, HTML.SPAN_ELEM, HTML.STYLE_ATTR, style, span);
319 span |= HtmlRendererUtils.renderHTMLAttributeWithOptionalStartElement(
320 writer, message, HTML.SPAN_ELEM, HTML.STYLE_CLASS_ATTR, styleClass, span);
321
322
323
324 span |= HtmlRendererUtils.renderHTMLAttributeWithOptionalStartElement(
325 writer, message, HTML.ROLE_ATTR, HTML.ROLE_ATTR,
326 message.getAttributes().get(HTML.ROLE_ATTR), span);
327 }
328
329 if (showSummary && !(title == null && tooltip))
330 {
331 writer.writeText(summary, null);
332 if (showDetail)
333 {
334 writer.writeText(" ", null);
335 }
336 }
337
338 if (showDetail)
339 {
340 writer.writeText(detail, null);
341 }
342
343 if (span)
344 {
345 writer.endElement(org.apache.myfaces.shared.renderkit.html.HTML.SPAN_ELEM);
346 }
347
348
349 facesMessage.rendered();
350 }
351
352
353 public static String[] getStyleAndStyleClass(UIComponent message,
354 FacesMessage.Severity severity)
355 {
356 String style = null;
357 String styleClass = null;
358 if (message instanceof HtmlMessage)
359 {
360 if (severity == FacesMessage.SEVERITY_INFO)
361 {
362 style = ((HtmlMessage) message).getInfoStyle();
363 styleClass = ((HtmlMessage) message).getInfoClass();
364 }
365 else if (severity == FacesMessage.SEVERITY_WARN)
366 {
367 style = ((HtmlMessage) message).getWarnStyle();
368 styleClass = ((HtmlMessage) message).getWarnClass();
369 }
370 else if (severity == FacesMessage.SEVERITY_ERROR)
371 {
372 style = ((HtmlMessage) message).getErrorStyle();
373 styleClass = ((HtmlMessage) message).getErrorClass();
374 }
375 else if (severity == FacesMessage.SEVERITY_FATAL)
376 {
377 style = ((HtmlMessage) message).getFatalStyle();
378 styleClass = ((HtmlMessage) message).getFatalClass();
379 }
380
381 if (style == null)
382 {
383 style = ((HtmlMessage) message).getStyle();
384 }
385
386 if (styleClass == null)
387 {
388 styleClass = ((HtmlMessage) message).getStyleClass();
389 }
390 }
391 else
392 {
393 Map<String, Object> attr = message.getAttributes();
394 if (severity == FacesMessage.SEVERITY_INFO)
395 {
396 style = (String) attr.get(org.apache.myfaces.shared.renderkit.JSFAttr.INFO_STYLE_ATTR);
397 styleClass = (String) attr.get(org.apache.myfaces.shared.renderkit.JSFAttr.INFO_CLASS_ATTR);
398 }
399 else if (severity == FacesMessage.SEVERITY_WARN)
400 {
401 style = (String) attr.get(org.apache.myfaces.shared.renderkit.JSFAttr.WARN_STYLE_ATTR);
402 styleClass = (String) attr.get(org.apache.myfaces.shared.renderkit.JSFAttr.WARN_CLASS_ATTR);
403 }
404 else if (severity == FacesMessage.SEVERITY_ERROR)
405 {
406 style = (String) attr.get(org.apache.myfaces.shared.renderkit.JSFAttr.ERROR_STYLE_ATTR);
407 styleClass = (String) attr.get(org.apache.myfaces.shared.renderkit.JSFAttr.ERROR_CLASS_ATTR);
408 }
409 else if (severity == FacesMessage.SEVERITY_FATAL)
410 {
411 style = (String) attr.get(org.apache.myfaces.shared.renderkit.JSFAttr.FATAL_STYLE_ATTR);
412 styleClass = (String) attr.get(org.apache.myfaces.shared.renderkit.JSFAttr.FATAL_CLASS_ATTR);
413 }
414
415 if (style == null)
416 {
417 style = (String) attr.get(org.apache.myfaces.shared.renderkit.JSFAttr.STYLE_ATTR);
418 }
419
420 if (styleClass == null)
421 {
422 styleClass = (String) attr.get(org.apache.myfaces.shared.renderkit.JSFAttr.STYLE_CLASS_ATTR);
423 }
424 }
425
426 return new String[]{style, styleClass};
427 }
428
429 protected String getFor(UIComponent component)
430 {
431 if (component instanceof UIMessage)
432 {
433 return ((UIMessage) component).getFor();
434 }
435
436 return (String) component.getAttributes().get(JSFAttr.FOR_ATTR);
437
438 }
439
440 protected String getTitle(UIComponent component)
441 {
442 if (component instanceof HtmlMessage)
443 {
444 return ((HtmlMessage) component).getTitle();
445 }
446
447 return (String) component.getAttributes().get(JSFAttr.TITLE_ATTR);
448
449 }
450
451 protected boolean isTooltip(UIComponent component)
452 {
453 if (component instanceof HtmlMessage)
454 {
455 return ((HtmlMessage) component).isTooltip();
456 }
457
458 return org.apache.myfaces.shared.renderkit.RendererUtils.getBooleanAttribute(component,
459 org.apache.myfaces.shared.renderkit.JSFAttr.TOOLTIP_ATTR, false);
460
461 }
462
463 protected boolean isShowSummary(UIComponent component)
464 {
465 if (component instanceof UIMessage)
466 {
467 return ((UIMessage) component).isShowSummary();
468 }
469
470 return org.apache.myfaces.shared.renderkit.RendererUtils.getBooleanAttribute(component,
471 org.apache.myfaces.shared.renderkit.JSFAttr.SHOW_SUMMARY_ATTR, false);
472
473 }
474
475 protected boolean isShowDetail(UIComponent component)
476 {
477 if (component instanceof UIMessage)
478 {
479 return ((UIMessage) component).isShowDetail();
480 }
481
482 return RendererUtils.getBooleanAttribute(component,
483 org.apache.myfaces.shared.renderkit.JSFAttr.SHOW_DETAIL_ATTR, false);
484
485 }
486
487 protected boolean isRedisplay(UIComponent component)
488 {
489 if (component instanceof UIMessage)
490 {
491 return ((UIMessage) component).isRedisplay();
492 }
493
494 return org.apache.myfaces.shared.renderkit.RendererUtils.getBooleanAttribute(component,
495 org.apache.myfaces.shared.renderkit.JSFAttr.REDISPLAY_ATTR, true);
496
497 }
498
499 }