From bc2ed3e86888def456adc41a3d61410eb6662bb3 Mon Sep 17 00:00:00 2001 From: Keith Donald Date: Sat, 29 Mar 2008 06:10:01 +0000 Subject: [PATCH] view scope --- .../model/SerializableListDataModel.java | 4 +++ .../faces/webflow/FlowViewStateManager.java | 6 ++--- .../faces/webflow/JsfViewFactoryTests.java | 4 +++ .../faces/webflow/JsfViewTests.java | 4 +++ .../webapp/WEB-INF/flows/booking/booking.xml | 2 +- .../main/webapp/WEB-INF/flows/main/main.xml | 15 ++++++----- .../WEB-INF/flows/main/reviewHotels.xhtml | 10 ++++---- .../webflow/definition/StateDefinition.java | 6 +++++ .../webflow/engine/RequestControlContext.java | 10 ++++++++ .../springframework/webflow/engine/State.java | 4 +++ .../webflow/engine/ViewState.java | 8 ++++++ .../webflow/engine/ViewVariable.java | 6 ++--- .../impl/RequestControlContextImpl.java | 25 +++++++++++++++++++ .../webflow/execution/RequestContext.java | 17 +++++++++++++ .../el/ImplicitFlowVariableELResolver.java | 1 + .../el/ScopeSearchingELResolver.java | 18 +++++++++++++ .../webflow/test/MockRequestContext.java | 17 +++++++++++++ .../test/MockRequestControlContext.java | 9 +++++++ .../webflow/engine/ViewStateTests.java | 6 ++--- .../webflow/engine/ViewVariableTests.java | 25 +++++++++++++------ 20 files changed, 166 insertions(+), 31 deletions(-) diff --git a/spring-faces/src/main/java/org/springframework/faces/model/SerializableListDataModel.java b/spring-faces/src/main/java/org/springframework/faces/model/SerializableListDataModel.java index 0def242e..d58334a4 100644 --- a/spring-faces/src/main/java/org/springframework/faces/model/SerializableListDataModel.java +++ b/spring-faces/src/main/java/org/springframework/faces/model/SerializableListDataModel.java @@ -97,4 +97,8 @@ public class SerializableListDataModel extends DataModel implements Serializable setRowIndex(newRowIndex); } + public String toString() { + return data.toString(); + } + } diff --git a/spring-faces/src/main/java/org/springframework/faces/webflow/FlowViewStateManager.java b/spring-faces/src/main/java/org/springframework/faces/webflow/FlowViewStateManager.java index bdb14515..03d12083 100644 --- a/spring-faces/src/main/java/org/springframework/faces/webflow/FlowViewStateManager.java +++ b/spring-faces/src/main/java/org/springframework/faces/webflow/FlowViewStateManager.java @@ -74,7 +74,7 @@ public class FlowViewStateManager extends StateManager { } RequestContext requestContext = RequestContextHolder.getRequestContext(); - SerializedView view = (SerializedView) requestContext.getFlowScope().get(SERIALIZED_VIEW_STATE); + SerializedView view = (SerializedView) requestContext.getViewScope().get(SERIALIZED_VIEW_STATE); viewRoot.processRestoreState(context, view.componentState); logger.debug("UIViewRoot component state restored"); } @@ -85,7 +85,7 @@ public class FlowViewStateManager extends StateManager { } RequestContext requestContext = RequestContextHolder.getRequestContext(); - SerializedView view = (SerializedView) requestContext.getFlowScope().get(SERIALIZED_VIEW_STATE); + SerializedView view = (SerializedView) requestContext.getViewScope().get(SERIALIZED_VIEW_STATE); if (view == null || !view.viewId.equals(viewId)) { logger.debug("No matching view in flow scope;"); return null; @@ -145,7 +145,7 @@ public class FlowViewStateManager extends StateManager { } SerializedView view = new SerializedView(context.getViewRoot().getViewId(), getTreeStructureToSave(context), getComponentStateToSave(context)); - requestContext.getFlowScope().put(SERIALIZED_VIEW_STATE, view); + requestContext.getViewScope().put(SERIALIZED_VIEW_STATE, view); return view; } diff --git a/spring-faces/src/test/java/org/springframework/faces/webflow/JsfViewFactoryTests.java b/spring-faces/src/test/java/org/springframework/faces/webflow/JsfViewFactoryTests.java index 4e312afc..d040c9df 100644 --- a/spring-faces/src/test/java/org/springframework/faces/webflow/JsfViewFactoryTests.java +++ b/spring-faces/src/test/java/org/springframework/faces/webflow/JsfViewFactoryTests.java @@ -228,6 +228,10 @@ public class JsfViewFactoryTests extends TestCase { private class NormalViewState implements StateDefinition { + public boolean isViewState() { + return true; + } + public String getId() { throw new UnsupportedOperationException("Auto-generated method stub"); } 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 61deb7a2..e7df8e65 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 @@ -265,6 +265,10 @@ public class JsfViewTests extends TestCase { MutableAttributeMap attrs = new LocalAttributeMap(); + public boolean isViewState() { + return true; + } + public ModalViewState() { attrs.asMap().put("modal", Boolean.TRUE); } diff --git a/spring-webflow-samples/booking-faces/src/main/webapp/WEB-INF/flows/booking/booking.xml b/spring-webflow-samples/booking-faces/src/main/webapp/WEB-INF/flows/booking/booking.xml index e90e23ac..7285c658 100755 --- a/spring-webflow-samples/booking-faces/src/main/webapp/WEB-INF/flows/booking/booking.xml +++ b/spring-webflow-samples/booking-faces/src/main/webapp/WEB-INF/flows/booking/booking.xml @@ -7,7 +7,7 @@ - + diff --git a/spring-webflow-samples/booking-faces/src/main/webapp/WEB-INF/flows/main/main.xml b/spring-webflow-samples/booking-faces/src/main/webapp/WEB-INF/flows/main/main.xml index 8cbeb06c..4e43dbbe 100755 --- a/spring-webflow-samples/booking-faces/src/main/webapp/WEB-INF/flows/main/main.xml +++ b/spring-webflow-samples/booking-faces/src/main/webapp/WEB-INF/flows/main/main.xml @@ -7,7 +7,7 @@ - + @@ -18,7 +18,7 @@ - + @@ -28,20 +28,19 @@ - + + + - - - - + @@ -56,5 +55,5 @@ - + \ No newline at end of file diff --git a/spring-webflow-samples/booking-faces/src/main/webapp/WEB-INF/flows/main/reviewHotels.xhtml b/spring-webflow-samples/booking-faces/src/main/webapp/WEB-INF/flows/main/reviewHotels.xhtml index 8f3e52ae..8555ee62 100644 --- a/spring-webflow-samples/booking-faces/src/main/webapp/WEB-INF/flows/main/reviewHotels.xhtml +++ b/spring-webflow-samples/booking-faces/src/main/webapp/WEB-INF/flows/main/reviewHotels.xhtml @@ -17,22 +17,22 @@
- + Name - #{hotel.name} + #{h.name} Address - #{hotel.address} + #{h.address} City, State - #{hotel.city}, #{hotel.state}, #{hotel.country} + #{h.city}, #{h.state}, #{h.country} Zip - #{hotel.zip} + #{h.zip} Action diff --git a/spring-webflow/src/main/java/org/springframework/webflow/definition/StateDefinition.java b/spring-webflow/src/main/java/org/springframework/webflow/definition/StateDefinition.java index 286d600f..8627c46b 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/definition/StateDefinition.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/definition/StateDefinition.java @@ -37,4 +37,10 @@ public interface StateDefinition extends Annotated { * @return the state identifier */ public String getId(); + + /** + * Returns true if this state is a view state. + * @return true if a view state, false otherwise + */ + public boolean isViewState(); } \ No newline at end of file diff --git a/spring-webflow/src/main/java/org/springframework/webflow/engine/RequestControlContext.java b/spring-webflow/src/main/java/org/springframework/webflow/engine/RequestControlContext.java index 62a26df4..bea026ad 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/engine/RequestControlContext.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/engine/RequestControlContext.java @@ -117,4 +117,14 @@ public interface RequestControlContext extends RequestContext { */ public boolean getAlwaysRedirectOnPause(); + /** + * Initialize view scope. Called by view states when they enter. + */ + public void initViewScope(); + + /** + * Destroy view-scope. Called by view-states when they exit. + */ + public void destroyViewScope(); + } \ No newline at end of file diff --git a/spring-webflow/src/main/java/org/springframework/webflow/engine/State.java b/spring-webflow/src/main/java/org/springframework/webflow/engine/State.java index b9d7f305..f6b52011 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/engine/State.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/engine/State.java @@ -98,6 +98,10 @@ public abstract class State extends AnnotatedObject implements StateDefinition { return id; } + public boolean isViewState() { + return false; + } + // implementation specific /** diff --git a/spring-webflow/src/main/java/org/springframework/webflow/engine/ViewState.java b/spring-webflow/src/main/java/org/springframework/webflow/engine/ViewState.java index c38654b4..0f170de1 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/engine/ViewState.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/engine/ViewState.java @@ -77,6 +77,12 @@ public class ViewState extends TransitionableState { this.viewFactory = viewFactory; } + // implementing StateDefinition + + public boolean isViewState() { + return true; + } + /** * Adds a view variable. * @param variable the variable @@ -156,6 +162,7 @@ public class ViewState extends TransitionableState { } protected void doPreEntryActions(RequestControlContext context) throws FlowExecutionException { + context.initViewScope(); createVariables(context); } @@ -196,6 +203,7 @@ public class ViewState extends TransitionableState { public void exit(RequestControlContext context) { destroyVariables(context); + context.destroyViewScope(); super.exit(context); } diff --git a/spring-webflow/src/main/java/org/springframework/webflow/engine/ViewVariable.java b/spring-webflow/src/main/java/org/springframework/webflow/engine/ViewVariable.java index 55a325d3..b8278a76 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/engine/ViewVariable.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/engine/ViewVariable.java @@ -58,7 +58,7 @@ public class ViewVariable extends AnnotatedObject { */ public void create(RequestContext context) { Object value = valueFactory.createInitialValue(context); - context.getFlowScope().put(name, value); + context.getViewScope().put(name, value); } /** @@ -67,7 +67,7 @@ public class ViewVariable extends AnnotatedObject { * @param context the executing flow */ public void restore(RequestContext context) { - Object value = context.getFlowScope().get(name); + Object value = context.getViewScope().get(name); valueFactory.restoreReferences(value, context); } @@ -76,6 +76,6 @@ public class ViewVariable extends AnnotatedObject { * @param context the executing flow */ public Object destroy(RequestContext context) { - return context.getFlowScope().remove(name); + return context.getViewScope().remove(name); } } diff --git a/spring-webflow/src/main/java/org/springframework/webflow/engine/impl/RequestControlContextImpl.java b/spring-webflow/src/main/java/org/springframework/webflow/engine/impl/RequestControlContextImpl.java index b120920f..a5cd8275 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/engine/impl/RequestControlContextImpl.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/engine/impl/RequestControlContextImpl.java @@ -48,6 +48,8 @@ import org.springframework.webflow.execution.FlowSession; */ class RequestControlContextImpl implements RequestControlContext { + private static final String FLOW_VIEW_MAP_ATTRIBUTE = "flowViewMap"; + /** * The owning flow execution carrying out this request. */ @@ -116,6 +118,21 @@ class RequestControlContextImpl implements RequestControlContext { return flowExecution.getFlashScope(); } + public boolean inViewState() { + return flowExecution.isActive() && getCurrentState() != null && getCurrentState().isViewState(); + } + + public MutableAttributeMap getViewScope() throws IllegalStateException { + if (!flowExecution.isActive()) { + throw new IllegalStateException("This flow is not active"); + } + if (!getCurrentState().isViewState()) { + throw new IllegalStateException("The current state '" + getCurrentState().getId() + "' of this flow '" + + getActiveFlow().getId() + "' is not a view state - view scope not accessible"); + } + return (MutableAttributeMap) getFlowScope().get(FLOW_VIEW_MAP_ATTRIBUTE); + } + public MutableAttributeMap getFlowScope() { return flowExecution.getActiveSession().getScope(); } @@ -196,6 +213,14 @@ class RequestControlContextImpl implements RequestControlContext { flowExecution.start(flow, input, this); } + public void initViewScope() { + getFlowScope().put(FLOW_VIEW_MAP_ATTRIBUTE, new LocalAttributeMap()); + } + + public void destroyViewScope() { + getFlowScope().remove(FLOW_VIEW_MAP_ATTRIBUTE); + } + public boolean handleEvent(Event event) throws FlowExecutionException { this.lastEvent = event; return flowExecution.handleEvent(event, this); diff --git a/spring-webflow/src/main/java/org/springframework/webflow/execution/RequestContext.java b/spring-webflow/src/main/java/org/springframework/webflow/execution/RequestContext.java index 99d5b163..ea992b93 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/execution/RequestContext.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/execution/RequestContext.java @@ -89,6 +89,22 @@ public interface RequestContext { */ public MutableAttributeMap getFlashScope(); + /** + * Returns true if the flow is currently active and in a view state. When in a view state {@link #getViewScope()}, + * can be safely called. + * @see #getViewScope() + * @return true if in a view state, false if not + */ + public boolean inViewState(); + + /** + * Returns a mutable map for accessing and/or setting attributes in view scope. View scoped attributes exist for + * the life of the current view state. + * @return the view scope + * @throws IllegalStateException this flow is not in a view-state + */ + public MutableAttributeMap getViewScope() throws IllegalStateException; + /** * Returns a mutable map for accessing and/or setting attributes in flow scope. Flow scoped attributes exist for * the life of the active flow session. @@ -177,4 +193,5 @@ public interface RequestContext { * @return the flow execution URL */ public String getFlowExecutionUrl() throws IllegalStateException; + } \ No newline at end of file diff --git a/spring-webflow/src/main/java/org/springframework/webflow/expression/el/ImplicitFlowVariableELResolver.java b/spring-webflow/src/main/java/org/springframework/webflow/expression/el/ImplicitFlowVariableELResolver.java index d7d2dfe9..bab6d123 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/expression/el/ImplicitFlowVariableELResolver.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/expression/el/ImplicitFlowVariableELResolver.java @@ -151,6 +151,7 @@ public class ImplicitFlowVariableELResolver extends ELResolver { vars.put("requestParameters", requestContextResolver); vars.put("requestScope", requestContextResolver); vars.put("flashScope", requestContextResolver); + vars.put("viewScope", requestContextResolver); vars.put("flowScope", requestContextResolver); vars.put("conversationScope", requestContextResolver); vars.put("messageContext", requestContextResolver); diff --git a/spring-webflow/src/main/java/org/springframework/webflow/expression/el/ScopeSearchingELResolver.java b/spring-webflow/src/main/java/org/springframework/webflow/expression/el/ScopeSearchingELResolver.java index a696e102..832bac45 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/expression/el/ScopeSearchingELResolver.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/expression/el/ScopeSearchingELResolver.java @@ -67,6 +67,9 @@ public class ScopeSearchingELResolver extends ELResolver { } else if (requestContext.getFlashScope().contains(attributeName)) { elContext.setPropertyResolved(true); return requestContext.getFlashScope().get(attributeName).getClass(); + } else if (requestContext.inViewState() && requestContext.getViewScope().contains(attributeName)) { + elContext.setPropertyResolved(true); + return requestContext.getViewScope().get(attributeName).getClass(); } else if (requestContext.getFlowScope().contains(attributeName)) { elContext.setPropertyResolved(true); return requestContext.getFlowScope().get(attributeName).getClass(); @@ -96,6 +99,12 @@ public class ScopeSearchingELResolver extends ELResolver { } elContext.setPropertyResolved(true); return requestContext.getFlashScope().get(attributeName); + } else if (requestContext.inViewState() && requestContext.getViewScope().contains(attributeName)) { + if (logger.isDebugEnabled()) { + logger.debug("Successfully resolved view scoped variable '" + property + "'"); + } + elContext.setPropertyResolved(true); + return requestContext.getViewScope().get(attributeName); } else if (requestContext.getFlowScope().contains(attributeName)) { if (logger.isDebugEnabled()) { logger.debug("Successfully resolved flow scoped variable '" + property + "'"); @@ -125,6 +134,9 @@ public class ScopeSearchingELResolver extends ELResolver { } else if (requestContext.getFlashScope().contains(attributeName)) { elContext.setPropertyResolved(true); return false; + } else if (requestContext.inViewState() && requestContext.getViewScope().contains(attributeName)) { + elContext.setPropertyResolved(true); + return false; } else if (requestContext.getFlowScope().contains(attributeName)) { elContext.setPropertyResolved(true); return false; @@ -154,6 +166,12 @@ public class ScopeSearchingELResolver extends ELResolver { } elContext.setPropertyResolved(true); requestContext.getFlashScope().put(attributeName, value); + } else if (requestContext.inViewState() && requestContext.getViewScope().contains(attributeName)) { + if (logger.isDebugEnabled()) { + logger.debug("Successfully resolved view scoped variable '" + property + "'"); + } + elContext.setPropertyResolved(true); + requestContext.getViewScope().put(attributeName, value); } else if (requestContext.getFlowScope().contains(attributeName)) { if (logger.isDebugEnabled()) { logger.debug("Successfully resolved flow scoped variable '" + property + "'"); diff --git a/spring-webflow/src/main/java/org/springframework/webflow/test/MockRequestContext.java b/spring-webflow/src/main/java/org/springframework/webflow/test/MockRequestContext.java index 13f5c0fe..3aadc3d8 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/test/MockRequestContext.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/test/MockRequestContext.java @@ -45,6 +45,8 @@ import org.springframework.webflow.execution.RequestContext; */ public class MockRequestContext implements RequestContext { + protected static final String FLOW_VIEW_MAP_ATTRIBUTE = "flowViewMap"; + private FlowExecutionContext flowExecutionContext; private ExternalContext externalContext; @@ -126,6 +128,21 @@ public class MockRequestContext implements RequestContext { return getMockFlowExecutionContext().getFlashScope(); } + public boolean inViewState() { + return getFlowExecutionContext().isActive() && getCurrentState() != null && getCurrentState().isViewState(); + } + + public MutableAttributeMap getViewScope() throws IllegalStateException { + if (!getFlowExecutionContext().isActive()) { + throw new IllegalStateException("This flow is not active"); + } + if (!getCurrentState().isViewState()) { + throw new IllegalStateException("The current state '" + getCurrentState().getId() + "' of this flow '" + + getActiveFlow().getId() + "' is not a view state - view scope not accessible"); + } + return (MutableAttributeMap) getFlowScope().get(FLOW_VIEW_MAP_ATTRIBUTE); + } + public MutableAttributeMap getFlowScope() { return getFlowExecutionContext().getActiveSession().getScope(); } diff --git a/spring-webflow/src/main/java/org/springframework/webflow/test/MockRequestControlContext.java b/spring-webflow/src/main/java/org/springframework/webflow/test/MockRequestControlContext.java index c45bd958..da7d7f55 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/test/MockRequestControlContext.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/test/MockRequestControlContext.java @@ -15,6 +15,7 @@ */ package org.springframework.webflow.test; +import org.springframework.webflow.core.collection.LocalAttributeMap; import org.springframework.webflow.core.collection.MutableAttributeMap; import org.springframework.webflow.engine.Flow; import org.springframework.webflow.engine.RequestControlContext; @@ -73,6 +74,14 @@ public class MockRequestControlContext extends MockRequestContext implements Req flow.start(this, input); } + public void initViewScope() { + getFlowScope().put(FLOW_VIEW_MAP_ATTRIBUTE, new LocalAttributeMap()); + } + + public void destroyViewScope() { + getFlowScope().remove(FLOW_VIEW_MAP_ATTRIBUTE); + } + public boolean handleEvent(Event event) { setLastEvent(event); return ((Flow) getActiveFlow()).handleEvent(this); diff --git a/spring-webflow/src/test/java/org/springframework/webflow/engine/ViewStateTests.java b/spring-webflow/src/test/java/org/springframework/webflow/engine/ViewStateTests.java index 957b4af3..d4ab66e0 100644 --- a/spring-webflow/src/test/java/org/springframework/webflow/engine/ViewStateTests.java +++ b/spring-webflow/src/test/java/org/springframework/webflow/engine/ViewStateTests.java @@ -55,7 +55,7 @@ public class ViewStateTests extends TestCase { })); MockRequestControlContext context = new MockRequestControlContext(flow); state.enter(context); - assertEquals("bar", context.getFlowScope().getString("foo")); + assertEquals("bar", context.getViewScope().getString("foo")); assertTrue("Render not called", context.getFlowScope().contains("renderCalled")); assertFalse(context.getFlowExecutionRedirectSent()); } @@ -151,7 +151,7 @@ public class ViewStateTests extends TestCase { state.resume(context); assertTrue("Render not called", context.getFlowScope().contains("renderCalled")); assertFalse(context.getFlowExecutionRedirectSent()); - assertEquals("Restored", ((TestBean) context.getFlowScope().get("foo")).datum1); + assertEquals("Restored", ((TestBean) context.getViewScope().get("foo")).datum1); } public void testResumeViewStateForEvent() { @@ -202,7 +202,7 @@ public class ViewStateTests extends TestCase { new ViewState(flow, "next", viewFactory); MockRequestControlContext context = new MockRequestControlContext(flow); state.enter(context); - assertTrue(context.getFlowScope().contains("foo")); + assertTrue(context.getViewScope().contains("foo")); context = new MockRequestControlContext(context.getFlowExecutionContext()); context.putRequestParameter("_eventId", "submit"); state.resume(context); diff --git a/spring-webflow/src/test/java/org/springframework/webflow/engine/ViewVariableTests.java b/spring-webflow/src/test/java/org/springframework/webflow/engine/ViewVariableTests.java index b40e235c..a6461fd6 100644 --- a/spring-webflow/src/test/java/org/springframework/webflow/engine/ViewVariableTests.java +++ b/spring-webflow/src/test/java/org/springframework/webflow/engine/ViewVariableTests.java @@ -3,7 +3,7 @@ package org.springframework.webflow.engine; import junit.framework.TestCase; import org.springframework.webflow.execution.RequestContext; -import org.springframework.webflow.test.MockRequestContext; +import org.springframework.webflow.test.MockRequestControlContext; public class ViewVariableTests extends TestCase { @@ -18,9 +18,12 @@ public class ViewVariableTests extends TestCase { public void restoreReferences(Object value, RequestContext context) { } }); - MockRequestContext context = new MockRequestContext(); + Flow flow = new Flow("flow"); + ViewState view = new ViewState(flow, "view", new StubViewFactory()); + MockRequestControlContext context = new MockRequestControlContext(flow); + view.enter(context); var.create(context); - assertEquals("bar", context.getFlowScope().get("foo")); + assertEquals("bar", context.getViewScope().get("foo")); } public void testDestroyVariable() { @@ -32,11 +35,14 @@ public class ViewVariableTests extends TestCase { public void restoreReferences(Object value, RequestContext context) { } }); - MockRequestContext context = new MockRequestContext(); + Flow flow = new Flow("flow"); + ViewState view = new ViewState(flow, "view", new StubViewFactory()); + MockRequestControlContext context = new MockRequestControlContext(flow); + view.enter(context); var.create(context); - assertEquals("bar", context.getFlowScope().get("foo")); + assertEquals("bar", context.getViewScope().get("foo")); var.destroy(context); - assertFalse(context.getFlowScope().contains("foo")); + assertFalse(context.getViewScope().contains("foo")); } public void testRestoreVariable() { @@ -50,10 +56,13 @@ public class ViewVariableTests extends TestCase { assertEquals("bar", value); } }); - MockRequestContext context = new MockRequestContext(); + Flow flow = new Flow("flow"); + ViewState view = new ViewState(flow, "view", new StubViewFactory()); + MockRequestControlContext context = new MockRequestControlContext(flow); + view.enter(context); var.create(context); var.restore(context); - assertEquals("bar", context.getFlowScope().get("foo")); + assertEquals("bar", context.getViewScope().get("foo")); assertTrue(restoreCalled); }