View Javadoc

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 }