Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: javax/faces/component/UISelectMany.java


1   /*
2    * Copyright 2004 The Apache Software Foundation.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package javax.faces.component;
17  
18  import java.lang.reflect.Array;
19  import java.util.ArrayList;
20  import java.util.Collection;
21  import java.util.Iterator;
22  import java.util.List;
23  
24  import javax.faces.application.FacesMessage;
25  import javax.faces.component._SelectItemsUtil._ValueConverter;
26  import javax.faces.context.FacesContext;
27  import javax.faces.convert.ConverterException;
28  import javax.faces.el.ValueBinding;
29  import javax.faces.render.Renderer;
30  
31  /**
32   * see Javadoc of JSF Specification
33   *
34   * @author Manfred Geiler (latest modification by $Author: svieujot $)
35   * @version $Revision: 280406 $ $Date: 2005-09-12 16:08:06 -0400 (Mon, 12 Sep 2005) $
36   */
37  public class UISelectMany extends UIInput
38  {
39      public static final String INVALID_MESSAGE_ID = "javax.faces.component.UISelectMany.INVALID";
40  
41      public Object[] getSelectedValues()
42      {
43          return (Object[]) getValue();
44      }
45  
46      public void setSelectedValues(Object[] selectedValues)
47      {
48          setValue(selectedValues);
49      }
50  
51      public ValueBinding getValueBinding(String name)
52      {
53          if (name == null)
54              throw new NullPointerException("name");
55          if (name.equals("selectedValues"))
56          {
57              return super.getValueBinding("value");
58          }
59          else
60          {
61              return super.getValueBinding(name);
62          }
63      }
64  
65      public void setValueBinding(String name, ValueBinding binding)
66      {
67          if (name == null)
68              throw new NullPointerException("name");
69          if (name.equals("selectedValues"))
70          {
71              super.setValueBinding("value", binding);
72          }
73          else
74          {
75              super.setValueBinding(name, binding);
76          }
77      }
78  
79      /**
80       * @return true if Objects are different (!)
81       */
82      protected boolean compareValues(Object previous, Object value)
83      {
84          if (previous == null)
85          {
86              // one is null, the other not
87              return value != null;
88          }
89          else if (value == null)
90          {
91              // one is null, the other not
92              return previous != null;
93          }
94          else
95          {
96              if (previous instanceof Object[] && value instanceof Object[])
97              {
98                  return compareObjectArrays((Object[]) previous,
99                                  (Object[]) value);
100             }
101             else if (previous instanceof List && value instanceof List)
102             {
103                 return compareLists((List) previous, (List) value);
104             }
105             else if (previous.getClass().isArray()
106                             && value.getClass().isArray())
107             {
108                 return comparePrimitiveArrays(previous, value);
109             }
110             else
111             {
112                 //Objects have different classes
113                 return true;
114             }
115         }
116     }
117 
118     private boolean compareObjectArrays(Object[] previous, Object[] value)
119     {
120         int length = value.length;
121         if (previous.length != length)
122         {
123             //different length
124             return true;
125         }
126 
127         boolean[] scoreBoard = new boolean[length];
128         for (int i = 0; i < length; i++)
129         {
130             Object p = previous[i];
131             boolean found = false;
132             for (int j = 0; j < length; j++)
133             {
134                 if (scoreBoard[j] == false)
135                 {
136                     Object v = value[j];
137                     if ((p == null && v == null)
138                                     || (p != null && v != null && p.equals(v)))
139                     {
140                         scoreBoard[j] = true;
141                         found = true;
142                         break;
143                     }
144                 }
145             }
146             if (!found)
147             {
148                 return true; //current element of previous array not found in new array
149             }
150         }
151 
152         return false; // arrays are identical
153     }
154 
155     private boolean compareLists(List previous, List value)
156     {
157         int length = value.size();
158         if (previous.size() != length)
159         {
160             //different length
161             return true;
162         }
163 
164         boolean[] scoreBoard = new boolean[length];
165         for (int i = 0; i < length; i++)
166         {
167             Object p = previous.get(i);
168             boolean found = false;
169             for (int j = 0; j < length; j++)
170             {
171                 if (scoreBoard[j] == false)
172                 {
173                     Object v = value.get(j);
174                     if ((p == null && v == null)
175                                     || (p != null && v != null && p.equals(v)))
176                     {
177                         scoreBoard[j] = true;
178                         found = true;
179                         break;
180                     }
181                 }
182             }
183             if (!found)
184             {
185                 return true; //current element of previous List not found in new List
186             }
187         }
188 
189         return false; // Lists are identical
190     }
191 
192     private boolean comparePrimitiveArrays(Object previous, Object value)
193     {
194         int length = Array.getLength(value);
195         if (Array.getLength(previous) != length)
196         {
197             //different length
198             return true;
199         }
200 
201         boolean[] scoreBoard = new boolean[length];
202         for (int i = 0; i < length; i++)
203         {
204             Object p = Array.get(previous, i);
205             boolean found = false;
206             for (int j = 0; j < length; j++)
207             {
208                 if (scoreBoard[j] == false)
209                 {
210                     Object v = Array.get(value, j);
211                     if ((p == null && v == null)
212                                     || (p != null && v != null && p.equals(v)))
213                     {
214                         scoreBoard[j] = true;
215                         found = true;
216                         break;
217                     }
218                 }
219             }
220             if (!found)
221             {
222                 return true; //current element of previous array not found in new array
223             }
224         }
225 
226         return false; // arrays are identical
227     }
228 
229     protected void validateValue(FacesContext context, Object convertedValue)
230     {
231         boolean empty = convertedValue == null
232                         || ((convertedValue instanceof Object[]) && (((Object[]) convertedValue).length == 0))
233                         || ((convertedValue instanceof List) && ((List) convertedValue).isEmpty());
234 
235         if (isRequired() && empty)
236         {
237             _MessageUtils.addErrorMessage(context, this, REQUIRED_MESSAGE_ID,
238                             new Object[] {getId()});
239             setValid(false);
240             return;
241         }
242 
243         if (!empty)
244         {
245             _ComponentUtils.callValidators(context, this, convertedValue);
246         }
247 
248         if (isValid() && convertedValue != null)
249         {
250             // all selected values must match to the values of the available options
251 
252             if (! (convertedValue instanceof Object[]) && ! (convertedValue instanceof List)) {
253                 _MessageUtils.addErrorMessage(context, this,
254                                 INVALID_MESSAGE_ID,
255                                 new Object[] {getId()});
256                 setValid(false);
257                 return;
258             }
259             
260             _ValueConverter converter = new _ValueConverter()
261             {
262                 public Object getConvertedValue(FacesContext context, String value)
263                 {
264                     Object convertedValue = UISelectMany.this.getConvertedValue(context, new String[] {value});
265                     if(convertedValue instanceof Collection)
266                     {
267                         Iterator iter = ((Collection)convertedValue).iterator();
268                         if(iter.hasNext())
269                         {
270                             return iter.next();
271                         }
272                         return null;
273                     }
274                     return ((Object[])convertedValue)[0];
275                 }
276             };
277 
278             if ( convertedValue instanceof Object[] ){ 
279               Object[] values = (Object[]) convertedValue;
280               if (values.length > 0)
281               {
282                   Collection items = new ArrayList();
283                   for (Iterator iter = new _SelectItemsIterator(this); iter.hasNext();)
284                   {
285                       items.add( iter.next() );
286                   }
287                   for (int i = 0, size = values.length; i < size; i++)
288                   {
289                       if (!_SelectItemsUtil.matchValue(context, values[i],
290                                       items.iterator(), converter))
291                       {
292                           _MessageUtils.addErrorMessage(context, this,
293                                           INVALID_MESSAGE_ID,
294                                           new Object[] {getId()});
295                           setValid(false);
296                       }
297                   }
298               }
299             }else{ // convertedValue instanceof List
300               List values = (List) convertedValue;
301               if ( ! values.isEmpty() )
302               {
303                   Collection items = new ArrayList();
304                   for (Iterator iter = new _SelectItemsIterator(this); iter.hasNext();)
305                   {
306                       items.add( iter.next() );
307                   }
308                   for (Iterator i = values.iterator(); i.hasNext();)
309                   {
310                       if (!_SelectItemsUtil.matchValue(context, i.next(),
311                                       items.iterator(), converter))
312                       {
313                           _MessageUtils.addErrorMessage(context, this,
314                                           INVALID_MESSAGE_ID,
315                                           new Object[] {getId()});
316                           setValid(false);
317                       }
318                   }
319               }
320             }
321         }
322     }
323 
324     /**
325      * First part is identical to super.validate except the empty condition.
326      * Second part: iterate through UISelectItem and UISelectItems and check
327      *              current values against these items
328      */
329     public void validate(FacesContext context)
330     {
331         // TODO : Setting the submitted value to null in the super class causes a bug, if set to null, you'll get the following error :
332         // java.lang.NullPointerException at org.apache.myfaces.renderkit._SharedRendererUtils.getConvertedUISelectManyValue(_SharedRendererUtils.java:118)
333         super.validate(context);
334     }
335 
336     protected Object getConvertedValue(FacesContext context,
337                     Object submittedValue)
338     {
339         try
340         {
341             Renderer renderer = getRenderer(context);
342             if (renderer != null)
343             {
344                 return renderer
345                                 .getConvertedValue(context, this,
346                                                 submittedValue);
347             }
348             else if (submittedValue == null)
349             {
350                 return null;
351             }
352             else if (submittedValue instanceof String[])
353             {
354                 return _SharedRendererUtils.getConvertedUISelectManyValue(
355                                 context, this, (String[]) submittedValue);
356             }
357         }
358         catch (ConverterException e)
359         {
360             FacesMessage facesMessage = e.getFacesMessage();
361             if (facesMessage != null)
362             {
363                 context.addMessage(getClientId(context), facesMessage);
364             }
365             else
366             {
367                 _MessageUtils.addErrorMessage(context, this,
368                                 CONVERSION_MESSAGE_ID, new Object[] {getId()});
369             }
370             setValid(false);
371         }
372         return submittedValue;
373     }
374 
375     //------------------ GENERATED CODE BEGIN (do not modify!) --------------------
376 
377     public static final String COMPONENT_TYPE = "javax.faces.SelectMany";
378     public static final String COMPONENT_FAMILY = "javax.faces.SelectMany";
379     private static final String DEFAULT_RENDERER_TYPE = "javax.faces.Listbox";
380 
381     public UISelectMany()
382     {
383         setRendererType(DEFAULT_RENDERER_TYPE);
384     }
385 
386     public String getFamily()
387     {
388         return COMPONENT_FAMILY;
389     }
390 
391     //------------------ GENERATED CODE END ---------------------------------------
392 }