1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.application.viewstate;
20
21 import java.io.Serializable;
22 import java.util.ArrayList;
23 import java.util.HashMap;
24 import java.util.List;
25 import java.util.Map;
26 import java.util.logging.Logger;
27 import javax.faces.context.FacesContext;
28 import org.apache.myfaces.shared.config.MyfacesConfig;
29 import org.apache.myfaces.spi.ViewScopeProvider;
30 import org.apache.myfaces.shared.util.LRULinkedHashMap;
31
32
33
34
35 class SerializedViewCollection implements Serializable
36 {
37 private static final Logger log = Logger.getLogger(SerializedViewCollection.class.getName());
38
39 private static final Object[] EMPTY_STATES = new Object[]{null, null};
40
41 private static final long serialVersionUID = -3734849062185115847L;
42 private final List<SerializedViewKey> _keys =
43 new ArrayList<SerializedViewKey>(
44 MyfacesConfig.INIT_PARAM_NUMBER_OF_VIEWS_IN_SESSION_DEFAULT);
45 private final Map<SerializedViewKey, Object> _serializedViews =
46 new HashMap<SerializedViewKey, Object>();
47
48
49
50
51
52
53
54
55 private HashMap<SerializedViewKey, String> _viewScopeIds = null;
56 private HashMap<String, Integer> _viewScopeIdCounts = null;
57
58 private final Map<SerializedViewKey, SerializedViewKey> _precedence =
59 new HashMap<SerializedViewKey, SerializedViewKey>();
60 private Map<String, SerializedViewKey> _lastWindowKeys = null;
61
62 public void put(FacesContext context, Object state,
63 SerializedViewKey key, SerializedViewKey previousRestoredKey)
64 {
65 put(context, state, key, previousRestoredKey, null, null);
66 }
67
68 public synchronized void put(FacesContext context, Object state,
69 SerializedViewKey key, SerializedViewKey previousRestoredKey,
70 ViewScopeProvider viewScopeProvider, String viewScopeId)
71 {
72 if (state == null)
73 {
74 state = EMPTY_STATES;
75 }
76 else if (state instanceof Object[] &&
77 ((Object[])state).length == 2 &&
78 ((Object[])state)[0] == null &&
79 ((Object[])state)[1] == null)
80 {
81
82
83 state = null;
84 }
85
86 if (_serializedViews.containsKey(key))
87 {
88
89 _serializedViews.put(key, state);
90
91 while (_keys.remove(key))
92 {
93
94 }
95 _keys.add(key);
96 return;
97 }
98
99 Integer maxCount = getNumberOfSequentialViewsInSession(context);
100 if (maxCount != null)
101 {
102 if (previousRestoredKey != null)
103 {
104 if (!_serializedViews.isEmpty())
105 {
106 _precedence.put((SerializedViewKey) key, previousRestoredKey);
107 }
108 else
109 {
110
111
112
113
114
115 previousRestoredKey = null;
116 }
117 }
118 }
119 _serializedViews.put(key, state);
120
121 if (viewScopeProvider != null && viewScopeId != null)
122 {
123 if (_viewScopeIds == null)
124 {
125 _viewScopeIds = new HashMap<SerializedViewKey, String>();
126 }
127 _viewScopeIds.put(key, viewScopeId);
128 if (_viewScopeIdCounts == null)
129 {
130 _viewScopeIdCounts = new HashMap<String, Integer>();
131 }
132 Integer vscount = _viewScopeIdCounts.get(viewScopeId);
133 vscount = (vscount == null) ? 1 : vscount + 1;
134 _viewScopeIdCounts.put(viewScopeId, vscount);
135 }
136
137 while (_keys.remove(key))
138 {
139
140 }
141 _keys.add(key);
142
143 if (previousRestoredKey != null && maxCount != null && maxCount > 0)
144 {
145 int count = 0;
146 SerializedViewKey previousKey = (SerializedViewKey) key;
147 do
148 {
149 previousKey = _precedence.get(previousKey);
150 count++;
151 }
152 while (previousKey != null && count < maxCount);
153
154 if (previousKey != null)
155 {
156 SerializedViewKey keyToRemove = (SerializedViewKey) previousKey;
157
158
159
160 do
161 {
162 while (_keys.remove(keyToRemove))
163 {
164
165 }
166
167 _serializedViews.remove(keyToRemove);
168
169 if (viewScopeProvider != null && _viewScopeIds != null)
170 {
171 String oldViewScopeId = _viewScopeIds.remove(keyToRemove);
172 if (oldViewScopeId != null)
173 {
174 Integer vscount = _viewScopeIdCounts.get(oldViewScopeId);
175 vscount = vscount - 1;
176 if (vscount != null && vscount.intValue() < 1)
177 {
178 _viewScopeIdCounts.remove(oldViewScopeId);
179 viewScopeProvider.destroyViewScopeMap(context, oldViewScopeId);
180 }
181 else
182 {
183 _viewScopeIdCounts.put(oldViewScopeId, vscount);
184 }
185 }
186 }
187
188 keyToRemove = _precedence.remove(keyToRemove);
189 }
190 while (keyToRemove != null);
191 }
192 }
193 int views = getNumberOfViewsInSession(context);
194 while (_keys.size() > views)
195 {
196 key = _keys.remove(0);
197 if (maxCount != null && maxCount > 0)
198 {
199 SerializedViewKey keyToRemove = (SerializedViewKey) key;
200
201
202
203 do
204 {
205 keyToRemove = _precedence.remove(keyToRemove);
206 }
207 while (keyToRemove != null);
208 }
209
210 _serializedViews.remove(key);
211
212 if (viewScopeProvider != null && _viewScopeIds != null)
213 {
214 String oldViewScopeId = _viewScopeIds.remove(key);
215 if (oldViewScopeId != null)
216 {
217 Integer vscount = _viewScopeIdCounts.get(oldViewScopeId);
218 vscount = vscount - 1;
219 if (vscount != null && vscount.intValue() < 1)
220 {
221 _viewScopeIdCounts.remove(oldViewScopeId);
222 viewScopeProvider.destroyViewScopeMap(context, oldViewScopeId);
223 }
224 else
225 {
226 _viewScopeIdCounts.put(oldViewScopeId, vscount);
227 }
228 }
229 }
230 }
231 }
232
233 protected Integer getNumberOfSequentialViewsInSession(FacesContext context)
234 {
235 return MyfacesConfig.getCurrentInstance(context.getExternalContext()).getNumberOfSequentialViewsInSession();
236 }
237
238
239
240
241
242
243
244 protected int getNumberOfViewsInSession(FacesContext context)
245 {
246 return MyfacesConfig.getCurrentInstance(context.getExternalContext()).getNumberOfViewsInSession();
247 }
248
249 public synchronized void putLastWindowKey(FacesContext context, String id, SerializedViewKey key)
250 {
251 if (_lastWindowKeys == null)
252 {
253 Integer i = getNumberOfSequentialViewsInSession(context);
254 int j = getNumberOfViewsInSession(context);
255 if (i != null && i> 0)
256 {
257 _lastWindowKeys = new LRULinkedHashMap<>((j / i) + 1);
258 }
259 else
260 {
261 _lastWindowKeys = new LRULinkedHashMap(j + 1);
262 }
263 }
264 _lastWindowKeys.put(id, key);
265 }
266
267 public SerializedViewKey getLastWindowKey(FacesContext context, String id)
268 {
269 if (_lastWindowKeys != null)
270 {
271 return _lastWindowKeys.get(id);
272 }
273 return null;
274 }
275
276 public Object get(SerializedViewKey key)
277 {
278 Object value = _serializedViews.get(key);
279 if (value == null)
280 {
281 if (_serializedViews.containsKey(key))
282 {
283 return EMPTY_STATES;
284 }
285 }
286 else if (value instanceof Object[] &&
287 ((Object[])value).length == 2 &&
288 ((Object[])value)[0] == null &&
289 ((Object[])value)[1] == null)
290 {
291
292 return null;
293 }
294 return value;
295 }
296 }