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 if (selectItem.isEscape())
224 {
225 writer.writeText(selectItem.getLabel(),HTML.LABEL_ATTR);
226 }
227 else
228 {
229 writer.write(selectItem.getLabel());
230 }
231 writer.endElement(HTML.TD_ELEM);
232
233 if (pageDirectionLayout)
234 {
235 writer.endElement(HTML.TR_ELEM);
236 writer.startElement(HTML.TR_ELEM, selectMany);
237 }
238 writer.startElement(HTML.TD_ELEM, selectMany);
239
240 writer.startElement(HTML.TABLE_ELEM, selectMany);
241 writer.writeAttribute(HTML.BORDER_ATTR, "0", null);
242
243 if(!pageDirectionLayout)
244 {
245 writer.startElement(HTML.TR_ELEM, selectMany);
246 }
247
248 SelectItemGroup group = (SelectItemGroup) selectItem;
249 SelectItem[] selectItems = group.getSelectItems();
250
251 for (SelectItem groupSelectItem : selectItems)
252 {
253 itemNum = renderGroupOrItemCheckbox(facesContext, selectMany, groupSelectItem, useSubmittedValues,
254 lookupSet, converter, pageDirectionLayout, itemNum);
255 }
256
257 if(!pageDirectionLayout)
258 {
259 writer.endElement(HTML.TR_ELEM);
260 }
261 writer.endElement(HTML.TABLE_ELEM);
262 writer.endElement(HTML.TD_ELEM);
263
264 if (pageDirectionLayout)
265 {
266 writer.endElement(HTML.TR_ELEM);
267 }
268
269 }
270 else
271 {
272 Object itemValue = selectItem.getValue();
273
274 String itemStrValue = org.apache.myfaces.shared.renderkit.RendererUtils.getConvertedStringValue(
275 facesContext, selectMany, converter, itemValue);
276
277 boolean checked = lookupSet.contains(itemStrValue);
278
279
280
281
282
283 if (HtmlRendererUtils.isHideNoSelectionOption(uiComponent) && selectItem.isNoSelectionOption()
284 && lookupSet.size() != 0 && !checked)
285 {
286
287 return itemNum;
288 }
289
290 writer.write("\t\t");
291 if (pageDirectionLayout)
292 {
293 writer.startElement(HTML.TR_ELEM, selectMany);
294 }
295 writer.startElement(HTML.TD_ELEM, selectMany);
296
297 boolean disabled = selectItem.isDisabled();
298
299 String itemId = renderCheckbox(facesContext, selectMany, itemStrValue, disabled, checked, false, itemNum);
300
301
302 boolean componentDisabled = isDisabled(facesContext, selectMany);
303 boolean itemDisabled = (componentDisabled || disabled);
304
305 HtmlRendererUtils.renderLabel(writer, selectMany, itemId, selectItem, itemDisabled, checked);
306
307 writer.endElement(HTML.TD_ELEM);
308 if (pageDirectionLayout)
309 {
310 writer.endElement(HTML.TR_ELEM);
311 }
312
313
314 itemNum++;
315 }
316
317 return itemNum;
318 }
319
320 @Deprecated
321 protected void renderCheckbox(FacesContext facesContext,
322 UIComponent uiComponent, String value, String label,
323 boolean disabled, boolean checked, boolean renderId) throws IOException
324 {
325 renderCheckbox(facesContext, uiComponent, value, disabled, checked, renderId, 0);
326 }
327
328
329
330
331
332 protected String renderCheckbox(FacesContext facesContext,
333 UIComponent uiComponent, String value, boolean disabled, boolean checked,
334 boolean renderId, Integer itemNum) throws IOException
335 {
336 String clientId = uiComponent.getClientId(facesContext);
337
338 String itemId = (itemNum == null)? null : clientId +
339 UINamingContainer.getSeparatorChar(facesContext) + itemNum;
340
341 ResponseWriter writer = facesContext.getResponseWriter();
342
343 writer.startElement(HTML.INPUT_ELEM, uiComponent);
344
345 if (itemId != null)
346 {
347 writer.writeAttribute(HTML.ID_ATTR, itemId, null);
348 }
349 else if (renderId)
350 {
351 writer.writeAttribute(HTML.ID_ATTR, clientId, null);
352 }
353 writer.writeAttribute(HTML.TYPE_ATTR, HTML.INPUT_TYPE_CHECKBOX, null);
354 writer.writeAttribute(HTML.NAME_ATTR, clientId, null);
355
356 if (checked)
357 {
358 writer.writeAttribute(HTML.CHECKED_ATTR,
359 org.apache.myfaces.shared.renderkit.html.HTML.CHECKED_ATTR, null);
360 }
361
362 if (disabled)
363 {
364 writer.writeAttribute(HTML.DISABLED_ATTR, HTML.DISABLED_ATTR, null);
365 }
366
367 if ((value != null) && (value.length() > 0))
368 {
369 writer.writeAttribute(HTML.VALUE_ATTR, value, null);
370 }
371
372 Map<String, List<ClientBehavior>> behaviors = null;
373 if (uiComponent instanceof UISelectBoolean)
374 {
375 if (uiComponent instanceof ClientBehaviorHolder && JavascriptUtils.isJavascriptAllowed(
376 facesContext.getExternalContext()))
377 {
378 behaviors = ((ClientBehaviorHolder) uiComponent).getClientBehaviors();
379
380 if (behaviors.isEmpty() && isCommonPropertiesOptimizationEnabled(facesContext))
381 {
382 long commonPropertiesMarked = CommonPropertyUtils.getCommonPropertiesMarked(uiComponent);
383 CommonPropertyUtils.renderChangeEventProperty(writer,
384 commonPropertiesMarked, uiComponent);
385 CommonPropertyUtils.renderEventProperties(writer,
386 commonPropertiesMarked, uiComponent);
387 CommonPropertyUtils.renderFieldEventPropertiesWithoutOnchange(writer,
388 commonPropertiesMarked, uiComponent);
389 }
390 else
391 {
392 long commonPropertiesMarked = CommonPropertyUtils.getCommonPropertiesMarked(uiComponent);
393 HtmlRendererUtils.renderBehaviorizedOnchangeEventHandler(
394 facesContext, writer, uiComponent, behaviors);
395 if (isCommonEventsOptimizationEnabled(facesContext))
396 {
397 Long commonEventsMarked = CommonEventUtils.getCommonEventsMarked(uiComponent);
398 CommonEventUtils.renderBehaviorizedEventHandlers(facesContext, writer,
399 commonPropertiesMarked, commonEventsMarked, uiComponent, behaviors);
400 CommonEventUtils.renderBehaviorizedFieldEventHandlersWithoutOnchange(
401 facesContext, writer, commonPropertiesMarked, commonEventsMarked, uiComponent, behaviors);
402 }
403 else
404 {
405 HtmlRendererUtils.renderBehaviorizedEventHandlers(facesContext,
406 writer, uiComponent, behaviors);
407 HtmlRendererUtils.renderBehaviorizedFieldEventHandlersWithoutOnchange(
408 facesContext, writer, uiComponent, behaviors);
409 }
410 }
411 HtmlRendererUtils.renderHTMLAttributes(writer, uiComponent,
412 HTML.INPUT_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED_AND_EVENTS);
413 }
414 else
415 {
416 HtmlRendererUtils.renderHTMLAttributes(writer, uiComponent,
417 HTML.INPUT_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED);
418 }
419 }
420 else
421 {
422 if (uiComponent instanceof ClientBehaviorHolder && JavascriptUtils.isJavascriptAllowed(
423 facesContext.getExternalContext()))
424 {
425 behaviors = ((ClientBehaviorHolder) uiComponent).getClientBehaviors();
426
427 if (behaviors.isEmpty() && isCommonPropertiesOptimizationEnabled(facesContext))
428 {
429 long commonPropertiesMarked = CommonPropertyUtils.getCommonPropertiesMarked(uiComponent);
430 CommonPropertyUtils.renderChangeEventProperty(writer,
431 commonPropertiesMarked, uiComponent);
432 CommonPropertyUtils.renderEventProperties(writer,
433 commonPropertiesMarked, uiComponent);
434 CommonPropertyUtils.renderFieldEventPropertiesWithoutOnchange(writer,
435 commonPropertiesMarked, uiComponent);
436 }
437 else
438 {
439 long commonPropertiesMarked = CommonPropertyUtils.getCommonPropertiesMarked(uiComponent);
440 HtmlRendererUtils.renderBehaviorizedOnchangeEventHandler(
441 facesContext, writer, uiComponent, behaviors);
442 if (isCommonEventsOptimizationEnabled(facesContext))
443 {
444 Long commonEventsMarked = CommonEventUtils.getCommonEventsMarked(uiComponent);
445 CommonEventUtils.renderBehaviorizedEventHandlers(facesContext, writer,
446 commonPropertiesMarked, commonEventsMarked, uiComponent, behaviors);
447 CommonEventUtils.renderBehaviorizedFieldEventHandlersWithoutOnchange(
448 facesContext, writer, commonPropertiesMarked, commonEventsMarked,
449 uiComponent, behaviors);
450 }
451 else
452 {
453 HtmlRendererUtils.renderBehaviorizedEventHandlers(facesContext, writer,
454 uiComponent, behaviors);
455 HtmlRendererUtils.renderBehaviorizedFieldEventHandlersWithoutOnchange(
456 facesContext, writer, uiComponent, behaviors);
457 }
458 }
459 HtmlRendererUtils.renderHTMLAttributes(writer, uiComponent,
460 HTML.INPUT_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED_AND_STYLE_AND_EVENTS);
461 }
462 else
463 {
464 HtmlRendererUtils.renderHTMLAttributes(writer, uiComponent,
465 HTML.INPUT_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED_AND_STYLE);
466 }
467 }
468 if (isDisabled(facesContext, uiComponent))
469 {
470 writer.writeAttribute(HTML.DISABLED_ATTR, Boolean.TRUE, null);
471 }
472
473 writer.endElement(HTML.INPUT_ELEM);
474
475 return itemId;
476 }
477
478 protected boolean isDisabled(FacesContext facesContext,
479 UIComponent component)
480 {
481
482
483 if (component instanceof HtmlSelectBooleanCheckbox)
484 {
485 return ((HtmlSelectBooleanCheckbox) component).isDisabled();
486 }
487 else if (component instanceof HtmlSelectManyCheckbox)
488 {
489 return ((HtmlSelectManyCheckbox) component).isDisabled();
490 }
491 else
492 {
493 return org.apache.myfaces.shared.renderkit.RendererUtils.getBooleanAttribute(component,
494 HTML.DISABLED_ATTR, false);
495 }
496 }
497
498 public void decode(FacesContext facesContext, UIComponent component)
499 {
500 org.apache.myfaces.shared.renderkit.RendererUtils.checkParamValidity(facesContext, component, null);
501 if (component instanceof UISelectBoolean)
502 {
503 HtmlRendererUtils.decodeUISelectBoolean(facesContext, component);
504 }
505 else if (component instanceof UISelectMany)
506 {
507 HtmlRendererUtils.decodeUISelectMany(facesContext, component);
508 }
509 else
510 {
511 throw new IllegalArgumentException("Unsupported component class "
512 + component.getClass().getName());
513 }
514 if (component instanceof ClientBehaviorHolder &&
515 !HtmlRendererUtils.isDisabled(component))
516 {
517 HtmlRendererUtils.decodeClientBehaviors(facesContext, component);
518 }
519 }
520
521 public Object getConvertedValue(FacesContext facesContext,
522 UIComponent component, Object submittedValue)
523 throws ConverterException
524 {
525 org.apache.myfaces.shared.renderkit.RendererUtils.checkParamValidity(facesContext, component, null);
526 if (component instanceof UISelectBoolean)
527 {
528 return submittedValue;
529 }
530 else if (component instanceof UISelectMany)
531 {
532 return org.apache.myfaces.shared.renderkit.RendererUtils.getConvertedUISelectManyValue(facesContext,
533 (UISelectMany) component, submittedValue);
534 }
535 else
536 {
537 throw new IllegalArgumentException("Unsupported component class "
538 + component.getClass().getName());
539 }
540 }
541
542
543
544
545
546
547
548 protected Converter getConverter(FacesContext facesContext,
549 UIComponent component)
550 {
551 if (component instanceof UISelectMany)
552 {
553 return HtmlRendererUtils.findUISelectManyConverterFailsafe(facesContext,
554 (UISelectMany) component);
555 }
556 else if (component instanceof UISelectOne)
557 {
558 return HtmlRendererUtils.findUIOutputConverterFailSafe(facesContext, component);
559 }
560 return null;
561 }
562
563 }