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.NoSuchElementException;
26 import java.util.logging.Level;
27 import java.util.logging.Logger;
28
29 import javax.faces.application.FacesMessage;
30 import javax.faces.component.UIComponent;
31 import javax.faces.component.UIMessages;
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.HtmlMessages;
36 import javax.faces.context.FacesContext;
37 import javax.faces.context.ResponseWriter;
38
39 import org.apache.myfaces.shared.renderkit.JSFAttr;
40 import org.apache.myfaces.shared.renderkit.RendererUtils;
41 import org.apache.myfaces.shared.util.NullIterator;
42
43
44
45
46
47 public abstract class HtmlMessagesRendererBase
48 extends HtmlMessageRendererBase
49 {
50
51 private static final Logger log = Logger.getLogger(HtmlMessagesRendererBase.class.getName());
52
53 protected static final String LAYOUT_LIST = "list";
54 protected static final String LAYOUT_TABLE = "table";
55
56 protected void renderMessages(FacesContext facesContext,
57 UIComponent messages)
58 throws IOException
59 {
60 renderMessages(facesContext, messages, false);
61 }
62
63 protected void renderMessages(FacesContext facesContext,
64 UIComponent messages, boolean alwaysRenderSpan)
65 throws IOException
66 {
67 renderMessages(facesContext, messages, alwaysRenderSpan, false);
68 }
69
70 protected void renderMessages(FacesContext facesContext,
71 UIComponent messages, boolean alwaysRenderSpan,
72 boolean renderDivWhenNoMessagesAndIdSet)
73 throws IOException
74 {
75
76 String forAttr = getFor(messages);
77 UIComponent forComponent = null;
78 if(forAttr != null && !"".equals(forAttr))
79 {
80 forComponent = messages.findComponent(forAttr);
81 if (forComponent == null)
82 {
83 log.severe("Could not render Messages. Unable to find component '"
84 + forAttr + "' (calling findComponent on component '"
85 + messages.getClientId(facesContext)
86 + "'). If the provided id was correct, wrap the message and its "
87 + "component into an h:panelGroup or h:panelGrid.");
88 return;
89 }
90 }
91
92 MessagesIterator messagesIterator = new MessagesIterator(facesContext,
93 isGlobalOnly(messages), isRedisplay(messages), forComponent);
94
95 if (messagesIterator.hasNext())
96 {
97 String layout = getLayout(messages);
98 if (layout == null)
99 {
100 if (log.isLoggable(Level.FINE))
101 {
102 log.fine("No messages layout given, using default layout 'list'.");
103 }
104 renderList(facesContext, messages, messagesIterator);
105 }
106 else if (layout.equalsIgnoreCase(LAYOUT_TABLE))
107 {
108 renderTable(facesContext, messages, messagesIterator);
109 }
110 else
111 {
112 if (log.isLoggable(Level.WARNING) && !layout.equalsIgnoreCase(LAYOUT_LIST))
113 {
114 log.warning("Unsupported messages layout '" + layout + "' - using default layout 'list'.");
115 }
116 renderList(facesContext, messages, messagesIterator);
117 }
118 }
119 else
120 {
121 if (renderDivWhenNoMessagesAndIdSet && messages.getId() != null &&
122 !messages.getId().startsWith(UIViewRoot.UNIQUE_ID_PREFIX))
123 {
124 ResponseWriter writer = facesContext.getResponseWriter();
125 writer.startElement(HTML.DIV_ELEM, messages);
126 writer.writeAttribute(HTML.ID_ATTR, messages.getClientId(facesContext), null);
127 writer.endElement(HTML.DIV_ELEM);
128 }
129 }
130
131 if (!renderDivWhenNoMessagesAndIdSet && alwaysRenderSpan)
132 {
133 Object forceSpan = messages.getAttributes().get("forceSpan");
134 boolean b = forceSpan instanceof Boolean ? (Boolean) forceSpan : Boolean.valueOf(forceSpan.toString());
135 if (b)
136 {
137 ResponseWriter writer = facesContext.getResponseWriter();
138
139 writer.startElement(HTML.SPAN_ELEM, null);
140 writer.writeAttribute(HTML.ID_ATTR,messages.getClientId(facesContext),null);
141 if(messages.getAttributes().get(JSFAttr.STYLE_CLASS_ATTR)!=null)
142 {
143 writer.writeAttribute(
144 HTML.CLASS_ATTR, messages.getAttributes().get(JSFAttr.STYLE_CLASS_ATTR), null);
145 }
146 if(messages.getAttributes().get(JSFAttr.STYLE_ATTR)!=null)
147 {
148 writer.writeAttribute(HTML.STYLE_ATTR, messages.getAttributes().get(JSFAttr.STYLE_ATTR), null);
149 }
150 writer.endElement(HTML.SPAN_ELEM);
151 }
152 }
153 }
154
155
156 private void renderList(FacesContext facesContext,
157 UIComponent messages,
158 MessagesIterator messagesIterator)
159 throws IOException
160 {
161 ResponseWriter writer = facesContext.getResponseWriter();
162
163 writer.startElement(HTML.UL_ELEM, messages);
164
165 Map<String, List<ClientBehavior>> behaviors = null;
166 if (messages instanceof ClientBehaviorHolder)
167 {
168 behaviors = ((ClientBehaviorHolder) messages).getClientBehaviors();
169 }
170
171 if (behaviors != null && !behaviors.isEmpty())
172 {
173 writer.writeAttribute(HTML.ID_ATTR, messages.getClientId(facesContext), null);
174 }
175 else
176 {
177 HtmlRendererUtils.writeIdIfNecessary(writer, messages, facesContext);
178 }
179 HtmlRendererUtils.renderHTMLAttributes(writer, messages, HTML.UNIVERSAL_ATTRIBUTES_WITHOUT_STYLE);
180
181 HtmlRendererUtils.renderHTMLAttribute(writer, HTML.STYLE_ATTR, HTML.STYLE_ATTR, getComponentStyle(messages));
182 HtmlRendererUtils.renderHTMLAttribute(writer, HTML.STYLE_CLASS_ATTR, HTML.STYLE_CLASS_ATTR,
183 getComponentStyleClass(messages));
184
185 while(messagesIterator.hasNext())
186 {
187 writer.startElement(org.apache.myfaces.shared.renderkit.html.HTML.LI_ELEM, messages);
188
189 FacesMessage facesMessage = (FacesMessage)messagesIterator.next();
190
191 String[] styleAndClass = getStyleAndStyleClass(messages, facesMessage.getSeverity());
192 String style = styleAndClass[0];
193 String styleClass = styleAndClass[1];
194
195 HtmlRendererUtils.renderHTMLAttribute(writer, HTML.STYLE_ATTR, HTML.STYLE_ATTR, style);
196 HtmlRendererUtils.renderHTMLAttribute(writer, HTML.STYLE_CLASS_ATTR, HTML.STYLE_CLASS_ATTR, styleClass);
197
198 renderSingleFacesMessage(facesContext,
199 messages,
200 facesMessage,
201 messagesIterator.getClientId(),false,false,false);
202 writer.endElement(HTML.LI_ELEM);
203 }
204
205 writer.endElement(HTML.UL_ELEM);
206 }
207
208
209 private void renderTable(FacesContext facesContext,
210 UIComponent messages,
211 MessagesIterator messagesIterator)
212 throws IOException
213 {
214 ResponseWriter writer = facesContext.getResponseWriter();
215
216 writer.startElement(HTML.TABLE_ELEM, messages);
217
218 Map<String, List<ClientBehavior>> behaviors = null;
219 if (messages instanceof ClientBehaviorHolder)
220 {
221 behaviors = ((ClientBehaviorHolder) messages).getClientBehaviors();
222 }
223
224 if (behaviors != null && !behaviors.isEmpty())
225 {
226 writer.writeAttribute(HTML.ID_ATTR, messages.getClientId(facesContext), null);
227 }
228 else
229 {
230 HtmlRendererUtils.writeIdIfNecessary(writer, messages, facesContext);
231 }
232 HtmlRendererUtils.renderHTMLAttributes(writer, messages, HTML.UNIVERSAL_ATTRIBUTES_WITHOUT_STYLE);
233
234 HtmlRendererUtils.renderHTMLAttribute(writer, HTML.STYLE_ATTR, HTML.STYLE_ATTR, getComponentStyle(messages));
235 HtmlRendererUtils.renderHTMLAttribute(writer, HTML.STYLE_CLASS_ATTR, HTML.STYLE_CLASS_ATTR,
236 getComponentStyleClass(messages));
237
238 while(messagesIterator.hasNext())
239 {
240 writer.startElement(HTML.TR_ELEM, messages);
241 writer.startElement(HTML.TD_ELEM, messages);
242
243 FacesMessage facesMessage = (FacesMessage)messagesIterator.next();
244
245 String[] styleAndClass = getStyleAndStyleClass(messages, facesMessage.getSeverity());
246 String style = styleAndClass[0];
247 String styleClass = styleAndClass[1];
248
249 HtmlRendererUtils.renderHTMLAttribute(writer, HTML.STYLE_ATTR, HTML.STYLE_ATTR, style);
250 HtmlRendererUtils.renderHTMLAttribute(writer, HTML.STYLE_CLASS_ATTR, HTML.STYLE_CLASS_ATTR, styleClass);
251
252 renderSingleFacesMessage(facesContext,
253 messages,
254 facesMessage,
255 messagesIterator.getClientId(),false,false,false);
256
257 writer.endElement(HTML.TD_ELEM);
258 writer.endElement(HTML.TR_ELEM);
259 }
260
261 writer.endElement(HTML.TABLE_ELEM);
262 }
263
264
265 public static String[] getStyleAndStyleClass(UIComponent messages,
266 FacesMessage.Severity severity)
267 {
268 String style = null;
269 String styleClass = null;
270 if (messages instanceof HtmlMessages)
271 {
272 if (severity == FacesMessage.SEVERITY_INFO)
273 {
274 style = ((HtmlMessages)messages).getInfoStyle();
275 styleClass = ((HtmlMessages)messages).getInfoClass();
276 }
277 else if (severity == FacesMessage.SEVERITY_WARN)
278 {
279 style = ((HtmlMessages)messages).getWarnStyle();
280 styleClass = ((HtmlMessages)messages).getWarnClass();
281 }
282 else if (severity == FacesMessage.SEVERITY_ERROR)
283 {
284 style = ((HtmlMessages)messages).getErrorStyle();
285 styleClass = ((HtmlMessages)messages).getErrorClass();
286 }
287 else if (severity == FacesMessage.SEVERITY_FATAL)
288 {
289 style = ((HtmlMessages)messages).getFatalStyle();
290 styleClass = ((HtmlMessages)messages).getFatalClass();
291 }
292
293
294
295
296
297
298
299
300
301
302 }
303 else
304 {
305 Map attr = messages.getAttributes();
306 if (severity == FacesMessage.SEVERITY_INFO)
307 {
308 style = (String)attr.get(org.apache.myfaces.shared.renderkit.JSFAttr.INFO_STYLE_ATTR);
309 styleClass = (String)attr.get(org.apache.myfaces.shared.renderkit.JSFAttr.INFO_CLASS_ATTR);
310 }
311 else if (severity == FacesMessage.SEVERITY_WARN)
312 {
313 style = (String)attr.get(org.apache.myfaces.shared.renderkit.JSFAttr.WARN_STYLE_ATTR);
314 styleClass = (String)attr.get(org.apache.myfaces.shared.renderkit.JSFAttr.WARN_CLASS_ATTR);
315 }
316 else if (severity == FacesMessage.SEVERITY_ERROR)
317 {
318 style = (String)attr.get(org.apache.myfaces.shared.renderkit.JSFAttr.ERROR_STYLE_ATTR);
319 styleClass = (String)attr.get(org.apache.myfaces.shared.renderkit.JSFAttr.ERROR_CLASS_ATTR);
320 }
321 else if (severity == FacesMessage.SEVERITY_FATAL)
322 {
323 style = (String)attr.get(org.apache.myfaces.shared.renderkit.JSFAttr.FATAL_STYLE_ATTR);
324 styleClass = (String)attr.get(JSFAttr.FATAL_CLASS_ATTR);
325 }
326
327
328
329
330
331
332
333
334
335
336 }
337
338 return new String[] {style, styleClass};
339 }
340
341 protected String getComponentStyleClass(UIComponent messages)
342 {
343 String styleClass = null;
344 if (messages instanceof HtmlMessages)
345 {
346 styleClass = ((HtmlMessages)messages).getStyleClass();
347 }
348 else
349 {
350 Map attr = messages.getAttributes();
351 styleClass = (String)attr.get(org.apache.myfaces.shared.renderkit.JSFAttr.STYLE_CLASS_ATTR);
352 }
353 return styleClass;
354 }
355
356 protected String getComponentStyle(UIComponent messages)
357 {
358 String style = null;
359 if (messages instanceof HtmlMessages)
360 {
361 style = ((HtmlMessages)messages).getStyle();
362 }
363 else
364 {
365 Map attr = messages.getAttributes();
366 style = (String)attr.get(org.apache.myfaces.shared.renderkit.JSFAttr.STYLE_ATTR);
367 }
368 return style;
369 }
370
371 protected String getTitle(UIComponent component)
372 {
373 if (component instanceof HtmlMessages)
374 {
375 return ((HtmlMessages)component).getTitle();
376 }
377 else
378 {
379 return (String)component.getAttributes().get(org.apache.myfaces.shared.renderkit.JSFAttr.TITLE_ATTR);
380 }
381 }
382
383 protected boolean isTooltip(UIComponent component)
384 {
385 if (component instanceof HtmlMessages)
386 {
387 return ((HtmlMessages)component).isTooltip();
388 }
389 else
390 {
391 return org.apache.myfaces.shared.renderkit.RendererUtils.getBooleanAttribute(component,
392 org.apache.myfaces.shared.renderkit.JSFAttr.TOOLTIP_ATTR, false);
393 }
394 }
395
396 protected boolean isShowSummary(UIComponent component)
397 {
398 if (component instanceof UIMessages)
399 {
400 return ((UIMessages)component).isShowSummary();
401 }
402 else
403 {
404 return RendererUtils.getBooleanAttribute(component, JSFAttr.SHOW_SUMMARY_ATTR, false);
405 }
406 }
407
408 protected boolean isShowDetail(UIComponent component)
409 {
410 if (component instanceof UIMessages)
411 {
412 return ((UIMessages)component).isShowDetail();
413 }
414 else
415 {
416 return org.apache.myfaces.shared.renderkit.RendererUtils.getBooleanAttribute(
417 component, JSFAttr.SHOW_DETAIL_ATTR, false);
418 }
419 }
420
421 protected boolean isGlobalOnly(UIComponent component)
422 {
423 if (component instanceof UIMessages)
424 {
425 return ((UIMessages)component).isGlobalOnly();
426 }
427 else
428 {
429 return org.apache.myfaces.shared.renderkit.RendererUtils.getBooleanAttribute(
430 component, JSFAttr.GLOBAL_ONLY_ATTR, false);
431 }
432 }
433
434 protected String getLayout(UIComponent component)
435 {
436 if (component instanceof HtmlMessages)
437 {
438 return ((HtmlMessages)component).getLayout();
439 }
440 else
441 {
442 return (String)component.getAttributes().get(JSFAttr.LAYOUT_ATTR);
443 }
444 }
445
446 protected String getFor(UIComponent component)
447 {
448 if (component instanceof UIMessages)
449 {
450 return ((UIMessages) component).getFor();
451 }
452
453 return (String) component.getAttributes().get(JSFAttr.FOR_ATTR);
454 }
455
456 protected boolean isRedisplay(UIComponent component)
457 {
458 if (component instanceof UIMessages)
459 {
460 return ((UIMessages) component).isRedisplay();
461 }
462
463 return org.apache.myfaces.shared.renderkit.RendererUtils.getBooleanAttribute(
464 component, org.apache.myfaces.shared.renderkit.JSFAttr.REDISPLAY_ATTR, true);
465
466 }
467
468 private static class MessagesIterator implements Iterator
469 {
470 private FacesContext _facesContext;
471 private Iterator _globalMessagesIterator;
472 private Iterator _clientIdsWithMessagesIterator;
473 private Iterator _componentMessagesIterator = null;
474 private String _clientId = null;
475 private boolean _redisplay;
476 private Object _next;
477
478 public MessagesIterator(FacesContext facesContext, boolean globalOnly, boolean redisplay,
479 UIComponent forComponent)
480 {
481 _facesContext = facesContext;
482
483 if(forComponent != null)
484 {
485 _clientId = forComponent.getClientId(facesContext);
486 _componentMessagesIterator = facesContext.getMessages(_clientId);
487 _globalMessagesIterator = org.apache.myfaces.shared.util.NullIterator.instance();
488 _clientIdsWithMessagesIterator = org.apache.myfaces.shared.util.NullIterator.instance();
489 }
490 else
491 {
492 if (globalOnly)
493 {
494 _globalMessagesIterator = facesContext.getMessages(null);
495 _clientIdsWithMessagesIterator = NullIterator.instance();
496 }
497 else
498 {
499 _globalMessagesIterator = org.apache.myfaces.shared.util.NullIterator.instance();
500 _clientIdsWithMessagesIterator = facesContext.getClientIdsWithMessages();
501 }
502 _componentMessagesIterator = null;
503 _clientId = null;
504 }
505
506 _redisplay = redisplay;
507 _next = null;
508 }
509
510 public boolean hasNext()
511 {
512 if(_next != null)
513 {
514 return true;
515 }
516 if(_globalMessagesIterator.hasNext())
517 {
518 do
519 {
520 _next = _globalMessagesIterator.next();
521 if(_redisplay || !((FacesMessage)_next).isRendered())
522 {
523 return true;
524 }
525 }
526 while(_globalMessagesIterator.hasNext());
527 }
528 if(_componentMessagesIterator != null && _componentMessagesIterator.hasNext())
529 {
530 do
531 {
532 _next = _componentMessagesIterator.next();
533 if(_redisplay || !((FacesMessage)_next).isRendered())
534 {
535 return true;
536 }
537 }
538 while(_componentMessagesIterator.hasNext());
539 }
540 if(_clientIdsWithMessagesIterator.hasNext())
541 {
542 do
543 {
544 _clientId = (String) _clientIdsWithMessagesIterator.next();
545 _componentMessagesIterator = _facesContext.getMessages(_clientId);
546 while(_componentMessagesIterator.hasNext())
547 {
548 _next = _componentMessagesIterator.next();
549 if(_redisplay || !((FacesMessage)_next).isRendered())
550 {
551 return true;
552 }
553 }
554 }
555 while(_clientIdsWithMessagesIterator.hasNext());
556
557 }
558 _next = null;
559 return false;
560 }
561
562 public Object next()
563 {
564 if(this.hasNext())
565 {
566 Object ret = _next;
567 _next = null;
568 return ret;
569 }
570 throw new NoSuchElementException();
571 }
572
573 public void remove()
574 {
575 throw new UnsupportedOperationException(this.getClass().getName() + " UnsupportedOperationException");
576 }
577
578 public String getClientId()
579 {
580 return _clientId;
581 }
582 }
583
584 }