diff options
author | Claude Brisson <cbrisson@apache.org> | 2018-10-15 13:08:41 +0000 |
---|---|---|
committer | Claude Brisson <cbrisson@apache.org> | 2018-10-15 13:08:41 +0000 |
commit | d0b749b76cfd4dd040c6d5e6274990fa858e50b0 (patch) | |
tree | c6dcd15050ec7b8b83f3cb4d5e4ebe28b5cd4ff2 /velocity-engine-core/src/main/java/org/apache/velocity/runtime | |
parent | a684e7eff5be127e100e9b43ac897ee414ca8937 (diff) | |
download | apache-velocity-engine-d0b749b76cfd4dd040c6d5e6274990fa858e50b0.tar.gz |
[VELOCITY-904] Added velocimacro.preserve.arguments.literals boolean flag (false by default) - if true, when printing null arguments, the macros will use the provided arguments literals
git-svn-id: https://svn.apache.org/repos/asf/velocity/engine/trunk@1843909 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'velocity-engine-core/src/main/java/org/apache/velocity/runtime')
4 files changed, 51 insertions, 11 deletions
diff --git a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/RuntimeConstants.java b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/RuntimeConstants.java index b042d7ab..59a10d5e 100644 --- a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/RuntimeConstants.java +++ b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/RuntimeConstants.java @@ -227,6 +227,13 @@ public interface RuntimeConstants */ String VM_BODY_REFERENCE = "velocimacro.body.reference"; + /** + * When displaying null or invalid non-quiet references, use the argument literal reference + * instead of the one in the macro block. Defaults to false. + * @since 2.1 + **/ + String VM_PRESERVE_ARGUMENTS_LITERALS = "velocimacro.preserve.arguments.literals"; + /* * ---------------------------------------------------------------------- * S T I C T M O D E B E H A V I O U R @@ -289,16 +296,19 @@ public interface RuntimeConstants /** * Allow dash in identifiers (backward compatibility option) + * @since 2.1 */ String PARSER_DASH_ALLOWED = "parser.allows.dash.in.identifiers"; /** * Space gobbling mode + * @since 2.0 */ String SPACE_GOBBLING = "space.gobbling"; /** * Space gobbling modes + * @since 2.0 */ enum SpaceGobbling { diff --git a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/VelocimacroManager.java b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/VelocimacroManager.java index a4b18153..994f47d6 100644 --- a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/VelocimacroManager.java +++ b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/VelocimacroManager.java @@ -323,11 +323,11 @@ public class VelocimacroManager this.sourceTemplate = sourceTemplate; vp = new VelocimacroProxy(); + vp.init(rsvc); vp.setName(this.vmName); vp.setMacroArgs(this.macroArgs); vp.setNodeTree(this.nodeTree); vp.setLocation(macro.getLine(), macro.getColumn(), macro.getTemplate()); - vp.init(rsvc); } /** diff --git a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/directive/VelocimacroProxy.java b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/directive/VelocimacroProxy.java index f0985a46..258e4fbd 100644 --- a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/directive/VelocimacroProxy.java +++ b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/directive/VelocimacroProxy.java @@ -52,6 +52,7 @@ public class VelocimacroProxy extends Directive private boolean strictArguments; private int maxCallDepth; private String bodyReference; + private boolean preserveArgumentsLiterals; /** * Return name of this Velocimacro. @@ -92,10 +93,13 @@ public class VelocimacroProxy extends Directive // for performance reasons we precache these strings - they are needed in // "render literal if null" functionality - literalArgArray = new String[macroArgs.size()]; - for(int i = 0; i < macroArgs.size(); i++) + if (preserveArgumentsLiterals) { - literalArgArray[i] = ".literal.$" + macroArgs.get(i); + literalArgArray = new String[macroArgs.size()]; + for (int i = 0; i < macroArgs.size(); i++) + { + literalArgArray[i] = ".literal.$" + macroArgs.get(i).name; + } } /* @@ -148,6 +152,8 @@ public class VelocimacroProxy extends Directive // get name of the reference that refers to AST block passed to block macro call bodyReference = rsvc.getString(RuntimeConstants.VM_BODY_REFERENCE, "bodyContent"); + + preserveArgumentsLiterals = rsvc.getBoolean(RuntimeConstants.VM_PRESERVE_ARGUMENTS_LITERALS, false); } public boolean render(InternalContextAdapter context, Writer writer, Node node) @@ -239,6 +245,15 @@ public class VelocimacroProxy extends Directive } } } + + if (preserveArgumentsLiterals) + { + for (String literalKey : literalArgArray) + { + // The behavior is not recursive. + context.remove(literalKey); + } + } } } @@ -299,7 +314,8 @@ public class VelocimacroProxy extends Directive /** * Gets the macro argument values and puts them in the context under * the argument names. Store and return an array of old and new values - * paired for each argument name, for later cleanup. + * paired for each argument name, for later cleanup. Also, put literal + * representations of arguments which evaluate to null in the context. */ protected Object[] handleArgValues(InternalContextAdapter context, Node node, int callArgNum) @@ -315,10 +331,12 @@ public class VelocimacroProxy extends Directive // put the new value in Object newVal = null; + Node argNode = null; if (i - 1 < callArgNum) { // There's a calling value. - newVal = node.jjtGetChild(i - 1).value(context); + argNode = node.jjtGetChild(i - 1); + newVal = argNode.value(context); } else if (macroArg.defaultVal != null) { @@ -349,6 +367,11 @@ public class VelocimacroProxy extends Directive context.put(macroArg.name, newVal); values[(i-1) * 2 + 1] = newVal; + + if (preserveArgumentsLiterals && newVal == null && argNode != null) + { + context.put(literalArgArray[i], argNode); + } } // return the array of replaced and new values diff --git a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTReference.java b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTReference.java index 8e1e4854..1b80e989 100644 --- a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTReference.java +++ b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTReference.java @@ -68,6 +68,7 @@ public class ASTReference extends SimpleNode private boolean escaped = false; private boolean computableReference = true; private boolean logOnNull = true; + private boolean lookupAlternateLiteral = false; private String escPrefix = ""; private String morePrefix = ""; private String identifier = ""; @@ -137,6 +138,7 @@ public class ASTReference extends SimpleNode strictEscape = rsvc.getBoolean(RuntimeConstants.RUNTIME_REFERENCES_STRICT_ESCAPE, false); strictRef = rsvc.getBoolean(RuntimeConstants.RUNTIME_REFERENCES_STRICT, false); + lookupAlternateLiteral = rsvc.getBoolean(RuntimeConstants.VM_PRESERVE_ARGUMENTS_LITERALS, false); /* * the only thing we can do in init() is getRoot() @@ -585,12 +587,17 @@ public class ASTReference extends SimpleNode */ private String getNullString(InternalContextAdapter context) { - Object callingArgument = context.get(".literal." + nullString); + String ret = nullString; - if (callingArgument != null) - return ((Node) callingArgument).literal(); - else - return nullString; + if (lookupAlternateLiteral) + { + Node callingArgument = (Node)context.get(".literal." + nullString); + if (callingArgument != null) + { + ret = ((Node) callingArgument).literal(); + } + } + return ret; } /** |