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 javax.faces.component;
030:
031: import java.util.*;
032:
033: import javax.el.*;
034: import javax.faces.application.*;
035: import javax.faces.context.*;
036: import javax.faces.model.*;
037:
038: public class UISelectOne extends UIInput {
039: public static final String COMPONENT_FAMILY = "javax.faces.SelectOne";
040: public static final String COMPONENT_TYPE = "javax.faces.SelectOne";
041: public static final String INVALID_MESSAGE_ID = "javax.faces.component.UISelectOne.INVALID";
042:
043: public UISelectOne() {
044: setRendererType("javax.faces.Menu");
045: }
046:
047: /**
048: * Returns the component family, used to select the renderer.
049: */
050: public String getFamily() {
051: return COMPONENT_FAMILY;
052: }
053:
054: public void validateValue(FacesContext context, Object value) {
055: super .validateValue(context, value);
056:
057: if (!isValid() || value == null)
058: return;
059:
060: ValueExpression ve = getValueExpression("value");
061:
062: Class type = null;
063: if (ve != null) {
064: type = ve.getType(context.getELContext());
065: }
066:
067: boolean hasValue = matchChildren(context.getApplication()
068: .getExpressionFactory(), this , value, type);
069:
070: if (!hasValue) {
071: String summary = Util
072: .l10n(
073: context,
074: INVALID_MESSAGE_ID,
075: "{0}: Validation Error: UISelectOne value '{1}' does not match a valid option.",
076: Util.getLabel(context, this ), value);
077:
078: String detail = summary;
079:
080: FacesMessage msg = new FacesMessage(summary, detail);
081:
082: context.addMessage(getClientId(context), msg);
083:
084: setValid(false);
085: }
086: }
087:
088: static boolean matchChildren(ExpressionFactory expressionFactory,
089: UIComponent comp, Object value, Class type) {
090: int count = comp.getChildCount();
091:
092: if (count <= 0)
093: return false;
094:
095: List<UIComponent> children = comp.getChildren();
096:
097: for (int i = 0; i < count; i++) {
098: UIComponent child = children.get(i);
099:
100: if (child instanceof UISelectItem) {
101: UISelectItem item = (UISelectItem) child;
102:
103: SelectItem selectItem = (SelectItem) item.getValue();
104:
105: if (selectItem == null) {
106: selectItem = new SelectItem(item.getItemValue());
107: }
108:
109: Object optionValue;
110:
111: if (type != null) {
112: optionValue = expressionFactory.coerceToType(
113: selectItem.getValue(), type);
114: } else {
115: optionValue = selectItem.getValue();
116: }
117:
118: if (value.equals(optionValue)) {
119: return true;
120: }
121: } else if (child instanceof UISelectItems) {
122: UISelectItems items = (UISelectItems) child;
123:
124: if (matchItems(expressionFactory, items.getValue(),
125: value, type))
126: return true;
127: }
128: }
129:
130: return false;
131: }
132:
133: private static boolean matchItems(
134: ExpressionFactory expressionFactory, Object selectValue,
135: Object value, Class type) {
136: if (selectValue instanceof SelectItemGroup) {
137: SelectItem[] items = ((SelectItemGroup) selectValue)
138: .getSelectItems();
139:
140: if (items != null) {
141: for (int i = 0; i < items.length; i++) {
142: if (matchItems(expressionFactory, items[i], value,
143: type))
144: return true;
145: }
146: }
147: } else if (selectValue instanceof SelectItem) {
148: SelectItem item = (SelectItem) selectValue;
149:
150: Object optionValue;
151:
152: if (type != null) {
153: optionValue = expressionFactory.coerceToType(item
154: .getValue(), type);
155: } else {
156: optionValue = item.getValue();
157: }
158:
159: return value.equals(optionValue) && !item.isDisabled();
160: } else if (selectValue instanceof SelectItem[]) {
161: SelectItem[] item = (SelectItem[]) selectValue;
162:
163: for (int i = 0; i < item.length; i++) {
164:
165: Object optionValue;
166:
167: if (type != null) {
168: optionValue = expressionFactory.coerceToType(
169: item[i].getValue(), type);
170: } else {
171: optionValue = item[i].getValue();
172: }
173:
174: if (value.equals(optionValue) && !item[i].isDisabled())
175: return true;
176: }
177: } else if (selectValue instanceof List) {
178: List list = (List) selectValue;
179:
180: int size = list.size();
181: for (int i = 0; i < size; i++) {
182: if (matchItems(expressionFactory, list.get(i), value,
183: type))
184: return true;
185: }
186: } else if (selectValue instanceof Map) {
187: Map map = (Map) selectValue;
188: Collection collection = map.values();
189: for (Iterator iterator = collection.iterator(); iterator
190: .hasNext();) {
191: Object o = iterator.next();
192: if (type != null) {
193: o = expressionFactory.coerceToType(o, type);
194: }
195: if (value.equals(o))
196: return true;
197: }
198: }
199:
200: return false;
201: }
202: }
|