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