1
2
3
4 package org.rcfaces.core.internal.tools;
5
6 import java.lang.reflect.Array;
7 import java.lang.reflect.Method;
8 import java.util.ArrayList;
9 import java.util.Arrays;
10 import java.util.Collection;
11 import java.util.Collections;
12 import java.util.HashMap;
13 import java.util.HashSet;
14 import java.util.Iterator;
15 import java.util.List;
16 import java.util.Map;
17 import java.util.Set;
18
19 import javax.faces.FacesException;
20 import javax.faces.component.UIComponent;
21 import javax.faces.context.FacesContext;
22 import javax.faces.model.DataModel;
23
24 import org.apache.commons.logging.Log;
25 import org.apache.commons.logging.LogFactory;
26 import org.rcfaces.core.internal.RcfacesContext;
27 import org.rcfaces.core.internal.capability.IGridComponent;
28 import org.rcfaces.core.internal.util.StringList;
29 import org.rcfaces.core.lang.IAdaptable;
30 import org.rcfaces.core.lang.OrderedSet;
31 import org.rcfaces.core.model.ICommitableObject;
32 import org.rcfaces.core.model.IIndexesModel;
33 import org.rcfaces.core.model.IRangeDataModel;
34
35
36
37
38
39
40 public class CollectionTools {
41 private static final String REVISION = "$Revision: 1.8 $";
42
43 private static final Log LOG = LogFactory.getLog(CollectionTools.class);
44
45 protected static final Object[] EMPTY_VALUES = new Object[0];
46
47 private static final Object[] EMPTY_STRING_ARRAY = new String[0];
48
49 private static final boolean SORT_INDICES = true;
50
51 private static final Map IMPLEMENTATION_TYPES = new HashMap(64);
52 static {
53 IMPLEMENTATION_TYPES.put(Collection.class, ArrayList.class);
54 IMPLEMENTATION_TYPES.put(List.class, ArrayList.class);
55 IMPLEMENTATION_TYPES.put(Set.class, HashSet.class);
56 IMPLEMENTATION_TYPES.put(Map.class, HashMap.class);
57
58 IMPLEMENTATION_TYPES.put(IIndexesModel.class, ArrayIndexesModel.class);
59 }
60
61 private static final IValuesAccessor NULL_VALUES_ACCESSOR = new AbstractValuesAccessor() {
62 private static final String REVISION = "$Revision: 1.8 $";
63
64 public int getCount(Object value) {
65 return 0;
66 }
67
68 public Object getFirst(Object value, Object refValues) {
69 return null;
70 }
71
72 public Object[] listValues(Object value, Object refValues) {
73 return EMPTY_VALUES;
74 }
75 };
76
77 private static final IValuesAccessor ARRAY_VALUES_ACCESSOR = new AbstractValuesAccessor() {
78 private static final String REVISION = "$Revision: 1.8 $";
79
80 public int getCount(Object array) {
81 return Array.getLength(array);
82 }
83
84 public Object getFirst(Object array, Object refValues) {
85 if (getCount(array) < 1) {
86 return null;
87 }
88
89 return Array.get(array, 0);
90 }
91
92 public Object[] listValues(Object array, Object refValues) {
93 return (Object[]) array;
94 }
95 };
96
97 private static final IValuesAccessor STRING_VALUES_ACCESSOR = new AbstractValuesAccessor() {
98 private static final String REVISION = "$Revision: 1.8 $";
99
100 public int getCount(Object array) {
101 return StringList.countTokens((String) array);
102 }
103
104 public Object getFirst(Object array, Object refValues) {
105 return StringList.getFirstToken((String) array);
106 }
107
108 public Object[] listValues(Object array, Object refValues) {
109 return convertToObjectArray(array);
110 }
111
112 };
113
114 private static final IValuesAccessor COLLECTION_VALUES_ACCESSOR = new AbstractValuesAccessor() {
115 private static final String REVISION = "$Revision: 1.8 $";
116
117 public int getCount(Object collection) {
118 return ((Collection) collection).size();
119 }
120
121 public Object getFirst(Object collection, Object refValues) {
122 Collection cl = (Collection) collection;
123
124 if (cl.isEmpty()) {
125 return null;
126 }
127
128 if (cl instanceof List) {
129 return ((List) cl).get(0);
130 }
131
132 return cl.iterator().next();
133 }
134
135 public Object[] listValues(Object collection, Object refValues) {
136 return ((Collection) collection).toArray();
137 }
138 };
139
140 private static final IValuesAccessor MAP_VALUES_ACCESSOR = new AbstractValuesAccessor() {
141 private static final String REVISION = "$Revision: 1.8 $";
142
143 public int getCount(Object map) {
144 return ((Map) map).size();
145 }
146
147 public Object getFirst(Object map, Object refValues) {
148 return ((Map) map).keySet().iterator().next();
149 }
150
151 public Object[] listValues(Object map, Object refValues) {
152 return ((Map) map).keySet().toArray();
153 }
154 };
155
156 private static final IValuesAccessor INDEXES_MODEL_VALUES_ACCESSOR = new AbstractValuesAccessor() {
157 private static final String REVISION = "$Revision: 1.8 $";
158
159 public int getCount(Object indexesModel) {
160 return ((IIndexesModel) indexesModel).countIndexes();
161 }
162
163 public Object getFirst(Object indexesModel, Object refValues) {
164 return ((IIndexesModel) indexesModel)
165 .getFirstSelectedObject(refValues);
166 }
167
168 public Object[] listValues(Object indexesModel, Object refValues) {
169 return ((IIndexesModel) indexesModel).listSelectedObjects(null,
170 refValues);
171 }
172 };
173
174 protected static IValuesAccessor getValuesAccessor(Object values,
175 Class providerClass, IValuesAccessor providerValuesAccessor,
176 boolean useValue) {
177
178 if (values == null) {
179 if (useValue == false) {
180 return null;
181 }
182 return NULL_VALUES_ACCESSOR;
183 }
184
185 if (values.getClass().isArray()) {
186 if (useValue == false) {
187 return null;
188 }
189 return ARRAY_VALUES_ACCESSOR;
190 }
191
192 if (values instanceof String) {
193 if (useValue == false) {
194 return null;
195 }
196 return STRING_VALUES_ACCESSOR;
197 }
198
199 if (values instanceof Collection) {
200 if (useValue == false) {
201 return null;
202 }
203 return COLLECTION_VALUES_ACCESSOR;
204 }
205
206 if (values instanceof Map) {
207 if (useValue == false) {
208 return null;
209 }
210 return MAP_VALUES_ACCESSOR;
211 }
212
213 if (values instanceof IIndexesModel) {
214 if (useValue == false) {
215 return null;
216 }
217 return INDEXES_MODEL_VALUES_ACCESSOR;
218 }
219
220 if (providerClass == null) {
221 return null;
222 }
223
224 if (values.getClass().isAssignableFrom(providerClass)) {
225 return providerValuesAccessor;
226 }
227
228 if (values instanceof IAdaptable) {
229 Object provider = ((IAdaptable) values).getAdapter(providerClass,
230 null);
231
232 if (provider != null) {
233 return new ProviderValuesAccessor(providerValuesAccessor,
234 provider);
235 }
236 }
237
238 Object provider = RcfacesContext.getCurrentInstance()
239 .getAdapterManager().getAdapter(values, providerClass, null);
240
241 if (provider != null) {
242 return new ProviderValuesAccessor(providerValuesAccessor, provider);
243 }
244
245 return null;
246 }
247
248 public static Object getEmptyValues() {
249 return EMPTY_VALUES;
250 }
251
252 protected static Object[] convertToObjectArray(Object values) {
253 if (values == null) {
254 return null;
255 }
256
257 if (values instanceof String) {
258 Set set = valuesToSet(values, true);
259 if (set.isEmpty()) {
260 return EMPTY_STRING_ARRAY;
261 }
262
263 return set.toArray(new String[set.size()]);
264 }
265
266 if (values instanceof Object[]) {
267 return (Object[]) values;
268 }
269
270 if (values instanceof Collection) {
271 return ((Collection) values).toArray();
272 }
273
274 if (values instanceof Map) {
275 return ((Map) values).keySet().toArray();
276 }
277
278 throw new FacesException("Can not convert object '" + values
279 + "' to object array.");
280 }
281
282 private static Object createNewValues(UIComponent component,
283 IValuesAccessor valuesAccessor) {
284 Class type = valuesAccessor.getComponentValuesType(null, component);
285 if (type == null) {
286
287 if ((component instanceof IComponentValueTypeCapability) == false) {
288 throw new FacesException(
289 "Can not identify IComponentValueType for component id='"
290 + component.getId() + " renderType='"
291 + component.getRendererType() + "'");
292 }
293
294 IComponentValueType componentValueType = ((IComponentValueTypeCapability) component)
295 .getComponentValueType();
296
297 Object values = componentValueType.createNewValue(component);
298
299 valuesAccessor.setComponentValues(component, values);
300
301 return values;
302 }
303
304 if (type.isArray()) {
305 Object values = Array.newInstance(type.getComponentType(), 0);
306
307 valuesAccessor.setComponentValues(component, values);
308
309 return values;
310 }
311
312 Class implementationType = (Class) IMPLEMENTATION_TYPES.get(type);
313 if (implementationType != null) {
314 type = implementationType;
315 }
316
317 Object values;
318 try {
319 values = type.newInstance();
320
321 } catch (Throwable th) {
322 throw new FacesException("Can not instanciate values for type '"
323 + type + "'", th);
324 }
325
326 valuesAccessor.setComponentValues(component, values);
327
328 return values;
329 }
330
331 public static void select(UIComponent component,
332 IValuesAccessor valuesAccessor, int indices[]) {
333 Object values = valuesAccessor.getComponentValues(component);
334
335 if (values == null) {
336 values = createNewValues(component, valuesAccessor);
337 }
338
339 if (values instanceof IIndexesModel) {
340 IIndexesModel indexesModel = cloneIndexModel(component,
341 valuesAccessor, (IIndexesModel) values);
342
343 for (int i = 0; i < indices.length; i++) {
344 indexesModel.addIndex(indices[i]);
345 }
346
347 return;
348 }
349
350 List rowDatas = getRowDatas((IGridComponent) component, indices);
351 if (rowDatas.isEmpty()) {
352 return;
353 }
354
355 select(component, valuesAccessor, values, rowDatas);
356 }
357
358 public static void select(UIComponent component,
359 IValuesAccessor valuesAccessor, int start, int end) {
360
361 Object values = valuesAccessor.getComponentValues(component);
362
363 if (values == null) {
364 values = createNewValues(component, valuesAccessor);
365 }
366
367 if (values instanceof IIndexesModel) {
368 IIndexesModel indexesModel = cloneIndexModel(component,
369 valuesAccessor, (IIndexesModel) values);
370
371 for (; start < end; start++) {
372 indexesModel.addIndex(start);
373 }
374
375 return;
376 }
377
378 List rowDatas = getRowDatas((IGridComponent) component, start, end);
379 if (rowDatas.isEmpty()) {
380 return;
381 }
382
383 select(component, valuesAccessor, values, rowDatas);
384 }
385
386 public static void select(UIComponent component,
387 IValuesAccessor valuesAccessor, int index) {
388
389 Object values = valuesAccessor.getComponentValues(component);
390
391 if (values == null) {
392 values = createNewValues(component, valuesAccessor);
393 }
394
395 if (values instanceof IIndexesModel) {
396 IIndexesModel indexesModel = cloneIndexModel(component,
397 valuesAccessor, (IIndexesModel) values);
398
399 indexesModel.addIndex(index);
400 return;
401 }
402
403 Object rowData = getRowData((IGridComponent) component, index);
404 if (rowData == null) {
405 LOG.error("No rowData for index='" + index + "'.");
406 return;
407 }
408
409 if (LOG.isDebugEnabled()) {
410 LOG.debug("Select index=" + index + " => " + rowData
411 + " selectedValues=" + values);
412 }
413
414 select(component, valuesAccessor, values, Collections
415 .singleton(rowData));
416 }
417
418 public static void selectAll(UIComponent component,
419 IValuesAccessor valuesAccessor) {
420
421 if ((component instanceof IGridComponent) == false) {
422 throw new UnsupportedOperationException(
423 "Can not list all values of component '"
424 + component.getId() + "'.");
425 }
426
427 Object values = valuesAccessor.getComponentValues(component);
428
429 if (values == null) {
430 values = createNewValues(component, valuesAccessor);
431 }
432
433 if (values instanceof IIndexesModel) {
434 IIndexesModel indexesModel = cloneIndexModel(component,
435 valuesAccessor, (IIndexesModel) values);
436
437 int rowCount = getRowCount(component);
438 for (int i = 0; i < rowCount; i++) {
439 indexesModel.addIndex(i);
440 }
441
442 return;
443 }
444
445 List rowDatas = getRowDatas((IGridComponent) component);
446 if (rowDatas.isEmpty()) {
447 return;
448 }
449
450 select(component, valuesAccessor, values, rowDatas);
451 }
452
453 public static void select(UIComponent component,
454 IValuesAccessor valuesAccessor, Object rowValue) {
455
456 Object values = valuesAccessor.getComponentValues(component);
457
458 if (values == null) {
459 values = createNewValues(component, valuesAccessor);
460 }
461
462 if (values instanceof IIndexesModel) {
463 int index = searchIndexIntoDataModel((IGridComponent) component,
464 rowValue);
465 if (index < 0) {
466 return;
467 }
468
469 select(component, valuesAccessor, index);
470
471 return;
472 }
473
474 select(component, valuesAccessor, values, Collections
475 .singletonList(rowValue));
476 }
477
478 private static Object select(UIComponent component,
479 IValuesAccessor valuesAccessor, Object values, Collection rowDatas) {
480
481 if (values.getClass().isArray()) {
482
483 int length = Array.getLength(values);
484
485 List l = null;
486
487 next_data: for (Iterator it = rowDatas.iterator(); it.hasNext();) {
488 Object rowData = it.next();
489
490 for (int i = 0; i < length; i++) {
491 if (Array.get(values, i).equals(rowData) == false) {
492 continue;
493 }
494
495 continue next_data;
496 }
497
498 if (l == null) {
499 l = new ArrayList();
500
501 } else if (l.contains(rowData)) {
502 continue;
503 }
504
505 l.add(rowData);
506 }
507
508 if (l == null) {
509 return values;
510 }
511
512 Class type = values.getClass().getComponentType();
513
514 Object newValues = Array.newInstance(type, length + l.size());
515
516 System.arraycopy(values, 0, newValues, 0, length);
517
518 for (Iterator it = l.iterator(); it.hasNext(); length++) {
519 Array.set(newValues, length, it.next());
520 }
521
522 valuesAccessor.setComponentValues(component, newValues);
523
524 return newValues;
525 }
526
527 if (values instanceof String) {
528 Set set = valuesToSet(values, false);
529
530 set.addAll(rowDatas);
531
532 String newValues = StringList.joinTokens(set);
533
534 if (newValues.equals(values)) {
535 return values;
536 }
537
538 valuesAccessor.setComponentValues(component, newValues);
539
540 return newValues;
541 }
542
543 if (values instanceof Collection) {
544 Collection collection = cloneCollection(component, valuesAccessor,
545 (Collection) values);
546
547 if (collection instanceof Set) {
548 collection.addAll(rowDatas);
549 return collection;
550 }
551
552 for (Iterator it = rowDatas.iterator(); it.hasNext();) {
553 Object rowData = it.next();
554
555 if (collection.contains(rowData)) {
556 continue;
557 }
558
559 collection.add(rowData);
560 }
561
562 return collection;
563 }
564
565 throw new FacesException("Select index is not implemented for values="
566 + values);
567 }
568
569 private static Collection cloneCollection(UIComponent component,
570 IValuesAccessor valuesAccessor, Collection collection) {
571
572 boolean copy = true;
573
574 if (collection instanceof ICommitableObject) {
575 copy = ((ICommitableObject) collection).isCommited();
576 }
577
578 if (copy == false) {
579 return collection;
580 }
581
582 try {
583 Method method = collection.getClass().getMethod("clone",
584 (Class[]) null);
585
586 collection = (Collection) method
587 .invoke(collection, (Object[]) null);
588
589 } catch (Throwable th) {
590 LOG.info("Can not copy the collection ! ("
591 + collection.getClass().getName() + ")", th);
592 }
593
594 valuesAccessor.setComponentValues(component, collection);
595
596 return collection;
597 }
598
599 private static int getRowCount(UIComponent component) {
600
601 IGridComponent gridComponent = (IGridComponent) component;
602
603 int index = gridComponent.getRowCount();
604
605 if (index >= 0) {
606 return index;
607 }
608
609 try {
610 for (index = 0;; index++) {
611 gridComponent.setRowIndex(index);
612
613 if (gridComponent.isRowAvailable()) {
614 return index;
615 }
616 }
617 } finally {
618 gridComponent.setRowIndex(-1);
619 }
620 }
621
622 public static void deselectAll(UIComponent component,
623 IValuesAccessor valuesAccessor) {
624
625 Object values = valuesAccessor.getComponentValues(component);
626 if (values == null) {
627 return;
628 }
629
630 if (values instanceof IIndexesModel) {
631 IIndexesModel indexesModel = cloneIndexModel(component,
632 valuesAccessor, (IIndexesModel) values);
633
634 indexesModel.clearIndexes();
635 return;
636 }
637
638 if (values instanceof Collection) {
639 Collection collection = cloneCollection(component, valuesAccessor,
640 (Collection) values);
641
642 collection.clear();
643 return;
644 }
645
646 if (values instanceof String) {
647 if ("".equals(values)) {
648 return;
649 }
650
651 valuesAccessor.setComponentValues(component, "");
652
653 return;
654 }
655
656 if (values instanceof Object[]) {
657 if (Array.getLength(values) == 0) {
658 return;
659 }
660
661 Class type = values.getClass().getComponentType();
662
663 values = Array.newInstance(type, 0);
664
665 valuesAccessor.setComponentValues(component, values);
666 return;
667 }
668
669 throw new FacesException("Deselect all is not implemented for values="
670 + values);
671 }
672
673 public static void deselect(UIComponent component,
674 IValuesAccessor valuesAccessor, Object rowValue) {
675
676 Object values = valuesAccessor.getComponentValues(component);
677
678 if (values == null) {
679 return;
680 }
681
682 if (values instanceof IIndexesModel) {
683 int index = searchIndexIntoDataModel((IGridComponent) component,
684 rowValue);
685
686 if (index < 0) {
687 return;
688 }
689
690 IIndexesModel indexesModel = cloneIndexModel(component,
691 valuesAccessor, (IIndexesModel) values);
692
693 indexesModel.removeIndex(index);
694
695 return;
696 }
697
698 deselect(component, valuesAccessor, values, Collections
699 .singletonList(rowValue));
700 }
701
702 public static void deselect(UIComponent component,
703 IValuesAccessor valuesAccessor, int index) {
704
705 Object values = valuesAccessor.getComponentValues(component);
706
707 if (values == null) {
708 return;
709 }
710
711 if (values instanceof IIndexesModel) {
712 IIndexesModel indexesModel = cloneIndexModel(component,
713 valuesAccessor, (IIndexesModel) values);
714
715 indexesModel.removeIndex(index);
716 return;
717 }
718
719 Object rowData = getRowData((IGridComponent) component, index);
720
721 if (rowData == null) {
722 LOG.error("No rowData for index='" + index + "'.");
723 return;
724 }
725
726 if (LOG.isDebugEnabled()) {
727 LOG.debug("Deselect index=" + index + " => " + rowData
728 + " selectedValues=" + values);
729 }
730
731 deselect(component, valuesAccessor, values, Collections
732 .singleton(rowData));
733 }
734
735 public static void deselect(UIComponent component,
736 IValuesAccessor valuesAccessor, int indices[]) {
737
738 if (indices == null || indices.length < 1) {
739 return;
740 }
741
742 Object values = valuesAccessor.getComponentValues(component);
743
744 if (values == null) {
745 return;
746 }
747
748 if (values instanceof IIndexesModel) {
749 IIndexesModel indexesModel = cloneIndexModel(component,
750 valuesAccessor, (IIndexesModel) values);
751
752 for (int i = 0; i < indices.length; i++) {
753 indexesModel.removeIndex(indices[i]);
754 }
755
756 return;
757 }
758
759 List rowDatas = getRowDatas((IGridComponent) component, indices);
760 if (rowDatas.isEmpty()) {
761 return;
762 }
763
764 deselect(component, valuesAccessor, values, rowDatas);
765 }
766
767 public static void deselect(UIComponent component,
768 IValuesAccessor valuesAccessor, int start, int end) {
769
770 Object values = valuesAccessor.getComponentValues(component);
771
772 if (values == null) {
773 return;
774 }
775
776 if (values instanceof IIndexesModel) {
777 IIndexesModel indexesModel = cloneIndexModel(component,
778 valuesAccessor, (IIndexesModel) values);
779
780 for (; start < end; start++) {
781 indexesModel.removeIndex(start);
782 }
783
784 return;
785 }
786
787 List rowDatas = getRowDatas((IGridComponent) component, start, end);
788 if (rowDatas.isEmpty()) {
789 return;
790 }
791
792 deselect(component, valuesAccessor, values, rowDatas);
793 }
794
795 private static Object deselect(UIComponent component,
796 IValuesAccessor valuesAccessor, Object values, Collection rowDatas) {
797
798 if (values.getClass().isArray()) {
799
800 int length = Array.getLength(values);
801 if (length == 0) {
802 return values;
803 }
804
805 for (Iterator it = rowDatas.iterator(); it.hasNext();) {
806 Object rowData = it.next();
807
808 for (int i = 0; i < length;) {
809 if (Array.get(values, i).equals(rowData) == false) {
810 i++;
811 continue;
812 }
813
814 length--;
815 if (i >= length) {
816 break;
817 }
818
819 System.arraycopy(values, i + 1, values, i, length - i);
820 }
821 }
822
823 if (Array.getLength(values) == length) {
824
825 return values;
826 }
827
828 Class type = values.getClass().getComponentType();
829
830 Object newValues = Array.newInstance(type, length);
831 if (length > 0) {
832 System.arraycopy(values, 0, newValues, 0, length);
833 }
834
835 valuesAccessor.setComponentValues(component, newValues);
836
837 return newValues;
838 }
839
840 if (values instanceof String) {
841 Set set = valuesToSet(values, false);
842
843 set.removeAll(rowDatas);
844
845 String newValues = StringList.joinTokens(set);
846
847 if (newValues.equals(values)) {
848 return values;
849 }
850
851 valuesAccessor.setComponentValues(component, newValues);
852
853 return newValues;
854 }
855
856 if (values instanceof Collection) {
857 Collection collection = cloneCollection(component, valuesAccessor,
858 (Collection) values);
859
860 if (collection instanceof Set) {
861 collection.removeAll(rowDatas);
862 return collection;
863 }
864
865 for (Iterator it = rowDatas.iterator(); it.hasNext();) {
866 Object rowData = it.next();
867
868 collection.remove(rowData);
869 }
870
871 return collection;
872 }
873
874 throw new FacesException(
875 "Deselect index is not implemented for selectedValues="
876 + values);
877 }
878
879 private static IIndexesModel cloneIndexModel(UIComponent component,
880 IValuesAccessor valuesAccessor, IIndexesModel indexesModel) {
881
882 boolean copy = true;
883
884 if (indexesModel instanceof ICommitableObject) {
885 copy = ((ICommitableObject) indexesModel).isCommited();
886 }
887
888 if (copy == false) {
889 return indexesModel;
890 }
891
892 indexesModel = indexesModel.copy();
893 valuesAccessor.setComponentValues(component, indexesModel);
894
895 return indexesModel;
896 }
897
898 private static List getRowDatas(IGridComponent gridComponent, int[] indices) {
899
900 int rowCount = gridComponent.getRowCount();
901 if (rowCount > 0) {
902 DataModel dataModel = gridComponent.getDataModelValue();
903
904 if (dataModel instanceof IRangeDataModel) {
905 ((IRangeDataModel) dataModel).setRowRange(0, rowCount);
906 }
907 }
908
909 if (SORT_INDICES) {
910 indices = (int[]) indices.clone();
911 Arrays.sort(indices);
912 }
913
914 List rowDatas = null;
915 try {
916 for (int i = 0; i < indices.length; i++) {
917 int index = indices[i];
918 gridComponent.setRowIndex(index);
919 if (gridComponent.isRowAvailable() == false) {
920 LOG.error("Row not available for index='" + index + "'.");
921 continue;
922 }
923
924 Object rowData = gridComponent.getRowData();
925
926 if (rowData == null) {
927 LOG.error("No rowData for index='" + index + "'.");
928 continue;
929 }
930
931 if (LOG.isDebugEnabled()) {
932 LOG.debug("Get row at index=" + index + " => " + rowData);
933 }
934
935 if (rowDatas == null) {
936 rowDatas = new ArrayList(indices.length - i);
937 }
938 rowDatas.add(rowData);
939 }
940
941 } finally {
942 gridComponent.setRowIndex(-1);
943 }
944
945 if (rowDatas == null) {
946 return Collections.EMPTY_LIST;
947 }
948
949 return rowDatas;
950 }
951
952 private static Object getRowData(IGridComponent gridComponent, int index) {
953
954 DataModel dataModel = gridComponent.getDataModelValue();
955
956 if (dataModel instanceof IRangeDataModel) {
957 ((IRangeDataModel) dataModel).setRowRange(index, 1);
958 }
959
960 Object rowData = null;
961 gridComponent.setRowIndex(index);
962 try {
963 if (gridComponent.isRowAvailable() == false) {
964 LOG.error("Row not available for index='" + index + "'.");
965 return null;
966 }
967
968 rowData = gridComponent.getRowData();
969
970 if (LOG.isDebugEnabled()) {
971 LOG.debug("Get row at index=" + index + " => " + rowData);
972 }
973
974 } finally {
975 gridComponent.setRowIndex(-1);
976 }
977
978 if (rowData == null) {
979 LOG.error("RowData is null for index='" + index + "'.");
980 }
981
982 return rowData;
983 }
984
985 private static List getRowDatas(IGridComponent gridComponent) {
986
987 int rowCount = gridComponent.getRowCount();
988 if (rowCount > 0) {
989 DataModel dataModel = gridComponent.getDataModelValue();
990
991 if (dataModel instanceof IRangeDataModel) {
992 ((IRangeDataModel) dataModel).setRowRange(0, rowCount);
993 }
994 }
995
996 List rowDatas = null;
997 try {
998 for (int index = 0;; index++) {
999 gridComponent.setRowIndex(index);
1000
1001 if (gridComponent.isRowAvailable() == false) {
1002 LOG.debug("Row not available for index='" + index + "'.");
1003 break;
1004 }
1005
1006 Object rowData = gridComponent.getRowData();
1007
1008 if (rowData == null) {
1009 LOG.debug("RowData is null for index='" + index + "'.");
1010 continue;
1011 }
1012
1013 if (rowDatas == null) {
1014 int size = rowCount - index;
1015
1016 if (size < 8) {
1017 size = 8;
1018 }
1019
1020 rowDatas = new ArrayList(size);
1021 }
1022
1023 if (LOG.isDebugEnabled()) {
1024 LOG.debug("Get row at index=" + index + " => " + rowData);
1025 }
1026
1027 rowDatas.add(rowData);
1028 }
1029
1030 } finally {
1031 gridComponent.setRowIndex(-1);
1032 }
1033
1034 if (rowDatas == null) {
1035 return Collections.EMPTY_LIST;
1036 }
1037
1038 return rowDatas;
1039 }
1040
1041 private static List getRowDatas(IGridComponent gridComponent, int start,
1042 int end) {
1043
1044 DataModel dataModel = gridComponent.getDataModelValue();
1045
1046 if (dataModel instanceof IRangeDataModel) {
1047 ((IRangeDataModel) dataModel).setRowRange(start, end - start + 1);
1048 }
1049
1050 List rowDatas = null;
1051 try {
1052 for (int index = start; index <= end; index++) {
1053 gridComponent.setRowIndex(index);
1054
1055 if (gridComponent.isRowAvailable() == false) {
1056 LOG.error("Row not available for index='" + index + "'.");
1057 break;
1058 }
1059
1060 Object rowData = gridComponent.getRowData();
1061
1062 if (rowData == null) {
1063 LOG.error("RowData is null for index='" + index + "'.");
1064 break;
1065 }
1066
1067 if (LOG.isDebugEnabled()) {
1068 LOG.debug("Get index=" + index + " => " + rowData);
1069 }
1070
1071 if (rowDatas == null) {
1072 rowDatas = new ArrayList(end - index + 1);
1073 }
1074
1075 rowDatas.add(rowData);
1076 }
1077
1078 } finally {
1079 gridComponent.setRowIndex(-1);
1080 }
1081
1082 if (rowDatas == null) {
1083 return Collections.EMPTY_LIST;
1084 }
1085
1086 return rowDatas;
1087 }
1088
1089 private static int searchIndexIntoDataModel(IGridComponent component,
1090 Object rowValue) {
1091 int rowCount = component.getRowCount();
1092 if (rowCount > 0) {
1093 DataModel dataModel = component.getDataModelValue();
1094
1095 if (dataModel instanceof IRangeDataModel) {
1096 ((IRangeDataModel) dataModel).setRowRange(0, rowCount);
1097 }
1098 }
1099
1100 try {
1101 for (int index = 0;; index++) {
1102 component.setRowIndex(index);
1103 if (component.isRowAvailable() == false) {
1104 break;
1105 }
1106
1107 Object rowData = component.getRowData();
1108
1109 if (rowData == null) {
1110 LOG.error("RowData is null for index='" + index + "'.");
1111 break;
1112 }
1113
1114 if (rowData.equals(rowValue) == false) {
1115 continue;
1116 }
1117
1118 if (LOG.isDebugEnabled()) {
1119 LOG.debug("Find row " + rowData + " => index=" + index);
1120 }
1121
1122 return index;
1123 }
1124
1125 } finally {
1126 component.setRowIndex(-1);
1127 }
1128
1129 return -1;
1130 }
1131
1132
1133
1134
1135
1136
1137 private static class ProviderValuesAccessor implements IValuesAccessor {
1138
1139 private final IValuesAccessor providerValuesAccessor;
1140
1141 private final Object provider;
1142
1143 public ProviderValuesAccessor(IValuesAccessor providerValuesAccessor,
1144 Object provider) {
1145 this.providerValuesAccessor = providerValuesAccessor;
1146 this.provider = provider;
1147 }
1148
1149 public int getCount(Object value) {
1150 return providerValuesAccessor.getCount(provider);
1151 }
1152
1153 public Object getFirst(Object value, Object refValues) {
1154 return providerValuesAccessor.getFirst(provider, null);
1155 }
1156
1157 public Object[] listValues(Object value, Object refValues) {
1158 return providerValuesAccessor.listValues(provider, null);
1159 }
1160
1161 public Object getAdaptedValues(Object value) {
1162 return provider;
1163 }
1164
1165 public Object getComponentValues(UIComponent component) {
1166 return providerValuesAccessor.getComponentValues(component);
1167 }
1168
1169 public void setComponentValues(UIComponent component, Object values) {
1170 providerValuesAccessor.setComponentValues(component, values);
1171 }
1172
1173 public Class getComponentValuesType(FacesContext facesContext,
1174 UIComponent component) {
1175 return providerValuesAccessor.getComponentValuesType(null,
1176 component);
1177 }
1178
1179 public void setAdaptedValues(Object value, Object values) {
1180 providerValuesAccessor.setAdaptedValues(value, values);
1181 }
1182 }
1183
1184
1185
1186
1187
1188
1189 protected interface IValuesAccessor {
1190 Object getFirst(Object value, Object refValues);
1191
1192 int getCount(Object value);
1193
1194 Object[] listValues(Object value, Object refValues);
1195
1196 Object getAdaptedValues(Object values);
1197
1198 void setAdaptedValues(Object value, Object values);
1199
1200 Object getComponentValues(UIComponent component);
1201
1202 void setComponentValues(UIComponent component, Object values);
1203
1204 Class getComponentValuesType(FacesContext facesContext,
1205 UIComponent component);
1206 }
1207
1208
1209
1210
1211
1212
1213 private static abstract class AbstractValuesAccessor implements
1214 IValuesAccessor {
1215 private static final String REVISION = "$Revision: 1.8 $";
1216
1217 public Object getComponentValues(UIComponent component) {
1218 throw new IllegalStateException("Not implemented !");
1219 }
1220
1221 public void setComponentValues(UIComponent component, Object values) {
1222 throw new IllegalStateException("Not implemented !");
1223 }
1224
1225 public Class getComponentValuesType(FacesContext facesContext,
1226 UIComponent component) {
1227 throw new IllegalStateException("Not implemented !");
1228 }
1229
1230 public Object getAdaptedValues(Object value) {
1231 return value;
1232 }
1233
1234 public void setAdaptedValues(Object value, Object values) {
1235 throw new IllegalStateException("Not supported");
1236 }
1237 }
1238
1239 public static Object adaptValues(Class target, Collection collection) {
1240 if (target == null || target.equals(Object.class)
1241 || target.equals(Object[].class)) {
1242 return collection.toArray();
1243 }
1244
1245 if (target.isArray()) {
1246 Object array = Array.newInstance(target.getComponentType(),
1247 collection.size());
1248
1249 if (array instanceof Object[]) {
1250 return collection.toArray((Object[]) array);
1251 }
1252
1253 Object src[] = collection.toArray();
1254
1255 System.arraycopy(src, 0, array, 0, collection.size());
1256
1257 return array;
1258 }
1259
1260 if (Set.class.isAssignableFrom(target)) {
1261 if (collection instanceof Set) {
1262 return collection;
1263 }
1264 return new HashSet(collection);
1265 }
1266
1267 if (List.class.isAssignableFrom(target)) {
1268 if (collection instanceof List) {
1269 return collection;
1270 }
1271 return new ArrayList(collection);
1272 }
1273
1274 if (Collection.class.isAssignableFrom(target)) {
1275 return collection;
1276 }
1277
1278 throw new FacesException("Invalid collection type '" + target + "'.");
1279 }
1280
1281 public static Set __convertSelection(Object selection) {
1282 if (selection instanceof Object[]) {
1283 return new OrderedSet(Arrays.asList((Object[]) selection));
1284 }
1285
1286 if (selection instanceof Collection) {
1287 return new OrderedSet((Collection) selection);
1288 }
1289
1290 if (selection == null) {
1291 return new OrderedSet();
1292 }
1293
1294 throw new FacesException(
1295 "Bad type of value for attribute selectedValues/checkedValues !");
1296 }
1297
1298 protected static void setValues(UIComponent component,
1299 IValuesAccessor valuesAccessor, Collection values) {
1300
1301 Object newValues = createNewValues(component, valuesAccessor);
1302
1303 select(component, valuesAccessor, newValues, values);
1304 }
1305
1306 protected static Set valuesToSet(UIComponent component,
1307 IValuesAccessor valuesAccessor, boolean immutable) {
1308 Object value = valuesAccessor.getComponentValues(component);
1309
1310 return valuesToSet(value, immutable);
1311 }
1312
1313 public static Set valuesToSet(Object value, boolean immutable) {
1314 if (value == null) {
1315 if (immutable == false) {
1316 return new OrderedSet();
1317 }
1318 return Collections.EMPTY_SET;
1319 }
1320
1321 if (value.getClass().isArray()) {
1322 int length = Array.getLength(value);
1323
1324 if (length < 1) {
1325 if (immutable == false) {
1326 return new OrderedSet();
1327 }
1328 return Collections.EMPTY_SET;
1329 }
1330
1331 Set set = new OrderedSet();
1332
1333 for (int i = 0; i < length; i++) {
1334 set.add(Array.get(value, i));
1335 }
1336
1337 if (LOG.isDebugEnabled() && immutable) {
1338 return Collections.unmodifiableSet(set);
1339 }
1340
1341 return set;
1342 }
1343
1344 if (value instanceof String) {
1345 String ss[] = StringList.parseTokensList((String) value);
1346
1347 if (ss.length == 0) {
1348 if (immutable == false) {
1349 return new OrderedSet();
1350 }
1351 return Collections.EMPTY_SET;
1352 }
1353
1354 Set set = new OrderedSet(Arrays.asList(ss));
1355
1356 if (LOG.isDebugEnabled() && immutable) {
1357 return Collections.unmodifiableSet(set);
1358 }
1359
1360 return set;
1361 }
1362
1363 if (value instanceof Set) {
1364 if (immutable == false) {
1365 return new OrderedSet((Set) value);
1366 }
1367
1368 if (LOG.isDebugEnabled() && immutable) {
1369 return Collections.unmodifiableSet((Set) value);
1370 }
1371
1372 return (Set) value;
1373 }
1374
1375 if (value instanceof Collection) {
1376 Collection col = (Collection) value;
1377 if (col.isEmpty() && immutable) {
1378 return Collections.EMPTY_SET;
1379 }
1380
1381 Set set = new OrderedSet((Collection) value);
1382
1383 if (LOG.isDebugEnabled() && immutable) {
1384 return Collections.unmodifiableSet(set);
1385 }
1386
1387 return set;
1388 }
1389
1390 if (immutable == false) {
1391 Set set = new OrderedSet();
1392 set.add(value);
1393
1394 return set;
1395 }
1396
1397 return Collections.singleton(value);
1398 }
1399
1400
1401
1402
1403
1404
1405 public interface IComponentValueType {
1406 Object createNewValue(UIComponent component);
1407 }
1408
1409
1410
1411
1412
1413
1414
1415 public interface IComponentValueTypeCapability {
1416 IComponentValueType getComponentValueType();
1417 }
1418 }