/*
* 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.engine.model;
import java.util.LinkedList;
import org.springframework.util.StringUtils;
/**
* Model support for flows.
* <p>
* Defines exactly one flow definition. A flow is composed of one or more states that define the steps of a
* conversation. One of those steps is the start state, which defines the conversation's starting point. <br>
* A flow may also exhibit the following characteristics:
* <ul>
* <li>Be annotated with attributes that define descriptive properties that may affect flow execution. (See
* {@link AttributeModel})
* <li>Be secured (See {@link SecuredModel})
* <li>Be a persistence context for managing persistent objects during the course of flow execution. (See
* {@link PersistenceContextModel})
* <li>Instantiate a set of instance variables when started. (See {@link VarModel})
* <li>Map input provided by callers that start it (See {@link InputModel})
* <li>Return output to callers that end it. (See {@link OutputModel})
* <li>Execute actions at start time and end time. (See {@link EvaluateModel}, {@link RenderModel} and {@link SetModel})
* <li>Define transitions shared by all states. (See {@link TransitionModel})
* <li>Handle exceptions thrown by during flow execution. (See {@link ExceptionHandlerModel})
* <li>Import one or more local bean definition files defining custom flow artifacts (such as actions, exception
* handlers, view factories, transition criteria, etc). (See {@link BeanImportModel})
* </ul>
*
* @author Scott Andrews
*/
public class FlowModel extends AbstractModel {
private String abztract;
private String parent;
private String startStateId;
private LinkedList<AttributeModel> attributes;
private SecuredModel secured;
private PersistenceContextModel persistenceContext;
private LinkedList<VarModel> vars;
private LinkedList<InputModel> inputs;
private LinkedList<OutputModel> outputs;
private LinkedList<AbstractActionModel> onStartActions;
private LinkedList<AbstractStateModel> states;
private LinkedList<TransitionModel> globalTransitions;
private LinkedList<AbstractActionModel> onEndActions;
private LinkedList<ExceptionHandlerModel> exceptionHandlers;
private LinkedList<BeanImportModel> beanImports;
/**
* Create a flow model
*/
public FlowModel() {
}
public boolean isMergeableWith(Model model) {
if ((model instanceof FlowModel)) {
return true;
} else {
return false;
}
}
public void merge(Model model) {
FlowModel flow = (FlowModel) model;
setParent(null);
setStartStateId(merge(getStartStateId(), flow.getStartStateId()));
setAttributes(merge(getAttributes(), flow.getAttributes()));
setSecured((SecuredModel) merge(getSecured(), flow.getSecured()));
setPersistenceContext((PersistenceContextModel) merge(getPersistenceContext(), flow.getPersistenceContext()));
setVars(merge(getVars(), flow.getVars(), false));
setInputs(merge(getInputs(), flow.getInputs()));
setOutputs(merge(getOutputs(), flow.getOutputs()));
setOnStartActions(merge(getOnStartActions(), flow.getOnStartActions(), false));
setStates(merge(getStates(), flow.getStates()));
setGlobalTransitions(merge(getGlobalTransitions(), flow.getGlobalTransitions()));
setOnEndActions(merge(getOnEndActions(), flow.getOnEndActions(), false));
setExceptionHandlers(merge(getExceptionHandlers(), flow.getExceptionHandlers()));
setBeanImports(merge(getBeanImports(), flow.getBeanImports()));
}
public Model createCopy() {
FlowModel copy = new FlowModel();
copy.setAbstract(abztract);
copy.setParent(parent);
copy.setStartStateId(startStateId);
copy.setAttributes(copyList(attributes));
copy.setSecured((SecuredModel) copy(secured));
copy.setPersistenceContext((PersistenceContextModel) copy(persistenceContext));
copy.setVars(copyList(vars));
copy.setInputs(copyList(inputs));
copy.setOutputs(copyList(outputs));
copy.setOnStartActions(copyList(onStartActions));
copy.setStates(copyList(states));
copy.setGlobalTransitions(copyList(globalTransitions));
copy.setOnEndActions(copyList(onEndActions));
copy.setExceptionHandlers(copyList(exceptionHandlers));
copy.setBeanImports(copyList(beanImports));
return copy;
}
/**
* @return the abstract
*/
public String getAbstract() {
return abztract;
}
/**
* @param abztract the abstract to set
*/
public void setAbstract(String abztract) {
if (StringUtils.hasText(abztract)) {
this.abztract = abztract;
} else {
this.abztract = null;
}
}
/**
* @return the parent
*/
public String getParent() {
return parent;
}
/**
* @param parent the parent to set
*/
public void setParent(String parent) {
if (StringUtils.hasText(parent)) {
this.parent = parent;
} else {
this.parent = null;
}
}
/**
* @return the id of the flow's start state
*/
public String getStartStateId() {
return startStateId;
}
/**
* @param startStateId the id of the flow's start state to set
*/
public void setStartStateId(String startStateId) {
if (StringUtils.hasText(startStateId)) {
this.startStateId = startStateId;
} else {
this.startStateId = null;
}
}
/**
* @return the attributes
*/
public LinkedList<AttributeModel> getAttributes() {
return attributes;
}
/**
* @param attributes the attributes to set
*/
public void setAttributes(LinkedList<AttributeModel> attributes) {
this.attributes = attributes;
}
/**
* @return the secured
*/
public SecuredModel getSecured() {
return secured;
}
/**
* @param secured the secured to set
*/
public void setSecured(SecuredModel secured) {
this.secured = secured;
}
/**
* @return the persistence context
*/
public PersistenceContextModel getPersistenceContext() {
return persistenceContext;
}
/**
* @param persistenceContext the persistence context to set
*/
public void setPersistenceContext(PersistenceContextModel persistenceContext) {
this.persistenceContext = persistenceContext;
}
/**
* @return the vars
*/
public LinkedList<VarModel> getVars() {
return vars;
}
/**
* @param vars the vars to set
*/
public void setVars(LinkedList<VarModel> vars) {
this.vars = vars;
}
/**
* @return the input mappings
*/
public LinkedList<InputModel> getInputs() {
return inputs;
}
/**
* @param inputs the input mappings to set
*/
public void setInputs(LinkedList<InputModel> inputs) {
this.inputs = inputs;
}
/**
* @return the output mappings
*/
public LinkedList<OutputModel> getOutputs() {
return outputs;
}
/**
* @param outputs the output mappings to set
*/
public void setOutputs(LinkedList<OutputModel> outputs) {
this.outputs = outputs;
}
/**
* @return the on start actions
*/
public LinkedList<AbstractActionModel> getOnStartActions() {
return onStartActions;
}
/**
* @param onStartActions the on start actions to set
*/
public void setOnStartActions(LinkedList<AbstractActionModel> onStartActions) {
this.onStartActions = onStartActions;
}
/**
* @return the states
*/
public LinkedList<AbstractStateModel> getStates() {
return states;
}
/**
* Get the state model for an identifier
* @param id the state identifier to find
* @return the state or null if the identifier was not found
*/
public AbstractStateModel getStateById(String id) {
if (states != null) {
for (AbstractStateModel state : states) {
if (id.equals(state.getId())) {
return state;
}
}
}
return null;
}
/**
* @param states the states to set
*/
public void setStates(LinkedList<AbstractStateModel> states) {
this.states = states;
}
/**
* @return the global transitions
*/
public LinkedList<TransitionModel> getGlobalTransitions() {
return globalTransitions;
}
/**
* @param globalTransitions the global transitions to set
*/
public void setGlobalTransitions(LinkedList<TransitionModel> globalTransitions) {
this.globalTransitions = globalTransitions;
}
/**
* @return the on end actions
*/
public LinkedList<AbstractActionModel> getOnEndActions() {
return onEndActions;
}
/**
* @param onEndActions the on end actions to set
*/
public void setOnEndActions(LinkedList<AbstractActionModel> onEndActions) {
this.onEndActions = onEndActions;
}
/**
* @return the exception handlers
*/
public LinkedList<ExceptionHandlerModel> getExceptionHandlers() {
return exceptionHandlers;
}
/**
* @param exceptionHandlers the exception handlers to set
*/
public void setExceptionHandlers(LinkedList<ExceptionHandlerModel> exceptionHandlers) {
this.exceptionHandlers = exceptionHandlers;
}
/**
* @return the bean imports
*/
public LinkedList<BeanImportModel> getBeanImports() {
return beanImports;
}
/**
* @param beanImports the bean imports to set
*/
public void setBeanImports(LinkedList<BeanImportModel> beanImports) {
this.beanImports = beanImports;
}
}