Announcement Announcement Module
Collapse
No announcement yet.
New PR3 Features Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • New PR3 Features

    The SWF team has gotten closer to finalizing the major new features for PR3.

    Here they are, all available now in CVS:

    - Transition actions: on the occurence of an event, the ability to execute an action after a state transition is matched but before the transition is executed. The action return result is adapted to a boolean expression--if true, the transition to the target state proceeds, if false, the current state is re-entered. By default a 'success' action result is mapped to true, anything else is mapped to false.

    The biggest use-case for this is in executing so-called 'cross-cutting' actions that have a logical 'success' or 'error' result -- like bindAndValidate.

    Here's an example:
    Code:
    	<view-state id="enterPriceAndItemCount" view="priceAndItemCountForm">
    		<transition on="submit" to="enterCategory">
    			<action bean="sellItemAction" method="bindAndValidate">
    				<property name="validatorMethod" value="validatePriceAndItemCount"/>
    			</action>
    		</transition>
    	</view-state>
    This reduces flow def LoC substantially in the typical 'wizard' flow cases, as previously you were forced to define a separate action state for each ViewState needing a bindAndValidate action.

    - Enhanced FlowExecutionListener lifecycle callbacks, including new 'flowStarting', and 'stateEntering' and 'stateEntered' methods. The first two can be used to test state preconditions (invariants that must hold true for a new state to be allowed to enter). 'stateEntered' can be used to test state postconditions (invariants that must hold true after a state has entered). The new 'StateConditionTester' strategy makes this easily pluggable behind a simple facade interface. 'Sell item' demonstrates this now.

    - State properties. States can now have arbitrary property metadata, just like actions. For example:

    Code:
    	<action-state id="setupForm">
    		<action bean="sellItemAction"/>
    		<transition on="success" to="enterPriceAndItemCount"/>
    		<property name="role" value="manager"/>
    	</action-state>
    The above example assigns the 'role' property to the 'setupForm' state with value 'manager'.

    State properties can be leveraged by StateConditionTesters or views or actions or whatever you want. For example, the SellItemStateConditionTester checks the 'role' property for the state that has been requested to enter and verifies the authenticated user has that role before allowing the state transition to complete.

    - A decision state and a decision action. These constructs allow you to evaluate one or more expressions to decide "where to go next" in a reusable way:

    The decision state:

    Code:
    	<decision-state id="requiresShipping">
    		<if test="$&#123;flowScope.sale.shipping&#125;" then="enterShippingDetails" else="showCostOverview"/>
    	</decision-state>
    The equivalent decision action:

    Code:
    	<action-state id="requiresShipping">
    		<action class="org.springframework.web.flow.action.DecisionAction">
    			<property name="criteria" value="$&#123;flowScope.sale.shipping&#125;"/>
    		</action>
    		<transition on="true" to="enterShippingDetails"/>
    		<transition on="false" to="showCostOverview"/>
    	</action-state>
    Erwin and I have debated whether we really need first class support for the decision state (as you could use the DecisionAction from a action state), but it just seems so elegant and sexy and flexible, with little introduced complexity--so right now we feel its a keeper. Please let us know if you agree or disagree.

    Putting it all together, from sell item:

    Before new features:

    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE webflow PUBLIC "-//SPRING//DTD WEBFLOW//EN"
    	"http&#58;//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="$&#123;#result == 'success' and flowScope.sale.shipping&#125;" to="enterShippingDetails"/>
    		<transition on="$&#123;#result == 'success' and !flowScope.sale.shipping&#125;" 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:
    <webflow id="sellItem" start-state="setupForm">
    
    	<action-state id="setupForm">
    		<action bean="sellItemAction"/>
    		<transition on="success" to="enterPriceAndItemCount"/>
    		<property name="role" value="manager"/>
    	</action-state>
    
    	<view-state id="enterPriceAndItemCount" view="priceAndItemCountForm">
    		<transition on="submit" to="enterCategory">
    			<action bean="sellItemAction" method="bindAndValidate">
    				<property name="validatorMethod" value="validatePriceAndItemCount"/>
    			</action>
    		</transition>
    	</view-state>
    
    	<view-state id="enterCategory" view="categoryForm">
    		<transition on="submit" to="requiresShipping">
    			<action bean="sellItemAction" method="bindAndValidate"/>
    		</transition>
    	</view-state>
    
    	<decision-state id="requiresShipping">
    		<if test="$&#123;flowScope.sale.shipping&#125;" then="enterShippingDetails" else="showCostOverview"/>
    	</decision-state>
    
    	<view-state id="enterShippingDetails" view="shippingDetailsForm">
    		<transition on="submit" to="showCostOverview">
    			<action bean="sellItemAction" method="bindAndValidate"/>
    		</transition>
    	</view-state>
    
    	<end-state id="showCostOverview" view="costOverview"/>
    
    </webflow>

  • #2
    Hi Keith,

    Great! It will help to reduce a lot of redundant state definitions.

    One question about the new decision-state. If you have more than two transitions to decide, it's better to use the DecisionAction or will work something like this?

    Code:
    <decision-state id="decisionExample">
      <if test="$&#123;value1 == 1&#125;" then="state1"/>
      <if test="$&#123;value1 == 2&#125;" then="state2"/>
      <if test="$&#123;value1 == 3&#125;" then="state3" else="state4"/>
    </decision-state>

    Comment


    • #3
      Yes.

      Comment


      • #4
        Keith,

        Are you planning to include in the PR3 the support to spawn a subflow starting execution in a given state?

        Comment


        • #5
          Yes, that's in now too :-)

          Comment


          • #6
            Great!

            We have done some work in this feature, in case you need it, I can help you with this feature.

            Comment

            Working...
            X