Fixed fallback to JSF navigation when inside a restored flow execution.
This commit is contained in:
@@ -18,8 +18,9 @@ Package org.springframework.webflow.executor
|
||||
* In a JSF 1.2 environment, SWF will now correctly maintain the "java.faces.ViewState" parameter accross flow
|
||||
execution redirects (SWF-445).
|
||||
* FlowPhaseListener now maintains FacesMessages accross a flow execution redirect by temporarily storing them in
|
||||
flash scope (SWF-745).
|
||||
the flow execution (SWF-745).
|
||||
* FlowPhaseListener will now save the JSF component state before a flow execution redirect is issued (SWF-747).
|
||||
* Fixed FlowPhaseListener to correctly deal with scenarios where we fallback to standard JSF navigation.
|
||||
|
||||
Changes in version 1.0.5 (03.10.2007)
|
||||
-------------------------------------
|
||||
|
||||
@@ -37,6 +37,10 @@ import org.springframework.webflow.executor.support.AutowiringSupport;
|
||||
* require special autowiring behaviour, consider overriding the {@link #autowire(ScopeType, String, Object)} method.
|
||||
* <p>
|
||||
* This phase listener will use the root web application context as {@link AutowireCapableBeanFactory}.
|
||||
* <p>
|
||||
* Note about customization: since PhaseListeners managed directly by the JSF provider cannot benefit from dependency
|
||||
* injection, See Spring's {@link org.springframework.web.jsf.DelegatingPhaseListenerMulticaster} when you need to
|
||||
* customize an AutowiringPhaseListener instance.
|
||||
*
|
||||
* @see FlowPhaseListener
|
||||
* @see WebApplicationContextUtils#getWebApplicationContext(ServletContext)
|
||||
|
||||
@@ -54,10 +54,16 @@ public class FlowExecutionHolder implements Serializable {
|
||||
private FlowExecutionLock flowExecutionLock;
|
||||
|
||||
/**
|
||||
* The currently selected view selection for this request.
|
||||
* The currently selected view for this request.
|
||||
*/
|
||||
private ViewSelection viewSelection;
|
||||
|
||||
/**
|
||||
* Flag that indicates whether or not it was Web Flow that processed navigation, or if there was fallback to the
|
||||
* standard JSF navigation handler. Defaults to false.
|
||||
*/
|
||||
private boolean navigationFallback = false;
|
||||
|
||||
/**
|
||||
* Creates a new flow execution holder for a flow execution that has not yet been placed in a repository.
|
||||
* @param flowExecution the flow execution to hold
|
||||
@@ -130,6 +136,24 @@ public class FlowExecutionHolder implements Serializable {
|
||||
this.viewSelection = viewSelection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether or not fallback happened to the standard JSF navigation handler. Defaults to false.
|
||||
*
|
||||
* @since 1.0.6
|
||||
*/
|
||||
public void setNavigationFallback(boolean b) {
|
||||
this.navigationFallback = b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether or not fallback happened to the standard JSF navigation handler.
|
||||
*
|
||||
* @since 1.0.6
|
||||
*/
|
||||
public boolean isNavigationFallback() {
|
||||
return navigationFallback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace the current flow execution with the one provided. This method will clear out all state associated with
|
||||
* the original execution and unlock it if necessary.
|
||||
@@ -138,6 +162,7 @@ public class FlowExecutionHolder implements Serializable {
|
||||
public void replaceWith(FlowExecution flowExecution) {
|
||||
this.flowExecutionKey = null;
|
||||
this.viewSelection = null;
|
||||
this.navigationFallback = false;
|
||||
unlockFlowExecutionIfNecessary();
|
||||
this.flowExecution = flowExecution;
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ public class FlowExecutionKeyStateHolder extends UIComponentBase {
|
||||
public static final String COMPONENT_ID = "FlowExecutionKeyStateHolder";
|
||||
|
||||
/**
|
||||
* The key value
|
||||
* The key value.
|
||||
*/
|
||||
private String flowExecutionKey;
|
||||
|
||||
@@ -65,7 +65,7 @@ public class FlowExecutionKeyStateHolder extends UIComponentBase {
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
// Do nothing so as to ensure the id never gets overwritten.
|
||||
// do nothing so as to ensure the id never gets overwritten.
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -170,12 +170,13 @@ public class FlowNavigationHandler extends DecoratingNavigationHandler {
|
||||
} else {
|
||||
// not a launch request - see if this is a resume request to continue an existing execution
|
||||
if (FlowExecutionHolderUtils.isFlowExecutionRestored(facesContext)) {
|
||||
FlowExecutionHolder holder = FlowExecutionHolderUtils.getFlowExecutionHolder(facesContext);
|
||||
|
||||
// a flow execution has been restored - see if we need to signal an event against it
|
||||
if (argumentExtractor.isEventIdPresent(context)) {
|
||||
// signal the event against the current flow execution
|
||||
String eventId = argumentExtractor.extractEventId(context);
|
||||
try {
|
||||
FlowExecutionHolder holder = FlowExecutionHolderUtils.getFlowExecutionHolder(facesContext);
|
||||
ViewSelection selectedView = holder.getFlowExecution().signalEvent(eventId, context);
|
||||
// set the next view to render
|
||||
holder.setViewSelection(selectedView);
|
||||
@@ -185,6 +186,7 @@ public class FlowNavigationHandler extends DecoratingNavigationHandler {
|
||||
+ "'; falling back to standard navigation handler.");
|
||||
}
|
||||
// not a valid event in the current state: proceed with standard navigation
|
||||
holder.setNavigationFallback(true);
|
||||
originalNavigationHandler.handleNavigation(facesContext, fromAction, outcome);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -382,13 +382,19 @@ public class FlowPhaseListener implements PhaseListener {
|
||||
* @param holder the holder
|
||||
*/
|
||||
protected void prepareResponse(final JsfExternalContext context, final FlowExecutionHolder holder) {
|
||||
if (holder.isNavigationFallback()) {
|
||||
// navigation was not processed by Web Flow, but by the standard JSF navigation handler
|
||||
// just leave response rendering up to JSF
|
||||
return;
|
||||
}
|
||||
|
||||
ViewSelection selectedView = holder.getViewSelection();
|
||||
if (selectedView == null) {
|
||||
// no navigation event has been processed - simply refresh the execution with the same key
|
||||
selectedView = holder.getFlowExecution().refresh(context);
|
||||
holder.setViewSelection(selectedView);
|
||||
} else {
|
||||
// an navigation event has been processed - generate a new flow execution key if necessary
|
||||
// a navigation event has been processed - generate a new flow execution key if necessary
|
||||
generateKey(context, holder);
|
||||
}
|
||||
new ResponseInstructionHandler() {
|
||||
|
||||
Reference in New Issue
Block a user