From 1af61c8e93c2ad75b836489b81e9573e7814181c Mon Sep 17 00:00:00 2001 From: Keith Donald Date: Tue, 7 Apr 2009 17:09:17 +0000 Subject: [PATCH] always clear flash scope on responseComplete unless response is flow execution redirect --- .../webflow/context/ExternalContext.java | 24 ++++++++++++------- .../portlet/PortletExternalContext.java | 16 ++++++++----- .../servlet/ServletExternalContext.java | 16 ++++++++----- .../webflow/engine/ViewState.java | 2 +- .../webflow/test/MockExternalContext.java | 18 +++++++++----- .../portlet/PortletExternalContextTests.java | 7 ++++++ .../servlet/ServletExternalContextTests.java | 6 +++++ 7 files changed, 61 insertions(+), 28 deletions(-) diff --git a/spring-webflow/src/main/java/org/springframework/webflow/context/ExternalContext.java b/spring-webflow/src/main/java/org/springframework/webflow/context/ExternalContext.java index 01648e3e..90cdd48b 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/context/ExternalContext.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/context/ExternalContext.java @@ -151,7 +151,7 @@ public interface ExternalContext { * flow execution to request a refresh operation, usually to support "refresh after event processing" behavior. * Calling this method also sets responseComplete status to true. * @see #isResponseComplete() - * @throws IllegalStateException if the response has completed or is not allowed + * @throws IllegalStateException if the response has completed */ public void requestFlowExecutionRedirect() throws IllegalStateException; @@ -162,7 +162,7 @@ public interface ExternalContext { * @see #isResponseComplete() * @param flowId the id of the flow definition to redirect to * @param input input to pass the flow; this input is generally encoded the url to launch the flow - * @throws IllegalStateException if the response has completed or is not allowed + * @throws IllegalStateException if the response has completed */ public void requestFlowDefinitionRedirect(String flowId, MutableAttributeMap input) throws IllegalStateException; @@ -171,7 +171,7 @@ public interface ExternalContext { * method also sets responseComplete status to true. * @see #isResponseComplete() * @param location the location of the resource to redirect to - * @throws IllegalStateException if the response has completed or is not allowed + * @throws IllegalStateException if the response has completed */ public void requestExternalRedirect(String location) throws IllegalStateException; @@ -193,20 +193,26 @@ public interface ExternalContext { public void recordResponseComplete(); /** - * Has the response been completed via a call to {@link #recordResponseComplete()}? + * Has the response been completed? Response complete status can be achieved by: + * + * @see #getResponseWriter() + * @see #recordResponseComplete() + * @see #requestFlowExecutionRedirect() + * @see #requestFlowDefinitionRedirect(String, MutableAttributeMap) + * @see #requestExternalRedirect(String) * @return true if yes, false otherwise */ public boolean isResponseComplete(); /** - * Returns true if the response has been completed with a request to redirect the caller to another resource. - * Supported redirects are flow execution redirects, flow definition redirects, and external redirects. + * Returns true if the response has been completed with flow execution redirect request. * @return true if a redirect response has been completed * @see #isResponseComplete() * @see #requestFlowExecutionRedirect() - * @see #requestFlowDefinitionRedirect(String, MutableAttributeMap) - * @see #requestExternalRedirect(String) */ - public boolean isRedirectResponseComplete(); + public boolean isResponseCompleteFlowExecutionRedirect(); } \ No newline at end of file diff --git a/spring-webflow/src/main/java/org/springframework/webflow/context/portlet/PortletExternalContext.java b/spring-webflow/src/main/java/org/springframework/webflow/context/portlet/PortletExternalContext.java index c931cbcd..96b0299c 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/context/portlet/PortletExternalContext.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/context/portlet/PortletExternalContext.java @@ -232,6 +232,10 @@ public class PortletExternalContext implements ExternalContext { responseComplete = true; } + public boolean isResponseCompleteFlowExecutionRedirect() { + return flowExecutionRedirectRequested; + } + public void requestFlowExecutionRedirect() throws IllegalStateException { assertRedirectResponseAllowed(); flowExecutionRedirectRequested = true; @@ -252,7 +256,7 @@ public class PortletExternalContext implements ExternalContext { } public void requestRedirectInPopup() throws IllegalStateException { - if (isRedirectResponseComplete()) { + if (isRedirectRequested()) { redirectInPopup = true; } else { throw new IllegalStateException( @@ -260,11 +264,6 @@ public class PortletExternalContext implements ExternalContext { } } - public boolean isRedirectResponseComplete() { - return getFlowExecutionRedirectRequested() || getFlowDefinitionRedirectRequested() - || getExternalRedirectRequested(); - } - // implementation specific methods /** @@ -375,4 +374,9 @@ public class PortletExternalContext implements ExternalContext { } } + private boolean isRedirectRequested() { + return getFlowExecutionRedirectRequested() || getFlowDefinitionRedirectRequested() + || getExternalRedirectRequested(); + } + } diff --git a/spring-webflow/src/main/java/org/springframework/webflow/context/servlet/ServletExternalContext.java b/spring-webflow/src/main/java/org/springframework/webflow/context/servlet/ServletExternalContext.java index c2c5cee3..a34e071c 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/context/servlet/ServletExternalContext.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/context/servlet/ServletExternalContext.java @@ -228,6 +228,10 @@ public class ServletExternalContext implements ExternalContext { responseComplete = true; } + public boolean isResponseCompleteFlowExecutionRedirect() { + return flowExecutionRedirectRequested; + } + public void requestFlowExecutionRedirect() throws IllegalStateException { assertResponseAllowed(); flowExecutionRedirectRequested = true; @@ -248,7 +252,7 @@ public class ServletExternalContext implements ExternalContext { } public void requestRedirectInPopup() throws IllegalStateException { - if (isRedirectResponseComplete()) { + if (isRedirectRequested()) { redirectInPopup = true; } else { throw new IllegalStateException( @@ -256,11 +260,6 @@ public class ServletExternalContext implements ExternalContext { } } - public boolean isRedirectResponseComplete() { - return getFlowExecutionRedirectRequested() || getFlowDefinitionRedirectRequested() - || getExternalRedirectRequested(); - } - // implementation specific methods /** @@ -377,4 +376,9 @@ public class ServletExternalContext implements ExternalContext { } } + private boolean isRedirectRequested() { + return getFlowExecutionRedirectRequested() || getFlowDefinitionRedirectRequested() + || getExternalRedirectRequested(); + } + } \ No newline at end of file diff --git a/spring-webflow/src/main/java/org/springframework/webflow/engine/ViewState.java b/spring-webflow/src/main/java/org/springframework/webflow/engine/ViewState.java index 862cff46..3f327847 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/engine/ViewState.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/engine/ViewState.java @@ -280,7 +280,7 @@ public class ViewState extends TransitionableState { } private void clearFlashIfNotRedirecting(RequestContext context) { - if (!context.getExternalContext().isRedirectResponseComplete()) { + if (!context.getExternalContext().isResponseCompleteFlowExecutionRedirect()) { clearFlash(context); } } diff --git a/spring-webflow/src/main/java/org/springframework/webflow/test/MockExternalContext.java b/spring-webflow/src/main/java/org/springframework/webflow/test/MockExternalContext.java index 22880e31..893e99fa 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/test/MockExternalContext.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/test/MockExternalContext.java @@ -169,6 +169,10 @@ public class MockExternalContext implements ExternalContext { responseComplete = true; } + public boolean isResponseCompleteFlowExecutionRedirect() { + return flowExecutionRedirectRequested; + } + public void requestFlowExecutionRedirect() throws IllegalStateException { assertResponseAllowed(); flowExecutionRedirectRequested = true; @@ -189,7 +193,7 @@ public class MockExternalContext implements ExternalContext { } public void requestRedirectInPopup() throws IllegalStateException { - if (isRedirectResponseComplete()) { + if (isRedirectRequested()) { redirectInPopup = true; } else { throw new IllegalStateException( @@ -197,11 +201,6 @@ public class MockExternalContext implements ExternalContext { } } - public boolean isRedirectResponseComplete() { - return getFlowExecutionRedirectRequested() || getFlowDefinitionRedirectRequested() - || getExternalRedirectRequested(); - } - /** * Set the context path of the application. * @param contextPath the context path @@ -420,6 +419,8 @@ public class MockExternalContext implements ExternalContext { return redirectInPopup; } + // internal helpers + private void assertResponseAllowed() throws IllegalStateException { if (!isResponseAllowed()) { if (getFlowExecutionRedirectRequested()) { @@ -439,6 +440,11 @@ public class MockExternalContext implements ExternalContext { } } + public boolean isRedirectRequested() { + return getFlowExecutionRedirectRequested() || getFlowDefinitionRedirectRequested() + || getExternalRedirectRequested(); + } + private class MockPrincipal implements Principal { private String name; diff --git a/spring-webflow/src/test/java/org/springframework/webflow/context/portlet/PortletExternalContextTests.java b/spring-webflow/src/test/java/org/springframework/webflow/context/portlet/PortletExternalContextTests.java index 34efe634..5957eb3d 100644 --- a/spring-webflow/src/test/java/org/springframework/webflow/context/portlet/PortletExternalContextTests.java +++ b/spring-webflow/src/test/java/org/springframework/webflow/context/portlet/PortletExternalContextTests.java @@ -88,6 +88,7 @@ public class PortletExternalContextTests extends TestCase { context.requestFlowExecutionRedirect(); assertTrue(context.getFlowExecutionRedirectRequested()); assertTrue(context.isResponseComplete()); + assertTrue(context.isResponseCompleteFlowExecutionRedirect()); assertFalse(context.isResponseAllowed()); } @@ -106,6 +107,7 @@ public class PortletExternalContextTests extends TestCase { assertTrue(context.getFlowDefinitionRedirectRequested()); assertEquals("foo", context.getFlowRedirectFlowId()); assertTrue(context.isResponseComplete()); + assertFalse(context.isResponseCompleteFlowExecutionRedirect()); assertFalse(context.isResponseAllowed()); } @@ -124,6 +126,7 @@ public class PortletExternalContextTests extends TestCase { assertTrue(context.getExternalRedirectRequested()); assertEquals("foo", context.getExternalRedirectUrl()); assertTrue(context.isResponseComplete()); + assertFalse(context.isResponseCompleteFlowExecutionRedirect()); } public void testCommitExternalRedirectRenderRequest() { @@ -142,6 +145,7 @@ public class PortletExternalContextTests extends TestCase { assertTrue(context.getFlowExecutionRedirectRequested()); assertTrue(context.getRedirectInPopup()); assertTrue(context.isResponseComplete()); + assertTrue(context.isResponseCompleteFlowExecutionRedirect()); } public void testCommitFlowRedirectPopup() { @@ -151,6 +155,7 @@ public class PortletExternalContextTests extends TestCase { assertEquals("foo", context.getFlowRedirectFlowId()); assertTrue(context.getRedirectInPopup()); assertTrue(context.isResponseComplete()); + assertFalse(context.isResponseCompleteFlowExecutionRedirect()); } public void testCommitExternalRedirectPopup() { @@ -160,6 +165,7 @@ public class PortletExternalContextTests extends TestCase { assertEquals("foo", context.getExternalRedirectUrl()); assertTrue(context.getRedirectInPopup()); assertTrue(context.isResponseComplete()); + assertFalse(context.isResponseCompleteFlowExecutionRedirect()); } public void testExecutionRedirectPopupRenderRequest() { @@ -214,6 +220,7 @@ public class PortletExternalContextTests extends TestCase { assertFalse(context.isResponseAllowed()); context.requestFlowExecutionRedirect(); assertTrue(context.isResponseComplete()); + assertTrue(context.isResponseCompleteFlowExecutionRedirect()); context.requestRedirectInPopup(); assertTrue(context.getRedirectInPopup()); assertFalse(context.isResponseAllowed()); diff --git a/spring-webflow/src/test/java/org/springframework/webflow/context/servlet/ServletExternalContextTests.java b/spring-webflow/src/test/java/org/springframework/webflow/context/servlet/ServletExternalContextTests.java index 1afd6740..13412a54 100644 --- a/spring-webflow/src/test/java/org/springframework/webflow/context/servlet/ServletExternalContextTests.java +++ b/spring-webflow/src/test/java/org/springframework/webflow/context/servlet/ServletExternalContextTests.java @@ -91,6 +91,7 @@ public class ServletExternalContextTests extends TestCase { context.requestFlowExecutionRedirect(); assertTrue(context.getFlowExecutionRedirectRequested()); assertTrue(context.isResponseComplete()); + assertTrue(context.isResponseCompleteFlowExecutionRedirect()); } public void testCommitFlowRedirect() { @@ -98,6 +99,7 @@ public class ServletExternalContextTests extends TestCase { assertTrue(context.getFlowDefinitionRedirectRequested()); assertEquals("foo", context.getFlowRedirectFlowId()); assertTrue(context.isResponseComplete()); + assertFalse(context.isResponseCompleteFlowExecutionRedirect()); } public void testCommitExternalRedirect() { @@ -106,6 +108,7 @@ public class ServletExternalContextTests extends TestCase { assertEquals("foo", context.getExternalRedirectUrl()); assertTrue(context.isResponseComplete()); assertFalse(context.isResponseAllowed()); + assertFalse(context.isResponseCompleteFlowExecutionRedirect()); } public void testCommitExecutionRedirectPopup() { @@ -115,6 +118,7 @@ public class ServletExternalContextTests extends TestCase { assertTrue(context.getRedirectInPopup()); assertTrue(context.isResponseComplete()); assertFalse(context.isResponseAllowed()); + assertTrue(context.isResponseCompleteFlowExecutionRedirect()); } public void testCommitFlowRedirectPopup() { @@ -140,6 +144,7 @@ public class ServletExternalContextTests extends TestCase { context.recordResponseComplete(); assertTrue(context.isResponseComplete()); assertFalse(context.isResponseAllowed()); + assertFalse(context.isResponseCompleteFlowExecutionRedirect()); } public void testDoubleCommitResponse() { @@ -191,6 +196,7 @@ public class ServletExternalContextTests extends TestCase { public void testRedirectInPopup() { context.requestFlowExecutionRedirect(); assertTrue(context.isResponseComplete()); + assertTrue(context.isResponseCompleteFlowExecutionRedirect()); assertFalse(context.isResponseAllowed()); context.requestRedirectInPopup(); assertTrue(context.getRedirectInPopup());