1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.renderkit.html.ext;
20
21 import org.apache.commons.logging.Log;
22 import org.apache.commons.logging.LogFactory;
23 import org.apache.myfaces.component.html.ext.HtmlMessage;
24 import org.apache.myfaces.component.html.ext.HtmlMessages;
25 import org.apache.myfaces.shared_tomahawk.renderkit.RendererUtils;
26 import org.apache.myfaces.shared_tomahawk.renderkit.html.HTML;
27 import org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlMessageRendererBase;
28
29 import javax.faces.application.FacesMessage;
30 import javax.faces.component.UIColumn;
31 import javax.faces.component.UIComponent;
32 import javax.faces.component.ValueHolder;
33 import javax.faces.component.html.HtmlOutputLabel;
34 import javax.faces.component.html.HtmlOutputText;
35 import javax.faces.context.FacesContext;
36 import javax.faces.context.ResponseWriter;
37 import java.io.IOException;
38 import java.text.MessageFormat;
39 import java.util.HashMap;
40 import java.util.Iterator;
41 import java.util.List;
42 import java.util.Map;
43
44
45
46
47
48
49
50
51
52
53 public class HtmlMessageRenderer
54 extends HtmlMessageRendererBase
55 {
56 private static final Log log = LogFactory.getLog(HtmlMessageRenderer.class);
57
58 private static final String OUTPUT_LABEL_MAP = HtmlMessageRenderer.class.getName() + ".OUTPUT_LABEL_MAP";
59
60 public void encodeEnd(FacesContext facesContext, UIComponent component)
61 throws IOException
62 {
63 super.encodeEnd(facesContext, component);
64 renderMessage(facesContext, component);
65
66 if (component instanceof HtmlMessage
67 && ((HtmlMessage)component).getForceSpan())
68 {
69 String forAttr = getFor(component);
70 HtmlMessage htmlMessage = (HtmlMessage) component;
71
72 UIComponent forComponent = component.findComponent(forAttr);
73
74 if (forComponent != null)
75 {
76 String forCompclientId = forComponent.getClientId(facesContext);
77
78 ResponseWriter writer = facesContext.getResponseWriter();
79 writer.startElement(HTML.SPAN_ELEM, null);
80 writer.writeAttribute(HTML.ID_ATTR, forCompclientId + "_msgFor", null);
81 if(htmlMessage.getStyleClass()!=null)
82 writer.writeAttribute(HTML.CLASS_ATTR,htmlMessage.getStyleClass(),null);
83 if(htmlMessage.getStyle()!=null)
84 writer.writeAttribute(HTML.STYLE_ATTR,htmlMessage.getStyle(),null);
85 writer.endElement(HTML.SPAN_ELEM);
86 }
87 }
88 }
89
90 protected String getSummary(FacesContext facesContext,
91 UIComponent message,
92 FacesMessage facesMessage,
93 String msgClientId)
94 {
95 String msgSummary = facesMessage.getSummary();
96 if (msgSummary == null) return null;
97
98 String inputLabel = null;
99 if (msgClientId != null) inputLabel = findInputLabel(facesContext, msgClientId);
100 if (inputLabel == null) inputLabel = "";
101
102 if(((message instanceof HtmlMessages && ((HtmlMessages) message).isReplaceIdWithLabel()) ||
103 (message instanceof HtmlMessage && ((HtmlMessage) message).isReplaceIdWithLabel()))&&
104 inputLabel.length()!=0)
105 msgSummary = msgSummary.replaceAll(findInputId(facesContext, msgClientId),inputLabel);
106
107
108 String summaryFormat;
109 if (message instanceof HtmlMessage)
110 {
111 summaryFormat = ((HtmlMessage)message).getSummaryFormat();
112 }
113 else
114 {
115 summaryFormat = (String)message.getAttributes().get("summaryFormat");
116 }
117
118 if (summaryFormat == null) return msgSummary;
119
120 MessageFormat format = new MessageFormat(summaryFormat, facesContext.getViewRoot().getLocale());
121
122 return format.format(new Object[] {msgSummary, inputLabel});
123 }
124
125 protected String getDetail(FacesContext facesContext,
126 UIComponent message,
127 FacesMessage facesMessage,
128 String msgClientId)
129 {
130 String msgDetail = facesMessage.getDetail();
131 if (msgDetail == null) return null;
132
133 String inputLabel = null;
134 if (msgClientId != null) inputLabel = findInputLabel(facesContext, msgClientId);
135 if (inputLabel == null) inputLabel = "";
136
137 if(((message instanceof HtmlMessages && ((HtmlMessages) message).isReplaceIdWithLabel()) ||
138 (message instanceof HtmlMessage && ((HtmlMessage) message).isReplaceIdWithLabel()))&&
139 inputLabel.length()!=0)
140 msgDetail = msgDetail.replaceAll(findInputId(facesContext, msgClientId),inputLabel);
141
142 String detailFormat;
143 if (message instanceof HtmlMessage)
144 {
145 detailFormat = ((HtmlMessage)message).getDetailFormat();
146 }
147 else
148 {
149 detailFormat = (String)message.getAttributes().get("detailFormat");
150 }
151
152 if (detailFormat == null) return msgDetail;
153
154 MessageFormat format = new MessageFormat(detailFormat, facesContext.getViewRoot().getLocale());
155 return format.format(new Object[] {msgDetail, inputLabel});
156 }
157
158
159 public static String findInputLabel(FacesContext facesContext, String inputClientId)
160 {
161 Map outputLabelMap = getOutputLabelMap(facesContext);
162 MessageLabelInfo info = ((MessageLabelInfo)outputLabelMap.get(inputClientId));
163
164 if(info == null)
165 {
166 UIComponent comp = facesContext.getViewRoot().findComponent(inputClientId);
167
168 UIComponent parent=comp;
169
170 while(parent != null && !((parent=parent.getParent())instanceof UIColumn));
171
172 if(parent != null)
173 {
174 UIColumn column = (UIColumn) parent;
175
176 if(column.getHeader()!=null)
177 {
178 UIComponent header = column.getHeader();
179
180 return getComponentText(facesContext, header);
181 }
182 }
183 }
184
185 return info==null?null:info.getText(facesContext);
186 }
187
188 public static String findInputId(FacesContext facesContext, String inputClientId)
189 {
190 Map outputLabelMap = getOutputLabelMap(facesContext);
191 MessageLabelInfo info = ((MessageLabelInfo)outputLabelMap.get(inputClientId));
192
193 if(info == null)
194 {
195 UIComponent comp = facesContext.getViewRoot().findComponent(inputClientId);
196
197 if(comp!=null)
198 {
199 return comp.getId();
200 }
201 }
202
203 return info==null?null:(info.getForComponent()==null?null:info.getForComponent().getId());
204 }
205
206
207
208
209
210
211 private static Map getOutputLabelMap(FacesContext facesContext)
212 {
213 Map map = (Map)facesContext.getExternalContext().getRequestMap().get(OUTPUT_LABEL_MAP);
214 if (map == null)
215 {
216 map = new HashMap();
217 createOutputLabelMap(facesContext, facesContext.getViewRoot(), map);
218 facesContext.getExternalContext().getRequestMap().put(OUTPUT_LABEL_MAP, map);
219 }
220 return map;
221 }
222
223 private static void createOutputLabelMap(FacesContext facesContext,
224 UIComponent root,
225 Map map)
226 {
227 for (Iterator it = root.getFacetsAndChildren(); it.hasNext(); )
228 {
229 UIComponent child = (UIComponent)it.next();
230 if (child instanceof HtmlOutputLabel)
231 {
232 String forAttr = ((HtmlOutputLabel)child).getFor();
233 if (forAttr != null)
234 {
235 UIComponent input = child.findComponent(forAttr);
236 if (input == null)
237 {
238 log.warn("Unable to find component '" + forAttr + "' (calling findComponent on component '" + child.getClientId(facesContext) + "')");
239 }
240 else
241 {
242 if (child.getValueBinding("value") != null)
243 {
244
245
246 map.put(input.getClientId(facesContext),
247 new MessageDefferedLabelInfo(
248 input, child));
249 }
250 else
251 {
252 map.put(input.getClientId(facesContext),
253 new MessageTextLabelInfo(
254 input,getComponentText(facesContext, (HtmlOutputLabel)child)));
255 }
256 }
257 }
258 }
259 else
260 {
261 createOutputLabelMap(facesContext, child, map);
262 }
263 }
264 }
265
266 private static String getComponentText(FacesContext facesContext, UIComponent component)
267 {
268 String text = null;
269
270 if(component instanceof ValueHolder)
271 {
272 text= RendererUtils.getStringValue(facesContext, component);
273 }
274
275 if (text == null || text.length() < 1)
276 {
277 StringBuffer buf = new StringBuffer();
278 List li = component.getChildren();
279
280 for (int i = 0; i < li.size(); i++)
281 {
282 UIComponent child = (UIComponent) li.get(i);
283
284 if(child instanceof HtmlOutputText)
285 {
286 String str = RendererUtils.getStringValue(facesContext, child);
287
288 if(str!=null)
289 buf.append(str);
290 }
291 }
292
293 text = buf.toString();
294 }
295 return text;
296 }
297
298 public static interface MessageLabelInfo
299 {
300 public UIComponent getForComponent();
301 public String getText(FacesContext context);
302 }
303
304 public final static class MessageTextLabelInfo implements MessageLabelInfo
305 {
306 private final UIComponent _forComponent;
307 private final String _text;
308
309 public MessageTextLabelInfo(final UIComponent forComponent, final String text)
310 {
311 _forComponent = forComponent;
312 _text = text;
313 }
314
315 public UIComponent getForComponent()
316 {
317 return _forComponent;
318 }
319
320 public String getText(FacesContext context)
321 {
322 return _text;
323 }
324 }
325
326 public final static class MessageDefferedLabelInfo implements MessageLabelInfo
327 {
328 private final UIComponent _forComponent;
329 private final UIComponent _labelComponent;
330 private String _text;
331
332 public MessageDefferedLabelInfo(final UIComponent forComponent, final UIComponent labelComponent)
333 {
334 _forComponent = forComponent;
335 _labelComponent = labelComponent;
336 }
337
338
339 public UIComponent getForComponent()
340 {
341 return _forComponent;
342 }
343
344 public String getText(FacesContext context)
345 {
346 if (_text == null)
347 {
348 _text = getComponentText(context, (HtmlOutputLabel)_labelComponent);
349 }
350 return _text;
351 }
352 }
353 }