Adjusting JSF implementation to the refactored View interface.

This commit is contained in:
Jeremy Grelle
2009-04-13 22:50:21 +00:00
parent b9368b48ff
commit 84abdc9175
4 changed files with 44 additions and 21 deletions

View File

@@ -28,6 +28,7 @@ import org.springframework.core.io.ContextResource;
import org.springframework.core.io.Resource;
import org.springframework.webflow.execution.RequestContext;
import org.springframework.webflow.execution.RequestContextHolder;
import org.springframework.webflow.execution.View;
/**
* Simple delegating {@link ViewHandler} implementation that provides JSF Form's with the correct FlowExecution URL,
@@ -120,7 +121,7 @@ public class FlowViewHandler extends ViewHandler {
private UIViewRoot restoreFlowView(FacesContext facesContext, String resourcePath) {
RequestContext context = RequestContextHolder.getRequestContext();
ViewRootHolder holder = (ViewRootHolder) context.getFlashScope().get(ViewRootHolder.VIEW_ROOT_HOLDER_KEY);
ViewRootHolder holder = (ViewRootHolder) context.getFlashScope().get(View.USER_EVENT_STATE_ATTRIBUTE);
if (holder != null && holder.getViewRoot().getViewId().equals(resourcePath)) {
return holder.getViewRoot();
} else {

View File

@@ -97,24 +97,27 @@ public class JsfView implements View {
return requestContext.getRequestParameters().size() > 1;
}
/*
* Executes postback-processing portions of the standard JSF lifecycle including APPLY_REQUEST_VALUES through
* INVOKE_APPLICATION.
*/
public void processUserEvent() {
/*
* Executes postback-processing portions of the standard JSF lifecycle including APPLY_REQUEST_VALUES through
* INVOKE_APPLICATION.
*/
FacesContext facesContext = FlowFacesContext.newInstance(requestContext, facesLifecycle);
facesContext.setViewRoot(viewRoot);
try {
// TODO - render response / response complete check
facesLifecycle.execute(facesContext);
// Must respect these flags in case user set them during RESTORE_VIEW phase
if (!facesContext.getRenderResponse() && !facesContext.getResponseComplete()) {
facesLifecycle.execute(facesContext);
}
} finally {
facesContext.release();
}
}
public Object getUserEventState() {
// TODO - return view root holder
return null;
// Set the temporary UIViewRoot state in Flash for the redirect, regardless of whether the lifecycle
// executed or not (i.e., it's still necessary when starting a flow and rendering a new view instance)
return new ViewRootHolder(getViewRoot());
}
public boolean hasFlowEvent() {
@@ -134,5 +137,4 @@ public class JsfView implements View {
private String getEventId() {
return (String) requestContext.getExternalContext().getRequestMap().get(EVENT_KEY);
}
}

View File

@@ -24,8 +24,6 @@ import javax.faces.component.UIViewRoot;
*/
class ViewRootHolder {
static final String VIEW_ROOT_HOLDER_KEY = "flowViewRootHolder";
private UIViewRoot viewRoot;
public ViewRootHolder(UIViewRoot viewRoot) {

View File

@@ -24,6 +24,7 @@ import org.springframework.webflow.execution.FlowExecutionKey;
import org.springframework.webflow.execution.RequestContext;
import org.springframework.webflow.execution.RequestContextHolder;
import org.springframework.webflow.test.MockExternalContext;
import org.springframework.webflow.test.MockParameterMap;
public class JsfViewTests extends TestCase {
@@ -126,12 +127,10 @@ public class JsfViewTests extends TestCase {
/**
* View already exists in view scope and must be restored and the lifecycle executed, no event signaled
*/
public final void testResume_Restored_NoEvent() {
public final void testProcessUserEvent_Restored_NoEvent() {
EasyMock.expect(flashScope.getBoolean(EasyMock.matches(FlowFacesContext.RENDER_RESPONSE_KEY))).andStubReturn(
Boolean.FALSE);
EasyMock.expect(flashScope.put(EasyMock.matches(ViewRootHolder.VIEW_ROOT_HOLDER_KEY), EasyMock.anyObject()))
.andStubReturn(null);
EasyMock.expect(flashScope.put(EasyMock.matches(FlowFacesContext.RENDER_RESPONSE_KEY), EasyMock.anyObject()))
.andStubReturn(null);
@@ -154,12 +153,10 @@ public class JsfViewTests extends TestCase {
* Ajax Request - View already exists in view scope and must be restored and the lifecycle executed, no event
* signaled
*/
public final void testGetView_Restore_Ajax_NoEvent() {
public final void testProcessUserEvent_Restored_Ajax_NoEvent() {
EasyMock.expect(flashScope.getBoolean(EasyMock.matches(FlowFacesContext.RENDER_RESPONSE_KEY))).andStubReturn(
Boolean.FALSE);
EasyMock.expect(flashScope.put(EasyMock.matches(ViewRootHolder.VIEW_ROOT_HOLDER_KEY), EasyMock.anyObject()))
.andStubReturn(null);
EasyMock.expect(flashScope.put(EasyMock.matches(FlowFacesContext.RENDER_RESPONSE_KEY), EasyMock.anyObject()))
.andStubReturn(null);
@@ -182,12 +179,10 @@ public class JsfViewTests extends TestCase {
/**
* View already exists in view scope and must be restored and the lifecycle executed, an event is signaled
*/
public final void testGetView_Restore_EventSignaled() {
public final void testProcessUserEvent_Restored_EventSignaled() {
EasyMock.expect(flashScope.getBoolean(EasyMock.matches(FlowFacesContext.RENDER_RESPONSE_KEY))).andStubReturn(
Boolean.FALSE);
EasyMock.expect(flashScope.put(EasyMock.matches(ViewRootHolder.VIEW_ROOT_HOLDER_KEY), EasyMock.anyObject()))
.andStubReturn(null);
EasyMock.expect(flashScope.put(EasyMock.matches(FlowFacesContext.RENDER_RESPONSE_KEY), EasyMock.anyObject()))
.andStubReturn(null);
@@ -207,6 +202,33 @@ public class JsfViewTests extends TestCase {
assertTrue("The lifecycle should have been invoked", ((EventSignalingLifecycle) lifecycle).executed);
}
public final void testUserEventQueued_GETRefresh() {
MockParameterMap requestParameterMap = new MockParameterMap();
requestParameterMap.put("execution", "e1s1");
EasyMock.expect(context.getRequestParameters()).andStubReturn(requestParameterMap);
EasyMock.replay(new Object[] { context, flowExecutionContext, flowMap, flashScope });
JsfView createdView = new JsfView(new UIViewRoot(), jsfMock.lifecycle(), context);
assertFalse("No user ever should be queued", createdView.userEventQueued());
}
public final void testUserEventQueued_FormSubmitted() {
MockParameterMap requestParameterMap = new MockParameterMap();
requestParameterMap.put("execution", "e1s1");
requestParameterMap.put("javax.faces.ViewState", "e1s1");
EasyMock.expect(context.getRequestParameters()).andStubReturn(requestParameterMap);
EasyMock.replay(new Object[] { context, flowExecutionContext, flowMap, flashScope });
JsfView createdView = new JsfView(new UIViewRoot(), jsfMock.lifecycle(), context);
assertTrue("User event should be queued", createdView.userEventQueued());
}
private class ExceptionalViewHandler extends MockViewHandler {
public void renderView(FacesContext context, UIViewRoot viewToRender) throws IOException, FacesException {
throw new IOException("Rendering blew up");