aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClaude Brisson <claude@renegat.net>2022-07-25 08:14:15 +0200
committerClaude Brisson <claude@renegat.net>2022-07-25 08:14:15 +0200
commit051f20a8b7b76ecd9f773ac83aac138867aa0976 (patch)
tree6a13b93739c25159f5fe95753c89688f8b7e14da
parent304a539700032d276520da4c1f926fdbcffeddeb (diff)
downloadapache-velocity-engine-051f20a8b7b76ecd9f773ac83aac138867aa0976.tar.gz
Make templates cloneable - fixes VELOCITY-958
-rw-r--r--velocity-engine-core/src/main/java/org/apache/velocity/Template.java7
-rw-r--r--velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/SimpleNode.java41
-rw-r--r--velocity-engine-core/src/main/java/org/apache/velocity/runtime/resource/Resource.java28
3 files changed, 73 insertions, 3 deletions
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 <a href="mailto:geirm@optonline.net">Geir Magnusson Jr.</a>
* @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 <a href="mailto:geirm@optonline.net">Geir Magnusson Jr.</a>
* @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
+ }
}