diff --git a/spring-faces/src/main/java/META-INF/faces-config.xml b/spring-faces/src/main/java/META-INF/faces-config.xml index 22ac2fa0..a676b13e 100644 --- a/spring-faces/src/main/java/META-INF/faces-config.xml +++ b/spring-faces/src/main/java/META-INF/faces-config.xml @@ -16,6 +16,10 @@ org.springframework.webflow.core.expression.el.ScopeSearchingELResolver org.springframework.faces.webflow.FlowExecutionViewHandler + + + org.springframework.faces.support.RequestLoggingPhaseListener + spring.faces.ClientTextValidator diff --git a/spring-faces/src/main/java/org/springframework/faces/support/RequestLoggingPhaseListener.java b/spring-faces/src/main/java/org/springframework/faces/support/RequestLoggingPhaseListener.java new file mode 100644 index 00000000..f8c6d8f9 --- /dev/null +++ b/spring-faces/src/main/java/org/springframework/faces/support/RequestLoggingPhaseListener.java @@ -0,0 +1,26 @@ +package org.springframework.faces.support; + +import javax.faces.event.PhaseEvent; +import javax.faces.event.PhaseId; +import javax.faces.event.PhaseListener; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +public class RequestLoggingPhaseListener implements PhaseListener { + + private Log logger = LogFactory.getLog(RequestLoggingPhaseListener.class); + + public void afterPhase(PhaseEvent event) { + // no-op + } + + public void beforePhase(PhaseEvent event) { + logger.debug("Entering JSF Phase: " + event.getPhaseId()); + } + + public PhaseId getPhaseId() { + return PhaseId.ANY_PHASE; + } + +} diff --git a/spring-faces/src/main/java/org/springframework/faces/webflow/FlowActionListener.java b/spring-faces/src/main/java/org/springframework/faces/webflow/FlowActionListener.java index b57a96a2..e161f78e 100644 --- a/spring-faces/src/main/java/org/springframework/faces/webflow/FlowActionListener.java +++ b/spring-faces/src/main/java/org/springframework/faces/webflow/FlowActionListener.java @@ -25,6 +25,7 @@ public class FlowActionListener implements ActionListener { } else { context.getExternalContext().getRequestMap().remove(JsfView.EVENT_KEY); } + context.renderResponse(); } } diff --git a/spring-faces/src/main/java/org/springframework/faces/webflow/FlowResponseStateManager.java b/spring-faces/src/main/java/org/springframework/faces/webflow/FlowResponseStateManager.java index 70cfa0c4..7da40538 100644 --- a/spring-faces/src/main/java/org/springframework/faces/webflow/FlowResponseStateManager.java +++ b/spring-faces/src/main/java/org/springframework/faces/webflow/FlowResponseStateManager.java @@ -13,9 +13,11 @@ import org.springframework.webflow.execution.RequestContextHolder; public class FlowResponseStateManager extends ResponseStateManager { - private static final int TREE_STATE_INDEX = 0; + private static final int VIEW_ID_INDEX = 0; - private static final int COMPONENT_STATE_INDEX = 1; + private static final int TREE_STATE_INDEX = 1; + + private static final int COMPONENT_STATE_INDEX = 2; // TODO - This needs to be replaced with a common static, probably from FlowExecutorArgumentExtractor private static final String VIEW_STATE_PARAM = "org.springframework.webflow.FlowExecutionKey"; @@ -25,21 +27,32 @@ public class FlowResponseStateManager extends ResponseStateManager { private static final char[] STATE_FIELD_END = "\" />".toCharArray(); - public Object getComponentStateToRestore(FacesContext context) { + public Object getState(FacesContext context, String viewId) { + Object[] structureAndState = new Object[2]; + structureAndState[0] = getTreeStructureToRestore(context, viewId); + if (structureAndState[0] == null) { + return null; + } + structureAndState[1] = getComponentStateToRestore(context); + return structureAndState; + } - Object[] state = (Object[]) RequestContextHolder.getRequestContext().getFlashScope().get(JsfView.STATE_KEY); - return state[COMPONENT_STATE_INDEX]; + public Object getComponentStateToRestore(FacesContext context) { + Object[] state = (Object[]) RequestContextHolder.getRequestContext().getFlowScope().get(JsfView.STATE_KEY); + if (state == null) { + return null; + } else { + return state[COMPONENT_STATE_INDEX]; + } } public Object getTreeStructureToRestore(FacesContext context, String viewId) { - Object[] state = (Object[]) RequestContextHolder.getRequestContext().getFlashScope().get(JsfView.STATE_KEY); - return state[TREE_STATE_INDEX]; - } - - public boolean isPostback(FacesContext context) { - - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Auto-generated method stub"); + Object[] state = (Object[]) RequestContextHolder.getRequestContext().getFlowScope().get(JsfView.STATE_KEY); + if (state == null || !state[VIEW_ID_INDEX].equals(viewId)) { + return null; + } else { + return state[TREE_STATE_INDEX]; + } } private FlowExecution getFlowExecution() { @@ -54,9 +67,10 @@ public class FlowResponseStateManager extends ResponseStateManager { */ public void writeState(FacesContext context, SerializedView state) throws IOException { - Object[] serializableState = new Object[] { state.getStructure(), state.getState() }; + Object[] serializableState = new Object[] { context.getViewRoot().getViewId(), state.getStructure(), + state.getState() }; - RequestContextHolder.getRequestContext().getFlashScope().put(JsfView.STATE_KEY, serializableState); + RequestContextHolder.getRequestContext().getFlowScope().put(JsfView.STATE_KEY, serializableState); Writer writer = context.getResponseWriter(); writer.write(STATE_FIELD_START); diff --git a/spring-faces/src/main/java/org/springframework/webflow/engine/builder/xml/JsfViewFactoryCreator.java b/spring-faces/src/main/java/org/springframework/webflow/engine/builder/xml/JsfViewFactoryCreator.java index 4d7fbc9e..2300c8d4 100644 --- a/spring-faces/src/main/java/org/springframework/webflow/engine/builder/xml/JsfViewFactoryCreator.java +++ b/spring-faces/src/main/java/org/springframework/webflow/engine/builder/xml/JsfViewFactoryCreator.java @@ -13,7 +13,7 @@ import org.springframework.webflow.execution.ViewFactory; /** * A ViewFactoryCreator implementation for creating JSF ViewFactories - * @author Jeremy Grellex + * @author Jeremy Grelle * */ public class JsfViewFactoryCreator implements ViewFactoryCreator { 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 8915fdbc..43a6f6f9 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 @@ -40,6 +40,7 @@ public class JsfViewTests extends TestCase { private RequestContext requestContext = EasyMock.createMock(RequestContext.class); private FlowExecutionContext flowExecutionContext = EasyMock.createMock(FlowExecutionContext.class); private MutableAttributeMap flashMap = EasyMock.createMock(MutableAttributeMap.class); + private MutableAttributeMap flowMap = EasyMock.createMock(MutableAttributeMap.class); private FlowExecutionKey key = new FlowExecutionKey() { @@ -92,17 +93,18 @@ public class JsfViewTests extends TestCase { public final void testRender() { EasyMock.expect(requestContext.getFlashScope()).andStubReturn(flashMap); + EasyMock.expect(requestContext.getFlowScope()).andStubReturn(flowMap); EasyMock.expect(requestContext.getFlowExecutionContext()).andStubReturn(flowExecutionContext); EasyMock.expect(flowExecutionContext.getKey()).andStubReturn(key); - EasyMock.expect(flashMap.put(EasyMock.matches(JsfView.STATE_KEY), EasyMock.anyObject())).andStubReturn(null); + EasyMock.expect(flowMap.put(EasyMock.matches(JsfView.STATE_KEY), EasyMock.anyObject())).andStubReturn(null); EasyMock.expect(flashMap.put(EasyMock.matches("renderResponse"), EasyMock.anyObject())).andStubReturn(null); EasyMock.expect(flashMap.put(EasyMock.matches("responseComplete"), EasyMock.anyObject())).andStubReturn(null); - EasyMock.replay(new Object[] { requestContext, flowExecutionContext, flashMap }); + EasyMock.replay(new Object[] { requestContext, flowExecutionContext, flowMap, flashMap }); view.render(); - EasyMock.verify(new Object[] { requestContext, flowExecutionContext, flashMap }); + EasyMock.verify(new Object[] { requestContext, flowExecutionContext, flowMap, flashMap }); assertNull("The FacesContext was not released", FacesContext.getCurrentInstance()); assertTrue(output.getBuffer().toString().contains(key.toString())); }