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()));
}