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 return;
599
600 Object[] serializedState = (Object[]) state;
601
602 if (!isInitialStateMarked() && !_fullState.isEmpty())
603 {
604 _fullState.clear();
605 if(_deltas != null)
606 {
607 _deltas.clear();
608 }
609 }
610
611 for (int cnt = 0; cnt < serializedState.length; cnt += 2)
612 {
613 Serializable key = (Serializable) serializedState[cnt];
614 Object savedValue = restoreAttachedState(context,
615 serializedState[cnt + 1]);
616
617 if (isInitialStateMarked())
618 {
619 if (savedValue instanceof InternalDeltaListMap)
620 {
621 for (Map.Entry<Object, Boolean> mapEntry : ((Map<Object, Boolean>) savedValue)
622 .entrySet())
623 {
624 boolean addOrRemove = mapEntry.getValue();
625 if (addOrRemove)
626 {
627
628 this.add(key, mapEntry.getKey());
629 }
630 else
631 {
632
633 this.remove(key, mapEntry.getKey());
634 }
635 }
636 }
637 else if (savedValue instanceof InternalMap)
638 {
639 for (Map.Entry<String, Object> mapEntry : ((Map<String, Object>) savedValue)
640 .entrySet())
641 {
642 this.put(key, mapEntry.getKey(), mapEntry.getValue());
643 }
644 }
645
646
647
648
649
650
651
652
653
654
655 else
656 {
657 put(key, savedValue);
658 }
659 }
660 else
661 {
662 put(key, savedValue);
663 }
664 }
665 }
666
667 public void setTransient(boolean transientValue)
668 {
669 _transient = transientValue;
670 }
671
672
673
674 static class InternalMap<K, V> extends HashMap<K, V> implements StateHolder
675 {
676 public InternalMap()
677 {
678 super();
679 }
680
681 public InternalMap(int initialCapacity, float loadFactor)
682 {
683 super(initialCapacity, loadFactor);
684 }
685
686 public InternalMap(Map<? extends K, ? extends V> m)
687 {
688 super(m);
689 }
690
691 public InternalMap(int initialSize)
692 {
693 super(initialSize);
694 }
695
696 public boolean isTransient()
697 {
698 return false;
699 }
700
701 public void setTransient(boolean newTransientValue)
702 {
703
704 }
705
706 public void restoreState(FacesContext context, Object state)
707 {
708 Object[] listAsMap = (Object[]) state;
709 for (int cnt = 0; cnt < listAsMap.length; cnt += 2)
710 {
711 this.put((K) listAsMap[cnt], (V) UIComponentBase
712 .restoreAttachedState(context, listAsMap[cnt + 1]));
713 }
714 }
715
716 public Object saveState(FacesContext context)
717 {
718 int cnt = 0;
719 Object[] mapArr = new Object[this.size() * 2];
720 for (Map.Entry<K, V> entry : this.entrySet())
721 {
722 mapArr[cnt] = entry.getKey();
723 Object value = entry.getValue();
724
725 if (value instanceof StateHolder ||
726 value instanceof List ||
727 !(value instanceof Serializable))
728 {
729 mapArr[cnt + 1] = saveAttachedState(context, value);
730 }
731 else
732 {
733 mapArr[cnt + 1] = value;
734 }
735 cnt += 2;
736 }
737 return mapArr;
738 }
739 }
740
741
742
743
744 static class InternalDeltaListMap<K, V> extends InternalMap<K, V>
745 {
746
747 public InternalDeltaListMap()
748 {
749 super();
750 }
751
752 public InternalDeltaListMap(int initialCapacity, float loadFactor)
753 {
754 super(initialCapacity, loadFactor);
755 }
756
757 public InternalDeltaListMap(int initialSize)
758 {
759 super(initialSize);
760 }
761
762 public InternalDeltaListMap(Map<? extends K, ? extends V> m)
763 {
764 super(m);
765 }
766 }
767
768 static class InternalList<T> extends ArrayList<T> implements StateHolder
769 {
770 public InternalList()
771 {
772 super();
773 }
774
775 public InternalList(Collection<? extends T> c)
776 {
777 super(c);
778 }
779
780 public InternalList(int initialSize)
781 {
782 super(initialSize);
783 }
784
785 public boolean isTransient()
786 {
787 return false;
788 }
789
790 public void setTransient(boolean newTransientValue)
791 {
792 }
793
794 public void restoreState(FacesContext context, Object state)
795 {
796 Object[] listAsArr = (Object[]) state;
797
798
799 for (Object elem : listAsArr)
800 {
801 add((T) restoreAttachedState(context, elem));
802 }
803 }
804
805 public Object saveState(FacesContext context)
806 {
807 Object[] values = new Object[size()];
808 for (int i = 0; i < size(); i++)
809 {
810 Object value = get(i);
811
812 if (value instanceof StateHolder ||
813 value instanceof List ||
814 !(value instanceof Serializable))
815 {
816 values[i] = saveAttachedState(context, value);
817 }
818 else
819 {
820 values[i] = value;
821 }
822 }
823 return values;
824 }
825 }
826
827 private static Object saveAttachedState(FacesContext context, Object attachedObject)
828 {
829 if (context == null)
830 {
831 throw new NullPointerException ("context");
832 }
833
834 if (attachedObject == null)
835 return null;
836
837
838 if (attachedObject instanceof StateHolder)
839 {
840 StateHolder holder = (StateHolder) attachedObject;
841 if (holder.isTransient())
842 {
843 return null;
844 }
845
846 return new _AttachedStateWrapper(attachedObject.getClass(), holder.saveState(context));
847 }
848 else if (attachedObject instanceof List)
849 {
850 List<Object> lst = new ArrayList<Object>(((List<?>) attachedObject).size());
851 for (Object item : (List<?>) attachedObject)
852 {
853 if (item != null)
854 {
855 lst.add(saveAttachedState(context, item));
856 }
857 }
858
859 return new _AttachedListStateWrapper(lst);
860 }
861 else if (attachedObject instanceof Serializable)
862 {
863 return attachedObject;
864 }
865 else
866 {
867 return new _AttachedStateWrapper(attachedObject.getClass(), null);
868 }
869 }
870
871 private static Object restoreAttachedState(FacesContext context, Object stateObj) throws IllegalStateException
872 {
873 if (context == null)
874 throw new NullPointerException("context");
875 if (stateObj == null)
876 return null;
877 if (stateObj instanceof _AttachedListStateWrapper)
878 {
879 List<Object> lst = ((_AttachedListStateWrapper) stateObj).getWrappedStateList();
880 List<Object> restoredList = new ArrayList<Object>(lst.size());
881 for (Object item : lst)
882 {
883 restoredList.add(restoreAttachedState(context, item));
884 }
885 return restoredList;
886 }
887 else if (stateObj instanceof _AttachedStateWrapper)
888 {
889 Class<?> clazz = ((_AttachedStateWrapper) stateObj).getClazz();
890 Object restoredObject;
891 try
892 {
893 restoredObject = clazz.newInstance();
894 }
895 catch (InstantiationException e)
896 {
897 throw new RuntimeException("Could not restore StateHolder of type " + clazz.getName()
898 + " (missing no-args constructor?)", e);
899 }
900 catch (IllegalAccessException e)
901 {
902 throw new RuntimeException(e);
903 }
904 if (restoredObject instanceof StateHolder)
905 {
906 _AttachedStateWrapper wrapper = (_AttachedStateWrapper) stateObj;
907 Object wrappedState = wrapper.getWrappedStateObject();
908
909 StateHolder holder = (StateHolder) restoredObject;
910 holder.restoreState(context, wrappedState);
911 }
912 return restoredObject;
913 }
914 else
915 {
916 return stateObj;
917 }
918 }
919 }