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.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 javax.faces.component.UIComponent;
26  import javax.faces.component.UISelectMany;
27  import javax.faces.component.UISelectOne;
28  import javax.faces.component.behavior.ClientBehavior;
29  import javax.faces.component.behavior.ClientBehaviorHolder;
30  import javax.faces.context.FacesContext;
31  import javax.faces.context.ResponseWriter;
32  import javax.faces.convert.Converter;
33  import org.apache.myfaces.shared.renderkit.html.util.SelectItemInfo;
34  import org.apache.myfaces.shared.renderkit.html.util.SelectItemsUtils;
35  
36  public class HtmlSelectableRendererBase extends HtmlRenderer
37  {
38      
39      protected void internalRenderSelect(FacesContext facesContext,
40              UIComponent uiComponent, boolean disabled, int size,
41              boolean selectMany, Converter converter) throws IOException
42      {
43          ResponseWriter writer = facesContext.getResponseWriter();
44          writer.startElement(HTML.SELECT_ELEM, uiComponent);
45          if (uiComponent instanceof ClientBehaviorHolder
46                  && !((ClientBehaviorHolder) uiComponent).getClientBehaviors()
47                          .isEmpty())
48          {
49              writer.writeAttribute(HTML.ID_ATTR,
50                      uiComponent.getClientId(facesContext), null);
51          }
52          else
53          {
54              HtmlRendererUtils.writeIdIfNecessary(writer, uiComponent,
55                      facesContext);
56          }
57          writer.writeAttribute(HTML.NAME_ATTR,
58                  uiComponent.getClientId(facesContext), null);
59          List<SelectItemInfo> selectItemList;
60          if (selectMany)
61          {
62              writer.writeAttribute(HTML.MULTIPLE_ATTR, HTML.MULTIPLE_ATTR, null);
63              selectItemList = SelectItemsUtils.getSelectItemInfoList((UISelectMany) uiComponent, facesContext);
64          }
65          else
66          {
67              selectItemList = SelectItemsUtils.getSelectItemInfoList(
68                      (UISelectOne) uiComponent, facesContext);
69          }
70  
71          if (size == Integer.MIN_VALUE)
72          {
73              //No size given (Listbox) --> size is number of select items
74              writer.writeAttribute(HTML.SIZE_ATTR,
75                      Integer.toString(selectItemList.size()), null);
76          }
77          else
78          {
79              writer.writeAttribute(HTML.SIZE_ATTR, Integer.toString(size), null);
80          }
81          Map<String, List<ClientBehavior>> behaviors = null;
82          if (uiComponent instanceof ClientBehaviorHolder)
83          {
84              behaviors = ((ClientBehaviorHolder) uiComponent)
85                      .getClientBehaviors();
86              long commonPropertiesMarked = 0L;
87              if (isCommonPropertiesOptimizationEnabled(facesContext))
88              {
89                  commonPropertiesMarked = CommonPropertyUtils.getCommonPropertiesMarked(uiComponent);
90              }
91              if (behaviors.isEmpty() && isCommonPropertiesOptimizationEnabled(facesContext))
92              {
93                  CommonPropertyUtils.renderChangeEventProperty(writer, 
94                          commonPropertiesMarked, uiComponent);
95                  CommonPropertyUtils.renderEventProperties(writer, 
96                          commonPropertiesMarked, uiComponent);
97                  // Note that on JSF 2.3, selectable components don't need onselect attribute
98                  // Please see https://issues.apache.org/jira/browse/MYFACES-4190
99                  CommonPropertyUtils.renderFieldEventPropertiesWithoutOnchangeAndOnselect(writer, 
100                         commonPropertiesMarked, uiComponent);
101             }
102             else
103             {
104                 HtmlRendererUtils.renderBehaviorizedOnchangeEventHandler(facesContext, writer,
105                         uiComponent, behaviors);
106                 if (isCommonEventsOptimizationEnabled(facesContext))
107                 {
108                     Long commonEventsMarked = CommonEventUtils.getCommonEventsMarked(uiComponent);
109                     CommonEventUtils.renderBehaviorizedEventHandlers(facesContext, writer, 
110                             commonPropertiesMarked, commonEventsMarked, uiComponent, behaviors);
111                     CommonEventUtils.renderBehaviorizedFieldEventHandlersWithoutOnchangeAndOnselect(
112                         facesContext, writer, commonPropertiesMarked, commonEventsMarked, uiComponent, behaviors);
113                 }
114                 else
115                 {
116                     HtmlRendererUtils.renderBehaviorizedEventHandlers(facesContext, writer, uiComponent,
117                             behaviors);
118                     HtmlRendererUtils.renderBehaviorizedFieldEventHandlersWithoutOnchangeAndOnselect(facesContext,
119                             writer, uiComponent, behaviors);
120                 }
121             }
122             if (isCommonPropertiesOptimizationEnabled(facesContext))
123             {
124                 CommonPropertyUtils.renderSelectPassthroughPropertiesWithoutDisabledAndEvents(writer, 
125                         CommonPropertyUtils.getCommonPropertiesMarked(uiComponent), uiComponent);
126             }
127             else
128             {
129                 HtmlRendererUtils.renderHTMLAttributes(
130                         writer,
131                         uiComponent,
132                         HTML.SELECT_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED_AND_EVENTS);
133             }
134         }
135         else
136         {
137             if (isCommonPropertiesOptimizationEnabled(facesContext))
138             {
139                 CommonPropertyUtils.renderSelectPassthroughPropertiesWithoutDisabled(writer, 
140                         CommonPropertyUtils.getCommonPropertiesMarked(uiComponent), uiComponent);
141             }
142             else
143             {
144                 HtmlRendererUtils.renderHTMLAttributes(writer, uiComponent,
145                         HTML.SELECT_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED);
146             }
147         }
148 
149         if (disabled)
150         {
151             writer.writeAttribute(HTML.DISABLED_ATTR, Boolean.TRUE, null);
152         }
153 
154         if (HtmlRendererUtils.isReadOnly(uiComponent))
155         {
156             writer.writeAttribute(HTML.READONLY_ATTR, HTML.READONLY_ATTR, null);
157         }
158 
159         Set lookupSet = HtmlRendererUtils.getSubmittedOrSelectedValuesAsSet(selectMany,
160                 uiComponent, facesContext, converter);
161 
162         SelectItemsUtils.renderSelectOptions(facesContext, uiComponent, converter, lookupSet,
163                 selectItemList);
164         // bug #970747: force separate end tag
165         writer.writeText(HtmlRendererUtils.STR_EMPTY, null);
166         writer.endElement(HTML.SELECT_ELEM);
167     }
168     
169 }