001: /*
002: * Copyright 2004 The Apache Software Foundation.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package org.apache.myfaces.shared_impl.renderkit.html;
017:
018: import org.apache.commons.logging.Log;
019: import org.apache.commons.logging.LogFactory;
020: import org.apache.myfaces.shared_impl.renderkit.JSFAttr;
021:
022: import javax.faces.FacesException;
023: import javax.faces.component.NamingContainer;
024: import javax.faces.component.UIComponent;
025: import javax.faces.component.UISelectBoolean;
026: import javax.faces.component.UISelectMany;
027: import javax.faces.component.html.HtmlSelectBooleanCheckbox;
028: import javax.faces.component.html.HtmlSelectManyCheckbox;
029: import javax.faces.context.FacesContext;
030: import javax.faces.context.ResponseWriter;
031: import javax.faces.convert.Converter;
032: import javax.faces.convert.ConverterException;
033: import javax.faces.model.SelectItem;
034: import javax.faces.model.SelectItemGroup;
035: import java.io.IOException;
036: import java.util.Iterator;
037: import java.util.Set;
038:
039: /**
040: * @author Thomas Spiegl (latest modification by $Author: baranda $)
041: * @author Anton Koinov
042: * @version $Revision: 542318 $ $Date: 2007-05-28 22:37:46 +0200 (Mo, 28 Mai 2007) $
043: */
044: public class HtmlCheckboxRendererBase extends HtmlRenderer {
045: private static final Log log = LogFactory
046: .getLog(HtmlCheckboxRendererBase.class);
047:
048: private static final String PAGE_DIRECTION = "pageDirection";
049:
050: private static final String LINE_DIRECTION = "lineDirection";
051:
052: private static final String EXTERNAL_TRUE_VALUE = "true";
053:
054: public void encodeEnd(FacesContext facesContext,
055: UIComponent uiComponent) throws IOException {
056: org.apache.myfaces.shared_impl.renderkit.RendererUtils
057: .checkParamValidity(facesContext, uiComponent, null);
058: if (uiComponent instanceof UISelectBoolean) {
059: Boolean value = org.apache.myfaces.shared_impl.renderkit.RendererUtils
060: .getBooleanValue(uiComponent);
061: boolean isChecked = value != null ? value.booleanValue()
062: : false;
063: renderCheckbox(facesContext, uiComponent,
064: EXTERNAL_TRUE_VALUE, false, isChecked, true, null); //TODO: the selectBoolean is never disabled
065: } else if (uiComponent instanceof UISelectMany) {
066: renderCheckboxList(facesContext, (UISelectMany) uiComponent);
067: } else {
068: throw new IllegalArgumentException(
069: "Unsupported component class "
070: + uiComponent.getClass().getName());
071: }
072: }
073:
074: public void renderCheckboxList(FacesContext facesContext,
075: UISelectMany selectMany) throws IOException {
076:
077: String layout = getLayout(selectMany);
078: boolean pageDirectionLayout = false; //Default to lineDirection
079: if (layout != null) {
080: if (layout.equals(PAGE_DIRECTION)) {
081: pageDirectionLayout = true;
082: } else if (layout.equals(LINE_DIRECTION)) {
083: pageDirectionLayout = false;
084: } else {
085: log.error("Wrong layout attribute for component "
086: + selectMany.getClientId(facesContext) + ": "
087: + layout);
088: }
089: }
090:
091: ResponseWriter writer = facesContext.getResponseWriter();
092:
093: writer.startElement(HTML.TABLE_ELEM, selectMany);
094: HtmlRendererUtils.renderHTMLAttributes(writer, selectMany,
095: HTML.SELECT_TABLE_PASSTHROUGH_ATTRIBUTES);
096: HtmlRendererUtils.writeIdIfNecessary(writer, selectMany,
097: facesContext);
098:
099: if (!pageDirectionLayout)
100: writer.startElement(HTML.TR_ELEM, selectMany);
101:
102: Converter converter;
103: try {
104: converter = org.apache.myfaces.shared_impl.renderkit.RendererUtils
105: .findUISelectManyConverter(facesContext, selectMany);
106: } catch (FacesException e) {
107: log.error("Error finding Converter for component with id "
108: + selectMany.getClientId(facesContext));
109: converter = null;
110: }
111:
112: Set lookupSet = org.apache.myfaces.shared_impl.renderkit.RendererUtils
113: .getSubmittedValuesAsSet(facesContext, selectMany,
114: converter, selectMany);
115: boolean useSubmittedValues = lookupSet != null;
116:
117: if (!useSubmittedValues) {
118: lookupSet = org.apache.myfaces.shared_impl.renderkit.RendererUtils
119: .getSelectedValuesAsSet(facesContext, selectMany,
120: converter, selectMany);
121: }
122:
123: int itemNum = 0;
124:
125: for (Iterator it = org.apache.myfaces.shared_impl.renderkit.RendererUtils
126: .getSelectItemList(selectMany).iterator(); it.hasNext();) {
127: SelectItem selectItem = (SelectItem) it.next();
128:
129: renderGroupOrItemCheckbox(facesContext, selectMany,
130: selectItem, useSubmittedValues, lookupSet,
131: converter, pageDirectionLayout,
132: new Integer(itemNum));
133:
134: itemNum++;
135: }
136:
137: if (!pageDirectionLayout)
138: writer.endElement(HTML.TR_ELEM);
139: writer.endElement(HTML.TABLE_ELEM);
140: }
141:
142: protected String getLayout(UISelectMany selectMany) {
143: if (selectMany instanceof HtmlSelectManyCheckbox) {
144: return ((HtmlSelectManyCheckbox) selectMany).getLayout();
145: }
146:
147: return (String) selectMany.getAttributes().get(
148: JSFAttr.LAYOUT_ATTR);
149: }
150:
151: protected void renderGroupOrItemCheckbox(FacesContext facesContext,
152: UIComponent uiComponent, SelectItem selectItem,
153: boolean useSubmittedValues, Set lookupSet,
154: Converter converter, boolean pageDirectionLayout,
155: Integer itemNum) throws IOException {
156:
157: ResponseWriter writer = facesContext.getResponseWriter();
158:
159: boolean isSelectItemGroup = (selectItem instanceof SelectItemGroup);
160:
161: Object itemValue = selectItem.getValue(); // TODO : Check here for getSubmittedValue. Look at RendererUtils.getValue
162:
163: UISelectMany selectMany = (UISelectMany) uiComponent;
164:
165: String itemStrValue = org.apache.myfaces.shared_impl.renderkit.RendererUtils
166: .getConvertedStringValue(facesContext, selectMany,
167: converter, itemValue);
168:
169: if (isSelectItemGroup) {
170: if (pageDirectionLayout)
171: writer.startElement(HTML.TR_ELEM, selectMany);
172:
173: writer.startElement(HTML.TD_ELEM, selectMany);
174: writer.write(selectItem.getLabel());
175: writer.endElement(HTML.TD_ELEM);
176:
177: if (pageDirectionLayout) {
178: writer.endElement(HTML.TR_ELEM);
179: writer.startElement(HTML.TR_ELEM, selectMany);
180: }
181: writer.startElement(HTML.TD_ELEM, selectMany);
182:
183: writer.startElement(HTML.TABLE_ELEM, selectMany);
184: writer.writeAttribute(HTML.BORDER_ATTR, "0", null);
185:
186: SelectItemGroup group = (SelectItemGroup) selectItem;
187: SelectItem[] selectItems = group.getSelectItems();
188:
189: for (int i = 0; i < selectItems.length; i++) {
190: renderGroupOrItemCheckbox(facesContext, selectMany,
191: selectItems[i], useSubmittedValues, lookupSet,
192: converter, pageDirectionLayout, new Integer(i));
193: }
194:
195: writer.endElement(HTML.TD_ELEM);
196: writer.endElement(HTML.TR_ELEM);
197: writer.endElement(HTML.TABLE_ELEM);
198: writer.endElement(HTML.TD_ELEM);
199:
200: if (pageDirectionLayout)
201: writer.endElement(HTML.TR_ELEM);
202:
203: } else {
204:
205: writer.write("\t\t");
206: if (pageDirectionLayout)
207: writer.startElement(HTML.TR_ELEM, selectMany);
208: writer.startElement(HTML.TD_ELEM, selectMany);
209:
210: boolean checked = lookupSet.contains(itemStrValue);
211:
212: boolean disabled = selectItem.isDisabled();
213:
214: String itemId = renderCheckbox(facesContext, selectMany,
215: itemStrValue, disabled, checked, false, itemNum);
216:
217: // label element after the input
218: boolean componentDisabled = isDisabled(facesContext,
219: selectMany);
220: boolean itemDisabled = (componentDisabled || disabled);
221:
222: HtmlRendererUtils.renderLabel(writer, selectMany, itemId,
223: selectItem.getLabel(), itemDisabled);
224:
225: writer.endElement(HTML.TD_ELEM);
226: if (pageDirectionLayout)
227: writer.endElement(HTML.TR_ELEM);
228: }
229: }
230:
231: @Deprecated
232: protected void renderCheckbox(FacesContext facesContext,
233: UIComponent uiComponent, String value, String label,
234: boolean disabled, boolean checked, boolean renderId)
235: throws IOException {
236: renderCheckbox(facesContext, uiComponent, value, disabled,
237: checked, renderId, 0);
238: }
239:
240: /**
241: * Renders the input item
242: * @return the 'id' value of the rendered element
243: */
244: protected String renderCheckbox(FacesContext facesContext,
245: UIComponent uiComponent, String value, boolean disabled,
246: boolean checked, boolean renderId, Integer itemNum)
247: throws IOException {
248: String clientId = uiComponent.getClientId(facesContext);
249:
250: String itemId = (itemNum == null) ? null : clientId
251: + NamingContainer.SEPARATOR_CHAR + itemNum;
252:
253: ResponseWriter writer = facesContext.getResponseWriter();
254:
255: writer.startElement(HTML.INPUT_ELEM, uiComponent);
256:
257: if (itemId != null) {
258: writer.writeAttribute(HTML.ID_ATTR, itemId, null);
259: }
260: writer.writeAttribute(HTML.TYPE_ATTR, HTML.INPUT_TYPE_CHECKBOX,
261: null);
262: writer.writeAttribute(HTML.NAME_ATTR, clientId, null);
263:
264: if (renderId) {
265: HtmlRendererUtils.writeIdIfNecessary(writer, uiComponent,
266: facesContext);
267: }
268:
269: if (checked) {
270: writer
271: .writeAttribute(
272: HTML.CHECKED_ATTR,
273: org.apache.myfaces.shared_impl.renderkit.html.HTML.CHECKED_ATTR,
274: null);
275: }
276:
277: if (disabled) {
278: writer.writeAttribute(HTML.DISABLED_ATTR,
279: HTML.DISABLED_ATTR, null);
280: }
281:
282: if ((value != null) && (value.length() > 0)) {
283: writer.writeAttribute(HTML.VALUE_ATTR, value, null);
284: }
285:
286: if (uiComponent instanceof UISelectBoolean) {
287: HtmlRendererUtils.renderHTMLAttributes(writer, uiComponent,
288: HTML.INPUT_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED);
289: } else {
290: HtmlRendererUtils
291: .renderHTMLAttributes(
292: writer,
293: uiComponent,
294: HTML.INPUT_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED_AND_STYLE);
295: }
296: if (isDisabled(facesContext, uiComponent)) {
297: writer.writeAttribute(HTML.DISABLED_ATTR, Boolean.TRUE,
298: null);
299: }
300:
301: writer.endElement(HTML.INPUT_ELEM);
302:
303: return itemId;
304: }
305:
306: protected boolean isDisabled(FacesContext facesContext,
307: UIComponent component) {
308: //TODO: overwrite in extended HtmlCheckboxRenderer and check for
309: // enabledOnUserRole
310: if (component instanceof HtmlSelectBooleanCheckbox) {
311: return ((HtmlSelectBooleanCheckbox) component).isDisabled();
312: } else if (component instanceof HtmlSelectManyCheckbox) {
313: return ((HtmlSelectManyCheckbox) component).isDisabled();
314: } else {
315: return org.apache.myfaces.shared_impl.renderkit.RendererUtils
316: .getBooleanAttribute(component, HTML.DISABLED_ATTR,
317: false);
318: }
319: }
320:
321: public void decode(FacesContext facesContext, UIComponent component) {
322: org.apache.myfaces.shared_impl.renderkit.RendererUtils
323: .checkParamValidity(facesContext, component, null);
324: if (component instanceof UISelectBoolean) {
325: HtmlRendererUtils.decodeUISelectBoolean(facesContext,
326: component);
327: } else if (component instanceof UISelectMany) {
328: HtmlRendererUtils.decodeUISelectMany(facesContext,
329: component);
330: } else {
331: throw new IllegalArgumentException(
332: "Unsupported component class "
333: + component.getClass().getName());
334: }
335: }
336:
337: public Object getConvertedValue(FacesContext facesContext,
338: UIComponent component, Object submittedValue)
339: throws ConverterException {
340: org.apache.myfaces.shared_impl.renderkit.RendererUtils
341: .checkParamValidity(facesContext, component, null);
342: if (component instanceof UISelectBoolean) {
343: return submittedValue;
344: } else if (component instanceof UISelectMany) {
345: return org.apache.myfaces.shared_impl.renderkit.RendererUtils
346: .getConvertedUISelectManyValue(facesContext,
347: (UISelectMany) component, submittedValue);
348: } else {
349: throw new IllegalArgumentException(
350: "Unsupported component class "
351: + component.getClass().getName());
352: }
353: }
354: }
|