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 javax.faces.component;
20
21 import java.util.Arrays;
22 import java.util.Iterator;
23
24 import javax.faces.context.FacesContext;
25 import javax.faces.convert.Converter;
26 import javax.faces.model.SelectItem;
27 import javax.faces.model.SelectItemGroup;
28
29 /**
30 * @author Mathias Broekelmann (latest modification by $Author: bommel $)
31 * @version $Revision: 1187701 $ $Date: 2011-10-22 07:21:54 -0500 (Sat, 22 Oct 2011) $
32 */
33 class _SelectItemsUtil
34 {
35
36 /**
37 * @param context the faces context
38 * @param uiComponent the component instance
39 * @param value the value to check
40 * @param converter a converter instance
41 * @param iterator contains instances of SelectItem
42 * @return if the value of a selectitem is equal to the given value
43 */
44 public static boolean matchValue(FacesContext context,
45 UIComponent uiComponent, Object value,
46 Iterator<SelectItem> selectItemsIter, Converter converter)
47 {
48 while (selectItemsIter.hasNext())
49 {
50 SelectItem item = selectItemsIter.next();
51 if (item instanceof SelectItemGroup)
52 {
53 SelectItemGroup itemgroup = (SelectItemGroup) item;
54 SelectItem[] selectItems = itemgroup.getSelectItems();
55 if (selectItems != null
56 && selectItems.length > 0
57 && matchValue(context, uiComponent, value, Arrays
58 .asList(selectItems).iterator(), converter))
59 {
60 return true;
61 }
62 }
63 else
64 {
65 Object itemValue = _convertOrCoerceValue(context,
66 uiComponent, value, item, converter);
67 if (value == itemValue || value.equals(itemValue))
68 {
69 return true;
70 }
71 }
72 }
73 return false;
74 }
75
76 /**
77 * @param context the faces context
78 * @param uiComponent the component instance
79 * @param value the value to check
80 * @param converter
81 * @param iterator contains instances of SelectItem
82 * @return if the value is a SelectItem of selectItemsIter, on which noSelectionOption is true
83 */
84 public static boolean isNoSelectionOption(FacesContext context,
85 UIComponent uiComponent, Object value,
86 Iterator<SelectItem> selectItemsIter, Converter converter)
87 {
88 while (selectItemsIter.hasNext())
89 {
90 SelectItem item = selectItemsIter.next();
91 if (item instanceof SelectItemGroup)
92 {
93 SelectItemGroup itemgroup = (SelectItemGroup) item;
94 SelectItem[] selectItems = itemgroup.getSelectItems();
95 if (selectItems != null
96 && selectItems.length > 0
97 && isNoSelectionOption(context, uiComponent, value,
98 Arrays.asList(selectItems).iterator(),
99 converter))
100 {
101 return true;
102 }
103 }
104 else if (item.isNoSelectionOption())
105 {
106 Object itemValue = _convertOrCoerceValue(context, uiComponent,
107 value, item, converter);
108 if (value == itemValue || value.equals(itemValue))
109 {
110 return true;
111 }
112 }
113 }
114 return false;
115 }
116
117 /**
118 * If converter is available and selectItem.value is String uses getAsObject,
119 * otherwise uses EL type coertion and return result.
120 */
121 private static Object _convertOrCoerceValue(FacesContext facesContext,
122 UIComponent uiComponent, Object value, SelectItem selectItem,
123 Converter converter)
124 {
125 Object itemValue = selectItem.getValue();
126 if (converter != null && itemValue instanceof String)
127 {
128 itemValue = converter.getAsObject(facesContext, uiComponent,
129 (String) itemValue);
130 }
131 else
132 {
133 // The javadoc of UISelectOne/UISelectMany says :
134 // "... Before comparing each option, coerce the option value type
135 // to the type of this component's value following the
136 // Expression Language coercion rules ..."
137 // If the coercion fails, just return the value without coerce,
138 // because it could be still valid the comparison for that value.
139 // and swallow the exception, because its information is no relevant
140 // on this context.
141 try
142 {
143 if (value instanceof java.lang.Enum)
144 {
145 // Values from an enum are a special case. There is one syntax were the
146 // particular enumeration is extended using something like
147 // SOMEVALUE { ... }, usually to override toString() method. In this case,
148 // value.getClass is not the target enum class, so we need to get the
149 // right one from super class.
150 Class targetClass = value.getClass();
151 if (targetClass != null && !targetClass.isEnum())
152 {
153 targetClass = targetClass.getSuperclass();
154 }
155 itemValue = _ClassUtils.convertToTypeNoLogging(facesContext, itemValue, targetClass);
156 }
157 else
158 {
159 itemValue = _ClassUtils.convertToTypeNoLogging(facesContext, itemValue, value.getClass());
160 }
161 }
162 catch (IllegalArgumentException e)
163 {
164 //itemValue = selectItem.getValue();
165 }
166 catch (Exception e)
167 {
168 //itemValue = selectItem.getValue();
169 }
170 }
171 return itemValue;
172 }
173
174 }