flowexecutionmanager.java
来自「spring的WEB开发插件,支持多状态WEB开发」· Java 代码 · 共 577 行 · 第 1/2 页
JAVA
577 行
}
}
/**
* Add a listener that will listen to executions for all flows.
* @param listener the listener to add
*/
public void addListener(FlowExecutionListener listener) {
addListener(listener, FlowExecutionListenerCriteriaFactory.allFlows());
}
/**
* Add a listener that wil listen to executions to flows matching the specified criteria
* @param listener the listener
* @param criteria the listener criteria
*/
public void addListener(FlowExecutionListener listener, FlowExecutionListenerCriteria criteria) {
List registeredCriteria = (List)this.flowExecutionListeners.get(listener);
registeredCriteria.add(criteria);
}
/**
* Remove the flow execution listener from the listener list.
* @param listener the listener
*/
public void removeListener(FlowExecutionListener listener) {
this.flowExecutionListeners.remove(listener);
}
/**
* Returns the storage strategy used by the flow execution manager.
*/
protected FlowExecutionStorage getStorage() {
return storage;
}
/**
* Set the storage strategy used by the flow execution manager.
*/
public void setStorage(FlowExecutionStorage storage) {
Assert.notNull(storage, "The flow execution storage strategy is required");
this.storage = storage;
}
/**
* Return the application transaction synchronization strategy to use.
* This defaults to a <i>synchronizer token</i> based transaction management
* system, as implemented by {@link FlowScopeTokenTransactionSynchronizer}.
*/
protected TransactionSynchronizer getTransactionSynchronizer() {
return transactionSynchronizer;
}
/**
* Set the application transaction synchronization strategy to use.
*/
public void setTransactionSynchronizer(TransactionSynchronizer transactionSynchronizer) {
this.transactionSynchronizer = transactionSynchronizer;
}
/**
* Returns the conversion service used by this flow execution manager.
*/
public ConversionService getConversionService() {
return conversionService;
}
/**
* Set the conversion service used by this flow execution manager.
*/
public void setConversionService(ConversionService conversionService) {
this.conversionService = conversionService;
}
/**
* Returns this flow execution manager's bean factory.
*/
protected BeanFactory getBeanFactory() {
return this.beanFactory;
}
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
if (getFlowLocator() instanceof BeanFactoryAware) {
// make the BeanFactoryFlowServiceLocator work
((BeanFactoryAware)getFlowLocator()).setBeanFactory(beanFactory);
}
}
// event processing
/**
* Signal the occurence of the specified event - this is the entry point into the
* webflow system for managing all executing flows.
* @param event the event that occured
* @return the view descriptor of the model and view to render
* @throws Exception in case of errors
*/
public ViewDescriptor onEvent(Event event) throws Exception {
return onEvent(event, null);
}
/**
* Signal the occurence of the specified event - this is the entry point into the
* webflow system for managing all executing flows.
* @param event the event that occured
* @param listener a listener interested in flow execution
* lifecycle events that happen <i>while handling this event</i>
* @return the view descriptor of the model and view to render
* @throws Exception in case of errors
*/
public ViewDescriptor onEvent(Event event, FlowExecutionListener listener) throws Exception {
if (logger.isDebugEnabled()) {
logger.debug("New request received from client, source event is: "+ event);
}
FlowExecution flowExecution;
ViewDescriptor viewDescriptor;
Serializable id = getFlowExecutionId(event);
if (id == null) {
// start a new flow execution
Flow flow = getFlow(event);
flowExecution = createFlowExecution(flow);
if (listener != null) {
flowExecution.getListeners().add(listener);
}
flowExecution.getListeners().fireCreated(flowExecution);
if (logger.isDebugEnabled()) {
logger.debug("Created new flow execution for flow definition: '" + flow.getId() + "'");
}
viewDescriptor = flowExecution.start(event);
}
else {
// client is participating in an existing flow execution,
// retrieve information about it
flowExecution = getStorage().load(id, event);
// rehydrate the execution if neccessary (if it had been serialized out)
flowExecution.rehydrate(getFlowLocator(), this, getTransactionSynchronizer());
if (listener != null) {
flowExecution.getListeners().add(listener);
}
flowExecution.getListeners().fireLoaded(flowExecution, id);
if (logger.isDebugEnabled()) {
logger.debug("Loaded existing flow execution from storage with id: '" + id + "'");
}
// signal the event within the current state
Assert.hasText(event.getId(), "No eventId could be obtained -- "
+ "make sure the client provides the _eventId parameter as input; the parameters provided for this request were:"
+ StylerUtils.style(event.getParameters()));
// see if the eventId was set to a static marker placeholder because
// of a client configuration error
if (event.getId().equals(getNotSetEventIdParameterMarker())) {
throw new IllegalArgumentException("The received eventId was the 'not set' marker '"
+ getNotSetEventIdParameterMarker()
+ "' -- this is likely a view (jsp, etc) configuration error --"
+ "the _eventId parameter must be set to a valid event");
}
viewDescriptor = flowExecution.signalEvent(event);
}
if (flowExecution.isActive()) {
// save the flow execution for future use
id = getStorage().save(id, flowExecution, event);
flowExecution.getListeners().fireSaved(flowExecution, id);
if (logger.isDebugEnabled()) {
logger.debug("Saved flow execution out to storage with id: '" + id + "'");
}
}
else {
// event execution resulted in the entire flow execution ending, cleanup
if (id != null) {
getStorage().remove(id, event);
flowExecution.getListeners().fireRemoved(flowExecution, id);
if (logger.isDebugEnabled()) {
logger.debug("Removed flow execution from storage with id: '" + id + "'");
}
}
}
if (listener != null) {
flowExecution.getListeners().remove(listener);
}
viewDescriptor = prepareViewDescriptor(viewDescriptor, id, flowExecution);
if (logger.isDebugEnabled()) {
logger.debug("Returning selected view to client: " + viewDescriptor);
}
return viewDescriptor;
}
// subclassing hooks
/**
* Create a new flow execution for given flow. Subclasses could redefine this
* if they wish to use a specialized FlowExecution implementation class.
* @param flow the flow
* @return the created flow execution
*/
protected FlowExecution createFlowExecution(Flow flow) {
return new FlowExecutionImpl(flow, getListeners(flow), getTransactionSynchronizer());
}
/**
* Obtain a flow to use from given event. If there is a "_flowId" parameter
* specified in the event, the flow with that id will be returend after
* lookup using the flow locator. If no "_flowId" parameter is present in the
* event, the default top-level flow will be returned.
*/
protected Flow getFlow(Event event) {
String flowId = ExternalEvent.verifySingleStringInputParameter(getFlowIdParameterName(), event.getParameter(getFlowIdParameterName()));
if (!StringUtils.hasText(flowId)) {
Assert.notNull(getFlow(),
"This flow execution manager is not configured with a default top-level flow--that means "
+ "the flow to launch must be provided by the client via the '"
+ getFlowIdParameterName() + "' parameter, yet no such parameter was provided in this event." +
" Parameters provided were: " + StylerUtils.style(event.getParameters()));
return getFlow();
}
else {
Assert.notNull(getFlowLocator(), "The flow locator is required to lookup the requested flow with id '"
+ flowId + "'; however, the flowLocator property is null");
return getFlowLocator().getFlow(flowId);
}
}
/**
* Returns the name of the flow id parameter in the event ("_flowId").
*/
protected String getFlowIdParameterName() {
return FLOW_ID_PARAMETER;
}
/**
* Obtain a unique flow execution id from given event.
* @param event the event
* @return the obtained id or <code>null</code> if not found
*/
protected String getFlowExecutionId(Event event) {
return ExternalEvent.verifySingleStringInputParameter(getFlowExecutionIdParameterName(), event.getParameter(getFlowExecutionIdParameterName()));
}
/**
* Returns the name of the flow execution id parameter in the event
* ("_flowExecutionId").
*/
protected String getFlowExecutionIdParameterName() {
return FLOW_EXECUTION_ID_PARAMETER;
}
/**
* Returns the marker value indicating that the event id parameter was not
* set properly in the event because of a view configuration error ("@NOT_SET@").
* <p>
* This is useful when a view relies on an dynamic means to set the eventId
* event parameter, for example, using javascript. This approach assumes
* the "not set" marker value will be a static default (a kind of fallback,
* submitted if the eventId does not get set to the proper dynamic value
* onClick, for example, if javascript was disabled).
*/
protected String getNotSetEventIdParameterMarker() {
return NOT_SET_EVENT_ID;
}
/**
* Do any processing necessary before given view descriptor can be returned
* to the client of the flow execution manager. This implementation adds
* a number of <i>infrastructure attributes</i> to the model that will be
* exposed to the view. More specifically, it will add the
* {@link #FLOW_EXECUTION_CONTEXT_ATTRIBUTE}, {@link #FLOW_EXECUTION_ID_ATTRIBUTE}
* and {@link #CURRENT_STATE_ID_ATTRIBUTE}.
* @param viewDescriptor the view descriptor to be processed
* @param flowExecutionId the unique id of the flow execution
* @param flowExecutionContext the flow context providing info about the flow execution
* @return the processed view descriptor
*/
protected ViewDescriptor prepareViewDescriptor(ViewDescriptor viewDescriptor, Serializable flowExecutionId,
FlowExecutionContext flowExecutionContext) {
if (flowExecutionContext.isActive() && viewDescriptor != null) {
if (viewDescriptor.isRedirect()) {
viewDescriptor.addObject(getFlowExecutionIdParameterName(), flowExecutionId);
}
else {
// make the entire flow execution context available in the model
viewDescriptor.addObject(FLOW_EXECUTION_CONTEXT_ATTRIBUTE, flowExecutionContext);
// make the unique flow execution id and current state id available in the model as convenience to views
viewDescriptor.addObject(FLOW_EXECUTION_ID_ATTRIBUTE, flowExecutionId);
viewDescriptor.addObject(CURRENT_STATE_ID_ATTRIBUTE, flowExecutionContext.getCurrentState().getId());
}
}
return viewDescriptor;
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?