Skip to content

Commit 969b371

Browse files
committed
Address review comments
1 parent b830b19 commit 969b371

File tree

6 files changed

+575
-1
lines changed

6 files changed

+575
-1
lines changed

spring-webflux/src/main/java/org/springframework/web/reactive/result/view/freemarker/FreeMarkerConfigurer.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,6 @@
5757
* Note: Spring's FreeMarker support requires FreeMarker 2.3 or higher.
5858
*
5959
* @author Rossen Stoyanchev
60-
* @author Issam El-atif
6160
* @since 5.0
6261
*/
6362
public class FreeMarkerConfigurer extends FreeMarkerConfigurationFactory

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
* RequestContext under the name "springMacroRequestContext", as needed by
1616
* the macros in this library.
1717
*
18+
* @author Darren Davison
19+
* @author Juergen Hoeller
1820
* @author Issam El-atif
1921
* @since 5.2
2022
-->
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
/*
2+
* Copyright 2002-2019 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.web.reactive.result.view;
18+
19+
import java.util.List;
20+
import java.util.Map;
21+
22+
import org.springframework.context.support.GenericApplicationContext;
23+
import org.springframework.ui.ModelMap;
24+
import org.springframework.web.server.ServerWebExchange;
25+
import org.springframework.web.util.UriTemplate;
26+
27+
/**
28+
* Dummy request context used for VTL and FTL macro tests.
29+
*
30+
* @author Darren Davison
31+
* @author Juergen Hoeller
32+
* @author Issam El-atif
33+
*
34+
* @see org.springframework.web.reactive.result.view.RequestContext
35+
*/
36+
public class DummyMacroRequestContext {
37+
38+
private final ServerWebExchange exchange;
39+
40+
private final ModelMap model;
41+
42+
private final GenericApplicationContext context;
43+
44+
private Map<String, String> messageMap;
45+
46+
private String contextPath;
47+
48+
public DummyMacroRequestContext(ServerWebExchange exchange, ModelMap model, GenericApplicationContext context) {
49+
this.exchange = exchange;
50+
this.model = model;
51+
this.context = context;
52+
}
53+
54+
public void setMessageMap(Map<String, String> messageMap) {
55+
this.messageMap = messageMap;
56+
}
57+
58+
/**
59+
* @see org.springframework.web.reactive.result.view.RequestContext#getMessage(String)
60+
*/
61+
public String getMessage(String code) {
62+
return this.messageMap.get(code);
63+
}
64+
65+
/**
66+
* @see org.springframework.web.reactive.result.view.RequestContext#getMessage(String, String)
67+
*/
68+
public String getMessage(String code, String defaultMsg) {
69+
String msg = this.messageMap.get(code);
70+
return (msg != null ? msg : defaultMsg);
71+
}
72+
73+
/**
74+
* @see org.springframework.web.reactive.result.view.RequestContext#getMessage(String, List)
75+
*/
76+
public String getMessage(String code, List<?> args) {
77+
return this.messageMap.get(code) + args;
78+
}
79+
80+
/**
81+
* @see org.springframework.web.reactive.result.view.RequestContext#getMessage(String, List, String)
82+
*/
83+
public String getMessage(String code, List<?> args, String defaultMsg) {
84+
String msg = this.messageMap.get(code);
85+
return (msg != null ? msg + args : defaultMsg);
86+
}
87+
88+
public void setContextPath(String contextPath) {
89+
this.contextPath = contextPath;
90+
}
91+
92+
/**
93+
* @see org.springframework.web.reactive.result.view.RequestContext#getContextPath()
94+
*/
95+
public String getContextPath() {
96+
return this.contextPath;
97+
}
98+
99+
/**
100+
* @see org.springframework.web.reactive.result.view.RequestContext#getContextUrl(String)
101+
*/
102+
public String getContextUrl(String relativeUrl) {
103+
return getContextPath() + relativeUrl;
104+
}
105+
106+
/**
107+
* @see org.springframework.web.reactive.result.view.RequestContext#getContextUrl(String, Map)
108+
*/
109+
public String getContextUrl(String relativeUrl, Map<String,String> params) {
110+
UriTemplate template = new UriTemplate(relativeUrl);
111+
return getContextPath() + template.expand(params).toASCIIString();
112+
}
113+
114+
/**
115+
* @see org.springframework.web.reactive.result.view.RequestContext#getBindStatus(String)
116+
*/
117+
public BindStatus getBindStatus(String path) throws IllegalStateException {
118+
return new BindStatus(new RequestContext(this.exchange, this.model, this.context), path, false);
119+
}
120+
121+
/**
122+
* @see org.springframework.web.reactive.result.view.RequestContext#getBindStatus(String, boolean)
123+
*/
124+
public BindStatus getBindStatus(String path, boolean htmlEscape) throws IllegalStateException {
125+
return new BindStatus(new RequestContext(this.exchange, this.model, this.context), path, true);
126+
}
127+
128+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
/*
2+
* Copyright 2002-2019 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.web.reactive.result.view.freemarker;
18+
19+
import java.io.IOException;
20+
import java.util.HashMap;
21+
import java.util.Properties;
22+
23+
import freemarker.template.Configuration;
24+
import freemarker.template.Template;
25+
import freemarker.template.TemplateException;
26+
import org.junit.Test;
27+
28+
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
29+
import org.springframework.beans.factory.support.RootBeanDefinition;
30+
import org.springframework.core.io.ByteArrayResource;
31+
import org.springframework.core.io.DefaultResourceLoader;
32+
import org.springframework.core.io.FileSystemResource;
33+
import org.springframework.core.io.Resource;
34+
import org.springframework.core.io.ResourceLoader;
35+
import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;
36+
import org.springframework.ui.freemarker.SpringTemplateLoader;
37+
38+
import static org.assertj.core.api.Assertions.assertThatIOException;
39+
import static org.hamcrest.MatcherAssert.assertThat;
40+
import static org.hamcrest.Matchers.instanceOf;
41+
import static org.junit.Assert.assertEquals;
42+
import static org.junit.Assert.assertTrue;
43+
44+
/**
45+
* @author Juergen Hoeller
46+
* @author Issam El-atif
47+
*/
48+
public class FreeMarkerConfigurerTests {
49+
50+
@Test
51+
public void freeMarkerConfigurerDefaultEncoding() throws IOException, TemplateException {
52+
FreeMarkerConfigurer configurer = new FreeMarkerConfigurer();
53+
configurer.afterPropertiesSet();
54+
Configuration cfg = configurer.getConfiguration();
55+
assertEquals("UTF-8", cfg.getDefaultEncoding());
56+
}
57+
58+
@Test
59+
public void freeMarkerConfigurerWithConfigLocation() {
60+
FreeMarkerConfigurer configurer = new FreeMarkerConfigurer();
61+
configurer.setConfigLocation(new FileSystemResource("myprops.properties"));
62+
Properties props = new Properties();
63+
props.setProperty("myprop", "/mydir");
64+
configurer.setFreemarkerSettings(props);
65+
assertThatIOException().isThrownBy(
66+
configurer::afterPropertiesSet);
67+
}
68+
69+
@Test
70+
public void freeMarkerConfigurerWithResourceLoaderPath() throws Exception {
71+
FreeMarkerConfigurer configurer = new FreeMarkerConfigurer();
72+
configurer.setTemplateLoaderPath("file:/mydir");
73+
configurer.afterPropertiesSet();
74+
Configuration cfg = configurer.getConfiguration();
75+
assertTrue(cfg.getTemplateLoader() instanceof SpringTemplateLoader);
76+
}
77+
78+
@Test
79+
@SuppressWarnings("rawtypes")
80+
public void freeMarkerConfigurerWithNonFileResourceLoaderPath() throws Exception {
81+
FreeMarkerConfigurer configurer = new FreeMarkerConfigurer();
82+
configurer.setTemplateLoaderPath("file:/mydir");
83+
Properties settings = new Properties();
84+
settings.setProperty("localized_lookup", "false");
85+
configurer.setFreemarkerSettings(settings);
86+
configurer.setResourceLoader(new ResourceLoader() {
87+
@Override
88+
public Resource getResource(String location) {
89+
if (!("file:/mydir".equals(location) || "file:/mydir/test".equals(location))) {
90+
throw new IllegalArgumentException(location);
91+
}
92+
return new ByteArrayResource("test".getBytes(), "test");
93+
}
94+
@Override
95+
public ClassLoader getClassLoader() {
96+
return getClass().getClassLoader();
97+
}
98+
});
99+
configurer.afterPropertiesSet();
100+
assertThat(configurer.getConfiguration(), instanceOf(Configuration.class));
101+
Configuration fc = configurer.getConfiguration();
102+
Template ft = fc.getTemplate("test");
103+
assertEquals("test", FreeMarkerTemplateUtils.processTemplateIntoString(ft, new HashMap()));
104+
}
105+
106+
@Test // SPR-12448
107+
public void freeMarkerConfigurationAsBean() {
108+
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
109+
RootBeanDefinition loaderDef = new RootBeanDefinition(SpringTemplateLoader.class);
110+
loaderDef.getConstructorArgumentValues().addGenericArgumentValue(new DefaultResourceLoader());
111+
loaderDef.getConstructorArgumentValues().addGenericArgumentValue("/freemarker");
112+
RootBeanDefinition configDef = new RootBeanDefinition(Configuration.class);
113+
configDef.getPropertyValues().add("templateLoader", loaderDef);
114+
beanFactory.registerBeanDefinition("freeMarkerConfig", configDef);
115+
beanFactory.getBean(Configuration.class);
116+
}
117+
118+
}

0 commit comments

Comments
 (0)