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