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