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.application.viewstate.StateCacheFactoryImpl;
34 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFWebConfigParam;
35 import org.apache.myfaces.renderkit.MyfacesResponseStateManager;
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 private static final Logger log = Logger.getLogger(HtmlResponseStateManager.class.getName());
50
51 private static final int STATE_PARAM = 0;
52 private static final int VIEWID_PARAM = 1;
53
54 public static final String STANDARD_STATE_SAVING_PARAM = "javax.faces.ViewState";
55
56
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
68 = "org.apache.myfaces.HANDLE_STATE_CACHING_MECHANICS";
69
70 private Boolean _handleStateCachingMechanics;
71
72 private StateCacheFactory _stateCacheFactory;
73
74 public HtmlResponseStateManager()
75 {
76 _stateCacheFactory = new StateCacheFactoryImpl();
77 }
78
79 protected boolean isHandlingStateCachingMechanics(FacesContext facesContext)
80 {
81 if (_handleStateCachingMechanics == null)
82 {
83 _handleStateCachingMechanics
84 = WebConfigParamUtils.getBooleanInitParameter(facesContext.getExternalContext(),
85 INIT_PARAM_HANDLE_STATE_CACHING_MECHANICS, true);
86 }
87 return _handleStateCachingMechanics.booleanValue();
88 }
89
90 public void writeState(FacesContext facesContext, Object state) throws IOException
91 {
92 ResponseWriter responseWriter = facesContext.getResponseWriter();
93
94 Object savedStateObject = null;
95
96 if (isHandlingStateCachingMechanics(facesContext))
97 {
98 savedStateObject = getStateCache(facesContext).encodeSerializedState(facesContext, state);
99 }
100 else
101 {
102 Object token = null;
103 Object[] savedState = new Object[2];
104 token = state;
105
106 if (log.isLoggable(Level.FINEST))
107 {
108 log.finest("Writing state in client");
109 }
110
111
112 if (token != null)
113 {
114 savedState[STATE_PARAM] = token;
115 }
116 else
117 {
118 if (log.isLoggable(Level.FINEST))
119 {
120 log.finest("No component states to be saved in client response!");
121 }
122 }
123
124 savedState[VIEWID_PARAM] = facesContext.getViewRoot().getViewId();
125
126 if (log.isLoggable(Level.FINEST))
127 {
128 log.finest("Writing view state and renderKit fields");
129 }
130
131 savedStateObject = savedState;
132 }
133
134
135 writeViewStateField(facesContext, responseWriter, savedStateObject);
136
137
138 writeRenderKitIdField(facesContext, responseWriter);
139 }
140
141 @Override
142 public void saveState(FacesContext facesContext, Object state)
143 {
144 if (isHandlingStateCachingMechanics(facesContext))
145 {
146 getStateCache(facesContext).saveSerializedView(facesContext, state);
147 }
148 else
149 {
150
151 }
152 }
153
154 private void writeViewStateField(FacesContext facesContext, ResponseWriter responseWriter, Object savedState)
155 throws IOException
156 {
157 String serializedState = StateUtils.construct(savedState, facesContext.getExternalContext());
158 ExternalContext extContext = facesContext.getExternalContext();
159 MyfacesConfig myfacesConfig = MyfacesConfig.getCurrentInstance(extContext);
160
161
162 if (JavascriptUtils.isJavascriptAllowed(extContext) && myfacesConfig.isViewStateJavascript())
163 {
164 HtmlRendererUtils.renderViewStateJavascript(facesContext, STANDARD_STATE_SAVING_PARAM, serializedState);
165 }
166 else
167 {
168 responseWriter.startElement(HTML.INPUT_ELEM, null);
169 responseWriter.writeAttribute(HTML.TYPE_ATTR, HTML.INPUT_TYPE_HIDDEN, null);
170 responseWriter.writeAttribute(HTML.NAME_ATTR, STANDARD_STATE_SAVING_PARAM, null);
171 if (myfacesConfig.isRenderViewStateId())
172 {
173 responseWriter.writeAttribute(HTML.ID_ATTR, STANDARD_STATE_SAVING_PARAM, null);
174 }
175 responseWriter.writeAttribute(HTML.VALUE_ATTR, serializedState, null);
176 responseWriter.endElement(HTML.INPUT_ELEM);
177 }
178 }
179
180 private void writeRenderKitIdField(FacesContext facesContext, ResponseWriter responseWriter) throws IOException
181 {
182
183 String defaultRenderKitId = facesContext.getApplication().getDefaultRenderKitId();
184 if (defaultRenderKitId != null && !RenderKitFactory.HTML_BASIC_RENDER_KIT.equals(defaultRenderKitId))
185 {
186 responseWriter.startElement(HTML.INPUT_ELEM, null);
187 responseWriter.writeAttribute(HTML.TYPE_ATTR, HTML.INPUT_TYPE_HIDDEN, null);
188 responseWriter.writeAttribute(HTML.NAME_ATTR, ResponseStateManager.RENDER_KIT_ID_PARAM, null);
189 responseWriter.writeAttribute(HTML.VALUE_ATTR, defaultRenderKitId, null);
190 responseWriter.endElement(HTML.INPUT_ELEM);
191 }
192 }
193
194 @Override
195 public Object getState(FacesContext facesContext, String viewId)
196 {
197 Object savedState = getSavedState(facesContext);
198 if (savedState == null)
199 {
200 return null;
201 }
202
203 if (isHandlingStateCachingMechanics(facesContext))
204 {
205 return getStateCache(facesContext).restoreSerializedView(facesContext, viewId, savedState);
206 }
207 else
208 {
209 return ((Object[])savedState)[STATE_PARAM];
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
240
241
242
243
244
245
246
247
248
249
250 private Object getSavedState(FacesContext facesContext)
251 {
252 Object encodedState =
253 facesContext.getExternalContext().getRequestParameterMap().get(STANDARD_STATE_SAVING_PARAM);
254 if(encodedState==null || (((String) encodedState).length() == 0))
255 {
256 return null;
257 }
258
259 Object savedStateObject = StateUtils.reconstruct((String)encodedState, facesContext.getExternalContext());
260
261 if (isHandlingStateCachingMechanics(facesContext))
262 {
263 return savedStateObject;
264 }
265 else
266 {
267 Object[] savedState = (Object[]) savedStateObject;
268
269 if (savedState == null)
270 {
271 if (log.isLoggable(Level.FINEST))
272 {
273 log.finest("No saved state");
274 }
275 return null;
276 }
277
278 String restoredViewId = (String)savedState[VIEWID_PARAM];
279
280 if (restoredViewId == null)
281 {
282
283 if (log.isLoggable(Level.FINEST))
284 {
285 log.finest("No saved state or state of a different viewId: " + restoredViewId);
286 }
287
288 return null;
289 }
290
291 return savedState;
292 }
293 }
294
295
296
297
298
299
300 @Override
301 public boolean isPostback(FacesContext context)
302 {
303 return context.getExternalContext().getRequestParameterMap().containsKey(ResponseStateManager.VIEW_STATE_PARAM);
304 }
305
306 @Override
307 public String getViewState(FacesContext facesContext, Object baseState)
308 {
309 if (baseState == null)
310 {
311 return null;
312 }
313
314 Object state = null;
315 if (isHandlingStateCachingMechanics(facesContext))
316 {
317 state = getStateCache(facesContext).saveSerializedView(facesContext, baseState);
318 }
319 else
320 {
321
322 Object[] savedState = new Object[2];
323
324 if (state != null)
325 {
326 savedState[STATE_PARAM] = baseState;
327 }
328
329 savedState[VIEWID_PARAM] = facesContext.getViewRoot().getViewId();
330
331 state = savedState;
332 }
333 return StateUtils.construct(state, facesContext.getExternalContext());
334 }
335
336 @Override
337 public boolean isWriteStateAfterRenderViewRequired(FacesContext facesContext)
338 {
339 return getStateCache(facesContext).isWriteStateAfterRenderViewRequired(facesContext);
340 }
341
342 protected StateCache getStateCache(FacesContext facesContext)
343 {
344 return _stateCacheFactory.getStateCache(facesContext);
345 }
346
347 }