diff --git a/spring-webflow/src/main/java/org/springframework/webflow/mvc/portlet/FlowHandlerAdapter.java b/spring-webflow/src/main/java/org/springframework/webflow/mvc/portlet/FlowHandlerAdapter.java index c15415f9..5d1efd58 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/mvc/portlet/FlowHandlerAdapter.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/mvc/portlet/FlowHandlerAdapter.java @@ -28,6 +28,8 @@ import javax.portlet.PortletSession; import javax.portlet.RenderRequest; import javax.portlet.RenderResponse; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.util.Assert; import org.springframework.web.portlet.HandlerAdapter; import org.springframework.web.portlet.ModelAndView; import org.springframework.web.portlet.context.PortletApplicationObjectSupport; @@ -42,17 +44,58 @@ import org.springframework.webflow.execution.repository.NoSuchFlowExecutionExcep import org.springframework.webflow.executor.FlowExecutionResult; import org.springframework.webflow.executor.FlowExecutor; -public class FlowHandlerAdapter extends PortletApplicationObjectSupport implements HandlerAdapter { +public class FlowHandlerAdapter extends PortletApplicationObjectSupport implements HandlerAdapter, InitializingBean { private static final String ACTION_REQUEST_FLOW_EXCEPTION_ATTRIBUTE = "actionRequestFlowException"; private FlowExecutor flowExecutor; - private FlowUrlHandler urlHandler; + private FlowUrlHandler flowUrlHandler; - public FlowHandlerAdapter(FlowExecutor flowExecutor) { + /** + * Creates a new flow handler adapter. + * @see #setFlowExecutor(FlowExecutor) + * @see #setFlowUrlHandler(FlowUrlHandler) + * @see #afterPropertiesSet() + */ + public FlowHandlerAdapter() { + } + + /** + * Returns the central service for executing flows. Required. + */ + public FlowExecutor getFlowExecutor() { + return flowExecutor; + } + + /** + * Sets the central service for executing flows. Required. + * @param flowExecutor + */ + public void setFlowExecutor(FlowExecutor flowExecutor) { this.flowExecutor = flowExecutor; - this.urlHandler = new DefaultFlowUrlHandler(); + } + + /** + * Returns the flow url handler. + */ + public FlowUrlHandler getFlowUrlHandler() { + return flowUrlHandler; + } + + /** + * Sets the flow url handler + * @param urlHandler the flow url handler + */ + public void setFlowUrlHandler(FlowUrlHandler urlHandler) { + this.flowUrlHandler = urlHandler; + } + + public void afterPropertiesSet() throws Exception { + Assert.notNull(flowExecutor, "The FlowExecutor to execute flows is required"); + if (flowUrlHandler == null) { + flowUrlHandler = new DefaultFlowUrlHandler(); + } } public boolean supports(Object handler) { @@ -70,7 +113,7 @@ public class FlowHandlerAdapter extends PortletApplicationObjectSupport implemen return handleException(e, flowHandler, request, response); } } - String flowExecutionKey = urlHandler.getFlowExecutionKey(request); + String flowExecutionKey = flowUrlHandler.getFlowExecutionKey(request); if (flowExecutionKey != null) { return resumeFlow(flowExecutionKey, flowHandler, request, response); } else { @@ -81,12 +124,12 @@ public class FlowHandlerAdapter extends PortletApplicationObjectSupport implemen public void handleAction(ActionRequest request, ActionResponse response, Object handler) throws Exception { FlowHandler flowHandler = (FlowHandler) handler; populateConveniencePortletProperties(request); - String flowExecutionKey = urlHandler.getFlowExecutionKey(request); + String flowExecutionKey = flowUrlHandler.getFlowExecutionKey(request); PortletExternalContext context = createPortletExternalContext(request, response); try { FlowExecutionResult result = flowExecutor.resumeExecution(flowExecutionKey, context); if (result.isPaused()) { - urlHandler.setFlowExecutionRenderParameter(result.getPausedKey(), response); + flowUrlHandler.setFlowExecutionRenderParameter(result.getPausedKey(), response); } else if (result.isEnded()) { handleFlowExecutionOutcome(result.getOutcome(), flowHandler, request, response); } else { @@ -178,7 +221,7 @@ public class FlowHandlerAdapter extends PortletApplicationObjectSupport implemen try { FlowExecutionResult result = flowExecutor.launchExecution(flowHandler.getFlowId(), input, context); if (result.isPaused()) { - urlHandler.setFlowExecutionInSession(result.getPausedKey(), request); + flowUrlHandler.setFlowExecutionInSession(result.getPausedKey(), request); } return null; } catch (FlowException e) { diff --git a/spring-webflow/src/main/java/org/springframework/webflow/mvc/servlet/FlowHandlerAdapter.java b/spring-webflow/src/main/java/org/springframework/webflow/mvc/servlet/FlowHandlerAdapter.java index d212723d..3fdd2751 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/mvc/servlet/FlowHandlerAdapter.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/mvc/servlet/FlowHandlerAdapter.java @@ -70,7 +70,7 @@ public class FlowHandlerAdapter extends WebApplicationObjectSupport implements H /** * A strategy for extracting flow arguments and generating flow urls. */ - private FlowUrlHandler urlHandler; + private FlowUrlHandler flowUrlHandler; /** * The representation of an Ajax client service capable of interacting with web flow. @@ -106,15 +106,15 @@ public class FlowHandlerAdapter extends WebApplicationObjectSupport implements H * Returns the flow url handler. */ public FlowUrlHandler getFlowUrlHandler() { - return urlHandler; + return flowUrlHandler; } /** * Sets the flow url handler - * @param urlHandler the flow url handler + * @param flowUrlHandler the flow url handler */ - public void setFlowUrlHandler(FlowUrlHandler urlHandler) { - this.urlHandler = urlHandler; + public void setFlowUrlHandler(FlowUrlHandler flowUrlHandler) { + this.flowUrlHandler = flowUrlHandler; } /** @@ -134,11 +134,11 @@ public class FlowHandlerAdapter extends WebApplicationObjectSupport implements H public void afterPropertiesSet() throws Exception { Assert.notNull(flowExecutor, "The FlowExecutor to execute flows is required"); - if (urlHandler == null) { - this.urlHandler = new DefaultFlowUrlHandler(); + if (flowUrlHandler == null) { + flowUrlHandler = new DefaultFlowUrlHandler(); } if (ajaxHandler == null) { - this.ajaxHandler = new SpringJavascriptAjaxHandler(); + ajaxHandler = new SpringJavascriptAjaxHandler(); } } @@ -149,7 +149,7 @@ public class FlowHandlerAdapter extends WebApplicationObjectSupport implements H public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { FlowHandler flowHandler = (FlowHandler) handler; - String flowExecutionKey = urlHandler.getFlowExecutionKey(request); + String flowExecutionKey = flowUrlHandler.getFlowExecutionKey(request); if (flowExecutionKey != null) { try { ServletExternalContext context = createServletExternalContext(request, response); @@ -181,7 +181,7 @@ public class FlowHandlerAdapter extends WebApplicationObjectSupport implements H */ protected ServletExternalContext createServletExternalContext(HttpServletRequest request, HttpServletResponse response) { - ServletExternalContext context = new MvcExternalContext(getServletContext(), request, response, urlHandler); + ServletExternalContext context = new MvcExternalContext(getServletContext(), request, response, flowUrlHandler); context.setAjaxRequest(ajaxHandler.isAjaxRequest(getServletContext(), request, response)); return context; } @@ -193,7 +193,7 @@ public class FlowHandlerAdapter extends WebApplicationObjectSupport implements H * @param request the current request */ protected String defaultGetFlowId(HttpServletRequest request) { - return urlHandler.getFlowId(request); + return flowUrlHandler.getFlowId(request); } /** @@ -239,7 +239,7 @@ public class FlowHandlerAdapter extends WebApplicationObjectSupport implements H if (logger.isDebugEnabled()) { logger.debug("Restarting a new execution of ended flow '" + flowId + "'"); } - response.sendRedirect(urlHandler.createFlowDefinitionUrl(flowId, outcome.getOutput(), request)); + response.sendRedirect(flowUrlHandler.createFlowDefinitionUrl(flowId, outcome.getOutput(), request)); } } @@ -261,7 +261,7 @@ public class FlowHandlerAdapter extends WebApplicationObjectSupport implements H logger.debug("Restarting a new execution of previously expired/ended flow '" + flowId + "'"); } // by default, attempt to restart the flow - response.sendRedirect(urlHandler.createFlowDefinitionUrl(flowId, null, request)); + response.sendRedirect(flowUrlHandler.createFlowDefinitionUrl(flowId, null, request)); } } else { throw e; @@ -300,7 +300,7 @@ public class FlowHandlerAdapter extends WebApplicationObjectSupport implements H private void sendFlowExecutionRedirect(FlowExecutionResult result, ServletExternalContext context, HttpServletRequest request, HttpServletResponse response) throws IOException { - String url = urlHandler.createFlowExecutionUrl(result.getFlowId(), result.getPausedKey(), request); + String url = flowUrlHandler.createFlowExecutionUrl(result.getFlowId(), result.getPausedKey(), request); if (logger.isDebugEnabled()) { logger.debug("Sending flow execution redirect to '" + url + "'"); } @@ -318,7 +318,7 @@ public class FlowHandlerAdapter extends WebApplicationObjectSupport implements H if (result.isPaused()) { input.put("refererExecution", result.getPausedKey()); } - String url = urlHandler.createFlowDefinitionUrl(flowId, input, request); + String url = flowUrlHandler.createFlowDefinitionUrl(flowId, input, request); if (logger.isDebugEnabled()) { logger.debug("Sending flow definition redirect to '" + url + "'"); } diff --git a/spring-webflow/src/test/java/org/springframework/webflow/mvc/portlet/FlowHandlerAdapterTests.java b/spring-webflow/src/test/java/org/springframework/webflow/mvc/portlet/FlowHandlerAdapterTests.java index 7b007eb5..dc83c8e3 100644 --- a/spring-webflow/src/test/java/org/springframework/webflow/mvc/portlet/FlowHandlerAdapterTests.java +++ b/spring-webflow/src/test/java/org/springframework/webflow/mvc/portlet/FlowHandlerAdapterTests.java @@ -18,7 +18,6 @@ import org.springframework.mock.web.portlet.MockRenderRequest; import org.springframework.mock.web.portlet.MockRenderResponse; import org.springframework.web.context.support.StaticWebApplicationContext; import org.springframework.web.portlet.ModelAndView; -import org.springframework.webflow.context.portlet.DefaultFlowUrlHandler; import org.springframework.webflow.context.portlet.PortletExternalContext; import org.springframework.webflow.core.FlowException; import org.springframework.webflow.core.collection.LocalAttributeMap; @@ -32,7 +31,7 @@ import org.springframework.webflow.test.MockFlowExecutionKey; public class FlowHandlerAdapterTests extends TestCase { private FlowHandlerAdapter controller; - private FlowExecutor executor; + private FlowExecutor flowExecutor; private MockPortletContext portletContext; private MockActionRequest actionRequest; private MockActionResponse actionResponse; @@ -46,9 +45,9 @@ public class FlowHandlerAdapterTests extends TestCase { private boolean handleExecutionOutcome; private boolean handleExecutionOutcomeCalled; - protected void setUp() { - executor = (FlowExecutor) EasyMock.createMock(FlowExecutor.class); - controller = new FlowHandlerAdapter(executor) { + protected void setUp() throws Exception { + flowExecutor = (FlowExecutor) EasyMock.createMock(FlowExecutor.class); + controller = new FlowHandlerAdapter() { protected PortletExternalContext createPortletExternalContext(PortletRequest request, PortletResponse response) { if (request instanceof ActionRequest) { @@ -58,17 +57,21 @@ public class FlowHandlerAdapterTests extends TestCase { } } }; + controller.setFlowExecutor(flowExecutor); + controller.setApplicationContext(new StaticWebApplicationContext()); portletContext = new MockPortletContext(); + controller.setPortletContext(portletContext); + controller.afterPropertiesSet(); + actionRequest = new MockActionRequest(); actionResponse = new MockActionResponse(); renderRequest = new MockRenderRequest(); renderResponse = new MockRenderResponse(); - actionContext = new PortletExternalContext(portletContext, actionRequest, actionResponse, - new DefaultFlowUrlHandler()); - renderContext = new PortletExternalContext(portletContext, renderRequest, renderResponse, - new DefaultFlowUrlHandler()); - controller.setApplicationContext(new StaticWebApplicationContext()); - controller.setPortletContext(portletContext); + actionContext = new PortletExternalContext(portletContext, actionRequest, actionResponse, controller + .getFlowUrlHandler()); + renderContext = new PortletExternalContext(portletContext, renderRequest, renderResponse, controller + .getFlowUrlHandler()); + flowHandler = new FlowHandler() { public String getFlowId() { return "foo"; @@ -101,47 +104,47 @@ public class FlowHandlerAdapterTests extends TestCase { public void testLaunchFlowRequest() throws Exception { renderRequest.setContextPath("/springtravel"); - executor.launchExecution("foo", flowInput, renderContext); + flowExecutor.launchExecution("foo", flowInput, renderContext); FlowExecutionResult result = FlowExecutionResult.createPausedResult("foo", "12345"); EasyMock.expectLastCall().andReturn(result); - EasyMock.replay(new Object[] { executor }); + EasyMock.replay(new Object[] { flowExecutor }); ModelAndView mv = controller.handleRender(renderRequest, renderResponse, flowHandler); assertNull(mv); - EasyMock.verify(new Object[] { executor }); + EasyMock.verify(new Object[] { flowExecutor }); } public void testResumeFlowActionRequest() throws Exception { actionRequest.setContextPath("/springtravel"); actionRequest.addParameter("execution", "12345"); - executor.resumeExecution("12345", actionContext); + flowExecutor.resumeExecution("12345", actionContext); FlowExecutionResult result = FlowExecutionResult.createPausedResult("foo", "123456"); EasyMock.expectLastCall().andReturn(result); - EasyMock.replay(new Object[] { executor }); + EasyMock.replay(new Object[] { flowExecutor }); controller.handleAction(actionRequest, actionResponse, flowHandler); - EasyMock.verify(new Object[] { executor }); + EasyMock.verify(new Object[] { flowExecutor }); } public void testResumeFlowRenderRequest() throws Exception { renderRequest.setContextPath("/springtravel"); renderRequest.addParameter("execution", "12345"); - executor.resumeExecution("12345", renderContext); + flowExecutor.resumeExecution("12345", renderContext); FlowExecutionResult result = FlowExecutionResult.createPausedResult("foo", "123456"); EasyMock.expectLastCall().andReturn(result); - EasyMock.replay(new Object[] { executor }); + EasyMock.replay(new Object[] { flowExecutor }); controller.handleRender(renderRequest, renderResponse, flowHandler); - EasyMock.verify(new Object[] { executor }); + EasyMock.verify(new Object[] { flowExecutor }); } public void testResumeFlowRenderRequestFromSession() throws Exception { renderRequest.setContextPath("/springtravel"); PortletSession session = renderRequest.getPortletSession(); session.setAttribute("execution", "12345"); - executor.resumeExecution("12345", renderContext); + flowExecutor.resumeExecution("12345", renderContext); FlowExecutionResult result = FlowExecutionResult.createPausedResult("foo", "123456"); EasyMock.expectLastCall().andReturn(result); - EasyMock.replay(new Object[] { executor }); + EasyMock.replay(new Object[] { flowExecutor }); controller.handleRender(renderRequest, renderResponse, flowHandler); - EasyMock.verify(new Object[] { executor }); + EasyMock.verify(new Object[] { flowExecutor }); } public void testDefaultHandleFlowException() throws Exception { @@ -160,13 +163,13 @@ public class FlowHandlerAdapterTests extends TestCase { public void testDefaultHandleNoSuchFlowExecutionException() throws Exception { actionRequest.setContextPath("/springtravel"); actionRequest.addParameter("execution", "12345"); - executor.resumeExecution("12345", actionContext); + flowExecutor.resumeExecution("12345", actionContext); FlowException flowException = new NoSuchFlowExecutionException(new MockFlowExecutionKey("12345"), null); EasyMock.expectLastCall().andThrow(flowException); - EasyMock.replay(new Object[] { executor }); + EasyMock.replay(new Object[] { flowExecutor }); controller.handleAction(actionRequest, actionResponse, flowHandler); assertNotNull(actionRequest.getPortletSession().getAttribute("actionRequestFlowException")); - EasyMock.verify(new Object[] { executor }); + EasyMock.verify(new Object[] { flowExecutor }); Exception e = (Exception) actionRequest.getPortletSession().getAttribute("actionRequestFlowException"); assertTrue(e instanceof NoSuchFlowExecutionException); } @@ -178,12 +181,12 @@ public class FlowHandlerAdapterTests extends TestCase { LocalAttributeMap output = new LocalAttributeMap(); output.put("bar", "baz"); FlowExecutionOutcome outcome = new FlowExecutionOutcome("finish", output); - executor.resumeExecution("12345", actionContext); + flowExecutor.resumeExecution("12345", actionContext); EasyMock.expectLastCall().andReturn(FlowExecutionResult.createEndedResult("bar", outcome)); - EasyMock.replay(new Object[] { executor }); + EasyMock.replay(new Object[] { flowExecutor }); controller.handleAction(actionRequest, actionResponse, flowHandler); assertTrue(handleExecutionOutcomeCalled); - EasyMock.verify(new Object[] { executor }); + EasyMock.verify(new Object[] { flowExecutor }); } public void testHandleFlowExceptionCustomFlowHandler() throws Exception { @@ -191,13 +194,13 @@ public class FlowHandlerAdapterTests extends TestCase { final FlowException flowException = new FlowException("Error") { }; renderRequest.setContextPath("/springtravel"); - executor.launchExecution("foo", flowInput, renderContext); + flowExecutor.launchExecution("foo", flowInput, renderContext); EasyMock.expectLastCall().andThrow(flowException); - EasyMock.replay(new Object[] { executor }); + EasyMock.replay(new Object[] { flowExecutor }); ModelAndView mv = controller.handleRender(renderRequest, renderResponse, flowHandler); assertNotNull(mv); assertEquals("error", mv.getViewName()); - EasyMock.verify(new Object[] { executor }); + EasyMock.verify(new Object[] { flowExecutor }); } public void testHandleFlowExceptionFromSession() throws Exception {