1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.trinidad.component;
20
21 import java.io.IOException;
22 import java.io.ObjectInputStream;
23 import java.io.Serializable;
24
25 import java.util.AbstractMap;
26 import java.util.Collections;
27 import java.util.List;
28 import java.util.Map;
29 import java.util.Set;
30
31 import javax.faces.component.NamingContainer;
32 import javax.faces.component.UIComponent;
33 import javax.faces.context.FacesContext;
34 import javax.faces.event.AbortProcessingException;
35 import javax.faces.event.FacesEvent;
36 import javax.faces.event.PhaseId;
37 import javax.faces.render.Renderer;
38
39 import org.apache.myfaces.trinidad.bean.FacesBean;
40 import org.apache.myfaces.trinidad.bean.PropertyKey;
41 import org.apache.myfaces.trinidad.event.SelectionEvent;
42 import org.apache.myfaces.trinidad.logging.TrinidadLogger;
43 import org.apache.myfaces.trinidad.model.CollectionModel;
44 import org.apache.myfaces.trinidad.model.SortCriterion;
45 import org.apache.myfaces.trinidad.render.ClientRowKeyManager;
46 import org.apache.myfaces.trinidad.render.ClientRowKeyManagerFactory;
47 import org.apache.myfaces.trinidad.util.ComponentUtils;
48
49
50
51
52
53
54
55
56 public abstract class UIXCollection extends UIXComponentBase
57 implements NamingContainer
58 {
59 static public final FacesBean.Type TYPE = new FacesBean.Type(
60 UIXComponentBase.TYPE);
61 static public final PropertyKey VAR_KEY =
62 TYPE.registerKey("var", String.class, PropertyKey.CAP_NOT_BOUND);
63
64 protected UIXCollection(String rendererType)
65 {
66 super(rendererType);
67 }
68
69 protected UIXCollection()
70 {
71 this(null);
72 }
73
74
75
76
77
78
79 final public String getVar()
80 {
81 return ComponentUtils.resolveString(getProperty(VAR_KEY));
82 }
83
84
85
86
87
88
89 final public void setVar(String var)
90 {
91 setProperty(VAR_KEY, (var));
92 InternalState iState = _getInternalState(false);
93 if (iState != null)
94 {
95 iState._var = var;
96 }
97 }
98
99
100
101
102
103
104
105 @Override
106 public void queueEvent(FacesEvent event)
107 {
108 if (event.getSource() == this)
109 {
110
111
112 if (!(event instanceof SelectionEvent))
113 {
114 InternalState iState = _getInternalState(true);
115 iState._hasEvent = true;
116 }
117 }
118
119
120
121
122 Object currencyKey = getRowKey();
123 event = new TableRowEvent(this, event, currencyKey);
124 super.queueEvent(event);
125 }
126
127
128
129
130
131
132
133 @Override
134 public void broadcast(FacesEvent event)
135 throws AbortProcessingException
136 {
137
138
139 if (event instanceof TableRowEvent)
140 {
141 TableRowEvent rowEvent = (TableRowEvent) event;
142 Object old = getRowKey();
143 setRowKey(rowEvent.getCurrencyKey());
144 FacesEvent wrapped = rowEvent.getEvent();
145 wrapped.getComponent().broadcast(wrapped);
146 setRowKey(old);
147 }
148 else
149 {
150 super.broadcast(event);
151 }
152 }
153
154
155
156
157
158
159 @Override
160 public final void processDecodes(FacesContext context)
161 {
162 if (context == null)
163 throw new NullPointerException();
164
165 _init();
166
167 InternalState iState = _getInternalState(true);
168 iState._isFirstRender = false;
169
170 if (!isRendered())
171 return;
172
173 _flushCachedModel();
174
175
176 iState._hasEvent = false;
177
178
179
180
181
182
183
184
185 decode(context);
186
187
188 decodeChildren(context);
189 }
190
191 @Override
192 protected void decodeChildrenImpl(FacesContext context)
193 {
194 processFacetsAndChildren(context, PhaseId.APPLY_REQUEST_VALUES);
195 }
196
197 @Override
198 protected void validateChildrenImpl(FacesContext context)
199 {
200 processFacetsAndChildren(context, PhaseId.PROCESS_VALIDATIONS);
201 }
202
203 @Override
204 protected void updateChildrenImpl(FacesContext context)
205 {
206 processFacetsAndChildren(context, PhaseId.UPDATE_MODEL_VALUES);
207 }
208
209
210
211
212
213
214 public void resetStampState()
215 {
216 InternalState iState = _getInternalState(true);
217
218 Object initKey = _getCurrencyKeyForInitialStampState();
219
220
221
222 if (iState._stampState != null)
223 iState._stampState.clear(initKey);
224 }
225
226 @Override
227 public Object processSaveState(FacesContext context)
228 {
229
230
231
232
233
234 Object currencyKey = _getCurrencyKey();
235 Object initKey = _getCurrencyKeyForInitialStampState();
236 if (currencyKey != initKey)
237 {
238 setRowKey(initKey);
239 }
240
241 Object savedState = super.processSaveState(context);
242
243 if (currencyKey != initKey)
244 {
245 setRowKey(currencyKey);
246 }
247
248 return savedState;
249 }
250
251 @Override
252 public Object saveState(FacesContext context)
253 {
254
255
256 Object superState = super.saveState(context);
257 final Object stampState, clientKeyMgr;
258
259
260
261
262 InternalState iState = _getInternalState(false);
263 if (iState != null)
264 {
265 stampState = iState._stampState;
266 clientKeyMgr = iState._clientKeyMgr;
267 }
268 else
269 {
270 stampState = null;
271 clientKeyMgr = null;
272 }
273
274 if ((superState != null) || (stampState != null) || (clientKeyMgr != null))
275 return new Object[]{superState, stampState, clientKeyMgr};
276 return null;
277 }
278
279
280 @SuppressWarnings("unchecked")
281 @Override
282 public void restoreState(FacesContext context, Object state)
283 {
284 final Object superState, stampState, clientKeyMgr;
285 Object[] array = (Object[]) state;
286 if (array != null)
287 {
288 superState = array[0];
289 stampState = array[1];
290 clientKeyMgr = array[2];
291 }
292 else
293 {
294 superState = stampState = clientKeyMgr = null;
295 }
296 super.restoreState(context, superState);
297
298 if ((stampState != null) || (clientKeyMgr != null))
299 {
300 InternalState iState = _getInternalState(true);
301 iState._stampState = (StampState) stampState;
302 iState._clientKeyMgr = (ClientRowKeyManager) clientKeyMgr;
303 }
304 else
305 {
306
307
308 InternalState iState = _getInternalState(false);
309 if (iState != null)
310 {
311 iState._stampState = null;
312 iState._clientKeyMgr = null;
313 }
314 }
315 }
316
317
318
319
320
321
322
323 public final boolean isRowAvailable()
324 {
325 return getCollectionModel().isRowAvailable();
326 }
327
328
329
330
331
332
333 public final int getRowCount()
334 {
335 return getCollectionModel().getRowCount();
336 }
337
338
339
340
341
342
343 public final int getRowIndex()
344 {
345 return getCollectionModel().getRowIndex();
346 }
347
348
349
350
351
352
353 public final Object getRowKey()
354 {
355 InternalState iState = _getInternalState(true);
356 if (iState._currentRowKey == _NULL)
357 {
358
359
360
361
362
363 iState._currentRowKey = getCollectionModel().getRowKey();
364 }
365
366 return iState._currentRowKey;
367 }
368
369
370
371
372
373
374 public final Object getRowData()
375 {
376 CollectionModel model = getCollectionModel();
377
378
379 return model.isRowAvailable() ? model.getRowData() : null;
380 }
381
382
383
384
385
386
387
388 public boolean isRowAvailable(int rowIndex)
389 {
390 return getCollectionModel().isRowAvailable(rowIndex);
391 }
392
393
394
395
396
397
398
399 public Object getRowData(int rowIndex)
400 {
401 return getCollectionModel().getRowData(rowIndex);
402 }
403
404
405
406
407
408 public abstract String getVarStatus();
409
410
411
412
413
414
415
416
417
418 public void setRowKey(Object rowKey)
419 {
420 preRowDataChange();
421 getCollectionModel().setRowKey(rowKey);
422 postRowDataChange();
423 if (_LOG.isFine() && (rowKey != null) && (!isRowAvailable()))
424 _LOG.fine("no row available for rowKey:"+rowKey);
425 }
426
427
428
429
430
431
432
433
434
435 public void setRowIndex(int rowIndex)
436 {
437 preRowDataChange();
438 getCollectionModel().setRowIndex(rowIndex);
439 postRowDataChange();
440 if (_LOG.isFine() && (rowIndex != -1) && (!isRowAvailable()))
441 _LOG.fine("no row available for rowIndex:"+rowIndex);
442 }
443
444
445
446
447
448
449 public final boolean isSortable(String property)
450 {
451 return getCollectionModel().isSortable(property);
452 }
453
454
455
456
457
458
459
460 public void setSortCriteria(List<SortCriterion> criteria)
461 {
462 getCollectionModel().setSortCriteria(criteria);
463 }
464
465
466
467
468
469
470
471
472 public final List<SortCriterion> getSortCriteria()
473 {
474 return getCollectionModel().getSortCriteria();
475 }
476
477
478
479
480
481
482
483
484
485 @Deprecated
486 protected void clearCurrencyStringCache()
487 {
488 _getInternalState(true)._clearTokenCache = true;
489 }
490
491
492
493
494 @Override
495 public final void encodeBegin(FacesContext context) throws IOException
496 {
497 _init();
498
499 InternalState istate = _getInternalState(true);
500
501
502
503
504 if (istate._clearTokenCache)
505 {
506 istate._clearTokenCache = false;
507 ClientRowKeyManager keyMgr = getClientRowKeyManager();
508 if (keyMgr instanceof DefaultClientKeyManager)
509 ((DefaultClientKeyManager) keyMgr).clear();
510 }
511 _flushCachedModel();
512
513 Object assertKey = null;
514 assert ((assertKey = getRowKey()) != null) || true;
515 __encodeBegin(context);
516
517 assert _assertKeyPreserved(assertKey) : "CurrencyKey not preserved";
518 }
519
520 @Override
521 public void encodeEnd(FacesContext context) throws IOException
522 {
523 Object assertKey = null;
524 assert ((assertKey = getRowKey()) != null) || true;
525 super.encodeEnd(context);
526
527 assert _assertKeyPreserved(assertKey) : "CurrencyKey not preserved";
528 }
529
530 private boolean _assertKeyPreserved(Object oldKey)
531 {
532 Object newKey = getRowKey();
533 return (oldKey != null) ? oldKey.equals(newKey) : (newKey == null);
534 }
535
536 void __encodeBegin(FacesContext context) throws IOException
537 {
538 super.encodeBegin(context);
539 }
540
541
542
543
544
545 boolean __isFirstRender()
546 {
547 InternalState iState = _getInternalState(true);
548 return iState._isFirstRender;
549 }
550
551
552
553
554
555 @Deprecated
556 public String getCurrencyString()
557 {
558 return getClientRowKey();
559 }
560
561
562
563
564
565 @Deprecated
566 public void setCurrencyString(String currency)
567 {
568 setClientRowKey(currency);
569 }
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585 public String getClientRowKey()
586 {
587
588
589
590
591
592 Object currencyObject = _getCurrencyKey();
593 if (currencyObject == null)
594 return null;
595
596 Object initKey = _getCurrencyKeyForInitialStampState();
597 if (_equals(currencyObject, initKey))
598 return null;
599
600 FacesContext fc = FacesContext.getCurrentInstance();
601 String key = getClientRowKeyManager().getClientRowKey(fc, this, currencyObject);
602 return key;
603 }
604
605
606
607
608
609
610
611
612
613
614
615 private Object _getCurrencyKey()
616 {
617
618
619
620
621 InternalState iState = _getInternalState(false);
622 if (iState == null)
623 return null;
624
625 return (iState._model != null)
626 ? getRowKey()
627 : _getCurrencyKeyForInitialStampState();
628 }
629
630
631
632
633
634
635 public void setClientRowKey(String clientRowKey)
636 {
637 if (clientRowKey == null)
638 {
639 setRowKey(_getCurrencyKeyForInitialStampState());
640 return;
641 }
642
643 FacesContext fc = FacesContext.getCurrentInstance();
644 Object rowkey = getClientRowKeyManager().getRowKey(fc, this, clientRowKey);
645
646 if (rowkey == null)
647 {
648 _LOG.severe("CANNOT_FIND_ROWKEY",clientRowKey);
649 }
650 else
651 setRowKey(rowkey);
652 }
653
654
655
656
657
658
659
660
661
662
663 @Override
664 protected final String getLocalClientId()
665 {
666 String id = super.getLocalClientId();
667 String key = getClientRowKey();
668 if (key != null)
669 {
670 StringBuilder bld = __getSharedStringBuilder();
671 bld.append(id).append(NamingContainer.SEPARATOR_CHAR).append(key);
672 id = bld.toString();
673 }
674
675 return id;
676 }
677
678
679
680
681
682
683
684 protected final void preRowDataChange()
685 {
686 _saveStampState();
687 InternalState iState = _getInternalState(true);
688
689 iState._currentRowKey = _NULL;
690 }
691
692
693
694
695
696
697
698
699 protected final void postRowDataChange()
700 {
701 Object rowData = getRowData();
702 if (_LOG.isFinest() && (rowData == null))
703 {
704 _LOG.finest("rowData is null at rowIndex:"+getRowIndex()+
705 " and currencyKey:"+getRowKey());
706 }
707
708 InternalState iState = _getInternalState(true);
709 if (rowData == null)
710 {
711
712
713 if (iState._prevVarValue != _NULL)
714 {
715 _setELVar(iState._var, iState._prevVarValue);
716 iState._prevVarValue = _NULL;
717 }
718 if (iState._prevVarStatus != _NULL)
719 {
720 _setELVar(iState._varStatus, iState._prevVarStatus);
721 iState._prevVarStatus = _NULL;
722 }
723 }
724 else
725 {
726 if (iState._var != null)
727 {
728 Object oldData = _setELVar(iState._var, rowData);
729 if (iState._prevVarValue == _NULL)
730 iState._prevVarValue = oldData;
731 }
732
733
734
735
736 if ((iState._varStatus != null) && (iState._prevVarStatus == _NULL))
737 {
738 Map<String, Object> varStatusMap = createVarStatusMap();
739 iState._prevVarStatus = _setELVar(iState._varStatus, varStatusMap);
740 }
741 }
742
743 _restoreStampState();
744 }
745
746
747
748
749
750
751 @SuppressWarnings("unchecked")
752 protected List<UIComponent> getStamps()
753 {
754 return getChildren();
755 }
756
757
758
759
760
761 private Object _getCurrencyKeyForInitialStampState()
762 {
763 InternalState iState = _getInternalState(false);
764 if (iState == null)
765 return null;
766
767 Object rowKey = iState._initialStampStateKey;
768 return (rowKey == _NULL) ? null : rowKey;
769 }
770
771
772
773
774
775
776
777
778
779 @SuppressWarnings("unchecked")
780 protected Object saveStampState(FacesContext context, UIComponent stamp)
781 {
782 if (stamp.isTransient())
783 return Transient.TRUE;
784
785
786
787
788
789
790
791
792
793 Object stampState = StampState.saveStampState(context, stamp);
794
795
796
797
798 assert(!(stampState instanceof Object[]));
799
800 int facetCount = _getFacetCount(stamp);
801 int childCount = stamp.getChildCount();
802
803 Object[] state = null;
804
805 if (facetCount > 0)
806 {
807 boolean facetStateIsEmpty = true;
808 Object[] facetState = null;
809
810 Map<String, UIComponent> facetMap = stamp.getFacets();
811
812 int i = 0;
813 for(Map.Entry<String, UIComponent> entry : facetMap.entrySet())
814 {
815 Object singleFacetState = saveStampState(context, entry.getValue());
816 if ((singleFacetState == null) ||
817 (singleFacetState == Transient.TRUE))
818 continue;
819
820
821
822 if (facetStateIsEmpty)
823 {
824 facetStateIsEmpty = false;
825 facetState = new Object[facetCount * 2];
826 }
827
828 int base = i * 2;
829 assert(facetState != null);
830 facetState[base] = entry.getKey();
831 facetState[base + 1] = singleFacetState;
832 i++;
833 }
834
835
836
837 if (!facetStateIsEmpty)
838 {
839
840 if(i < facetCount)
841 {
842 Object[] trimmed = new Object[i*2];
843 System.arraycopy(facetState, 0, trimmed, 0, i*2);
844 facetState = trimmed;
845 }
846 state = new Object[3];
847 state[2] = facetState;
848 }
849 }
850
851
852
853 Object childState = StampState.saveChildStampState(context,
854 stamp,
855 this);
856 if (childState != null)
857 {
858
859
860 if (state == null)
861 state = new Object[2];
862 state[1] = childState;
863 }
864
865
866
867 if (state == null)
868 return stampState;
869
870
871 state[0] = stampState;
872 return state;
873 }
874
875
876
877
878
879
880
881 @SuppressWarnings("unchecked")
882 protected void restoreStampState(FacesContext context, UIComponent stamp,
883 Object stampState)
884 {
885
886 if ((stampState == Transient.TRUE) || (stampState == null))
887 return;
888
889
890
891 if (!(stampState instanceof Object[]))
892 {
893 StampState.restoreStampState(context, stamp, stampState);
894
895 return;
896 }
897
898 Object[] state = (Object[]) stampState;
899 int stateSize = state.length;
900
901 assert(stateSize >= 1);
902
903 StampState.restoreStampState(context, stamp, state[0]);
904
905
906
907 if (stateSize >= 3)
908 {
909 Object[] facetStateArray = (Object[]) state[2];
910
911
912 assert(facetStateArray != null);
913
914 for(int i=0; i<facetStateArray.length; i+=2)
915 {
916 String facetName = (String) facetStateArray[i];
917 Object facetState = facetStateArray[i + 1];
918 if (facetState != Transient.TRUE)
919 restoreStampState(context, stamp.getFacet(facetName), facetState);
920 }
921 }
922
923
924 if (stateSize >= 2)
925 {
926 StampState.restoreChildStampState(context,
927 stamp,
928 this,
929 state[1]);
930 }
931 }
932
933
934
935
936
937
938
939
940 protected final void processComponent(
941 FacesContext context,
942 UIComponent component,
943 PhaseId phaseId)
944 {
945 if (component != null)
946 {
947 if (phaseId == PhaseId.APPLY_REQUEST_VALUES)
948 component.processDecodes(context);
949 else if (phaseId == PhaseId.PROCESS_VALIDATIONS)
950 component.processValidators(context);
951 else if (phaseId == PhaseId.UPDATE_MODEL_VALUES)
952 component.processUpdates(context);
953 else
954 throw new IllegalArgumentException(_LOG.getMessage(
955 "BAD_PHASEID",phaseId));
956 }
957 }
958
959
960
961
962
963
964
965
966
967 protected abstract void processFacetsAndChildren(
968 FacesContext context,
969 PhaseId phaseId);
970
971
972
973
974 protected final CollectionModel getCollectionModel()
975 {
976 return getCollectionModel(true);
977 }
978
979
980
981
982
983
984
985
986
987
988 public final ClientRowKeyManager getClientRowKeyManager()
989 {
990
991
992
993 InternalState iState = _getInternalState(true);
994 if (iState._clientKeyMgr == null)
995 {
996 FacesContext fc = FacesContext.getCurrentInstance();
997 Renderer r = getRenderer(fc);
998 iState._clientKeyMgr = (r instanceof ClientRowKeyManagerFactory)
999 ? ((ClientRowKeyManagerFactory) r).createClientRowKeyManager(fc, this)
1000 : new DefaultClientKeyManager();
1001 }
1002 return iState._clientKeyMgr;
1003 }
1004
1005
1006
1007
1008
1009
1010 protected final CollectionModel getCollectionModel(
1011 boolean createIfNull)
1012 {
1013 InternalState iState = _getInternalState(true);
1014 if (iState._model == null && createIfNull)
1015 {
1016
1017
1018
1019
1020
1021
1022 _init();
1023
1024 iState._value = getValue();
1025 iState._model = createCollectionModel(null, iState._value);
1026 assert iState._model != null;
1027 }
1028
1029 if ((iState._initialStampStateKey == _NULL) &&
1030 (iState._model != null))
1031 {
1032
1033
1034
1035
1036
1037 iState._initialStampStateKey = iState._model.getRowKey();
1038 }
1039 return iState._model;
1040 }
1041
1042
1043
1044
1045
1046
1047 protected abstract CollectionModel createCollectionModel(
1048 CollectionModel current,
1049 Object value);
1050
1051
1052
1053
1054 protected abstract Object getValue();
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065 protected Map<String, Object> createVarStatusMap()
1066 {
1067 return new AbstractMap<String, Object>()
1068 {
1069 @Override
1070 public Object get(Object key)
1071 {
1072
1073
1074 if ("model".equals(key))
1075 return getCollectionModel();
1076 if ("rowKey".equals(key))
1077 return getRowKey();
1078 if ("index".equals(key))
1079 return Integer.valueOf(getRowIndex());
1080 if ("current".equals(key))
1081 return getRowData();
1082 return null;
1083 }
1084
1085 @Override
1086 public Set<Map.Entry<String, Object>> entrySet()
1087 {
1088 return Collections.emptySet();
1089 }
1090 };
1091 }
1092
1093
1094
1095
1096
1097
1098 void __init()
1099 {
1100 InternalState iState = _getInternalState(true);
1101 iState._var = getVar();
1102 if (_LOG.isFine() && (iState._var == null))
1103 {
1104 _LOG.fine("'var' attribute is null.");
1105 }
1106 iState._varStatus = getVarStatus();
1107 if (_LOG.isFinest() && (iState._varStatus == null))
1108 {
1109 _LOG.finest("'varStatus' attribute is null.");
1110 }
1111 }
1112
1113 private void _init()
1114 {
1115 InternalState iState = _getInternalState(true);
1116 if (!iState._isInitialized)
1117 {
1118 assert iState._model == null;
1119 iState._isInitialized = true;
1120 __init();
1121 }
1122 }
1123
1124 private void _flushCachedModel()
1125 {
1126 InternalState iState = _getInternalState(true);
1127 Object value = getValue();
1128 if (iState._value != value)
1129 {
1130 iState._value = value;
1131 iState._model = createCollectionModel(iState._model, value);
1132 }
1133 }
1134
1135
1136
1137
1138
1139 Object __getMyStampState()
1140 {
1141 return _state;
1142 }
1143
1144
1145
1146
1147
1148
1149 void __setMyStampState(Object stampState)
1150 {
1151 InternalState iState = (InternalState) stampState;
1152 _state = iState;
1153 }
1154
1155
1156
1157
1158
1159
1160 boolean __hasEvent()
1161 {
1162 InternalState iState = _getInternalState(true);
1163 return iState._hasEvent;
1164 }
1165
1166
1167
1168
1169
1170
1171
1172 private void _saveStampState()
1173 {
1174
1175
1176
1177 StampState stampState = _getStampState();
1178 FacesContext context = getFacesContext();
1179 Object currencyObj = getRowKey();
1180 int position = 0;
1181 for(UIComponent stamp : getStamps())
1182 {
1183 Object state = saveStampState(context, stamp);
1184
1185
1186
1187
1188 String stampId = String.valueOf(position++);
1189 stampState.put(currencyObj, stampId, state);
1190 if (_LOG.isFinest())
1191 _LOG.finest("saving stamp state for currencyObject:"+currencyObj+
1192 " and stampId:"+stampId);
1193 }
1194 }
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204 private void _restoreStampState()
1205 {
1206 StampState stampState = _getStampState();
1207 FacesContext context = getFacesContext();
1208 Object currencyObj = getRowKey();
1209 int position = 0;
1210 for(UIComponent stamp : getStamps())
1211 {
1212
1213
1214
1215
1216 String stampId = String.valueOf(position++);
1217 Object state = stampState.get(currencyObj, stampId);
1218 if (state == null)
1219 {
1220 Object iniStateObj = _getCurrencyKeyForInitialStampState();
1221 state = stampState.get(iniStateObj, stampId);
1222
1223
1224
1225
1226
1227
1228 }
1229 restoreStampState(context, stamp, state);
1230 }
1231 }
1232
1233 private InternalState _getInternalState(boolean create)
1234 {
1235 if ((_state == null) && create)
1236 {
1237 _state = new InternalState();
1238 }
1239 return _state;
1240 }
1241
1242 private StampState _getStampState()
1243 {
1244 InternalState iState = _getInternalState(true);
1245 if (iState._stampState == null)
1246 iState._stampState = new StampState();
1247
1248 return iState._stampState;
1249 }
1250
1251
1252
1253
1254
1255
1256
1257 private Object _setELVar(String varName, Object newData)
1258 {
1259 if (varName == null)
1260 return null;
1261
1262
1263
1264
1265 return TableUtils.setupELVariable(getFacesContext(), varName, newData);
1266 }
1267
1268 private static boolean _equals(Object a, Object b)
1269 {
1270 if (b == null)
1271 return (a == null);
1272
1273 return b.equals(a);
1274 }
1275
1276
1277
1278
1279
1280 private int _getFacetCount(UIComponent component)
1281 {
1282 if (component instanceof UIXComponent)
1283 return ((UIXComponent) component).getFacetCount();
1284
1285 return component.getFacets().size();
1286 }
1287
1288 private static final class DefaultClientKeyManager extends ClientRowKeyManager
1289 {
1290
1291 public void clear()
1292 {
1293 _currencyCache.clear();
1294 }
1295
1296
1297
1298
1299 @Override
1300 public Object getRowKey(FacesContext context, UIComponent component, String clientRowKey)
1301 {
1302 if (_isOptimizedKey(clientRowKey))
1303 return clientRowKey;
1304
1305 ValueMap<Object,String> currencyCache = _currencyCache;
1306 Object rowkey = currencyCache.getKey(clientRowKey);
1307 return rowkey;
1308 }
1309
1310
1311
1312
1313 @Override
1314 public String getClientRowKey(FacesContext context, UIComponent component, Object rowKey)
1315 {
1316 assert rowKey != null;
1317
1318 ValueMap<Object,String> currencyCache = _currencyCache;
1319 String key = currencyCache.get(rowKey);
1320
1321 if (key == null)
1322 {
1323
1324
1325
1326 if (rowKey instanceof String)
1327 {
1328
1329
1330 key = rowKey.toString();
1331 if (_isOptimizedKey(key))
1332 {
1333
1334 return key;
1335 }
1336 }
1337
1338 key = _createToken(currencyCache);
1339
1340 if (_LOG.isFiner())
1341 _LOG.finer("Storing token:"+key+
1342 " for rowKey:"+rowKey);
1343
1344 currencyCache.put(rowKey, key);
1345 }
1346 return key;
1347 }
1348
1349 private static boolean _isOptimizedKey(String key)
1350 {
1351
1352
1353
1354
1355
1356
1357 return ((key.length() > 0) && (!Character.isDigit(key.charAt(0))));
1358 }
1359
1360 private static String _createToken(ValueMap<Object,String> currencyCache)
1361 {
1362 String key = String.valueOf(currencyCache.size());
1363 return key;
1364 }
1365
1366 private ValueMap<Object,String> _currencyCache = new ValueMap<Object,String>();
1367 private static final long serialVersionUID = 1L;
1368 }
1369
1370
1371
1372
1373
1374
1375 private static final class InternalState implements Serializable
1376 {
1377 private transient boolean _hasEvent = false;
1378 private transient Object _prevVarValue = _NULL;
1379 private transient Object _prevVarStatus = _NULL;
1380 private transient String _var = null;
1381 private transient String _varStatus = null;
1382 private transient Object _value = null;
1383 private transient CollectionModel _model = null;
1384 private tr