end-state bug fix
This commit is contained in:
@@ -97,26 +97,29 @@ public class JsfViewFactory implements ViewFactory {
|
||||
UIViewRoot viewRoot = viewHandler.restoreView(facesContext, viewName);
|
||||
if (viewRoot != null) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("View root restored for '" + viewName + "'");
|
||||
logger.debug("UIViewRoot restored for '" + viewName + "'");
|
||||
}
|
||||
facesContext.setViewRoot(viewRoot);
|
||||
processTree(facesContext, viewRoot);
|
||||
view = createJsfView(viewRoot, lifecycle, context);
|
||||
facesContext.setViewRoot(view.getViewRoot());
|
||||
processTree(facesContext, view.getViewRoot());
|
||||
view.setRestored(true);
|
||||
} else {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Creating view root for '" + viewName + "'");
|
||||
logger.debug("Creating UIViewRoot from '" + viewName + "'");
|
||||
}
|
||||
view = createJsfView(viewHandler.createView(facesContext, viewName), lifecycle, context);
|
||||
facesContext.setViewRoot(view.getViewRoot());
|
||||
viewRoot = viewHandler.createView(facesContext, viewName);
|
||||
facesContext.setViewRoot(viewRoot);
|
||||
view = createJsfView(viewRoot, lifecycle, context);
|
||||
view.setRestored(false);
|
||||
}
|
||||
} else {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Creating view root for '" + viewName + "'");
|
||||
logger.debug("Creating transient UIViewRoot from '" + viewName + "'");
|
||||
}
|
||||
view = createJsfView(viewHandler.createView(facesContext, viewName), lifecycle, context);
|
||||
facesContext.setViewRoot(view.getViewRoot());
|
||||
UIViewRoot viewRoot = viewHandler.createView(facesContext, viewName);
|
||||
viewRoot.setTransient(true);
|
||||
facesContext.setViewRoot(viewRoot);
|
||||
view = createJsfView(viewRoot, lifecycle, context);
|
||||
view.setRestored(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,34 +137,31 @@ public interface ExternalContext {
|
||||
*/
|
||||
public Writer getResponseWriter();
|
||||
|
||||
/**
|
||||
* Is a response allowed to be written for this request?
|
||||
* @return true if yes, false otherwise
|
||||
*/
|
||||
public boolean isResponseAllowed();
|
||||
|
||||
/**
|
||||
* Request that a flow execution redirect be performed by the calling environment. Typically called from within a
|
||||
* flow execution to request a refresh operation, usually to support "refresh after event processing" behavior.
|
||||
* Calling this method commits the response.
|
||||
* @see #isResponseCommitted()
|
||||
* @throws IllegalStateException if a response has already been committed
|
||||
*/
|
||||
public void requestFlowExecutionRedirect() throws IllegalStateException;
|
||||
public void requestFlowExecutionRedirect();
|
||||
|
||||
/**
|
||||
* Request that a flow definition redirect be performed by the calling environment. Typically called from within a
|
||||
* flow execution end state to request starting a new, independent execution of a flow in a chain-like manner.
|
||||
* Calling this method commits the response.
|
||||
* @see #isResponseCommitted()
|
||||
* @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 a response has already been committed
|
||||
*/
|
||||
public void requestFlowDefinitionRedirect(String flowId, MutableAttributeMap input) throws IllegalStateException;
|
||||
public void requestFlowDefinitionRedirect(String flowId, MutableAttributeMap input);
|
||||
|
||||
/**
|
||||
* Request a redirect to an arbitrary resource location. May not be supported in some environments. Calling this
|
||||
* method commits the response.
|
||||
* @see #isResponseCommitted()
|
||||
* Request a redirect to an arbitrary resource location. May not be supported in some environments.
|
||||
* @param location the location of the resource to redirect to
|
||||
* @throws IllegalStateException if a response has already been committed
|
||||
*/
|
||||
public void requestExternalRedirect(String location) throws IllegalStateException;
|
||||
public void requestExternalRedirect(String location);
|
||||
|
||||
/**
|
||||
* Request that the redirect response requested be sent to the client in a manner that causes the client to issue
|
||||
@@ -179,20 +176,13 @@ public interface ExternalContext {
|
||||
* Called by flow artifacts such as View states and end states to indicate they handled the response, typically by
|
||||
* writing out content to the response stream. Setting this flag allows this external context to know the response
|
||||
* was handled, and that it not need to take additional response handling action itself.
|
||||
* @throws IllegalStateException if a response has already been committed
|
||||
*/
|
||||
public void recordResponseCommitted() throws IllegalStateException;
|
||||
public void recordResponseComplete();
|
||||
|
||||
/**
|
||||
* Has the response been committed?
|
||||
* Has the response been completed via a call to {@link #recordResponseComplete()}?
|
||||
* @return true if yes, false otherwise
|
||||
*/
|
||||
public boolean isResponseCommitted();
|
||||
|
||||
/**
|
||||
* Is a response allowed to be written for this request?
|
||||
* @return true if yes, false otherwise
|
||||
*/
|
||||
public boolean isResponseAllowed();
|
||||
public boolean isResponseComplete();
|
||||
|
||||
}
|
||||
@@ -28,7 +28,6 @@ import javax.portlet.PortletResponse;
|
||||
import javax.portlet.RenderRequest;
|
||||
import javax.portlet.RenderResponse;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.webflow.context.ExternalContext;
|
||||
import org.springframework.webflow.core.collection.LocalAttributeMap;
|
||||
import org.springframework.webflow.core.collection.LocalParameterMap;
|
||||
@@ -93,7 +92,7 @@ public class PortletExternalContext implements ExternalContext {
|
||||
|
||||
/**
|
||||
* A flag indicating if the flow committed the response. Set to true by requesting an execution redirect, definition
|
||||
* redirect, external redirect, or by calling {@link ExternalContext#recordResponseCommitted()}
|
||||
* redirect, external redirect, or by calling {@link ExternalContext#recordResponseComplete()}
|
||||
*/
|
||||
private boolean responseCommitted;
|
||||
|
||||
@@ -227,27 +226,23 @@ public class PortletExternalContext implements ExternalContext {
|
||||
return isRenderPhase();
|
||||
}
|
||||
|
||||
public boolean isResponseCommitted() {
|
||||
public boolean isResponseComplete() {
|
||||
return responseCommitted;
|
||||
}
|
||||
|
||||
public void recordResponseCommitted() {
|
||||
assertResponseNotCommitted();
|
||||
public void recordResponseComplete() {
|
||||
responseCommitted = true;
|
||||
}
|
||||
|
||||
public void requestFlowExecutionRedirect() {
|
||||
recordResponseCommitted();
|
||||
flowExecutionRedirectRequested = true;
|
||||
}
|
||||
|
||||
public void requestExternalRedirect(String uri) {
|
||||
recordResponseCommitted();
|
||||
externalRedirectUrl = uri;
|
||||
}
|
||||
|
||||
public void requestFlowDefinitionRedirect(String flowId, MutableAttributeMap input) {
|
||||
recordResponseCommitted();
|
||||
flowDefinitionRedirectFlowId = flowId;
|
||||
flowDefinitionRedirectFlowInput = input;
|
||||
}
|
||||
@@ -344,8 +339,4 @@ public class PortletExternalContext implements ExternalContext {
|
||||
}
|
||||
}
|
||||
|
||||
private void assertResponseNotCommitted() throws IllegalStateException {
|
||||
Assert.isTrue(!responseCommitted, "A response has already been committed to this ExternalContext");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -24,7 +24,6 @@ import javax.servlet.ServletContext;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.webflow.context.ExternalContext;
|
||||
import org.springframework.webflow.core.collection.LocalAttributeMap;
|
||||
import org.springframework.webflow.core.collection.LocalParameterMap;
|
||||
@@ -79,7 +78,7 @@ public class ServletExternalContext implements ExternalContext {
|
||||
|
||||
/**
|
||||
* A flag indicating if the flow committed the response. Set to true by requesting an execution redirect, definition
|
||||
* redirect, external redirect, or by calling {@link ExternalContext#recordResponseCommitted()}
|
||||
* redirect, external redirect, or by calling {@link ExternalContext#recordResponseComplete()}
|
||||
*/
|
||||
private boolean responseCommitted;
|
||||
|
||||
@@ -220,27 +219,23 @@ public class ServletExternalContext implements ExternalContext {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isResponseCommitted() {
|
||||
public boolean isResponseComplete() {
|
||||
return responseCommitted;
|
||||
}
|
||||
|
||||
public void recordResponseCommitted() {
|
||||
assertResponseNotCommitted();
|
||||
public void recordResponseComplete() {
|
||||
responseCommitted = true;
|
||||
}
|
||||
|
||||
public void requestFlowExecutionRedirect() {
|
||||
recordResponseCommitted();
|
||||
flowExecutionRedirectRequested = true;
|
||||
}
|
||||
|
||||
public void requestExternalRedirect(String location) {
|
||||
recordResponseCommitted();
|
||||
externalRedirectUrl = location;
|
||||
}
|
||||
|
||||
public void requestFlowDefinitionRedirect(String flowId, MutableAttributeMap input) {
|
||||
recordResponseCommitted();
|
||||
flowDefinitionRedirectFlowId = flowId;
|
||||
flowDefinitionRedirectFlowInput = input;
|
||||
}
|
||||
@@ -346,7 +341,4 @@ public class ServletExternalContext implements ExternalContext {
|
||||
this.flowUrlHandler = flowUrlHandler;
|
||||
}
|
||||
|
||||
private void assertResponseNotCommitted() throws IllegalStateException {
|
||||
Assert.isTrue(!responseCommitted, "A response has already been committed to this ExternalContext");
|
||||
}
|
||||
}
|
||||
@@ -98,7 +98,7 @@ public class EndState extends State {
|
||||
// entire flow execution is ending; issue the final response
|
||||
if (finalResponseAction != null && context.getExternalContext().isResponseAllowed()) {
|
||||
ActionExecutor.execute(finalResponseAction, context);
|
||||
context.getExternalContext().recordResponseCommitted();
|
||||
context.getExternalContext().recordResponseComplete();
|
||||
}
|
||||
context.endActiveFlowSession(getId(), createSessionOutput(context));
|
||||
} else {
|
||||
|
||||
@@ -243,8 +243,8 @@ public class ViewState extends TransitionableState {
|
||||
}
|
||||
context.getFlashScope().clear();
|
||||
context.getMessageContext().clearMessages();
|
||||
context.getExternalContext().recordResponseComplete();
|
||||
context.viewRendered(view);
|
||||
context.getExternalContext().recordResponseCommitted();
|
||||
}
|
||||
|
||||
private void restoreVariables(RequestContext context) {
|
||||
|
||||
@@ -570,9 +570,15 @@ public class FlowModelFlowBuilder extends AbstractFlowBuilder {
|
||||
attributes.put("commit", fromStringTo(Boolean.class).execute(state.getCommit()));
|
||||
}
|
||||
parseAndPutSecured(state.getSecured(), attributes);
|
||||
Action finalResponseAction;
|
||||
ViewFactory viewFactory = parseViewFactory(state.getView(), state.getId(), true);
|
||||
if (viewFactory != null) {
|
||||
finalResponseAction = new ViewFactoryActionAdapter(viewFactory);
|
||||
} else {
|
||||
finalResponseAction = null;
|
||||
}
|
||||
getLocalContext().getFlowArtifactFactory().createEndState(state.getId(), flow,
|
||||
parseActions(state.getOnEntryActions()),
|
||||
new ViewFactoryActionAdapter(parseViewFactory(state.getView(), state.getId(), true)),
|
||||
parseActions(state.getOnEntryActions()), finalResponseAction,
|
||||
parseFlowOutputMapper(state.getOutputs()), parseExceptionHandlers(state.getExceptionHandlers(), null),
|
||||
attributes);
|
||||
}
|
||||
|
||||
@@ -253,7 +253,7 @@ public class FlowHandlerAdapter extends WebContentGenerator implements HandlerAd
|
||||
protected void defaultHandleExecutionOutcome(String flowId, FlowExecutionOutcome outcome,
|
||||
ServletExternalContext context, HttpServletRequest request, HttpServletResponse response)
|
||||
throws IOException {
|
||||
if (!context.isResponseCommitted()) {
|
||||
if (!context.isResponseComplete()) {
|
||||
// by default, just start the flow over passing the output as input
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Ended flow '" + flowId + "' did not commit a response; "
|
||||
|
||||
@@ -154,27 +154,24 @@ public class MockExternalContext implements ExternalContext {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isResponseCommitted() {
|
||||
public boolean isResponseComplete() {
|
||||
return responseCommitted;
|
||||
}
|
||||
|
||||
public void recordResponseCommitted() throws IllegalStateException {
|
||||
public void recordResponseComplete() throws IllegalStateException {
|
||||
responseCommitted = true;
|
||||
}
|
||||
|
||||
public void requestFlowExecutionRedirect() {
|
||||
recordResponseCommitted();
|
||||
flowExecutionRedirectRequested = true;
|
||||
}
|
||||
|
||||
public void requestFlowDefinitionRedirect(String flowId, MutableAttributeMap input) {
|
||||
recordResponseCommitted();
|
||||
flowDefinitionRedirectFlowId = flowId;
|
||||
flowDefinitionRedirectFlowInput = input;
|
||||
}
|
||||
|
||||
public void requestExternalRedirect(String uri) {
|
||||
recordResponseCommitted();
|
||||
externalRedirectUrl = uri;
|
||||
}
|
||||
|
||||
|
||||
@@ -68,25 +68,22 @@ public class PortletExternalContextTests extends TestCase {
|
||||
}
|
||||
|
||||
public void testNotResponseCommitted() {
|
||||
assertFalse(context.isResponseCommitted());
|
||||
assertFalse(context.isResponseComplete());
|
||||
}
|
||||
|
||||
public void testCommitExecutionRedirect() {
|
||||
context.requestFlowExecutionRedirect();
|
||||
assertTrue(context.isResponseCommitted());
|
||||
assertTrue(context.getFlowExecutionRedirectRequested());
|
||||
}
|
||||
|
||||
public void testCommitFlowRedirect() {
|
||||
context.requestFlowDefinitionRedirect("foo", null);
|
||||
assertTrue(context.isResponseCommitted());
|
||||
assertTrue(context.getFlowDefinitionRedirectRequested());
|
||||
assertEquals("foo", context.getFlowRedirectFlowId());
|
||||
}
|
||||
|
||||
public void testCommitExternalRedirect() {
|
||||
context.requestExternalRedirect("foo");
|
||||
assertTrue(context.isResponseCommitted());
|
||||
assertTrue(context.getExternalRedirectRequested());
|
||||
assertEquals("foo", context.getExternalRedirectUrl());
|
||||
}
|
||||
@@ -94,7 +91,6 @@ public class PortletExternalContextTests extends TestCase {
|
||||
public void testCommitExecutionRedirectPopup() {
|
||||
context.requestFlowExecutionRedirect();
|
||||
context.requestRedirectInPopup();
|
||||
assertTrue(context.isResponseCommitted());
|
||||
assertTrue(context.getFlowExecutionRedirectRequested());
|
||||
assertTrue(context.getRedirectInPopup());
|
||||
}
|
||||
@@ -102,7 +98,6 @@ public class PortletExternalContextTests extends TestCase {
|
||||
public void testCommitFlowRedirectPopup() {
|
||||
context.requestFlowDefinitionRedirect("foo", null);
|
||||
context.requestRedirectInPopup();
|
||||
assertTrue(context.isResponseCommitted());
|
||||
assertTrue(context.getFlowDefinitionRedirectRequested());
|
||||
assertEquals("foo", context.getFlowRedirectFlowId());
|
||||
assertTrue(context.getRedirectInPopup());
|
||||
@@ -111,7 +106,6 @@ public class PortletExternalContextTests extends TestCase {
|
||||
public void testCommitExternalRedirectPopup() {
|
||||
context.requestExternalRedirect("foo");
|
||||
context.requestRedirectInPopup();
|
||||
assertTrue(context.isResponseCommitted());
|
||||
assertTrue(context.getExternalRedirectRequested());
|
||||
assertEquals("foo", context.getExternalRedirectUrl());
|
||||
assertTrue(context.getRedirectInPopup());
|
||||
|
||||
@@ -66,25 +66,22 @@ public class ServletExternalContextTests extends TestCase {
|
||||
}
|
||||
|
||||
public void testNotResponseCommitted() {
|
||||
assertFalse(context.isResponseCommitted());
|
||||
assertFalse(context.isResponseComplete());
|
||||
}
|
||||
|
||||
public void testCommitExecutionRedirect() {
|
||||
context.requestFlowExecutionRedirect();
|
||||
assertTrue(context.isResponseCommitted());
|
||||
assertTrue(context.getFlowExecutionRedirectRequested());
|
||||
}
|
||||
|
||||
public void testCommitFlowRedirect() {
|
||||
context.requestFlowDefinitionRedirect("foo", null);
|
||||
assertTrue(context.isResponseCommitted());
|
||||
assertTrue(context.getFlowDefinitionRedirectRequested());
|
||||
assertEquals("foo", context.getFlowRedirectFlowId());
|
||||
}
|
||||
|
||||
public void testCommitExternalRedirect() {
|
||||
context.requestExternalRedirect("foo");
|
||||
assertTrue(context.isResponseCommitted());
|
||||
assertTrue(context.getExternalRedirectRequested());
|
||||
assertEquals("foo", context.getExternalRedirectUrl());
|
||||
}
|
||||
@@ -92,7 +89,6 @@ public class ServletExternalContextTests extends TestCase {
|
||||
public void testCommitExecutionRedirectPopup() {
|
||||
context.requestFlowExecutionRedirect();
|
||||
context.requestRedirectInPopup();
|
||||
assertTrue(context.isResponseCommitted());
|
||||
assertTrue(context.getFlowExecutionRedirectRequested());
|
||||
assertTrue(context.getRedirectInPopup());
|
||||
}
|
||||
@@ -100,7 +96,6 @@ public class ServletExternalContextTests extends TestCase {
|
||||
public void testCommitFlowRedirectPopup() {
|
||||
context.requestFlowDefinitionRedirect("foo", null);
|
||||
context.requestRedirectInPopup();
|
||||
assertTrue(context.isResponseCommitted());
|
||||
assertTrue(context.getFlowDefinitionRedirectRequested());
|
||||
assertEquals("foo", context.getFlowRedirectFlowId());
|
||||
assertTrue(context.getRedirectInPopup());
|
||||
@@ -109,7 +104,6 @@ public class ServletExternalContextTests extends TestCase {
|
||||
public void testCommitExternalRedirectPopup() {
|
||||
context.requestExternalRedirect("foo");
|
||||
context.requestRedirectInPopup();
|
||||
assertTrue(context.isResponseCommitted());
|
||||
assertTrue(context.getExternalRedirectRequested());
|
||||
assertEquals("foo", context.getExternalRedirectUrl());
|
||||
assertTrue(context.getRedirectInPopup());
|
||||
@@ -119,4 +113,4 @@ public class ServletExternalContextTests extends TestCase {
|
||||
assertTrue(context.isResponseAllowed());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -166,7 +166,7 @@ public class FlowHandlerAdapterTests extends TestCase {
|
||||
flowExecutor.resumeExecution("12345", context);
|
||||
LocalAttributeMap output = new LocalAttributeMap();
|
||||
output.put("bar", "baz");
|
||||
context.recordResponseCommitted();
|
||||
context.recordResponseComplete();
|
||||
FlowExecutionOutcome outcome = new FlowExecutionOutcome("finish", output);
|
||||
FlowExecutionResult result = FlowExecutionResult.createEndedResult("foo", outcome);
|
||||
EasyMock.expectLastCall().andReturn(result);
|
||||
|
||||
Reference in New Issue
Block a user