diff options
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 + } } |