From 051f20a8b7b76ecd9f773ac83aac138867aa0976 Mon Sep 17 00:00:00 2001 From: Claude Brisson Date: Mon, 25 Jul 2022 08:14:15 +0200 Subject: Make templates cloneable - fixes VELOCITY-958 --- .../main/java/org/apache/velocity/Template.java | 7 +++- .../velocity/runtime/parser/node/SimpleNode.java | 41 +++++++++++++++++++++- .../apache/velocity/runtime/resource/Resource.java | 28 ++++++++++++++- 3 files changed, 73 insertions(+), 3 deletions(-) (limited to 'velocity-engine-core') diff --git a/velocity-engine-core/src/main/java/org/apache/velocity/Template.java b/velocity-engine-core/src/main/java/org/apache/velocity/Template.java index c5c0e1e4..31cca192 100644 --- a/velocity-engine-core/src/main/java/org/apache/velocity/Template.java +++ b/velocity-engine-core/src/main/java/org/apache/velocity/Template.java @@ -65,7 +65,7 @@ import java.util.concurrent.ConcurrentHashMap; * @author Geir Magnusson Jr. * @version $Id$ */ -public class Template extends Resource +public class Template extends Resource implements Cloneable { /* * The name of the variable to use when placing @@ -433,4 +433,9 @@ public class Template extends Resource throw ve; } } + + @Override + protected void deepCloneData() throws CloneNotSupportedException { + setData(((SimpleNode)data).clone(this)); + } } diff --git a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/SimpleNode.java b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/SimpleNode.java index ac9f7da8..f85d6926 100644 --- a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/SimpleNode.java +++ b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/SimpleNode.java @@ -44,7 +44,7 @@ import org.slf4j.Logger; /** * */ -public class SimpleNode implements Node +public class SimpleNode implements Node, Cloneable { /** */ protected RuntimeServices rsvc = null; @@ -608,4 +608,43 @@ public class SimpleNode implements Node { return parser; } + + /** + * Root node deep cloning + * @param template owner template + * @return cloned node + * @throws CloneNotSupportedException + * @since 2.4 + */ + public Node clone(Template template) throws CloneNotSupportedException + { + if (parent != null) { + throw new IllegalStateException("cannot clone a child node without knowing its parent"); + } + return clone(template, null); + } + + /** + * Child node deep cloning + * @param template owner template + * @param parent parent node + * @return cloned node + * @throws CloneNotSupportedException + * @since 2.4 + */ + protected Node clone(Template template, Node parent) throws CloneNotSupportedException + { + SimpleNode clone = (SimpleNode)super.clone(); + clone.template = template; + clone.parent = parent; + if (children != null) + { + clone.children = new SimpleNode[children.length]; + for (int i = 0; i < children.length; ++i) + { + clone.children[i] = ((SimpleNode)children[i]).clone(template, clone); + } + } + return clone; + } } diff --git a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/resource/Resource.java b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/resource/Resource.java index faf93a62..5922604d 100644 --- a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/resource/Resource.java +++ b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/resource/Resource.java @@ -35,7 +35,7 @@ import org.slf4j.Logger; * @author Geir Magnusson Jr. * @version $Id$ */ -public abstract class Resource +public abstract class Resource implements Cloneable { protected RuntimeServices rsvc = null; protected Logger log = null; @@ -291,4 +291,30 @@ public abstract class Resource { return type; } + + /** + * @return cloned resource + * @since 2.4 + */ + @Override + public Object clone() { + try + { + Resource clone = (Resource) super.clone(); + clone.deepCloneData(); + return clone; + } + catch (CloneNotSupportedException e) { + throw new RuntimeException("cloning not supported"); + } + } + + /** + * Deep cloning of resource data + * @return cloned data + */ + protected void deepCloneData() throws CloneNotSupportedException + { + // default implementation does nothing + } } -- cgit v1.2.3