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.renderkit.JSFAttr;
24  import org.apache.myfaces.shared_orchestra.renderkit.RendererUtils;
25  import org.apache.myfaces.shared_orchestra.config.MyfacesConfig;
26  
27  import javax.faces.component.UIComponent;
28  import javax.faces.component.UIOutput;
29  import javax.faces.component.UISelectOne;
30  import javax.faces.component.EditableValueHolder;
31  import javax.faces.component.html.HtmlSelectOneRadio;
32  import javax.faces.context.FacesContext;
33  import javax.faces.context.ResponseWriter;
34  import javax.faces.convert.Converter;
35  import javax.faces.convert.ConverterException;
36  import javax.faces.model.SelectItem;
37  import javax.faces.model.SelectItemGroup;
38  import java.io.IOException;
39  import java.util.Iterator;
40  import java.util.List;
41  
42  /**
43   * @author Manfred Geiler (latest modification by $Author: skitching $)
44   * @author Thomas Spiegl
45   * @version $Revision: 673826 $ $Date: 2008-07-03 16:43:52 -0500 (Thu, 03 Jul 2008) $
46   */
47  public class HtmlRadioRendererBase
48          extends HtmlRenderer
49  {
50      private static final Log log = LogFactory.getLog(HtmlRadioRendererBase.class);
51  
52      private static final String PAGE_DIRECTION = "pageDirection";
53      private static final String LINE_DIRECTION = "lineDirection";
54  
55      public void encodeEnd(FacesContext facesContext, UIComponent uiComponent) throws IOException
56      {
57          org.apache.myfaces.shared_orchestra.renderkit.RendererUtils.checkParamValidity(facesContext, uiComponent, UISelectOne.class);
58  
59          UISelectOne selectOne = (UISelectOne)uiComponent;
60  
61          String layout = getLayout(selectOne);
62  
63          boolean pageDirectionLayout = false; // Defaults to LINE_DIRECTION
64          if (layout != null)
65          {
66              if (layout.equals(PAGE_DIRECTION))
67              {
68                  pageDirectionLayout = true;
69              }
70              else if (layout.equals(LINE_DIRECTION))
71              {
72                  pageDirectionLayout = false;
73              }
74              else
75              {
76                  log.error("Wrong layout attribute for component " + selectOne.getClientId(facesContext) + ": " + layout);
77              }
78          }
79  
80          ResponseWriter writer = facesContext.getResponseWriter();
81  
82          writer.startElement(HTML.TABLE_ELEM, selectOne);
83          HtmlRendererUtils.renderHTMLAttributes(writer, selectOne,
84                                                 HTML.SELECT_TABLE_PASSTHROUGH_ATTRIBUTES);
85          HtmlRendererUtils.writeIdIfNecessary(writer, uiComponent, facesContext);
86  
87          if (!pageDirectionLayout) writer.startElement(HTML.TR_ELEM, selectOne);
88  
89          Converter converter;
90          List selectItemList = org.apache.myfaces.shared_orchestra.renderkit.RendererUtils.getSelectItemList(selectOne);
91          converter = HtmlRendererUtils.findUIOutputConverterFailSafe(facesContext, selectOne);
92  
93          Object currentValue = org.apache.myfaces.shared_orchestra.renderkit.RendererUtils.getObjectValue(selectOne);
94  
95          currentValue = org.apache.myfaces.shared_orchestra.renderkit.RendererUtils.getConvertedStringValue(facesContext, selectOne, converter, currentValue);
96  
97          for (Iterator it = selectItemList.iterator(); it.hasNext(); )
98          {
99              SelectItem selectItem = (SelectItem)it.next();
100 
101             renderGroupOrItemRadio(facesContext, selectOne,
102                                    selectItem, currentValue,
103                                    converter, pageDirectionLayout);
104         }
105 
106         if (!pageDirectionLayout) writer.endElement(HTML.TR_ELEM);
107         writer.endElement(HTML.TABLE_ELEM);
108     }
109 
110 
111     protected String getLayout(UIComponent selectOne)
112     {
113         if (selectOne instanceof HtmlSelectOneRadio)
114         {
115             return ((HtmlSelectOneRadio)selectOne).getLayout();
116         }
117 
118         return (String)selectOne.getAttributes().get(JSFAttr.LAYOUT_ATTR);
119     }
120 
121 
122     protected String getStyleClass(UISelectOne selectOne)
123      {
124          if (selectOne instanceof HtmlSelectOneRadio)
125          {
126              return ((HtmlSelectOneRadio)selectOne).getStyleClass();
127          }
128 
129          return (String)selectOne.getAttributes().get(JSFAttr.STYLE_CLASS_ATTR);
130      }
131 
132 
133     protected void renderGroupOrItemRadio(FacesContext facesContext,
134                                           UIComponent uiComponent, SelectItem selectItem,
135                                           Object currentValue,
136                                           Converter converter, boolean pageDirectionLayout) throws IOException{
137 
138         ResponseWriter writer = facesContext.getResponseWriter();
139 
140         boolean isSelectItemGroup = (selectItem instanceof SelectItemGroup);
141 
142         // TODO : Check here for getSubmittedValue. Look at RendererUtils.getValue
143         // this is useless object creation
144 //        Object itemValue = selectItem.getValue();
145 
146         UISelectOne selectOne = (UISelectOne)uiComponent;
147 
148         if (isSelectItemGroup) {
149             if (pageDirectionLayout)
150                 writer.startElement(HTML.TR_ELEM, selectOne);
151 
152             writer.startElement(HTML.TD_ELEM, selectOne);
153             writer.write(selectItem.getLabel());
154             writer.endElement(HTML.TD_ELEM);
155 
156             if (pageDirectionLayout) {
157                 writer.endElement(HTML.TR_ELEM);
158                 writer.startElement(HTML.TR_ELEM, selectOne);
159             }
160             writer.startElement(HTML.TD_ELEM, selectOne);
161 
162             writer.startElement(HTML.TABLE_ELEM, selectOne);
163             writer.writeAttribute(HTML.BORDER_ATTR, "0", null);
164 
165             SelectItemGroup group = (SelectItemGroup) selectItem;
166             SelectItem[] selectItems = group.getSelectItems();
167 
168             for (int i=0; i<selectItems.length; i++) {
169                 renderGroupOrItemRadio(facesContext, selectOne, selectItems[i], currentValue, converter, pageDirectionLayout);
170             }
171 
172             writer.endElement(HTML.TD_ELEM);
173             writer.endElement(HTML.TR_ELEM);
174             writer.endElement(HTML.TABLE_ELEM);
175             writer.endElement(HTML.TD_ELEM);
176 
177             if (pageDirectionLayout)
178                 writer.endElement(HTML.TR_ELEM);
179 
180         } else {
181 
182         writer.write("\t\t");
183         if (pageDirectionLayout)
184             writer.startElement(HTML.TR_ELEM, selectOne);
185         writer.startElement(HTML.TD_ELEM, selectOne);
186         writer.startElement(HTML.LABEL_ELEM, selectOne);
187 
188         String itemStrValue = org.apache.myfaces.shared_orchestra.renderkit.RendererUtils.getConvertedStringValue(facesContext, selectOne, converter, selectItem.getValue());
189         boolean itemDisabled = selectItem.isDisabled();
190 
191         boolean itemChecked = itemStrValue.equals(currentValue);
192 
193         String labelClass;
194         boolean componentDisabled = isDisabled(facesContext, selectOne);
195 
196         if (componentDisabled || itemDisabled) {
197             labelClass = (String) selectOne.getAttributes().get(JSFAttr.DISABLED_CLASS_ATTR);
198         } else {
199             labelClass = (String) selectOne.getAttributes().get(JSFAttr.ENABLED_CLASS_ATTR);
200         }
201         if (labelClass != null) {
202             writer.writeAttribute("class", labelClass, "labelClass");
203         }
204 
205         renderRadio(facesContext, selectOne, itemStrValue, selectItem
206                 .getLabel(), itemDisabled, itemChecked, false);
207         writer.endElement(HTML.LABEL_ELEM);
208         writer.endElement(HTML.TD_ELEM);
209         if (pageDirectionLayout)
210             writer.endElement(HTML.TR_ELEM);
211         }
212     }
213 
214     protected void renderRadio(FacesContext facesContext,
215                                UIComponent uiComponent,
216                                String value,
217                                String label,
218                                boolean disabled,
219                                boolean checked, boolean renderId)
220             throws IOException
221     {
222         String clientId = uiComponent.getClientId(facesContext);
223 
224         ResponseWriter writer = facesContext.getResponseWriter();
225 
226         writer.startElement(HTML.INPUT_ELEM, uiComponent);
227         writer.writeAttribute(HTML.TYPE_ATTR, HTML.INPUT_TYPE_RADIO, null);
228         writer.writeAttribute(HTML.NAME_ATTR, clientId, null);
229 
230         if (renderId) {
231             writer.writeAttribute(HTML.ID_ATTR, clientId, null);
232         }
233 
234         if (checked)
235         {
236             writer.writeAttribute(HTML.CHECKED_ATTR, HTML.CHECKED_ATTR, null);
237         }
238 
239         if ((value != null) && (value.length() > 0))
240         {
241             writer.writeAttribute(HTML.VALUE_ATTR, value, null);
242         }
243 
244         HtmlRendererUtils.renderHTMLAttributes(writer, uiComponent, HTML.INPUT_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED);
245         if (disabled || isDisabled(facesContext, uiComponent))
246         {
247             writer.writeAttribute(HTML.DISABLED_ATTR, HTML.DISABLED_ATTR, null);
248         }
249 
250         writer.endElement(HTML.INPUT_ELEM);
251 
252         if ((label != null) && (label.length() > 0))
253         {
254             writer.write(HTML.NBSP_ENTITY);
255             writer.writeText(label, null);
256         }
257     }
258 
259 
260     protected boolean isDisabled(FacesContext facesContext, UIComponent uiComponent)
261     {
262         //TODO: overwrite in extended HtmlRadioRenderer and check for enabledOnUserRole
263         boolean disabled;
264         boolean readonly;
265         if (uiComponent instanceof HtmlSelectOneRadio)
266         {
267             disabled = ((HtmlSelectOneRadio) uiComponent).isDisabled();
268             readonly = ((HtmlSelectOneRadio) uiComponent).isReadonly();
269         }
270         else
271         {
272             disabled = RendererUtils.getBooleanAttribute(uiComponent,
273                     HTML.DISABLED_ATTR, false);
274             readonly = RendererUtils.getBooleanAttribute(uiComponent,
275                     HTML.READONLY_ATTR, false);
276         }
277  
278         if (!disabled && readonly)
279         {
280             disabled = MyfacesConfig.getCurrentInstance(facesContext
281                             .getExternalContext()).isReadonlyAsDisabledForSelect();
282         }
283         return disabled;
284     }
285 
286 
287     public void decode(FacesContext facesContext, UIComponent uiComponent)
288     {
289         org.apache.myfaces.shared_orchestra.renderkit.RendererUtils.checkParamValidity(facesContext, uiComponent, null);
290         if (uiComponent instanceof EditableValueHolder)
291         {
292             HtmlRendererUtils.decodeUISelectOne(facesContext, uiComponent);
293         }
294     }
295 
296 
297     public Object getConvertedValue(FacesContext facesContext, UIComponent uiComponent, Object submittedValue) throws ConverterException
298     {
299         RendererUtils.checkParamValidity(facesContext, uiComponent, UIOutput.class);
300         return org.apache.myfaces.shared_orchestra.renderkit.RendererUtils.getConvertedUIOutputValue(facesContext,
301                                                                                            (UIOutput)uiComponent,
302                                                                                            submittedValue);
303     }
304 
305 }