KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > myfaces > application > jsp > JspStateManagerImpl


1 /*
2  * Copyright 2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.apache.myfaces.application.jsp;
17
18 import org.apache.myfaces.application.MyfacesStateManager;
19 import org.apache.myfaces.application.TreeStructureManager;
20 import org.apache.myfaces.renderkit.MyfacesResponseStateManager;
21
22 import org.apache.commons.logging.Log;
23 import org.apache.commons.logging.LogFactory;
24
25 import javax.faces.FactoryFinder;
26 import javax.faces.application.StateManager;
27 import javax.faces.component.UIViewRoot;
28 import javax.faces.context.ExternalContext;
29 import javax.faces.context.FacesContext;
30 import javax.faces.render.RenderKit;
31 import javax.faces.render.RenderKitFactory;
32 import javax.faces.render.ResponseStateManager;
33 import java.io.IOException JavaDoc;
34
35
36 /**
37  * Default StateManager implementation.
38  * @author Thomas Spiegl (latest modification by $Author: matzew $)
39  * @version $Revision: 1.22 $ $Date: 2005/01/18 07:03:15 $
40  *
41  * @author Thomas Spiegl (latest modification by $Author: matzew $)
42  * @author Manfred Geiler
43  * @version $Revision: 1.22 $ $Date: 2005/01/18 07:03:15 $
44  * $Log: JspStateManagerImpl.java,v $
45  * Revision 1.22 2005/01/18 07:03:15 matzew
46  * added patch form Sean Schofield to solve state saving issue on server side. (MyFaces-81)
47  *
48  * Revision 1.21 2004/10/13 11:50:59 matze
49  * renamed packages to org.apache
50  *
51  * Revision 1.20 2004/08/15 15:35:26 o_rossmueller
52  * fix #1008685: hold view state by viewId
53  *
54  * Revision 1.19 2004/08/15 15:31:09 o_rossmueller
55  * fix #1008685: hold view state by viewId
56  *
57  * Revision 1.18 2004/08/13 13:15:20 manolito
58  * FIXME comment
59  *
60  * Revision 1.17 2004/07/21 11:22:40 mwessendorf
61  * last modification in effect of Adam Winer bug-report.
62  *
63  * Revision 1.16 2004/07/01 22:05:20 mwessendorf
64  * ASF switch
65  *
66  * Revision 1.15 2004/05/18 08:29:38 manolito
67  * saveSerializedView now caches the SerializedView within the request, so that multiple calls only process the saveState methods of components once.
68  *
69  * Revision 1.14 2004/04/13 08:08:08 manolito
70  * NPE bug fix
71  *
72  * Revision 1.13 2004/04/06 10:26:03 royalts
73  * restoreView(...) returns null if restoredViewId != viewId
74  *
75  * Revision 1.12 2004/04/06 10:20:27 manolito
76  * no state restoring for different viewId
77  *
78  * Revision 1.11 2004/03/25 08:52:40 manolito
79  * fixed server state saving
80  */

81 public class JspStateManagerImpl
82     extends MyfacesStateManager
83 {
84     private static final Log log = LogFactory.getLog(JspStateManagerImpl.class);
85     private static final String JavaDoc SERIALIZED_VIEW_SESSION_ATTR
86             = JspStateManagerImpl.class.getName() + ".SERIALIZED_VIEW";
87     private static final String JavaDoc SERIALIZED_VIEW_REQUEST_ATTR
88             = JspStateManagerImpl.class.getName() + ".SERIALIZED_VIEW";
89
90     private RenderKitFactory _renderKitFactory = null;
91
92     public JspStateManagerImpl()
93     {
94         if (log.isTraceEnabled()) log.trace("New JspStateManagerImpl instance created");
95     }
96
97
98     protected Object JavaDoc getComponentStateToSave(FacesContext facesContext)
99     {
100         UIViewRoot viewRoot = facesContext.getViewRoot();
101         if (viewRoot.isTransient())
102         {
103             return null;
104         }
105
106         Object JavaDoc serializedComponentStates = viewRoot.processSaveState(facesContext);
107         //Locale is a state attribute of UIViewRoot and need not be saved explicitly
108
return serializedComponentStates;
109     }
110
111     protected Object JavaDoc getTreeStructureToSave(FacesContext facesContext)
112     {
113         UIViewRoot viewRoot = facesContext.getViewRoot();
114         if (viewRoot.isTransient())
115         {
116             return null;
117         }
118         TreeStructureManager tsm = new TreeStructureManager();
119         return tsm.buildTreeStructureToSave(viewRoot);
120     }
121
122     protected void restoreComponentState(FacesContext facesContext,
123                                          UIViewRoot uiViewRoot,
124                                          String JavaDoc renderKitId)
125     {
126         Object JavaDoc serializedComponentStates;
127         if (isSavingStateInClient(facesContext))
128         {
129             RenderKit renderKit = getRenderKitFactory().getRenderKit(facesContext, renderKitId);
130             ResponseStateManager responseStateManager = renderKit.getResponseStateManager();
131             serializedComponentStates = responseStateManager.getComponentStateToRestore(facesContext);
132             if (serializedComponentStates == null)
133             {
134                 log.error("No serialized component state found in client request!");
135                 // mark UIViewRoot invalid by resetting view id
136
uiViewRoot.setViewId(null);
137                 return;
138             }
139         }
140         else
141         {
142             SerializedView serializedView = getSerializedViewFromServletSession(facesContext.getExternalContext(),
143                                                                                 uiViewRoot.getViewId());
144             if (serializedView == null)
145             {
146                 log.error("No serialized view found in server session!");
147                 // mark UIViewRoot invalid by resetting view id
148
uiViewRoot.setViewId(null);
149                 return;
150             }
151             serializedComponentStates = serializedView.getState();
152             if (serializedComponentStates == null)
153             {
154                 log.error("No serialized component state found in server session!");
155                 return;
156             }
157         }
158
159         if (uiViewRoot.getRenderKitId() == null)
160         {
161             //Just to be sure...
162
uiViewRoot.setRenderKitId(renderKitId);
163         }
164
165         uiViewRoot.processRestoreState(facesContext, serializedComponentStates);
166     }
167
168     protected UIViewRoot restoreTreeStructure(FacesContext facesContext,
169                                               String JavaDoc viewId,
170                                               String JavaDoc renderKitId)
171     {
172         UIViewRoot uiViewRoot = null;
173         if (isSavingStateInClient(facesContext))
174         {
175             //reconstruct tree structure from request
176
RenderKit rk = getRenderKitFactory().getRenderKit(facesContext, renderKitId);
177             ResponseStateManager responseStateManager = rk.getResponseStateManager();
178             Object JavaDoc treeStructure = responseStateManager.getTreeStructureToRestore(facesContext, viewId);
179             if (treeStructure == null)
180             {
181                 if (log.isDebugEnabled()) log.debug("No tree structure state found in client request");
182                 return null;
183             }
184
185             TreeStructureManager tsm = new TreeStructureManager();
186             uiViewRoot = tsm.restoreTreeStructure((TreeStructureManager.TreeStructComponent)treeStructure);
187             if (log.isTraceEnabled()) log.trace("Tree structure restored from client request");
188         }
189         else
190         {
191             //reconstruct tree structure from ServletSession
192
SerializedView serializedView = getSerializedViewFromServletSession(facesContext.getExternalContext(),
193                                                                                 viewId);
194             if (serializedView == null)
195             {
196                 if (log.isDebugEnabled()) log.debug("No serialized view found in server session!");
197                 return null;
198             }
199
200             Object JavaDoc treeStructure = serializedView.getStructure();
201             if (treeStructure == null)
202             {
203                 if (log.isDebugEnabled()) log.debug("No tree structure state found in server session, former UIViewRoot must have been transient");
204                 return null;
205             }
206
207             TreeStructureManager tsm = new TreeStructureManager();
208             uiViewRoot = tsm.restoreTreeStructure((TreeStructureManager.TreeStructComponent)serializedView.getStructure());
209             if (log.isTraceEnabled()) log.trace("Tree structure restored from server session");
210         }
211
212         return uiViewRoot;
213     }
214
215     public UIViewRoot restoreView(FacesContext facescontext, String JavaDoc viewId, String JavaDoc renderKitId)
216     {
217         UIViewRoot uiViewRoot = restoreTreeStructure(facescontext, viewId, renderKitId);
218         if (uiViewRoot != null)
219         {
220             uiViewRoot.setViewId(viewId);
221             restoreComponentState(facescontext, uiViewRoot, renderKitId);
222             String JavaDoc restoredViewId = uiViewRoot.getViewId();
223             if (restoredViewId == null || !(restoredViewId.equals(viewId)))
224             {
225                 return null;
226             }
227
228             if (!isSavingStateInClient(facescontext))
229             {
230                 removeSerializedViewFromServletSession(facescontext.getExternalContext(), viewId);
231             }
232         }
233         return uiViewRoot;
234     }
235
236     public SerializedView saveSerializedView(FacesContext facesContext) throws IllegalStateException JavaDoc
237     {
238         //removeTransientComponents(facesContext.getViewRoot());
239

240         ExternalContext externalContext = facesContext.getExternalContext();
241
242         // SerializedView already created before within this request?
243
SerializedView serializedView = (SerializedView)externalContext.getRequestMap()
244                                                             .get(SERIALIZED_VIEW_REQUEST_ATTR);
245         if (serializedView == null)
246         {
247             // first call to saveSerializedView --> create SerializedView
248
Object JavaDoc treeStruct = getTreeStructureToSave(facesContext);
249             Object JavaDoc compStates = getComponentStateToSave(facesContext);
250             serializedView = new StateManager.SerializedView(treeStruct, compStates);
251             externalContext.getRequestMap().put(SERIALIZED_VIEW_REQUEST_ATTR,
252                                                 serializedView);
253         }
254
255         if (isSavingStateInClient(facesContext))
256         {
257             return serializedView;
258         }
259         else
260         {
261             //save state in server session
262
saveSerializedViewInServletSession(externalContext,
263                                                facesContext.getViewRoot().getViewId(),
264                                                serializedView);
265             return null; //return null to signal that saving is done
266
}
267     }
268
269     public void writeState(FacesContext facesContext,
270                            SerializedView serializedView) throws IOException JavaDoc
271     {
272         if (!isSavingStateInClient(facesContext))
273         {
274             throw new IllegalStateException JavaDoc("Must not be called in server state saving mode");
275         }
276
277         UIViewRoot uiViewRoot = facesContext.getViewRoot();
278         //save state in response (client)
279
RenderKit renderKit = getRenderKitFactory().getRenderKit(facesContext, uiViewRoot.getRenderKitId());
280         renderKit.getResponseStateManager().writeState(facesContext, serializedView);
281     }
282
283     /**
284      * MyFaces extension
285      * @param facesContext
286      * @param serializedView
287      * @throws IOException
288      */

289     public void writeStateAsUrlParams(FacesContext facesContext,
290                                       SerializedView serializedView) throws IOException JavaDoc
291     {
292         if (!isSavingStateInClient(facesContext))
293         {
294             throw new IllegalStateException JavaDoc("Must not be called in server state saving mode");
295         }
296
297         UIViewRoot uiViewRoot = facesContext.getViewRoot();
298         //save state in response (client)
299
RenderKit renderKit = getRenderKitFactory().getRenderKit(facesContext, uiViewRoot.getRenderKitId());
300         ResponseStateManager responseStateManager = renderKit.getResponseStateManager();
301         if (responseStateManager instanceof MyfacesResponseStateManager)
302         {
303             ((MyfacesResponseStateManager)responseStateManager).writeStateAsUrlParams(facesContext,
304                                                                                       serializedView);
305         }
306         else
307         {
308             log.error("ResponseStateManager of render kit " + uiViewRoot.getRenderKitId() + " is no MyfacesResponseStateManager and does not support saving state in url parameters.");
309         }
310     }
311
312
313
314     //helpers
315

316     protected RenderKitFactory getRenderKitFactory()
317     {
318         if (_renderKitFactory == null)
319         {
320             _renderKitFactory = (RenderKitFactory)FactoryFinder.getFactory(FactoryFinder.RENDER_KIT_FACTORY);
321         }
322         return _renderKitFactory;
323     }
324     
325     protected void saveSerializedViewInServletSession(ExternalContext externalContext,
326                                                       String JavaDoc viewId,
327                                                       SerializedView serializedView)
328     {
329         // TODO: What, if user has more than one browser window open on the same page?!
330
// only the state of the latest accessed window will be stored at the moment
331
Object JavaDoc sv[] = new Object JavaDoc[] {serializedView.getStructure(), serializedView.getState()};
332         externalContext.getSessionMap().put(SERIALIZED_VIEW_SESSION_ATTR + "-" + viewId, sv);
333     }
334     
335     protected SerializedView getSerializedViewFromServletSession(ExternalContext externalContext,
336                                                                  String JavaDoc viewId)
337     {
338         String JavaDoc key = SERIALIZED_VIEW_SESSION_ATTR + "-" + viewId;
339         if (externalContext.getSessionMap().get(key) == null)
340         {
341             return null; // no state information in session
342
}
343
344         Object JavaDoc sv[] = (Object JavaDoc[])externalContext.getSessionMap().get(key);
345         return new SerializedView(sv[0], sv[1]);
346     }
347
348     protected void removeSerializedViewFromServletSession(ExternalContext externalContext, String JavaDoc viewId)
349     {
350         externalContext.getSessionMap().remove(SERIALIZED_VIEW_SESSION_ATTR + "-" + viewId);
351     }
352
353     /*
354     protected Map getSessionViewMap(ExternalContext externalContext)
355     {
356         Map sessionMap = externalContext.getSessionMap();
357         Map viewMap = (Map)sessionMap.get(VIEW_MAP_SESSION_PARAM);
358         if (viewMap == null)
359         {
360             viewMap = new HashMap();
361             sessionMap.put(VIEW_MAP_SESSION_PARAM, viewMap);
362         }
363         return viewMap;
364     }
365     */

366
367
368     /*
369     private void removeTransientComponents(UIComponent root)
370     {
371         if (root.getChildCount() > 0)
372         {
373             for (Iterator it = root.getChildren().iterator(); it.hasNext(); )
374             {
375                 UIComponent child = (UIComponent)it.next();
376                 if (child.isTransient())
377                 {
378                     it.remove();
379                 }
380             }
381         }
382
383         for (Iterator it = root.getFacets().values().iterator(); it.hasNext(); )
384         {
385             UIComponent facet = (UIComponent)it.next();
386             if (facet.isTransient())
387             {
388                 it.remove();
389             }
390         }
391     }
392     */

393 }
394
Popular Tags