You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by lu...@apache.org on 2011/08/21 03:23:59 UTC
svn commit: r1159932 - in
/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces:
application/StateManagerImpl.java
view/facelets/DefaultFaceletsStateManagementStrategy.java
Author: lu4242
Date: Sun Aug 21 01:23:58 2011
New Revision: 1159932
URL: http://svn.apache.org/viewvc?rev=1159932&view=rev
Log:
MYFACES-3257 Clarify partial state save/restore traversal requirements
Modified:
myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/StateManagerImpl.java
myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/DefaultFaceletsStateManagementStrategy.java
Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/StateManagerImpl.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/StateManagerImpl.java?rev=1159932&r1=1159931&r2=1159932&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/StateManagerImpl.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/StateManagerImpl.java Sun Aug 21 01:23:58 2011
@@ -149,70 +149,79 @@ public class StateManagerImpl extends St
String viewId = uiViewRoot.getViewId();
ViewDeclarationLanguage vdl = facesContext.getApplication().
getViewHandler().getViewDeclarationLanguage(facesContext,viewId);
- if (vdl != null)
+
+ try
{
- StateManagementStrategy sms = vdl.getStateManagementStrategy(facesContext, viewId);
-
- if (sms != null)
+ facesContext.getAttributes().put(StateManager.IS_SAVING_STATE, Boolean.TRUE);
+ if (vdl != null)
{
- if (log.isLoggable(Level.FINEST)) log.finest("Calling saveView of StateManagementStrategy: "+sms.getClass().getName());
+ StateManagementStrategy sms = vdl.getStateManagementStrategy(facesContext, viewId);
- serializedView = sms.saveView(facesContext);
-
- // If MyfacesResponseStateManager is used, give the option to do
- // additional operations for save the state if is necessary.
- if (StateCacheUtils.isMyFacesResponseStateManager(responseStateManager))
+ if (sms != null)
{
- StateCacheUtils.getMyFacesResponseStateManager(responseStateManager).saveState(facesContext, serializedView);
+ if (log.isLoggable(Level.FINEST)) log.finest("Calling saveView of StateManagementStrategy: "+sms.getClass().getName());
+
+ serializedView = sms.saveView(facesContext);
+
+ // If MyfacesResponseStateManager is used, give the option to do
+ // additional operations for save the state if is necessary.
+ if (StateCacheUtils.isMyFacesResponseStateManager(responseStateManager))
+ {
+ StateCacheUtils.getMyFacesResponseStateManager(responseStateManager).saveState(facesContext, serializedView);
+ }
+
+ return serializedView;
}
-
- return serializedView;
}
+
+ // In StateManagementStrategy.saveView there is a check for transient at
+ // start, but the same applies for VDL without StateManagementStrategy,
+ // so this should be checked before call parent (note that parent method
+ // does not do this check).
+ if (uiViewRoot.isTransient())
+ {
+ return null;
+ }
+
+ if (log.isLoggable(Level.FINEST)) log.finest("Entering saveSerializedView");
+
+ checkForDuplicateIds(facesContext, facesContext.getViewRoot(), new HashSet<String>());
+
+ if (log.isLoggable(Level.FINEST)) log.finest("Processing saveSerializedView - Checked for duplicate Ids");
+
+ ExternalContext externalContext = facesContext.getExternalContext();
+
+ // SerializedView already created before within this request?
+ serializedView = externalContext.getRequestMap()
+ .get(SERIALIZED_VIEW_REQUEST_ATTR);
+ if (serializedView == null)
+ {
+ if (log.isLoggable(Level.FINEST)) log.finest("Processing saveSerializedView - create new serialized view");
+
+ // first call to saveSerializedView --> create SerializedView
+ Object treeStruct = getTreeStructureToSave(facesContext);
+ Object compStates = getComponentStateToSave(facesContext);
+ serializedView = new Object[] {treeStruct, compStates};
+ externalContext.getRequestMap().put(SERIALIZED_VIEW_REQUEST_ATTR,
+ serializedView);
+
+ if (log.isLoggable(Level.FINEST)) log.finest("Processing saveSerializedView - new serialized view created");
+ }
+
+ // If MyfacesResponseStateManager is used, give the option to do
+ // additional operations for save the state if is necessary.
+ if (StateCacheUtils.isMyFacesResponseStateManager(responseStateManager))
+ {
+ StateCacheUtils.getMyFacesResponseStateManager(responseStateManager).saveState(facesContext, serializedView);
+ }
+
+ if (log.isLoggable(Level.FINEST)) log.finest("Exiting saveView");
}
-
- // In StateManagementStrategy.saveView there is a check for transient at
- // start, but the same applies for VDL without StateManagementStrategy,
- // so this should be checked before call parent (note that parent method
- // does not do this check).
- if (uiViewRoot.isTransient())
- {
- return null;
- }
-
- if (log.isLoggable(Level.FINEST)) log.finest("Entering saveSerializedView");
-
- checkForDuplicateIds(facesContext, facesContext.getViewRoot(), new HashSet<String>());
-
- if (log.isLoggable(Level.FINEST)) log.finest("Processing saveSerializedView - Checked for duplicate Ids");
-
- ExternalContext externalContext = facesContext.getExternalContext();
-
- // SerializedView already created before within this request?
- serializedView = externalContext.getRequestMap()
- .get(SERIALIZED_VIEW_REQUEST_ATTR);
- if (serializedView == null)
- {
- if (log.isLoggable(Level.FINEST)) log.finest("Processing saveSerializedView - create new serialized view");
-
- // first call to saveSerializedView --> create SerializedView
- Object treeStruct = getTreeStructureToSave(facesContext);
- Object compStates = getComponentStateToSave(facesContext);
- serializedView = new Object[] {treeStruct, compStates};
- externalContext.getRequestMap().put(SERIALIZED_VIEW_REQUEST_ATTR,
- serializedView);
-
- if (log.isLoggable(Level.FINEST)) log.finest("Processing saveSerializedView - new serialized view created");
- }
-
- // If MyfacesResponseStateManager is used, give the option to do
- // additional operations for save the state if is necessary.
- if (StateCacheUtils.isMyFacesResponseStateManager(responseStateManager))
+ finally
{
- StateCacheUtils.getMyFacesResponseStateManager(responseStateManager).saveState(facesContext, serializedView);
+ facesContext.getAttributes().remove(StateManager.IS_SAVING_STATE);
}
- if (log.isLoggable(Level.FINEST)) log.finest("Exiting saveView");
-
return serializedView;
}
Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/DefaultFaceletsStateManagementStrategy.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/DefaultFaceletsStateManagementStrategy.java?rev=1159932&r1=1159931&r2=1159932&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/DefaultFaceletsStateManagementStrategy.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/DefaultFaceletsStateManagementStrategy.java Sun Aug 21 01:23:58 2011
@@ -21,6 +21,7 @@ package org.apache.myfaces.view.facelets
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
@@ -34,13 +35,16 @@ import javax.faces.component.ContextCall
import javax.faces.component.UIComponent;
import javax.faces.component.UIViewParameter;
import javax.faces.component.UIViewRoot;
+import javax.faces.component.visit.VisitCallback;
+import javax.faces.component.visit.VisitContext;
+import javax.faces.component.visit.VisitHint;
+import javax.faces.component.visit.VisitResult;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.event.PostAddToViewEvent;
import javax.faces.event.PreRemoveFromViewEvent;
import javax.faces.event.SystemEvent;
import javax.faces.event.SystemEventListener;
-import javax.faces.render.RenderKit;
import javax.faces.render.RenderKitFactory;
import javax.faces.render.ResponseStateManager;
import javax.faces.view.StateManagementStrategy;
@@ -49,9 +53,10 @@ import javax.faces.view.ViewDeclarationL
import javax.faces.view.ViewMetadata;
import org.apache.myfaces.application.StateManagerImpl;
-import org.apache.myfaces.shared.renderkit.RendererUtils;
+import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFWebConfigParam;
import org.apache.myfaces.shared.util.ClassUtils;
import org.apache.myfaces.shared.util.HashMapUtils;
+import org.apache.myfaces.shared.util.WebConfigParamUtils;
/**
* This class implements partial state saving feature when facelets
@@ -112,6 +117,17 @@ public class DefaultFaceletsStateManagem
*/
public static final String COMPONENT_ADDED_AFTER_BUILD_VIEW = "oam.COMPONENT_ADDED_AFTER_BUILD_VIEW";
+ /**
+ * If this param is set to true (by default), when pss algorithm is executed to save state, a visit tree
+ * traversal is done, instead a plain traversal like previous versions (2.0.7/2.1.1 and earlier) of MyFaces Core.
+ *
+ * This param is just provided to preserve backwards behavior.
+ */
+ @JSFWebConfigParam(since="2.0.8, 2.1.2", defaultValue="true", expectedValues="true, false")
+ public static final String SAVE_STATE_WITH_VISIT_TREE_ON_PSS = "org.apache.myfaces.SAVE_STATE_WITH_VISIT_TREE_ON_PSS";
+
+ private static final String SKIP_ITERATION_HINT = "javax.faces.visit.SKIP_ITERATION";
+
private static final String SERIALIZED_VIEW_REQUEST_ATTR =
StateManagerImpl.class.getName() + ".SERIALIZED_VIEW";
@@ -119,6 +135,8 @@ public class DefaultFaceletsStateManagem
private RenderKitFactory _renderKitFactory = null;
+ private Boolean _saveStateWithVisitTreeOnPSS;
+
public DefaultFaceletsStateManagementStrategy ()
{
_vdlFactory = (ViewDeclarationLanguageFactory)FactoryFinder.getFactory(FactoryFinder.VIEW_DECLARATION_LANGUAGE_FACTORY);
@@ -449,7 +467,14 @@ public class DefaultFaceletsStateManagem
{
states = new HashMap<String, Object>();
- saveStateOnMap(context,(Map<String,Object>) states, view);
+ if (isSaveStateWithVisitTreeOnPSS(context))
+ {
+ saveStateOnMapVisitTree(context,(Map<String,Object>) states, view);
+ }
+ else
+ {
+ saveStateOnMap(context,(Map<String,Object>) states, view);
+ }
if ( ((Map<String,Object>)states).isEmpty())
{
@@ -626,7 +651,124 @@ public class DefaultFaceletsStateManagem
setClientsIdsAdded(uiViewRoot, clientIdsAdded);
}
+
+ public boolean isSaveStateWithVisitTreeOnPSS(FacesContext facesContext)
+ {
+ if (_saveStateWithVisitTreeOnPSS == null)
+ {
+ _saveStateWithVisitTreeOnPSS = WebConfigParamUtils.getBooleanInitParameter(facesContext.getExternalContext(),
+ SAVE_STATE_WITH_VISIT_TREE_ON_PSS, Boolean.TRUE);
+ }
+ return Boolean.TRUE.equals(_saveStateWithVisitTreeOnPSS);
+ }
+
+ private void saveStateOnMapVisitTree(final FacesContext facesContext, final Map<String,Object> states,
+ final UIViewRoot uiViewRoot)
+ {
+ facesContext.getAttributes().put(SKIP_ITERATION_HINT, Boolean.TRUE);
+ try
+ {
+ EnumSet<VisitHint> visitHints = EnumSet.of(VisitHint.SKIP_ITERATION);
+ uiViewRoot.visitTree( VisitContext.createVisitContext (facesContext, null, visitHints), new VisitCallback()
+ {
+ public VisitResult visit(VisitContext context, UIComponent target)
+ {
+ FacesContext facesContext = context.getFacesContext();
+ Object state;
+
+ if ((target == null) || target.isTransient()) {
+ // No need to bother with these components or their children.
+
+ return VisitResult.REJECT;
+ }
+
+ ComponentState componentAddedAfterBuildView = (ComponentState) target.getAttributes().get(COMPONENT_ADDED_AFTER_BUILD_VIEW);
+
+ //Note if UIViewRoot has this marker, JSF 1.2 like state saving is used.
+ if (componentAddedAfterBuildView != null && (target.getParent() != null))
+ {
+ if (ComponentState.REMOVE_ADD.equals(componentAddedAfterBuildView))
+ {
+ registerOnAddRemoveList(target.getClientId());
+ target.getAttributes().put(COMPONENT_ADDED_AFTER_BUILD_VIEW, ComponentState.ADDED);
+ }
+ else if (ComponentState.ADD.equals(componentAddedAfterBuildView))
+ {
+ registerOnAddList(target.getClientId());
+ target.getAttributes().put(COMPONENT_ADDED_AFTER_BUILD_VIEW, ComponentState.ADDED);
+ }
+ else if (ComponentState.ADDED.equals(componentAddedAfterBuildView))
+ {
+ registerOnAddList(target.getClientId());
+ }
+ ensureClearInitialState(target);
+ //Save all required info to restore the subtree.
+ //This includes position, structure and state of subtree
+
+ int childIndex = target.getParent().getChildren().indexOf(target);
+ if (childIndex >= 0)
+ {
+ states.put(target.getClientId(facesContext), new AttachedFullStateWrapper(
+ new Object[]{
+ target.getParent().getClientId(facesContext),
+ null,
+ childIndex,
+ internalBuildTreeStructureToSave(target),
+ target.processSaveState(facesContext)}));
+ }
+ else
+ {
+ String facetName = null;
+ for (Map.Entry<String, UIComponent> entry : target.getParent().getFacets().entrySet())
+ {
+ if (target.equals(entry.getValue()))
+ {
+ facetName = entry.getKey();
+ break;
+ }
+ }
+ states.put(target.getClientId(facesContext),new AttachedFullStateWrapper(new Object[]{
+ target.getParent().getClientId(facesContext),
+ facetName,
+ null,
+ internalBuildTreeStructureToSave(target),
+ target.processSaveState(facesContext)}));
+ }
+ return VisitResult.REJECT;
+ }
+ else if (uiViewRoot.getParent() != null)
+ {
+ state = target.saveState (facesContext);
+
+ if (state != null) {
+ // Save by client ID into our map.
+
+ states.put (target.getClientId (facesContext), state);
+ }
+
+ return VisitResult.ACCEPT;
+ }
+ else
+ {
+ //Only UIViewRoot has no parent in a component tree.
+ return VisitResult.ACCEPT;
+ }
+ }
+ });
+ }
+ finally
+ {
+ facesContext.getAttributes().remove(SKIP_ITERATION_HINT);
+ }
+
+ Object state = uiViewRoot.saveState (facesContext);
+ if (state != null) {
+ // Save by client ID into our map.
+ states.put (uiViewRoot.getClientId (facesContext), state);
+ }
+ }
+
private void saveStateOnMap(final FacesContext context, final Map<String,Object> states,
final UIComponent component)
{