1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package javax.faces.component;
20
21 import java.lang.reflect.Array;
22 import java.util.Arrays;
23 import java.util.ArrayList;
24 import java.util.Collection;
25 import java.util.Collections;
26 import java.util.Iterator;
27 import java.util.List;
28
29 import javax.faces.application.FacesMessage;
30 import javax.faces.context.FacesContext;
31 import javax.faces.convert.ConverterException;
32 import javax.faces.el.ValueBinding;
33 import javax.faces.render.Renderer;
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56 public class UISelectMany extends UIInput
57 {
58 public static final String COMPONENT_TYPE = "javax.faces.SelectMany";
59 public static final String COMPONENT_FAMILY = "javax.faces.SelectMany";
60 public static final String INVALID_MESSAGE_ID = "javax.faces.component.UISelectMany.INVALID";
61
62 private static final String DEFAULT_RENDERER_TYPE = "javax.faces.Listbox";
63
64 public UISelectMany()
65 {
66 setRendererType(DEFAULT_RENDERER_TYPE);
67 }
68
69 public String getFamily()
70 {
71 return COMPONENT_FAMILY;
72 }
73
74 public Object[] getSelectedValues()
75 {
76 return (Object[]) getValue();
77 }
78
79 public void setSelectedValues(Object[] selectedValues)
80 {
81 setValue(selectedValues);
82 }
83
84 public ValueBinding getValueBinding(String name)
85 {
86 if (name == null)
87 throw new NullPointerException("name");
88 if (name.equals("selectedValues"))
89 {
90 return super.getValueBinding("value");
91 }
92 else
93 {
94 return super.getValueBinding(name);
95 }
96 }
97
98 public void setValueBinding(String name, ValueBinding binding)
99 {
100 if (name == null)
101 throw new NullPointerException("name");
102 if (name.equals("selectedValues"))
103 {
104 super.setValueBinding("value", binding);
105 }
106 else
107 {
108 super.setValueBinding(name, binding);
109 }
110 }
111
112
113
114
115 protected boolean compareValues(Object previous, Object value)
116 {
117 if (previous == null)
118 {
119
120 return value != null;
121 }
122 else if (value == null)
123 {
124
125 return previous != null;
126 }
127 else
128 {
129 if (previous instanceof Object[] && value instanceof Object[])
130 {
131 return compareObjectArrays((Object[]) previous,
132 (Object[]) value);
133 }
134 else if (previous instanceof List && value instanceof List)
135 {
136 return compareLists((List) previous, (List) value);
137 }
138 else if (previous.getClass().isArray()
139 && value.getClass().isArray())
140 {
141 return comparePrimitiveArrays(previous, value);
142 }
143 else
144 {
145
146 return true;
147 }
148 }
149 }
150
151 private boolean compareObjectArrays(Object[] previous, Object[] value)
152 {
153 int length = value.length;
154 if (previous.length != length)
155 {
156
157 return true;
158 }
159
160 boolean[] scoreBoard = new boolean[length];
161 for (int i = 0; i < length; i++)
162 {
163 Object p = previous[i];
164 boolean found = false;
165 for (int j = 0; j < length; j++)
166 {
167 if (scoreBoard[j] == false)
168 {
169 Object v = value[j];
170 if ((p == null && v == null)
171 || (p != null && v != null && p.equals(v)))
172 {
173 scoreBoard[j] = true;
174 found = true;
175 break;
176 }
177 }
178 }
179 if (!found)
180 {
181 return true;
182 }
183 }
184
185 return false;
186 }
187
188 private boolean compareLists(List previous, List value)
189 {
190 int length = value.size();
191 if (previous.size() != length)
192 {
193
194 return true;
195 }
196
197 boolean[] scoreBoard = new boolean[length];
198 for (int i = 0; i < length; i++)
199 {
200 Object p = previous.get(i);
201 boolean found = false;
202 for (int j = 0; j < length; j++)
203 {
204 if (scoreBoard[j] == false)
205 {
206 Object v = value.get(j);
207 if ((p == null && v == null)
208 || (p != null && v != null && p.equals(v)))
209 {
210 scoreBoard[j] = true;
211 found = true;
212 break;
213 }
214 }
215 }
216 if (!found)
217 {
218 return true;
219 }
220 }
221
222 return false;
223 }
224
225 private boolean comparePrimitiveArrays(Object previous, Object value)
226 {
227 int length = Array.getLength(value);
228 if (Array.getLength(previous) != length)
229 {
230
231 return true;
232 }
233
234 boolean[] scoreBoard = new boolean[length];
235 for (int i = 0; i < length; i++)
236 {
237 Object p = Array.get(previous, i);
238 boolean found = false;
239 for (int j = 0; j < length; j++)
240 {
241 if (scoreBoard[j] == false)
242 {
243 Object v = Array.get(value, j);
244 if ((p == null && v == null)
245 || (p != null && v != null && p.equals(v)))
246 {
247 scoreBoard[j] = true;
248 found = true;
249 break;
250 }
251 }
252 }
253 if (!found)
254 {
255 return true;
256 }
257 }
258
259 return false;
260 }
261
262 protected void validateValue(FacesContext context, Object convertedValue)
263 {
264 Iterator itemValues = _createItemValuesIterator(convertedValue);
265
266
267 if (itemValues == null)
268 {
269 _MessageUtils.addErrorMessage(context, this,
270 INVALID_MESSAGE_ID,
271 new Object[] {getId()});
272 setValid(false);
273 return;
274 }
275
276 boolean hasValues = itemValues.hasNext();
277
278
279 if (isRequired() && !hasValues)
280 {
281 _MessageUtils.addErrorMessage(context, this, REQUIRED_MESSAGE_ID,
282 new Object[] {getId()});
283 setValid(false);
284 return;
285 }
286
287
288 if (hasValues)
289 {
290 _ComponentUtils.callValidators(context, this, convertedValue);
291 }
292
293 if (isValid() && hasValues)
294 {
295 Collection items = new ArrayList();
296 for (Iterator iter = new _SelectItemsIterator(this); iter.hasNext();)
297 {
298 items.add( iter.next() );
299 }
300 while (itemValues.hasNext())
301 {
302 Object itemValue = itemValues.next();
303
304 if (!_SelectItemsUtil.matchValue(itemValue, items.iterator()))
305 {
306 _MessageUtils.addErrorMessage(context, this,
307 INVALID_MESSAGE_ID,
308 new Object[] {getId()});
309 setValid(false);
310 return;
311 }
312 }
313 }
314 }
315
316
317
318
319
320
321 public void validate(FacesContext context)
322 {
323
324
325 super.validate(context);
326 }
327
328 protected Object getConvertedValue(FacesContext context,
329 Object submittedValue)
330 {
331 try
332 {
333 Renderer renderer = getRenderer(context);
334 if (renderer != null)
335 {
336 return renderer
337 .getConvertedValue(context, this,
338 submittedValue);
339 }
340 else if (submittedValue == null)
341 {
342 return null;
343 }
344 else if (submittedValue instanceof String[])
345 {
346 return _SharedRendererUtils.getConvertedUISelectManyValue(
347 context, this, (String[]) submittedValue);
348 }
349 }
350 catch (ConverterException e)
351 {
352 FacesMessage facesMessage = e.getFacesMessage();
353 if (facesMessage != null)
354 {
355 context.addMessage(getClientId(context), facesMessage);
356 }
357 else
358 {
359 _MessageUtils.addErrorMessage(context, this,
360 CONVERSION_MESSAGE_ID, new Object[] {getId()});
361 }
362 setValid(false);
363 }
364 return submittedValue;
365 }
366
367 private Iterator _createItemValuesIterator(Object convertedValue)
368 {
369 if (convertedValue == null)
370 {
371 return Collections.EMPTY_LIST.iterator();
372 }
373 else
374 {
375 Class valueClass = convertedValue.getClass();
376 if (valueClass.isArray())
377 {
378 return new _PrimitiveArrayIterator(convertedValue);
379 }
380 else if (convertedValue instanceof Object[])
381 {
382 Object[] values = (Object[]) convertedValue;
383 return Arrays.asList(values).iterator();
384 }
385 else if (convertedValue instanceof List)
386 {
387 List values = (List) convertedValue;
388 return values.iterator();
389 }
390 else
391 {
392
393 return null;
394 }
395 }
396 }
397 }