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