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.execution;
017:
018: /**
019: * A command that executes a behavior and returns a logical execution result a
020: * calling flow execution can respond to.
021: * <p>
022: * Actions typically delegate down to the application (or service) layer to
023: * perform business operations. They often retrieve data to support response
024: * rendering. They act as a bridge between a SWF web-tier and your middle-tier
025: * business logic layer.
026: * <p>
027: * When an action completes execution it signals a result event describing the
028: * outcome of that execution (for example, "success", "error", "yes", "no",
029: * "tryAgain", etc). In addition to providing a logical outcome the flow can
030: * respond to, a result event may have payload associated with it, for example a
031: * "success" return value or an "error" error code. The result event is
032: * typically used as grounds for a state transition out of the current state of
033: * the calling Flow.
034: * <p>
035: * Action implementations are often application-scoped singletons instantiated
036: * and managed by a web-tier Spring application context to take advantage of
037: * Spring's externalized configuration and dependency injection capabilities
038: * (which is a form of Inversion of Control [IoC]). Actions may also be stateful
039: * prototypes, storing conversational state as instance variables. Action
040: * instance definitions may also be locally scoped to a specific flow definition
041: * (see use of the "import" element of the root XML flow definition element.)
042: * <p>
043: * Note: Actions are directly instantiatable for use in a standalone test
044: * environment and can be parameterized with mocks or stubs, as they are simple
045: * POJOs. Action proxies may also be generated at runtime for delegating to POJO
046: * business operations that have no dependency on the Spring Web Flow API.
047: * <p>
048: * Note: if an Action is a singleton managed in application scope, take care not
049: * to store and/or modify caller-specific state in a unsafe manner. The Action
050: * {@link #execute(RequestContext)} method runs in an independently executing
051: * thread on each invocation so make sure you deal only with local data or
052: * internal, thread-safe services.
053: * <p>
054: * Note: an Action is not a controller like a Spring MVC controller or a Struts
055: * action is a controller. Flow actions are <i>commands</i>. Such commands do
056: * not select views, they execute arbitrary behavioral logic and then return an
057: * logical execution result. The flow that invokes an Action is responsible for
058: * responding to the execution result to decide what to do next. In Spring Web
059: * Flow, the flow <i>is</i> the controller.
060: *
061: * @author Keith Donald
062: * @author Erwin Vervaet
063: */
064: public interface Action {
065:
066: /**
067: * Execute this action. Action execution will occur in the context of a
068: * request associated with an active flow execution.
069: * <p>
070: * Action invocation is typically triggered in a production environment by a
071: * state within a flow carrying out the execution of a flow definition. The
072: * result of action execution, a logical outcome event, can be used as
073: * grounds for a transition out of the calling state.
074: * <p>
075: * Note: The {@link RequestContext} argument to this method provides access
076: * to data about the active flow execution in the context of the currently
077: * executing thread. Among other things, this allows this action to access
078: * {@link RequestContext#getRequestScope() data} set by other actions, as
079: * well as set its own attributes it wishes to expose in a given scope.
080: * <p>
081: * Some notes about actions and their usage of the attribute scope types:
082: * <ul>
083: * <li>Attributes set in
084: * {@link RequestContext#getRequestScope() request scope} exist for the life
085: * of the currently executing request only.
086: * <li>Attributes set in {@link RequestContext#getFlashScope() flash scope}
087: * exist until the next external user event is signaled. That time includes
088: * the current request plus any redirect or additional refreshes to the next
089: * view.
090: * <li>Attributes set in {@link RequestContext#getFlowScope() flow scope}
091: * exist for the life of the flow session and will be
092: * cleaned up automatically when the flow session ends.
093: * <li>Attributes set in
094: * {@link RequestContext#getConversationScope() conversation scope} exist
095: * for the life of the entire flow execution representing a single logical
096: * "conversation" with a user.
097: * </ul>
098: * <p>
099: * All attributes present in any scope are typically exposed in a model
100: * for access by a view when an "interactive" state type such as a view
101: * state is entered.
102: * <p>
103: * Note: flow scope should generally not be used as a general purpose cache,
104: * but rather as a context for data needed locally by other states of the
105: * flow this action participates in. For example, it would be inappropriate
106: * to stuff large collections of objects (like those returned to support a
107: * search results view) into flow scope. Instead, put such result
108: * collections in request scope, and ensure you execute this action again
109: * each time you wish to view those results. 2nd level caches managed
110: * outside of SWF are more general cache solutions.
111: * <p>
112: * Note: as flow scoped attributes are eligible for serialization they
113: * should be <code>Serializable</code>.
114: *
115: * @param context the action execution context, for accessing and setting
116: * data in a {@link ScopeType scope type}, as well as obtaining other flow
117: * contextual information (e.g. request context attributes and flow
118: * execution context information)
119: * @return a logical result outcome, used as grounds for a transition in the
120: * calling flow (e.g. "success", "error", "yes", "no", * ...)
121: * @throws Exception a exception occured during action execution, either
122: * checked or unchecked; note, any <i>recoverable</i> exceptions should be
123: * caught within this method and an appropriate result outcome returned
124: * <i>or</i> be handled by the current state of the calling flow execution.
125: */
126: public Event execute(RequestContext context) throws Exception;
127: }
|