1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package javax.faces.component.behavior;
20
21 import java.io.Serializable;
22 import java.util.ArrayList;
23 import java.util.Collection;
24 import java.util.HashMap;
25 import java.util.Iterator;
26 import java.util.List;
27 import java.util.Map;
28
29 import javax.el.ValueExpression;
30 import javax.faces.component.StateHelper;
31 import javax.faces.component.StateHolder;
32 import javax.faces.component.UIComponentBase;
33 import javax.faces.context.FacesContext;
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147 class _DeltaStateHelper <A extends AjaxBehavior> implements StateHelper
148 {
149
150
151
152
153
154
155
156 private A _target;
157
158
159
160
161 private Map<Serializable, Object> _fullState;
162
163
164
165
166 private Map<Serializable, Object> _deltas;
167
168
169
170
171
172
173
174 private boolean _transient = false;
175
176 public _DeltaStateHelper(A target)
177 {
178 super();
179 this._target = target;
180 _fullState = new HashMap<Serializable, Object>();
181 _deltas = null;
182
183 }
184
185
186
187
188
189
190 private boolean _createDeltas()
191 {
192 if (isInitialStateMarked())
193 {
194 if (_deltas == null)
195 {
196 _deltas = new HashMap<Serializable, Object>(2);
197 }
198 return true;
199 }
200
201 return false;
202 }
203
204 protected boolean isInitialStateMarked()
205 {
206 return _target.initialStateMarked();
207 }
208
209 public void add(Serializable key, Object value)
210 {
211 if (_createDeltas())
212 {
213
214 Map<Object, Boolean> deltaListMapValues = (Map<Object, Boolean>) _deltas
215 .get(key);
216 if (deltaListMapValues == null)
217 {
218 deltaListMapValues = new InternalDeltaListMap<Object, Boolean>(
219 3);
220 _deltas.put(key, deltaListMapValues);
221 }
222 deltaListMapValues.put(value, Boolean.TRUE);
223 }
224
225
226 List<Object> fullListValues = (List<Object>) _fullState.get(key);
227 if (fullListValues == null)
228 {
229 fullListValues = new InternalList<Object>(3);
230 _fullState.put(key, fullListValues);
231 }
232 fullListValues.add(value);
233 }
234
235 public Object eval(Serializable key)
236 {
237 Object returnValue = _fullState.get(key);
238 if (returnValue != null)
239 {
240 return returnValue;
241 }
242 ValueExpression expression = _target.getValueExpression(key
243 .toString());
244 if (expression != null)
245 {
246 return expression.getValue(FacesContext.getCurrentInstance()
247 .getELContext());
248 }
249 return null;
250 }
251
252 public Object eval(Serializable key, Object defaultValue)
253 {
254 Object returnValue = _fullState.get(key);
255 if (returnValue != null)
256 {
257 return returnValue;
258 }
259 ValueExpression expression = _target.getValueExpression(key
260 .toString());
261 if (expression != null)
262 {
263 return expression.getValue(FacesContext.getCurrentInstance()
264 .getELContext());
265 }
266 return defaultValue;
267 }
268
269 public Object get(Serializable key)
270 {
271 return _fullState.get(key);
272 }
273
274 public Object put(Serializable key, Object value)
275 {
276 Object returnValue = null;
277 if (_createDeltas())
278 {
279 if (_deltas.containsKey(key))
280 {
281 returnValue = _deltas.put(key, value);
282 _fullState.put(key, value);
283 }
284 else if (value == null && !_fullState.containsKey(key))
285 {
286 returnValue = null;
287 }
288 else
289 {
290 _deltas.put(key, value);
291 returnValue = _fullState.put(key, value);
292 }
293 }
294 else
295 {
296
297
298
299
300
301
302 returnValue = _fullState.put(key, value);
303 }
304 return returnValue;
305 }
306
307 public Object put(Serializable key, String mapKey, Object value)
308 {
309 boolean returnSet = false;
310 Object returnValue = null;
311 if (_createDeltas())
312 {
313
314 Map<String, Object> mapValues = (Map<String, Object>) _deltas
315 .get(key);
316 if (mapValues == null)
317 {
318 mapValues = new InternalMap<String, Object>();
319 _deltas.put(key, mapValues);
320 }
321 if (mapValues.containsKey(mapKey))
322 {
323 returnValue = mapValues.put(mapKey, value);
324 returnSet = true;
325 }
326 else
327 {
328 mapValues.put(mapKey, value);
329 }
330 }
331
332
333 Map<String, Object> mapValues = (Map<String, Object>) _fullState
334 .get(key);
335 if (mapValues == null)
336 {
337 mapValues = new InternalMap<String, Object>();
338 _fullState.put(key, mapValues);
339 }
340 if (returnSet)
341 {
342 mapValues.put(mapKey, value);
343 }
344 else
345 {
346 returnValue = mapValues.put(mapKey, value);
347 }
348 return returnValue;
349 }
350
351 public Object remove(Serializable key)
352 {
353 Object returnValue = null;
354 if (_createDeltas())
355 {
356 if (_deltas.containsKey(key))
357 {
358
359 returnValue = _deltas.put(key, null);
360 _fullState.remove(key);
361 }
362 else
363 {
364
365 _deltas.put(key, null);
366 returnValue = _fullState.remove(key);
367 }
368 }
369 else
370 {
371 returnValue = _fullState.remove(key);
372 }
373 return returnValue;
374 }
375
376 public Object remove(Serializable key, Object valueOrKey)
377 {
378
379
380
381
382
383
384 Object collectionOrMap = _fullState.get(key);
385 Object returnValue = null;
386 if (collectionOrMap instanceof InternalMap)
387 {
388 if (_createDeltas())
389 {
390 returnValue = _removeValueOrKeyFromMap(_deltas, key,
391 valueOrKey, true);
392 _removeValueOrKeyFromMap(_fullState, key, valueOrKey, false);
393 }
394 else
395 {
396 returnValue = _removeValueOrKeyFromMap(_fullState, key,
397 valueOrKey, false);
398 }
399 }
400 else if (collectionOrMap instanceof InternalList)
401 {
402 if (_createDeltas())
403 {
404 returnValue = _removeValueOrKeyFromCollectionDelta(_deltas,
405 key, valueOrKey);
406 _removeValueOrKeyFromCollection(_fullState, key, valueOrKey);
407 }
408 else
409 {
410 returnValue = _removeValueOrKeyFromCollection(_fullState, key,
411 valueOrKey);
412 }
413 }
414 return returnValue;
415 }
416
417 private static Object _removeValueOrKeyFromCollectionDelta(
418 Map<Serializable, Object> stateMap, Serializable key,
419 Object valueOrKey)
420 {
421 Object returnValue = null;
422 Map<Object, Boolean> c = (Map<Object, Boolean>) stateMap.get(key);
423 if (c != null)
424 {
425 if (c.containsKey(valueOrKey))
426 {
427 returnValue = valueOrKey;
428 }
429 c.put(valueOrKey, Boolean.FALSE);
430 }
431 return returnValue;
432 }
433
434 private static Object _removeValueOrKeyFromCollection(
435 Map<Serializable, Object> stateMap, Serializable key,
436 Object valueOrKey)
437 {
438 Object returnValue = null;
439 Collection c = (Collection) stateMap.get(key);
440 if (c != null)
441 {
442 if (c.remove(valueOrKey))
443 {
444 returnValue = valueOrKey;
445 }
446 if (c.isEmpty())
447 {
448 stateMap.remove(key);
449 }
450 }
451 return returnValue;
452 }
453
454 private static Object _removeValueOrKeyFromMap(
455 Map<Serializable, Object> stateMap, Serializable key,
456 Object valueOrKey, boolean delta)
457 {
458 if (valueOrKey == null)
459 {
460 return null;
461 }
462
463 Object returnValue = null;
464 Map<String, Object> map = (Map<String, Object>) stateMap.get(key);
465 if (map != null)
466 {
467 if (delta)
468 {
469
470 returnValue = map.put((String) valueOrKey, null);
471 }
472 else
473 {
474 returnValue = map.remove(valueOrKey);
475 }
476
477 if (map.isEmpty())
478 {
479
480 stateMap.put(key, null);
481 }
482 }
483 return returnValue;
484 }
485
486 public boolean isTransient()
487 {
488 return _transient;
489 }
490
491
492
493
494
495
496
497
498
499
500
501
502
503 public Object saveState(FacesContext context)
504 {
505 Map serializableMap = (isInitialStateMarked()) ? _deltas : _fullState;
506
507 if (serializableMap == null || serializableMap.size() == 0)
508 {
509 return null;
510 }
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526 Map.Entry<Serializable, Object> entry;
527
528 Object[] retArr = new Object[serializableMap.entrySet().size() * 2];
529
530
531 Iterator<Map.Entry<Serializable, Object>> it = serializableMap
532 .entrySet().iterator();
533 int cnt = 0;
534 while (it.hasNext())
535 {
536 entry = it.next();
537 retArr[cnt] = entry.getKey();
538
539 Object value = entry.getValue();
540
541
542
543
544 if (value instanceof StateHolder ||
545 value instanceof List ||
546 !(value instanceof Serializable))
547 {
548 Object savedValue = saveAttachedState(context,
549 value);
550 retArr[cnt + 1] = savedValue;
551 }
552 else
553 {
554 retArr[cnt + 1] = value;
555 }
556 cnt += 2;
557 }
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592 return retArr;
593 }
594
595 public void restoreState(FacesContext context, Object state)
596 {
597 if (state == null)
598 {
599 return;
600 }
601
602 Object[] serializedState = (Object[]) state;
603
604 if (!isInitialStateMarked() && !_fullState.isEmpty())
605 {
606 _fullState.clear();
607 if(_deltas != null)
608 {
609 _deltas.clear();
610 }
611 }
612
613 for (int cnt = 0; cnt < serializedState.length; cnt += 2)
614 {
615 Serializable key = (Serializable) serializedState[cnt];
616 Object savedValue = restoreAttachedState(context,
617 serializedState[cnt + 1]);
618
619 if (isInitialStateMarked())
620 {
621 if (savedValue instanceof InternalDeltaListMap)
622 {
623 for (Map.Entry<Object, Boolean> mapEntry : ((Map<Object, Boolean>) savedValue)
624 .entrySet())
625 {
626 boolean addOrRemove = mapEntry.getValue();
627 if (addOrRemove)
628 {
629
630 this.add(key, mapEntry.getKey());
631 }
632 else
633 {
634
635 this.remove(key, mapEntry.getKey());
636 }
637 }
638 }
639 else if (savedValue instanceof InternalMap)
640 {
641 for (Map.Entry<String, Object> mapEntry : ((Map<String, Object>) savedValue)
642 .entrySet())
643 {
644 this.put(key, mapEntry.getKey(), mapEntry.getValue());
645 }
646 }
647
648
649
650
651
652
653
654
655
656
657 else
658 {
659 put(key, savedValue);
660 }
661 }
662 else
663 {
664 put(key, savedValue);
665 }
666 }
667 }
668
669 public void setTransient(boolean transientValue)
670 {
671 _transient = transientValue;
672 }
673
674
675
676 static class InternalMap<K, V> extends HashMap<K, V> implements StateHolder
677 {
678 public InternalMap()
679 {
680 super();
681 }
682
683 public InternalMap(int initialCapacity, float loadFactor)
684 {
685 super(initialCapacity, loadFactor);
686 }
687
688 public InternalMap(Map<? extends K, ? extends V> m)
689 {
690 super(m);
691 }
692
693 public InternalMap(int initialSize)
694 {
695 super(initialSize);
696 }
697
698 public boolean isTransient()
699 {
700 return false;
701 }
702
703 public void setTransient(boolean newTransientValue)
704 {
705
706 }
707
708 public void restoreState(FacesContext context, Object state)
709 {
710 Object[] listAsMap = (Object[]) state;
711 for (int cnt = 0; cnt < listAsMap.length; cnt += 2)
712 {
713 this.put((K) listAsMap[cnt], (V) UIComponentBase
714 .restoreAttachedState(context, listAsMap[cnt + 1]));
715 }
716 }
717
718 public Object saveState(FacesContext context)
719 {
720 int cnt = 0;
721 Object[] mapArr = new Object[this.size() * 2];
722 for (Map.Entry<K, V> entry : this.entrySet())
723 {
724 mapArr[cnt] = entry.getKey();
725 Object value = entry.getValue();
726
727 if (value instanceof StateHolder ||
728 value instanceof List ||
729 !(value instanceof Serializable))
730 {
731 mapArr[cnt + 1] = saveAttachedState(context, value);
732 }
733 else
734 {
735 mapArr[cnt + 1] = value;
736 }
737 cnt += 2;
738 }
739 return mapArr;
740 }
741 }
742
743
744
745
746 static class InternalDeltaListMap<K, V> extends InternalMap<K, V>
747 {
748
749 public InternalDeltaListMap()
750 {
751 super();
752 }
753
754 public InternalDeltaListMap(int initialCapacity, float loadFactor)
755 {
756 super(initialCapacity, loadFactor);
757 }
758
759 public InternalDeltaListMap(int initialSize)
760 {
761 super(initialSize);
762 }
763
764 public InternalDeltaListMap(Map<? extends K, ? extends V> m)
765 {
766 super(m);
767 }
768 }
769
770 static class InternalList<T> extends ArrayList<T> implements StateHolder
771 {
772 public InternalList()
773 {
774 super();
775 }
776
777 public InternalList(Collection<? extends T> c)
778 {
779 super(c);
780 }
781
782 public InternalList(int initialSize)
783 {
784 super(initialSize);
785 }
786
787 public boolean isTransient()
788 {
789 return false;
790 }
791
792 public void setTransient(boolean newTransientValue)
793 {
794 }
795
796 public void restoreState(FacesContext context, Object state)
797 {
798 Object[] listAsArr = (Object[]) state;
799
800
801 for (Object elem : listAsArr)
802 {
803 add((T) restoreAttachedState(context, elem));
804 }
805 }
806
807 public Object saveState(FacesContext context)
808 {
809 Object[] values = new Object[size()];
810 for (int i = 0; i < size(); i++)
811 {
812 Object value = get(i);
813
814 if (value instanceof StateHolder ||
815 value instanceof List ||
816 !(value instanceof Serializable))
817 {
818 values[i] = saveAttachedState(context, value);
819 }
820 else
821 {
822 values[i] = value;
823 }
824 }
825 return values;
826 }
827 }
828
829 private static Object saveAttachedState(FacesContext context, Object attachedObject)
830 {
831 if (context == null)
832 {
833 throw new NullPointerException ("context");
834 }
835
836 if (attachedObject == null)
837 {
838 return null;
839 }
840
841
842 if (attachedObject instanceof StateHolder)
843 {
844 StateHolder holder = (StateHolder) attachedObject;
845 if (holder.isTransient())
846 {
847 return null;
848 }
849
850 return new _AttachedStateWrapper(attachedObject.getClass(), holder.saveState(context));
851 }
852 else if (attachedObject instanceof List)
853 {
854 List<Object> lst = new ArrayList<Object>(((List<?>) attachedObject).size());
855 for (Object item : (List<?>) attachedObject)
856 {
857 if (item != null)
858 {
859 lst.add(saveAttachedState(context, item));
860 }
861 }
862
863 return new _AttachedListStateWrapper(lst);
864 }
865 else if (attachedObject instanceof Serializable)
866 {
867 return attachedObject;
868 }
869 else
870 {
871 return new _AttachedStateWrapper(attachedObject.getClass(), null);
872 }
873 }
874
875 private static Object restoreAttachedState(FacesContext context, Object stateObj) throws IllegalStateException
876 {
877 if (context == null)
878 {
879 throw new NullPointerException("context");
880 }
881 if (stateObj == null)
882 {
883 return null;
884 }
885 if (stateObj instanceof _AttachedListStateWrapper)
886 {
887 List<Object> lst = ((_AttachedListStateWrapper) stateObj).getWrappedStateList();
888 List<Object> restoredList = new ArrayList<Object>(lst.size());
889 for (Object item : lst)
890 {
891 restoredList.add(restoreAttachedState(context, item));
892 }
893 return restoredList;
894 }
895 else if (stateObj instanceof _AttachedStateWrapper)
896 {
897 Class<?> clazz = ((_AttachedStateWrapper) stateObj).getClazz();
898 Object restoredObject;
899 try
900 {
901 restoredObject = clazz.newInstance();
902 }
903 catch (InstantiationException e)
904 {
905 throw new RuntimeException("Could not restore StateHolder of type " + clazz.getName()
906 + " (missing no-args constructor?)", e);
907 }
908 catch (IllegalAccessException e)
909 {
910 throw new RuntimeException(e);
911 }
912 if (restoredObject instanceof StateHolder)
913 {
914 _AttachedStateWrapper wrapper = (_AttachedStateWrapper) stateObj;
915 Object wrappedState = wrapper.getWrappedStateObject();
916
917 StateHolder holder = (StateHolder) restoredObject;
918 holder.restoreState(context, wrappedState);
919 }
920 return restoredObject;
921 }
922 else
923 {
924 return stateObj;
925 }
926 }
927 }