Fix Mustache to not ignore native fetcher
Alter the logic of `MustacheEnvironmentCollector` so that the native fetcher is always consulted if it exists. When the context is a map (as it is in a web View for instance) you can't assume a non-null fetcher actually contains the property you are searching for. See gh-21060
This commit is contained in:
@@ -19,6 +19,7 @@ package org.springframework.boot.autoconfigure.mustache;
|
||||
import com.samskivert.mustache.DefaultCollector;
|
||||
import com.samskivert.mustache.Mustache.Collector;
|
||||
import com.samskivert.mustache.Mustache.VariableFetcher;
|
||||
import com.samskivert.mustache.Template;
|
||||
|
||||
import org.springframework.context.EnvironmentAware;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
@@ -35,8 +36,6 @@ public class MustacheEnvironmentCollector extends DefaultCollector implements En
|
||||
|
||||
private ConfigurableEnvironment environment;
|
||||
|
||||
private final VariableFetcher propertyFetcher = new PropertyVariableFetcher();
|
||||
|
||||
@Override
|
||||
public void setEnvironment(Environment environment) {
|
||||
this.environment = (ConfigurableEnvironment) environment;
|
||||
@@ -46,19 +45,45 @@ public class MustacheEnvironmentCollector extends DefaultCollector implements En
|
||||
public VariableFetcher createFetcher(Object ctx, String name) {
|
||||
VariableFetcher fetcher = super.createFetcher(ctx, name);
|
||||
if (fetcher != null) {
|
||||
return fetcher;
|
||||
return new PropertyVariableFetcher(fetcher);
|
||||
}
|
||||
if (this.environment.containsProperty(name)) {
|
||||
return this.propertyFetcher;
|
||||
return new PropertyVariableFetcher();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private class PropertyVariableFetcher implements VariableFetcher {
|
||||
|
||||
private final VariableFetcher nativeFetcher;
|
||||
|
||||
PropertyVariableFetcher() {
|
||||
this.nativeFetcher = null;
|
||||
}
|
||||
|
||||
PropertyVariableFetcher(VariableFetcher nativeFetcher) {
|
||||
this.nativeFetcher = nativeFetcher;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object get(Object ctx, String name) {
|
||||
return MustacheEnvironmentCollector.this.environment.getProperty(name);
|
||||
Object result;
|
||||
if (this.nativeFetcher != null) {
|
||||
try {
|
||||
result = this.nativeFetcher.get(ctx, name);
|
||||
if (result != null && result != Template.NO_FETCHER_FOUND) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
catch (Exception ex) {
|
||||
// fall through
|
||||
}
|
||||
}
|
||||
result = MustacheEnvironmentCollector.this.environment.getProperty(name);
|
||||
if (result == null) {
|
||||
return Template.NO_FETCHER_FOUND;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@DirtiesContext
|
||||
@SpringBootTest(webEnvironment = WebEnvironment.NONE, properties = { "env.FOO=There", "foo=World" })
|
||||
@SpringBootTest(webEnvironment = WebEnvironment.NONE, properties = { "env.FOO=There", "foo=World", "bar.name=Bar" })
|
||||
class MustacheStandaloneIntegrationTests {
|
||||
|
||||
@Autowired
|
||||
@@ -60,15 +60,51 @@ class MustacheStandaloneIntegrationTests {
|
||||
.isEqualTo("Hello: There");
|
||||
}
|
||||
|
||||
@Test
|
||||
void environmentCollectorCompoundKeyStandardMap() {
|
||||
assertThat(this.compiler.standardsMode(true).compile("Hello: {{env.foo}}")
|
||||
.execute(Collections.singletonMap("world", "World"))).isEqualTo("Hello: There");
|
||||
}
|
||||
|
||||
@Test
|
||||
void environmentCollectorCompoundKeyWithBean() {
|
||||
assertThat(this.compiler.compile("Hello: {{foo.name}}")
|
||||
.execute(Collections.singletonMap("foo", new Foo()))).isEqualTo("Hello: Foo");
|
||||
}
|
||||
|
||||
@Test
|
||||
void environmentCollectorCompoundKeyWithBeanPrefersEnvironment() {
|
||||
assertThat(this.compiler.compile("Hello: {{bar.name}}")
|
||||
.execute(Collections.singletonMap("bar", new Foo()))).isEqualTo("Hello: Bar");
|
||||
}
|
||||
|
||||
@Test
|
||||
void environmentCollectorSimpleKey() {
|
||||
assertThat(this.compiler.compile("Hello: {{foo}}").execute(new Object())).isEqualTo("Hello: World");
|
||||
}
|
||||
|
||||
@Test
|
||||
void environmentCollectorSimpleKeyMap() {
|
||||
assertThat(this.compiler.compile("Hello: {{foo}}").execute(Collections.singletonMap("world", "Foo")))
|
||||
.isEqualTo("Hello: World");
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@Import({ MustacheAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class })
|
||||
static class Application {
|
||||
|
||||
}
|
||||
|
||||
static class Foo {
|
||||
private String name = "Foo";
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user