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 org.apache.commons.logging.Log;
22 import org.apache.commons.logging.LogFactory;
23 import org.apache.myfaces.renderkit.MyfacesResponseStateManager;
24 import org.apache.myfaces.shared_impl.config.MyfacesConfig;
25 import org.apache.myfaces.shared_impl.renderkit.html.HTML;
26 import org.apache.myfaces.shared_impl.renderkit.html.HtmlRendererUtils;
27 import org.apache.myfaces.shared_impl.renderkit.html.util.JavascriptUtils;
28 import org.apache.myfaces.shared_impl.util.StateUtils;
29
30 import javax.faces.application.StateManager;
31 import javax.faces.context.ExternalContext;
32 import javax.faces.context.FacesContext;
33 import javax.faces.context.ResponseWriter;
34 import javax.faces.render.RenderKitFactory;
35 import javax.faces.render.ResponseStateManager;
36 import java.io.IOException;
37
38
39
40
41
42 public class HtmlResponseStateManager
43 extends MyfacesResponseStateManager {
44 private static final Log log = LogFactory.getLog(HtmlResponseStateManager.class);
45
46 private static final int TREE_PARAM = 0;
47 private static final int STATE_PARAM = 1;
48 private static final int VIEWID_PARAM = 2;
49
50 public static final String STANDARD_STATE_SAVING_PARAM = "javax.faces.ViewState";
51
52 public void writeState(FacesContext facescontext,
53 StateManager.SerializedView serializedview) throws IOException {
54 ResponseWriter responseWriter = facescontext.getResponseWriter();
55
56 Object[] savedState = new Object[3];
57
58 if (facescontext.getApplication().getStateManager().isSavingStateInClient(facescontext)) {
59 if (log.isTraceEnabled()) log.trace("Writing state in client");
60 Object treeStruct = serializedview.getStructure();
61 Object compStates = serializedview.getState();
62
63 if(treeStruct != null)
64 {
65 savedState[TREE_PARAM]=treeStruct;
66 }
67 else {
68 log.error("No tree structure to be saved in client response!");
69 }
70
71 if (compStates != null) {
72 savedState[STATE_PARAM] = compStates;
73 }
74 else {
75 log.error("No component states to be saved in client response!");
76 }
77 }
78 else {
79 if (log.isTraceEnabled()) log.trace("Writing state in server");
80
81 Object treeStruct = serializedview.getStructure();
82 if (treeStruct != null) {
83 if (treeStruct instanceof String) {
84 savedState[TREE_PARAM] = treeStruct;
85 }
86 }
87 }
88
89 savedState[VIEWID_PARAM] = facescontext.getViewRoot().getViewId();
90
91 if (log.isTraceEnabled()) log.trace("Writing view state and renderKit fields");
92
93
94 writeViewStateField(facescontext, responseWriter, savedState);
95
96
97 writeRenderKitIdField(facescontext, responseWriter);
98 }
99
100 private void writeViewStateField(FacesContext facesContext,
101 ResponseWriter responseWriter,
102 Object savedState) throws IOException
103 {
104 String serializedState = StateUtils.construct(savedState,
105 facesContext.getExternalContext());
106 ExternalContext extContext = facesContext.getExternalContext();
107 MyfacesConfig myfacesConfig = MyfacesConfig.getCurrentInstance(extContext);
108
109
110 if (JavascriptUtils.isJavascriptAllowed(extContext) && myfacesConfig.isViewStateJavascript()) {
111 HtmlRendererUtils.renderViewStateJavascript(facesContext, STANDARD_STATE_SAVING_PARAM, serializedState);
112 } else {
113 responseWriter.startElement(HTML.INPUT_ELEM, null);
114 responseWriter.writeAttribute(HTML.TYPE_ATTR, HTML.INPUT_TYPE_HIDDEN, null);
115 responseWriter.writeAttribute(HTML.NAME_ATTR, STANDARD_STATE_SAVING_PARAM, null);
116 if (myfacesConfig.isRenderViewStateId()) {
117 responseWriter.writeAttribute(HTML.ID_ATTR, STANDARD_STATE_SAVING_PARAM, null);
118 }
119 responseWriter.writeAttribute(HTML.VALUE_ATTR, serializedState, null);
120 responseWriter.endElement(HTML.INPUT_ELEM);
121 }
122 }
123
124 private void writeRenderKitIdField(FacesContext facesContext,
125 ResponseWriter responseWriter) throws IOException {
126
127 String defaultRenderKitId = facesContext.getApplication().getDefaultRenderKitId();
128 if (defaultRenderKitId != null && !RenderKitFactory.HTML_BASIC_RENDER_KIT.equals(defaultRenderKitId)) {
129 responseWriter.startElement(HTML.INPUT_ELEM, null);
130 responseWriter.writeAttribute(HTML.TYPE_ATTR, HTML.INPUT_TYPE_HIDDEN, null);
131 responseWriter.writeAttribute(HTML.NAME_ATTR, ResponseStateManager.RENDER_KIT_ID_PARAM, null);
132 responseWriter.writeAttribute(HTML.VALUE_ATTR, defaultRenderKitId, null);
133 responseWriter.endElement(HTML.INPUT_ELEM);
134 }
135 }
136
137 @Override
138 public Object getState(FacesContext facesContext, String viewId) {
139 Object[] savedState = getSavedState(facesContext);
140 if (savedState == null) {
141 return null;
142 }
143
144 return new Object[] { savedState[TREE_PARAM], savedState[STATE_PARAM] };
145 }
146
147 @Override
148 public Object getTreeStructureToRestore(FacesContext facesContext, String viewId) {
149
150
151 Object[] savedState = getSavedState(facesContext);
152 if (savedState == null) {
153 return null;
154 }
155
156 return savedState[TREE_PARAM];
157 }
158
159 @Override
160 public Object getComponentStateToRestore(FacesContext facesContext) {
161
162
163 Object[] savedState = getSavedState(facesContext);
164 if (savedState == null) {
165 return null;
166 }
167
168 return savedState[STATE_PARAM];
169 }
170
171
172
173
174
175
176
177
178
179 private Object[] getSavedState(FacesContext facesContext) {
180 Object encodedState =
181 facesContext.getExternalContext().
182 getRequestParameterMap().get(STANDARD_STATE_SAVING_PARAM);
183 if(encodedState==null || (((String) encodedState).length() == 0)) {
184 return null;
185 }
186
187 Object[] savedState = (Object[]) StateUtils.reconstruct(
188 (String) encodedState, facesContext.getExternalContext());
189
190 if (savedState == null)
191 {
192 if (log.isTraceEnabled()) {
193 log.trace("No saved state");
194 }
195 return null;
196 }
197
198 String restoredViewId = (String) savedState[VIEWID_PARAM];
199
200 if (restoredViewId == null) {
201
202 if (log.isTraceEnabled()) {
203 log.trace("No saved state or state of a different viewId: " + restoredViewId);
204 }
205
206 return null;
207 }
208
209 return savedState;
210 }
211
212
213
214
215
216
217 @Override
218 public boolean isPostback(FacesContext context)
219 {
220 return context.getExternalContext()
221 .getRequestParameterMap().containsKey(ResponseStateManager.VIEW_STATE_PARAM);
222 }
223 }
224
225