⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 abstractflowbuilder.java

📁 spring的WEB开发插件,支持多状态WEB开发
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
/*
 * Copyright 2002-2005 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.springframework.webflow.config;

import java.util.HashMap;
import java.util.Map;

import org.springframework.util.StringUtils;
import org.springframework.webflow.Action;
import org.springframework.webflow.ActionState;
import org.springframework.webflow.AnnotatedAction;
import org.springframework.webflow.EndState;
import org.springframework.webflow.Flow;
import org.springframework.webflow.FlowAttributeMapper;
import org.springframework.webflow.SubflowState;
import org.springframework.webflow.Transition;
import org.springframework.webflow.TransitionCriteria;
import org.springframework.webflow.TransitionCriteriaFactory;
import org.springframework.webflow.ViewDescriptorCreator;
import org.springframework.webflow.ViewState;
import org.springframework.webflow.access.AutowireMode;
import org.springframework.webflow.access.FlowServiceLocator;
import org.springframework.webflow.access.ServiceLookupException;
import org.springframework.webflow.action.DelegatingAction;
import org.springframework.webflow.action.MultiAction;
import org.springframework.webflow.support.ActionTransitionCriteria;

/**
 * Base class for flow builders that programmatically build flows in Java
 * configuration code.
 * <p>
 * To give you an example of what a simple Java-based web flow builder
 * definition might look like, the following example defines the 'dynamic' web
 * flow roughly equivalent to the work flow statically implemented in Spring
 * MVC's simple form controller:
 * 
 * <pre>
 * public class CustomerDetailFlowBuilder extends AbstractFlowBuilder {
 *     protected String flowId() {
 *         return &quot;customerDetails&quot;;
 *     }
 * 
 *     public void buildStates() {
 *         // get customer information
 *         addActionState(&quot;getDetails&quot;,
 *             action(GetCustomerAction.class, AutowireMode.BY_TYPE),
 *             on(success(), &quot;displayDetails&quot;));
 *         // view customer information               
 *         addViewState(&quot;displayDetails&quot;, &quot;customerDetails&quot;,
 *             on(submit(), &quot;bindAndValidate&quot;);
 *         // bind and validate customer information updates 
 *         addActionState(&quot;bindAndValidate&quot;,
 *             method("bindAndValidate", action(&quot;customerAction&quot;)),
 *             new Transition[] {
 *                 on(error(), &quot;displayDetails&quot;),
 *                 on(success(), &quot;finish&quot;)
 *             });
 *         // finish
 *         addEndState(&quot;finish&quot;);
 *     }
 * }
 * </pre>
 * 
 * What this Java-based FlowBuilder implementation does is add four states to a
 * flow identified as "customerDetails". These include a "get"
 * <code>ActionState</code> (the start state), a <code>ViewState</code>
 * state, a "bind and validate" <code>ActionState</code>, and an end marker
 * state (<code>EndState</code>).
 * 
 * The first state, an action state, will be assigned the indentifier
 * <code>getDetails</code>. This action state will automatically be
 * configured with the following defaults:
 * <ol>
 * <li>An autowired action instance of <code>GetCustomerDetails.class</code>. This is
 * the <code>Action</code> implementation that will execute when this state is
 * entered. In this example, that <code>Action</code> will go out to the DB,
 * load the Customer, and put it in the Flow's request context.
 * <li>A <code>success</code> transition to a default view state, called
 * <code>displayDetails</code>. This means when the get <code>Action</code>
 * returns a <code>success</code> result event (aka outcome), the <code>displayDetails</code>
 * state will be entered.
 * <li>It will act as the start state for this flow (by default, the first
 * state added to a flow during the build process is treated as the start
 * state).
 * </ol>
 * 
 * The second state, a view state, will be identified as <code>displayDetails</code>.
 * This view state will automatically be configured with the following defaults:
 * <ol>
 * <li>A view name called <code>customerDetails</code> -- this is the
 * logical name of a view resource. This logical view name gets mapped to a
 * physical view resource (jsp, etc.) by the calling front controller (via a
 * Spring view resolver, or a Struts action forward, for example).
 * <li>A <code>submit</code> transition to a bind and validate action state,
 * indentified by the default id <code>bindAndValidate</code>. This means
 * when a <code>submit</code> event is signaled by the view (for example, on a
 * submit button click), the bindAndValidate action state will be entered and
 * the <code>bindAndValidate</code> method of the 
 * <code>customerAction</code> <code>Action</code> implementation
 * will be executed.
 * </ol>
 * 
 * The third state, an action state, will be indentified as <code>
 * bindAndValidate</code>. This action state will automatically be configured
 * with the following defaults:
 * <ol>
 * <li>An action bean named <code>customerAction</code> --
 * this is the name of the <code>Action</code> implementation exported in the application
 * context that will execute when this state is entered. In this example, the
 * <code>Action</code> has a "bindAndValidate" method that
 * will bind form input in the HTTP request to a backing Customer form
 * object, validate it, and update the DB.
 * <li>A <code>success</code> transition to a default end state, called
 * <code>finish</code>. This means if the <code>Action</code> returns a
 * <code>success</code> result, the <code>finish</code> end state will be
 * transitioned to and the flow will terminate.
 * <li>An <code>error</code> transition back to the form view. This means if
 * the <code>Action</code> returns an <code>error</code> event, the <code>
 * displayDetails</code> view state will be transitioned back to.
 * </ol>
 * 
 * The fourth and last state, an end state, will be indentified with the default
 * end state id <code>finish</code>. This end state is a marker that signals
 * the end of the flow. When entered, the flow session terminates, and if this
 * flow is acting as a root flow in the current flow execution, any
 * flow-allocated resources will be cleaned up. An end state can optionally be
 * configured with a logical view name to forward to when entered. It will also
 * trigger a state transition in a resuming parent flow if this flow was
 * participating as a spawned 'subflow' within a suspended parent flow.
 * 
 * @author Keith Donald
 * @author Erwin Vervaet
 */
public abstract class AbstractFlowBuilder extends BaseFlowBuilder {

	/**
	 * Create an instance of a abstract flow builder; default constructor.
	 */
	protected AbstractFlowBuilder() {
		super();
	}

	/**
	 * Create an instance of an abstract flow builder, using the specified
	 * service locator to obtain needed flow services during configuation.
	 * @param flowServiceLocator the service locator
	 */
	protected AbstractFlowBuilder(FlowServiceLocator flowServiceLocator) {
		super(flowServiceLocator);
	}

	public final Flow init() throws FlowBuilderException {
		Flow flow = getFlowServiceLocator().createFlow(AutowireMode.DEFAULT);
		flow.setId(flowId());
		flow.setProperties(flowProperties());
		setFlow(flow);
		return flow;
	}
	
	/**
	 * Returns the id (name) of the flow built by this builder. Subclasses
	 * should override to return the unique flowId.
	 * @return the unique flow id
	 */
	protected abstract String flowId();

	/**
	 * Hook subclasses may override to provide additional properties about the flow built by
	 * this builder.  Returns <code>null</code> by default.
	 * @return additional properties describing the flow being built
	 */
	protected Map flowProperties() {
		return null;
	}

	public void dispose() {
		setFlow(null);
	}

	/**
	 * Adds a <code>ViewState</code> to the flow built by this builder. A view
	 * state triggers the rendering of a view template when entered.
	 * @param stateId the <code>ViewState</code> id; must be locally unique
	 *        to the flow built by this builder
	 * @param viewName the name of the logical view to render; this name
	 *        will be mapped to a physical resource template such as a JSP when
	 *        the ViewState is entered and control returns to the front
	 *        controller
	 * @param transition a single supported transition for this state, mapping a
	 *        path from this state to another state (triggered by an event)
	 * @return the view state
	 * @throws IllegalArgumentException the stateId was not unique
	 */
	protected ViewState addViewState(String stateId, String viewName, Transition transition)
			throws IllegalArgumentException {
		return new ViewState(getFlow(), stateId, view(viewName), transition);
	}

	/**
	 * Adds a <code>ViewState</code> to the flow built by this builder. A view
	 * state triggers the rendering of a view template when entered.
	 * @param stateId the <code>ViewState</code> id; must be unique in the
	 *        context of the flow built by this builder
	 * @param viewName the name of the logical view to render; this name
	 *        will be mapped to a physical resource template such as a JSP when
	 *        the ViewState is entered and control returns to the front
	 *        controller
	 * @param transitions the supported transitions for this state, where each
	 *        transition maps a path from this state to another state (triggered
	 *        by an event)
	 * @return the view state
	 * @throws IllegalArgumentException the stateId was not unique
	 */
	protected ViewState addViewState(String stateId, String viewName, Transition[] transitions)
			throws IllegalArgumentException {
		return new ViewState(getFlow(), stateId, view(viewName), transitions);
	}

	/**
	 * Adds a <code>ViewState</code> to the flow built by this builder. A view
	 * state triggers the rendering of a view template when entered.
	 * @param stateId the <code>ViewState</code> id; must be unique in the
	 *        context of the flow built by this builder
	 * @param viewName the name of the logical view to render; this name
	 *        will be mapped to a physical resource template such as a JSP when
	 *        the ViewState is entered and control returns to the front
	 *        controller
	 * @param transitions the supported transitions for this state, where each
	 *        transition maps a path from this state to another state (triggered
	 *        by an event)
	 * @param properties additional properties describing the state
	 * @return the view state
	 * @throws IllegalArgumentException the stateId was not unique
	 */
	protected ViewState addViewState(String stateId, String viewName, Transition[] transitions, Map properties)
			throws IllegalArgumentException {
		return new ViewState(getFlow(), stateId, view(viewName), transitions, properties);
	}

	/**
	 * Turn given view name into a corresponding view descriptor creator.
	 * @param viewName the view name (might be encoded)
	 * @return the corresponding view descriptor creator
	 */
	protected ViewDescriptorCreator view(String viewName) {
		return (ViewDescriptorCreator)fromStringTo(ViewDescriptorCreator.class).execute(viewName);
	}
	
	/**
	 * Adds a <code>ViewState</code> to the flow built by this builder. A view
	 * state triggers the rendering of a view template when entered.
	 * @param stateId the <code>ViewState</code> id; must be unique in the
	 *        context of the flow built by this builder
	 * @param creater the factory to produce a descriptor noting the name 
	 *        of the logical view to render; this name will be mapped to a physical
	 *        resource template such as a JSP when the ViewState is entered and control
	 *        returns to the front controller
	 * @param transitions the supported transitions for this state, where each
	 *        transition maps a path from this state to another state (triggered
	 *        by an event)
	 * @param properties additional properties describing the state
	 * @return the view state
	 * @throws IllegalArgumentException the stateId was not unique
	 */
	protected ViewState addViewState(String stateId, ViewDescriptorCreator creater, Transition[] transitions, Map properties)
			throws IllegalArgumentException {
		return new ViewState(getFlow(), stateId, creater, transitions, properties);
	}

	/**

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -