aboutsummaryrefslogtreecommitdiff
path: root/velocity-engine-core/src/main/java/org
diff options
context:
space:
mode:
authorClaude Brisson <cbrisson@apache.org>2019-06-05 23:46:02 +0000
committerClaude Brisson <cbrisson@apache.org>2019-06-05 23:46:02 +0000
commite1e494870d13a58cc23a6209aac6e0fe67dae1cc (patch)
tree70e6b539755673095107c43a75dbfa6e1a4f794b /velocity-engine-core/src/main/java/org
parent41bd49095236a247202c9411fc1d089a7b61e503 (diff)
downloadapache-velocity-engine-e1e494870d13a58cc23a6209aac6e0fe67dae1cc.tar.gz
[engine][VELOCITY-915] Add new backward compatibility flags to mimic 1.7 behavior for invalid references event handlers
git-svn-id: https://svn.apache.org/repos/asf/velocity/engine/trunk@1860691 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'velocity-engine-core/src/main/java/org')
-rw-r--r--velocity-engine-core/src/main/java/org/apache/velocity/app/event/implement/ReportInvalidReferences.java20
-rw-r--r--velocity-engine-core/src/main/java/org/apache/velocity/runtime/RuntimeConstants.java24
-rw-r--r--velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTReference.java75
3 files changed, 93 insertions, 26 deletions
diff --git a/velocity-engine-core/src/main/java/org/apache/velocity/app/event/implement/ReportInvalidReferences.java b/velocity-engine-core/src/main/java/org/apache/velocity/app/event/implement/ReportInvalidReferences.java
index 42ffa919..c76aa17b 100644
--- a/velocity-engine-core/src/main/java/org/apache/velocity/app/event/implement/ReportInvalidReferences.java
+++ b/velocity-engine-core/src/main/java/org/apache/velocity/app/event/implement/ReportInvalidReferences.java
@@ -25,6 +25,7 @@ import org.apache.velocity.exception.ParseErrorException;
import org.apache.velocity.runtime.RuntimeServices;
import org.apache.velocity.util.RuntimeServicesAware;
import org.apache.velocity.util.introspection.Info;
+import org.slf4j.Logger;
import java.util.ArrayList;
import java.util.List;
@@ -39,7 +40,7 @@ import java.util.List;
* Note that InvalidReferenceHandler can be used
* in two modes. If the Velocity properties file contains the following:
* <pre>
- * eventhandler.invalidreference.exception = true
+ * event_handler.invalid_references.exception = true
* </pre>
* then the event handler will throw a ParseErrorRuntimeException upon
* hitting the first invalid reference. This stops processing and is
@@ -61,8 +62,10 @@ import java.util.List;
public class ReportInvalidReferences implements
InvalidReferenceEventHandler, RuntimeServicesAware
{
+ public static final String EVENTHANDLER_INVALIDREFERENCE_EXCEPTION = "event_handler.invalid_references.exception";
- public static final String EVENTHANDLER_INVALIDREFERENCE_EXCEPTION = "eventhandler.invalidreference.exception";
+ @Deprecated
+ public static final String OLD_EVENTHANDLER_INVALIDREFERENCE_EXCEPTION = "eventhandler.invalidreference.exception";
/**
* List of InvalidReferenceInfo objects
@@ -172,9 +175,16 @@ public class ReportInvalidReferences implements
*/
public void setRuntimeServices(RuntimeServices rs)
{
- stopOnFirstInvalidReference = rs.getConfiguration().getBoolean(
- EVENTHANDLER_INVALIDREFERENCE_EXCEPTION,
- false);
+ Boolean b = rs.getConfiguration().getBoolean(OLD_EVENTHANDLER_INVALIDREFERENCE_EXCEPTION, null);
+ if (b == null)
+ {
+ b = rs.getConfiguration().getBoolean(EVENTHANDLER_INVALIDREFERENCE_EXCEPTION, false);
+ }
+ else
+ {
+ rs.getLog().warn("configuration key '{}' has been deprecated in favor of '{}'", OLD_EVENTHANDLER_INVALIDREFERENCE_EXCEPTION, EVENTHANDLER_INVALIDREFERENCE_EXCEPTION);
+ }
+ stopOnFirstInvalidReference = b.booleanValue();
}
}
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 27782632..c4d59ef2 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
@@ -274,6 +274,30 @@ public interface RuntimeConstants extends DeprecatedRuntimeConstants
*/
String EVENTHANDLER_INVALIDREFERENCES = "event_handler.invalid_references.class";
+ /**
+ * The <code>event_handler.invalid_references.quiet</code> property specifies if invalid quiet references
+ * (as in <code>$!foo</code>) trigger events (defaults to false).
+ * {@link org.apache.velocity.app.event.InvalidReferenceEventHandler} implementations to use.
+ * @since 2.2
+ */
+ String EVENTHANDLER_INVALIDREFERENCES_QUIET = "event_handler.invalid_references.quiet";
+
+ /**
+ * The <code>event_handler.invalid_references.null</code> property specifies if invalid null references
+ * (aka the value is present in the context or parent object but is null or a method returned null)
+ * trigger invalid reference events (defaults to false).
+ * {@link org.apache.velocity.app.event.InvalidReferenceEventHandler} implementations to use.
+ * @since 2.2
+ */
+ String EVENTHANDLER_INVALIDREFERENCES_NULL = "event_handler.invalid_references.null";
+
+ /**
+ * The <code>event_handler.invalid_references.tested</code> property specifies if invalid tested references
+ * (as in <code>#if($foo)</code> ) trigger invalid reference events (defaults to false).
+ * {@link org.apache.velocity.app.event.InvalidReferenceEventHandler} implementations to use.
+ * @since 2.2
+ */
+ String EVENTHANDLER_INVALIDREFERENCES_TESTED = "event_handler.invalid_references.tested";
/*
* ----------------------------------------------------------------------
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 058dff39..e78e1463 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
@@ -102,6 +102,25 @@ public class ASTReference extends SimpleNode
private int numChildren = 0;
+ /**
+ * Whether to trigger an event for invalid quiet references
+ * @since 2.2
+ */
+ private boolean warnInvalidQuietReferences = false;
+
+ /**
+ * Whether to trigger an event for invalid null references, that is when a value
+ * is present in the context or parent object but is null
+ * @since 2.2
+ */
+ private boolean warnInvalidNullReferences = false;
+
+ /**
+ * Whether to trigger an event for invalid tested references - as in #if($foo)
+ * @since 2.2
+ */
+ private boolean warnInvalidTestedReferences = false;
+
protected Info uberInfo;
/**
@@ -196,6 +215,16 @@ public class ASTReference extends SimpleNode
checkEmpty =
rsvc.getBoolean(RuntimeConstants.CHECK_EMPTY_OBJECTS, true);
+ /* invalid references special cases */
+
+ warnInvalidQuietReferences =
+ rsvc.getBoolean(RuntimeConstants.EVENTHANDLER_INVALIDREFERENCES_QUIET, false);
+ warnInvalidNullReferences =
+ rsvc.getBoolean(RuntimeConstants.EVENTHANDLER_INVALIDREFERENCES_NULL, false);
+ warnInvalidTestedReferences =
+ rsvc.getBoolean(RuntimeConstants.EVENTHANDLER_INVALIDREFERENCES_TESTED, false);
+
+
/**
* In the case we are referencing a variable with #if($foo) or
* #if( ! $foo) then we allow variables to be undefined and we
@@ -272,23 +301,28 @@ public class ASTReference extends SimpleNode
Object result = getRootVariableValue(context);
+ /* a reference which has been provided an alternate value
+ * is *knowingly* potentially null and should be accepted
+ * in strict mode (except if the alternate value is null)
+ */
+ if (astAlternateValue != null && (result == null || !DuckType.asBoolean(result, false)))
+ {
+ result = astAlternateValue.value(context);
+ }
+
if (result == null && !strictRef)
{
/*
* do not trigger an invalid reference if the reference is present, but with a null value
* don't either for a quiet reference or inside an #if/#elseif evaluation context
*/
- if (referenceType != QUIET_REFERENCE &&
- (numChildren > 0 ||
- !context.containsKey(rootString) && !onlyTestingReference))
+ if ((referenceType != QUIET_REFERENCE || warnInvalidQuietReferences) &&
+ (numChildren > 0 ||
+ (!context.containsKey(rootString) || warnInvalidNullReferences) &&
+ (!onlyTestingReference || warnInvalidTestedReferences)))
{
result = EventHandlerUtil.invalidGetMethod(rsvc, context,
- "$" + rootString, null, null, uberInfo);
- }
-
- if (result == null && astAlternateValue != null)
- {
- result = astAlternateValue.value(context);
+ "$" + rootString, null, null, uberInfo);
}
return result;
@@ -311,6 +345,7 @@ public class ASTReference extends SimpleNode
{
Object previousResult = result;
int failedChild = -1;
+
for (int i = 0; i < numChildren; i++)
{
if (strictRef && result == null)
@@ -327,6 +362,10 @@ public class ASTReference extends SimpleNode
}
previousResult = result;
result = jjtGetChild(i).execute(result,context);
+ if (astAlternateValue != null && (result == null || !DuckType.asBoolean(result, checkEmpty)))
+ {
+ result = astAlternateValue.value(context);
+ }
if (result == null && !strictRef) // If strict and null then well catch this
// next time through the loop
{
@@ -344,7 +383,9 @@ public class ASTReference extends SimpleNode
* don't either for a quiet reference,
* or inside an #if/#elseif evaluation context when there's no child
*/
- if (!context.containsKey(rootString) && referenceType != QUIET_REFERENCE && (!onlyTestingReference || numChildren > 0))
+ if ((!context.containsKey(rootString) || warnInvalidNullReferences) &&
+ (referenceType != QUIET_REFERENCE || warnInvalidQuietReferences) &&
+ (!onlyTestingReference || warnInvalidTestedReferences || numChildren > 0))
{
result = EventHandlerUtil.invalidGetMethod(rsvc, context,
"$" + rootString, previousResult, null, uberInfo);
@@ -357,9 +398,9 @@ public class ASTReference extends SimpleNode
// (it means the getter has been called and returned null)
// do not either for a quiet reference or if the *last* child failed while testing the reference
Object getter = context.icacheGet(child);
- if (getter == null &&
- referenceType != QUIET_REFERENCE &&
- (!onlyTestingReference || failedChild < numChildren - 1))
+ if ((getter == null || warnInvalidNullReferences) &&
+ (referenceType != QUIET_REFERENCE || warnInvalidQuietReferences) &&
+ (!onlyTestingReference || warnInvalidTestedReferences || failedChild < numChildren - 1))
{
StringBuilder name = new StringBuilder("$").append(rootString);
for (int i = 0; i <= failedChild; i++)
@@ -391,14 +432,6 @@ public class ASTReference extends SimpleNode
}
}
- /*
- * Time to try the alternate value if needed
- */
- if (astAlternateValue != null && (result == null || !DuckType.asBoolean(result, checkEmpty)))
- {
- result = astAlternateValue.value(context);
- }
-
return result;
}
catch(MethodInvocationException mie)