1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.application;
20
21 import java.io.IOException;
22 import java.util.HashSet;
23 import java.util.Set;
24 import java.util.logging.Level;
25 import java.util.logging.Logger;
26
27 import javax.faces.FactoryFinder;
28 import javax.faces.application.StateManager;
29 import javax.faces.component.NamingContainer;
30 import javax.faces.component.UIComponent;
31 import javax.faces.component.UIViewRoot;
32 import javax.faces.context.FacesContext;
33 import javax.faces.render.RenderKit;
34 import javax.faces.render.RenderKitFactory;
35 import javax.faces.render.ResponseStateManager;
36 import javax.faces.view.StateManagementStrategy;
37 import javax.faces.view.ViewDeclarationLanguage;
38
39 import org.apache.myfaces.application.viewstate.StateCacheUtils;
40
41 public class StateManagerImpl extends StateManager
42 {
43 private static final Logger log = Logger.getLogger(StateManagerImpl.class.getName());
44
45 private static final String SERIALIZED_VIEW_REQUEST_ATTR =
46 StateManagerImpl.class.getName() + ".SERIALIZED_VIEW";
47
48 private RenderKitFactory _renderKitFactory = null;
49
50 public StateManagerImpl()
51 {
52 }
53
54 @Override
55 protected Object getComponentStateToSave(FacesContext facesContext)
56 {
57 if (log.isLoggable(Level.FINEST))
58 {
59 log.finest("Entering getComponentStateToSave");
60 }
61
62 UIViewRoot viewRoot = facesContext.getViewRoot();
63 if (viewRoot.isTransient())
64 {
65 return null;
66 }
67
68 Object serializedComponentStates = viewRoot.processSaveState(facesContext);
69
70 if (log.isLoggable(Level.FINEST))
71 {
72 log.finest("Exiting getComponentStateToSave");
73 }
74 return serializedComponentStates;
75 }
76
77
78
79
80
81
82
83 @Override
84 protected Object getTreeStructureToSave(FacesContext facesContext)
85 {
86 if (log.isLoggable(Level.FINEST))
87 {
88 log.finest("Entering getTreeStructureToSave");
89 }
90 UIViewRoot viewRoot = facesContext.getViewRoot();
91 if (viewRoot.isTransient())
92 {
93 return null;
94 }
95 TreeStructureManager tsm = new TreeStructureManager();
96 Object retVal = tsm.buildTreeStructureToSave(viewRoot);
97 if (log.isLoggable(Level.FINEST))
98 {
99 log.finest("Exiting getTreeStructureToSave");
100 }
101 return retVal;
102 }
103
104 @Override
105 public UIViewRoot restoreView(FacesContext facesContext, String viewId, String renderKitId)
106 {
107 if (log.isLoggable(Level.FINEST))
108 {
109 log.finest("Entering restoreView - viewId: " + viewId + " ; renderKitId: " + renderKitId);
110 }
111
112 UIViewRoot uiViewRoot = null;
113
114 ViewDeclarationLanguage vdl = facesContext.getApplication().
115 getViewHandler().getViewDeclarationLanguage(facesContext,viewId);
116 StateManagementStrategy sms = null;
117 if (vdl != null)
118 {
119 sms = vdl.getStateManagementStrategy(facesContext, viewId);
120 }
121
122 if (sms != null)
123 {
124 if (log.isLoggable(Level.FINEST))
125 {
126 log.finest("Redirect to StateManagementStrategy: " + sms.getClass().getName());
127 }
128
129 uiViewRoot = sms.restoreView(facesContext, viewId, renderKitId);
130 }
131 else
132 {
133 RenderKit renderKit = getRenderKitFactory().getRenderKit(facesContext, renderKitId);
134 ResponseStateManager responseStateManager = renderKit.getResponseStateManager();
135
136 Object state = responseStateManager.getState(facesContext, viewId);
137
138 if (state != null)
139 {
140 Object[] stateArray = (Object[])state;
141 TreeStructureManager tsm = new TreeStructureManager();
142 uiViewRoot = tsm.restoreTreeStructure(stateArray[0]);
143
144 if (uiViewRoot != null)
145 {
146 facesContext.setViewRoot (uiViewRoot);
147 uiViewRoot.processRestoreState(facesContext, stateArray[1]);
148 }
149 }
150 }
151 if (log.isLoggable(Level.FINEST))
152 {
153 log.finest("Exiting restoreView - " + viewId);
154 }
155
156 return uiViewRoot;
157 }
158
159
160
161
162
163 @Override
164 public Object saveView(FacesContext facesContext)
165 {
166 Object serializedView = null;
167 UIViewRoot uiViewRoot = facesContext.getViewRoot();
168 ResponseStateManager responseStateManager = facesContext.getRenderKit().getResponseStateManager();
169
170 String viewId = uiViewRoot.getViewId();
171 ViewDeclarationLanguage vdl = facesContext.getApplication().
172 getViewHandler().getViewDeclarationLanguage(facesContext,viewId);
173
174 try
175 {
176 facesContext.getAttributes().put(StateManager.IS_SAVING_STATE, Boolean.TRUE);
177 if (vdl != null)
178 {
179 StateManagementStrategy sms = vdl.getStateManagementStrategy(facesContext, viewId);
180
181 if (sms != null)
182 {
183 if (log.isLoggable(Level.FINEST))
184 {
185 log.finest("Calling saveView of StateManagementStrategy: " + sms.getClass().getName());
186 }
187
188 serializedView = sms.saveView(facesContext);
189
190
191
192 if (StateCacheUtils.isMyFacesResponseStateManager(responseStateManager))
193 {
194 StateCacheUtils.getMyFacesResponseStateManager(responseStateManager).
195 saveState(facesContext, serializedView);
196 }
197
198 return serializedView;
199 }
200 }
201
202
203
204
205
206 if (uiViewRoot.isTransient())
207 {
208 return null;
209 }
210
211 if (log.isLoggable(Level.FINEST))
212 {
213 log.finest("Entering saveSerializedView");
214 }
215
216 checkForDuplicateIds(facesContext, facesContext.getViewRoot(), new HashSet<String>());
217
218 if (log.isLoggable(Level.FINEST))
219 {
220 log.finest("Processing saveSerializedView - Checked for duplicate Ids");
221 }
222
223
224 serializedView = facesContext.getAttributes().get(SERIALIZED_VIEW_REQUEST_ATTR);
225 if (serializedView == null)
226 {
227 if (log.isLoggable(Level.FINEST))
228 {
229 log.finest("Processing saveSerializedView - create new serialized view");
230 }
231
232
233 Object treeStruct = getTreeStructureToSave(facesContext);
234 Object compStates = getComponentStateToSave(facesContext);
235 serializedView = new Object[] {treeStruct, compStates};
236 facesContext.getAttributes().put(SERIALIZED_VIEW_REQUEST_ATTR,
237 serializedView);
238
239 if (log.isLoggable(Level.FINEST))
240 {
241 log.finest("Processing saveSerializedView - new serialized view created");
242 }
243 }
244
245
246
247 if (StateCacheUtils.isMyFacesResponseStateManager(responseStateManager))
248 {
249 StateCacheUtils.getMyFacesResponseStateManager(responseStateManager).
250 saveState(facesContext, serializedView);
251 }
252
253 if (log.isLoggable(Level.FINEST))
254 {
255 log.finest("Exiting saveView");
256 }
257 }
258 finally
259 {
260 facesContext.getAttributes().remove(StateManager.IS_SAVING_STATE);
261 }
262
263 return serializedView;
264 }
265
266 private static void checkForDuplicateIds(FacesContext context,
267 UIComponent component,
268 Set<String> ids)
269 {
270 String id = component.getId();
271 if (id != null && !ids.add(id))
272 {
273 throw new IllegalStateException("Client-id : " + id +
274 " is duplicated in the faces tree. Component : " +
275 component.getClientId(context)+", path: " +
276 getPathToComponent(component));
277 }
278
279 if (component instanceof NamingContainer)
280 {
281 ids = new HashSet<String>();
282 }
283
284 int facetCount = component.getFacetCount();
285 if (facetCount > 0)
286 {
287 for (UIComponent facet : component.getFacets().values())
288 {
289 checkForDuplicateIds (context, facet, ids);
290 }
291 }
292 for (int i = 0, childCount = component.getChildCount(); i < childCount; i++)
293 {
294 UIComponent child = component.getChildren().get(i);
295 checkForDuplicateIds (context, child, ids);
296 }
297 }
298
299 private static String getPathToComponent(UIComponent component)
300 {
301 StringBuffer buf = new StringBuffer();
302
303 if(component == null)
304 {
305 buf.append("{Component-Path : ");
306 buf.append("[null]}");
307 return buf.toString();
308 }
309
310 getPathToComponent(component,buf);
311
312 buf.insert(0,"{Component-Path : ");
313 buf.append("}");
314
315 return buf.toString();
316 }
317
318 private static void getPathToComponent(UIComponent component, StringBuffer buf)
319 {
320 if(component == null)
321 {
322 return;
323 }
324
325 StringBuffer intBuf = new StringBuffer();
326
327 intBuf.append("[Class: ");
328 intBuf.append(component.getClass().getName());
329 if(component instanceof UIViewRoot)
330 {
331 intBuf.append(",ViewId: ");
332 intBuf.append(((UIViewRoot) component).getViewId());
333 }
334 else
335 {
336 intBuf.append(",Id: ");
337 intBuf.append(component.getId());
338 }
339 intBuf.append("]");
340
341 buf.insert(0,intBuf.toString());
342
343 getPathToComponent(component.getParent(),buf);
344 }
345
346 @Override
347 public void writeState(FacesContext facesContext,
348 Object state) throws IOException
349 {
350 if (log.isLoggable(Level.FINEST))
351 {
352 log.finest("Entering writeState");
353 }
354
355
356
357 RenderKit renderKit = facesContext.getRenderKit();
358 ResponseStateManager responseStateManager = renderKit.getResponseStateManager();
359
360 responseStateManager.writeState(facesContext, state);
361
362 if (log.isLoggable(Level.FINEST))
363 {
364 log.finest("Exiting writeState");
365 }
366
367 }
368
369
370
371 protected RenderKitFactory getRenderKitFactory()
372 {
373 if (_renderKitFactory == null)
374 {
375 _renderKitFactory = (RenderKitFactory)FactoryFinder.getFactory(FactoryFinder.RENDER_KIT_FACTORY);
376 }
377 return _renderKitFactory;
378 }
379
380 }