diff --git a/spring-webflow/src/main/java/org/springframework/webflow/engine/model/AbstractActionModel.java b/spring-webflow/src/main/java/org/springframework/webflow/engine/model/AbstractActionModel.java index a480475f..104a8abd 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/engine/model/AbstractActionModel.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/engine/model/AbstractActionModel.java @@ -42,6 +42,10 @@ public abstract class AbstractActionModel extends AbstractModel { // not mergeable } + protected void fillCopy(final AbstractActionModel copy) { + copy.setOutputs(copyList(attributes)); + } + /** * @return the attributes */ diff --git a/spring-webflow/src/main/java/org/springframework/webflow/engine/model/AbstractMappingModel.java b/spring-webflow/src/main/java/org/springframework/webflow/engine/model/AbstractMappingModel.java index d3239851..db42023f 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/engine/model/AbstractMappingModel.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/engine/model/AbstractMappingModel.java @@ -32,6 +32,14 @@ public abstract class AbstractMappingModel extends AbstractModel { private String required; + protected AbstractMappingModel fillCopy(AbstractMappingModel copy) { + copy.setName(name); + copy.setValue(value); + copy.setType(type); + copy.setRequired(required); + return copy; + } + /** * @return the name */ diff --git a/spring-webflow/src/main/java/org/springframework/webflow/engine/model/AbstractModel.java b/spring-webflow/src/main/java/org/springframework/webflow/engine/model/AbstractModel.java index 98771acf..4958e34a 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/engine/model/AbstractModel.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/engine/model/AbstractModel.java @@ -59,7 +59,11 @@ public abstract class AbstractModel implements Model { */ protected Model merge(Model child, Model parent) { if (child == null) { - return parent; + if (parent == null) { + return null; + } else { + return parent.createCopy(); + } } else if (parent == null) { return child; } else { @@ -93,7 +97,7 @@ public abstract class AbstractModel implements Model { if (parent == null) { return null; } else { - return new LinkedList(parent); + return copyList(parent); } } else if (parent == null) { return child; @@ -114,9 +118,9 @@ public abstract class AbstractModel implements Model { } if (!matchFound) { if (addAtEnd) { - child.addLast(parentElement); + child.addLast(parentElement.createCopy()); } else { - child.addFirst(parentElement); + child.addFirst(parentElement.createCopy()); } } } @@ -124,4 +128,23 @@ public abstract class AbstractModel implements Model { } } + protected Model copy(Model model) { + if (model == null) { + return null; + } + return model.createCopy(); + } + + protected LinkedList copyList(LinkedList list) { + if (list == null) { + return null; + } + LinkedList copy = new LinkedList(); + for (Iterator it = list.iterator(); it.hasNext();) { + Model model = (Model) it.next(); + copy.add(model.createCopy()); + } + return copy; + } + } diff --git a/spring-webflow/src/main/java/org/springframework/webflow/engine/model/AbstractStateModel.java b/spring-webflow/src/main/java/org/springframework/webflow/engine/model/AbstractStateModel.java index 71665f72..d427ac12 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/engine/model/AbstractStateModel.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/engine/model/AbstractStateModel.java @@ -38,6 +38,15 @@ public abstract class AbstractStateModel extends AbstractModel { private LinkedList exceptionHandlers; + protected void fillCopy(AbstractStateModel copy) { + copy.setId(id); + copy.setParent(parent); + copy.setAttributes(copyList(attributes)); + copy.setSecured((SecuredModel) copy(secured)); + copy.setOnEntryActions(copyList(onEntryActions)); + copy.setExceptionHandlers(copyList(exceptionHandlers)); + } + /** * @return the id */ @@ -130,4 +139,4 @@ public abstract class AbstractStateModel extends AbstractModel { this.exceptionHandlers = exceptionHandlers; } -} \ No newline at end of file +} diff --git a/spring-webflow/src/main/java/org/springframework/webflow/engine/model/AbstractTransitionableStateModel.java b/spring-webflow/src/main/java/org/springframework/webflow/engine/model/AbstractTransitionableStateModel.java index f2a4960c..326693e5 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/engine/model/AbstractTransitionableStateModel.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/engine/model/AbstractTransitionableStateModel.java @@ -28,6 +28,12 @@ public abstract class AbstractTransitionableStateModel extends AbstractStateMode private LinkedList onExitActions; + protected void fillCopy(final AbstractTransitionableStateModel copy) { + super.fillCopy(copy); + copy.setTransitions(copyList(transitions)); + copy.setOnExitActions(copyList(onExitActions)); + } + /** * @return the transitions */ @@ -56,4 +62,4 @@ public abstract class AbstractTransitionableStateModel extends AbstractStateMode this.onExitActions = onExitActions; } -} \ No newline at end of file +} diff --git a/spring-webflow/src/main/java/org/springframework/webflow/engine/model/ActionStateModel.java b/spring-webflow/src/main/java/org/springframework/webflow/engine/model/ActionStateModel.java index e2ed3712..9410f419 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/engine/model/ActionStateModel.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/engine/model/ActionStateModel.java @@ -55,6 +55,13 @@ public class ActionStateModel extends AbstractTransitionableStateModel { setActions(merge(getActions(), state.getActions(), false)); } + public Model createCopy() { + ActionStateModel copy = new ActionStateModel(getId()); + super.fillCopy(copy); + copy.setActions(copyList(actions)); + return copy; + } + /** * @return the actions */ @@ -69,4 +76,4 @@ public class ActionStateModel extends AbstractTransitionableStateModel { this.actions = actions; } -} \ No newline at end of file +} diff --git a/spring-webflow/src/main/java/org/springframework/webflow/engine/model/AttributeModel.java b/spring-webflow/src/main/java/org/springframework/webflow/engine/model/AttributeModel.java index cd737615..01b25354 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/engine/model/AttributeModel.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/engine/model/AttributeModel.java @@ -57,6 +57,12 @@ public class AttributeModel extends AbstractModel { setType(merge(getType(), attribute.getType())); } + public Model createCopy() { + AttributeModel copy = new AttributeModel(name, value); + copy.setType(type); + return copy; + } + /** * @return the name */ diff --git a/spring-webflow/src/main/java/org/springframework/webflow/engine/model/BeanImportModel.java b/spring-webflow/src/main/java/org/springframework/webflow/engine/model/BeanImportModel.java index 3d916caa..1dc1b6fb 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/engine/model/BeanImportModel.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/engine/model/BeanImportModel.java @@ -45,7 +45,11 @@ public class BeanImportModel extends AbstractModel { } - /** + public Model createCopy() { + return new BeanImportModel(resource); + } + + /** * @return the resource */ public String getResource() { diff --git a/spring-webflow/src/main/java/org/springframework/webflow/engine/model/BinderModel.java b/spring-webflow/src/main/java/org/springframework/webflow/engine/model/BinderModel.java index 9c8c3e8b..77a4d3b9 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/engine/model/BinderModel.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/engine/model/BinderModel.java @@ -42,4 +42,9 @@ public class BinderModel extends AbstractModel { setBindings(merge(getBindings(), binder.getBindings())); } -} \ No newline at end of file + public Model createCopy() { + BinderModel copy = new BinderModel(); + copy.setBindings(copyList(bindings)); + return copy; + } +} diff --git a/spring-webflow/src/main/java/org/springframework/webflow/engine/model/BindingModel.java b/spring-webflow/src/main/java/org/springframework/webflow/engine/model/BindingModel.java index e9e4bed4..efac4205 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/engine/model/BindingModel.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/engine/model/BindingModel.java @@ -56,7 +56,11 @@ public class BindingModel extends AbstractModel { setRequired(merge(getRequired(), binding.getRequired())); } - public String getProperty() { + public Model createCopy() { + return new BindingModel(property, converter, required); + } + + public String getProperty() { return property; } diff --git a/spring-webflow/src/main/java/org/springframework/webflow/engine/model/DecisionStateModel.java b/spring-webflow/src/main/java/org/springframework/webflow/engine/model/DecisionStateModel.java index 86719bb9..c7d67eb9 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/engine/model/DecisionStateModel.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/engine/model/DecisionStateModel.java @@ -56,6 +56,14 @@ public class DecisionStateModel extends AbstractStateModel { setOnExitActions(merge(getOnExitActions(), state.getOnExitActions(), false)); } + public Model createCopy() { + DecisionStateModel copy = new DecisionStateModel(getId()); + super.fillCopy(copy); + copy.setIfs(copyList(ifs)); + copy.setOnExitActions(copyList(onExitActions)); + return copy; + } + /** * @return the ifs */ @@ -84,4 +92,4 @@ public class DecisionStateModel extends AbstractStateModel { this.onExitActions = onExitActions; } -} \ No newline at end of file +} diff --git a/spring-webflow/src/main/java/org/springframework/webflow/engine/model/EndStateModel.java b/spring-webflow/src/main/java/org/springframework/webflow/engine/model/EndStateModel.java index 98b46ad6..e5bc0107 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/engine/model/EndStateModel.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/engine/model/EndStateModel.java @@ -60,6 +60,15 @@ public class EndStateModel extends AbstractStateModel { setOutputs(merge(getOutputs(), state.getOutputs(), false)); } + public Model createCopy() { + EndStateModel copy = new EndStateModel(getId()); + super.fillCopy(copy); + copy.setView(view); + copy.setCommit(commit); + copy.setOutputs(outputs); + return copy; + } + /** * @return the view */ diff --git a/spring-webflow/src/main/java/org/springframework/webflow/engine/model/EvaluateModel.java b/spring-webflow/src/main/java/org/springframework/webflow/engine/model/EvaluateModel.java index 60741293..a0d8d295 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/engine/model/EvaluateModel.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/engine/model/EvaluateModel.java @@ -40,6 +40,14 @@ public class EvaluateModel extends AbstractActionModel { setExpression(expression); } + public Model createCopy() { + EvaluateModel copy = new EvaluateModel(expression); + super.fillCopy(copy); + copy.setResult(result); + copy.setResultType(resultType); + return copy; + } + /** * @return the expression */ diff --git a/spring-webflow/src/main/java/org/springframework/webflow/engine/model/ExceptionHandlerModel.java b/spring-webflow/src/main/java/org/springframework/webflow/engine/model/ExceptionHandlerModel.java index e756874d..897470d1 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/engine/model/ExceptionHandlerModel.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/engine/model/ExceptionHandlerModel.java @@ -43,7 +43,11 @@ public class ExceptionHandlerModel extends AbstractModel { public void merge(Model model) { } - public String getBean() { + public Model createCopy() { + return new ExceptionHandlerModel(bean); + } + + public String getBean() { return bean; } diff --git a/spring-webflow/src/main/java/org/springframework/webflow/engine/model/FlowModel.java b/spring-webflow/src/main/java/org/springframework/webflow/engine/model/FlowModel.java index 6c884501..7ad16d64 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/engine/model/FlowModel.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/engine/model/FlowModel.java @@ -35,8 +35,7 @@ import org.springframework.util.StringUtils; *
@@ -225,4 +225,4 @@ public class TransitionModel extends AbstractModel { public void setActions(LinkedList actions) { this.actions = actions; } -} \ No newline at end of file +} diff --git a/spring-webflow/src/main/java/org/springframework/webflow/engine/model/VarModel.java b/spring-webflow/src/main/java/org/springframework/webflow/engine/model/VarModel.java index 380f20c4..509529e9 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/engine/model/VarModel.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/engine/model/VarModel.java @@ -55,7 +55,11 @@ public class VarModel extends AbstractModel { setClassName(merge(getClassName(), var.getClassName())); } - /** + public Model createCopy() { + return new VarModel(name, className); + } + + /** * @return the name */ public String getName() { diff --git a/spring-webflow/src/main/java/org/springframework/webflow/engine/model/ViewStateModel.java b/spring-webflow/src/main/java/org/springframework/webflow/engine/model/ViewStateModel.java index e7017c95..81b7a77c 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/engine/model/ViewStateModel.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/engine/model/ViewStateModel.java @@ -75,6 +75,23 @@ public class ViewStateModel extends AbstractTransitionableStateModel { setOnRenderActions(merge(getOnRenderActions(), state.getOnRenderActions(), false)); } + public Model createCopy() { + ViewStateModel copy = new ViewStateModel(getId()); + super.fillCopy(copy); + copy.setView(view); + copy.setRedirect(redirect); + copy.setPopup(popup); + copy.setModel(model); + copy.setVars(copyList(vars)); + if (binder != null) { + copy.setBinder((BinderModel) binder.createCopy()); + } else { + copy.setBinder(null); + } + copy.setOnRenderActions(copyList(onRenderActions)); + return copy; + } + /** * @return the view */