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.UISelectBoolean;
30 import javax.faces.component.UISelectMany;
31 import javax.faces.component.UISelectOne;
32 import javax.faces.component.behavior.ClientBehavior;
33 import javax.faces.component.behavior.ClientBehaviorHolder;
34 import javax.faces.component.html.HtmlSelectBooleanCheckbox;
35 import javax.faces.component.html.HtmlSelectManyCheckbox;
36 import javax.faces.context.FacesContext;
37 import javax.faces.context.ResponseWriter;
38 import javax.faces.convert.Converter;
39 import javax.faces.convert.ConverterException;
40 import javax.faces.model.SelectItem;
41 import javax.faces.model.SelectItemGroup;
42
43 import org.apache.myfaces.shared.renderkit.JSFAttr;
44 import org.apache.myfaces.shared.renderkit.html.util.ResourceUtils;
45
46 public class HtmlCheckboxRendererBase extends HtmlRenderer
47 {
48
49
50 private static final Logger log = Logger.getLogger(HtmlCheckboxRendererBase.class.getName());
51
52 private static final String PAGE_DIRECTION = "pageDirection";
53
54 private static final String LINE_DIRECTION = "lineDirection";
55
56 private static final String EXTERNAL_TRUE_VALUE = "true";
57
58 public void encodeEnd(FacesContext facesContext, UIComponent uiComponent)
59 throws IOException
60 {
61 org.apache.myfaces.shared.renderkit.RendererUtils.checkParamValidity(facesContext, uiComponent, null);
62
63 Map<String, List<ClientBehavior>> behaviors = null;
64 if (uiComponent instanceof ClientBehaviorHolder)
65 {
66 behaviors = ((ClientBehaviorHolder) uiComponent).getClientBehaviors();
67 if (!behaviors.isEmpty())
68 {
69 ResourceUtils.renderDefaultJsfJsInlineIfNecessary(facesContext, facesContext.getResponseWriter());
70 }
71 }
72
73 if (uiComponent instanceof UISelectBoolean)
74 {
75 Boolean value = org.apache.myfaces.shared.renderkit.RendererUtils.getBooleanValue( uiComponent );
76 boolean isChecked = value != null ? value.booleanValue() : false;
77 renderCheckbox(facesContext, uiComponent, EXTERNAL_TRUE_VALUE, false,isChecked, true, null);
78
79 }
80 else if (uiComponent instanceof UISelectMany)
81 {
82 renderCheckboxList(facesContext, (UISelectMany) uiComponent);
83 }
84 else
85 {
86 throw new IllegalArgumentException("Unsupported component class "
87 + uiComponent.getClass().getName());
88 }
89 }
90
91 public void renderCheckboxList(FacesContext facesContext,
92 UISelectMany selectMany) throws IOException
93 {
94
95 String layout = getLayout(selectMany);
96 boolean pageDirectionLayout = false;
97 if (layout != null)
98 {
99 if (layout.equals(PAGE_DIRECTION))
100 {
101 pageDirectionLayout = true;
102 }
103 else if (layout.equals(LINE_DIRECTION))
104 {
105 pageDirectionLayout = false;
106 }
107 else
108 {
109 log.severe("Wrong layout attribute for component "
110 + selectMany.getClientId(facesContext) + ": " + layout);
111 }
112 }
113
114 ResponseWriter writer = facesContext.getResponseWriter();
115
116 writer.startElement(HTML.TABLE_ELEM, selectMany);
117 HtmlRendererUtils.renderHTMLAttributes(writer, selectMany,
118 HTML.SELECT_TABLE_PASSTHROUGH_ATTRIBUTES);
119
120 Map<String, List<ClientBehavior>> behaviors = null;
121 if (selectMany instanceof ClientBehaviorHolder)
122 {
123 behaviors = ((ClientBehaviorHolder) selectMany).getClientBehaviors();
124 }
125
126 if (behaviors != null && !behaviors.isEmpty())
127 {
128 writer.writeAttribute(HTML.ID_ATTR, selectMany.getClientId(facesContext), null);
129 }
130 else
131 {
132 HtmlRendererUtils.writeIdIfNecessary(writer, selectMany, facesContext);
133 }
134
135 if (!pageDirectionLayout)
136 {
137 writer.startElement(HTML.TR_ELEM, null);
138 }
139
140 Converter converter = getConverter(facesContext, selectMany);
141
142 Set lookupSet = org.apache.myfaces.shared.renderkit.RendererUtils.getSubmittedValuesAsSet(
143 facesContext, selectMany, converter, selectMany);
144 boolean useSubmittedValues = lookupSet != null;
145
146 if (!useSubmittedValues)
147 {
148 lookupSet = org.apache.myfaces.shared.renderkit.RendererUtils.getSelectedValuesAsSet(
149 facesContext, selectMany, converter, selectMany);
150 }
151
152 int itemNum = 0;
153
154 for (Iterator it = org.apache.myfaces.shared.renderkit.RendererUtils.getSelectItemList(
155 selectMany, facesContext)
156 .iterator(); it.hasNext();)
157 {
158 SelectItem selectItem = (SelectItem) it.next();
159
160 itemNum = renderGroupOrItemCheckbox(facesContext, selectMany,
161 selectItem, useSubmittedValues, lookupSet,
162 converter, pageDirectionLayout, itemNum);
163 }
164
165 if (!pageDirectionLayout)
166 {
167 writer.endElement(HTML.TR_ELEM);
168 }
169 writer.endElement(HTML.TABLE_ELEM);
170 }
171
172 protected String getLayout(UISelectMany selectMany)
173 {
174 if (selectMany instanceof HtmlSelectManyCheckbox)
175 {
176 return ((HtmlSelectManyCheckbox) selectMany).getLayout();
177 }
178
179 return (String) selectMany.getAttributes().get(JSFAttr.LAYOUT_ATTR);
180 }
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195 protected int renderGroupOrItemCheckbox(FacesContext facesContext,
196 UIComponent uiComponent, SelectItem selectItem,
197 boolean useSubmittedValues, Set lookupSet,
198 Converter converter, boolean pageDirectionLayout,
199 Integer itemNum) throws IOException
200 {
201
202 ResponseWriter writer = facesContext.getResponseWriter();
203
204 boolean isSelectItemGroup = (selectItem instanceof SelectItemGroup);
205
206 UISelectMany selectMany = (UISelectMany) uiComponent;
207
208 if (isSelectItemGroup)
209 {
210 if (pageDirectionLayout)
211 {
212 writer.startElement(HTML.TR_ELEM, null);
213 }
214
215 writer.startElement(HTML.TD_ELEM, null);
216 if (selectItem.isEscape())
217 {
218 writer.writeText(selectItem.getLabel(),HTML.LABEL_ATTR);
219 }
220 else
221 {
222 writer.write(selectItem.getLabel());
223 }
224 writer.endElement(HTML.TD_ELEM);
225
226 if (pageDirectionLayout)
227 {
228 writer.endElement(HTML.TR_ELEM);
229 writer.startElement(HTML.TR_ELEM, null);
230 }
231 writer.startElement(HTML.TD_ELEM, null);
232
233 writer.startElement(HTML.TABLE_ELEM, null);
234 writer.writeAttribute(HTML.BORDER_ATTR, "0", null);
235
236 if(!pageDirectionLayout)
237 {
238 writer.startElement(HTML.TR_ELEM, null);
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, null);
287 }
288 writer.startElement(HTML.TD_ELEM, null);
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 facesContext.getNamingContainerSeparatorChar() + 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)
369 {
370 behaviors = ((ClientBehaviorHolder) uiComponent).getClientBehaviors();
371
372 if (behaviors.isEmpty() && isCommonPropertiesOptimizationEnabled(facesContext))
373 {
374 long commonPropertiesMarked = CommonPropertyUtils.getCommonPropertiesMarked(uiComponent);
375 CommonPropertyUtils.renderChangeEventProperty(writer,
376 commonPropertiesMarked, uiComponent);
377 CommonPropertyUtils.renderEventProperties(writer,
378 commonPropertiesMarked, uiComponent);
379 CommonPropertyUtils.renderFieldEventPropertiesWithoutOnchange(writer,
380 commonPropertiesMarked, uiComponent);
381 }
382 else
383 {
384 long commonPropertiesMarked = CommonPropertyUtils.getCommonPropertiesMarked(uiComponent);
385 HtmlRendererUtils.renderBehaviorizedOnchangeEventHandler(
386 facesContext, writer, uiComponent, itemId != null ? itemId : clientId, behaviors);
387 if (isCommonEventsOptimizationEnabled(facesContext))
388 {
389 Long commonEventsMarked = CommonEventUtils.getCommonEventsMarked(uiComponent);
390 CommonEventUtils.renderBehaviorizedEventHandlers(facesContext, writer,
391 commonPropertiesMarked, commonEventsMarked, uiComponent,
392 itemId != null ? itemId : clientId, behaviors);
393 CommonEventUtils.renderBehaviorizedFieldEventHandlersWithoutOnchange(
394 facesContext, writer, commonPropertiesMarked, commonEventsMarked, uiComponent,
395 itemId != null ? itemId : clientId, behaviors);
396 }
397 else
398 {
399 HtmlRendererUtils.renderBehaviorizedEventHandlers(facesContext,
400 writer, uiComponent, behaviors);
401 HtmlRendererUtils.renderBehaviorizedFieldEventHandlersWithoutOnchange(
402 facesContext, writer, uiComponent,
403 itemId != null ? itemId : clientId, behaviors);
404 }
405 }
406 HtmlRendererUtils.renderHTMLAttributes(writer, uiComponent,
407 HTML.INPUT_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED_AND_EVENTS);
408 }
409 else
410 {
411 HtmlRendererUtils.renderHTMLAttributes(writer, uiComponent,
412 HTML.INPUT_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED);
413 }
414 }
415 else
416 {
417 if (uiComponent instanceof ClientBehaviorHolder)
418 {
419 behaviors = ((ClientBehaviorHolder) uiComponent).getClientBehaviors();
420
421 if (behaviors.isEmpty() && isCommonPropertiesOptimizationEnabled(facesContext))
422 {
423 long commonPropertiesMarked = CommonPropertyUtils.getCommonPropertiesMarked(uiComponent);
424 CommonPropertyUtils.renderChangeEventProperty(writer,
425 commonPropertiesMarked, uiComponent);
426 CommonPropertyUtils.renderEventProperties(writer,
427 commonPropertiesMarked, uiComponent);
428 CommonPropertyUtils.renderFieldEventPropertiesWithoutOnchange(writer,
429 commonPropertiesMarked, uiComponent);
430 }
431 else
432 {
433 long commonPropertiesMarked = CommonPropertyUtils.getCommonPropertiesMarked(uiComponent);
434 HtmlRendererUtils.renderBehaviorizedOnchangeEventHandler(
435 facesContext, writer, uiComponent, itemId != null ? itemId : clientId, behaviors);
436 if (isCommonEventsOptimizationEnabled(facesContext))
437 {
438 Long commonEventsMarked = CommonEventUtils.getCommonEventsMarked(uiComponent);
439 CommonEventUtils.renderBehaviorizedEventHandlers(facesContext, writer,
440 commonPropertiesMarked, commonEventsMarked, uiComponent,
441 itemId != null ? itemId : clientId, behaviors);
442 CommonEventUtils.renderBehaviorizedFieldEventHandlersWithoutOnchange(
443 facesContext, writer, commonPropertiesMarked, commonEventsMarked,
444 uiComponent, itemId != null ? itemId : clientId, behaviors);
445 }
446 else
447 {
448 HtmlRendererUtils.renderBehaviorizedEventHandlers(facesContext, writer,
449 uiComponent, itemId != null ? itemId : clientId, behaviors);
450 HtmlRendererUtils.renderBehaviorizedFieldEventHandlersWithoutOnchange(
451 facesContext, writer, uiComponent, itemId != null ? itemId : clientId, behaviors);
452 }
453 }
454 HtmlRendererUtils.renderHTMLAttributes(writer, uiComponent,
455 HTML.INPUT_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED_AND_STYLE_AND_EVENTS);
456 }
457 else
458 {
459 HtmlRendererUtils.renderHTMLAttributes(writer, uiComponent,
460 HTML.INPUT_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED_AND_STYLE);
461 }
462 }
463 if (isDisabled(facesContext, uiComponent))
464 {
465 writer.writeAttribute(HTML.DISABLED_ATTR, Boolean.TRUE, null);
466 }
467
468 writer.endElement(HTML.INPUT_ELEM);
469
470 return itemId;
471 }
472
473 protected boolean isDisabled(FacesContext facesContext,
474 UIComponent component)
475 {
476
477
478 if (component instanceof HtmlSelectBooleanCheckbox)
479 {
480 return ((HtmlSelectBooleanCheckbox) component).isDisabled();
481 }
482 else if (component instanceof HtmlSelectManyCheckbox)
483 {
484 return ((HtmlSelectManyCheckbox) component).isDisabled();
485 }
486 else
487 {
488 return org.apache.myfaces.shared.renderkit.RendererUtils.getBooleanAttribute(component,
489 HTML.DISABLED_ATTR, false);
490 }
491 }
492
493 public void decode(FacesContext facesContext, UIComponent component)
494 {
495 org.apache.myfaces.shared.renderkit.RendererUtils.checkParamValidity(facesContext, component, null);
496 if (component instanceof UISelectBoolean)
497 {
498 HtmlRendererUtils.decodeUISelectBoolean(facesContext, component);
499 }
500 else if (component instanceof UISelectMany)
501 {
502 HtmlRendererUtils.decodeUISelectMany(facesContext, component);
503 }
504 else
505 {
506 throw new IllegalArgumentException("Unsupported component class "
507 + component.getClass().getName());
508 }
509 if (component instanceof ClientBehaviorHolder &&
510 !HtmlRendererUtils.isDisabled(component))
511 {
512 HtmlRendererUtils.decodeClientBehaviors(facesContext, component);
513 }
514 }
515
516 public Object getConvertedValue(FacesContext facesContext,
517 UIComponent component, Object submittedValue)
518 throws ConverterException
519 {
520 org.apache.myfaces.shared.renderkit.RendererUtils.checkParamValidity(facesContext, component, null);
521 if (component instanceof UISelectBoolean)
522 {
523 return submittedValue;
524 }
525 else if (component instanceof UISelectMany)
526 {
527 return org.apache.myfaces.shared.renderkit.RendererUtils.getConvertedUISelectManyValue(facesContext,
528 (UISelectMany) component, submittedValue);
529 }
530 else
531 {
532 throw new IllegalArgumentException("Unsupported component class "
533 + component.getClass().getName());
534 }
535 }
536
537
538
539
540
541
542
543 protected Converter getConverter(FacesContext facesContext,
544 UIComponent component)
545 {
546 if (component instanceof UISelectMany)
547 {
548 return HtmlRendererUtils.findUISelectManyConverterFailsafe(facesContext,
549 (UISelectMany) component);
550 }
551 else if (component instanceof UISelectOne)
552 {
553 return HtmlRendererUtils.findUIOutputConverterFailSafe(facesContext, component);
554 }
555 return null;
556 }
557
558 }