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.List;
23 import java.util.Map;
24 import java.util.logging.Level;
25 import java.util.logging.Logger;
26
27 import javax.faces.component.UIComponent;
28 import javax.faces.component.UIInput;
29 import javax.faces.component.UIOutput;
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.HtmlInputText;
34 import javax.faces.component.html.HtmlOutputText;
35 import javax.faces.context.FacesContext;
36 import javax.faces.context.ResponseWriter;
37 import javax.faces.convert.ConverterException;
38
39 import org.apache.myfaces.shared.component.EscapeCapable;
40 import org.apache.myfaces.shared.renderkit.JSFAttr;
41 import org.apache.myfaces.shared.renderkit.RendererUtils;
42 import org.apache.myfaces.shared.renderkit.html.util.ResourceUtils;
43
44 public class HtmlTextRendererBase
45 extends HtmlRenderer
46 {
47
48 private static final Logger log = Logger.getLogger(HtmlTextRendererBase.class.getName());
49
50 private static final String AUTOCOMPLETE_VALUE_OFF = "off";
51
52 public void encodeEnd(FacesContext facesContext, UIComponent component)
53 throws IOException
54 {
55 org.apache.myfaces.shared.renderkit.RendererUtils.checkParamValidity(facesContext,component,null);
56
57 Map<String, List<ClientBehavior>> behaviors = null;
58 if (component instanceof ClientBehaviorHolder)
59 {
60 behaviors = ((ClientBehaviorHolder) component).getClientBehaviors();
61 if (!behaviors.isEmpty())
62 {
63 ResourceUtils.renderDefaultJsfJsInlineIfNecessary(facesContext, facesContext.getResponseWriter());
64 }
65 }
66
67 if (component instanceof UIInput)
68 {
69 renderInput(facesContext, component);
70 }
71 else if (component instanceof UIOutput)
72 {
73 renderOutput(facesContext, component);
74 }
75 else
76 {
77 throw new IllegalArgumentException("Unsupported component class " + component.getClass().getName());
78 }
79 }
80
81
82 protected void renderOutput(FacesContext facesContext, UIComponent component)
83 throws IOException
84 {
85
86 String text = org.apache.myfaces.shared.renderkit.RendererUtils.getStringValue(facesContext, component);
87 if (log.isLoggable(Level.FINE))
88 {
89 log.fine("renderOutput '" + text + "'");
90 }
91 boolean escape;
92 if (component instanceof HtmlOutputText || component instanceof EscapeCapable)
93 {
94 escape = ((HtmlOutputText)component).isEscape();
95 }
96 else
97 {
98 escape = RendererUtils.getBooleanAttribute(component,
99 org.apache.myfaces.shared.renderkit.JSFAttr.ESCAPE_ATTR,
100 true);
101 }
102 if (text != null)
103 {
104 ResponseWriter writer = facesContext.getResponseWriter();
105 boolean span = false;
106
107 if (isCommonPropertiesOptimizationEnabled(facesContext))
108 {
109 long commonPropertiesMarked = CommonPropertyUtils.getCommonPropertiesMarked(component);
110 if ( (commonPropertiesMarked & ~(CommonPropertyConstants.ESCAPE_PROP)) > 0)
111 {
112 span = true;
113 writer.startElement(HTML.SPAN_ELEM, component);
114 HtmlRendererUtils.writeIdIfNecessary(writer, component, facesContext);
115 }
116 else if (CommonPropertyUtils.isIdRenderingNecessary(component))
117 {
118 span = true;
119 writer.startElement(HTML.SPAN_ELEM, component);
120 writer.writeAttribute(HTML.ID_ATTR, component.getClientId(facesContext), null);
121 }
122
123 CommonPropertyUtils.renderUniversalProperties(writer, commonPropertiesMarked, component);
124 CommonPropertyUtils.renderStyleProperties(writer, commonPropertiesMarked, component);
125
126 if (isRenderOutputEventAttributes())
127 {
128 HtmlRendererUtils.renderHTMLAttributes(writer, component, HTML.EVENT_HANDLER_ATTRIBUTES);
129 }
130 }
131 else
132 {
133 if(component.getId()!=null && !component.getId().startsWith(UIViewRoot.UNIQUE_ID_PREFIX))
134 {
135 span = true;
136
137 writer.startElement(HTML.SPAN_ELEM, component);
138
139 HtmlRendererUtils.writeIdIfNecessary(writer, component, facesContext);
140
141 HtmlRendererUtils.renderHTMLAttributes(writer, component, HTML.COMMON_PASSTROUGH_ATTRIBUTES);
142
143 }
144 else
145 {
146 span = HtmlRendererUtils.renderHTMLAttributesWithOptionalStartElement(writer,component,
147 HTML.SPAN_ELEM,HTML.COMMON_PASSTROUGH_ATTRIBUTES);
148 }
149 }
150
151 if (escape)
152 {
153 if (log.isLoggable(Level.FINE))
154 {
155 log.fine("renderOutputText writing '" + text + "'");
156 }
157 writer.writeText(text, org.apache.myfaces.shared.renderkit.JSFAttr.VALUE_ATTR);
158 }
159 else
160 {
161 writer.write(text);
162 }
163
164 if(span)
165 {
166 writer.endElement(org.apache.myfaces.shared.renderkit.html.HTML.SPAN_ELEM);
167 }
168 }
169 }
170
171 protected boolean isRenderOutputEventAttributes()
172 {
173 return true;
174 }
175
176 protected void renderInput(FacesContext facesContext, UIComponent component)
177 throws IOException
178 {
179
180 renderInputBegin(facesContext, component);
181 renderInputEnd(facesContext, component);
182 }
183
184
185 protected void renderInputBegin(FacesContext facesContext,
186 UIComponent component) throws IOException
187 {
188 ResponseWriter writer = facesContext.getResponseWriter();
189
190 String clientId = component.getClientId(facesContext);
191
192 writer.startElement(HTML.INPUT_ELEM, component);
193 writer.writeAttribute(HTML.ID_ATTR, clientId, null);
194 writer.writeAttribute(HTML.NAME_ATTR, clientId, null);
195
196
197 String inputHtmlType = getInputHtmlType(component);
198 writer.writeAttribute(HTML.TYPE_ATTR, inputHtmlType, null);
199
200 renderValue(facesContext, component, writer);
201
202 Map<String, List<ClientBehavior>> behaviors = null;
203 if (component instanceof ClientBehaviorHolder)
204 {
205 behaviors = ((ClientBehaviorHolder) component).getClientBehaviors();
206
207 long commonPropertiesMarked = 0L;
208 if (isCommonPropertiesOptimizationEnabled(facesContext))
209 {
210 commonPropertiesMarked = CommonPropertyUtils.getCommonPropertiesMarked(component);
211 }
212 if (behaviors.isEmpty() && isCommonPropertiesOptimizationEnabled(facesContext))
213 {
214 CommonPropertyUtils.renderChangeEventProperty(writer,
215 commonPropertiesMarked, component);
216 CommonPropertyUtils.renderEventProperties(writer,
217 commonPropertiesMarked, component);
218 CommonPropertyUtils.renderFieldEventPropertiesWithoutOnchange(writer,
219 commonPropertiesMarked, component);
220 }
221 else
222 {
223 HtmlRendererUtils.renderBehaviorizedOnchangeEventHandler(facesContext, writer, component, behaviors);
224 if (isCommonEventsOptimizationEnabled(facesContext))
225 {
226 Long commonEventsMarked = CommonEventUtils.getCommonEventsMarked(component);
227 CommonEventUtils.renderBehaviorizedEventHandlers(facesContext, writer,
228 commonPropertiesMarked, commonEventsMarked, component, behaviors);
229 CommonEventUtils.renderBehaviorizedFieldEventHandlersWithoutOnchange(
230 facesContext, writer, commonPropertiesMarked, commonEventsMarked, component, behaviors);
231 }
232 else
233 {
234 HtmlRendererUtils.renderBehaviorizedEventHandlers(facesContext, writer, component, behaviors);
235 HtmlRendererUtils.renderBehaviorizedFieldEventHandlersWithoutOnchange(
236 facesContext, writer, component, behaviors);
237 }
238 }
239 if (isCommonPropertiesOptimizationEnabled(facesContext))
240 {
241 CommonPropertyUtils.renderInputPassthroughPropertiesWithoutDisabledAndEvents(writer,
242 commonPropertiesMarked, component);
243 }
244 else
245 {
246 HtmlRendererUtils.renderHTMLAttributes(writer, component,
247 HTML.INPUT_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED_AND_EVENTS);
248 }
249 }
250 else
251 {
252 if (isCommonPropertiesOptimizationEnabled(facesContext))
253 {
254 CommonPropertyUtils.renderInputPassthroughPropertiesWithoutDisabled(writer,
255 CommonPropertyUtils.getCommonPropertiesMarked(component), component);
256 }
257 else
258 {
259 HtmlRendererUtils.renderHTMLAttributes(writer, component,
260 HTML.INPUT_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED);
261 }
262 }
263
264 if (isDisabled(facesContext, component))
265 {
266 writer.writeAttribute(HTML.DISABLED_ATTR, Boolean.TRUE, null);
267 }
268
269 if (isAutocompleteOff(facesContext, component))
270 {
271 writer.writeAttribute(HTML.AUTOCOMPLETE_ATTR, AUTOCOMPLETE_VALUE_OFF, HTML.AUTOCOMPLETE_ATTR);
272 }
273 }
274
275 protected void renderValue(FacesContext facesContext, UIComponent component, ResponseWriter writer)
276 throws IOException
277 {
278 String value = RendererUtils.getStringValue(facesContext, component);
279 if (log.isLoggable(Level.FINE))
280 {
281 log.fine("renderInput '" + value + "'");
282 }
283
284 if (value != null)
285 {
286 writer.writeAttribute(HTML.VALUE_ATTR, value, JSFAttr.VALUE_ATTR);
287 }
288 }
289
290 protected void renderInputEnd(FacesContext facesContext, UIComponent component) throws IOException
291 {
292 ResponseWriter writer = facesContext.getResponseWriter();
293
294 writer.endElement(HTML.INPUT_ELEM);
295 }
296
297 protected boolean isDisabled(FacesContext facesContext, UIComponent component)
298 {
299
300 if (component instanceof HtmlInputText)
301 {
302 return ((HtmlInputText)component).isDisabled();
303 }
304
305 return org.apache.myfaces.shared.renderkit.RendererUtils.getBooleanAttribute(component,
306 HTML.DISABLED_ATTR, false);
307
308 }
309
310
311
312
313 protected boolean isAutocompleteOff(FacesContext facesContext, UIComponent component)
314 {
315 if (component instanceof HtmlInputText)
316 {
317 String autocomplete = ((HtmlInputText)component).getAutocomplete();
318 if (autocomplete != null)
319 {
320 return autocomplete.equals(AUTOCOMPLETE_VALUE_OFF);
321 }
322 }
323
324 return false;
325 }
326
327
328 public void decode(FacesContext facesContext, UIComponent component)
329 {
330 RendererUtils.checkParamValidity(facesContext,component,null);
331
332 if (component instanceof UIInput)
333 {
334 HtmlRendererUtils.decodeUIInput(facesContext, component);
335 if (component instanceof ClientBehaviorHolder &&
336 !HtmlRendererUtils.isDisabled(component))
337 {
338 HtmlRendererUtils.decodeClientBehaviors(facesContext, component);
339 }
340 }
341 else if (component instanceof UIOutput)
342 {
343
344 }
345 else
346 {
347 throw new IllegalArgumentException("Unsupported component class " + component.getClass().getName());
348 }
349 }
350
351
352 public Object getConvertedValue(FacesContext facesContext, UIComponent component, Object submittedValue)
353 throws ConverterException
354 {
355 org.apache.myfaces.shared.renderkit.RendererUtils.checkParamValidity(facesContext, component, UIOutput.class);
356 return RendererUtils.getConvertedUIOutputValue(facesContext,
357 (UIOutput)component,
358 submittedValue);
359 }
360
361
362
363
364 protected String getInputHtmlType(UIComponent component)
365 {
366
367 return HTML.INPUT_TYPE_TEXT;
368 }
369
370 public static void renderOutputText(FacesContext facesContext,
371 UIComponent component, String text, boolean escape)
372 throws IOException
373 {
374 if (text != null)
375 {
376 ResponseWriter writer = facesContext.getResponseWriter();
377 boolean span = false;
378
379 if (component.getId() != null
380 && !component.getId().startsWith(
381 UIViewRoot.UNIQUE_ID_PREFIX))
382 {
383 span = true;
384
385 writer.startElement(HTML.SPAN_ELEM, component);
386
387 HtmlRendererUtils.writeIdIfNecessary(writer, component,
388 facesContext);
389
390 HtmlRendererUtils.renderHTMLAttributes(writer, component,
391 HTML.COMMON_PASSTROUGH_ATTRIBUTES);
392
393 }
394 else
395 {
396 span = HtmlRendererUtils
397 .renderHTMLAttributesWithOptionalStartElement(writer,
398 component, HTML.SPAN_ELEM,
399 HTML.COMMON_PASSTROUGH_ATTRIBUTES);
400 }
401
402 if (escape)
403 {
404 if (log.isLoggable(Level.FINE))
405 {
406 log.fine("renderOutputText writing '" + text + "'");
407 }
408 writer.writeText(text,
409 org.apache.myfaces.shared.renderkit.JSFAttr.VALUE_ATTR);
410 }
411 else
412 {
413 writer.write(text);
414 }
415
416 if (span)
417 {
418 writer.endElement(org.apache.myfaces.shared.renderkit.html.HTML.SPAN_ELEM);
419 }
420 }
421 }
422 }