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