Source Code Cross Referenced for AbstractFlowBuilder.java in  » Workflow-Engines » spring-webflow-1.0.4 » org » springframework » webflow » engine » builder » 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.engine.builder 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Copyright 2004-2007 the original author or authors.
0003:         *
0004:         * Licensed under the Apache License, Version 2.0 (the "License");
0005:         * you may not use this file except in compliance with the License.
0006:         * You may obtain a copy of the License at
0007:         *
0008:         *      http://www.apache.org/licenses/LICENSE-2.0
0009:         *
0010:         * Unless required by applicable law or agreed to in writing, software
0011:         * distributed under the License is distributed on an "AS IS" BASIS,
0012:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0013:         * See the License for the specific language governing permissions and
0014:         * limitations under the License.
0015:         */
0016:        package org.springframework.webflow.engine.builder;
0017:
0018:        import org.springframework.binding.expression.Expression;
0019:        import org.springframework.binding.expression.SettableExpression;
0020:        import org.springframework.binding.mapping.AttributeMapper;
0021:        import org.springframework.binding.mapping.Mapping;
0022:        import org.springframework.binding.mapping.MappingBuilder;
0023:        import org.springframework.binding.method.MethodSignature;
0024:        import org.springframework.core.style.ToStringCreator;
0025:        import org.springframework.webflow.action.AbstractBeanInvokingAction;
0026:        import org.springframework.webflow.action.ActionResultExposer;
0027:        import org.springframework.webflow.action.BeanInvokingActionFactory;
0028:        import org.springframework.webflow.action.EvaluateAction;
0029:        import org.springframework.webflow.action.MultiAction;
0030:        import org.springframework.webflow.core.collection.AttributeMap;
0031:        import org.springframework.webflow.core.collection.CollectionUtils;
0032:        import org.springframework.webflow.engine.AnnotatedAction;
0033:        import org.springframework.webflow.engine.Flow;
0034:        import org.springframework.webflow.engine.FlowAttributeMapper;
0035:        import org.springframework.webflow.engine.FlowExecutionExceptionHandler;
0036:        import org.springframework.webflow.engine.State;
0037:        import org.springframework.webflow.engine.TargetStateResolver;
0038:        import org.springframework.webflow.engine.Transition;
0039:        import org.springframework.webflow.engine.TransitionCriteria;
0040:        import org.springframework.webflow.engine.ViewSelector;
0041:        import org.springframework.webflow.engine.support.ActionTransitionCriteria;
0042:        import org.springframework.webflow.execution.Action;
0043:        import org.springframework.webflow.execution.ScopeType;
0044:        import org.springframework.webflow.execution.support.EventFactorySupport;
0045:
0046:        /**
0047:         * Base class for flow builders that programmatically build flows in Java
0048:         * configuration code.
0049:         * <p>
0050:         * To give you an example of what a simple Java-based web flow builder
0051:         * definition might look like, the following example defines the 'dynamic' web
0052:         * flow roughly equivalent to the work flow statically implemented in Spring
0053:         * MVC's simple form controller:
0054:         * 
0055:         * <pre class="code">
0056:         * public class CustomerDetailFlowBuilder extends AbstractFlowBuilder {
0057:         * 	public void buildStates() {
0058:         * 		// get customer information
0059:         * 		addActionState(&quot;getDetails&quot;, action(&quot;customerAction&quot;), transition(on(success()), to(&quot;displayDetails&quot;)));
0060:         * 
0061:         * 		// view customer information               
0062:         * 		addViewState(&quot;displayDetails&quot;, &quot;customerDetails&quot;, transition(on(submit()), to(&quot;bindAndValidate&quot;)));
0063:         * 
0064:         * 		// bind and validate customer information updates 
0065:         * 		addActionState(&quot;bindAndValidate&quot;, action(&quot;customerAction&quot;), new Transition[] {
0066:         * 				transition(on(error()), to(&quot;displayDetails&quot;)), transition(on(success()), to(&quot;finish&quot;)) });
0067:         * 
0068:         * 		// finish
0069:         * 		addEndState(&quot;finish&quot;);
0070:         * 	}
0071:         * }
0072:         * </pre>
0073:         * 
0074:         * What this Java-based FlowBuilder implementation does is add four states to a
0075:         * flow. These include a "get" <code>ActionState</code> (the start state), a
0076:         * <code>ViewState</code> state, a "bind and validate"
0077:         * <code>ActionState</code>, and an end marker state (<code>EndState</code>).
0078:         * <p>
0079:         * The first state, an action state, will be assigned the indentifier
0080:         * <code>getDetails</code>. This action state will automatically be
0081:         * configured with the following defaults:
0082:         * <ol>
0083:         * <li>The action instance with id <code>customerAction</code>. This is the
0084:         * <code>Action</code> implementation that will execute when this state is
0085:         * entered. In this example, that <code>Action</code> will go out to the DB,
0086:         * load the Customer, and put it in the Flow's request context.
0087:         * <li>A <code>success</code> transition to a default view state, called
0088:         * <code>displayDetails</code>. This means when the <code>Action</code>
0089:         * returns a <code>success</code> result event (aka outcome), the
0090:         * <code>displayDetails</code> state will be entered.
0091:         * <li>It will act as the start state for this flow (by default, the first
0092:         * state added to a flow during the build process is treated as the start
0093:         * state).
0094:         * </ol>
0095:         * <p>
0096:         * The second state, a view state, will be identified as
0097:         * <code>displayDetails</code>. This view state will automatically be
0098:         * configured with the following defaults:
0099:         * <ol>
0100:         * <li>A view name called <code>customerDetails</code>. This is the logical
0101:         * name of a view resource. This logical view name gets mapped to a physical
0102:         * view resource (jsp, etc.) by the calling front controller (via a Spring view
0103:         * resolver, or a Struts action forward, for example).
0104:         * <li>A <code>submit</code> transition to a bind and validate action state,
0105:         * indentified by the default id <code>bindAndValidate</code>. This means
0106:         * when a <code>submit</code> event is signaled by the view (for example, on a
0107:         * submit button click), the bindAndValidate action state will be entered and
0108:         * the <code>bindAndValidate</code> method of the
0109:         * <code>customerAction</code> <code>Action</code> implementation will be
0110:         * executed.
0111:         * </ol>
0112:         * <p>
0113:         * The third state, an action state, will be indentified as
0114:         * <code>bindAndValidate</code>. This action state will automatically be
0115:         * configured with the following defaults:
0116:         * <ol>
0117:         * <li>An action bean named <code>customerAction</code> -- this is the name
0118:         * of the <code>Action</code> implementation exported in the application
0119:         * context that will execute when this state is entered. In this example, the
0120:         * <code>Action</code> has a "bindAndValidate" method that will bind form
0121:         * input in the HTTP request to a backing Customer form object, validate it, and
0122:         * update the DB.
0123:         * <li>A <code>success</code> transition to a default end state, called
0124:         * <code>finish</code>. This means if the <code>Action</code> returns a
0125:         * <code>success</code> result, the <code>finish</code> end state will be
0126:         * transitioned to and the flow will terminate.
0127:         * <li>An <code>error</code> transition back to the form view. This means if
0128:         * the <code>Action</code> returns an <code>error</code> event, the <code>
0129:         * displayDetails</code> view state will be transitioned back to.
0130:         * </ol>
0131:         * <p>
0132:         * The fourth and last state, an end state, will be indentified with the default
0133:         * end state id <code>finish</code>. This end state is a marker that signals
0134:         * the end of the flow. When entered, the flow session terminates, and if this
0135:         * flow is acting as a root flow in the current flow execution, any
0136:         * flow-allocated resources will be cleaned up. An end state can optionally be
0137:         * configured with a logical view name to forward to when entered. It will also
0138:         * trigger a state transition in a resuming parent flow if this flow was
0139:         * participating as a spawned 'subflow' within a suspended parent flow.
0140:         * 
0141:         * @author Keith Donald
0142:         * @author Erwin Vervaet
0143:         */
0144:        public abstract class AbstractFlowBuilder extends BaseFlowBuilder {
0145:
0146:            /**
0147:             * A helper for creating commonly used event identifiers that drive
0148:             * transitions created by this builder.
0149:             */
0150:            private EventFactorySupport eventFactorySupport = new EventFactorySupport();
0151:
0152:            /**
0153:             * Default constructor for subclassing.
0154:             */
0155:            protected AbstractFlowBuilder() {
0156:                super ();
0157:            }
0158:
0159:            /**
0160:             * Create an instance of an abstract flow builder, using the specified
0161:             * locator to obtain needed flow services at build time.
0162:             * @param flowServiceLocator the locator for services needed by this builder
0163:             * to build its Flow
0164:             */
0165:            protected AbstractFlowBuilder(FlowServiceLocator flowServiceLocator) {
0166:                super (flowServiceLocator);
0167:            }
0168:
0169:            /**
0170:             * Returns the configured event factory support helper for creating commonly
0171:             * used event identifiers that drive transitions created by this builder.
0172:             */
0173:            public EventFactorySupport getEventFactorySupport() {
0174:                return eventFactorySupport;
0175:            }
0176:
0177:            /**
0178:             * Sets the event factory support helper to use to create commonly used
0179:             * event identifiers that drive transitions created by this builder.
0180:             */
0181:            public void setEventFactorySupport(
0182:                    EventFactorySupport eventFactorySupport) {
0183:                this .eventFactorySupport = eventFactorySupport;
0184:            }
0185:
0186:            public void init(String flowId, AttributeMap attributes)
0187:                    throws FlowBuilderException {
0188:                setFlow(getFlowArtifactFactory().createFlow(flowId,
0189:                        flowAttributes().union(attributes)));
0190:                initBuilder();
0191:            }
0192:
0193:            /**
0194:             * Hook subclasses may override to provide additional properties for the
0195:             * flow built by this builder. Returns a empty collection by default.
0196:             * @return additional properties describing the flow being built, should not
0197:             * return null
0198:             */
0199:            protected AttributeMap flowAttributes() {
0200:                return CollectionUtils.EMPTY_ATTRIBUTE_MAP;
0201:            }
0202:
0203:            /**
0204:             * Hook method subclasses can override to initialize the flow builder.
0205:             * Will be called by {@link #init(String, AttributeMap)} after
0206:             * creating the initial Flow object. As a consequence, {@link #getFlow()}
0207:             * can be called to retrieve the Flow object under construction.
0208:             */
0209:            protected void initBuilder() {
0210:            }
0211:
0212:            // view state
0213:
0214:            /**
0215:             * Adds a view state to the flow built by this builder.
0216:             * @param stateId the state identifier
0217:             * @param viewName the string-encoded view selector
0218:             * @param transition the sole transition (path) out of this state
0219:             * @return the fully constructed view state instance
0220:             */
0221:            protected State addViewState(String stateId, String viewName,
0222:                    Transition transition) {
0223:                return getFlowArtifactFactory().createViewState(stateId,
0224:                        getFlow(), null, viewSelector(viewName), null,
0225:                        new Transition[] { transition }, null, null, null);
0226:            }
0227:
0228:            /**
0229:             * Adds a view state to the flow built by this builder.
0230:             * @param stateId the state identifier
0231:             * @param viewName the string-encoded view selector
0232:             * @param transitions the transitions (paths) out of this state
0233:             * @return the fully constructed view state instance
0234:             */
0235:            protected State addViewState(String stateId, String viewName,
0236:                    Transition[] transitions) {
0237:                return getFlowArtifactFactory().createViewState(stateId,
0238:                        getFlow(), null, viewSelector(viewName), null,
0239:                        transitions, null, null, null);
0240:            }
0241:
0242:            /**
0243:             * Adds a view state to the flow built by this builder.
0244:             * @param stateId the state identifier
0245:             * @param viewName the string-encoded view selector
0246:             * @param renderAction the action to execute on state entry and refresh; may
0247:             * be null
0248:             * @param transition the sole transition (path) out of this state
0249:             * @return the fully constructed view state instance
0250:             */
0251:            protected State addViewState(String stateId, String viewName,
0252:                    Action renderAction, Transition transition) {
0253:                return getFlowArtifactFactory().createViewState(stateId,
0254:                        getFlow(), null, viewSelector(viewName),
0255:                        new Action[] { renderAction },
0256:                        new Transition[] { transition }, null, null, null);
0257:            }
0258:
0259:            /**
0260:             * Adds a view state to the flow built by this builder.
0261:             * @param stateId the state identifier
0262:             * @param viewName the string-encoded view selector
0263:             * @param renderAction the action to execute on state entry and refresh; may
0264:             * be null
0265:             * @param transitions the transitions (paths) out of this state
0266:             * @return the fully constructed view state instance
0267:             */
0268:            protected State addViewState(String stateId, String viewName,
0269:                    Action renderAction, Transition[] transitions) {
0270:                return getFlowArtifactFactory().createViewState(stateId,
0271:                        getFlow(), null, viewSelector(viewName),
0272:                        new Action[] { renderAction }, transitions, null, null,
0273:                        null);
0274:            }
0275:
0276:            /**
0277:             * Adds a view state to the flow built by this builder.
0278:             * @param stateId the state identifier
0279:             * @param entryActions the actions to execute when the state is entered
0280:             * @param viewSelector the view selector that will make the view selection
0281:             * when the state is entered
0282:             * @param renderActions any 'render actions' to execute on state entry and
0283:             * refresh; may be null
0284:             * @param transitions the transitions (path) out of this state
0285:             * @param exceptionHandlers any exception handlers to attach to the state
0286:             * @param exitActions the actions to execute when the state exits
0287:             * @param attributes attributes to assign to the state that may be used to
0288:             * affect state construction and execution
0289:             * @return the fully constructed view state instance
0290:             */
0291:            protected State addViewState(String stateId, Action[] entryActions,
0292:                    ViewSelector viewSelector, Action[] renderActions,
0293:                    Transition[] transitions,
0294:                    FlowExecutionExceptionHandler[] exceptionHandlers,
0295:                    Action[] exitActions, AttributeMap attributes) {
0296:                return getFlowArtifactFactory()
0297:                        .createViewState(stateId, getFlow(), entryActions,
0298:                                viewSelector, renderActions, transitions,
0299:                                exceptionHandlers, exitActions, attributes);
0300:            }
0301:
0302:            // action state
0303:
0304:            /**
0305:             * Adds an action state to the flow built by this builder.
0306:             * @param stateId the state identifier
0307:             * @param action the single action to execute when the state is entered
0308:             * @param transition the single transition (path) out of this state
0309:             * @return the fully constructed action state instance
0310:             */
0311:            protected State addActionState(String stateId, Action action,
0312:                    Transition transition) {
0313:                return getFlowArtifactFactory().createActionState(stateId,
0314:                        getFlow(), null, new Action[] { action },
0315:                        new Transition[] { transition }, null, null, null);
0316:            }
0317:
0318:            /**
0319:             * Adds an action state to the flow built by this builder.
0320:             * @param stateId the state identifier
0321:             * @param action the single action to execute when the state is entered
0322:             * @param transitions the transitions (paths) out of this state
0323:             * @return the fully constructed action state instance
0324:             */
0325:            protected State addActionState(String stateId, Action action,
0326:                    Transition[] transitions) {
0327:                return getFlowArtifactFactory().createActionState(stateId,
0328:                        getFlow(), null, new Action[] { action }, transitions,
0329:                        null, null, null);
0330:            }
0331:
0332:            /**
0333:             * Adds an action state to the flow built by this builder.
0334:             * @param stateId the state identifier
0335:             * @param action the single action to execute when the state is entered
0336:             * @param transition the single transition (path) out of this state
0337:             * @param exceptionHandler the exception handler to handle exceptions thrown
0338:             * by the action
0339:             * @return the fully constructed action state instance
0340:             */
0341:            protected State addActionState(String stateId, Action action,
0342:                    Transition transition,
0343:                    FlowExecutionExceptionHandler exceptionHandler) {
0344:                return getFlowArtifactFactory()
0345:                        .createActionState(
0346:                                stateId,
0347:                                getFlow(),
0348:                                null,
0349:                                new Action[] { action },
0350:                                new Transition[] { transition },
0351:                                new FlowExecutionExceptionHandler[] { exceptionHandler },
0352:                                null, null);
0353:            }
0354:
0355:            /**
0356:             * Adds an action state to the flow built by this builder.
0357:             * @param stateId the state identifier
0358:             * @param entryActions any generic entry actions to add to the state
0359:             * @param actions the actions to execute in a chain when the state is
0360:             * entered
0361:             * @param transitions the transitions (paths) out of this state
0362:             * @param exceptionHandlers the exception handlers to handle exceptions
0363:             * thrown by the actions
0364:             * @param exitActions the exit actions to execute when the state exits
0365:             * @param attributes attributes to assign to the state that may be used to
0366:             * affect state construction and execution
0367:             * @return the fully constructed action state instance
0368:             */
0369:            protected State addActionState(String stateId,
0370:                    Action[] entryActions, Action[] actions,
0371:                    Transition[] transitions,
0372:                    FlowExecutionExceptionHandler[] exceptionHandlers,
0373:                    Action[] exitActions, AttributeMap attributes) {
0374:                return getFlowArtifactFactory().createActionState(stateId,
0375:                        getFlow(), entryActions, actions, transitions,
0376:                        exceptionHandlers, exitActions, attributes);
0377:            }
0378:
0379:            // decision state
0380:
0381:            /**
0382:             * Adds a decision state to the flow built by this builder.
0383:             * @param stateId the state identifier
0384:             * @param transitions the transitions (paths) out of this state
0385:             * @return the fully constructed decision state instance
0386:             */
0387:            protected State addDecisionState(String stateId,
0388:                    Transition[] transitions) {
0389:                return getFlowArtifactFactory().createDecisionState(stateId,
0390:                        getFlow(), null, transitions, null, null, null);
0391:            }
0392:
0393:            /**
0394:             * Adds a decision state to the flow built by this builder.
0395:             * @param stateId the state identifier
0396:             * @param decisionCriteria the criteria that defines the decision
0397:             * @param trueStateId the target state on a "true" decision
0398:             * @param falseStateId the target state on a "false" decision
0399:             * @return the fully constructed decision state instance
0400:             */
0401:            protected State addDecisionState(String stateId,
0402:                    TransitionCriteria decisionCriteria, String trueStateId,
0403:                    String falseStateId) {
0404:                Transition thenTransition = getFlowArtifactFactory()
0405:                        .createTransition(to(trueStateId), decisionCriteria,
0406:                                null, null);
0407:                Transition elseTransition = getFlowArtifactFactory()
0408:                        .createTransition(to(falseStateId), null, null, null);
0409:                return getFlowArtifactFactory().createDecisionState(stateId,
0410:                        getFlow(), null,
0411:                        new Transition[] { thenTransition, elseTransition },
0412:                        null, null, null);
0413:            }
0414:
0415:            /**
0416:             * Adds a decision state to the flow built by this builder.
0417:             * @param stateId the state identifier
0418:             * @param entryActions the entry actions to execute when the state enters
0419:             * @param transitions the transitions (paths) out of this state
0420:             * @param exceptionHandlers the exception handlers to handle exceptions
0421:             * thrown by the state
0422:             * @param exitActions the exit actions to execute when the state exits
0423:             * @param attributes attributes to assign to the state that may be used to
0424:             * affect state construction and execution
0425:             * @return the fully constructed decision state instance
0426:             */
0427:            protected State addDecisionState(String stateId,
0428:                    Action[] entryActions, Transition[] transitions,
0429:                    FlowExecutionExceptionHandler[] exceptionHandlers,
0430:                    Action[] exitActions, AttributeMap attributes) {
0431:                return getFlowArtifactFactory().createDecisionState(stateId,
0432:                        getFlow(), entryActions, transitions,
0433:                        exceptionHandlers, exitActions, attributes);
0434:            }
0435:
0436:            // subflow state
0437:
0438:            /**
0439:             * Adds a subflow state to the flow built by this builder.
0440:             * @param stateId the state identifier
0441:             * @param subflow the flow that will act as the subflow
0442:             * @param attributeMapper the mapper to map subflow input and output
0443:             * attributes
0444:             * @param transition the single transition (path) out of the state
0445:             * @return the fully constructed subflow state instance
0446:             */
0447:            protected State addSubflowState(String stateId, Flow subflow,
0448:                    FlowAttributeMapper attributeMapper, Transition transition) {
0449:                return getFlowArtifactFactory().createSubflowState(stateId,
0450:                        getFlow(), null, subflow, attributeMapper,
0451:                        new Transition[] { transition }, null, null, null);
0452:            }
0453:
0454:            /**
0455:             * Adds a subflow state to the flow built by this builder.
0456:             * @param stateId the state identifier
0457:             * @param subflow the flow that will act as the subflow
0458:             * @param attributeMapper the mapper to map subflow input and output
0459:             * attributes
0460:             * @param transitions the transitions (paths) out of the state
0461:             * @return the fully constructed subflow state instance
0462:             */
0463:            protected State addSubflowState(String stateId, Flow subflow,
0464:                    FlowAttributeMapper attributeMapper,
0465:                    Transition[] transitions) {
0466:                return getFlowArtifactFactory().createSubflowState(stateId,
0467:                        getFlow(), null, subflow, attributeMapper, transitions,
0468:                        null, null, null);
0469:            }
0470:
0471:            /**
0472:             * Adds a subflow state to the flow built by this builder.
0473:             * @param stateId the state identifier
0474:             * @param entryActions the entry actions to execute when the state enters
0475:             * @param subflow the flow that will act as the subflow
0476:             * @param attributeMapper the mapper to map subflow input and output
0477:             * attributes
0478:             * @param transitions the transitions (paths) out of this state
0479:             * @param exceptionHandlers the exception handlers to handle exceptions
0480:             * thrown by the state
0481:             * @param exitActions the exit actions to execute when the state exits
0482:             * @param attributes attributes to assign to the state that may be used to
0483:             * affect state construction and execution
0484:             * @return the fully constructed subflow state instance
0485:             */
0486:            protected State addSubflowState(String stateId,
0487:                    Action[] entryActions, Flow subflow,
0488:                    FlowAttributeMapper attributeMapper,
0489:                    Transition[] transitions,
0490:                    FlowExecutionExceptionHandler[] exceptionHandlers,
0491:                    Action[] exitActions, AttributeMap attributes) {
0492:                return getFlowArtifactFactory()
0493:                        .createSubflowState(stateId, getFlow(), entryActions,
0494:                                subflow, attributeMapper, transitions,
0495:                                exceptionHandlers, exitActions, attributes);
0496:            }
0497:
0498:            // end state
0499:
0500:            /**
0501:             * Adds an end state to the flow built by this builder.
0502:             * @param stateId the state identifier
0503:             * @return the fully constructed end state instance
0504:             */
0505:            protected State addEndState(String stateId) {
0506:                return getFlowArtifactFactory().createEndState(stateId,
0507:                        getFlow(), null, null, null, null, null);
0508:            }
0509:
0510:            /**
0511:             * Adds an end state to the flow built by this builder.
0512:             * @param stateId the state identifier
0513:             * @param viewName the string-encoded view selector
0514:             * @return the fully constructed end state instance
0515:             */
0516:            protected State addEndState(String stateId, String viewName) {
0517:                return getFlowArtifactFactory().createEndState(stateId,
0518:                        getFlow(), null, viewSelector(viewName), null, null,
0519:                        null);
0520:            }
0521:
0522:            /**
0523:             * Adds an end state to the flow built by this builder.
0524:             * @param stateId the state identifier
0525:             * @param viewName the string-encoded view selector
0526:             * @param outputMapper the output mapper to map output attributes for the
0527:             * end state (a flow outcome)
0528:             * @return the fully constructed end state instance
0529:             */
0530:            protected State addEndState(String stateId, String viewName,
0531:                    AttributeMapper outputMapper) {
0532:                return getFlowArtifactFactory().createEndState(stateId,
0533:                        getFlow(), null, viewSelector(viewName), outputMapper,
0534:                        null, null);
0535:            }
0536:
0537:            /**
0538:             * Adds an end state to the flow built by this builder.
0539:             * @param stateId the state identifier
0540:             * @param entryActions the actions to execute when the state is entered
0541:             * @param viewSelector the view selector that will make the view selection
0542:             * when the state is entered
0543:             * @param outputMapper the output mapper to map output attributes for the
0544:             * end state (a flow outcome)
0545:             * @param exceptionHandlers any exception handlers to attach to the state
0546:             * @param attributes attributes to assign to the state that may be used to
0547:             * affect state construction and execution
0548:             * @return the fully constructed end state instance
0549:             */
0550:            protected State addEndState(String stateId, Action[] entryActions,
0551:                    ViewSelector viewSelector, AttributeMapper outputMapper,
0552:                    FlowExecutionExceptionHandler[] exceptionHandlers,
0553:                    AttributeMap attributes) {
0554:                return getFlowArtifactFactory().createEndState(stateId,
0555:                        getFlow(), entryActions, viewSelector, outputMapper,
0556:                        exceptionHandlers, attributes);
0557:            }
0558:
0559:            // helpers to create misc. flow artifacts
0560:
0561:            /**
0562:             * Factory method that creates a view selector from an encoded
0563:             * view name. See {@link TextToViewSelector} for information on the
0564:             * conversion rules.
0565:             * @param viewName the encoded view selector
0566:             * @return the view selector
0567:             */
0568:            public ViewSelector viewSelector(String viewName) {
0569:                return (ViewSelector) fromStringTo(ViewSelector.class).execute(
0570:                        viewName);
0571:            }
0572:
0573:            /**
0574:             * Resolves the action with the specified id. Simply looks the action up by
0575:             * id and returns it.
0576:             * @param id the action id
0577:             * @return the action
0578:             * @throws FlowArtifactLookupException the action could not be resolved
0579:             */
0580:            protected Action action(String id)
0581:                    throws FlowArtifactLookupException {
0582:                return getFlowServiceLocator().getAction(id);
0583:            }
0584:
0585:            /**
0586:             * Creates a bean invoking action that invokes the method identified by the
0587:             * signature on the bean associated with the action identifier.
0588:             * @param beanId the id identifying an arbitrary
0589:             * <code>java.lang.Object</code> to be used as an action
0590:             * @param methodSignature the signature of the method to invoke on the POJO
0591:             * @return the adapted bean invoking action
0592:             * @throws FlowArtifactLookupException the action could not be resolved
0593:             */
0594:            protected Action action(String beanId,
0595:                    MethodSignature methodSignature)
0596:                    throws FlowArtifactLookupException {
0597:                return getBeanInvokingActionFactory().createBeanInvokingAction(
0598:                        beanId, getFlowServiceLocator().getBeanFactory(),
0599:                        methodSignature, null,
0600:                        getFlowServiceLocator().getConversionService(), null);
0601:            }
0602:
0603:            /**
0604:             * Creates a bean invoking action that invokes the method identified by the
0605:             * signature on the bean associated with the action identifier.
0606:             * @param beanId the id identifying an arbitrary
0607:             * <code>java.lang.Object</code> to be used as an action
0608:             * @param methodSignature the signature of the method to invoke on the POJO
0609:             * @return the adapted bean invoking action
0610:             * @throws FlowArtifactLookupException the action could not be resolved
0611:             */
0612:            protected Action action(String beanId,
0613:                    MethodSignature methodSignature,
0614:                    ActionResultExposer resultExposer)
0615:                    throws FlowArtifactLookupException {
0616:                return getBeanInvokingActionFactory().createBeanInvokingAction(
0617:                        beanId, getFlowServiceLocator().getBeanFactory(),
0618:                        methodSignature, resultExposer,
0619:                        getFlowServiceLocator().getConversionService(), null);
0620:            }
0621:
0622:            /**
0623:             * Creates an evaluate action that evaluates the expression when executed.
0624:             * @param expression the expression to evaluate
0625:             */
0626:            protected Action action(Expression expression) {
0627:                return action(expression, null);
0628:            }
0629:
0630:            /**
0631:             * Creates an evaluate action that evaluates the expression when executed.
0632:             * @param expression the expression to evaluate
0633:             * @param resultExposer the evaluation result exposer
0634:             */
0635:            protected Action action(Expression expression,
0636:                    ActionResultExposer resultExposer) {
0637:                return new EvaluateAction(expression, resultExposer);
0638:            }
0639:
0640:            /**
0641:             * Parses the expression string into an evaluatable {@link Expression} object.
0642:             * @param expressionString the expression string, e.g. flowScope.order.number
0643:             * @return the evaluatable expression
0644:             */
0645:            protected Expression expression(String expressionString) {
0646:                return getFlowServiceLocator().getExpressionParser()
0647:                        .parseExpression(expressionString);
0648:            }
0649:
0650:            /**
0651:             * Parses the expression string into a settable {@link Expression} object.
0652:             * @param expressionString the expression string, e.g. flowScope.order.number
0653:             * @return the evaluatable expression
0654:             * @since 1.0.2
0655:             */
0656:            protected SettableExpression settableExpression(
0657:                    String expressionString) {
0658:                return getFlowServiceLocator().getExpressionParser()
0659:                        .parseSettableExpression(expressionString);
0660:            }
0661:
0662:            /**
0663:             * Convert the encoded method signature string to a {@link MethodSignature}
0664:             * object. Method signatures are used to match methods on POJO services to
0665:             * invoke on a {@link AbstractBeanInvokingAction bean invoking action}.
0666:             * <p>
0667:             * Encoded method signature format:
0668:             * 
0669:             * Method without arguments:
0670:             * <pre>
0671:             *       ${methodName}
0672:             * </pre>
0673:             * 
0674:             * Method with arguments:
0675:             * <pre>
0676:             *       ${methodName}(${arg1}, ${arg2}, ${arg n})
0677:             * </pre>
0678:             * 
0679:             * @param method the encoded method signature
0680:             * @return the method signature
0681:             * @see #action(String, MethodSignature, ActionResultExposer)
0682:             */
0683:            protected MethodSignature method(String method) {
0684:                return (MethodSignature) fromStringTo(MethodSignature.class)
0685:                        .execute(method);
0686:            }
0687:
0688:            /**
0689:             * Factory method for a {@link ActionResultExposer result exposer}. A
0690:             * result exposer is used to expose an action result such as a method return
0691:             * value or expression evaluation result to the calling flow.
0692:             * @param resultName the result name
0693:             * @return the result exposer
0694:             * @see #action(String, MethodSignature, ActionResultExposer)
0695:             */
0696:            protected ActionResultExposer result(String resultName) {
0697:                return result(resultName, ScopeType.REQUEST);
0698:            }
0699:
0700:            /**
0701:             * Factory method for a {@link ActionResultExposer result exposer}. A
0702:             * result exposer is used to expose an action result such as a method return
0703:             * value or expression evaluation result to the calling flow.
0704:             * @param resultName the result name
0705:             * @param resultScope the scope of the result
0706:             * @return the result exposer
0707:             * @see #action(String, MethodSignature, ActionResultExposer)
0708:             */
0709:            protected ActionResultExposer result(String resultName,
0710:                    ScopeType resultScope) {
0711:                return new ActionResultExposer(resultName, resultScope);
0712:            }
0713:
0714:            /**
0715:             * Wrap given action in an {@link AnnotatedAction}} to be able
0716:             * to annotate it with attributes.
0717:             * @param action the action to annotate
0718:             * @return the wrapped action
0719:             * @since 1.0.4
0720:             */
0721:            protected AnnotatedAction annotate(Action action) {
0722:                if (action instanceof  AnnotatedAction) {
0723:                    return (AnnotatedAction) action;
0724:                } else {
0725:                    return new AnnotatedAction(action);
0726:                }
0727:            }
0728:
0729:            /**
0730:             * Creates an annotated action decorator that instructs the specified method
0731:             * be invoked on the multi action when it is executed. Use this when working
0732:             * with MultiActions to specify the method on the MultiAction to invoke for
0733:             * a particular usage scenario. Use the {@link #method(String)} factory
0734:             * method when working with
0735:             * {@link AbstractBeanInvokingAction bean invoking actions}.
0736:             * @param methodName the name of the method on the multi action instance
0737:             * @param multiAction the multi action
0738:             * @return the annotated action that when invoked sets up a context property
0739:             * used by the multi action to instruct it with what method to invoke
0740:             * @since 1.0.4
0741:             */
0742:            protected AnnotatedAction invoke(String methodName,
0743:                    Action multiAction) {
0744:                AnnotatedAction annotatedAction;
0745:                if (multiAction instanceof  AnnotatedAction) {
0746:                    // already wrapped in an AnnotatedAction
0747:                    annotatedAction = (AnnotatedAction) multiAction;
0748:                } else {
0749:                    annotatedAction = new AnnotatedAction(multiAction);
0750:                }
0751:                annotatedAction.setMethod(methodName);
0752:                return annotatedAction;
0753:            }
0754:
0755:            /**
0756:             * Creates an annotated action decorator that instructs the specified method
0757:             * be invoked on the multi action when it is executed. Use this when working
0758:             * with MultiActions to specify the method on the MultiAction to invoke for
0759:             * a particular usage scenario. Use the {@link #method(String)} factory
0760:             * method when working with
0761:             * {@link AbstractBeanInvokingAction bean invoking actions}.
0762:             * @param methodName the name of the method on the multi action instance
0763:             * @param multiAction the multi action
0764:             * @return the annotated action that when invoked sets up a context property
0765:             * used by the multi action to instruct it with what method to invoke
0766:             */
0767:            protected AnnotatedAction invoke(String methodName,
0768:                    MultiAction multiAction) throws FlowArtifactLookupException {
0769:                return invoke(methodName, (Action) multiAction);
0770:            }
0771:
0772:            /**
0773:             * Creates an annotated action decorator that makes the given action
0774:             * an named action.
0775:             * @param name the action name
0776:             * @param action the action to name
0777:             * @return the annotated named action
0778:             */
0779:            protected AnnotatedAction name(String name, Action action) {
0780:                AnnotatedAction annotatedAction;
0781:                if (action instanceof  AnnotatedAction) {
0782:                    // already wrapped in an AnnotatedAction
0783:                    annotatedAction = (AnnotatedAction) action;
0784:                } else {
0785:                    annotatedAction = new AnnotatedAction(action);
0786:                }
0787:                annotatedAction.setName(name);
0788:                return annotatedAction;
0789:            }
0790:
0791:            /**
0792:             * Request that the attribute mapper with the specified name be used to map
0793:             * attributes between a parent flow and a spawning subflow when the subflow
0794:             * state being constructed is entered.
0795:             * @param id the id of the attribute mapper that will map attributes between
0796:             * the flow built by this builder and the subflow
0797:             * @return the attribute mapper
0798:             * @throws FlowArtifactLookupException no FlowAttributeMapper implementation
0799:             * was exported with the specified id
0800:             */
0801:            protected FlowAttributeMapper attributeMapper(String id)
0802:                    throws FlowArtifactLookupException {
0803:                return getFlowServiceLocator().getAttributeMapper(id);
0804:            }
0805:
0806:            /**
0807:             * Request that the <code>Flow</code> with the specified flowId be spawned
0808:             * as a subflow when the subflow state being built is entered. Simply
0809:             * resolves the subflow definition by id and returns it; throwing a
0810:             * fail-fast exception if it does not exist.
0811:             * @param id the flow definition id
0812:             * @return the flow to be used as a subflow, this should be passed to a
0813:             * addSubflowState call
0814:             * @throws FlowArtifactLookupException when the flow cannot be resolved
0815:             */
0816:            protected Flow flow(String id) throws FlowArtifactLookupException {
0817:                return getFlowServiceLocator().getSubflow(id);
0818:            }
0819:
0820:            /**
0821:             * Creates a transition criteria that is used to match a Transition. The
0822:             * criteria is based on the provided expression string.
0823:             * @param transitionCriteriaExpression the transition criteria expression,
0824:             * typically simply a static event identifier (e.g. "submit")
0825:             * @return the transition criteria
0826:             * @see TextToTransitionCriteria
0827:             */
0828:            protected TransitionCriteria on(String transitionCriteriaExpression) {
0829:                return (TransitionCriteria) fromStringTo(
0830:                        TransitionCriteria.class).execute(
0831:                        transitionCriteriaExpression);
0832:            }
0833:
0834:            /**
0835:             * Creates a target state resolver for the given state id expression.
0836:             * @param targetStateIdExpression the target state id expression
0837:             * @return the target state resolver
0838:             * @see TextToTargetStateResolver
0839:             */
0840:            protected TargetStateResolver to(String targetStateIdExpression) {
0841:                return (TargetStateResolver) fromStringTo(
0842:                        TargetStateResolver.class).execute(
0843:                        targetStateIdExpression);
0844:            }
0845:
0846:            /**
0847:             * Creates a new transition.
0848:             * @param matchingCriteria the criteria that determines when the transition
0849:             * matches
0850:             * @param targetStateResolver the resolver of the transition's target state
0851:             * @return the transition
0852:             */
0853:            protected Transition transition(
0854:                    TransitionCriteria matchingCriteria,
0855:                    TargetStateResolver targetStateResolver) {
0856:                return getFlowArtifactFactory().createTransition(
0857:                        targetStateResolver, matchingCriteria, null, null);
0858:            }
0859:
0860:            /**
0861:             * Creates a new transition.
0862:             * @param matchingCriteria the criteria that determines when the transition
0863:             * matches
0864:             * @param targetStateResolver the resolver of the transition's target state
0865:             * @param executionCriteria the criteria that determines if a matched
0866:             * transition is allowed to execute
0867:             * @return the transition
0868:             */
0869:            protected Transition transition(
0870:                    TransitionCriteria matchingCriteria,
0871:                    TargetStateResolver targetStateResolver,
0872:                    TransitionCriteria executionCriteria) {
0873:                return getFlowArtifactFactory().createTransition(
0874:                        targetStateResolver, matchingCriteria,
0875:                        executionCriteria, null);
0876:            }
0877:
0878:            /**
0879:             * Creates a new transition.
0880:             * @param matchingCriteria the criteria that determines when the transition
0881:             * matches
0882:             * @param targetStateResolver the resolver of the transition's target state
0883:             * @param executionCriteria the criteria that determines if a matched
0884:             * transition is allowed to execute
0885:             * @param attributes transition attributes
0886:             * @return the transition
0887:             */
0888:            protected Transition transition(
0889:                    TransitionCriteria matchingCriteria,
0890:                    TargetStateResolver targetStateResolver,
0891:                    TransitionCriteria executionCriteria,
0892:                    AttributeMap attributes) {
0893:                return getFlowArtifactFactory().createTransition(
0894:                        targetStateResolver, matchingCriteria,
0895:                        executionCriteria, attributes);
0896:            }
0897:
0898:            /**
0899:             * Creates a <code>TransitionCriteria</code> that will execute the
0900:             * specified action when the Transition is executed but before the
0901:             * transition's target state is entered.
0902:             * <p>
0903:             * This criteria will only allow the Transition to complete execution if the
0904:             * Action completes successfully.
0905:             * @param action the action to execute after a transition is matched but
0906:             * before it transitions to its target state
0907:             * @return the transition execution criteria
0908:             */
0909:            protected TransitionCriteria ifReturnedSuccess(Action action) {
0910:                return new ActionTransitionCriteria(action);
0911:            }
0912:
0913:            /**
0914:             * Creates the <code>success</code> event id. "Success" indicates that an
0915:             * action completed successfuly.
0916:             * @return the event id
0917:             */
0918:            protected String success() {
0919:                return eventFactorySupport.getSuccessEventId();
0920:            }
0921:
0922:            /**
0923:             * Creates the <code>error</code> event id. "Error" indicates that an
0924:             * action completed with an error status.
0925:             * @return the event id
0926:             */
0927:            protected String error() {
0928:                return eventFactorySupport.getErrorEventId();
0929:            }
0930:
0931:            /**
0932:             * Creates the <code>submit</code> event id. "Submit" indicates the user
0933:             * submitted a request (form) for processing.
0934:             * @return the event id
0935:             */
0936:            protected String submit() {
0937:                return "submit";
0938:            }
0939:
0940:            /**
0941:             * Creates the <code>back</code> event id. "Back" indicates the user wants
0942:             * to go to the previous step in the flow.
0943:             * @return the event id
0944:             */
0945:            protected String back() {
0946:                return "back";
0947:            }
0948:
0949:            /**
0950:             * Creates the <code>cancel</code> event id. "Cancel" indicates the flow
0951:             * was aborted because the user changed their mind.
0952:             * @return the event id
0953:             */
0954:            protected String cancel() {
0955:                return "cancel";
0956:            }
0957:
0958:            /**
0959:             * Creates the <code>finish</code> event id. "Finish" indicates the flow
0960:             * has finished processing.
0961:             * @return the event id
0962:             */
0963:            protected String finish() {
0964:                return "finish";
0965:            }
0966:
0967:            /**
0968:             * Creates the <code>select</code> event id. "Select" indicates an object
0969:             * was selected for processing or display.
0970:             * @return the event id
0971:             */
0972:            protected String select() {
0973:                return "select";
0974:            }
0975:
0976:            /**
0977:             * Creates the <code>edit</code> event id. "Edit" indicates an object was
0978:             * selected for creation or updating.
0979:             * @return the event id
0980:             */
0981:            protected String edit() {
0982:                return "edit";
0983:            }
0984:
0985:            /**
0986:             * Creates the <code>add</code> event id. "Add" indicates a child object
0987:             * is being added to a parent collection.
0988:             * @return the event id
0989:             */
0990:            protected String add() {
0991:                return "add";
0992:            }
0993:
0994:            /**
0995:             * Creates the <code>delete</code> event id. "Delete" indicates a object
0996:             * is being removed.
0997:             * @return the event id
0998:             */
0999:            protected String delete() {
1000:                return "delete";
1001:            }
1002:
1003:            /**
1004:             * Creates the <code>yes</code> event id. "Yes" indicates a true result
1005:             * was returned.
1006:             * @return the event id
1007:             */
1008:            protected String yes() {
1009:                return eventFactorySupport.getYesEventId();
1010:            }
1011:
1012:            /**
1013:             * Creates the <code>no</code> event id. "False" indicates a false result
1014:             * was returned.
1015:             * @return the event id
1016:             */
1017:            protected String no() {
1018:                return eventFactorySupport.getNoEventId();
1019:            }
1020:
1021:            /**
1022:             * Factory method that returns a new, fully configured mapping builder to
1023:             * assist with building {@link Mapping} objects used by a
1024:             * {@link FlowAttributeMapper} to map attributes.
1025:             * @return the mapping builder
1026:             */
1027:            protected MappingBuilder mapping() {
1028:                MappingBuilder mapping = new MappingBuilder(
1029:                        getFlowServiceLocator().getExpressionParser());
1030:                mapping.setConversionService(getFlowServiceLocator()
1031:                        .getConversionService());
1032:                return mapping;
1033:            }
1034:
1035:            public String toString() {
1036:                return new ToStringCreator(this ).toString();
1037:            }
1038:
1039:            // internal helpers
1040:
1041:            private FlowArtifactFactory getFlowArtifactFactory() {
1042:                return getFlowServiceLocator().getFlowArtifactFactory();
1043:            }
1044:
1045:            private BeanInvokingActionFactory getBeanInvokingActionFactory() {
1046:                return getFlowServiceLocator().getBeanInvokingActionFactory();
1047:            }
1048:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.