View Javadoc

    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one
    3    * or more contributor license agreements.  See the NOTICE file
    4    * distributed with this work for additional information
    5    * regarding copyright ownership.  The ASF licenses this file
    6    * to you under the Apache License, Version 2.0 (the
    7    * "License"); you may not use this file except in compliance
    8    * with the License.  You may obtain a copy of the License at
    9    *
    10   *   http://www.apache.org/licenses/LICENSE-2.0
    11   *
    12   * Unless required by applicable law or agreed to in writing,
    13   * software distributed under the License is distributed on an
    14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    15   * KIND, either express or implied.  See the License for the
    16   * specific language governing permissions and limitations
    17   * under the License.
    18   */
    19  package org.apache.myfaces.shared_orchestra.renderkit.html;
    20
    21  import org.apache.commons.logging.Log;
    22  import org.apache.commons.logging.LogFactory;
    23  import org.apache.myfaces.shared_orchestra.config.MyfacesConfig;
    24  import org.apache.myfaces.shared_orchestra.renderkit.JSFAttr;
    25  import org.apache.myfaces.shared_orchestra.renderkit.RendererUtils;
    26
    27  import javax.faces.FacesException;
    28  import javax.faces.component.UIComponent;
    29  import javax.faces.component.UISelectBoolean;
    30  import javax.faces.component.UISelectMany;
    31  import javax.faces.component.html.HtmlSelectBooleanCheckbox;
    32  import javax.faces.component.html.HtmlSelectManyCheckbox;
    33  import javax.faces.context.FacesContext;
    34  import javax.faces.context.ResponseWriter;
    35  import javax.faces.convert.Converter;
    36  import javax.faces.convert.ConverterException;
    37  import javax.faces.model.SelectItem;
    38  import javax.faces.model.SelectItemGroup;
    39  import java.io.IOException;
    40  import java.util.Iterator;
    41  import java.util.Set;
    42
    43  /**
    44   * @author Thomas Spiegl (latest modification by $Author: skitching $)
    45   * @author Anton Koinov
    46   * @version $Revision: 673826 $ $Date: 2008-07-03 16:43:52 -0500 (Thu, 03 Jul 2008) $
    47   */
    48  public class HtmlCheckboxRendererBase extends HtmlRenderer {
    49      private static final Log log = LogFactory
    50              .getLog(HtmlCheckboxRendererBase.class);
    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          org.apache.myfaces.shared_orchestra.renderkit.RendererUtils.checkParamValidity(facesContext, uiComponent, null);
    61          if (uiComponent instanceof UISelectBoolean) {
    62              Boolean value = org.apache.myfaces.shared_orchestra.renderkit.RendererUtils.getBooleanValue( uiComponent );
    63              boolean isChecked = value != null ? value.booleanValue() : false;
    64              renderCheckbox(facesContext, uiComponent, EXTERNAL_TRUE_VALUE,
    65                      null, false,isChecked, true);
    66          } else if (uiComponent instanceof UISelectMany) {
    67              renderCheckboxList(facesContext, (UISelectMany) uiComponent);
    68          } else {
    69              throw new IllegalArgumentException("Unsupported component class "
    70                      + uiComponent.getClass().getName());
    71          }
    72      }
    73
    74      public void renderCheckboxList(FacesContext facesContext,
    75              UISelectMany selectMany) throws IOException {
    76
    77          String layout = getLayout(selectMany);
    78          boolean pageDirectionLayout = false; //Default to lineDirection
    79          if (layout != null) {
    80              if (layout.equals(PAGE_DIRECTION)) {
    81                  pageDirectionLayout = true;
    82              } else if (layout.equals(LINE_DIRECTION)) {
    83                  pageDirectionLayout = false;
    84              } else {
    85                  log.error("Wrong layout attribute for component "
    86                          + selectMany.getClientId(facesContext) + ": " + layout);
    87              }
    88          }
    89
    90          ResponseWriter writer = facesContext.getResponseWriter();
    91
    92          writer.startElement(HTML.TABLE_ELEM, selectMany);
    93          HtmlRendererUtils.renderHTMLAttributes(writer, selectMany,
    94                  HTML.SELECT_TABLE_PASSTHROUGH_ATTRIBUTES);
    95          HtmlRendererUtils.writeIdIfNecessary(writer, selectMany, facesContext);
    96
    97          if (!pageDirectionLayout)
    98              writer.startElement(HTML.TR_ELEM, selectMany);
    99
    100         Converter converter;
    101         try {
    102             converter = org.apache.myfaces.shared_orchestra.renderkit.RendererUtils.findUISelectManyConverter(facesContext,
    103                     selectMany);
    104         } catch (FacesException e) {
    105             log.error("Error finding Converter for component with id "
    106                     + selectMany.getClientId(facesContext));
    107             converter = null;
    108         }
    109
    110         Set lookupSet = org.apache.myfaces.shared_orchestra.renderkit.RendererUtils.getSubmittedValuesAsSet(facesContext, selectMany, converter, selectMany);
    111         boolean useSubmittedValues = lookupSet != null;
    112
    113         if (!useSubmittedValues) {
    114             lookupSet = org.apache.myfaces.shared_orchestra.renderkit.RendererUtils.getSelectedValuesAsSet(facesContext, selectMany, converter, selectMany);
    115         }
    116
    117         for (Iterator it = org.apache.myfaces.shared_orchestra.renderkit.RendererUtils.getSelectItemList(selectMany)
    118                 .iterator(); it.hasNext();) {
    119             SelectItem selectItem = (SelectItem) it.next();
    120
    121             renderGroupOrItemCheckbox(facesContext, selectMany,
    122                     selectItem, useSubmittedValues, lookupSet,
    123                     converter, pageDirectionLayout);
    124         }
    125
    126         if (!pageDirectionLayout)
    127             writer.endElement(HTML.TR_ELEM);
    128         writer.endElement(HTML.TABLE_ELEM);
    129     }
    130
    131     protected String getLayout(UISelectMany selectMany) {
    132         if (selectMany instanceof HtmlSelectManyCheckbox) {
    133             return ((HtmlSelectManyCheckbox) selectMany).getLayout();
    134         } else {
    135             return (String) selectMany.getAttributes().get(JSFAttr.LAYOUT_ATTR);
    136         }
    137     }
    138
    139     protected void renderGroupOrItemCheckbox(FacesContext facesContext,
    140             UIComponent uiComponent, SelectItem selectItem,
    141             boolean useSubmittedValues, Set lookupSet,
    142             Converter converter, boolean pageDirectionLayout) throws IOException{
    143
    144         ResponseWriter writer = facesContext.getResponseWriter();
    145
    146         boolean isSelectItemGroup = (selectItem instanceof SelectItemGroup);
    147
    148         Object itemValue = selectItem.getValue(); // TODO : Check here for getSubmittedValue. Look at RendererUtils.getValue
    149
    150         UISelectMany selectMany = (UISelectMany)uiComponent;
    151
    152         String itemStrValue;
    153         if (converter == null) {
    154             itemStrValue = itemValue.toString();
    155         } else {
    156             itemStrValue = converter.getAsString(facesContext, selectMany,
    157                     itemValue);
    158         }
    159
    160         if (isSelectItemGroup) {
    161             if (pageDirectionLayout)
    162                 writer.startElement(HTML.TR_ELEM, selectMany);
    163
    164             writer.startElement(HTML.TD_ELEM, selectMany);
    165             writer.write(selectItem.getLabel());
    166             writer.endElement(HTML.TD_ELEM);
    167
    168             if (pageDirectionLayout) {
    169                 writer.endElement(HTML.TR_ELEM);
    170                 writer.startElement(HTML.TR_ELEM, selectMany);
    171             }
    172             writer.startElement(HTML.TD_ELEM, selectMany);
    173
    174             writer.startElement(HTML.TABLE_ELEM, selectMany);
    175             writer.writeAttribute(HTML.BORDER_ATTR, "0", null);
    176
    177             SelectItemGroup group = (SelectItemGroup) selectItem;
    178             SelectItem[] selectItems = group.getSelectItems();
    179
    180             for (int i=0; i<selectItems.length; i++) {
    181                 renderGroupOrItemCheckbox(facesContext, selectMany, selectItems[i], useSubmittedValues, lookupSet, converter, pageDirectionLayout);
    182             }
    183
    184             writer.endElement(HTML.TD_ELEM);
    185             writer.endElement(HTML.TR_ELEM);
    186             writer.endElement(HTML.TABLE_ELEM);
    187             writer.endElement(HTML.TD_ELEM);
    188
    189             if (pageDirectionLayout)
    190                 writer.endElement(HTML.TR_ELEM);
    191
    192         } else {
    193
    194         writer.write("\t\t");
    195         if (pageDirectionLayout)
    196             writer.startElement(HTML.TR_ELEM, selectMany);
    197         writer.startElement(HTML.TD_ELEM, selectMany);
    198         writer.startElement(HTML.LABEL_ELEM, selectMany);
    199
    200         boolean checked = lookupSet.contains(itemStrValue);
    201
    202         boolean disabled = selectItem.isDisabled();
    203
    204
    205         String labelClass = null;
    206         boolean componentDisabled = isDisabled(facesContext, selectMany);
    207
    208         if (componentDisabled || disabled) {
    209             labelClass = (String) selectMany.getAttributes().get(JSFAttr.DISABLED_CLASS_ATTR);
    210         } else {
    211             labelClass = (String) selectMany.getAttributes().get(org.apache.myfaces.shared_orchestra.renderkit.JSFAttr.ENABLED_CLASS_ATTR);
    212         }
    213         if (labelClass != null) {
    214             writer.writeAttribute("class", labelClass, "labelClass");
    215         }
    216
    217             renderCheckbox(facesContext, selectMany, itemStrValue, selectItem
    218                 .getLabel(), disabled, checked, false);
    219
    220         writer.endElement(HTML.LABEL_ELEM);
    221         writer.endElement(HTML.TD_ELEM);
    222         if (pageDirectionLayout)
    223             writer.endElement(HTML.TR_ELEM);
    224         }
    225     }
    226
    227     protected void renderCheckbox(FacesContext facesContext,
    228             UIComponent uiComponent, String value, String label,
    229             boolean disabled, boolean checked, boolean renderId) throws IOException {
    230         String clientId = uiComponent.getClientId(facesContext);
    231
    232         ResponseWriter writer = facesContext.getResponseWriter();
    233
    234         writer.startElement(HTML.INPUT_ELEM, uiComponent);
    235         writer.writeAttribute(HTML.TYPE_ATTR, HTML.INPUT_TYPE_CHECKBOX, null);
    236         writer.writeAttribute(HTML.NAME_ATTR, clientId, null);
    237
    238         if (renderId) {
    239             HtmlRendererUtils.writeIdIfNecessary(writer, uiComponent, facesContext);
    240         }
    241
    242         if (checked) {
    243             writer.writeAttribute(HTML.CHECKED_ATTR, org.apache.myfaces.shared_orchestra.renderkit.html.HTML.CHECKED_ATTR, null);
    244         }
    245
    246         if ((value != null) && (value.length() > 0)) {
    247             writer.writeAttribute(HTML.VALUE_ATTR, value, null);
    248         }
    249
    250         HtmlRendererUtils.renderHTMLAttributes(writer, uiComponent,
    251                 HTML.INPUT_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED);
    252         if (disabled || isDisabled(facesContext, uiComponent)) {
    253             writer.writeAttribute(HTML.DISABLED_ATTR, HTML.DISABLED_ATTR, null);
    254         }
    255
    256         writer.endElement(HTML.INPUT_ELEM);
    257
    258         if ((label != null) && (label.length() > 0)) {
    259             writer.write(HTML.NBSP_ENTITY);
    260             writer.writeText(label, null);
    261         }
    262     }
    263
    264     protected boolean isDisabled(FacesContext facesContext,
    265             UIComponent component) {
    266         //TODO: overwrite in extended HtmlCheckboxRenderer and check for
    267         // enabledOnUserRole
    268         boolean disabled;
    269         boolean readonly;
    270         if (component instanceof HtmlSelectBooleanCheckbox) {
    271             disabled = ((HtmlSelectBooleanCheckbox) component).isDisabled();
    272             readonly = ((HtmlSelectBooleanCheckbox) component).isReadonly();
    273         } else if (component instanceof HtmlSelectManyCheckbox) {
    274             disabled = ((HtmlSelectManyCheckbox) component).isDisabled();
    275             readonly = ((HtmlSelectManyCheckbox) component).isReadonly();
    276         } else {
    277             disabled = RendererUtils.getBooleanAttribute(component,
    278                     HTML.DISABLED_ATTR, false);
    279             readonly = RendererUtils.getBooleanAttribute(component,
    280                     HTML.READONLY_ATTR, false);
    281         }
    282         if (!disabled && readonly) {
    283             disabled = MyfacesConfig.getCurrentInstance(facesContext
    284                             .getExternalContext()).isReadonlyAsDisabledForSelect();
    285         }
    286         return disabled;
    287     }
    288
    289     public void decode(FacesContext facesContext, UIComponent component) {
    290         org.apache.myfaces.shared_orchestra.renderkit.RendererUtils.checkParamValidity(facesContext, component, null);
    291         if (component instanceof UISelectBoolean) {
    292             HtmlRendererUtils.decodeUISelectBoolean(facesContext, component);
    293         } else if (component instanceof UISelectMany) {
    294             HtmlRendererUtils.decodeUISelectMany(facesContext, component);
    295         } else {
    296             throw new IllegalArgumentException("Unsupported component class "
    297                     + component.getClass().getName());
    298         }
    299     }
    300
    301     public Object getConvertedValue(FacesContext facesContext,
    302             UIComponent component, Object submittedValue)
    303             throws ConverterException {
    304         org.apache.myfaces.shared_orchestra.renderkit.RendererUtils.checkParamValidity(facesContext, component, null);
    305         if (component instanceof UISelectBoolean) {
    306             return submittedValue;
    307         } else if (component instanceof UISelectMany) {
    308             return org.apache.myfaces.shared_orchestra.renderkit.RendererUtils.getConvertedUISelectManyValue(facesContext,
    309                     (UISelectMany) component, submittedValue);
    310         } else {
    311             throw new IllegalArgumentException("Unsupported component class "
    312                     + component.getClass().getName());
    313         }
    314     }
    315 }