aboutsummaryrefslogtreecommitdiff
path: root/velocity-engine-core/src/main/java/org/apache/velocity/runtime
diff options
context:
space:
mode:
authorClaude Brisson <cbrisson@apache.org>2018-10-15 13:08:41 +0000
committerClaude Brisson <cbrisson@apache.org>2018-10-15 13:08:41 +0000
commitd0b749b76cfd4dd040c6d5e6274990fa858e50b0 (patch)
treec6dcd15050ec7b8b83f3cb4d5e4ebe28b5cd4ff2 /velocity-engine-core/src/main/java/org/apache/velocity/runtime
parenta684e7eff5be127e100e9b43ac897ee414ca8937 (diff)
downloadapache-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')
-rw-r--r--velocity-engine-core/src/main/java/org/apache/velocity/runtime/RuntimeConstants.java10
-rw-r--r--velocity-engine-core/src/main/java/org/apache/velocity/runtime/VelocimacroManager.java2
-rw-r--r--velocity-engine-core/src/main/java/org/apache/velocity/runtime/directive/VelocimacroProxy.java33
-rw-r--r--velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTReference.java17
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;
}
/**