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

📄 transitionablestate.java

📁 spring的WEB开发插件,支持多状态WEB开发
💻 JAVA
字号:
/*
 * 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;

import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import org.springframework.core.CollectionFactory;
import org.springframework.core.style.ToStringCreator;

/**
 * Abstract superclass for states that have one or more transitions. State
 * transitions are typically triggered by events.
 * 
 * @see org.springframework.webflow.Transition
 * @see org.springframework.webflow.TransitionCriteria
 * 
 * @author Keith Donald
 * @author Erwin Vervaet
 */
public abstract class TransitionableState extends State {

	/**
	 * The set of possible transitions out of this state.
	 */
	private Set transitions = CollectionFactory.createLinkedSetIfPossible(6);
	
	/**
	 * An action to execute when exiting this state. 
	 */
	private Action exitAction;
	
	/**
	 * Default constructor for bean style usage.
	 */
	protected TransitionableState() {
	}

	/**
	 * Create a new transitionable state.
	 * @param flow the owning flow
	 * @param id the state identifier (must be unique to the flow)
	 * @param transition the sole transition of this state
	 * @throws IllegalArgumentException when this state cannot be added to given flow
	 */
	protected TransitionableState(Flow flow, String id, Transition transition) throws IllegalArgumentException {
		super(flow, id);
		add(transition);
	}

	/**
	 * Create a new transitionable state.
	 * @param flow the owning flow
	 * @param id the state identifier (must be unique to the flow)
	 * @param transition the sole transition of this state
	 * @param properties additional properties describing this state
	 * @throws IllegalArgumentException when this state cannot be added to given flow
	 */
	protected TransitionableState(Flow flow, String id, Transition transition, Map properties)
			throws IllegalArgumentException {
		super(flow, id, properties);
		add(transition);
	}

	/**
	 * Create a new transitionable state.
	 * @param flow the owning flow
	 * @param id the state identifier (must be unique to the flow)
	 * @param transitions the transitions of this state
	 * @throws IllegalArgumentException when this state cannot be added to given flow
	 */
	protected TransitionableState(Flow flow, String id, Transition[] transitions) throws IllegalArgumentException {
		super(flow, id);
		addAll(transitions);
	}

	/**
	 * Create a new transitionable state.
	 * @param flow the owning flow
	 * @param id the state identifier (must be unique to the flow)
	 * @param transitions the transitions of this state
	 * @param properties additional properties describing this state
	 * @throws IllegalArgumentException when this state cannot be added to given flow
	 */
	protected TransitionableState(Flow flow, String id, Transition[] transitions, Map properties)
			throws IllegalArgumentException {
		super(flow, id, properties);
		addAll(transitions);
	}

	/**
	 * Returns the exit action for this state (may be null).
	 * @return the exit action
	 */
	public Action getExitAction() {
		return exitAction;
	}

	/**
	 * Sets the exit action for this state.
	 * @param exitAction the exit action (may be null).
	 */
	public void setExitAction(Action exitAction) {
		this.exitAction = exitAction;
	}
	
	/**
	 * Add a transition to this state.
	 * @param transition the transition to add
	 */
	public void add(Transition transition) {
		transition.setSourceState(this);
		this.transitions.add(transition);
	}

	/**
	 * Add given list of transitions to this state.
	 * @param transitions the transitions to add
	 */
	public void addAll(Transition[] transitions) {
		for (int i = 0; i < transitions.length; i++) {
			add(transitions[i]);
		}
	}

	/**
	 * Returns an iterator looping over all transitions in this state.
	 */
	public Iterator transitionsIterator() {
		return transitions.iterator();
	}

	/**
	 * Returns the list of transitions owned by this state.
	 */
	public Transition[] getTransitions() {
		return (Transition[])transitions.toArray(new Transition[transitions.size()]);
	}

	/**
	 * Returns a list of the supported transitional criteria used to match
	 * transitions in this state.
	 * @return the list of transitional criteria
	 */
	public TransitionCriteria[] getTransitionCriterias() {
		TransitionCriteria[] res = new TransitionCriteria[transitions.size()];
		Iterator it = transitionsIterator();
		int i = 0;
		while (it.hasNext()) {
			res[i++] = ((Transition)it.next()).getMatchingCriteria();
		}
		return res;
	}

	/**
	 * Returns whether or not this state has a transition that will fire for
	 * given flow execution request context.
	 * @param context a flow execution context
	 */
	public boolean hasTransitionFor(RequestContext context) {
		return getTransition(context) != null;
	}

	/**
	 * Gets a transition for given flow execution request context.
	 * @param context a flow execution context
	 * @return the transition, or null if not found
	 */
	public Transition getTransition(RequestContext context) {
		Iterator it = transitionsIterator();
		while (it.hasNext()) {
			Transition transition = (Transition)it.next();
			if (transition.matches(context)) {
				return transition;
			}
		}
		return null;
	}

	/**
	 * Get a transition in this state for given flow execution request context.
	 * Throws and exception when when there is no corresponding transition.
	 * @throws NoMatchingTransitionException when the transition cannot be found
	 */
	public Transition getRequiredTransition(RequestContext context) throws NoMatchingTransitionException {
		Transition transition = getTransition(context);
		if (transition == null) {
			throw new NoMatchingTransitionException(this, context);
		}
		return transition;
	}

	/**
	 * Notify this state that the specified Event was signaled within it. By
	 * default, receipt of the event will trigger a search for a matching state
	 * transition. If a valid transition is matched, its execution will be
	 * requested. If a transition could not be matched, or the transition
	 * execution failed, an exception will be thrown.
	 * @param event the event that occured
	 * @param context the context associated with this request
	 * @return the view descriptor
	 * @throws NoMatchingTransitionException when no matching transition can be found
	 * @throws CannotExecuteStateTransitionException when a transition could
	 *         not be executed on receipt of the event
	 */
	public ViewDescriptor onEvent(Event event, StateContext context)
			throws NoMatchingTransitionException, CannotExecuteTransitionException {
		if (logger.isDebugEnabled()) {
			logger.debug("Event '" + event.getId() + "' signaled in context: " + context);
		}
		context.setLastEvent(event);
		Transition transition = getRequiredTransition(context);
		if (logger.isDebugEnabled()) {
			logger.debug("Event '" + event.getId() + "' matched transition to state: '" + transition.getTargetStateId() + "'");
		}
		return transition.execute(context);
	}

	/**
	 * Re-enter this state. This is typically called when a transition out
	 * of this state is selected, but transition execution rolls back and
	 * as a result the flow reenters the source state.
	 * <p>
	 * By default, this just calls <code>enter()</code>.
	 * @param context the request context in an executing flow (a client instance of a flow)
	 * @return a view descriptor containing model and view information needed to
	 *         render the results of the state processing
	 */
	public ViewDescriptor reenter(StateContext context) {
		// just re-enter this state
		return enter(context);
	}

	/**
	 * Exit this state. This is typically called when a transition takes the flow
	 * out of this state into another state. By default just executes the exit action, if
	 * one is registered.
	 * @param context the flow execution request context
	 */
	public void exit(StateContext context) {
		if (this.exitAction != null) {
			new ActionExecutor(exitAction).execute(context);
		}
	}
	
	protected void createToString(ToStringCreator creator) {
		creator.append("transitions", this.transitions).append("exitAction", exitAction);
	}

}

⌨️ 快捷键说明

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