1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.renderkit.html.ext;
20
21 import java.io.IOException;
22 import java.util.List;
23
24 import javax.faces.FacesException;
25 import javax.faces.component.NamingContainer;
26 import javax.faces.component.UIComponent;
27 import javax.faces.component.UIInput;
28 import javax.faces.component.UISelectOne;
29 import javax.faces.component.UIViewRoot;
30 import javax.faces.context.FacesContext;
31 import javax.faces.context.ResponseWriter;
32 import javax.faces.convert.Converter;
33 import javax.faces.model.SelectItem;
34
35 import org.apache.myfaces.component.UserRoleUtils;
36 import org.apache.myfaces.custom.radio.HtmlRadio;
37 import org.apache.myfaces.shared_tomahawk.renderkit.JSFAttr;
38 import org.apache.myfaces.shared_tomahawk.renderkit.RendererUtils;
39 import org.apache.myfaces.shared_tomahawk.renderkit.html.HTML;
40 import org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlRadioRendererBase;
41 import org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlRendererUtils;
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60 public class HtmlRadioRenderer
61 extends HtmlRadioRendererBase
62 {
63
64
65 private static final String LAYOUT_SPREAD = "spread";
66
67 public void encodeEnd(FacesContext context, UIComponent component) throws IOException
68 {
69 if (context == null) throw new NullPointerException("context");
70 if (component == null) throw new NullPointerException("component");
71
72 if (component instanceof HtmlRadio)
73 {
74 renderRadio(context, (HtmlRadio)component);
75 }
76 else if (HtmlRendererUtils.isDisplayValueOnly(component))
77 {
78 HtmlRendererUtils.renderDisplayValueOnlyForSelects(context, component);
79 }
80 else if (component instanceof UISelectOne)
81 {
82 String layout = getLayout(component);
83 if (layout != null && layout.equals(LAYOUT_SPREAD))
84 {
85 return;
86 }
87 else
88 {
89 super.encodeEnd(context, component);
90 }
91 }
92 else
93 {
94 throw new IllegalArgumentException("Unsupported component class " + component.getClass().getName());
95 }
96 }
97
98 protected void renderRadio(FacesContext facesContext, HtmlRadio radio) throws IOException
99 {
100 String forAttr = radio.getFor();
101 if (forAttr == null)
102 {
103 throw new IllegalStateException("mandatory attribute 'for'");
104 }
105 int index = radio.getIndex();
106 if (index < 0)
107 {
108 throw new IllegalStateException("positive index must be given");
109 }
110
111 UIComponent uiComponent = radio.findComponent(forAttr);
112 if (uiComponent == null)
113 {
114 throw new IllegalStateException("Could not find component '" + forAttr + "' (calling findComponent on component '" + radio.getClientId(facesContext) + "')");
115 }
116 if (!(uiComponent instanceof UISelectOne))
117 {
118 throw new IllegalStateException("UISelectOne expected");
119 }
120
121 UISelectOne uiSelectOne = (UISelectOne)uiComponent;
122 Converter converter;
123 List selectItemList = RendererUtils.getSelectItemList(uiSelectOne);
124 if (index >= selectItemList.size())
125 {
126 throw new IndexOutOfBoundsException("index " + index + " >= " + selectItemList.size());
127 }
128
129 try
130 {
131 converter = RendererUtils.findUIOutputConverter(facesContext, uiSelectOne);
132 }
133 catch (FacesException e)
134 {
135 converter = null;
136 }
137
138 Object currentValue = RendererUtils.getObjectValue(uiSelectOne);
139 currentValue
140 = RendererUtils.getConvertedStringValue(facesContext, uiSelectOne,
141 converter, currentValue);
142 SelectItem selectItem = (SelectItem)selectItemList.get(index);
143 String itemStrValue
144 = RendererUtils.getConvertedStringValue(facesContext, uiSelectOne,
145 converter,
146 selectItem.getValue());
147
148 ResponseWriter writer = facesContext.getResponseWriter();
149
150
151
152
153
154
155
156
157
158
159
160
161 String itemId = renderRadio(facesContext,
162 uiSelectOne,
163 radio,
164 itemStrValue,
165 selectItem.isDisabled(),
166 itemStrValue.equals(currentValue),
167 false,
168 index);
169
170
171
172 boolean componentDisabled = isDisabled(facesContext, uiSelectOne);
173 boolean itemDisabled = selectItem.isDisabled();
174 boolean disabled = (componentDisabled || itemDisabled);
175
176 renderLabel(writer, radio, uiSelectOne, itemId, selectItem, disabled);
177 }
178
179
180
181
182
183 protected String renderRadio(FacesContext facesContext,
184 UIInput uiComponent,
185 HtmlRadio radio,
186 String value,
187 boolean disabled,
188 boolean checked,
189 boolean renderId,
190 Integer itemNum)
191 throws IOException
192 {
193 String clientId = uiComponent.getClientId(facesContext);
194
195 String itemId = (radio.getId()!=null && !radio.getId().startsWith(UIViewRoot.UNIQUE_ID_PREFIX)) ?
196 radio.getClientId(facesContext) :
197 (itemNum == null)? null : clientId + NamingContainer.SEPARATOR_CHAR + itemNum;
198
199 ResponseWriter writer = facesContext.getResponseWriter();
200
201 writer.startElement(HTML.INPUT_ELEM, uiComponent);
202
203 if (itemId != null)
204 {
205 writer.writeAttribute(HTML.ID_ATTR, itemId, null);
206 }
207 else if (renderId) {
208 writer.writeAttribute(HTML.ID_ATTR, clientId, null);
209 }
210
211 writer.writeAttribute(HTML.TYPE_ATTR, HTML.INPUT_TYPE_RADIO, null);
212 writer.writeAttribute(HTML.NAME_ATTR, clientId, null);
213
214 if (disabled) {
215 writer.writeAttribute(HTML.DISABLED_ATTR, HTML.DISABLED_ATTR, null);
216 }
217
218 if (checked)
219 {
220 writer.writeAttribute(HTML.CHECKED_ATTR, HTML.CHECKED_ATTR, null);
221 }
222
223 if (value != null)
224 {
225 writer.writeAttribute(HTML.VALUE_ATTR, value, null);
226 }
227
228 renderHTMLAttributes(writer, radio ,uiComponent, HTML.INPUT_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED);
229
230 if (isDisabled(facesContext, uiComponent))
231 {
232 writer.writeAttribute(org.apache.myfaces.shared_tomahawk.renderkit.html.HTML.DISABLED_ATTR, Boolean.TRUE, null);
233 }
234
235 writer.endElement(HTML.INPUT_ELEM);
236
237 return itemId;
238 }
239
240 public static void renderLabel(ResponseWriter writer, UIComponent radio,
241 UIComponent component, String forClientId, SelectItem item,
242 boolean disabled) throws IOException
243 {
244 writer.startElement(HTML.LABEL_ELEM, component);
245 writer.writeAttribute(HTML.FOR_ATTR, forClientId, null);
246
247 String labelClass = null;
248
249 if (disabled)
250 {
251 labelClass = (String) radio.getAttributes().get(
252 JSFAttr.DISABLED_CLASS_ATTR);
253 if (labelClass == null)
254 {
255 labelClass = (String) component.getAttributes().get(
256 JSFAttr.DISABLED_CLASS_ATTR);
257 }
258 }
259 else
260 {
261 labelClass = (String) radio.getAttributes().get(
262 JSFAttr.ENABLED_CLASS_ATTR);
263 if (labelClass == null)
264 {
265 labelClass = (String) component.getAttributes().get(
266 JSFAttr.ENABLED_CLASS_ATTR);
267 }
268 }
269 if (labelClass != null)
270 {
271 writer.writeAttribute("class", labelClass, "labelClass");
272 }
273
274 if ((item.getLabel() != null) && (item.getLabel().length() > 0))
275 {
276 writer.write(HTML.NBSP_ENTITY);
277 if(item.isEscape())
278 {
279 writer.writeText(item.getLabel(), null);
280 }
281 else
282 {
283 writer.write(item.getLabel());
284 }
285 }
286
287 writer.endElement(HTML.LABEL_ELEM);
288 }
289
290 private static boolean renderHTMLAttributes(ResponseWriter writer,
291 UIComponent radio, UIComponent selectOne, String[] attributes) throws IOException
292 {
293 boolean somethingDone = false;
294 for (int i = 0, len = attributes.length; i < len; i++)
295 {
296 String attrName = attributes[i];
297 Object value = radio.getAttributes().get(attrName);
298 if (value == null)
299 {
300 value = selectOne.getAttributes().get(attrName);
301 }
302 if (HtmlRendererUtils.renderHTMLAttribute(writer, attrName, attrName, value ))
303 {
304 somethingDone = true;
305 }
306 }
307 return somethingDone;
308 }
309
310 protected boolean isDisabled(FacesContext facesContext, UIComponent uiComponent)
311 {
312 if (!UserRoleUtils.isEnabledOnUserRole(uiComponent))
313 {
314 return true;
315 }
316 else
317 {
318 return super.isDisabled(facesContext, uiComponent);
319 }
320 }
321
322
323 public void decode(FacesContext facesContext, UIComponent uiComponent)
324 {
325 if (uiComponent instanceof HtmlRadio)
326 {
327
328 }
329 else
330 {
331 super.decode(facesContext, uiComponent);
332 }
333 }
334
335 }