New PR3 Features under consideration
- States may now be parameterized with properties when they are entered by a calling Transition. Likewise the states themselves may have ${placeholders} that will be resolved to values at runtime, allowing you to reuse a single state in a different context (kind of like a template).
Note: this replaces the action transition precondition support discussed in the earlier "bindAndValidate" thread on this forum. While that approach worked, it just didn't feel right: it made the flow less explicit, and a precondition really shouldn't have side effects.
- A DecisionState type has been introduced, allowing you to evaluate one or more expressions to decide "where to go next" in a reusable way.
See the following before/after code from the "sellItem" sample for examples of both of these features:
Before new features
Code:
?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE webflow PUBLIC "-//SPRING//DTD WEBFLOW//EN"
"http://www.springframework.org/dtd/spring-webflow.dtd">
<webflow id="sellItem" start-state="setupForm">
<action-state id="setupForm">
<action bean="sellItemAction"/>
<transition on="success" to="enterPriceAndItemCount"/>
</action-state>
<view-state id="enterPriceAndItemCount" view="priceAndItemCountForm">
<transition on="submit" to="bindAndValidatePriceAndItemCount"/>
</view-state>
<action-state id="bindAndValidatePriceAndItemCount">
<action bean="sellItemAction" method="bindAndValidate">
<property name="validatorMethod" value="validatePriceAndItemCount"/>
</action>
<transition on="success" to="enterCategory"/>
<transition on="error" to="enterPriceAndItemCount"/>
</action-state>
<view-state id="enterCategory" view="categoryForm">
<transition on="submit" to="bindAndValidateCategory"/>
</view-state>
<action-state id="bindAndValidateCategory">
<action bean="sellItemAction" method="bindAndValidate"/>
<transition on="${#result == 'success' and flowScope.sale.shipping}" to="enterShippingDetails"/>
<transition on="${#result == 'success' and !flowScope.sale.shipping}" to="showCostOverview"/>
<transition on="error" to="enterCategory"/>
</action-state>
<view-state id="enterShippingDetails" view="shippingDetailsForm">
<transition on="submit" to="bindAndValidateShippingDetails"/>
</view-state>
<action-state id="bindAndValidateShippingDetails">
<action bean="sellItemAction" method="bindAndValidate"/>
<transition on="success" to="showCostOverview"/>
<transition on="error" to="enterShippingDetails"/>
</action-state>
<end-state id="showCostOverview" view="costOverview"/>
</webflow>
After new features
Code:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE webflow PUBLIC "-//SPRING//DTD WEBFLOW//EN"
"http://www.springframework.org/dtd/spring-webflow.dtd">
<webflow id="sellItem" start-state="setupForm">
<action-state id="setupForm">
<action bean="sellItemAction"/>
<transition on="success" to="enterPriceAndItemCount"/>
</action-state>
<view-state id="enterPriceAndItemCount" view="priceAndItemCountForm">
<transition on="submit" to="bindAndValidate">
<property name="validatorMethod" value="validatePriceAndItemCount"/>
<property name="successState" value="enterCategory"/>
<property name="errorState" value="enterPriceAndItemCount"/>
</transition>
</view-state>
<view-state id="enterCategory" view="categoryForm">
<transition on="submit" to="bindAndValidate">
<property name="successState" value="shippingRequired"/>
<property name="errorState" value="enterCategory"/>
</transition>
</view-state>
<decision-state id="shippingRequired">
<if test="${flowScope.sale.shipping}" then="enterShippingDetails" else="showCostOverview"/>
</decision-state>
<view-state id="enterShippingDetails" view="shippingDetailsForm">
<transition on="submit" to="bindAndValidate">
<property name="successState" value="showCostOverview"/>
<property name="errorState" value="enterShippingDetails"/>
</transition>
</view-state>
<end-state id="showCostOverview" view="costOverview"/>
<action-state id="bindAndValidate">
<action bean="sellItemAction" method="bindAndValidate">
<property name="validatorMethod" value="${validatorMethod}"/>
</action>
<transition on="success" to="${successState}"/>
<transition on="error" to="${errorState}"/>
</action-state>
</webflow>
Use of the parameterization is of course completely optional, so the "Before new features" version still works perfectly fine.
Let us know what you think. We're also enhancing FlowExecutionListener to provide support for state pre and post conditions.