Skip to content

Commit

Permalink
Prevent NPE in Mojarra when creating initial view
Browse files Browse the repository at this point in the history
Refactor JsfViewFactory to only attempt a restoreView when state is
available. This prevents a NullPointerException from being thrown
when using Mojarra with partial state saving disabled. This change
also makes Web Flow behave in a similar way to the standard
FacesServlet.

Issue: SWF-1571
  • Loading branch information
philwebb committed Nov 16, 2012
1 parent 47e6c00 commit d31900e
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 1 deletion.
Expand Up @@ -142,4 +142,13 @@ private void writeRenderKitIdField(FacesContext context, ResponseWriter writer)
writer.endElement("input");
}
}

/**
* Determine if the request context has existing state.
* @param context the request context
* @return {@code true} if the context has state
*/
static boolean hasState(RequestContext context) {
return (context != null) && (context.getViewScope().contains(FACES_VIEW_STATE));
}
}
Expand Up @@ -132,7 +132,12 @@ private UIViewRoot getViewRootForAlreadySetView(RequestContext context, FacesCon

private UIViewRoot getViewStateViewRoot(RequestContext context, FacesContext facesContext, ViewHandler viewHandler,
String viewName) {
UIViewRoot viewRoot = viewHandler.restoreView(facesContext, viewName);
UIViewRoot viewRoot = null;
if (FlowResponseStateManager.hasState(context)) {
// Only try an initial restore if we have state (see SWF-1571)
viewRoot = viewHandler.restoreView(facesContext, viewName);
}

if (viewRoot != null) {
if (logger.isDebugEnabled()) {
logger.debug("UIViewRoot restored for '" + viewName + "'");
Expand All @@ -144,6 +149,7 @@ private UIViewRoot getViewStateViewRoot(RequestContext context, FacesContext fac
}
viewRoot = viewHandler.createView(facesContext, viewName);
}

return viewRoot;
}

Expand Down
Expand Up @@ -72,12 +72,15 @@ public class JsfViewFactoryTests extends TestCase {

private final MockHttpServletResponse response = new MockHttpServletResponse();

private LocalAttributeMap<Object> viewScope = new LocalAttributeMap<Object>();

protected void setUp() throws Exception {
configureJsf();
this.extContext.setNativeContext(this.servletContext);
this.extContext.setNativeRequest(this.request);
this.extContext.setNativeResponse(this.response);
RequestContextHolder.setRequestContext(this.context);
EasyMock.expect(this.context.getViewScope()).andStubReturn(this.viewScope);
EasyMock.expect(this.context.getFlashScope()).andStubReturn(this.flashMap);
EasyMock.expect(this.context.getExternalContext()).andStubReturn(this.extContext);
EasyMock.expect(this.context.getRequestParameters()).andStubReturn(
Expand Down Expand Up @@ -148,6 +151,7 @@ public final void testGetView_Restore() {
EasyMock.expectLastCall().andReturn(true);

EasyMock.replay(new Object[] { this.context });
setupViewState();

View restoredView = this.factory.getView(this.context);

Expand Down Expand Up @@ -194,6 +198,7 @@ public final void testGetView_RestoreWithBindings() {
EasyMock.expectLastCall().andReturn(true);

EasyMock.replay(new Object[] { this.context });
setupViewState();

View restoredView = this.factory.getView(this.context);

Expand Down Expand Up @@ -229,6 +234,7 @@ public final void testGetView_Restore_Ajax() {
EasyMock.expectLastCall().andReturn(true);

EasyMock.replay(new Object[] { this.context });
setupViewState();

View restoredView = this.factory.getView(this.context);

Expand Down Expand Up @@ -279,6 +285,7 @@ public void testGetView_ExceptionsOnPostRestoreStateEvent() throws Exception {

this.context.inViewState();
EasyMock.expectLastCall().andReturn(true);
setupViewState();

EasyMock.replay(new Object[] { this.context });
this.factory.getView(this.context);
Expand All @@ -289,6 +296,10 @@ public void testGetView_ExceptionsOnPostRestoreStateEvent() throws Exception {
.getExceptionQueuedEventContext().getException());
}

private void setupViewState() {
this.viewScope.put(FlowResponseStateManager.FACES_VIEW_STATE, "X");
}

private class NoExecutionLifecycle extends FlowLifecycle {

public NoExecutionLifecycle(Lifecycle delegate) {
Expand Down

0 comments on commit d31900e

Please sign in to comment.