Skip to content

Commit 2f640fe

Browse files
committed
Polish FreeMarker macro support in spring-webflux
See gh-23002
1 parent ac28de0 commit 2f640fe

File tree

8 files changed

+234
-130
lines changed

8 files changed

+234
-130
lines changed

spring-webflux/src/main/resources/org/springframework/web/reactive/result/view/freemarker/spring.ftl

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,15 @@
1010
* all macros within it available to any application using Spring's
1111
* FreeMarkerConfigurer.
1212
*
13-
* To take advantage of these macros, the "exposeSpringMacroHelpers" property
14-
* of the FreeMarker class needs to be set to "true". This will expose a
15-
* RequestContext under the name "springMacroRequestContext", as needed by
16-
* the macros in this library.
13+
* To take advantage of these macros, the "requestContextAttribute" property of
14+
* the FreeMarkerView class must be set to "springMacroRequestContext". This will
15+
* expose a RequestContext under the name "springMacroRequestContext", as needed
16+
* by the macros in this library.
1717
*
1818
* @author Darren Davison
1919
* @author Juergen Hoeller
2020
* @author Issam El-atif
21+
* @author Sam Brannen
2122
* @since 5.2
2223
-->
2324

@@ -71,7 +72,7 @@
7172
* RequestContext. This can be customized by calling "setDefaultHtmlEscape"
7273
* on the "springMacroRequestContext" context variable, or via the
7374
* "defaultHtmlEscape" context-param in web.xml (same as for the JSP bind tag).
74-
* Also regards a "htmlEscape" variable in the namespace of this library.
75+
* Also regards an "htmlEscape" variable in the namespace of this library.
7576
*
7677
* Producing no output, the following context variable will be available
7778
* each time this macro is referenced (assuming you import this library in
@@ -173,8 +174,7 @@
173174
-->
174175
<#macro formTextarea path attributes="">
175176
<@bind path/>
176-
<textarea id="${status.expression?replace('[','')?replace(']','')}" name="${status.expression}" ${attributes?no_esc}>
177-
${stringStatusValue}</textarea>
177+
<textarea id="${status.expression?replace('[','')?replace(']','')}" name="${status.expression}" ${attributes?no_esc}>${stringStatusValue}</textarea>
178178
</#macro>
179179

180180
<#--
@@ -320,10 +320,10 @@ ${stringStatusValue}</textarea>
320320
*
321321
* @param value the current value in a list iteration
322322
-->
323-
<#macro checkSelected value>
324-
<#if stringStatusValue?is_number && stringStatusValue == value?number>selected="selected"</#if>
325-
<#if stringStatusValue?is_string && stringStatusValue == value>selected="selected"</#if>
326-
</#macro>
323+
<#macro checkSelected value><#--
324+
--><#if stringStatusValue?is_number && stringStatusValue == value?number> selected="selected"</#if><#--
325+
--><#if stringStatusValue?is_string && stringStatusValue == value> selected="selected"</#if><#--
326+
--></#macro>
327327

328328
<#--
329329
* contains

spring-webflux/src/test/java/org/springframework/web/reactive/result/view/DummyMacroRequestContext.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,12 @@
2525
import org.springframework.web.util.UriTemplate;
2626

2727
/**
28-
* Dummy request context used for VTL and FTL macro tests.
28+
* Dummy request context used for FreeMarker macro tests.
2929
*
3030
* @author Darren Davison
3131
* @author Juergen Hoeller
3232
* @author Issam El-atif
33-
*
33+
* @since 5.2
3434
* @see org.springframework.web.reactive.result.view.RequestContext
3535
*/
3636
public class DummyMacroRequestContext {
@@ -115,14 +115,14 @@ public String getContextUrl(String relativeUrl, Map<String,String> params) {
115115
* @see org.springframework.web.reactive.result.view.RequestContext#getBindStatus(String)
116116
*/
117117
public BindStatus getBindStatus(String path) throws IllegalStateException {
118-
return new BindStatus(new RequestContext(this.exchange, this.model, this.context), path, false);
118+
return getBindStatus(path, false);
119119
}
120120

121121
/**
122122
* @see org.springframework.web.reactive.result.view.RequestContext#getBindStatus(String, boolean)
123123
*/
124124
public BindStatus getBindStatus(String path, boolean htmlEscape) throws IllegalStateException {
125-
return new BindStatus(new RequestContext(this.exchange, this.model, this.context), path, true);
125+
return new BindStatus(new RequestContext(this.exchange, this.model, this.context), path, htmlEscape);
126126
}
127127

128128
}

spring-webflux/src/test/java/org/springframework/web/reactive/result/view/freemarker/FreeMarkerConfigurerTests.java

Lines changed: 19 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -16,21 +16,16 @@
1616

1717
package org.springframework.web.reactive.result.view.freemarker;
1818

19-
import java.io.IOException;
2019
import java.util.HashMap;
2120
import java.util.Properties;
2221

2322
import freemarker.cache.ClassTemplateLoader;
2423
import freemarker.cache.MultiTemplateLoader;
2524
import freemarker.template.Configuration;
2625
import freemarker.template.Template;
27-
import freemarker.template.TemplateException;
2826
import org.junit.Test;
2927

30-
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
31-
import org.springframework.beans.factory.support.RootBeanDefinition;
3228
import org.springframework.core.io.ByteArrayResource;
33-
import org.springframework.core.io.DefaultResourceLoader;
3429
import org.springframework.core.io.FileSystemResource;
3530
import org.springframework.core.io.Resource;
3631
import org.springframework.core.io.ResourceLoader;
@@ -43,34 +38,34 @@
4338
/**
4439
* @author Juergen Hoeller
4540
* @author Issam El-atif
41+
* @author Sam Brannen
42+
* @since 5.2
4643
*/
4744
public class FreeMarkerConfigurerTests {
4845

46+
private final FreeMarkerConfigurer freeMarkerConfigurer = new FreeMarkerConfigurer();
47+
4948
@Test
50-
public void freeMarkerConfigurerDefaultEncoding() throws IOException, TemplateException {
51-
FreeMarkerConfigurer configurer = new FreeMarkerConfigurer();
52-
configurer.afterPropertiesSet();
53-
Configuration cfg = configurer.getConfiguration();
49+
public void freeMarkerConfigurerDefaultEncoding() throws Exception {
50+
freeMarkerConfigurer.afterPropertiesSet();
51+
Configuration cfg = freeMarkerConfigurer.getConfiguration();
5452
assertThat(cfg.getDefaultEncoding()).isEqualTo("UTF-8");
5553
}
5654

5755
@Test
5856
public void freeMarkerConfigurerWithConfigLocation() {
59-
FreeMarkerConfigurer configurer = new FreeMarkerConfigurer();
60-
configurer.setConfigLocation(new FileSystemResource("myprops.properties"));
57+
freeMarkerConfigurer.setConfigLocation(new FileSystemResource("myprops.properties"));
6158
Properties props = new Properties();
6259
props.setProperty("myprop", "/mydir");
63-
configurer.setFreemarkerSettings(props);
64-
assertThatIOException().isThrownBy(
65-
configurer::afterPropertiesSet);
60+
freeMarkerConfigurer.setFreemarkerSettings(props);
61+
assertThatIOException().isThrownBy(freeMarkerConfigurer::afterPropertiesSet);
6662
}
6763

6864
@Test
6965
public void freeMarkerConfigurerWithResourceLoaderPath() throws Exception {
70-
FreeMarkerConfigurer configurer = new FreeMarkerConfigurer();
71-
configurer.setTemplateLoaderPath("file:/mydir");
72-
configurer.afterPropertiesSet();
73-
Configuration cfg = configurer.getConfiguration();
66+
freeMarkerConfigurer.setTemplateLoaderPath("file:/mydir");
67+
freeMarkerConfigurer.afterPropertiesSet();
68+
Configuration cfg = freeMarkerConfigurer.getConfiguration();
7469
assertThat(cfg.getTemplateLoader()).isInstanceOf(MultiTemplateLoader.class);
7570
MultiTemplateLoader multiTemplateLoader = (MultiTemplateLoader)cfg.getTemplateLoader();
7671
assertThat(multiTemplateLoader.getTemplateLoader(0)).isInstanceOf(SpringTemplateLoader.class);
@@ -80,12 +75,11 @@ public void freeMarkerConfigurerWithResourceLoaderPath() throws Exception {
8075
@Test
8176
@SuppressWarnings("rawtypes")
8277
public void freeMarkerConfigurerWithNonFileResourceLoaderPath() throws Exception {
83-
FreeMarkerConfigurer configurer = new FreeMarkerConfigurer();
84-
configurer.setTemplateLoaderPath("file:/mydir");
78+
freeMarkerConfigurer.setTemplateLoaderPath("file:/mydir");
8579
Properties settings = new Properties();
8680
settings.setProperty("localized_lookup", "false");
87-
configurer.setFreemarkerSettings(settings);
88-
configurer.setResourceLoader(new ResourceLoader() {
81+
freeMarkerConfigurer.setFreemarkerSettings(settings);
82+
freeMarkerConfigurer.setResourceLoader(new ResourceLoader() {
8983
@Override
9084
public Resource getResource(String location) {
9185
if (!("file:/mydir".equals(location) || "file:/mydir/test".equals(location))) {
@@ -98,23 +92,11 @@ public ClassLoader getClassLoader() {
9892
return getClass().getClassLoader();
9993
}
10094
});
101-
configurer.afterPropertiesSet();
102-
assertThat(configurer.getConfiguration()).isInstanceOf(Configuration.class);
103-
Configuration fc = configurer.getConfiguration();
95+
freeMarkerConfigurer.afterPropertiesSet();
96+
assertThat(freeMarkerConfigurer.getConfiguration()).isInstanceOf(Configuration.class);
97+
Configuration fc = freeMarkerConfigurer.getConfiguration();
10498
Template ft = fc.getTemplate("test");
10599
assertThat(FreeMarkerTemplateUtils.processTemplateIntoString(ft, new HashMap())).isEqualTo("test");
106100
}
107101

108-
@Test // SPR-12448
109-
public void freeMarkerConfigurationAsBean() {
110-
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
111-
RootBeanDefinition loaderDef = new RootBeanDefinition(SpringTemplateLoader.class);
112-
loaderDef.getConstructorArgumentValues().addGenericArgumentValue(new DefaultResourceLoader());
113-
loaderDef.getConstructorArgumentValues().addGenericArgumentValue("/freemarker");
114-
RootBeanDefinition configDef = new RootBeanDefinition(Configuration.class);
115-
configDef.getPropertyValues().add("templateLoader", loaderDef);
116-
beanFactory.registerBeanDefinition("freeMarkerConfig", configDef);
117-
beanFactory.getBean(Configuration.class);
118-
}
119-
120102
}

0 commit comments

Comments
 (0)