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