001: /*
002: * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved
003: *
004: * This file is part of Resin(R) Open Source
005: *
006: * Each copy or derived work must preserve the copyright notice and this
007: * notice unmodified.
008: *
009: * Resin Open Source is free software; you can redistribute it and/or modify
010: * it under the terms of the GNU General Public License version 2
011: * as published by the Free Software Foundation.
012: *
013: * Resin Open Source is distributed in the hope that it will be useful,
014: * but WITHOUT ANY WARRANTY; without even the implied warranty of
015: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
016: * of NON-INFRINGEMENT. See the GNU General Public License for more
017: * details.
018: *
019: * You should have received a copy of the GNU General Public License
020: * along with Resin Open Source; if not, write to the
021: *
022: * Free Software Foundation, Inc.
023: * 59 Temple Place, Suite 330
024: * Boston, MA 02111-1307 USA
025: *
026: * @author Scott Ferguson
027: */
028:
029: package com.caucho.jsf.html;
030:
031: import javax.faces.component.*;
032: import javax.faces.context.*;
033: import javax.faces.model.*;
034: import javax.faces.convert.*;
035: import javax.el.*;
036: import java.io.*;
037: import java.util.*;
038: import java.lang.reflect.*;
039:
040: /**
041: * The base renderer
042: */
043: abstract class SelectRenderer extends BaseRenderer {
044: private static Map<Class, Class> _primitiveTypeMap = new HashMap<Class, Class>();
045:
046: @Override
047: public Object getConvertedValue(FacesContext context,
048: UIComponent component, Object submittedValue)
049: throws ConverterException {
050: if (component instanceof UISelectMany) {
051: return getConvertedValue(context, (UISelectMany) component,
052: submittedValue);
053: }
054: return super .getConvertedValue(context, component,
055: submittedValue);
056: }
057:
058: private Object getConvertedValue(FacesContext context,
059: UISelectMany uiSelectMany, Object submittedValue)
060: throws ConverterException {
061: String[] strValues = (String[]) submittedValue;
062:
063: Converter converter = uiSelectMany.getConverter();
064:
065: Object[] values = null;
066:
067: ValueExpression valueExpr = uiSelectMany
068: .getValueExpression("value");
069:
070: if (valueExpr != null) {
071: Class cl;
072: cl = valueExpr.getType(context.getELContext());
073: if (cl.isArray()) {
074: cl = cl.getComponentType();
075: if (cl.isPrimitive()) {
076: cl = _primitiveTypeMap.get(cl);
077: }
078: converter = context.getApplication()
079: .createConverter(cl);
080: values = (Object[]) Array.newInstance(cl,
081: strValues.length);
082: } else if (java.util.List.class.isAssignableFrom(cl)) {
083: values = strValues;
084:
085: uiSelectMany.setSelectedValues(values);
086: uiSelectMany.setValid(true);
087:
088: return values;
089: } else {
090: //todo should never happen as per spec. should an exception be thrown?
091: }
092: } else {
093: values = new Object[strValues.length];
094: }
095:
096: for (int i = 0; i < strValues.length; i++) {
097: if (converter != null) {
098: values[i] = converter.getAsObject(context,
099: uiSelectMany, strValues[i]);
100: } else {
101: values[i] = strValues[i];
102: }
103: }
104:
105: uiSelectMany.setSelectedValues(values);
106: uiSelectMany.setValid(true);
107:
108: return values;
109: }
110:
111: public List<SelectItem> accrueSelectItems(UIComponent component) {
112: ArrayList<SelectItem> itemList = new ArrayList<SelectItem>();
113:
114: int count = component.getChildCount();
115: if (count == 0)
116: return itemList;
117:
118: List<UIComponent> children = component.getChildren();
119:
120: for (int i = 0; i < count; i++) {
121: UIComponent child = children.get(i);
122:
123: if (child instanceof UISelectItem) {
124: UISelectItem uiSelectItem = (UISelectItem) child;
125:
126: SelectItem item = (SelectItem) uiSelectItem.getValue();
127:
128: if (item == null) {
129: item = new SelectItem(uiSelectItem.getItemValue(),
130: uiSelectItem.getItemLabel(), uiSelectItem
131: .getItemDescription(), uiSelectItem
132: .isItemDisabled(), uiSelectItem
133: .isItemEscaped());
134: }
135:
136: itemList.add(item);
137: } else if (child instanceof UISelectItems) {
138: UISelectItems selectedItems = (UISelectItems) child;
139:
140: Object value = selectedItems.getValue();
141:
142: if (value instanceof SelectItem) {
143: itemList.add((SelectItem) value);
144: } else if (value instanceof SelectItem[]) {
145: SelectItem[] items = (SelectItem[]) value;
146:
147: itemList.ensureCapacity(itemList.size()
148: + items.length);
149:
150: for (SelectItem item : items) {
151: itemList.add(item);
152: }
153: } else if (value instanceof Collection) {
154: Collection items = (Collection) value;
155:
156: itemList.ensureCapacity(itemList.size()
157: + items.size());
158:
159: itemList.addAll(items);
160: } else if (value instanceof Map) {
161: Map map = (Map) value;
162:
163: itemList.ensureCapacity(itemList.size()
164: + map.size());
165:
166: Set<Map.Entry> entries = map.entrySet();
167: for (Map.Entry entry : entries) {
168: itemList.add(new SelectItem(entry.getValue(),
169: String.valueOf(entry.getKey())));
170: }
171: }
172: }
173: }
174: return itemList;
175: }
176:
177: protected void encodeChildren(ResponseWriter out,
178: FacesContext context, UIComponent component,
179: Object[] values, String enabledClass, String disabledClass)
180: throws IOException {
181:
182: List<SelectItem> list = accrueSelectItems(component);
183:
184: for (int i = 0; i < list.size(); i++) {
185: SelectItem selectItem = list.get(i);
186:
187: out.startElement("option", component);
188:
189: // jsf/31c4
190: /*
191: out.writeAttribute("id", childId, "id");
192: //out.writeAttribute("name", child.getClientId(context), "name");
193: */
194:
195: if (selectItem.isDisabled()) {
196: out.writeAttribute("disabled", "disabled", "disabled");
197:
198: if (disabledClass != null)
199: out.writeAttribute("class", disabledClass,
200: "disabledClass");
201: } else {
202: if (enabledClass != null)
203: out.writeAttribute("class", enabledClass,
204: "enabledClass");
205: }
206:
207: if (values != null) {
208: for (int j = 0; j < values.length; j++) {
209: if (values[j].equals(selectItem.getValue())) {
210: out.writeAttribute("selected", "selected",
211: "selected");
212: break;
213: }
214: }
215: }
216:
217: out.writeAttribute("value", String.valueOf(selectItem
218: .getValue()), "value");
219:
220: String label = selectItem.getLabel();
221:
222: if (label != null)
223: out.writeText(label, "label");
224:
225: out.endElement("option");
226: out.write("\n");
227:
228: }
229: }
230:
231: protected void encodeOneChildren(ResponseWriter out,
232: FacesContext context, UIComponent component, Object value,
233: String enabledClass, String disabledClass)
234: throws IOException {
235: String clientId = component.getClientId(context);
236:
237: ValueExpression ve = component.getValueExpression("value");
238:
239: Class type = null;
240: if (ve != null) {
241: type = ve.getType(context.getELContext());
242: }
243:
244: List<SelectItem> items = accrueSelectItems(component);
245: for (int i = 0; i < items.size(); i++) {
246: String childId = clientId + ":" + i;
247:
248: SelectItem selectItem = items.get(i);
249:
250: String itemLabel = selectItem.getLabel();
251: Object itemValue = selectItem.getValue();
252:
253: out.startElement("option", component);
254:
255: // jsf/31c4
256: /*
257: out.writeAttribute("id", childId, "id");
258: //out.writeAttribute("name", child.getClientId(context), "name");
259: */
260:
261: Object optionValue;
262: if (type != null) {
263: optionValue = context.getApplication()
264: .getExpressionFactory().coerceToType(itemValue,
265: type);
266: } else {
267: optionValue = selectItem.getValue();
268: }
269:
270: if (value != null && value.equals(optionValue))
271: out.writeAttribute("selected", "selected", "selected");
272:
273: if (selectItem.isDisabled()) {
274: out.writeAttribute("disabled", "disabled", "disabled");
275:
276: if (disabledClass != null)
277: out.writeAttribute("class", disabledClass,
278: "disabledClass");
279: } else {
280: if (enabledClass != null)
281: out.writeAttribute("class", enabledClass,
282: "enabledClass");
283: }
284:
285: String itemValueString = toString(context, component,
286: itemValue);
287: out.writeAttribute("value", itemValueString, "value");
288:
289: if (itemLabel == null)
290: itemLabel = itemValueString;
291:
292: out.writeText(itemLabel, "label");
293:
294: out.endElement("option");
295: out.write("\n");
296: }
297: }
298:
299: static {
300: _primitiveTypeMap.put(boolean.class, Boolean.class);
301: _primitiveTypeMap.put(byte.class, Byte.class);
302: _primitiveTypeMap.put(char.class, Character.class);
303: _primitiveTypeMap.put(short.class, Short.class);
304: _primitiveTypeMap.put(int.class, Integer.class);
305: _primitiveTypeMap.put(long.class, Long.class);
306: _primitiveTypeMap.put(float.class, Float.class);
307: _primitiveTypeMap.put(double.class, Double.class);
308: }
309: }
|