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.Set;
26 import java.util.logging.Logger;
27
28 import javax.faces.component.UIComponent;
29 import javax.faces.component.UINamingContainer;
30 import javax.faces.component.UISelectBoolean;
31 import javax.faces.component.UISelectMany;
32 import javax.faces.component.UISelectOne;
33 import javax.faces.component.behavior.ClientBehavior;
34 import javax.faces.component.behavior.ClientBehaviorHolder;
35 import javax.faces.component.html.HtmlSelectBooleanCheckbox;
36 import javax.faces.component.html.HtmlSelectManyCheckbox;
37 import javax.faces.context.FacesContext;
38 import javax.faces.context.ResponseWriter;
39 import javax.faces.convert.Converter;
40 import javax.faces.convert.ConverterException;
41 import javax.faces.model.SelectItem;
42 import javax.faces.model.SelectItemGroup;
43
44 import org.apache.myfaces.shared.renderkit.JSFAttr;
45 import org.apache.myfaces.shared.renderkit.html.util.JavascriptUtils;
46 import org.apache.myfaces.shared.renderkit.html.util.ResourceUtils;
47
48
49
50
51
52
53 public class HtmlCheckboxRendererBase extends HtmlRenderer
54 {
55
56
57 private static final Logger log = Logger.getLogger(HtmlCheckboxRendererBase.class.getName());
58
59 private static final String PAGE_DIRECTION = "pageDirection";
60
61 private static final String LINE_DIRECTION = "lineDirection";
62
63 private static final String EXTERNAL_TRUE_VALUE = "true";
64
65 public void encodeEnd(FacesContext facesContext, UIComponent uiComponent)
66 throws IOException
67 {
68 org.apache.myfaces.shared.renderkit.RendererUtils.checkParamValidity(facesContext, uiComponent, null);
69
70 Map<String, List<ClientBehavior>> behaviors = null;
71 if (uiComponent instanceof ClientBehaviorHolder)
72 {
73 behaviors = ((ClientBehaviorHolder) uiComponent).getClientBehaviors();
74 if (!behaviors.isEmpty())
75 {
76 ResourceUtils.renderDefaultJsfJsInlineIfNecessary(facesContext, facesContext.getResponseWriter());
77 }
78 }
79
80 if (uiComponent instanceof UISelectBoolean)
81 {
82 Boolean value = org.apache.myfaces.shared.renderkit.RendererUtils.getBooleanValue( uiComponent );
83 boolean isChecked = value != null ? value.booleanValue() : false;
84 renderCheckbox(facesContext, uiComponent, EXTERNAL_TRUE_VALUE, false,isChecked, true, null);
85
86 }
87 else if (uiComponent instanceof UISelectMany)
88 {
89 renderCheckboxList(facesContext, (UISelectMany) uiComponent);
90 }
91 else
92 {
93 throw new IllegalArgumentException("Unsupported component class "
94 + uiComponent.getClass().getName());
95 }
96 }
97
98 public void renderCheckboxList(FacesContext facesContext,
99 UISelectMany selectMany) throws IOException
100 {
101
102 String layout = getLayout(selectMany);
103 boolean pageDirectionLayout = false;
104 if (layout != null)
105 {
106 if (layout.equals(PAGE_DIRECTION))
107 {
108 pageDirectionLayout = true;
109 }
110 else if (layout.equals(LINE_DIRECTION))
111 {
112 pageDirectionLayout = false;
113 }
114 else
115 {
116 log.severe("Wrong layout attribute for component "
117 + selectMany.getClientId(facesContext) + ": " + layout);
118 }
119 }
120
121 ResponseWriter writer = facesContext.getResponseWriter();
122
123 writer.startElement(HTML.TABLE_ELEM, selectMany);
124 HtmlRendererUtils.renderHTMLAttributes(writer, selectMany,
125 HTML.SELECT_TABLE_PASSTHROUGH_ATTRIBUTES);
126
127 Map<String, List<ClientBehavior>> behaviors = null;
128 if (selectMany instanceof ClientBehaviorHolder)
129 {
130 behaviors = ((ClientBehaviorHolder) selectMany).getClientBehaviors();
131 }
132
133 if (behaviors != null && !behaviors.isEmpty())
134 {
135 writer.writeAttribute(HTML.ID_ATTR, selectMany.getClientId(facesContext), null);
136 }
137 else
138 {
139 HtmlRendererUtils.writeIdIfNecessary(writer, selectMany, facesContext);
140 }
141
142 if (!pageDirectionLayout)
143 {
144 writer.startElement(HTML.TR_ELEM, selectMany);
145 }
146
147 Converter converter = getConverter(facesContext, selectMany);
148
149 Set lookupSet = org.apache.myfaces.shared.renderkit.RendererUtils.getSubmittedValuesAsSet(
150 facesContext, selectMany, converter, selectMany);
151 boolean useSubmittedValues = lookupSet != null;
152
153 if (!useSubmittedValues)
154 {
155 lookupSet = org.apache.myfaces.shared.renderkit.RendererUtils.getSelectedValuesAsSet(
156 facesContext, selectMany, converter, selectMany);
157 }
158
159 int itemNum = 0;
160
161 for (Iterator it = org.apache.myfaces.shared.renderkit.RendererUtils.getSelectItemList(
162 selectMany, facesContext)
163 .iterator(); it.hasNext();)
164 {
165 SelectItem selectItem = (SelectItem) it.next();
166
167 itemNum = renderGroupOrItemCheckbox(facesContext, selectMany,
168 selectItem, useSubmittedValues, lookupSet,
169 converter, pageDirectionLayout, itemNum);
170 }
171
172 if (!pageDirectionLayout)
173 {
174 writer.endElement(HTML.TR_ELEM);
175 }
176 writer.endElement(HTML.TABLE_ELEM);
177 }
178
179 protected String getLayout(UISelectMany selectMany)
180 {
181 if (selectMany instanceof HtmlSelectManyCheckbox)
182 {
183 return ((HtmlSelectManyCheckbox) selectMany).getLayout();
184 }
185
186 return (String) selectMany.getAttributes().get(JSFAttr.LAYOUT_ATTR);
187 }
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202 protected int renderGroupOrItemCheckbox(FacesContext facesContext,
203 UIComponent uiComponent, SelectItem selectItem,
204 boolean useSubmittedValues, Set lookupSet,
205 Converter converter, boolean pageDirectionLayout,
206 Integer itemNum) throws IOException
207 {
208
209 ResponseWriter writer = facesContext.getResponseWriter();
210
211 boolean isSelectItemGroup = (selectItem instanceof SelectItemGroup);
212
213 UISelectMany selectMany = (UISelectMany) uiComponent;
214
215 if (isSelectItemGroup)
216 {
217 if (pageDirectionLayout)
218 {
219 writer.startElement(HTML.TR_ELEM, selectMany);
220 }
221
222 writer.startElement(HTML.TD_ELEM, selectMany);
223 writer.write(selectItem.getLabel());
224 writer.endElement(HTML.TD_ELEM);
225
226 if (pageDirectionLayout)
227 {
228 writer.endElement(HTML.TR_ELEM);
229 writer.startElement(HTML.TR_ELEM, selectMany);
230 }
231 writer.startElement(HTML.TD_ELEM, selectMany);
232
233 writer.startElement(HTML.TABLE_ELEM, selectMany);
234 writer.writeAttribute(HTML.BORDER_ATTR, "0", null);
235
236 if(!pageDirectionLayout)
237 {
238 writer.startElement(HTML.TR_ELEM, selectMany);
239 }
240
241 SelectItemGroup group = (SelectItemGroup) selectItem;
242 SelectItem[] selectItems = group.getSelectItems();
243
244 for (SelectItem groupSelectItem : selectItems)
245 {
246 itemNum = renderGroupOrItemCheckbox(facesContext, selectMany, groupSelectItem, useSubmittedValues,
247 lookupSet, converter, pageDirectionLayout, itemNum);
248 }
249
250 if(!pageDirectionLayout)
251 {
252 writer.endElement(HTML.TR_ELEM);
253 }
254 writer.endElement(HTML.TABLE_ELEM);
255 writer.endElement(HTML.TD_ELEM);
256
257 if (pageDirectionLayout)
258 {
259 writer.endElement(HTML.TR_ELEM);
260 }
261
262 }
263 else
264 {
265 Object itemValue = selectItem.getValue();
266
267 String itemStrValue = org.apache.myfaces.shared.renderkit.RendererUtils.getConvertedStringValue(
268 facesContext, selectMany, converter, itemValue);
269
270 boolean checked = lookupSet.contains(itemStrValue);
271
272
273
274
275
276 if (HtmlRendererUtils.isHideNoSelectionOption(uiComponent) && selectItem.isNoSelectionOption()
277 && lookupSet.size() != 0 && !checked)
278 {
279
280 return itemNum;
281 }
282
283 writer.write("\t\t");
284 if (pageDirectionLayout)
285 {
286 writer.startElement(HTML.TR_ELEM, selectMany);
287 }
288 writer.startElement(HTML.TD_ELEM, selectMany);
289
290 boolean disabled = selectItem.isDisabled();
291
292 String itemId = renderCheckbox(facesContext, selectMany, itemStrValue, disabled, checked, false, itemNum);
293
294
295 boolean componentDisabled = isDisabled(facesContext, selectMany);
296 boolean itemDisabled = (componentDisabled || disabled);
297
298 HtmlRendererUtils.renderLabel(writer, selectMany, itemId, selectItem, itemDisabled, checked);
299
300 writer.endElement(HTML.TD_ELEM);
301 if (pageDirectionLayout)
302 {
303 writer.endElement(HTML.TR_ELEM);
304 }
305
306
307 itemNum++;
308 }
309
310 return itemNum;
311 }
312
313 @Deprecated
314 protected void renderCheckbox(FacesContext facesContext,
315 UIComponent uiComponent, String value, String label,
316 boolean disabled, boolean checked, boolean renderId) throws IOException
317 {
318 renderCheckbox(facesContext, uiComponent, value, disabled, checked, renderId, 0);
319 }
320
321
322
323
324
325 protected String renderCheckbox(FacesContext facesContext,
326 UIComponent uiComponent, String value, boolean disabled, boolean checked,
327 boolean renderId, Integer itemNum) throws IOException
328 {
329 String clientId = uiComponent.getClientId(facesContext);
330
331 String itemId = (itemNum == null)? null : clientId +
332 UINamingContainer.getSeparatorChar(facesContext) + itemNum;
333
334 ResponseWriter writer = facesContext.getResponseWriter();
335
336 writer.startElement(HTML.INPUT_ELEM, uiComponent);
337
338 if (itemId != null)
339 {
340 writer.writeAttribute(HTML.ID_ATTR, itemId, null);
341 }
342 else if (renderId)
343 {
344 writer.writeAttribute(HTML.ID_ATTR, clientId, null);
345 }
346 writer.writeAttribute(HTML.TYPE_ATTR, HTML.INPUT_TYPE_CHECKBOX, null);
347 writer.writeAttribute(HTML.NAME_ATTR, clientId, null);
348
349 if (checked)
350 {
351 writer.writeAttribute(HTML.CHECKED_ATTR,
352 org.apache.myfaces.shared.renderkit.html.HTML.CHECKED_ATTR, null);
353 }
354
355 if (disabled)
356 {
357 writer.writeAttribute(HTML.DISABLED_ATTR, HTML.DISABLED_ATTR, null);
358 }
359
360 if ((value != null) && (value.length() > 0))
361 {
362 writer.writeAttribute(HTML.VALUE_ATTR, value, null);
363 }
364
365 Map<String, List<ClientBehavior>> behaviors = null;
366 if (uiComponent instanceof UISelectBoolean)
367 {
368 if (uiComponent instanceof ClientBehaviorHolder && JavascriptUtils.isJavascriptAllowed(
369 facesContext.getExternalContext()))
370 {
371 behaviors = ((ClientBehaviorHolder) uiComponent).getClientBehaviors();
372
373 if (behaviors.isEmpty() && isCommonPropertiesOptimizationEnabled(facesContext))
374 {
375 long commonPropertiesMarked = CommonPropertyUtils.getCommonPropertiesMarked(uiComponent);
376 CommonPropertyUtils.renderChangeEventProperty(writer,
377 commonPropertiesMarked, uiComponent);
378 CommonPropertyUtils.renderEventProperties(writer,
379 commonPropertiesMarked, uiComponent);
380 CommonPropertyUtils.renderFieldEventPropertiesWithoutOnchange(writer,
381 commonPropertiesMarked, uiComponent);
382 }
383 else
384 {
385 long commonPropertiesMarked = CommonPropertyUtils.getCommonPropertiesMarked(uiComponent);
386 HtmlRendererUtils.renderBehaviorizedOnchangeEventHandler(
387 facesContext, writer, uiComponent, behaviors);
388 if (isCommonEventsOptimizationEnabled(facesContext))
389 {
390 Long commonEventsMarked = CommonEventUtils.getCommonEventsMarked(uiComponent);
391 CommonEventUtils.renderBehaviorizedEventHandlers(facesContext, writer,
392 commonPropertiesMarked, commonEventsMarked, uiComponent, behaviors);
393 CommonEventUtils.renderBehaviorizedFieldEventHandlersWithoutOnchange(
394 facesContext, writer, commonPropertiesMarked, commonEventsMarked, uiComponent, behaviors);
395 }
396 else
397 {
398 HtmlRendererUtils.renderBehaviorizedEventHandlers(facesContext,
399 writer, uiComponent, behaviors);
400 HtmlRendererUtils.renderBehaviorizedFieldEventHandlersWithoutOnchange(
401 facesContext, writer, uiComponent, behaviors);
402 }
403 }
404 HtmlRendererUtils.renderHTMLAttributes(writer, uiComponent,
405 HTML.INPUT_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED_AND_EVENTS);
406 }
407 else
408 {
409 HtmlRendererUtils.renderHTMLAttributes(writer, uiComponent,
410 HTML.INPUT_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED);
411 }
412 }
413 else
414 {
415 if (uiComponent instanceof ClientBehaviorHolder && JavascriptUtils.isJavascriptAllowed(
416 facesContext.getExternalContext()))
417 {
418 behaviors = ((ClientBehaviorHolder) uiComponent).getClientBehaviors();
419
420 if (behaviors.isEmpty() && isCommonPropertiesOptimizationEnabled(facesContext))
421 {
422 long commonPropertiesMarked = CommonPropertyUtils.getCommonPropertiesMarked(uiComponent);
423 CommonPropertyUtils.renderChangeEventProperty(writer,
424 commonPropertiesMarked, uiComponent);
425 CommonPropertyUtils.renderEventProperties(writer,
426 commonPropertiesMarked, uiComponent);
427 CommonPropertyUtils.renderFieldEventPropertiesWithoutOnchange(writer,
428 commonPropertiesMarked, uiComponent);
429 }
430 else
431 {
432 long commonPropertiesMarked = CommonPropertyUtils.getCommonPropertiesMarked(uiComponent);
433 HtmlRendererUtils.renderBehaviorizedOnchangeEventHandler(
434 facesContext, writer, uiComponent, behaviors);
435 if (isCommonEventsOptimizationEnabled(facesContext))
436 {
437 Long commonEventsMarked = CommonEventUtils.getCommonEventsMarked(uiComponent);
438 CommonEventUtils.renderBehaviorizedEventHandlers(facesContext, writer,
439 commonPropertiesMarked, commonEventsMarked, uiComponent, behaviors);
440 CommonEventUtils.renderBehaviorizedFieldEventHandlersWithoutOnchange(
441 facesContext, writer, commonPropertiesMarked, commonEventsMarked,
442 uiComponent, behaviors);
443 }
444 else
445 {
446 HtmlRendererUtils.renderBehaviorizedEventHandlers(facesContext, writer,
447 uiComponent, behaviors);
448 HtmlRendererUtils.renderBehaviorizedFieldEventHandlersWithoutOnchange(
449 facesContext, writer, uiComponent, behaviors);
450 }
451 }
452 HtmlRendererUtils.renderHTMLAttributes(writer, uiComponent,
453 HTML.INPUT_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED_AND_STYLE_AND_EVENTS);
454 }
455 else
456 {
457 HtmlRendererUtils.renderHTMLAttributes(writer, uiComponent,
458 HTML.INPUT_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED_AND_STYLE);
459 }
460 }
461 if (isDisabled(facesContext, uiComponent))
462 {
463 writer.writeAttribute(HTML.DISABLED_ATTR, Boolean.TRUE, null);
464 }
465
466 writer.endElement(HTML.INPUT_ELEM);
467
468 return itemId;
469 }
470
471 protected boolean isDisabled(FacesContext facesContext,
472 UIComponent component)
473 {
474
475
476 if (component instanceof HtmlSelectBooleanCheckbox)
477 {
478 return ((HtmlSelectBooleanCheckbox) component).isDisabled();
479 }
480 else if (component instanceof HtmlSelectManyCheckbox)
481 {
482 return ((HtmlSelectManyCheckbox) component).isDisabled();
483 }
484 else
485 {
486 return org.apache.myfaces.shared.renderkit.RendererUtils.getBooleanAttribute(component,
487 HTML.DISABLED_ATTR, false);
488 }
489 }
490
491 public void decode(FacesContext facesContext, UIComponent component)
492 {
493 org.apache.myfaces.shared.renderkit.RendererUtils.checkParamValidity(facesContext, component, null);
494 if (component instanceof UISelectBoolean)
495 {
496 HtmlRendererUtils.decodeUISelectBoolean(facesContext, component);
497 }
498 else if (component instanceof UISelectMany)
499 {
500 HtmlRendererUtils.decodeUISelectMany(facesContext, component);
501 }
502 else
503 {
504 throw new IllegalArgumentException("Unsupported component class "
505 + component.getClass().getName());
506 }
507 if (component instanceof ClientBehaviorHolder &&
508 !HtmlRendererUtils.isDisabled(component))
509 {
510 HtmlRendererUtils.decodeClientBehaviors(facesContext, component);
511 }
512 }
513
514 public Object getConvertedValue(FacesContext facesContext,
515 UIComponent component, Object submittedValue)
516 throws ConverterException
517 {
518 org.apache.myfaces.shared.renderkit.RendererUtils.checkParamValidity(facesContext, component, null);
519 if (component instanceof UISelectBoolean)
520 {
521 return submittedValue;
522 }
523 else if (component instanceof UISelectMany)
524 {
525 return org.apache.myfaces.shared.renderkit.RendererUtils.getConvertedUISelectManyValue(facesContext,
526 (UISelectMany) component, submittedValue);
527 }
528 else
529 {
530 throw new IllegalArgumentException("Unsupported component class "
531 + component.getClass().getName());
532 }
533 }
534
535
536
537
538
539
540
541 protected Converter getConverter(FacesContext facesContext,
542 UIComponent component)
543 {
544 if (component instanceof UISelectMany)
545 {
546 return HtmlRendererUtils.findUISelectManyConverterFailsafe(facesContext,
547 (UISelectMany) component);
548 }
549 else if (component instanceof UISelectOne)
550 {
551 return HtmlRendererUtils.findUIOutputConverterFailSafe(facesContext, component);
552 }
553 return null;
554 }
555
556 }