<?xml version="1.0" encoding="UTF-8"?>
<chapter id="flow-executor">
	<title>Flow executors</title>
	<sect1 id="executor-intro">
		<title>Introduction</title>
		<para>
			Flow executors are the highest-level entry points into
			the Spring Web Flow system, responsible for driving the execution of flows
			across a variety of environments.
		</para>
		<para>
			In this chapter, you will learn how to execute flows within Spring MVC, Struts, 
			and Java Server Faces (JSF) based applications.
		</para>
    </sect1>
    <sect1 id="executor">
    	<title>FlowExecutor</title>
    	<para>
    		<literal>org.springframework.webflow.executor.FlowExecutor</literal> is the 
    		central facade interface external systems use to drive the execution of flows.
    		This facade acts as a simple, convenient service entry-point into
    		the Spring Web Flow system that is reusable across environments.
    	</para>
    	<para>
    		The <literal>FlowExecutor</literal> interface is shown below:
    	</para>
    	<programlisting>
    public interface FlowExecutor {
        public void executeFlowRequest(ExternalContext context);
    }    	
    	</programlisting>
    	<para>
    		Execution typically consists of either:
    		<orderedlist>
    			<listitem>
    				<para>
    					Launching (start) a new execution of a flow definition.
    				</para>
    			</listitem>
    			<listitem>
    				<para>
    					Resuming a paused flow execution by signaling an event against its current state.
    				</para>
    			</listitem>
    		</orderedlist>
    	</para>
    	<para>
    		The ExternalContext provides normalized access to properties of an external system that has called into Spring Web Flow.
    		This context allows access to environment-specific request parameters as well as 
    		externally-managed request, session, and application-level attributes.
    	</para>
		<para>
			<literal>ExternalContext</literal> implementations exist for each of
			the environments Spring Web Flow supports.  If a flow artifact such as an Action needs
			to access native constructs of the calling environment it can downcast a context to its
			specific implementation.  The need for such downcasting is considered a corner case.
		</para>
    	<sect2 id="flowexecutor-impl">
    		<title>FlowExecutorImpl</title>
	    	<para>
    			The default executor implementation is <literal>org.springframework.webflow.executor.FlowExecutorImpl</literal>.
    			It allows for configuration of a <literal>FlowDefinitionLocator</literal> responsible for loading the flow definitions to execute, as well as
    			the <literal>FlowExecutionRepository</literal> strategy responsible for persisting flow executions that remain 
    			active beyond a single request into the server.
    		</para>
    		<para>
    			The configurable <literal>FlowExecutorImpl</literal> properties are shown below:
    		</para>
		    <table>
   				<title>FlowExecutorImpl properties</title>
	   	   		<tgroup cols="3">
    				<colspec colname="c1" colwidth="2*" />
	   	        	<colspec colname="c2" colwidth="4*" />
	            	<colspec colname="c3" colwidth="2*" />
        	    	<thead>
		        		<row>
         		   	    	<entry>Property name</entry>
                			<entry>Description</entry>
    	          			<entry>Cardinality</entry>
        	        	</row>
   					</thead>
   					<tbody>
						<row>
           					<entry>definitionLocator</entry>
							<entry>The service for loading flow definitions to be executed, typically a <literal>FlowDefinitionRegistry</literal></entry>
					    	<entry>
								<emphasis>1</emphasis>
							</entry>
						</row>
						<row>
           					<entry>executionFactory</entry>
							<entry>The factory for creating new flow executions.</entry>
					    	<entry>
								<emphasis>1</emphasis>
							</entry>
						</row>
 						<row>
     						<entry>executionRepository</entry>
							<entry>The repository for saving and loading persistent (paused) flow executions</entry>
							<entry> 
								<emphasis>1</emphasis>
							</entry>
						</row>
					</tbody>
				</tgroup>
			</table>
		</sect2>
    	<sect2 id="executor-simple">
    		<title>A typical flow executor configuration with Spring 2.0</title>
	    	<programlisting>
    &lt;?xml version="1.0" encoding="UTF-8"?&gt;	    	
    &lt;beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:web="http://www.springframework.org/schema/webflow-config"
           xsi:schemaLocation="
               http://www.springframework.org/schema/beans
               http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
               http://www.springframework.org/schema/webflow-config
               http://www.springframework.org/schema/webflow-config/spring-webflow-config-2.0.xsd"&gt;
           	    	
        &lt;!-- Launches new flow executions and resumes existing executions. --&gt;
        &lt;web:flow-executor id="flowExecutor" registry-ref="flowRegistry"/>

        &lt;!-- Creates the registry of flow definitions for this application --&gt;
        &lt;web:flow-registry id="flowRegistry"&gt;
            &lt;web:flow-location path="/WEB-INF/flows/**/*-flow.xml"/&gt;
        &lt;/web:flow-registry&gt;
        
    &lt;/beans&gt;
	        </programlisting>
	    	<para>
	    		This instructs Spring to create a flow executor that can execute all XML-based flow definitions 
    			contained within the <literal>/WEB-INF/flows</literal> directory. The default flow execution 
    			repository, <literal>continuation</literal>, is used.
    		</para>
    	</sect2>
    	<sect2 id="executor-custom-repo">
    		<title>A flow executor using a simple execution repository</title>
	    	<programlisting>
    &lt;web:flow-executor id="flowExecutor" registry-ref="flowRegistry" repository-type="simple"/&gt;
	    	</programlisting>
	    	<para>
	    		This executor is configured with a simple repository that manages
	    		execution state in the user session.
	    	</para>	
    	</sect2>
    	<sect2 id="executor-custom-repo2">
    		<title>A flow executor using a client-side continuation-based execution repository</title>
	    	<programlisting>
    &lt;web:flow-executor id="flowExecutor" registry-ref="flowRegistry" repository-type="client"/&gt;
	    	</programlisting>
	    	<para>
	    		This executor is configured with a continuation-based repository that serializes
    			continuation state to the client using no server-side state.
	    	</para>	
    	</sect2>		
    	<sect2 id="executor-custom-repo3">
    		<title>A flow executor using a single key execution repository</title>
	    	<programlisting>
    &lt;web:flow-executor id="flowExecutor" registry-ref="flowRegistry" repository-type="singleKey"/>&gt;
	    	</programlisting>
	    	<para>
	    		This executor is configured with a simple repository that assigns a single 
	    		flow execution key per conversation.  The key, once assigned, never changes
	    		for the duration of the conversation.
	    	</para>	
    	</sect2>
    	<sect2 id="executor-custom-repo4">
    		<title>A flow executor setting custom conversation management attributes</title>
	    	<programlisting>
    &lt;web:flow-executor id="flowExecutor" registry-ref="flowRegistry">
        &lt;web:flow-repository type="continuation" max-conversations="5" max-continuations="30" conversation-manager-ref="conversationManager"/&gt;
    &lt;/web:flow-executor&gt;

    &lt;bean id="conversationManager" class="example.MyCustomConversationalStateManager"/&gt;
	    	</programlisting>
	    	<para>
	    		This executor is configured with a continuation repository configured with custom settings for:
	 			<orderedlist>
					<listitem><para>The maximum number of active conversations per user session (5)</para></listitem>
					<listitem><para>The maximum number of restorable flow execution snapshots (continuations) per conversation (30)</para></listitem>
					<listitem><para>Where conversational state will be stored (via a custom conversationManager)</para></listitem>
				</orderedlist>
				The <literal>flow:repository</literal> child element is the more flexible form for configuring the flow execution repository.
				Use it or the convenient <literal>repository-type</literal> attribute, not both.
	    	</para>	
    	</sect2>
    	<sect2 id="executor-excution-attributes">
    		<title>A flow executor setting system execution attributes</title>
			<programlisting>
    &lt;web:flow-executor id="flowExecutor" registry-ref="flowRegistry" repository-type="continuation"&gt;
        &lt;web:flow-execution-attributes&gt;
            &lt;web:alwaysRedirectOnPause value="false"/&gt;
            &lt;web:attribute name="foo" value="bar"/&gt;
        &lt;/flow:execution-attributes&gt;
    &lt;/web:flow-executor&gt;
			</programlisting>
	    	<para>
	    		This executor is configured to set two flow execution system attributes
	    		<literal>alwaysRedirectOnPause=false</literal> and <literal>foo=bar</literal>.
	    	</para>
	    	<para>
	    		<note>
	    			<para>
			    		The <literal>alwaysRedirectOnPause</literal> attribute determines if 
			    		a flow execution redirect occurs automatically each time an execution pauses
			    		(automated <literal>POST+REDIRECT+GET</literal> behavior).
			    		Setting this attribute to false will disable the <emphasis>default 'true' behavior</emphasis>.
			    	</para>
	    		</note>
	    	</para>
		</sect2>
    	<sect2 id="executor-excution-listeners">
    		<title>A flow executor setting custom execution listeners</title>
			<programlisting>
    &lt;web:flow-executor id="flowExecutor" registry-ref="flowRegistry" repository-type="continuation"&gt;
        &lt;web:flow-execution-listeners&gt;
            &lt;web:flow-listener ref="listener" criteria="order-flow"/&gt;
        &lt;/web:flow-execution-listeners&gt;
    &lt;/web:flow-executor&gt;

    &lt;!-- A FlowExecutionListener to observe the lifecycle of order-flow executions --&gt;
    &lt;bean id="listener" class="example.OrderFlowExecutionListener"/&gt;
			</programlisting>
	    	<para>
	    		This executor is configured to apply the execution listener to the "order-flow".
	    	</para>	
		</sect2>    	
	</sect1>
</chapter>