1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.renderkit.html;
20
21 import java.io.IOException;
22 import java.util.logging.Level;
23 import java.util.logging.Logger;
24
25 import javax.faces.context.ExternalContext;
26 import javax.faces.context.FacesContext;
27 import javax.faces.context.ResponseWriter;
28 import javax.faces.render.RenderKitFactory;
29 import javax.faces.render.ResponseStateManager;
30
31 import org.apache.myfaces.application.StateCache;
32 import org.apache.myfaces.application.StateCacheFactory;
33 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFWebConfigParam;
34 import org.apache.myfaces.renderkit.MyfacesResponseStateManager;
35 import org.apache.myfaces.renderkit.StateCacheFactoryImpl;
36 import org.apache.myfaces.shared.config.MyfacesConfig;
37 import org.apache.myfaces.shared.renderkit.html.HTML;
38 import org.apache.myfaces.shared.renderkit.html.HtmlRendererUtils;
39 import org.apache.myfaces.shared.renderkit.html.util.JavascriptUtils;
40 import org.apache.myfaces.shared.util.StateUtils;
41 import org.apache.myfaces.shared.util.WebConfigParamUtils;
42
43
44
45
46
47 public class HtmlResponseStateManager extends MyfacesResponseStateManager
48 {
49
50 private static final Logger log = Logger.getLogger(HtmlResponseStateManager.class.getName());
51
52
53 private static final int STATE_PARAM = 0;
54 private static final int VIEWID_PARAM = 1;
55
56 public static final String STANDARD_STATE_SAVING_PARAM = "javax.faces.ViewState";
57
58
59
60
61
62
63
64
65
66 @JSFWebConfigParam(since="2.0.6", expectedValues="true, false", defaultValue="true", group="state")
67 public static final String INIT_PARAM_HANDLE_STATE_CACHING_MECHANICS = "org.apache.myfaces.HANDLE_STATE_CACHING_MECHANICS";
68
69 private Boolean _handleStateCachingMechanics;
70
71 private StateCacheFactory _stateCacheFactory;
72
73 public HtmlResponseStateManager()
74 {
75 _stateCacheFactory = new StateCacheFactoryImpl();
76 }
77
78 protected boolean isHandlingStateCachingMechanics(FacesContext facesContext)
79 {
80 if (_handleStateCachingMechanics == null)
81 {
82 _handleStateCachingMechanics = WebConfigParamUtils.getBooleanInitParameter(facesContext.getExternalContext(), INIT_PARAM_HANDLE_STATE_CACHING_MECHANICS, true);
83 }
84 return _handleStateCachingMechanics.booleanValue();
85 }
86
87 public void writeState(FacesContext facesContext, Object state) throws IOException
88 {
89 ResponseWriter responseWriter = facesContext.getResponseWriter();
90
91 Object token = null;
92 Object[] savedState = new Object[2];
93
94 if (isHandlingStateCachingMechanics(facesContext))
95 {
96
97 token = getStateCache(facesContext).encodeSerializedState(facesContext, state);
98 }
99 else
100 {
101 token = state;
102 }
103
104 if (log.isLoggable(Level.FINEST))
105 log.finest("Writing state in client");
106
107
108 if (token != null)
109 {
110 savedState[STATE_PARAM] = token;
111 }
112 else
113 {
114 if (log.isLoggable(Level.FINEST))
115 log.finest("No component states to be saved in client response!");
116 }
117
118 savedState[VIEWID_PARAM] = facesContext.getViewRoot().getViewId();
119
120 if (log.isLoggable(Level.FINEST))
121 log.finest("Writing view state and renderKit fields");
122
123
124 writeViewStateField(facesContext, responseWriter, savedState);
125
126
127 writeRenderKitIdField(facesContext, responseWriter);
128 }
129
130 @Override
131 public void saveState(FacesContext facesContext, Object state)
132 {
133 if (isHandlingStateCachingMechanics(facesContext))
134 {
135 getStateCache(facesContext).saveSerializedView(facesContext, state);
136 }
137 else
138 {
139
140 }
141 }
142
143 private void writeViewStateField(FacesContext facesContext, ResponseWriter responseWriter, Object savedState)
144 throws IOException
145 {
146 String serializedState = StateUtils.construct(savedState, facesContext.getExternalContext());
147 ExternalContext extContext = facesContext.getExternalContext();
148 MyfacesConfig myfacesConfig = MyfacesConfig.getCurrentInstance(extContext);
149
150
151 if (JavascriptUtils.isJavascriptAllowed(extContext) && myfacesConfig.isViewStateJavascript())
152 {
153 HtmlRendererUtils.renderViewStateJavascript(facesContext, STANDARD_STATE_SAVING_PARAM, serializedState);
154 }
155 else
156 {
157 responseWriter.startElement(HTML.INPUT_ELEM, null);
158 responseWriter.writeAttribute(HTML.TYPE_ATTR, HTML.INPUT_TYPE_HIDDEN, null);
159 responseWriter.writeAttribute(HTML.NAME_ATTR, STANDARD_STATE_SAVING_PARAM, null);
160 if (myfacesConfig.isRenderViewStateId())
161 {
162 responseWriter.writeAttribute(HTML.ID_ATTR, STANDARD_STATE_SAVING_PARAM, null);
163 }
164 responseWriter.writeAttribute(HTML.VALUE_ATTR, serializedState, null);
165 responseWriter.endElement(HTML.INPUT_ELEM);
166 }
167 }
168
169 private void writeRenderKitIdField(FacesContext facesContext, ResponseWriter responseWriter) throws IOException
170 {
171
172 String defaultRenderKitId = facesContext.getApplication().getDefaultRenderKitId();
173 if (defaultRenderKitId != null && !RenderKitFactory.HTML_BASIC_RENDER_KIT.equals(defaultRenderKitId))
174 {
175 responseWriter.startElement(HTML.INPUT_ELEM, null);
176 responseWriter.writeAttribute(HTML.TYPE_ATTR, HTML.INPUT_TYPE_HIDDEN, null);
177 responseWriter.writeAttribute(HTML.NAME_ATTR, ResponseStateManager.RENDER_KIT_ID_PARAM, null);
178 responseWriter.writeAttribute(HTML.VALUE_ATTR, defaultRenderKitId, null);
179 responseWriter.endElement(HTML.INPUT_ELEM);
180 }
181 }
182
183 @Override
184 public Object getState(FacesContext facesContext, String viewId)
185 {
186 Object[] savedState = getSavedState(facesContext);
187 if (savedState == null)
188 {
189 return null;
190 }
191
192 if (isHandlingStateCachingMechanics(facesContext))
193 {
194 return getStateCache(facesContext).restoreSerializedView(facesContext, viewId, savedState[STATE_PARAM]);
195 }
196 else
197 {
198 return savedState[STATE_PARAM];
199 }
200 }
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239 private Object[] getSavedState(FacesContext facesContext) {
240 Object encodedState =
241 facesContext.getExternalContext().
242 getRequestParameterMap().get(STANDARD_STATE_SAVING_PARAM);
243 if(encodedState==null || (((String) encodedState).length() == 0)) {
244 return null;
245 }
246
247 Object[] savedState = (Object[])StateUtils.reconstruct((String)encodedState, facesContext.getExternalContext());
248
249
250 if (savedState == null)
251 {
252 if (log.isLoggable(Level.FINEST)) {
253 log.finest("No saved state");
254 }
255 return null;
256 }
257
258 String restoredViewId = (String)savedState[VIEWID_PARAM];
259
260 if (restoredViewId == null)
261 {
262
263 if (log.isLoggable(Level.FINEST))
264 {
265 log.finest("No saved state or state of a different viewId: " + restoredViewId);
266 }
267
268 return null;
269 }
270
271 return savedState;
272 }
273
274
275
276
277
278
279 @Override
280 public boolean isPostback(FacesContext context)
281 {
282 return context.getExternalContext().getRequestParameterMap().containsKey(ResponseStateManager.VIEW_STATE_PARAM);
283 }
284
285 @Override
286 public String getViewState(FacesContext facesContext, Object baseState)
287 {
288 if (baseState == null)
289 {
290 return null;
291 }
292
293 Object state = null;
294 if (isHandlingStateCachingMechanics(facesContext))
295 {
296 state = getStateCache(facesContext).saveSerializedView(facesContext, baseState);
297 }
298 else
299 {
300 state = baseState;
301 }
302
303 Object[] savedState = new Object[2];
304
305 if (state != null)
306 {
307 savedState[STATE_PARAM] = state;
308 }
309
310 savedState[VIEWID_PARAM] = facesContext.getViewRoot().getViewId();
311
312 return StateUtils.construct(savedState, facesContext.getExternalContext());
313 }
314
315 @Override
316 public boolean isWriteStateAfterRenderViewRequired(FacesContext facesContext)
317 {
318 return getStateCache(facesContext).isWriteStateAfterRenderViewRequired(facesContext);
319 }
320
321 protected StateCache getStateCache(FacesContext facesContext)
322 {
323 return _stateCacheFactory.getStateCache(facesContext);
324 }
325
326 }