From ae9aba4e49276769dcbbea182cdc7a493f078d00 Mon Sep 17 00:00:00 2001 From: Keith Donald Date: Tue, 1 May 2007 22:22:03 +0000 Subject: [PATCH] still SWF 302 work - phase listener mods and more javadoc --- .../executor/jsf/FlowNavigationHandler.java | 10 +++++++- .../executor/jsf/FlowPhaseListener.java | 23 ++++++++++++++++--- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/spring-webflow/src/main/java/org/springframework/webflow/executor/jsf/FlowNavigationHandler.java b/spring-webflow/src/main/java/org/springframework/webflow/executor/jsf/FlowNavigationHandler.java index 357ce723..74f27d42 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/executor/jsf/FlowNavigationHandler.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/executor/jsf/FlowNavigationHandler.java @@ -164,7 +164,8 @@ public class FlowNavigationHandler extends DecoratingNavigationHandler { } else { // bind the new execution as the 'current execution' - FlowExecutionHolderUtils.setFlowExecutionHolder(new FlowExecutionHolder(flowExecution), facesContext); + FlowExecutionHolderUtils.setFlowExecutionHolder(new FlowExecutionHolder(flowExecution), + facesContext); } // start the new execution ViewSelection selectedView = flowExecution.start(createInput(context), context); @@ -185,6 +186,10 @@ public class FlowNavigationHandler extends DecoratingNavigationHandler { holder.setViewSelection(selectedView); } catch (NoMatchingTransitionException e) { + if (logger.isDebugEnabled()) { + logger.debug("No flow state transition found for event '" + eventId + + "'; falling back to standard navigation handler."); + } // not a valid event in the current state: proceed with standard navigation originalNavigationHandler.handleNavigation(facesContext, fromAction, outcome); } @@ -238,6 +243,9 @@ public class FlowNavigationHandler extends DecoratingNavigationHandler { } private void cleanupResources(FacesContext context) { + if (logger.isDebugEnabled()) { + logger.debug("Cleaning up allocated flow system resources"); + } FlowExecutionHolderUtils.unlockCurrentFlowExecutionIfNecessary(context); ExternalContextHolder.setExternalContext(null); } diff --git a/spring-webflow/src/main/java/org/springframework/webflow/executor/jsf/FlowPhaseListener.java b/spring-webflow/src/main/java/org/springframework/webflow/executor/jsf/FlowPhaseListener.java index ace51849..7b3ad638 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/executor/jsf/FlowPhaseListener.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/executor/jsf/FlowPhaseListener.java @@ -225,10 +225,24 @@ public class FlowPhaseListener implements PhaseListener { if (event.getPhaseId() == PhaseId.RESTORE_VIEW) { ExternalContextHolder.setExternalContext(new JsfExternalContext(context)); restoreFlowExecution(event.getFacesContext()); + // we do not need to worry about clean up here since other phases will continue to run even if an exception + // occurs in restoreFlowExecution(FacesContext) } else if (event.getPhaseId() == PhaseId.RENDER_RESPONSE) { if (FlowExecutionHolderUtils.isFlowExecutionRestored(event.getFacesContext())) { - prepareResponse(getCurrentContext(), FlowExecutionHolderUtils.getFlowExecutionHolder(context)); + try { + prepareResponse(getCurrentContext(), FlowExecutionHolderUtils.getFlowExecutionHolder(context)); + } + catch (RuntimeException e) { + // we must cleanup here since this is the render response phase and the after phase callback will + // NOT run when an exception occurs (which typically does the cleanup--see below) + cleanupResources(context); + throw e; + } + catch (Error e) { + cleanupResources(context); + throw e; + } } } } @@ -241,7 +255,7 @@ public class FlowPhaseListener implements PhaseListener { saveFlowExecution(getCurrentContext(), FlowExecutionHolderUtils.getFlowExecutionHolder(context)); } finally { - // always cleanup after save - done with flow execution request processing + // always cleanup after save - we are done with flow execution request processing cleanupResources(context); } } @@ -413,7 +427,7 @@ public class FlowPhaseListener implements PhaseListener { if (flowExecution.isActive()) { // save the flow execution out to the repository if (logger.isDebugEnabled()) { - logger.debug("Saving continuation to repository with key " + holder.getFlowExecutionKey()); + logger.debug("Saving execution to repository with key " + holder.getFlowExecutionKey()); } repository.putFlowExecution(holder.getFlowExecutionKey(), flowExecution); } @@ -435,6 +449,9 @@ public class FlowPhaseListener implements PhaseListener { } private void cleanupResources(FacesContext context) { + if (logger.isDebugEnabled()) { + logger.debug("Cleaning up allocated flow system resources"); + } FlowExecutionHolderUtils.unlockCurrentFlowExecutionIfNecessary(context); ExternalContextHolder.setExternalContext(null); }