Author: cbrisson
Date: Wed Jun 12 00:58:53 2019
New Revision: 1861084
URL: http://svn.apache.org/viewvc?rev=1861084&view=rev
Log:
[engine][VELOCITY-917] Merge changes from trunk
Modified:
velocity/engine/branches/parser_experiments/ (props changed)
velocity/engine/branches/parser_experiments/src/changes/changes.xml
velocity/engine/branches/parser_experiments/velocity-engine-core/src/main/java/
(props changed)
velocity/engine/branches/parser_experiments/velocity-engine-core/src/main/java/org/apache/velocity/app/event/implement/ReportInvalidReferences.java
velocity/engine/branches/parser_experiments/velocity-engine-core/src/main/java/org/apache/velocity/runtime/RuntimeConstants.java
velocity/engine/branches/parser_experiments/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTReference.java
velocity/engine/branches/parser_experiments/velocity-engine-core/src/main/parser/Parser.jjt
velocity/engine/branches/parser_experiments/velocity-engine-core/src/test/java/
(props changed)
velocity/engine/branches/parser_experiments/velocity-engine-core/src/test/java/org/apache/velocity/test/BuiltInEventHandlerTestCase.java
Propchange: velocity/engine/branches/parser_experiments/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Wed Jun 12 00:58:53 2019
@@ -2,4 +2,4 @@
/velocity/engine/branches/VELOCITY-892:1844076-1854372
/velocity/engine/branches/VELOCITY-898:1843220-1843786
/velocity/engine/branches/VELOCITY-909:1854851-1855185
-/velocity/engine/trunk:992133,1032159
+/velocity/engine/trunk:992133,1032159,1860001-1861083
Modified: velocity/engine/branches/parser_experiments/src/changes/changes.xml
URL:
http://svn.apache.org/viewvc/velocity/engine/branches/parser_experiments/src/changes/changes.xml?rev=1861084&r1=1861083&r2=1861084&view=diff
==============================================================================
--- velocity/engine/branches/parser_experiments/src/changes/changes.xml
(original)
+++ velocity/engine/branches/parser_experiments/src/changes/changes.xml Wed Jun
12 00:58:53 2019
@@ -25,10 +25,23 @@
</properties>
<body>
+ <release version="2.2" date="Not yet released">
+ <action type="add" dev="cbrisson" issue="VELOCITY-916">
+ Implement template location tracking with slf4j MDC tags; disabled
by default, activated
+ with <code>runtime.log.track_location</code>. Once activated, an
MDC-aware logger will be
+ able to display the <code>file</code>, <code>line</code> and
<code>column</code> MDC tags
+ </action>
+ <action type="fix" dev="cbrisson">
+ Introspection: favor non-vararg methods on ambiguities as does the
Java compiler
+ </action>
+ <action type="fix" dev="cbrisson" issue="VELOCITY-912">
+ Also allow hyphen in subproperties when the corresponding backward
compatibility flag is on
+ </action>
+ </release>
<release version="2.1" date="2019-03-15">
<action type="fix" dev="cbrisson" issue="VELOCITY-909">
Reorganization of configuration properties key names, for clarity
and consistency,
- see the <a href="configuration-property-changes-in-2.1.html">table
of correspondance</a>.
+ see the <a href="configuration-property-changes-in-2.1.html">table
of correspondance</a>
</action>
<action type="fix" dev="cbrisson">
Rendering of arrays should display their content, as for lists
Propchange:
velocity/engine/branches/parser_experiments/velocity-engine-core/src/main/java/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Wed Jun 12 00:58:53 2019
@@ -4,3 +4,4 @@
/velocity/engine/branches/VELOCITY-898/velocity-engine-core/src/main/java:1843220-1843786
/velocity/engine/branches/VELOCITY-909/velocity-engine-core/src/main/java:1854851-1855185
/velocity/engine/trunk/src/java:1032134
+/velocity/engine/trunk/velocity-engine-core/src/main/java:1860001-1861083
Modified:
velocity/engine/branches/parser_experiments/velocity-engine-core/src/main/java/org/apache/velocity/app/event/implement/ReportInvalidReferences.java
URL:
http://svn.apache.org/viewvc/velocity/engine/branches/parser_experiments/velocity-engine-core/src/main/java/org/apache/velocity/app/event/implement/ReportInvalidReferences.java?rev=1861084&r1=1861083&r2=1861084&view=diff
==============================================================================
---
velocity/engine/branches/parser_experiments/velocity-engine-core/src/main/java/org/apache/velocity/app/event/implement/ReportInvalidReferences.java
(original)
+++
velocity/engine/branches/parser_experiments/velocity-engine-core/src/main/java/org/apache/velocity/app/event/implement/ReportInvalidReferences.java
Wed Jun 12 00:58:53 2019
@@ -25,6 +25,7 @@ import org.apache.velocity.exception.Par
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 imp
*/
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();
}
}
Modified:
velocity/engine/branches/parser_experiments/velocity-engine-core/src/main/java/org/apache/velocity/runtime/RuntimeConstants.java
URL:
http://svn.apache.org/viewvc/velocity/engine/branches/parser_experiments/velocity-engine-core/src/main/java/org/apache/velocity/runtime/RuntimeConstants.java?rev=1861084&r1=1861083&r2=1861084&view=diff
==============================================================================
---
velocity/engine/branches/parser_experiments/velocity-engine-core/src/main/java/org/apache/velocity/runtime/RuntimeConstants.java
(original)
+++
velocity/engine/branches/parser_experiments/velocity-engine-core/src/main/java/org/apache/velocity/runtime/RuntimeConstants.java
Wed Jun 12 00:58:53 2019
@@ -274,6 +274,30 @@ public interface RuntimeConstants extend
*/
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";
/*
* ----------------------------------------------------------------------
Modified:
velocity/engine/branches/parser_experiments/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTReference.java
URL:
http://svn.apache.org/viewvc/velocity/engine/branches/parser_experiments/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTReference.java?rev=1861084&r1=1861083&r2=1861084&view=diff
==============================================================================
---
velocity/engine/branches/parser_experiments/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTReference.java
(original)
+++
velocity/engine/branches/parser_experiments/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTReference.java
Wed Jun 12 00:58:53 2019
@@ -102,6 +102,25 @@ public class ASTReference extends Simple
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 Simple
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,25 +301,30 @@ public class ASTReference extends Simple
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,
rsvc.dollar() + rootString, null, null, uberInfo);
}
- if (result == null && astAlternateValue != null)
- {
- result = astAlternateValue.value(context);
- }
-
return result;
}
@@ -311,6 +345,7 @@ public class ASTReference extends Simple
{
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 Simple
}
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 Simple
* 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,
rsvc.dollar() + rootString,
previousResult, null, uberInfo);
@@ -357,9 +398,9 @@ public class ASTReference extends Simple
// (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(String.valueOf(rsvc.dollar())).append(rootString);
for (int i = 0; i <= failedChild; i++)
@@ -391,14 +432,6 @@ public class ASTReference extends Simple
}
}
- /*
- * 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)
Modified:
velocity/engine/branches/parser_experiments/velocity-engine-core/src/main/parser/Parser.jjt
URL:
http://svn.apache.org/viewvc/velocity/engine/branches/parser_experiments/velocity-engine-core/src/main/parser/Parser.jjt?rev=1861084&r1=1861083&r2=1861084&view=diff
==============================================================================
---
velocity/engine/branches/parser_experiments/velocity-engine-core/src/main/parser/Parser.jjt
(original)
+++
velocity/engine/branches/parser_experiments/velocity-engine-core/src/main/parser/Parser.jjt
Wed Jun 12 00:58:53 2019
@@ -106,7 +106,7 @@ import org.slf4j.Logger;
* @author <a href="mailto:[email protected]">Jason van Zyl</a>
* @author <a href="mailto:[email protected]">Geir Magnusson Jr.</a>
* @author <a href="[email protected]">Henning P. Schmiedehausen</a>
- * @version $Id: $
+ * @version $Id$
*/
public class ${parser.name}Parser implements
org.apache.velocity.runtime.parser.Parser
{
Propchange:
velocity/engine/branches/parser_experiments/velocity-engine-core/src/test/java/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Wed Jun 12 00:58:53 2019
@@ -4,4 +4,4 @@
/velocity/engine/branches/VELOCITY-898/velocity-engine-core/src/test/java:1843220-1843786
/velocity/engine/branches/VELOCITY-909/velocity-engine-core/src/test/java:1854851-1855185
/velocity/engine/trunk/src/test:1032134
-/velocity/engine/trunk/velocity-engine-core/src/test/java:992133,1032159
+/velocity/engine/trunk/velocity-engine-core/src/test/java:992133,1032159,1860001-1861083
Modified:
velocity/engine/branches/parser_experiments/velocity-engine-core/src/test/java/org/apache/velocity/test/BuiltInEventHandlerTestCase.java
URL:
http://svn.apache.org/viewvc/velocity/engine/branches/parser_experiments/velocity-engine-core/src/test/java/org/apache/velocity/test/BuiltInEventHandlerTestCase.java?rev=1861084&r1=1861083&r2=1861084&view=diff
==============================================================================
---
velocity/engine/branches/parser_experiments/velocity-engine-core/src/test/java/org/apache/velocity/test/BuiltInEventHandlerTestCase.java
(original)
+++
velocity/engine/branches/parser_experiments/velocity-engine-core/src/test/java/org/apache/velocity/test/BuiltInEventHandlerTestCase.java
Wed Jun 12 00:58:53 2019
@@ -128,9 +128,10 @@ public class BuiltInEventHandlerTestCase
context.put("a1","test");
context.put("b1","test");
+ context.put("n1", null);
Writer writer = new StringWriter();
- ve.evaluate(context,writer,"test","$a1 $c1 $a1.length() $a1.foobar()");
+ ve.evaluate(context,writer,"test","$a1 $c1 $a1.length() $a1.foobar()
$!c1 $n1 $!n1 #if($c1) nop #end");
List errors = reporter.getInvalidReferences();
assertEquals(2,errors.size());
@@ -143,7 +144,7 @@ public class BuiltInEventHandlerTestCase
public void testReportInvalidReferences2() throws Exception
{
VelocityEngine ve = new VelocityEngine();
- ve.setProperty("eventhandler.invalidreference.exception","true");
+ ve.setProperty("event_handler.invalid_references.exception","true");
ReportInvalidReferences reporter = new ReportInvalidReferences();
ve.init();
@@ -169,6 +170,137 @@ public class BuiltInEventHandlerTestCase
}
/**
+ * Test reporting of invalid syntax
+ * @throws Exception
+ */
+ public void testReportQuietInvalidReferences() throws Exception
+ {
+ VelocityEngine ve = new VelocityEngine();
+ ve.setProperty("event_handler.invalid_references.quiet","true");
+ ReportInvalidReferences reporter = new ReportInvalidReferences();
+ ve.init();
+
+ VelocityContext context = new VelocityContext();
+ EventCartridge ec = new EventCartridge();
+ ec.addEventHandler(reporter);
+ ec.attachToContext(context);
+
+ context.put("a1","test");
+ context.put("b1","test");
+ context.put("n1", null);
+ Writer writer = new StringWriter();
+
+ ve.evaluate(context,writer,"test","$a1 $c1 $a1.length() $a1.foobar()
$!c1 $n1 $!n1 #if($c1) nop #end");
+
+ List errors = reporter.getInvalidReferences();
+ assertEquals(3,errors.size());
+ assertEquals("$c1",((InvalidReferenceInfo)
errors.get(0)).getInvalidReference());
+ assertEquals("$a1.foobar()",((InvalidReferenceInfo)
errors.get(1)).getInvalidReference());
+ assertEquals("$c1",((InvalidReferenceInfo)
errors.get(2)).getInvalidReference());
+
+ log("Caught invalid references (local configuration).");
+ }
+
+ /**
+ * Test reporting of invalid syntax
+ * @throws Exception
+ */
+ public void testReportNullInvalidReferences() throws Exception
+ {
+ VelocityEngine ve = new VelocityEngine();
+ ve.setProperty("event_handler.invalid_references.null","true");
+ ReportInvalidReferences reporter = new ReportInvalidReferences();
+ ve.init();
+
+ VelocityContext context = new VelocityContext();
+ EventCartridge ec = new EventCartridge();
+ ec.addEventHandler(reporter);
+ ec.attachToContext(context);
+
+ context.put("a1","test");
+ context.put("b1","test");
+ context.put("n1", null);
+ Writer writer = new StringWriter();
+
+ ve.evaluate(context,writer,"test","$a1 $c1 $a1.length() $a1.foobar()
$!c1 $n1 $!n1 #if($c1) nop #end");
+
+ List errors = reporter.getInvalidReferences();
+ assertEquals(3,errors.size());
+ assertEquals("$c1",((InvalidReferenceInfo)
errors.get(0)).getInvalidReference());
+ assertEquals("$a1.foobar()",((InvalidReferenceInfo)
errors.get(1)).getInvalidReference());
+ assertEquals("$n1",((InvalidReferenceInfo)
errors.get(2)).getInvalidReference());
+
+ log("Caught invalid references (local configuration).");
+ }
+
+ /**
+ * Test reporting of invalid syntax
+ * @throws Exception
+ */
+ public void testReportNullQuietInvalidReferences() throws Exception
+ {
+ VelocityEngine ve = new VelocityEngine();
+ ve.setProperty("event_handler.invalid_references.quiet","true");
+ ve.setProperty("event_handler.invalid_references.null","true");
+ ReportInvalidReferences reporter = new ReportInvalidReferences();
+ ve.init();
+
+ VelocityContext context = new VelocityContext();
+ EventCartridge ec = new EventCartridge();
+ ec.addEventHandler(reporter);
+ ec.attachToContext(context);
+
+ context.put("a1","test");
+ context.put("b1","test");
+ context.put("n1", null);
+ Writer writer = new StringWriter();
+
+ ve.evaluate(context,writer,"test","$a1 $c1 $a1.length() $a1.foobar()
$!c1 $n1 $!n1 #if($c1) nop #end");
+
+ List errors = reporter.getInvalidReferences();
+ assertEquals(5,errors.size());
+ assertEquals("$c1",((InvalidReferenceInfo)
errors.get(0)).getInvalidReference());
+ assertEquals("$a1.foobar()",((InvalidReferenceInfo)
errors.get(1)).getInvalidReference());
+ assertEquals("$c1",((InvalidReferenceInfo)
errors.get(2)).getInvalidReference());
+ assertEquals("$n1",((InvalidReferenceInfo)
errors.get(3)).getInvalidReference());
+ assertEquals("$n1",((InvalidReferenceInfo)
errors.get(4)).getInvalidReference());
+
+ log("Caught invalid references (local configuration).");
+ }
+
+ /**
+ * Test reporting of invalid syntax
+ * @throws Exception
+ */
+ public void testReportTestedInvalidReferences() throws Exception
+ {
+ VelocityEngine ve = new VelocityEngine();
+ ve.setProperty("event_handler.invalid_references.tested","true");
+ ReportInvalidReferences reporter = new ReportInvalidReferences();
+ ve.init();
+
+ VelocityContext context = new VelocityContext();
+ EventCartridge ec = new EventCartridge();
+ ec.addEventHandler(reporter);
+ ec.attachToContext(context);
+
+ context.put("a1","test");
+ context.put("b1","test");
+ context.put("n1", null);
+ Writer writer = new StringWriter();
+
+ ve.evaluate(context,writer,"test","$a1 $c1 $a1.length() $a1.foobar()
$!c1 $n1 $!n1 #if($c1) nop #end");
+
+ List errors = reporter.getInvalidReferences();
+ assertEquals(3,errors.size());
+ assertEquals("$c1",((InvalidReferenceInfo)
errors.get(0)).getInvalidReference());
+ assertEquals("$a1.foobar()",((InvalidReferenceInfo)
errors.get(1)).getInvalidReference());
+ assertEquals("$c1",((InvalidReferenceInfo)
errors.get(2)).getInvalidReference());
+
+ log("Caught invalid references (local configuration).");
+ }
+
+ /**
* Test escaping
* @throws Exception
*/