1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.application.jsp;
20
21 import org.apache.commons.collections.map.ReferenceMap;
22 import org.apache.commons.collections.map.AbstractReferenceMap;
23 import org.apache.commons.lang.builder.EqualsBuilder;
24 import org.apache.commons.lang.builder.HashCodeBuilder;
25 import org.apache.commons.logging.Log;
26 import org.apache.commons.logging.LogFactory;
27 import org.apache.myfaces.application.MyfacesStateManager;
28 import org.apache.myfaces.application.TreeStructureManager;
29 import org.apache.myfaces.renderkit.MyfacesResponseStateManager;
30 import org.apache.myfaces.shared_impl.renderkit.ViewSequenceUtils;
31 import org.apache.myfaces.shared_impl.util.MyFacesObjectInputStream;
32
33 import javax.faces.FactoryFinder;
34 import javax.faces.application.StateManager;
35 import javax.faces.component.NamingContainer;
36 import javax.faces.component.UIComponent;
37 import javax.faces.component.UIViewRoot;
38 import javax.faces.context.ExternalContext;
39 import javax.faces.context.FacesContext;
40 import javax.faces.render.RenderKit;
41 import javax.faces.render.RenderKitFactory;
42 import javax.faces.render.ResponseStateManager;
43 import java.io.*;
44 import java.util.*;
45 import java.util.zip.GZIPInputStream;
46 import java.util.zip.GZIPOutputStream;
47
48
49
50
51
52
53
54
55
56 public class JspStateManagerImpl
57 extends MyfacesStateManager {
58 private static final Log log = LogFactory.getLog(JspStateManagerImpl.class);
59 private static final String SERIALIZED_VIEW_SESSION_ATTR
60 = JspStateManagerImpl.class.getName() + ".SERIALIZED_VIEW";
61 private static final String SERIALIZED_VIEW_REQUEST_ATTR
62 = JspStateManagerImpl.class.getName() + ".SERIALIZED_VIEW";
63 private static final String RESTORED_SERIALIZED_VIEW_REQUEST_ATTR
64 = JspStateManagerImpl.class.getName() + ".RESTORED_SERIALIZED_VIEW";
65
66
67
68
69
70
71
72
73
74 private static final String NUMBER_OF_VIEWS_IN_SESSION_PARAM = "org.apache.myfaces.NUMBER_OF_VIEWS_IN_SESSION";
75
76
77
78
79
80
81
82 private static final int DEFAULT_NUMBER_OF_VIEWS_IN_SESSION = 20;
83
84
85
86
87
88
89 private static final String SERIALIZE_STATE_IN_SESSION_PARAM = "org.apache.myfaces.SERIALIZE_STATE_IN_SESSION";
90
91
92
93
94
95
96 private static final String COMPRESS_SERVER_STATE_PARAM = "org.apache.myfaces.COMPRESS_STATE_IN_SESSION";
97
98
99
100
101 private static final boolean DEFAULT_COMPRESS_SERVER_STATE_PARAM = true;
102
103
104
105
106 private static final boolean DEFAULT_SERIALIZE_STATE_IN_SESSION = true;
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 private static final String CACHE_OLD_VIEWS_IN_SESSION_MODE = "org.apache.myfaces.CACHE_OLD_VIEWS_IN_SESSION_MODE";
132
133
134
135
136
137
138 private static final String CACHE_OLD_VIEWS_IN_SESSION_MODE_HARD_SOFT = "hard-soft";
139
140 private static final String CACHE_OLD_VIEWS_IN_SESSION_MODE_SOFT = "soft";
141
142 private static final String CACHE_OLD_VIEWS_IN_SESSION_MODE_SOFT_WEAK = "soft-weak";
143
144 private static final String CACHE_OLD_VIEWS_IN_SESSION_MODE_WEAK = "weak";
145
146 private static final String CACHE_OLD_VIEWS_IN_SESSION_MODE_OFF = "off";
147
148 private static final int UNCOMPRESSED_FLAG = 0;
149 private static final int COMPRESSED_FLAG = 1;
150
151 private RenderKitFactory _renderKitFactory = null;
152
153 public JspStateManagerImpl() {
154 if (log.isTraceEnabled()) log.trace("New JspStateManagerImpl instance created");
155 }
156
157 protected Object getComponentStateToSave(FacesContext facesContext) {
158 if (log.isTraceEnabled()) log.trace("Entering getComponentStateToSave");
159
160 UIViewRoot viewRoot = facesContext.getViewRoot();
161 if (viewRoot.isTransient()) {
162 return null;
163 }
164
165 Object serializedComponentStates = viewRoot.processSaveState(facesContext);
166
167 if (log.isTraceEnabled()) log.trace("Exiting getComponentStateToSave");
168 return serializedComponentStates;
169 }
170
171
172
173
174
175
176
177 protected Object getTreeStructureToSave(FacesContext facesContext) {
178 if (log.isTraceEnabled()) log.trace("Entering getTreeStructureToSave");
179 UIViewRoot viewRoot = facesContext.getViewRoot();
180 if (viewRoot.isTransient()) {
181 return null;
182 }
183 TreeStructureManager tsm = new TreeStructureManager();
184 Object retVal = tsm.buildTreeStructureToSave(viewRoot);
185 if (log.isTraceEnabled()) log.trace("Exiting getTreeStructureToSave");
186 return retVal;
187 }
188
189
190
191
192
193
194
195 protected void restoreComponentState(FacesContext facesContext,
196 UIViewRoot uiViewRoot,
197 String renderKitId) {
198 if (log.isTraceEnabled()) log.trace("Entering restoreComponentState");
199
200
201
202
203
204 Object serializedComponentStates;
205 if (isSavingStateInClient(facesContext)) {
206 RenderKit renderKit = getRenderKitFactory().getRenderKit(facesContext, renderKitId);
207 ResponseStateManager responseStateManager = renderKit.getResponseStateManager();
208 serializedComponentStates = responseStateManager.getComponentStateToRestore(facesContext);
209 if (serializedComponentStates == null) {
210 log.error("No serialized component state found in client request!");
211
212 uiViewRoot.setViewId(null);
213 return;
214 }
215 }
216 else {
217 String viewId = uiViewRoot.getViewId();
218 String sequenceStr = getSequenceString(facesContext, renderKitId, viewId);
219 SerializedView serializedView = getSerializedViewFromServletSession(facesContext,
220 viewId,
221 sequenceStr);
222 if (serializedView == null) {
223 log.error("No serialized view found in server session!");
224
225 uiViewRoot.setViewId(null);
226 return;
227 }
228 serializedComponentStates = serializedView.getState();
229 if (serializedComponentStates == null) {
230 log.error("No serialized component state found in server session!");
231 return;
232 }
233 }
234
235 if (uiViewRoot.getRenderKitId() == null) {
236
237 uiViewRoot.setRenderKitId(renderKitId);
238 }
239
240
241 uiViewRoot.processRestoreState(facesContext, serializedComponentStates);
242
243 if (log.isTraceEnabled()) log.trace("Exiting restoreComponentState");
244 }
245
246
247
248
249 protected UIViewRoot restoreTreeStructure(FacesContext facesContext,
250 String viewId,
251 String renderKitId) {
252 if (log.isTraceEnabled()) log.trace("Entering restoreTreeStructure");
253
254 UIViewRoot uiViewRoot;
255 if (isSavingStateInClient(facesContext)) {
256
257 RenderKit rk = getRenderKitFactory().getRenderKit(facesContext, renderKitId);
258 ResponseStateManager responseStateManager = rk.getResponseStateManager();
259 Object treeStructure = responseStateManager.getTreeStructureToRestore(facesContext, viewId);
260 if (treeStructure == null) {
261 if (log.isDebugEnabled())
262 log.debug("Exiting restoreTreeStructure - No tree structure state found in client request");
263 return null;
264 }
265
266 TreeStructureManager tsm = new TreeStructureManager();
267 uiViewRoot = tsm.restoreTreeStructure((TreeStructureManager.TreeStructComponent) treeStructure);
268 if (log.isTraceEnabled()) log.trace("Tree structure restored from client request");
269 }
270 else {
271 String sequenceStr = getSequenceString(facesContext, renderKitId, viewId);
272
273 SerializedView serializedView = getSerializedViewFromServletSession(facesContext,
274 viewId,
275 sequenceStr);
276 if (serializedView == null) {
277 if (log.isDebugEnabled())
278 log.debug("Exiting restoreTreeStructure - No serialized view found in server session!");
279 return null;
280 }
281
282 Object treeStructure = serializedView.getStructure();
283 if (treeStructure == null) {
284 if (log.isDebugEnabled())
285 log.debug("Exiting restoreTreeStructure - No tree structure state found in server session, former UIViewRoot must have been transient");
286 return null;
287 }
288
289 TreeStructureManager tsm = new TreeStructureManager();
290 uiViewRoot = tsm.restoreTreeStructure((TreeStructureManager.TreeStructComponent) serializedView.getStructure());
291 if (log.isTraceEnabled()) log.trace("Tree structure restored from server session");
292 }
293
294 if (log.isTraceEnabled()) log.trace("Exiting restoreTreeStructure");
295 return uiViewRoot;
296 }
297
298 private String getSequenceString(FacesContext facesContext, String renderKitId, String viewId) {
299 RenderKit rk = getRenderKitFactory().getRenderKit(facesContext, renderKitId);
300
301 if(rk==null)
302 throw new NullPointerException("RenderKit for renderKitId : "+renderKitId + " on viewId : " + viewId + " could not be retrieved. Please specify a valid renderkit-id.");
303
304 ResponseStateManager responseStateManager = rk.getResponseStateManager();
305 String sequenceStr = (String) responseStateManager.getTreeStructureToRestore(facesContext, viewId);
306 return sequenceStr;
307 }
308
309 public UIViewRoot restoreView(FacesContext facescontext, String viewId, String renderKitId) {
310 if (log.isTraceEnabled()) log.trace("Entering restoreView");
311
312 UIViewRoot uiViewRoot = restoreTreeStructure(facescontext, viewId, renderKitId);
313 if (uiViewRoot != null) {
314 uiViewRoot.setViewId(viewId);
315 restoreComponentState(facescontext, uiViewRoot, renderKitId);
316 String restoredViewId = uiViewRoot.getViewId();
317 if (restoredViewId == null || !(restoredViewId.equals(viewId))) {
318 if (log.isTraceEnabled()) log.trace("Exiting restoreView - restored view is null.");
319 return null;
320 }
321 }
322
323 if (log.isTraceEnabled()) log.trace("Exiting restoreView");
324
325 return uiViewRoot;
326 }
327
328 public SerializedView saveSerializedView(FacesContext facesContext) throws IllegalStateException {
329 if (log.isTraceEnabled()) log.trace("Entering saveSerializedView");
330
331 checkForDuplicateIds(facesContext, facesContext.getViewRoot(), new HashSet());
332
333 if (log.isTraceEnabled()) log.trace("Processing saveSerializedView - Checked for duplicate Ids");
334
335 ExternalContext externalContext = facesContext.getExternalContext();
336
337
338 SerializedView serializedView = (SerializedView) externalContext.getRequestMap()
339 .get(SERIALIZED_VIEW_REQUEST_ATTR);
340 if (serializedView == null) {
341 if (log.isTraceEnabled()) log.trace("Processing saveSerializedView - create new serialized view");
342
343
344 Object treeStruct = getTreeStructureToSave(facesContext);
345 Object compStates = getComponentStateToSave(facesContext);
346 serializedView = new StateManager.SerializedView(treeStruct, compStates);
347 externalContext.getRequestMap().put(SERIALIZED_VIEW_REQUEST_ATTR,
348 serializedView);
349
350 if (log.isTraceEnabled()) log.trace("Processing saveSerializedView - new serialized view created");
351 }
352
353 if (!isSavingStateInClient(facesContext)) {
354 if (log.isTraceEnabled())
355 log.trace("Processing saveSerializedView - server-side state saving - save state");
356
357 saveSerializedViewInServletSession(facesContext, serializedView);
358
359 if (log.isTraceEnabled()) log.trace("Exiting saveSerializedView - server-side state saving - saved state");
360 Integer sequence = ViewSequenceUtils.getViewSequence(facesContext);
361 return new SerializedView(sequence.toString(), null);
362 }
363
364 if (log.isTraceEnabled()) log.trace("Exiting saveSerializedView - client-side state saving");
365
366 return serializedView;
367 }
368
369 private static void checkForDuplicateIds(FacesContext context,
370 UIComponent component,
371 Set ids) {
372 String id = component.getId();
373 if (id != null && !ids.add(id)) {
374 throw new IllegalStateException("Client-id : " + id +
375 " is duplicated in the faces tree. Component : " + component.getClientId(context) + ", path: " +
376 getPathToComponent(component));
377 }
378 if (component instanceof NamingContainer)
379 {
380 ids = new HashSet();
381 }
382 Iterator it = component.getFacetsAndChildren();
383 while (it.hasNext()) {
384 UIComponent kid = (UIComponent) it.next();
385 checkForDuplicateIds(context, kid, ids);
386 }
387 }
388
389 private static String getPathToComponent(UIComponent component) {
390 StringBuffer buf = new StringBuffer();
391
392 if (component == null) {
393 buf.append("{Component-Path : ");
394 buf.append("[null]}");
395 return buf.toString();
396 }
397
398 getPathToComponent(component, buf);
399
400 buf.insert(0, "{Component-Path : ");
401 buf.append("}");
402
403 return buf.toString();
404 }
405
406 private static void getPathToComponent(UIComponent component, StringBuffer buf) {
407 if (component == null)
408 return;
409
410 StringBuffer intBuf = new StringBuffer();
411
412 intBuf.append("[Class: ");
413 intBuf.append(component.getClass().getName());
414 if (component instanceof UIViewRoot) {
415 intBuf.append(",ViewId: ");
416 intBuf.append(((UIViewRoot) component).getViewId());
417 }
418 else {
419 intBuf.append(",Id: ");
420 intBuf.append(component.getId());
421 }
422 intBuf.append("]");
423
424 buf.insert(0, intBuf.toString());
425
426 if (component != null) {
427 getPathToComponent(component.getParent(), buf);
428 }
429 }
430
431 public void writeState(FacesContext facesContext,
432 SerializedView serializedView) throws IOException {
433 if (log.isTraceEnabled()) log.trace("Entering writeState");
434
435 if (log.isTraceEnabled())
436 log.trace("Processing writeState - either client-side (full state) or server-side (partial information; e.g. sequence)");
437 if (serializedView != null) {
438 UIViewRoot uiViewRoot = facesContext.getViewRoot();
439
440 RenderKit renderKit = getRenderKitFactory().getRenderKit(facesContext, uiViewRoot.getRenderKitId());
441 renderKit.getResponseStateManager().writeState(facesContext, serializedView);
442
443 if (log.isTraceEnabled()) log.trace("Exiting writeState");
444 }
445 }
446
447
448
449
450
451
452
453
454 public void writeStateAsUrlParams(FacesContext facesContext,
455 SerializedView serializedView) throws IOException {
456 if (log.isTraceEnabled()) log.trace("Entering writeStateAsUrlParams");
457
458 if (isSavingStateInClient(facesContext)) {
459 if (log.isTraceEnabled())
460 log.trace("Processing writeStateAsUrlParams - client-side state saving writing state");
461
462 UIViewRoot uiViewRoot = facesContext.getViewRoot();
463
464 RenderKit renderKit = getRenderKitFactory().getRenderKit(facesContext, uiViewRoot.getRenderKitId());
465 ResponseStateManager responseStateManager = renderKit.getResponseStateManager();
466 if (responseStateManager instanceof MyfacesResponseStateManager) {
467 ((MyfacesResponseStateManager) responseStateManager).writeStateAsUrlParams(facesContext,
468 serializedView);
469 }
470 else {
471 log.error("ResponseStateManager of render kit " + uiViewRoot.getRenderKitId() + " is no MyfacesResponseStateManager and does not support saving state in url parameters.");
472 }
473 }
474
475 if (log.isTraceEnabled()) log.trace("Exiting writeStateAsUrlParams");
476 }
477
478
479
480 protected RenderKitFactory getRenderKitFactory() {
481 if (_renderKitFactory == null) {
482 _renderKitFactory = (RenderKitFactory) FactoryFinder.getFactory(FactoryFinder.RENDER_KIT_FACTORY);
483 }
484 return _renderKitFactory;
485 }
486
487 protected void saveSerializedViewInServletSession(FacesContext context,
488 SerializedView serializedView) {
489 Map sessionMap = context.getExternalContext().getSessionMap();
490 SerializedViewCollection viewCollection = (SerializedViewCollection) sessionMap
491 .get(SERIALIZED_VIEW_SESSION_ATTR);
492 if (viewCollection == null) {
493 viewCollection = new SerializedViewCollection();
494 sessionMap.put(SERIALIZED_VIEW_SESSION_ATTR, viewCollection);
495 }
496 viewCollection.add(context, serializeView(context, serializedView));
497
498 sessionMap.put(SERIALIZED_VIEW_SESSION_ATTR, viewCollection);
499 }
500
501 protected SerializedView getSerializedViewFromServletSession(FacesContext context, String viewId, String sequenceStr) {
502 ExternalContext externalContext = context.getExternalContext();
503 Map requestMap = externalContext.getRequestMap();
504 SerializedView serializedView = null;
505 if (requestMap.containsKey(RESTORED_SERIALIZED_VIEW_REQUEST_ATTR)) {
506 serializedView = (SerializedView) requestMap.get(RESTORED_SERIALIZED_VIEW_REQUEST_ATTR);
507 }
508 else {
509 SerializedViewCollection viewCollection = (SerializedViewCollection) externalContext
510 .getSessionMap().get(SERIALIZED_VIEW_SESSION_ATTR);
511 if (viewCollection != null) {
512 Integer sequence = null;
513 if (sequenceStr == null) {
514
515 sequence = ViewSequenceUtils.getCurrentSequence(context);
516 }
517 else {
518 sequence = new Integer(sequenceStr);
519 }
520 if (sequence != null) {
521 Object state = viewCollection.get(sequence, viewId);
522 if (state != null) {
523 serializedView = deserializeView(state);
524 }
525 }
526 }
527 requestMap.put(RESTORED_SERIALIZED_VIEW_REQUEST_ATTR, serializedView);
528 ViewSequenceUtils.nextViewSequence(context);
529 }
530 return serializedView;
531 }
532
533 protected Object serializeView(FacesContext context, SerializedView serializedView) {
534 if (log.isTraceEnabled()) log.trace("Entering serializeView");
535
536 if (isSerializeStateInSession(context)) {
537 if (log.isTraceEnabled()) log.trace("Processing serializeView - serialize state in session");
538
539 ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);
540 try {
541 OutputStream os = baos;
542 if (isCompressStateInSession(context)) {
543 if (log.isTraceEnabled()) log.trace("Processing serializeView - serialize compressed");
544
545 os.write(COMPRESSED_FLAG);
546 os = new GZIPOutputStream(os, 1024);
547 }
548 else {
549 if (log.isTraceEnabled()) log.trace("Processing serializeView - serialize uncompressed");
550
551 os.write(UNCOMPRESSED_FLAG);
552 }
553 ObjectOutputStream out = new ObjectOutputStream(os);
554 out.writeObject(serializedView.getStructure());
555 out.writeObject(serializedView.getState());
556 out.close();
557 baos.close();
558
559 if (log.isTraceEnabled()) log.trace("Exiting serializeView - serialized. Bytes : " + baos.size());
560 return baos.toByteArray();
561 }
562 catch (IOException e) {
563 log.error("Exiting serializeView - Could not serialize state: " + e.getMessage(), e);
564 return null;
565 }
566 }
567 else {
568 if (log.isTraceEnabled()) log.trace("Exiting serializeView - do not serialize state in session.");
569 return new Object[]{serializedView.getStructure(), serializedView.getState()};
570 }
571 }
572
573
574
575
576
577
578
579
580 protected boolean isSerializeStateInSession(FacesContext context) {
581 String value = context.getExternalContext().getInitParameter(
582 SERIALIZE_STATE_IN_SESSION_PARAM);
583 boolean serialize = DEFAULT_SERIALIZE_STATE_IN_SESSION;
584 if (value != null) {
585 serialize = new Boolean(value).booleanValue();
586 }
587 return serialize;
588 }
589
590
591
592
593
594
595
596
597 protected boolean isCompressStateInSession(FacesContext context) {
598 String value = context.getExternalContext().getInitParameter(
599 COMPRESS_SERVER_STATE_PARAM);
600 boolean compress = DEFAULT_COMPRESS_SERVER_STATE_PARAM;
601 if (value != null) {
602 compress = new Boolean(value).booleanValue();
603 }
604 return compress;
605 }
606
607 protected SerializedView deserializeView(Object state) {
608 if (log.isTraceEnabled()) log.trace("Entering deserializeView");
609
610 if (state instanceof byte[]) {
611 if (log.isTraceEnabled())
612 log.trace("Processing deserializeView - deserializing serialized state. Bytes : " + ((byte[]) state).length);
613
614 try {
615 ByteArrayInputStream bais = new ByteArrayInputStream((byte[]) state);
616 InputStream is = bais;
617 if (is.read() == COMPRESSED_FLAG) {
618 is = new GZIPInputStream(is);
619 }
620 ObjectInputStream in = new MyFacesObjectInputStream(
621 is);
622 return new SerializedView(in.readObject(), in.readObject());
623 }
624 catch (IOException e) {
625 log.error("Exiting deserializeView - Could not deserialize state: " + e.getMessage(), e);
626 return null;
627 }
628 catch (ClassNotFoundException e) {
629 log.error("Exiting deserializeView - Could not deserialize state: " + e.getMessage(), e);
630 return null;
631 }
632 }
633 else if (state instanceof Object[]) {
634 if (log.isTraceEnabled()) log.trace("Exiting deserializeView - state not serialized.");
635
636 Object[] value = (Object[]) state;
637 return new SerializedView(value[0], value[1]);
638 }
639 else if (state == null) {
640 log.error("Exiting deserializeView - this method should not be called with a null-state.");
641 return null;
642 }
643 else {
644 log.error("Exiting deserializeView - this method should not be called with a state of type : " + state.getClass());
645 return null;
646 }
647 }
648
649 protected static class SerializedViewCollection implements Serializable {
650 private static final long serialVersionUID = -3734849062185115847L;
651
652 private final List _keys = new ArrayList(DEFAULT_NUMBER_OF_VIEWS_IN_SESSION);
653 private final Map _serializedViews = new HashMap();
654
655
656
657 private transient Map _oldSerializedViews = null;
658
659 public synchronized void add(FacesContext context, Object state) {
660 Object key = new SerializedViewKey(context);
661 _serializedViews.put(key, state);
662
663 while (_keys.remove(key)) ;
664 _keys.add(key);
665
666 int views = getNumberOfViewsInSession(context);
667 while (_keys.size() > views) {
668 key = _keys.remove(0);
669 Object oldView = _serializedViews.remove(key);
670 if (oldView != null &&
671 !CACHE_OLD_VIEWS_IN_SESSION_MODE_OFF.equals(getCacheOldViewsInSessionMode(context)))
672 {
673 getOldSerializedViewsMap().put(key, oldView);
674 }
675 }
676 }
677
678
679
680
681
682
683
684
685 protected int getNumberOfViewsInSession(FacesContext context) {
686 String value = context.getExternalContext().getInitParameter(
687 NUMBER_OF_VIEWS_IN_SESSION_PARAM);
688 int views = DEFAULT_NUMBER_OF_VIEWS_IN_SESSION;
689 if (value != null) {
690 try {
691 views = Integer.parseInt(value);
692 if (views <= 0) {
693 log.error("Configured value for " + NUMBER_OF_VIEWS_IN_SESSION_PARAM
694 + " is not valid, must be an value > 0, using default value ("
695 + DEFAULT_NUMBER_OF_VIEWS_IN_SESSION);
696 views = DEFAULT_NUMBER_OF_VIEWS_IN_SESSION;
697 }
698 }
699 catch (Throwable e) {
700 log.error("Error determining the value for " + NUMBER_OF_VIEWS_IN_SESSION_PARAM
701 + ", expected an integer value > 0, using default value ("
702 + DEFAULT_NUMBER_OF_VIEWS_IN_SESSION + "): " + e.getMessage(), e);
703 }
704 }
705 return views;
706 }
707
708
709
710
711 protected Map getOldSerializedViewsMap() {
712 FacesContext context = FacesContext.getCurrentInstance();
713 if (_oldSerializedViews == null && context != null)
714 {
715 String cacheMode = getCacheOldViewsInSessionMode(context);
716 if (CACHE_OLD_VIEWS_IN_SESSION_MODE_WEAK.equals(cacheMode))
717 {
718 _oldSerializedViews = new ReferenceMap(AbstractReferenceMap.WEAK, AbstractReferenceMap.WEAK, true);
719 }
720 else if (CACHE_OLD_VIEWS_IN_SESSION_MODE_SOFT_WEAK.equals(cacheMode))
721 {
722 _oldSerializedViews = new ReferenceMap(AbstractReferenceMap.SOFT, AbstractReferenceMap.WEAK, true);
723 }
724 else if (CACHE_OLD_VIEWS_IN_SESSION_MODE_SOFT.equals(cacheMode))
725 {
726 _oldSerializedViews = new ReferenceMap(AbstractReferenceMap.SOFT, AbstractReferenceMap.SOFT, true);
727 }
728 else if (CACHE_OLD_VIEWS_IN_SESSION_MODE_HARD_SOFT.equals(cacheMode))
729 {
730 _oldSerializedViews = new ReferenceMap(AbstractReferenceMap.HARD, AbstractReferenceMap.SOFT);
731 }
732 }
733 return _oldSerializedViews;
734 }
735
736
737
738
739
740
741
742
743
744 protected String getCacheOldViewsInSessionMode(FacesContext context) {
745 String value = context.getExternalContext().getInitParameter(
746 CACHE_OLD_VIEWS_IN_SESSION_MODE);
747 if (value == null)
748 {
749 return CACHE_OLD_VIEWS_IN_SESSION_MODE_OFF;
750 }
751 else if (value.equalsIgnoreCase(CACHE_OLD_VIEWS_IN_SESSION_MODE_SOFT))
752 {
753 return CACHE_OLD_VIEWS_IN_SESSION_MODE_SOFT;
754 }
755 else if (value.equalsIgnoreCase(CACHE_OLD_VIEWS_IN_SESSION_MODE_SOFT_WEAK))
756 {
757 return CACHE_OLD_VIEWS_IN_SESSION_MODE_SOFT_WEAK;
758 }
759 else if (value.equalsIgnoreCase(CACHE_OLD_VIEWS_IN_SESSION_MODE_WEAK))
760 {
761 return CACHE_OLD_VIEWS_IN_SESSION_MODE_WEAK;
762 }
763 else if (value.equalsIgnoreCase(CACHE_OLD_VIEWS_IN_SESSION_MODE_HARD_SOFT))
764 {
765 return CACHE_OLD_VIEWS_IN_SESSION_MODE_HARD_SOFT;
766 }
767 else
768 {
769 return CACHE_OLD_VIEWS_IN_SESSION_MODE_OFF;
770 }
771 }
772
773 public Object get(Integer sequence, String viewId) {
774 Object key = new SerializedViewKey(viewId, sequence);
775 Object value = _serializedViews.get(key);
776 if (value == null)
777 {
778 Map oldSerializedViewMap = getOldSerializedViewsMap();
779 if (oldSerializedViewMap != null)
780 {
781 value = oldSerializedViewMap.get(key);
782 }
783 }
784 return value;
785 }
786 }
787
788 protected static class SerializedViewKey implements Serializable {
789 private static final long serialVersionUID = -1170697124386063642L;
790
791 private final String _viewId;
792 private final Integer _sequenceId;
793
794 public SerializedViewKey(String viewId, Integer sequence) {
795 _sequenceId = sequence;
796 _viewId = viewId;
797 }
798
799 public SerializedViewKey(FacesContext context) {
800 _sequenceId = ViewSequenceUtils.getViewSequence(context);
801 _viewId = context.getViewRoot().getViewId();
802 }
803
804 public boolean equals(Object obj) {
805 if (obj == null) {
806 return false;
807 }
808 if (obj == this) {
809 return true;
810 }
811 if (obj instanceof SerializedViewKey) {
812 SerializedViewKey other = (SerializedViewKey) obj;
813 return new EqualsBuilder().append(other._viewId, _viewId).append(other._sequenceId,
814 _sequenceId).isEquals();
815 }
816 return false;
817 }
818
819 public int hashCode() {
820 return new HashCodeBuilder().append(_viewId).append(_sequenceId).toHashCode();
821 }
822 }
823 }