KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > springframework > webflow > test > execution > AbstractExternalizedFlowExecutionTests


1 /*
2  * Copyright 2002-2006 the original author or authors.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.springframework.webflow.test.execution;
17
18 import java.io.File JavaDoc;
19
20 import org.springframework.core.io.FileSystemResource;
21 import org.springframework.core.io.Resource;
22 import org.springframework.webflow.core.collection.AttributeMap;
23 import org.springframework.webflow.definition.FlowDefinition;
24 import org.springframework.webflow.definition.registry.FlowDefinitionResource;
25 import org.springframework.webflow.engine.Flow;
26 import org.springframework.webflow.engine.builder.FlowAssembler;
27 import org.springframework.webflow.engine.builder.FlowBuilder;
28 import org.springframework.webflow.engine.builder.FlowServiceLocator;
29 import org.springframework.webflow.engine.impl.FlowExecutionImplFactory;
30 import org.springframework.webflow.execution.FlowExecutionListener;
31 import org.springframework.webflow.execution.factory.StaticFlowExecutionListenerLoader;
32 import org.springframework.webflow.test.MockFlowServiceLocator;
33
34 /**
35  * Base class for flow integration tests that verify an externalized flow
36  * definition executes as expected. Supports caching of the flow definition
37  * built from an externalized resource to speed up test execution.
38  *
39  * @author Keith Donald
40  */

41 public abstract class AbstractExternalizedFlowExecutionTests extends AbstractFlowExecutionTests {
42
43     /**
44      * The cached flow definition.
45      */

46     private static FlowDefinition cachedFlowDefinition;
47
48     /**
49      * The flag indicating if the flow definition built from an externalized
50      * resource as part of this test should be cached.
51      */

52     private boolean cacheFlowDefinition = false;
53     
54     /**
55      * Internal helper that return the flow execution factory used by the
56      * test cast to a {@link FlowExecutionImplFactory}.
57      */

58     private FlowExecutionImplFactory getFlowExecutionImplFactory() {
59         return (FlowExecutionImplFactory)getFlowExecutionFactory();
60     }
61     
62     /**
63      * Returns if flow definition caching is turned on.
64      */

65     protected boolean isCacheFlowDefinition() {
66         return cacheFlowDefinition;
67     }
68
69     /**
70      * Sets the flag indicating if the flow definition built from an
71      * externalized resource as part of this test should be cached.
72      * Default is false.
73      */

74     protected void setCacheFlowDefinition(boolean cacheFlowDefinition) {
75         this.cacheFlowDefinition = cacheFlowDefinition;
76     }
77
78     /**
79      * Sets system attributes to be associated with the flow execution the next
80      * time one is {@link #startFlow() started} by this test. Useful for
81      * assigning attributes that influence flow execution behavior.
82      * @param executionAttributes the system attributes to assign
83      */

84     protected void setFlowExecutionAttributes(AttributeMap executionAttributes) {
85         getFlowExecutionImplFactory().setExecutionAttributes(executionAttributes);
86     }
87
88     /**
89      * Set the listener to be attached to the flow execution the next time one
90      * is {@link #startFlow() started} by this test. Useful for attaching a
91      * listener that does test assertions during the execution of the flow.
92      * @param executionListener the listener to attach
93      */

94     protected void setFlowExecutionListener(FlowExecutionListener executionListener) {
95         getFlowExecutionImplFactory().setExecutionListenerLoader(
96                 new StaticFlowExecutionListenerLoader(executionListener));
97     }
98
99     protected final FlowDefinition getFlowDefinition() {
100         if (isCacheFlowDefinition() && cachedFlowDefinition != null) {
101             return cachedFlowDefinition;
102         }
103         FlowServiceLocator flowServiceLocator = createFlowServiceLocator();
104         Flow flow = createFlow(getFlowDefinitionResource(), flowServiceLocator);
105         if (isCacheFlowDefinition()) {
106             cachedFlowDefinition = flow;
107         }
108         return flow;
109     }
110
111     /**
112      * Returns the flow artifact factory to use during flow definition
113      * construction time for accessing externally managed flow artifacts such as
114      * actions and flows to be used as subflows.
115      * <p>
116      * This implementation just creates a {@link MockFlowServiceLocator} and
117      * populates it with services by calling {@link #registerMockServices(MockFlowServiceLocator)}.
118      * @return the flow artifact factory
119      */

120     protected FlowServiceLocator createFlowServiceLocator() {
121         MockFlowServiceLocator serviceLocator = new MockFlowServiceLocator();
122         registerMockServices(serviceLocator);
123         return serviceLocator;
124     }
125
126     /**
127      * Template method called by {@link #createFlowServiceLocator()} to allow
128      * registration of mock implementations of services needed to test the flow
129      * execution. Useful when testing flow definitions in execution in isolation
130      * from flows and middle-tier services. Subclasses may override.
131      * @param serviceRegistry the mock service registry (and locator)
132      */

133     protected void registerMockServices(MockFlowServiceLocator serviceRegistry) {
134     }
135
136     /**
137      * Factory method to assemble another flow definition from a resource.
138      * Called by {@link #getFlowDefinition()} to create the "main" flow to test.
139      * May also be called by subclasses to create subflow definitions whose
140      * executions should also be exercised by this test.
141      * @param resource the flow definition resource
142      * @return the built flow definition, ready for execution
143      * @see #createFlowBuilder(Resource, FlowServiceLocator)
144      */

145     protected final Flow createFlow(FlowDefinitionResource resource, FlowServiceLocator serviceLocator) {
146         FlowBuilder builder = createFlowBuilder(resource.getLocation(), serviceLocator);
147         FlowAssembler assembler = new FlowAssembler(resource.getId(), resource.getAttributes(), builder);
148         return assembler.assembleFlow();
149     }
150
151     /**
152      * Returns the pointer to the resource that houses the definition of the
153      * flow to be tested. Subclasses must implement.
154      * <p>
155      * Example usage:
156      * <pre class="code">
157      * protected FlowDefinitionResource getFlowDefinitionResource() {
158      * return createFlowDefinitionResource(&quot;/WEB-INF/flows/order-flow.xml&quot;);
159      * }
160      * </pre>
161      * @return the flow definition resource
162      */

163     protected abstract FlowDefinitionResource getFlowDefinitionResource();
164
165     /**
166      * Factory method to create the builder that will build the flow whose
167      * execution will be tested. Subclasses must override.
168      * @param resource the externalized flow definition resource location
169      * @param serviceLocator the flow service locator
170      * @return the flow builder that will build the flow to be tested
171      */

172     protected abstract FlowBuilder createFlowBuilder(Resource resource, FlowServiceLocator serviceLocator);
173
174     /**
175      * Convenient factory method that creates a {@link FlowDefinitionResource}
176      * from a file path. Typically called by subclasses overriding
177      * {@link #getFlowDefinitionResource()}.
178      * @param filePath the full path to the externalized flow definition file
179      * @return the flow definition resource
180      */

181     protected final FlowDefinitionResource createFlowDefinitionResource(String JavaDoc filePath) {
182         return createFlowDefinitionResource(new File JavaDoc(filePath));
183     }
184
185     /**
186      * Convenient factory method that creates a {@link FlowDefinitionResource}
187      * from a file in a directory. Typically called by subclasses overriding
188      * {@link #getFlowDefinitionResource()}.
189      * @param fileDirectory the directory containing the file
190      * @param fileName the short file name
191      * @return the flow definition resource pointing to the file
192      */

193     protected final FlowDefinitionResource createFlowDefinitionResource(String JavaDoc fileDirectory, String JavaDoc fileName) {
194         return createFlowDefinitionResource(new File JavaDoc(fileDirectory, fileName));
195     }
196
197     /**
198      * Convenient factory method that creates a {@link FlowDefinitionResource}
199      * from a file.
200      * @param file the file
201      * @return the flow definition resource
202      */

203     protected FlowDefinitionResource createFlowDefinitionResource(File JavaDoc file) {
204         return new FlowDefinitionResource(new FileSystemResource(file));
205     }
206 }
Popular Tags