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.ArrayList;
23 import java.util.Arrays;
24 import java.util.Collection;
25 import java.util.Collections;
26 import java.util.Iterator;
27 import java.util.List;
28 import javax.el.ValueExpression;
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 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFComponent;
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52 @JSFComponent(defaultRendererType = "javax.faces.Listbox")
53 public class UISelectMany extends UIInput
54 {
55 public static final String COMPONENT_TYPE = "javax.faces.SelectMany";
56 public static final String COMPONENT_FAMILY = "javax.faces.SelectMany";
57
58 public static final String INVALID_MESSAGE_ID = "javax.faces.component.UISelectMany.INVALID";
59
60 public UISelectMany()
61 {
62 setRendererType("javax.faces.Listbox");
63 }
64
65 @Override
66 public String getFamily()
67 {
68 return COMPONENT_FAMILY;
69 }
70
71 public Object[] getSelectedValues()
72 {
73 return (Object[]) getValue();
74 }
75
76 public void setSelectedValues(Object[] selectedValues)
77 {
78 setValue(selectedValues);
79 }
80
81
82
83
84 public ValueBinding getValueBinding(String name)
85 {
86 if (name == null)
87 {
88 throw new NullPointerException("name");
89 }
90 if (name.equals("selectedValues"))
91 {
92 return super.getValueBinding("value");
93 }
94 else
95 {
96 return super.getValueBinding(name);
97 }
98 }
99
100
101
102
103 public void setValueBinding(String name, ValueBinding binding)
104 {
105 if (name == null)
106 {
107 throw new NullPointerException("name");
108 }
109 if (name.equals("selectedValues"))
110 {
111 super.setValueBinding("value", binding);
112 }
113 else
114 {
115 super.setValueBinding(name, binding);
116 }
117 }
118
119 public ValueExpression getValueExpression(String name)
120 {
121 if (name == null)
122 {
123 throw new NullPointerException("name");
124 }
125 if (name.equals("selectedValues"))
126 {
127 return super.getValueExpression("value");
128 }
129 else
130 {
131 return super.getValueExpression(name);
132 }
133 }
134
135 public void setValueExpression(String name, ValueExpression binding)
136 {
137 if (name == null)
138 {
139 throw new NullPointerException("name");
140 }
141 if (name.equals("selectedValues"))
142 {
143 super.setValueExpression("value", binding);
144 }
145 else
146 {
147 super.setValueExpression(name, binding);
148 }
149 }
150
151
152
153
154 protected boolean compareValues(Object previous, Object value)
155 {
156 if (previous == null)
157 {
158
159 return value != null;
160 }
161 else if (value == null)
162 {
163
164 return previous != null;
165 }
166 else
167 {
168 if (previous instanceof Object[] && value instanceof Object[])
169 {
170 return compareObjectArrays((Object[]) previous, (Object[]) value);
171 }
172 else if (previous instanceof List && value instanceof List)
173 {
174 return compareLists((List) previous, (List) value);
175 }
176 else if (previous.getClass().isArray() && value.getClass().isArray())
177 {
178 return comparePrimitiveArrays(previous, value);
179 }
180 else
181 {
182
183 return true;
184 }
185 }
186 }
187
188 private boolean compareObjectArrays(Object[] previous, Object[] value)
189 {
190 int length = value.length;
191 if (previous.length != 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[i];
201 boolean found = false;
202 for (int j = 0; j < length; j++)
203 {
204 if (scoreBoard[j] == false)
205 {
206 Object v = value[j];
207 if ((p == null && v == null) || (p != null && v != null && p.equals(v)))
208 {
209 scoreBoard[j] = true;
210 found = true;
211 break;
212 }
213 }
214 }
215 if (!found)
216 {
217 return true;
218 }
219 }
220
221 return false;
222 }
223
224 private boolean compareLists(List previous, List value)
225 {
226 int length = value.size();
227 if (previous.size() != length)
228 {
229
230 return true;
231 }
232
233 boolean[] scoreBoard = new boolean[length];
234 for (int i = 0; i < length; i++)
235 {
236 Object p = previous.get(i);
237 boolean found = false;
238 for (int j = 0; j < length; j++)
239 {
240 if (scoreBoard[j] == false)
241 {
242 Object v = value.get(j);
243 if ((p == null && v == null) || (p != null && v != null && p.equals(v)))
244 {
245 scoreBoard[j] = true;
246 found = true;
247 break;
248 }
249 }
250 }
251 if (!found)
252 {
253 return true;
254 }
255 }
256
257 return false;
258 }
259
260 private boolean comparePrimitiveArrays(Object previous, Object value)
261 {
262 int length = Array.getLength(value);
263 if (Array.getLength(previous) != length)
264 {
265
266 return true;
267 }
268
269 boolean[] scoreBoard = new boolean[length];
270 for (int i = 0; i < length; i++)
271 {
272 Object p = Array.get(previous, i);
273 boolean found = false;
274 for (int j = 0; j < length; j++)
275 {
276 if (scoreBoard[j] == false)
277 {
278 Object v = Array.get(value, j);
279 if ((p == null && v == null) || (p != null && v != null && p.equals(v)))
280 {
281 scoreBoard[j] = true;
282 found = true;
283 break;
284 }
285 }
286 }
287 if (!found)
288 {
289 return true;
290 }
291 }
292
293 return false;
294 }
295
296 protected void validateValue(FacesContext context, Object convertedValue)
297 {
298 Iterator itemValues = _createItemValuesIterator(convertedValue);
299
300
301 if (itemValues == null)
302 {
303 _MessageUtils.addErrorMessage(context, this, INVALID_MESSAGE_ID, new Object[]
304 { _MessageUtils.getLabel(context, this) });
305 setValid(false);
306 return;
307 }
308
309 boolean hasValues = itemValues.hasNext();
310
311
312 if (isRequired() && !hasValues)
313 {
314 if (getRequiredMessage() != null)
315 {
316 String requiredMessage = getRequiredMessage();
317 context.addMessage(this.getClientId(context), new FacesMessage(
318 FacesMessage.SEVERITY_ERROR, requiredMessage, requiredMessage));
319 }
320 else
321 {
322 _MessageUtils.addErrorMessage(context, this, REQUIRED_MESSAGE_ID, new Object[]
323 { _MessageUtils.getLabel(context, this) });
324 }
325 setValid(false);
326 return;
327 }
328
329
330 if (hasValues)
331 {
332 _ComponentUtils.callValidators(context, this, convertedValue);
333 }
334
335 if (isValid() && hasValues)
336 {
337
338
339 _SelectItemsUtil._ValueConverter converter = new _SelectItemsUtil._ValueConverter()
340 {
341 public Object getConvertedValue(FacesContext context, String value)
342 {
343 Object convertedValue = UISelectMany.this.getConvertedValue(context,
344 new String[]
345 { value });
346 if (convertedValue instanceof Collection)
347 {
348 Iterator iter = ((Collection) convertedValue).iterator();
349 if (iter.hasNext())
350 {
351 return iter.next();
352 }
353 return null;
354 }
355 return ((Object[]) convertedValue)[0];
356 }
357 };
358
359 Collection items = new ArrayList();
360 for (Iterator iter = new _SelectItemsIterator(this); iter.hasNext();)
361 {
362 items.add(iter.next());
363 }
364 while (itemValues.hasNext())
365 {
366 Object itemValue = itemValues.next();
367
368 if (!_SelectItemsUtil.matchValue(context, itemValue, items.iterator(), converter))
369 {
370 _MessageUtils.addErrorMessage(context, this, INVALID_MESSAGE_ID, new Object[]
371 { _MessageUtils.getLabel(context, this) });
372 setValid(false);
373 return;
374 }
375 }
376 }
377 }
378
379
380
381
382
383 public void validate(FacesContext context)
384 {
385
386
387
388
389 super.validate(context);
390 }
391
392 protected Object getConvertedValue(FacesContext context, Object submittedValue)
393 {
394 try
395 {
396 Renderer renderer = getRenderer(context);
397 if (renderer != null)
398 {
399 return renderer.getConvertedValue(context, this, submittedValue);
400 }
401 else if (submittedValue == null)
402 {
403 return null;
404 }
405 else if (submittedValue instanceof String[])
406 {
407 return _SharedRendererUtils.getConvertedUISelectManyValue(context, this,
408 (String[]) submittedValue);
409 }
410 }
411 catch (ConverterException e)
412 {
413 FacesMessage facesMessage = e.getFacesMessage();
414 if (facesMessage != null)
415 {
416 context.addMessage(getClientId(context), facesMessage);
417 }
418 else
419 {
420 _MessageUtils.addErrorMessage(context, this, CONVERSION_MESSAGE_ID, new Object[]
421 { _MessageUtils.getLabel(context, this) });
422 }
423 setValid(false);
424 }
425 return submittedValue;
426 }
427
428 private Iterator _createItemValuesIterator(Object convertedValue)
429 {
430 if (convertedValue == null)
431 {
432 return Collections.EMPTY_LIST.iterator();
433 }
434 else
435 {
436 Class valueClass = convertedValue.getClass();
437 if (valueClass.isArray())
438 {
439 return new _PrimitiveArrayIterator(convertedValue);
440 }
441 else if (convertedValue instanceof Object[])
442 {
443 Object[] values = (Object[]) convertedValue;
444 return Arrays.asList(values).iterator();
445 }
446 else if (convertedValue instanceof List)
447 {
448 List values = (List) convertedValue;
449 return values.iterator();
450 }
451 else
452 {
453
454 return null;
455 }
456 }
457 }
458 }