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 javax.faces.context.ExternalContext;
22 import javax.faces.context.FacesContext;
23
24 import org.apache.myfaces.application.StateCache;
25 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFWebConfigParam;
26 import org.apache.myfaces.shared.util.WebConfigParamUtils;
27
28 class ClientSideStateCacheImpl extends StateCache<Object, Object>
29 {
30
31
32
33
34
35
36 @JSFWebConfigParam(since="2.1.9, 2.0.15", defaultValue="0", group="state")
37 public static final String INIT_PARAM_CLIENT_VIEW_STATE_TIMEOUT =
38 "org.apache.myfaces.CLIENT_VIEW_STATE_TIMEOUT";
39 public static final Long INIT_PARAM_CLIENT_VIEW_STATE_TIMEOUT_DEFAULT = 0L;
40
41 private static final int STATE_PARAM = 0;
42 private static final int VIEWID_PARAM = 1;
43 private static final int TIMESTAMP_PARAM = 2;
44
45 private static final Object[] EMPTY_STATES = new Object[]{null, null};
46
47 private Long _clientViewStateTimeout;
48
49 @Override
50 public Object saveSerializedView(FacesContext facesContext,
51 Object serializedView)
52 {
53
54
55
56 return encodeSerializedState(facesContext, serializedView);
57 }
58
59 @Override
60 public Object restoreSerializedView(FacesContext facesContext,
61 String viewId, Object viewState)
62 {
63 Object[] state = (Object[]) viewState;
64 long clientViewStateTimeout = getClientViewStateTimeout(facesContext.getExternalContext());
65
66 if (clientViewStateTimeout > 0L)
67 {
68 Long timeStamp = (Long) state[TIMESTAMP_PARAM];
69 if (timeStamp == null)
70 {
71
72 return null;
73 }
74 long passedTime = (System.currentTimeMillis() - timeStamp.longValue()) / 60000;
75
76 if (passedTime > clientViewStateTimeout)
77 {
78
79 return null;
80 }
81 }
82
83 String restoredViewId = (String) state[VIEWID_PARAM];
84
85 if (viewId != null && !viewId.equals(restoredViewId))
86 {
87
88 return null;
89 }
90
91
92 if (state[STATE_PARAM] == null)
93 {
94 return EMPTY_STATES;
95 }
96 else
97 {
98 Object serializedView = state[STATE_PARAM];
99 if (serializedView instanceof Object[] &&
100 ((Object[])serializedView).length == 2 &&
101 ((Object[])serializedView)[0] == null &&
102 ((Object[])serializedView)[1] == null)
103 {
104
105 return null;
106 }
107
108 return state[STATE_PARAM];
109 }
110 }
111
112 @Override
113 public Object encodeSerializedState(FacesContext facesContext,
114 Object serializedView)
115 {
116 Object[] state = null;
117
118 if (getClientViewStateTimeout(facesContext.getExternalContext()).longValue() > 0L)
119 {
120 state = new Object[3];
121 state[TIMESTAMP_PARAM] = System.currentTimeMillis();
122 }
123 else
124 {
125 state = new Object[2];
126 }
127
128 if (serializedView == null)
129 {
130 state[STATE_PARAM] = EMPTY_STATES;
131 }
132 else if (serializedView instanceof Object[] &&
133 ((Object[])serializedView).length == 2 &&
134 ((Object[])serializedView)[0] == null &&
135 ((Object[])serializedView)[1] == null)
136 {
137
138
139 state[STATE_PARAM] = null;
140 }
141 else
142 {
143 state[STATE_PARAM] = serializedView;
144 }
145
146 state[VIEWID_PARAM] = facesContext.getViewRoot().getViewId();
147
148 return state;
149 }
150
151 @Override
152 public boolean isWriteStateAfterRenderViewRequired(FacesContext facesContext)
153 {
154 return true;
155 }
156
157
158
159
160 protected Long getClientViewStateTimeout(ExternalContext context)
161 {
162 if (_clientViewStateTimeout == null)
163 {
164 _clientViewStateTimeout = WebConfigParamUtils.getLongInitParameter(
165 context, INIT_PARAM_CLIENT_VIEW_STATE_TIMEOUT,
166 INIT_PARAM_CLIENT_VIEW_STATE_TIMEOUT_DEFAULT);
167 if (_clientViewStateTimeout.longValue() < 0L)
168 {
169 _clientViewStateTimeout = 0L;
170 }
171 }
172 return _clientViewStateTimeout;
173 }
174
175 }