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