diff --git a/spring-faces/src/main/java/org/springframework/faces/webflow/JsfView.java b/spring-faces/src/main/java/org/springframework/faces/webflow/JsfView.java index e4c28c14..7c91a505 100644 --- a/spring-faces/src/main/java/org/springframework/faces/webflow/JsfView.java +++ b/spring-faces/src/main/java/org/springframework/faces/webflow/JsfView.java @@ -81,7 +81,7 @@ public class JsfView implements View { } } - public void resume() { + public void processUserEvent() { FacesContext facesContext = FlowFacesContext.newInstance(context, facesLifecycle); facesContext.setViewRoot(viewRoot); try { @@ -95,11 +95,11 @@ public class JsfView implements View { } - public boolean eventSignaled() { + public boolean hasFlowEvent() { return context.getExternalContext().getRequestMap().contains(EVENT_KEY); } - public Event getEvent() { + public Event getFlowEvent() { String eventId = (String) context.getExternalContext().getRequestMap().get(EVENT_KEY); return new Event(this, eventId); } diff --git a/spring-faces/src/test/java/org/springframework/faces/webflow/JsfViewFactoryTests.java b/spring-faces/src/test/java/org/springframework/faces/webflow/JsfViewFactoryTests.java index d040c9df..5345abec 100644 --- a/spring-faces/src/test/java/org/springframework/faces/webflow/JsfViewFactoryTests.java +++ b/spring-faces/src/test/java/org/springframework/faces/webflow/JsfViewFactoryTests.java @@ -107,7 +107,7 @@ public class JsfViewFactoryTests extends TestCase { assertNotNull("A View was not created", newView); assertTrue("A JsfView was expected", newView instanceof JsfView); assertEquals("View name did not match", VIEW_ID, ((JsfView) newView).getViewRoot().getViewId()); - assertFalse("An unexpected event was signaled,", newView.eventSignaled()); + assertFalse("An unexpected event was signaled,", newView.hasFlowEvent()); } /** @@ -130,7 +130,7 @@ public class JsfViewFactoryTests extends TestCase { assertNotNull("A View was not restored", restoredView); assertTrue("A JsfView was expected", restoredView instanceof JsfView); assertEquals("View name did not match", VIEW_ID, ((JsfView) restoredView).getViewRoot().getViewId()); - assertFalse("An unexpected event was signaled,", restoredView.eventSignaled()); + assertFalse("An unexpected event was signaled,", restoredView.hasFlowEvent()); } /** @@ -159,7 +159,7 @@ public class JsfViewFactoryTests extends TestCase { assertTrue("A JsfView was expected", restoredView instanceof JsfView); assertTrue("An AjaxViewRoot was not set", ((JsfView) restoredView).getViewRoot() instanceof AjaxViewRoot); assertEquals("View name did not match", VIEW_ID, ((JsfView) restoredView).getViewRoot().getViewId()); - assertFalse("An unexpected event was signaled,", restoredView.eventSignaled()); + assertFalse("An unexpected event was signaled,", restoredView.hasFlowEvent()); } /** @@ -184,7 +184,7 @@ public class JsfViewFactoryTests extends TestCase { assertTrue("A JsfView was expected", newView instanceof JsfView); assertEquals("View name did not match", VIEW_ID, ((JsfView) newView).getViewRoot().getViewId()); assertSame("View root was not the third party instance", newRoot, ((JsfView) newView).getViewRoot()); - assertFalse("An unexpected event was signaled,", newView.eventSignaled()); + assertFalse("An unexpected event was signaled,", newView.hasFlowEvent()); } private class NoExecutionLifecycle extends FlowLifecycle { diff --git a/spring-faces/src/test/java/org/springframework/faces/webflow/JsfViewTests.java b/spring-faces/src/test/java/org/springframework/faces/webflow/JsfViewTests.java index e7df8e65..dba4fa9e 100644 --- a/spring-faces/src/test/java/org/springframework/faces/webflow/JsfViewTests.java +++ b/spring-faces/src/test/java/org/springframework/faces/webflow/JsfViewTests.java @@ -152,9 +152,9 @@ public class JsfViewTests extends TestCase { JsfView restoredView = new JsfView(existingRoot, lifecycle, context); restoredView.setRestored(true); - restoredView.resume(); + restoredView.processUserEvent(); - assertFalse("An unexpected event was signaled,", restoredView.eventSignaled()); + assertFalse("An unexpected event was signaled,", restoredView.hasFlowEvent()); assertTrue("The lifecycle should have been invoked", ((NoEventLifecycle) lifecycle).executed); } @@ -182,9 +182,9 @@ public class JsfViewTests extends TestCase { JsfView restoredView = new JsfView(ajaxRoot, lifecycle, context); restoredView.setRestored(true); - restoredView.resume(); + restoredView.processUserEvent(); - assertFalse("An unexpected event was signaled,", restoredView.eventSignaled()); + assertFalse("An unexpected event was signaled,", restoredView.hasFlowEvent()); assertTrue("The lifecycle should have been invoked", ((NoEventLifecycle) lifecycle).executed); } @@ -210,10 +210,10 @@ public class JsfViewTests extends TestCase { JsfView restoredView = new JsfView(existingRoot, lifecycle, context); restoredView.setRestored(true); - restoredView.resume(); + restoredView.processUserEvent(); - assertTrue("No event was signaled,", restoredView.eventSignaled()); - assertEquals("Event should be " + event, event, restoredView.getEvent().getId()); + assertTrue("No event was signaled,", restoredView.hasFlowEvent()); + assertEquals("Event should be " + event, event, restoredView.getFlowEvent().getId()); assertTrue("The lifecycle should have been invoked", ((EventSignalingLifecycle) lifecycle).executed); } 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 c78f7708..462bbfaf 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 @@ -183,11 +183,11 @@ public class ViewState extends TransitionableState { public void resume(RequestControlContext context) { restoreVariables(context); View view = viewFactory.getView(context); - view.resume(); - if (view.eventSignaled()) { - Event event = view.getEvent(); + view.processUserEvent(); + if (view.hasFlowEvent()) { + Event event = view.getFlowEvent(); if (logger.isDebugEnabled()) { - logger.debug("Event '" + event.getId() + "' signaled on view " + view); + logger.debug("Event '" + event.getId() + "' returned from view " + view); } boolean stateExited = context.handleEvent(event); if (!stateExited && context.getExternalContext().isResponseAllowed()) { diff --git a/spring-webflow/src/main/java/org/springframework/webflow/engine/support/ActionExecutingViewFactory.java b/spring-webflow/src/main/java/org/springframework/webflow/engine/support/ActionExecutingViewFactory.java index 5fa4b08a..35d58533 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/engine/support/ActionExecutingViewFactory.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/engine/support/ActionExecutingViewFactory.java @@ -66,15 +66,15 @@ public class ActionExecutingViewFactory implements ViewFactory { } } - public void resume() { + public void processUserEvent() { } - public boolean eventSignaled() { + public boolean hasFlowEvent() { return context.getExternalContext().getRequestParameterMap().contains("_eventId"); } - public Event getEvent() { + public Event getFlowEvent() { return new Event(this, context.getExternalContext().getRequestParameterMap().get("_eventId")); } diff --git a/spring-webflow/src/main/java/org/springframework/webflow/execution/View.java b/spring-webflow/src/main/java/org/springframework/webflow/execution/View.java index d198b3bf..3b9508e9 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/execution/View.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/execution/View.java @@ -40,19 +40,19 @@ public interface View { /** * Execute the view resume lifecycle. This typically results in a view model binding and validation. */ - public void resume(); + public void processUserEvent(); /** * Returns true if an event occurred the flow system should handle. * @return true if yes, false otherwise */ - public boolean eventSignaled(); + public boolean hasFlowEvent(); /** - * Get the user event the flow should handle. Returns an event object when {@link #eventSignaled()} returns true. - * Returns null otherwise + * Get the user event the flow should handle. Returns an event object when {@link #hasFlowEvent()} returns + * true. Returns null otherwise * @return the event, or null if there is no event for the flow system to handle */ - public Event getEvent(); + public Event getFlowEvent(); } diff --git a/spring-webflow/src/main/java/org/springframework/webflow/mvc/portlet/PortletMvcView.java b/spring-webflow/src/main/java/org/springframework/webflow/mvc/portlet/PortletMvcView.java index ef63d5e6..81252778 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/mvc/portlet/PortletMvcView.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/mvc/portlet/PortletMvcView.java @@ -23,28 +23,36 @@ import javax.portlet.RenderResponse; import org.springframework.context.ApplicationContext; import org.springframework.web.portlet.DispatcherPortlet; -import org.springframework.web.servlet.View; import org.springframework.web.servlet.ViewRendererServlet; import org.springframework.webflow.context.ExternalContext; import org.springframework.webflow.execution.RequestContext; import org.springframework.webflow.mvc.view.MvcView; +/** + * Spring Web Portlet MVC view implementation. + * @author Keith Donald + * @author Scott Andrews + */ public class PortletMvcView extends MvcView { private ApplicationContext applicationContext; + /** + * Creates a new portlet view. + * @param view the view to render + * @param context the current flow request context + * @param applicationContext the application context + */ public PortletMvcView(org.springframework.web.servlet.View view, RequestContext context, ApplicationContext applicationContext) { super(view, context); this.applicationContext = applicationContext; } - public void render(Map model, ExternalContext context) throws Exception { + public void doRender(org.springframework.web.servlet.View view, Map model, ExternalContext context) throws Exception { PortletContext portletContext = (PortletContext) context.getNativeContext(); RenderRequest request = (RenderRequest) context.getNativeRequest(); RenderResponse response = (RenderResponse) context.getNativeResponse(); - View view = getView(); - // Set the content type on the response if needed and if possible. // The Portlet spec requires the content type to be set on the RenderResponse; // it's not sufficient to let the View set it on the ServletResponse. @@ -55,14 +63,11 @@ public class PortletMvcView extends MvcView { response.setContentType(contentType); } } - // Expose Portlet ApplicationContext to view objects. request.setAttribute(ViewRendererServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE, applicationContext); - // These attributes are required by the ViewRendererServlet. request.setAttribute(ViewRendererServlet.VIEW_ATTRIBUTE, view); request.setAttribute(ViewRendererServlet.MODEL_ATTRIBUTE, model); - // Include the content of the view in the render response. portletContext.getRequestDispatcher(DispatcherPortlet.DEFAULT_VIEW_RENDERER_URL).include(request, response); } diff --git a/spring-webflow/src/main/java/org/springframework/webflow/mvc/servlet/ServletMvcView.java b/spring-webflow/src/main/java/org/springframework/webflow/mvc/servlet/ServletMvcView.java index cbe3bc3b..c66daa8b 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/mvc/servlet/ServletMvcView.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/mvc/servlet/ServletMvcView.java @@ -24,15 +24,24 @@ import org.springframework.webflow.context.ExternalContext; import org.springframework.webflow.execution.RequestContext; import org.springframework.webflow.mvc.view.MvcView; +/** + * Creates a new Spring Web Servlet MVC view. + * @author Keith Donald + */ public class ServletMvcView extends MvcView { + /** + * Creates a new servlet view. + * @param view the view to render + * @param context the current flow request context. + */ public ServletMvcView(org.springframework.web.servlet.View view, RequestContext context) { super(view, context); } - public void render(Map model, ExternalContext context) throws Exception { - getView().render(model, (HttpServletRequest) context.getNativeRequest(), - (HttpServletResponse) context.getNativeResponse()); + public void doRender(org.springframework.web.servlet.View view, Map model, ExternalContext context) throws Exception { + view.render(model, (HttpServletRequest) context.getNativeRequest(), (HttpServletResponse) context + .getNativeResponse()); } } \ No newline at end of file diff --git a/spring-webflow/src/main/java/org/springframework/webflow/mvc/view/MvcView.java b/spring-webflow/src/main/java/org/springframework/webflow/mvc/view/MvcView.java index e8be7bea..c7f8965b 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/mvc/view/MvcView.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/mvc/view/MvcView.java @@ -55,6 +55,11 @@ import org.springframework.webflow.execution.RequestContext; import org.springframework.webflow.execution.View; import org.springframework.webflow.expression.DefaultExpressionParserFactory; +/** + * Base view implementation for the Spring Web MVC Servlet and Spring Web MVC Portlet frameworks. + * + * @author Keith Donald + */ public abstract class MvcView implements View { private static final MappingResultsCriteria PROPERTY_NOT_FOUND_ERROR = new PropertyNotFoundError(); @@ -75,15 +80,28 @@ public abstract class MvcView implements View { private String eventId; + /** + * Creates a new MVC view. + * @param view the Spring MVC view to render + * @param context the current flow request context + */ public MvcView(org.springframework.web.servlet.View view, RequestContext context) { this.view = view; this.context = context; } + /** + * Sets the expression parser to use to parse model expressions. + * @param expressionParser the expression parser + */ public void setExpressionParser(ExpressionParser expressionParser) { this.expressionParser = expressionParser; } + /** + * Sets the formatter registry to use to expose formatters for field values. + * @param formatterRegistry the formatter registry + */ public void setFormatterRegistry(FormatterRegistry formatterRegistry) { this.formatterRegistry = formatterRegistry; } @@ -98,20 +116,27 @@ public abstract class MvcView implements View { model.put("currentUser", context.getExternalContext().getCurrentUser()); // TODO expose flow context to mvc view try { - render(model, context.getExternalContext()); + doRender(view, model, context.getExternalContext()); } catch (IOException e) { throw e; } catch (Exception e) { - throw new RuntimeException("Unexpected exception occurred rendering view " + view, e); + throw new IllegalStateException("Unexpected exception occurred rendering view " + view, e); } } - public abstract void render(Map model, ExternalContext context) throws Exception; + /** + * Template method subclasses should override to execute the view rendering logic. + * @param view the MVC view to render + * @param model the view model data + * @param context the flow external context, providing access to the request and response + * @throws Exception an exception occurred rendering the view + */ + protected abstract void doRender(org.springframework.web.servlet.View view, Map model, ExternalContext context) + throws Exception; - public void resume() { + public void processUserEvent() { determineEventId(context); if (eventId == null) { - // nothing to do return; } Object model = getModelObject(); @@ -132,12 +157,12 @@ public abstract class MvcView implements View { } } - public boolean eventSignaled() { + public boolean hasFlowEvent() { return eventId != null && !viewErrors; } - public Event getEvent() { - if (!eventSignaled()) { + public Event getFlowEvent() { + if (!hasFlowEvent()) { return null; } return new Event(this, eventId, context.getRequestParameters().asAttributeMap()); @@ -300,10 +325,6 @@ public abstract class MvcView implements View { return null; } - protected org.springframework.web.servlet.View getView() { - return view; - } - private static class PropertyNotFoundError implements MappingResultsCriteria { public boolean test(MappingResult result) { return result.getResult().isError() && "propertyNotFound".equals(result.getResult().getErrorCode()); diff --git a/spring-webflow/src/main/java/org/springframework/webflow/test/MockViewFactoryCreator.java b/spring-webflow/src/main/java/org/springframework/webflow/test/MockViewFactoryCreator.java index 4c88389f..c02cf8aa 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/test/MockViewFactoryCreator.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/test/MockViewFactoryCreator.java @@ -94,15 +94,15 @@ class MockViewFactoryCreator implements ViewFactoryCreator { return viewId; } - public void resume() { + public void processUserEvent() { // TODO - implement me as appropriate for a test environment } - public boolean eventSignaled() { + public boolean hasFlowEvent() { return context.getRequestParameters().contains("_eventId"); } - public Event getEvent() { + public Event getFlowEvent() { return new Event(this, context.getRequestParameters().get("_eventId")); } diff --git a/spring-webflow/src/test/java/org/springframework/webflow/engine/StubViewFactory.java b/spring-webflow/src/test/java/org/springframework/webflow/engine/StubViewFactory.java index 9180d4e4..d0b2d93d 100644 --- a/spring-webflow/src/test/java/org/springframework/webflow/engine/StubViewFactory.java +++ b/spring-webflow/src/test/java/org/springframework/webflow/engine/StubViewFactory.java @@ -37,15 +37,15 @@ public class StubViewFactory implements ViewFactory { context.getFlowScope().put("renderCalled", Boolean.TRUE); } - public void resume() { + public void processUserEvent() { } - public boolean eventSignaled() { + public boolean hasFlowEvent() { return context.getExternalContext().getRequestParameterMap().contains("_eventId"); } - public Event getEvent() { + public Event getFlowEvent() { return new Event(this, context.getExternalContext().getRequestParameterMap().get("_eventId")); } } diff --git a/spring-webflow/src/test/java/org/springframework/webflow/mvc/view/MvcViewFactoryTests.java b/spring-webflow/src/test/java/org/springframework/webflow/mvc/view/MvcViewFactoryTests.java index 005c3316..65c63824 100644 --- a/spring-webflow/src/test/java/org/springframework/webflow/mvc/view/MvcViewFactoryTests.java +++ b/spring-webflow/src/test/java/org/springframework/webflow/mvc/view/MvcViewFactoryTests.java @@ -61,7 +61,7 @@ public class MvcViewFactoryTests extends TestCase { context.setExternalContext(externalContext); context.getMockFlowExecutionContext().setKey(new GeneratedFlowExecutionKey()); View view = viewFactory.getView(context); - assertEquals(false, view.eventSignaled()); + assertEquals(false, view.hasFlowEvent()); view.render(); assertEquals("/parent/myview.jsp", response.getForwardedUrl()); } @@ -81,7 +81,7 @@ public class MvcViewFactoryTests extends TestCase { context.setExternalContext(externalContext); context.getMockFlowExecutionContext().setKey(new GeneratedFlowExecutionKey()); View view = viewFactory.getView(context); - assertEquals(false, view.eventSignaled()); + assertEquals(false, view.hasFlowEvent()); view.render(); assertEquals("myview", response.getForwardedUrl()); } @@ -109,9 +109,9 @@ public class MvcViewFactoryTests extends TestCase { context.setExternalContext(externalContext); context.getMockFlowExecutionContext().setKey(new GeneratedFlowExecutionKey()); View view = viewFactory.getView(context); - view.resume(); - assertEquals(true, view.eventSignaled()); - Event e = view.getEvent(); + view.processUserEvent(); + assertEquals(true, view.hasFlowEvent()); + Event e = view.getFlowEvent(); assertEquals(view, e.getSource()); assertEquals("foo", e.getId()); view.render(); @@ -141,9 +141,9 @@ public class MvcViewFactoryTests extends TestCase { context.setExternalContext(externalContext); context.getMockFlowExecutionContext().setKey(new GeneratedFlowExecutionKey()); View view = viewFactory.getView(context); - view.resume(); - assertEquals(true, view.eventSignaled()); - Event e = view.getEvent(); + view.processUserEvent(); + assertEquals(true, view.hasFlowEvent()); + Event e = view.getFlowEvent(); assertEquals(view, e.getSource()); assertEquals("foo", e.getId()); view.render(); diff --git a/spring-webflow/src/test/java/org/springframework/webflow/mvc/view/MvcViewTests.java b/spring-webflow/src/test/java/org/springframework/webflow/mvc/view/MvcViewTests.java index 61b662fe..58be78c0 100644 --- a/spring-webflow/src/test/java/org/springframework/webflow/mvc/view/MvcViewTests.java +++ b/spring-webflow/src/test/java/org/springframework/webflow/mvc/view/MvcViewTests.java @@ -21,8 +21,6 @@ import org.springframework.validation.BindingResult; import org.springframework.web.servlet.View; import org.springframework.webflow.context.ExternalContext; import org.springframework.webflow.execution.RequestContext; -import org.springframework.webflow.mvc.view.BindingModel; -import org.springframework.webflow.mvc.view.MvcView; import org.springframework.webflow.test.MockFlowExecutionKey; import org.springframework.webflow.test.MockRequestContext; @@ -99,9 +97,9 @@ public class MvcViewTests extends TestCase { context.getMockFlowExecutionContext().setKey(new MockFlowExecutionKey("c1v1")); org.springframework.web.servlet.View mvcView = new MockView(); MvcView view = new MockMvcView(mvcView, context); - view.resume(); - assertFalse(view.eventSignaled()); - assertNull(view.getEvent()); + view.processUserEvent(); + assertFalse(view.hasFlowEvent()); + assertNull(view.getFlowEvent()); } public void testResumeEventNoModelBinding() throws Exception { @@ -114,9 +112,9 @@ public class MvcViewTests extends TestCase { org.springframework.web.servlet.View mvcView = new MockView(); MvcView view = new MockMvcView(mvcView, context); view.setFormatterRegistry(formatterRegistry); - view.resume(); - assertTrue(view.eventSignaled()); - assertEquals("submit", view.getEvent().getId()); + view.processUserEvent(); + assertTrue(view.hasFlowEvent()); + assertEquals("submit", view.getFlowEvent().getId()); } public void testResumeEventModelBinding() throws Exception { @@ -137,9 +135,9 @@ public class MvcViewTests extends TestCase { org.springframework.web.servlet.View mvcView = new MockView(); MvcView view = new MockMvcView(mvcView, context); view.setFormatterRegistry(formatterRegistry); - view.resume(); - assertTrue(view.eventSignaled()); - assertEquals("submit", view.getEvent().getId()); + view.processUserEvent(); + assertTrue(view.hasFlowEvent()); + assertEquals("submit", view.getFlowEvent().getId()); assertEquals("foo", bindBean.getStringProperty()); assertEquals(new Integer(5), bindBean.getIntegerProperty()); Calendar cal = Calendar.getInstance(); @@ -154,9 +152,10 @@ public class MvcViewTests extends TestCase { super(view, context); } - public void render(Map model, ExternalContext context) throws Exception { - getView().render(model, (HttpServletRequest) context.getNativeRequest(), - (HttpServletResponse) context.getNativeResponse()); + protected void doRender(org.springframework.web.servlet.View view, Map model, ExternalContext context) + throws Exception { + view.render(model, (HttpServletRequest) context.getNativeRequest(), (HttpServletResponse) context + .getNativeResponse()); } }