Patrick Barry created VELOCITY-986: -------------------------------------- Summary: Regression test failure Key: VELOCITY-986 URL: https://issues.apache.org/jira/browse/VELOCITY-986 Project: Velocity Issue Type: Bug Components: Engine Affects Versions: 2.4.1, 2.4 Reporter: Patrick Barry
We recently tried to upgrade to 2.4 and 2.4.1 and both had this issue, so we had to rollback. We have a template looking like this: https://my.example.com?size=${input.size} In our VelocityContext, we have have an InnerContext values that should be used. IE {"size"= "1089", "name="tyler", age="28"} In versions 2.3 and below, this would evaluate to [https://my.example.com?size=1089|https://my.example.com/?size=1089] With newest versions, it gives us the number of items in our map. So [https://my.example.com?size=3|https://my.example.com/?size=1089] Here is a unit test of our usage. This test includes the ability to register many different "providers", however, I kept it simple and just used one. Providers have a prefix, so in the example above, we use a prefix provider of "input". This allows to "scope" contexts. {code:java} import org.apache.commons.collections4.map.CaseInsensitiveMap; import org.apache.commons.lang3.NotImplementedException; import org.apache.commons.lang3.StringUtils; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.Velocity; import org.apache.velocity.app.VelocityEngine; import org.apache.velocity.context.Context; import org.junit.Test; import java.io.StringWriter; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; import static org.junit.jupiter.api.Assertions.assertEquals; public class VelocityRegressionTest { @Test public void testVelocityTemplate() throws Exception { VelocityEngine velocityEngine = new VelocityEngine(); velocityEngine.init(); VariableProviderCaseInsensitiveMap<String> innerMap = new VariableProviderCaseInsensitiveMap<>("input"); innerMap.put("size", "1098"); innerMap.put("name", "Tyler"); innerMap.put("try", "1"); Context innerContext = new VariableProviderVelocityContext(List.of(innerMap)); VelocityContext context = new VelocityContext(innerContext); StringWriter sw = new StringWriter(); String vt = "https://my.example.com?size=${input.size}"; Velocity.evaluate(context, sw, "", vt); assertEquals("https://my.example.com?size=1098", sw.toString()); } static class VariableProviderCaseInsensitiveMap<T> extends CaseInsensitiveMap<String, T> { private String providerContextPrefix = null; public VariableProviderCaseInsensitiveMap(final String providerContextPrefix) { if (!StringUtils.isBlank(providerContextPrefix)) { this.providerContextPrefix = providerContextPrefix; } } public String getProviderContextPrefix() { return providerContextPrefix; } public Set<String> getKeys() { return super.keySet(); } public Map<String, T> getMap() {return this;} } static class VariableProviderVelocityContext extends VelocityContext { protected final List<VariableProviderCaseInsensitiveMap> providers; public VariableProviderVelocityContext( final List<VariableProviderCaseInsensitiveMap> providers ) { super(); this.providers = providers; } private Object lookup(String key) { for (VariableProviderCaseInsensitiveMap provider : providers) { final String contextPrefix = provider.getProviderContextPrefix(); if (contextPrefix.equalsIgnoreCase(key)) { return provider.getMap(); } } return null; } @Override public Object internalGet(String var1) { return lookup(var1); } @Override public Object internalPut(String key, Object value) { throw new NotImplementedException("internalRemove is not valid and is not implemented"); } @Override public String[] internalGetKeys() { List<String> keys = new LinkedList<>(); for (VariableProviderCaseInsensitiveMap provider : providers) { String prefix = provider.getProviderContextPrefix(); if (StringUtils.isNotBlank(prefix)) { keys.add(prefix); } //the prefix is the key name for a context provider. else { keys.addAll(provider.getKeys()); } } return keys.toArray(new String[0]); } @Override public boolean internalContainsKey(String var1) { return lookup(var1) != null; } @Override public Object internalRemove(String var1) { throw new NotImplementedException("internalRemove is not valid and is not implemented"); } } } {code} -- This message was sent by Atlassian Jira (v8.20.10#820010) --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@velocity.apache.org For additional commands, e-mail: dev-h...@velocity.apache.org