From 4e062a5a414a4752b7014aca54e7df149c952924 Mon Sep 17 00:00:00 2001 From: Jeremy Grelle Date: Mon, 26 Nov 2007 21:23:01 +0000 Subject: [PATCH] Restoring proper delegation semantics for requests handled by the FacesServlet. --- .../faces/webflow/FlowActionListener.java | 8 ++++ .../faces/webflow/FlowViewHandler.java | 6 ++- .../faces/webflow/FlowViewStateManager.java | 44 ++++++++++++++++++- .../faces/webflow/JsfUtils.java | 11 ++++- .../faces/webflow/JsfViewFactory.java | 7 ++- 5 files changed, 71 insertions(+), 5 deletions(-) diff --git a/spring-faces/src/main/java/org/springframework/faces/webflow/FlowActionListener.java b/spring-faces/src/main/java/org/springframework/faces/webflow/FlowActionListener.java index 76e08ede..a1f5f95f 100644 --- a/spring-faces/src/main/java/org/springframework/faces/webflow/FlowActionListener.java +++ b/spring-faces/src/main/java/org/springframework/faces/webflow/FlowActionListener.java @@ -38,10 +38,18 @@ public class FlowActionListener implements ActionListener { private static final Log logger = LogFactory.getLog(FlowActionListener.class); + private ActionListener delegate; + public FlowActionListener(ActionListener delegate) { + this.delegate = delegate; } public void processAction(ActionEvent actionEvent) throws AbortProcessingException { + if (!JsfUtils.isFlowRequest()) { + delegate.processAction(actionEvent); + return; + } + FacesContext context = FacesContext.getCurrentInstance(); ActionSource source = (ActionSource) actionEvent.getSource(); String result = null; diff --git a/spring-faces/src/main/java/org/springframework/faces/webflow/FlowViewHandler.java b/spring-faces/src/main/java/org/springframework/faces/webflow/FlowViewHandler.java index 8bdb451c..0e11439a 100644 --- a/spring-faces/src/main/java/org/springframework/faces/webflow/FlowViewHandler.java +++ b/spring-faces/src/main/java/org/springframework/faces/webflow/FlowViewHandler.java @@ -40,7 +40,11 @@ public class FlowViewHandler extends ViewHandler { } public String getActionURL(FacesContext context, String viewId) { - return RequestContextHolder.getRequestContext().getFlowExecutionUrl(); + if (JsfUtils.isFlowRequest()) { + return RequestContextHolder.getRequestContext().getFlowExecutionUrl(); + } else { + return delegate.getActionURL(context, viewId); + } } // ------------------- Pass-through delegate methods ------------------// diff --git a/spring-faces/src/main/java/org/springframework/faces/webflow/FlowViewStateManager.java b/spring-faces/src/main/java/org/springframework/faces/webflow/FlowViewStateManager.java index 22deb231..3ded510c 100644 --- a/spring-faces/src/main/java/org/springframework/faces/webflow/FlowViewStateManager.java +++ b/spring-faces/src/main/java/org/springframework/faces/webflow/FlowViewStateManager.java @@ -20,7 +20,17 @@ public class FlowViewStateManager extends StateManager { private static final String ACTIVE_VIEW_ROOT = "org.springframework.webflow.viewRoot"; + private StateManager delegate; + + public FlowViewStateManager(StateManager original) { + this.delegate = original; + } + protected Object getComponentStateToSave(FacesContext context) { + if (!JsfUtils.isFlowRequest()) { + return super.getComponentStateToSave(context); + } + UIViewRoot viewRoot = context.getViewRoot(); if (viewRoot.isTransient()) { return null; @@ -30,6 +40,10 @@ public class FlowViewStateManager extends StateManager { } protected Object getTreeStructureToSave(FacesContext context) { + if (!JsfUtils.isFlowRequest()) { + return super.getTreeStructureToSave(context); + } + UIViewRoot viewRoot = context.getViewRoot(); if (viewRoot.isTransient()) { return null; @@ -39,6 +53,11 @@ public class FlowViewStateManager extends StateManager { } protected void restoreComponentState(FacesContext context, UIViewRoot viewRoot, String renderKitId) { + if (!JsfUtils.isFlowRequest()) { + super.restoreComponentState(context, viewRoot, renderKitId); + return; + } + RequestContext requestContext = RequestContextHolder.getRequestContext(); SerializedView view = (SerializedView) requestContext.getFlowScope().get(SERIALIZED_VIEW_STATE); viewRoot.processRestoreState(context, view.componentState); @@ -46,6 +65,10 @@ public class FlowViewStateManager extends StateManager { } protected UIViewRoot restoreTreeStructure(FacesContext context, String viewId, String renderKitId) { + if (!JsfUtils.isFlowRequest()) { + return super.restoreTreeStructure(context, viewId, renderKitId); + } + RequestContext requestContext = RequestContextHolder.getRequestContext(); SerializedView view = (SerializedView) requestContext.getFlowScope().get(SERIALIZED_VIEW_STATE); if (view == null || !view.viewId.equals(viewId)) { @@ -66,17 +89,29 @@ public class FlowViewStateManager extends StateManager { public void writeState(FacesContext context, javax.faces.application.StateManager.SerializedView state) throws IOException { + if (!JsfUtils.isFlowRequest()) { + delegate.writeState(context, state); + } + // nothing to do, as saving state to client always returns false } public boolean isSavingStateInClient(FacesContext context) { - return false; + if (!JsfUtils.isFlowRequest()) { + return delegate.isSavingStateInClient(context); + } else { + return false; + } } /** * JSF 1.1 version of state saving */ public javax.faces.application.StateManager.SerializedView saveSerializedView(FacesContext context) { + if (!JsfUtils.isFlowRequest()) { + return delegate.saveSerializedView(context); + } + SerializedView view = (SerializedView) saveView(context); return new javax.faces.application.StateManager.SerializedView(view.treeStructure, view.componentState); } @@ -85,6 +120,10 @@ public class FlowViewStateManager extends StateManager { * JSF 1.2 version of state saving */ public Object saveView(FacesContext context) { + if (!JsfUtils.isFlowRequest()) { + return delegate.saveView(context); + } + RequestContext requestContext = RequestContextHolder.getRequestContext(); if (logger.isDebugEnabled()) { logger.debug("Saving view root '" + context.getViewRoot().getViewId() + "' in flow scope"); @@ -96,6 +135,9 @@ public class FlowViewStateManager extends StateManager { } public UIViewRoot restoreView(FacesContext context, String viewId, String renderKitId) { + if (!JsfUtils.isFlowRequest()) { + return delegate.restoreView(context, viewId, renderKitId); + } UIViewRoot viewRoot = restoreTreeStructure(context, viewId, renderKitId); if (viewRoot != null) { diff --git a/spring-faces/src/main/java/org/springframework/faces/webflow/JsfUtils.java b/spring-faces/src/main/java/org/springframework/faces/webflow/JsfUtils.java index 2b2dcbb8..b7930cb3 100644 --- a/spring-faces/src/main/java/org/springframework/faces/webflow/JsfUtils.java +++ b/spring-faces/src/main/java/org/springframework/faces/webflow/JsfUtils.java @@ -50,9 +50,16 @@ class JsfUtils { } } + public static boolean isFlowRequest() { + if (RequestContextHolder.getRequestContext() != null) { + return true; + } else { + return false; + } + } + public static boolean isAsynchronousFlowRequest() { - if (RequestContextHolder.getRequestContext() != null - && RequestContextHolder.getRequestContext().getRequestParameters().contains("ajaxSource")) { + if (isFlowRequest() && RequestContextHolder.getRequestContext().getRequestParameters().contains("ajaxSource")) { return true; } else { return false; diff --git a/spring-faces/src/main/java/org/springframework/faces/webflow/JsfViewFactory.java b/spring-faces/src/main/java/org/springframework/faces/webflow/JsfViewFactory.java index 41a4b983..b9b4f5cf 100644 --- a/spring-faces/src/main/java/org/springframework/faces/webflow/JsfViewFactory.java +++ b/spring-faces/src/main/java/org/springframework/faces/webflow/JsfViewFactory.java @@ -32,6 +32,7 @@ import org.apache.commons.logging.LogFactory; import org.springframework.binding.expression.Expression; import org.springframework.core.io.ContextResource; import org.springframework.core.io.ResourceLoader; +import org.springframework.faces.ui.AjaxViewRoot; import org.springframework.webflow.execution.RequestContext; import org.springframework.webflow.execution.View; import org.springframework.webflow.execution.ViewFactory; @@ -117,7 +118,11 @@ public class JsfViewFactory implements ViewFactory { } private JsfView createJsfView(UIViewRoot root, Lifecycle lifecycle, RequestContext context) { - return new JsfView(root, lifecycle, context); + if (JsfUtils.isAsynchronousFlowRequest()) { + return new JsfView(new AjaxViewRoot(root), lifecycle, context); + } else { + return new JsfView(root, lifecycle, context); + } } private FacesContext createFlowFacesContext(RequestContext context, Lifecycle lifecycle) {