Source Code Cross Referenced for FlowExecutorFactoryBean.java in  » Workflow-Engines » spring-webflow-1.0.4 » org » springframework » webflow » config » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Workflow Engines » spring webflow 1.0.4 » org.springframework.webflow.config 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Copyright 2004-2007 the original author or authors.
003:         *
004:         * Licensed under the Apache License, Version 2.0 (the "License");
005:         * you may not use this file except in compliance with the License.
006:         * You may obtain a copy of the License at
007:         *
008:         *      http://www.apache.org/licenses/LICENSE-2.0
009:         *
010:         * Unless required by applicable law or agreed to in writing, software
011:         * distributed under the License is distributed on an "AS IS" BASIS,
012:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013:         * See the License for the specific language governing permissions and
014:         * limitations under the License.
015:         */
016:        package org.springframework.webflow.config;
017:
018:        import java.util.Map;
019:
020:        import org.springframework.beans.factory.FactoryBean;
021:        import org.springframework.beans.factory.InitializingBean;
022:        import org.springframework.binding.mapping.AttributeMapper;
023:        import org.springframework.util.Assert;
024:        import org.springframework.webflow.context.ExternalContext;
025:        import org.springframework.webflow.conversation.ConversationManager;
026:        import org.springframework.webflow.conversation.impl.SessionBindingConversationManager;
027:        import org.springframework.webflow.core.collection.AttributeMap;
028:        import org.springframework.webflow.core.collection.LocalAttributeMap;
029:        import org.springframework.webflow.core.collection.MutableAttributeMap;
030:        import org.springframework.webflow.definition.registry.FlowDefinitionLocator;
031:        import org.springframework.webflow.definition.registry.FlowDefinitionRegistry;
032:        import org.springframework.webflow.engine.impl.FlowExecutionImplFactory;
033:        import org.springframework.webflow.engine.impl.FlowExecutionImplStateRestorer;
034:        import org.springframework.webflow.execution.FlowExecution;
035:        import org.springframework.webflow.execution.FlowExecutionFactory;
036:        import org.springframework.webflow.execution.FlowExecutionListener;
037:        import org.springframework.webflow.execution.factory.FlowExecutionListenerLoader;
038:        import org.springframework.webflow.execution.factory.StaticFlowExecutionListenerLoader;
039:        import org.springframework.webflow.execution.repository.FlowExecutionRepository;
040:        import org.springframework.webflow.execution.repository.continuation.ClientContinuationFlowExecutionRepository;
041:        import org.springframework.webflow.execution.repository.continuation.ContinuationFlowExecutionRepository;
042:        import org.springframework.webflow.execution.repository.support.FlowExecutionStateRestorer;
043:        import org.springframework.webflow.execution.repository.support.SimpleFlowExecutionRepository;
044:        import org.springframework.webflow.executor.FlowExecutor;
045:        import org.springframework.webflow.executor.FlowExecutorImpl;
046:
047:        /**
048:         * The default flow executor factory implementation. As a <code>FactoryBean</code>,
049:         * this class has been designed for use as a Spring managed bean.
050:         * <p>
051:         * This factory encapsulates the construction and assembly of a
052:         * {@link FlowExecutor}, including the provision of its
053:         * {@link FlowExecutionRepository} strategy.
054:         * <p>
055:         * The {@link #setDefinitionLocator(FlowDefinitionLocator) definition locator}
056:         * property is required, all other properties are optional.
057:         * <p>
058:         * This class has been designed with subclassing in mind. If you want to do advanced
059:         * Spring Web Flow customization, e.g. using a custom
060:         * {@link org.springframework.webflow.executor.FlowExecutor} implementation,
061:         * consider subclassing this class and overriding one or more of the provided
062:         * hook methods.
063:         * 
064:         * @author Keith Donald
065:         * @author Erwin Vervaet
066:         */
067:        public class FlowExecutorFactoryBean implements  FactoryBean,
068:                InitializingBean {
069:
070:            /**
071:             * The locator the executor will use to access flow definitions registered
072:             * in a central registry. Required.
073:             */
074:            private FlowDefinitionLocator definitionLocator;
075:
076:            /**
077:             * Execution attributes to apply.
078:             */
079:            private MutableAttributeMap executionAttributes;
080:
081:            /**
082:             * The loader that will determine which listeners to attach to flow definition executions. 
083:             */
084:            private FlowExecutionListenerLoader executionListenerLoader;
085:
086:            /**
087:             * The conversation manager to be used by the flow execution repository to
088:             * store state associated with conversations driven by Spring Web Flow.
089:             */
090:            private ConversationManager conversationManager;
091:
092:            /**
093:             * The maximum number of allowed concurrent conversations in the session.
094:             */
095:            private Integer maxConversations;
096:
097:            /**
098:             * The type of execution repository to configure with executors created by
099:             * this factory.  Optional.  Will fallback to default value if not set.
100:             */
101:            private RepositoryType repositoryType;
102:
103:            /**
104:             * The maximum number of allowed continuations for a single conversation.
105:             * Only used when the repository type is {@link RepositoryType#CONTINUATION}.
106:             */
107:            private Integer maxContinuations;
108:
109:            /**
110:             * A custom attribute mapper to use for mapping attributes of an
111:             * {@link ExternalContext} to a new {@link FlowExecution} during the
112:             * {@link FlowExecutor#launch(String, ExternalContext) launch flow} operation.
113:             */
114:            private AttributeMapper inputMapper;
115:
116:            /**
117:             * The flow executor this factory bean creates.
118:             */
119:            private FlowExecutor flowExecutor;
120:
121:            /**
122:             * Spring Web Flow executor system defaults. 
123:             */
124:            private FlowSystemDefaults defaults = new FlowSystemDefaults();
125:
126:            /**
127:             * Sets the flow definition locator that will locate flow definitions needed
128:             * for execution. Typically also a {@link FlowDefinitionRegistry}. Required.
129:             * @param definitionLocator the flow definition locator (registry)
130:             */
131:            public void setDefinitionLocator(
132:                    FlowDefinitionLocator definitionLocator) {
133:                this .definitionLocator = definitionLocator;
134:            }
135:
136:            /**
137:             * Sets the system attributes that apply to flow executions launched by the
138:             * executor created by this factory. Execution attributes may affect flow
139:             * execution behavior.
140:             * <p>
141:             * Note: this method simply accepts a generic <code>java.util.Map</code>
142:             * to allow for easy configuration by Spring. The map entries should consist
143:             * of non-null String keys with object values.
144:             * @param executionAttributes the flow execution system attributes
145:             */
146:            public void setExecutionAttributes(Map executionAttributes) {
147:                this .executionAttributes = new LocalAttributeMap(
148:                        executionAttributes);
149:            }
150:
151:            /**
152:             * Convenience setter that sets a single listener that always applies to flow
153:             * executions launched by the executor created by this factory.
154:             * @param executionListener the flow execution listener
155:             */
156:            public void setExecutionListener(
157:                    FlowExecutionListener executionListener) {
158:                setExecutionListeners(new FlowExecutionListener[] { executionListener });
159:            }
160:
161:            /**
162:             * Convenience setter that sets a list of listeners that always apply to
163:             * flow executions launched by the executor created by this factory.
164:             * @param executionListeners the flow execution listeners
165:             */
166:            public void setExecutionListeners(
167:                    FlowExecutionListener[] executionListeners) {
168:                setExecutionListenerLoader(new StaticFlowExecutionListenerLoader(
169:                        executionListeners));
170:            }
171:
172:            /**
173:             * Sets the strategy for loading the listeners that will observe executions
174:             * of a flow definition. Allows full control over what listeners should
175:             * apply to executions of a flow definition launched by the executor created
176:             * by this factory.
177:             */
178:            public void setExecutionListenerLoader(
179:                    FlowExecutionListenerLoader executionListenerLoader) {
180:                this .executionListenerLoader = executionListenerLoader;
181:            }
182:
183:            /**
184:             * Sets the type of flow execution repository that should be configured for
185:             * the flow executors created by this factory. This factory encapsulates the
186:             * construction of the repository implementation corresponding to the
187:             * provided type.
188:             * @param repositoryType the flow execution repository type
189:             */
190:            public void setRepositoryType(RepositoryType repositoryType) {
191:                this .repositoryType = repositoryType;
192:            }
193:
194:            /**
195:             * Set the maximum number of continuation snapshots allowed for a single
196:             * conversation when using the {@link RepositoryType#CONTINUATION continuation}
197:             * flow execution repository.
198:             * @see ContinuationFlowExecutionRepository#setMaxContinuations(int)
199:             * @since 1.0.1
200:             */
201:            public void setMaxContinuations(int maxContinuations) {
202:                this .maxContinuations = new Integer(maxContinuations);
203:            }
204:
205:            /**
206:             * Returns the configured maximum number of continuation snapshots allowed
207:             * for a single conversation when using the
208:             * {@link RepositoryType#CONTINUATION continuation} flow execution repository.
209:             * @return the configured value or null if the user did not explicitly
210:             * specify a value and wants to use the default
211:             * @since 1.0.1
212:             */
213:            protected Integer getMaxContinuations() {
214:                return maxContinuations;
215:            }
216:
217:            /**
218:             * Sets the strategy for managing conversations that should be configured
219:             * for flow executors created by this factory.
220:             * <p>
221:             * The conversation manager is used by the flow execution repository
222:             * subsystem to begin and end new conversations that store execution state.
223:             * <p>
224:             * By default, a {@link SessionBindingConversationManager} is used. Do not
225:             * use {@link #setMaxConversations(int)} when using this method.
226:             */
227:            public void setConversationManager(
228:                    ConversationManager conversationManager) {
229:                this .conversationManager = conversationManager;
230:            }
231:
232:            /**
233:             * Set the maximum number of allowed concurrent conversations in the session. This
234:             * is a convenience setter to allow easy configuration of the maxConversations
235:             * property of the default {@link SessionBindingConversationManager}. Do not use
236:             * this when using {@link #setConversationManager(ConversationManager)}.
237:             * @see SessionBindingConversationManager#setMaxConversations(int)
238:             * @since 1.0.1
239:             */
240:            public void setMaxConversations(int maxConversations) {
241:                this .maxConversations = new Integer(maxConversations);
242:            }
243:
244:            /**
245:             * Returns the configured maximum number of allowed concurrent conversations
246:             * in the session. Will only be used when using the default conversation manager,
247:             * e.g. when no explicit conversation manager has been configured using
248:             * {@link #setConversationManager(ConversationManager)}.
249:             * @return the configured value or null if the user did not explicitly 
250:             * specify a value and wants to use the default
251:             * @since 1.0.1
252:             */
253:            protected Integer getMaxConversations() {
254:                return maxConversations;
255:            }
256:
257:            /**
258:             * Set the service responsible for mapping attributes of an
259:             * {@link ExternalContext} to a new {@link FlowExecution} during the
260:             * {@link FlowExecutor#launch(String, ExternalContext) launch flow} operation.
261:             * <p>
262:             * This is optional. If not set, a default implementation will be used
263:             * that simply exposes all request parameters as flow execution input attributes.
264:             */
265:            public void setInputMapper(AttributeMapper inputMapper) {
266:                this .inputMapper = inputMapper;
267:            }
268:
269:            /**
270:             * Return the configured input mapper.
271:             */
272:            protected AttributeMapper getInputMapper() {
273:                return inputMapper;
274:            }
275:
276:            /**
277:             * Set system defaults that should be used.
278:             * @param defaults the defaults to use.
279:             */
280:            public void setDefaults(FlowSystemDefaults defaults) {
281:                this .defaults = defaults;
282:            }
283:
284:            // implementing InitializingBean
285:
286:            public void afterPropertiesSet() throws Exception {
287:                Assert.notNull(definitionLocator,
288:                        "The flow definition locator is required");
289:
290:                // apply defaults
291:                executionAttributes = defaults
292:                        .applyExecutionAttributes(executionAttributes);
293:                repositoryType = defaults.applyIfNecessary(repositoryType);
294:
295:                // pass all available parameters to the hook methods so that they
296:                // can participate in the construction process
297:
298:                // a factory for flow executions
299:                FlowExecutionFactory executionFactory = createFlowExecutionFactory(
300:                        executionAttributes, executionListenerLoader);
301:
302:                // a strategy to restore deserialized flow executions
303:                FlowExecutionStateRestorer executionStateRestorer = createFlowExecutionStateRestorer(
304:                        definitionLocator, executionAttributes,
305:                        executionListenerLoader);
306:
307:                // a repository to store flow executions
308:                FlowExecutionRepository executionRepository = createExecutionRepository(
309:                        repositoryType, executionStateRestorer,
310:                        conversationManager);
311:
312:                // combine all pieces of the puzzle to get an operational flow executor
313:                flowExecutor = createFlowExecutor(definitionLocator,
314:                        executionFactory, executionRepository);
315:            }
316:
317:            // subclassing hook methods
318:
319:            /**
320:             * Create the conversation manager to be used in the default case, e.g. when no
321:             * explicit conversation manager has been configured using
322:             * {@link #setConversationManager(ConversationManager)}. This implementation
323:             * return a {@link SessionBindingConversationManager}.
324:             * @return the default conversation manager
325:             */
326:            protected ConversationManager createDefaultConversationManager() {
327:                SessionBindingConversationManager conversationManager = new SessionBindingConversationManager();
328:                if (getMaxConversations() != null) {
329:                    conversationManager
330:                            .setMaxConversations(getMaxConversations()
331:                                    .intValue());
332:                }
333:                return conversationManager;
334:            }
335:
336:            /**
337:             * Create the flow execution factory to be used by the executor produced by this
338:             * factory bean. Configure the execution factory appropriately. Subclasses may
339:             * override if they which to use a custom execution factory, e.g. to use a custom
340:             * FlowExecution implementation.
341:             * @param executionAttributes execution attributes to apply to created executions
342:             * @param executionListenerLoader decides which listeners to apply to created executions
343:             * @return a new flow execution factory instance
344:             */
345:            protected FlowExecutionFactory createFlowExecutionFactory(
346:                    AttributeMap executionAttributes,
347:                    FlowExecutionListenerLoader executionListenerLoader) {
348:                FlowExecutionImplFactory executionFactory = new FlowExecutionImplFactory();
349:                executionFactory.setExecutionAttributes(executionAttributes);
350:                if (executionListenerLoader != null) {
351:                    executionFactory
352:                            .setExecutionListenerLoader(executionListenerLoader);
353:                }
354:                return executionFactory;
355:            }
356:
357:            /**
358:             * Create the flow execution state restorer to be used by the executor produced by
359:             * this factory bean. Configure the state restorer appropriately. Subclasses may
360:             * override if they which to use a custom state restorer implementation.
361:             * @param definitionLocator the definition locator to use
362:             * @param executionAttributes execution attributes to apply to restored executions
363:             * @param executionListenerLoader decides which listeners should apply to restored
364:             * flow executions
365:             * @return a new state restorer instance
366:             */
367:            protected FlowExecutionStateRestorer createFlowExecutionStateRestorer(
368:                    FlowDefinitionLocator definitionLocator,
369:                    AttributeMap executionAttributes,
370:                    FlowExecutionListenerLoader executionListenerLoader) {
371:                FlowExecutionImplStateRestorer executionStateRestorer = new FlowExecutionImplStateRestorer(
372:                        definitionLocator);
373:                executionStateRestorer
374:                        .setExecutionAttributes(executionAttributes);
375:                if (executionListenerLoader != null) {
376:                    executionStateRestorer
377:                            .setExecutionListenerLoader(executionListenerLoader);
378:                }
379:                return executionStateRestorer;
380:            }
381:
382:            /**
383:             * Factory method for creating the flow execution repository for saving and
384:             * loading executing flows. Subclasses may override to customize the
385:             * repository implementation used.
386:             * @param repositoryType a hint indicating what type of repository to create
387:             * @param executionStateRestorer the execution state restorer strategy to be used by
388:             * the repository
389:             * @param conversationManager the conversation manager specified by the user,
390:             * could be null in which case the default conversation manager should be used
391:             * @return a new flow execution repository instance
392:             */
393:            protected FlowExecutionRepository createExecutionRepository(
394:                    RepositoryType repositoryType,
395:                    FlowExecutionStateRestorer executionStateRestorer,
396:                    ConversationManager conversationManager) {
397:                if (repositoryType == RepositoryType.CLIENT) {
398:                    if (conversationManager == null) {
399:                        // use the default no-op conversation manager
400:                        return new ClientContinuationFlowExecutionRepository(
401:                                executionStateRestorer);
402:                    } else {
403:                        // use the conversation manager specified by the user
404:                        return new ClientContinuationFlowExecutionRepository(
405:                                executionStateRestorer, conversationManager);
406:                    }
407:                } else {
408:                    // determine the conversation manager to use
409:                    ConversationManager conversationManagerToUse = conversationManager;
410:                    if (conversationManagerToUse == null) {
411:                        conversationManagerToUse = createDefaultConversationManager();
412:                    }
413:
414:                    if (repositoryType == RepositoryType.SIMPLE) {
415:                        return new SimpleFlowExecutionRepository(
416:                                executionStateRestorer,
417:                                conversationManagerToUse);
418:                    } else if (repositoryType == RepositoryType.CONTINUATION) {
419:                        ContinuationFlowExecutionRepository repository = new ContinuationFlowExecutionRepository(
420:                                executionStateRestorer,
421:                                conversationManagerToUse);
422:                        if (getMaxContinuations() != null) {
423:                            repository
424:                                    .setMaxContinuations(getMaxContinuations()
425:                                            .intValue());
426:                        }
427:                        return repository;
428:                    } else if (repositoryType == RepositoryType.SINGLEKEY) {
429:                        SimpleFlowExecutionRepository repository = new SimpleFlowExecutionRepository(
430:                                executionStateRestorer,
431:                                conversationManagerToUse);
432:                        repository.setAlwaysGenerateNewNextKey(false);
433:                        return repository;
434:                    } else {
435:                        throw new IllegalStateException(
436:                                "Cannot create execution repository - unsupported repository type "
437:                                        + repositoryType);
438:                    }
439:                }
440:            }
441:
442:            /**
443:             * Create the flow executor instance created by this factory bean and configure
444:             * it appropriately. Subclasses may override if they which to use a custom executor
445:             * implementation.
446:             * @param definitionLocator the definition locator to use
447:             * @param executionFactory the execution factory to use
448:             * @param executionRepository the execution repository to use
449:             * @return a new flow executor instance
450:             */
451:            protected FlowExecutor createFlowExecutor(
452:                    FlowDefinitionLocator definitionLocator,
453:                    FlowExecutionFactory executionFactory,
454:                    FlowExecutionRepository executionRepository) {
455:                FlowExecutorImpl flowExecutor = new FlowExecutorImpl(
456:                        definitionLocator, executionFactory,
457:                        executionRepository);
458:                if (getInputMapper() != null) {
459:                    flowExecutor.setInputMapper(inputMapper);
460:                }
461:                return flowExecutor;
462:            }
463:
464:            // implementing FactoryBean
465:
466:            public Class getObjectType() {
467:                return FlowExecutor.class;
468:            }
469:
470:            public boolean isSingleton() {
471:                return true;
472:            }
473:
474:            public Object getObject() throws Exception {
475:                return getFlowExecutor();
476:            }
477:
478:            /**
479:             * Returns the flow executor constructed by the factory bean.
480:             * @since 1.0.2
481:             */
482:            public FlowExecutor getFlowExecutor() {
483:                return flowExecutor;
484:            }
485:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.