view polishing
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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()) {
|
||||
|
||||
@@ -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"));
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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());
|
||||
|
||||
@@ -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"));
|
||||
}
|
||||
|
||||
|
||||
@@ -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"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user