<?xml version="1.0" encoding="UTF-8"?>
<chapter id="flow-execution">
	<title>Flow execution</title>
	<sect1 id="execution-intro">
		<title>Introduction</title>
		<para>
			Once a flow has been defined, any number of executions of it can be launched in parallel 
			at runtime.  Execution of a flow is carried out by a dedicated system that 
			is based internally on a state machine that runs atop the Java VM.  As the life of a
			flow execution can span more than one request into the server, this system 
			is also responsible for persisting execution state across requests.
		</para>
		<para>
			This chapter documents Spring Web Flow's flow execution system.  You will
			learn the core constructs of the system and how to execute flows out-of-container 
			within a JUnit test environment.
		</para>
    </sect1>
    <sect1 id="execution">
    	<title>FlowExecution</title>
    	<para>
		    A <literal>org.springframework.webflow.execution.FlowExecution</literal> is a runtime instantiation of a flow definition.
		    Given a single <literal>FlowDefinition</literal>, any
		    number of independent flow executions may be created.
		    These executions are typically created by a <literal>FlowExecutionFactory</literal>.
		</para>
		<para>
		    A flow execution carries out the execution of program instructions defined within
		    its definition in response to user events.
		</para>
		<para>
			<emphasis>
				It may be helpful to think of a flow definition as analagous to a Java <literal>Class</literal>, and a 
				flow execution as analagous to an object instance of that <literal>Class</literal>.  Signaling
				an execution event can be considered analagous to sending an object a message.
			</emphasis>
		</para>
	    <sect2 id="execution-creation">
 	  	 	<title>Flow execution creation</title>
 	  	 	<programlisting>
    FlowDefinition definition = ...
    FlowExecutionFactory factory = ...
    FlowExecution execution = factory.createFlowExecution(definition);
 	  	 	</programlisting>
			<para>
				Once created, a new flow execution is initially inactive, waiting to be started.  Once 
				started, a flow execution becomes active by entering its <literal>startState</literal>.  
				From there, it continues executing until it enters a state where user input is required
				to continue or it terminates.
			</para>
 	  	</sect2>
	    <sect2 id="execution-start">
 	  	 	<title>Flow execution startup</title>
 	  	 	<programlisting>
    ExternalContext context = ...
    execution.start(context);
 	  	 	</programlisting>
			<para>
				When a flow execution reaches a state where input is required to continue, it is said to have <emphasis>paused</emphasis>,
				where it waits in that state for user input to be provided.
			</para>
			<para>			
				User input is provided by <emphasis>signaling an event</emphasis> that
				<emphasis>resumes</emphasis> the flow execution by communicating what user action was taken.
				Attributes of the signal event request form the basis for user input.  The flow execution 
				resumes by consuming the event.
			</para>
			<para>
				Once a flow execution has resumed, it continues executing until it again enters a 
				state where more input is needed or it terminates.  Once a flow execution has terminated
				it becomes inactive and cannot be resumed.
			</para>
 	  	</sect2>
	    <sect2 id="execution-resume">
 	  	 	<title>Flow execution resume</title>
 	  	 	<programlisting>
    ExternalContext context = ...
    execution.resume(context);
    if (execution.isActive()) {
        // still active but paused
    } else {
        // has ended
    }
 	  	 	</programlisting>
 	  	</sect2>		
	    <sect2 id="execution-lifecycle">
 	  	 	<title>Flow execution lifecycle</title>
   	 		<para>
    			As outlined, a flow execution can go through a number of phases throughout its lifecycle; 
   		 		for example, <emphasis>created</emphasis>, <emphasis>active</emphasis>, <emphasis>paused</emphasis>, 
   		 		<emphasis>ended</emphasis>.
   		 	</para>
    		<para>
   	 			Spring Web Flow gives you the ability to observe the lifecycle of an 
    			executing flow by implementing a <literal>FlowExecutionListener</literal>.
    		</para>
    		<para>
    			The different phases of a flow execution are shown graphically below:
	    	</para>
			<mediaobject>
				<imageobject role="fo">
					<imagedata fileref="images/flowexecution-statediagram.png" format="PNG" align="center"/>
				</imageobject>
				<imageobject role="html">
					<imagedata fileref="images/flowexecution-statediagram.png" format="PNG" align="center"/>
				</imageobject>
				<caption>
					<para>Flow execution lifecycle</para>
				</caption>
			</mediaobject>
		</sect2>
	    <sect2 id="execution-properties">
 	  	 	<title>Flow execution properties</title>
   	 		<para>
   	 			The Spring Web Flow flow execution implementation is <literal>org.springframework.webflow.engine.impl.FlowExecutionImpl</literal>,
   	 			typically created by a <literal>FlowExecutionImplFactory</literal> (a <literal>FlowExecutionFactory</literal> implementation).
   	 			The configurable properties of this flow execution implementation are summarized below:
   		 	</para>
	    	<table>
   				<title>Flow Execution properties</title>
	            <tgroup cols="4">
    	            <colspec colname="c1" colwidth="2*" />
	                <colspec colname="c2" colwidth="4*" />
	                <colspec colname="c2" colwidth="2*" />
	                <colspec colname="c2" colwidth="2*" />
        	        <thead>
		                <row>
            	            <entry>Property name</entry>
                	        <entry>Description</entry>
    	          			<entry>Cardinality</entry>
	                        <entry>Default value</entry>
        	            </row>
   					</thead>
   					<tbody>
						<row>
             				<entry>definition</entry>
							<entry>The flow definition to be executed.</entry>
						    <entry>
								<emphasis>1</emphasis>
							</entry>
						</row>
 						<row>
     						<entry>listeners</entry>
							<entry>The set of observers observing the lifecycle of this flow execution.</entry>
							<entry>
								<emphasis>0..*</emphasis>
							</entry>
							<entry>Empty</entry>
						</row>
 						<row>
     						<entry>attributes</entry>
							<entry>Global system attributes that can be used to affect flow execution behavior</entry>
							<entry>
								<emphasis>0..*</emphasis>
							</entry>
							<entry>Empty</entry>
						</row>
					</tbody>
				</tgroup>
			</table>
    		<para>
    			The configurable constructs related to flow execution are shown graphically below:
	    	</para>
			<mediaobject>
				<imageobject role="fo">
					<imagedata fileref="images/flowexecution-classdiagram.png" format="PNG" align="center"/>
				</imageobject>
				<imageobject role="html">
					<imagedata fileref="images/flowexecution-classdiagram.png" format="PNG" align="center"/>
				</imageobject>
				<caption>
					<para>Flow execution</para>
				</caption>
			</mediaobject>
		</sect2>
	    <sect2 id="execution-impl-creation">
 	  	 	<title>Flow execution impl creation</title>
 	  	 	<programlisting>
    FlowExecutionFactory factory = new FlowExecutionImplFactory();
    factory.setExecutionListeners(...);
    factory.setExecutionAttributes(...);
    FlowExecution execution = factory.createFlowExecution(definition);
 	  	 	</programlisting>
 	  	</sect2>		
	</sect1>
	<sect1 id="execution-context">
		<title>Flow execution context</title>
		<para>
			Once created, a flow execution, representing the state of a flow at a point in time, 
			maintains contextual state about itself that can be reasoned upon by clients.  In addition,
			a flow execution exposes several data structures, called scopes, that allow clients to set 
			arbitrary attributes that are managed by the execution.
		</para>
		<para>
			The contextual properties associated with a flow execution are summarized below:
		</para>
    	<table>
			<title>Flow Execution Context properties</title>
            <tgroup cols="4">
   	            <colspec colname="c1" colwidth="2*" />
                <colspec colname="c2" colwidth="4*" />
                <colspec colname="c2" colwidth="2*" />
                <colspec colname="c2" colwidth="2*" />
       	        <thead>
	                <row>
           	            <entry>Property name</entry>
               	        <entry>Description</entry>
   	          			<entry>Cardinality</entry>
                        <entry>Default value</entry>
       	            </row>
				</thead>
				<tbody>
					<row>
           				<entry>active</entry>
						<entry>
							A flag indicating if the flow execution is active.
							An inactive flow execution has either ended or has never been started.
						</entry>
					    <entry>
							<emphasis>1</emphasis>
						</entry>
					</row>
					<row>
   						<entry>definition</entry>
						<entry>
							The definition of the flow execution.  The flow definition serves as
							the blueprint for the program.  <emphasis>It may be helpful to think of a flow
							definition as like a <literal>Class</literal> and a 
							flow execution as like an instance of that <literal>Class</literal></emphasis>.
							This method may always be safely called.
						</entry>
						<entry>
							<emphasis>1</emphasis>
						</entry>
					</row>
					<row>
   						<entry>activeSession</entry>
						<entry>
							The active flow session, tracking the flow that is currently executing
							and what state it is in.  The active session can change over the life of the 
							flow execution because a flow can spawn another flow as a subflow.
							This property can only be queried while the flow execution is active.
						</entry>
						<entry>
							<emphasis>1</emphasis>
						</entry>
					</row>
					<row>
   						<entry>conversationScope</entry>
						<entry>
							A data map that forms the basis for "conversation scope". Arbitrary attributes placed in this map will be retained
							for the life of the flow execution and correspond to the length of the logical conversation.
							This map is <emphasis>shared</emphasis> by all flow sessions.
						</entry>
						<entry>
							<emphasis>1</emphasis>
						</entry>
					</row>					
				</tbody>
			</tgroup>
		</table>
		<para>
			As a flow execution is manipulated by clients its contextual state changes.  Consider how 
			contextual state is effected when the following events occur:
		</para>
    	<table>
			<title>An ordered set of events and their effects on flow execution context</title>
            <tgroup cols="3">
   	            <colspec colname="c1" colwidth="2*" />
   	            <colspec colname="c1" colwidth="2*" />
                <colspec colname="c2" colwidth="4*" />
       	        <thead>
	                <row>
           	            <entry>Flow Execution Event</entry>
           	            <entry>Active?</entry>
               	        <entry>Value of the <literal>activeSession</literal> property</entry>
       	            </row>
				</thead>
				<tbody>
					<row>
           				<entry>created</entry>
						<entry>false</entry>
						<entry>Throws an IllegalStateException</entry>
					</row>
					<row>
   						<entry>started</entry>
						<entry>true</entry>
						<entry>
							A <literal>FlowSession</literal> whose <literal>definition</literal>
							is the top-level flow definition and whose <literal>state</literal> is the definition's start state.
						</entry>
					</row>
					<row>
   						<entry>state entered</entry>
						<entry>true</entry>
						<entry>
							A <literal>FlowSession</literal> whose <literal>definition</literal>
							is the top-level flow definition and whose <literal>state</literal> is the newly entered state.
						</entry>
					</row>
					<row>
   						<entry>subflow spawned</entry>
						<entry>true</entry>
						<entry>
							A <literal>FlowSession</literal> whose <literal>definition</literal>
							is the subflow definition and whose <literal>state</literal> is the subflow's start state.
						</entry>
					</row>
					<row>
   						<entry>subflow ended</entry>
						<entry>true</entry>
						<entry>
							A <literal>FlowSession</literal> whose <literal>definition</literal> is back to the
							top-level flow definition and whose <literal>state</literal> is the resuming state.
						</entry>
					</row>
					<row>
   						<entry>ended</entry>
						<entry>false</entry>
						<entry>Throws an IllegalStateException</entry>
					</row>
				</tbody>
			</tgroup>
		</table>
		<para>
			As you can see, the <literal>activeSession</literal> of a flow execution changes when a subflow 
			is spawned.  Each flow execution maintains a stack of flow sessions, where each flow session 
			represents a spawned instance of a flow definition.  When a flow execution starts, the session stack initially 
			consists of one (1) entry, an instance dubbed the <emphasis>root session</emphasis>.
			When a subflow is spawned, the stack increases to two (2) entries.  When the subflow ends, 
			the stack decreases back to one (1) entry.  The active session is always
			the session at the top of the stack.
		</para>
		<para>
			The contextual properties associated with a <literal>FlowSession</literal> are summarized below:
		</para>
    	<table>
			<title>Flow Session properties</title>
            <tgroup cols="4">
   	            <colspec colname="c1" colwidth="2*" />
                <colspec colname="c2" colwidth="4*" />
                <colspec colname="c2" colwidth="2*" />
                <colspec colname="c2" colwidth="2*" />
       	        <thead>
	                <row>
           	            <entry>Property name</entry>
               	        <entry>Description</entry>
   	          			<entry>Cardinality</entry>
                        <entry>Default value</entry>
       	            </row>
				</thead>
				<tbody>
					<row>
           				<entry>definition</entry>
						<entry>
							The definition of the flow the session is an instance of.
						</entry>
					    <entry>
							<emphasis>1</emphasis>
						</entry>
					</row>
					<row>
   						<entry>state</entry>
						<entry>
							The current state of the session.
						</entry>
						<entry>
							<emphasis>1</emphasis>
						</entry>
					</row>
					<row>
   						<entry>status</entry>
						<entry>
							A status indicator describing what the session is currently doing.
						</entry>
						<entry>
							<emphasis>1</emphasis>
						</entry>
					</row>
					<row>
   						<entry>scope</entry>
						<entry>
							A data map that forms the basis for <emphasis>flow scope</emphasis>.
							Arbitrary attributes placed in this map will be retained for the scope 
							of the flow session.  This map is <emphasis>local</emphasis> to the session.
						</entry>
						<entry>
							<emphasis>1</emphasis>
						</entry>
					</row>
					<row>
   						<entry>flashMap</entry>
						<entry>
							A data map that forms the basis for <emphasis>flash scope</emphasis>.
							Attributes placed in this map will be retained until the next 
							external user event is signaled in the session.
						</entry>
						<entry>
							<emphasis>1</emphasis>
						</entry>
					</row>					
				</tbody>
			</tgroup>
		</table>
		<para>
			The following graphic illustrates an example flow execution context and flow 
			session stack:
		</para>
		<mediaobject>
			<imageobject role="fo">
				<imagedata fileref="images/flowexecution-sessionstack.png" format="PNG" align="center"/>
			</imageobject>
			<imageobject role="html">
				<imagedata fileref="images/flowexecution-sessionstack.png" format="PNG" align="center"/>
			</imageobject>
			<caption>
				<para>Flow execution context</para>
			</caption>
		</mediaobject>
		<para>
			In this illustration, a flow execution has been created for the <literal>Book Flight</literal> flow.
			The execution is currently active and the <literal>activeSession</literal> indicates it
			is in the <literal>Display Seating Chart</literal> state of the <literal>Assign Seats</literal> flow,
			which was spawned as a subflow from the <literal>Enter Seat Assignments</literal> state.		
		</para>
		<note>
			<para>
				Note how the active session status is <literal>paused</literal>, indicating the flow execution 
				is currently waiting for user input to be provided to continue.  In this case, it is
				expected the user will choose a seat for their flight.
			</para>
		</note>
    </sect1>
   	<sect1 id="execution-scopes">
		<title>Flow execution scopes</title>
		<para>
			As alluded to, a flow execution manages several containers called <emphasis>scopes</emphasis>,
			which allow arbitrary attributes to be stored for a period of time.  There are four scope 
			types, each with different storage management semantics:
		</para>
    	<table>
			<title>Flow execution scope types</title>
            <tgroup cols="2">
   	            <colspec colname="c1" colwidth="2*" />
                <colspec colname="c2" colwidth="4*" />
       	        <thead>
	                <row>
           	            <entry>Scope type name</entry>
               	        <entry>Management Semantics</entry>
       	            </row>
				</thead>
				<tbody>
					<row>
           				<entry>request</entry>
						<entry>
							Eligible for garbage collection when a single call into the flow execution completes.
						</entry>
					</row>
					<row>
   						<entry>flash</entry>
						<entry>
							Cleared when the next user event is signaled into the flow session; eligible for garbage collection when the flow session ends.
						</entry>
					</row>
					<row>
   						<entry>flow</entry>
						<entry>
							Eligible for garbage collection when the flow session ends.						
						</entry>
					</row>
					<row>
   						<entry>conversation</entry>
						<entry>
							Eligible for garbage collection when the root session of the governing flow execution (logical conversation) ends.					
						</entry>
					</row>
				</tbody>
			</tgroup>
		</table>
	</sect1>
	<sect1 id="execution-testing">
		<title>Flow execution testing</title>
		<para>
			Spring Web Flow provides support within the <literal>org.springframework.webflow.test</literal> 
			package for testing flow executions with JUnit.  This support is provided as convenience but is 
			entirely optional, as a flow execution is instantiable in any environment with the standard
			Java <literal>new</literal> operator.
		</para>
		<para>
			The general strategy for testing flows follows:
		</para>
		<para>
    		<orderedlist>
    			<listitem>
    				<para>
    					Your own implementations of definitional artifacts used by a flow such as actions, 
	    				attribute mappers, and exception handlers should be unit tested in isolation.
	    				Spring Web Flow ships convenient stubs to assist with this, for instance
	    				<literal>MockRequestContext</literal>.
    				</para>
    			</listitem>
    			<listitem>
    				<para>
    					The execution of a flow should be tested as part of a system integration test.
    					Such a test should exercise all possible paths of the flow, asserting that
    					the flow responds to events as expected.
    				</para>
    			</listitem>
    		</orderedlist>
    	</para>
    	<note>
    		<para>
	    		A flow execution integration test typically selects mock or stub implementations of application 
	    		services called by the flow, though it may also exercise production implementations.
   		 		Both are useful, supported system test configurations.
   		 	</para>
    	</note>
	    <sect2 id="execution-testing-example">
 	  	 	<title>Flow execution test example</title>
   	 		<para>
   	 			To help illustrate testing a flow execution, first consider the following flow definition
   	 			to search a phonebook for contacts:
   		 	</para>
			<mediaobject>
				<imageobject role="fo">
					<imagedata fileref="images/flow-search.png" format="PNG" align="center"/>
				</imageobject>
				<imageobject role="html">
					<imagedata fileref="images/flow-search.png" format="PNG" align="center"/>
				</imageobject>
				<caption>
					<para>Phonebook Search Flow - State Diagram</para>
				</caption>
			</mediaobject>
   	 		<para>
   	 			The corresponding XML-based flow definition implementation:
   		 	</para>					 	
   		 	<programlisting>
    &lt;?xml version="1.0" encoding="UTF-8"?&gt;
    &lt;flow xmlns="http://www.springframework.org/schema/webflow"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="
              http://www.springframework.org/schema/webflow
              http://www.springframework.org/schema/webflow/spring-webflow-2.0.xsd"&gt;
                             
        &lt;start-state idref="enterCriteria"/&gt;
    
        &lt;view-state id="enterCriteria" view="searchCriteria"&gt;
            &lt;render-actions&gt;
                &lt;action bean="formAction" method="setupForm"/&gt;
            &lt;/render-actions&gt;
            &lt;transition on="search" to="displayResults"&gt;
                &lt;action bean="formAction" method="bindAndValidate"/&gt;
            &lt;/transition&gt;
        &lt;/view-state&gt;
    
        &lt;view-state id="displayResults" view="searchResults"&gt;
            &lt;render-actions&gt;
                &lt;bean-action bean="phonebook" method="search"&gt;
                    &lt;method-arguments&gt;
                        &lt;argument expression="flowScope.searchCriteria"/&gt;
                    &lt;/method-arguments&gt;
                    &lt;method-result name="results"/&gt;
               &lt;/bean-action&gt;
            &lt;/render-actions&gt;
            &lt;transition on="newSearch" to="enterCriteria"/&gt;
            &lt;transition on="select" to="browseDetails"/&gt;
        &lt;/view-state&gt;
	    
        &lt;subflow-state id="browseDetails" flow="detail-flow"&gt;
            &lt;attribute-mapper&gt;
                &lt;input-mapper&gt;
                    &lt;mapping source="requestParameters.id" target="id" from="string" to="long"/&gt;
                &lt;/input-mapper&gt;
            &lt;/attribute-mapper&gt;
            &lt;transition on="finish" to="displayResults"/&gt;
        &lt;/subflow-state&gt;
    
    &lt;/flow>   		 	
   		 	</programlisting>
			<para>
				Above you see a flow with three (3) states that execute these behaviors, respectively:
			</para>
			<para>
	    		<orderedlist>
    				<listitem>
    					<para>
							The first state <literal>enterCriteria</literal> displays a search criteria form so the user can enter who
							he or she wishes to search for.    					
	    				</para>
	    			</listitem>
	    			<listitem>
    					<para>
							On form submit and successful data binding and validation, the search is executed.
					  		After search execution a results view is displayed.
	    				</para>
	    			</listitem>
	    			<listitem>
    					<para>
							From the results view, the user may select a result they wish to browse additional details on
							or they may request a new search.  On select, the "detail" flow is spawned and 
							when it finishes the search is re-executed and it's results redisplayed.
	    				</para>
	    			</listitem>
	    		</orderedlist>
	    	</para>
	    	<para>
				From this behavior narrative the following assertable test scenarios can be extracted:
	    	</para>
	    		<orderedlist>
    				<listitem>
    					<para>
							That when a flow execution starts, it enters the <literal>enterCriteria</literal> state and 
							makes a <literal>searchCriteria</literal> view selection containing a <emphasis>form object</emphasis>
							to be used as the basis for form field population.
	    				</para>
	    			</listitem>
	    			<listitem>
    					<para>
					  		That on submit with valid input, the search is executed and a <literal>searchResults</literal> view selection is made.
	    				</para>
	    			</listitem>
	    			<listitem>
    					<para>
							That on submit with invalid input, the <literal>searchCriteria</literal> view is reselected.
	    				</para>
	    			</listitem>
	    			<listitem>
    					<para>
							That on newSearch, the <literal>searchCriteria</literal> view is selected.
	    				</para>
	    			</listitem>
	    			<listitem>
    					<para>
							That on select, the <literal>detail</literal> flow is spawned and passed the <literal>id</literal> of the selected result as expected.
	    				</para>
	    			</listitem>
	    		</orderedlist>
	    	<para>
				To assist with writing these assertions, Spring Web Flow ships with JUnit-based flow execution 
				test support within the <literal>org.springframwork.webflow.test</literal> package.
				These base test classes are indicated below:
	    	</para>
	    	<table>
   				<title>Flow execution test support hierarchy</title>
	            <tgroup cols="2">
    	            <colspec colname="c1" colwidth="3*" />
	                <colspec colname="c2" colwidth="4*" />
        	        <thead>
		                <row>
            	            <entry>Class name</entry>
                	        <entry>Description</entry>
        	            </row>
   					</thead>
   					<tbody>
						<row>
             				<entry>AbstractFlowExecutionTests</entry>
							<entry>The most generic base class for flow execution tests.</entry>
						</row>
						<row>
             				<entry>AbstractExternalizedFlowExecutionTests</entry>
							<entry>The base class for flow execution tests whose flow is defined within an externalized resource, such as a file.</entry>
						</row>
						<row>
             				<entry>AbstractXmlFlowExecutionTests</entry>
							<entry>The base class for flow execution tests whose flow is defined within an externalized XML resource.</entry>
						</row>
					</tbody>
				</tgroup>
			</table>
		</sect2>
    </sect1>
</chapter>