javavelocityapache-velocity

Apache Velocity: Verify if all variables in a context are present in velocity template


Is it possible in Apache Velocity 1.7 to check if all keys specified in a VelocityContext are valid for a template? For example, let's say I have a template, card.vm, that looks like this:

card {
    type: CREDIT
    company: VISA
    name: "${firstName} ${lastName}"
}

If I then execute the following code, it should throw an error since cardNumber is not present in the card.vm template:

VelocityContext context = new VelocityContext();
context.put("firstName", "tuk");
context.put("lastName", "man");
context.put("cardNumber", "1234");
StringWriter writer = new StringWriter();
t.merge(context, writer);

Solution

  • As Christopher mentioned on the velocity mailing list for your earlier question, you can always create a subclass of VelocityContext to customize behavior like this.

    For instance, this will track what keys have been put into the context and track what keys were used in the context. You would then call context.checkForUnreferencedValues() after you merge the template.

    You will likely need to customize the code depending on what helper objects are adding keys to your context and whether you are reusing it.

        static class ReferenceCountingVelocityContext extends VelocityContext {
            private Set<String> keysToCheck = new HashSet<>();
            private Set<String> keysUsed = new HashSet<>();
    
            @Override
            public Object put(String key, Object value) {
                keysToCheck.add(key);
                return super.put(key, value);
            }
    
            @Override
            public Object get(String key) {
                keysUsed.add(key);
                return super.get(key);
            }
            public void checkForUnreferencedValues() throws UnusedVelocityContextKeyException {
                if (!keysToCheck.containsAll(keysUsed)) {
                    throw new UnusedVelocityContextKeyException();
                }
            }
        }