All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.springframework.webflow.executor.FlowExecutorImpl Maven / Gradle / Ivy

There is a newer version: 3.0.0
Show newest version
/*
 * Copyright 2004-2012 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.executor;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.util.Assert;
import org.springframework.webflow.context.ExternalContext;
import org.springframework.webflow.context.ExternalContextHolder;
import org.springframework.webflow.core.FlowException;
import org.springframework.webflow.core.collection.MutableAttributeMap;
import org.springframework.webflow.definition.FlowDefinition;
import org.springframework.webflow.definition.registry.FlowDefinitionLocator;
import org.springframework.webflow.execution.FlowExecution;
import org.springframework.webflow.execution.FlowExecutionFactory;
import org.springframework.webflow.execution.FlowExecutionKey;
import org.springframework.webflow.execution.repository.FlowExecutionLock;
import org.springframework.webflow.execution.repository.FlowExecutionRepository;

/**
 * The default implementation of the central facade for driving the execution of flows within an application.
 * 

* This object is responsible for creating and launching new flow executions as requested by clients, as well as * resuming existing, paused executions (that were waiting to be resumed in response to a user event). *

* This object is a facade or entry point into the Spring Web Flow execution system and makes the overall system easier * to use. The name executor was chosen as executors drive executions. *

* Commonly used configurable properties
*

* * * * * * * * * * * * * * * * * * * * *
namedescriptiondefault
definitionLocatorThe service locator responsible for loading flow definitions to execute.None
executionFactoryThe factory responsible for creating new flow executions.None
executionRepositoryThe repository responsible for managing flow execution persistence.None
*

* * @see FlowDefinitionLocator * @see FlowExecutionFactory * @see FlowExecutionRepository * * @author Keith Donald * @author Erwin Vervaet * @author Colin Sampaleanu */ public class FlowExecutorImpl implements FlowExecutor { private static final Log logger = LogFactory.getLog(FlowExecutorImpl.class); /** * The locator to access flow definitions registered in a central registry. */ private FlowDefinitionLocator definitionLocator; /** * The abstract factory for creating a new execution of a flow definition. */ private FlowExecutionFactory executionFactory; /** * The repository used to save, update, and load existing flow executions to/from a persistent store. */ private FlowExecutionRepository executionRepository; /** * Create a new flow executor. * @param definitionLocator the locator for accessing flow definitions to execute * @param executionFactory the factory for creating executions of flow definitions * @param executionRepository the repository for persisting paused flow executions */ public FlowExecutorImpl(FlowDefinitionLocator definitionLocator, FlowExecutionFactory executionFactory, FlowExecutionRepository executionRepository) { Assert.notNull(definitionLocator, "The locator for accessing flow definitions is required"); Assert.notNull(executionFactory, "The execution factory for creating new flow executions is required"); Assert.notNull(executionRepository, "The repository for persisting flow executions is required"); this.definitionLocator = definitionLocator; this.executionFactory = executionFactory; this.executionRepository = executionRepository; } /** * Returns the locator to load flow definitions to execute. */ public FlowDefinitionLocator getDefinitionLocator() { return definitionLocator; } /** * Returns the abstract factory used to create new executions of a flow. */ public FlowExecutionFactory getExecutionFactory() { return executionFactory; } /** * Returns the repository used to save, update, and load existing flow executions to/from a persistent store. */ public FlowExecutionRepository getExecutionRepository() { return executionRepository; } public FlowExecutionResult launchExecution(String flowId, MutableAttributeMap input, ExternalContext context) throws FlowException { try { if (logger.isDebugEnabled()) { logger.debug("Launching new execution of flow '" + flowId + "' with input " + input); } ExternalContextHolder.setExternalContext(context); FlowDefinition flowDefinition = definitionLocator.getFlowDefinition(flowId); FlowExecution flowExecution = executionFactory.createFlowExecution(flowDefinition); flowExecution.start(input, context); if (!flowExecution.hasEnded()) { FlowExecutionLock lock = executionRepository.getLock(flowExecution.getKey()); lock.lock(); try { executionRepository.putFlowExecution(flowExecution); } finally { lock.unlock(); } return createPausedResult(flowExecution); } else { return createEndResult(flowExecution); } } finally { ExternalContextHolder.setExternalContext(null); } } public FlowExecutionResult resumeExecution(String flowExecutionKey, ExternalContext context) throws FlowException { try { if (logger.isDebugEnabled()) { logger.debug("Resuming flow execution with key '" + flowExecutionKey); } ExternalContextHolder.setExternalContext(context); FlowExecutionKey key = executionRepository.parseFlowExecutionKey(flowExecutionKey); FlowExecutionLock lock = executionRepository.getLock(key); lock.lock(); try { FlowExecution flowExecution = executionRepository.getFlowExecution(key); flowExecution.resume(context); if (!flowExecution.hasEnded()) { executionRepository.putFlowExecution(flowExecution); return createPausedResult(flowExecution); } else { executionRepository.removeFlowExecution(flowExecution); return createEndResult(flowExecution); } } finally { lock.unlock(); } } finally { ExternalContextHolder.setExternalContext(null); } } private FlowExecutionResult createEndResult(FlowExecution flowExecution) { return FlowExecutionResult.createEndedResult(flowExecution.getDefinition().getId(), flowExecution.getOutcome()); } private FlowExecutionResult createPausedResult(FlowExecution flowExecution) { return FlowExecutionResult.createPausedResult(flowExecution.getDefinition().getId(), flowExecution.getKey() .toString()); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy