DefaultFreemarkerEmailConfigurer.java

1
package fr.sii.ogham.template.freemarker.configurer;
2
3
import fr.sii.ogham.core.builder.MessagingBuilder;
4
import fr.sii.ogham.core.builder.configurer.ConfigurerFor;
5
import fr.sii.ogham.core.builder.configurer.DefaultMessagingConfigurer;
6
import fr.sii.ogham.core.builder.configurer.MessagingConfigurer;
7
import fr.sii.ogham.core.builder.configurer.MessagingConfigurerAdapter;
8
import fr.sii.ogham.core.builder.context.BuildContext;
9
import fr.sii.ogham.core.builder.resolution.ResourceResolutionBuilder;
10
import fr.sii.ogham.core.exception.configurer.ConfigureException;
11
import fr.sii.ogham.core.exception.configurer.MissingImplementationException;
12
import fr.sii.ogham.core.message.content.EmailVariant;
13
import fr.sii.ogham.core.util.ClasspathUtils;
14
import fr.sii.ogham.template.freemarker.FreeMarkerTemplateDetector;
15
import fr.sii.ogham.template.freemarker.builder.FreemarkerEmailBuilder;
16
import freemarker.template.TemplateExceptionHandler;
17
import org.slf4j.Logger;
18
import org.slf4j.LoggerFactory;
19
20
import static fr.sii.ogham.core.builder.configuration.MayOverride.overrideIfNotSet;
21
import static fr.sii.ogham.template.freemarker.FreemarkerConstants.DEFAULT_FREEMARKER_EMAIL_CONFIGURER_PRIORITY;
22
23
/**
24
 * Default configurer for Freemarker template engine that is automatically
25
 * applied every time a {@link MessagingBuilder} instance is created through
26
 * {@link MessagingBuilder#standard()} or {@link MessagingBuilder#minimal()}.
27
 * 
28
 * <p>
29
 * The configurer has a priority of 80000 in order to be applied after global
30
 * configurer but before any sender implementation.
31
 * </p>
32
 * 
33
 * This configurer is applied only if {@code freemarker.template.Configuration}
34
 * and {@code freemarker.template.Template} are present in the classpath. If not
35
 * present, template engine is not registered at all.
36
 * 
37
 * <p>
38
 * This configurer inherits environment configuration (see
39
 * {@link BuildContext}).
40
 * </p>
41
 * <p>
42
 * It also copies resource resolution configuration of
43
 * {@link DefaultMessagingConfigurer} to inherit resource resolution lookups
44
 * (see {@link ResourceResolutionBuilder}).
45
 * </p>
46
 * 
47
 * <p>
48
 * This configurer applies the following configuration:
49
 * <ul>
50
 * <li>Configures template prefix/suffix paths:
51
 * <ul>
52
 * <li>Uses the first property that has a value for classpath resolution prefix:
53
 * <ol>
54
 * <li>"ogham.email.freemarker.classpath.path-prefix"</li>
55
 * <li>"ogham.email.template.classpath.path-prefix"</li>
56
 * <li>"ogham.email.freemarker.path-prefix"</li>
57
 * <li>"ogham.email.template.path-prefix"</li>
58
 * <li>"ogham.template.path-prefix"</li>
59
 * </ol>
60
 * </li>
61
 * <li>Uses the first property that has a value for classpath resolution suffix:
62
 * <ol>
63
 * <li>"ogham.email.freemarker.classpath.path-suffix"</li>
64
 * <li>"ogham.email.template.classpath.path-suffix"</li>
65
 * <li>"ogham.email.freemarker.path-suffix"</li>
66
 * <li>"ogham.email.template.path-suffix"</li>
67
 * <li>"ogham.template.path-suffix"</li>
68
 * </ol>
69
 * </li>
70
 * <li>Uses the first property that has a value for file resolution prefix:
71
 * <ol>
72
 * <li>"ogham.email.freemarker.file.path-prefix"</li>
73
 * <li>"ogham.email.template.file.path-prefix"</li>
74
 * <li>"ogham.email.freemarker.path-prefix"</li>
75
 * <li>"ogham.email.template.path-prefix"</li>
76
 * <li>"ogham.template.path-prefix"</li>
77
 * </ol>
78
 * </li>
79
 * <li>Uses the first property that has a value for file resolution suffix:
80
 * <ol>
81
 * <li>"ogham.email.freemarker.file.path-suffix"</li>
82
 * <li>"ogham.email.template.file.path-suffix"</li>
83
 * <li>"ogham.email.freemarker.path-suffix"</li>
84
 * <li>"ogham.email.template.path-suffix"</li>
85
 * <li>"ogham.template.path-suffix"</li>
86
 * </ol>
87
 * </li>
88
 * </ul>
89
 * </li>
90
 * <li>Configures email alternative content:
91
 * <ul>
92
 * <li>Automatically loads HTML template if extension is .html.ftl</li>
93
 * <li>Automatically loads text template if extension is .txt.ftl</li>
94
 * </ul>
95
 * </li>
96
 * <li>Configures encoding:
97
 * <ul>
98
 * <li>It uses "ogham.freemarker.default-encoding" property value as charset for
99
 * template parsing if defined. Default charset is UTF-8</li>
100
 * </ul>
101
 * </li>
102
 * <li>Configures template detection:
103
 * <ul>
104
 * <li>Uses {@link FreeMarkerTemplateDetector} to detect if templates are
105
 * parseable by Freemarker</li>
106
 * </ul>
107
 * </li>
108
 * <li>Configures static method access from templates:
109
 * <ul>
110
 * <li>Uses property value of ${ogham.freemarker.static-method-access.enable} if
111
 * provided to enable/disable static method access from templates (default is
112
 * enabled is nothing is configured)</li>
113
 * <li>Uses property value of
114
 * ${ogham.freemarker.static-method-access.variable-name} if provided to set the
115
 * name used to access static methods from templates (default is 'statics')</li>
116
 * </ul>
117
 * </li>
118
 * </ul>
119
 * 
120
 * @author Aurélien Baudet
121
 *
122
 */
123
public final class DefaultFreemarkerEmailConfigurer {
124
	private static final Logger LOG = LoggerFactory.getLogger(DefaultFreemarkerEmailConfigurer.class);
125
126
	@ConfigurerFor(targetedBuilder = { "minimal", "standard" }, priority = DEFAULT_FREEMARKER_EMAIL_CONFIGURER_PRIORITY)
127
	public static class FreemakerConfigurer implements MessagingConfigurer {
128
		private final MessagingConfigurerAdapter delegate;
129
130
		public FreemakerConfigurer() {
131
			this(new DefaultMessagingConfigurer());
132
		}
133
134
		public FreemakerConfigurer(MessagingConfigurerAdapter delegate) {
135
			super();
136
			this.delegate = delegate;
137
		}
138
139
		@Override
140
		public void configure(MessagingBuilder msgBuilder) throws ConfigureException {
141 1 1. configure : removed call to fr/sii/ogham/template/freemarker/configurer/DefaultFreemarkerEmailConfigurer$FreemakerConfigurer::checkCanUseFreemarker → RUN_ERROR
			checkCanUseFreemarker();
142
143
			FreemarkerEmailBuilder builder = msgBuilder.email().template(FreemarkerEmailBuilder.class);
144
			// apply default resource resolution configuration
145 1 1. configure : negated conditional → RUN_ERROR
			if (delegate != null) {
146 1 1. configure : removed call to fr/sii/ogham/core/builder/configurer/MessagingConfigurerAdapter::configure → RUN_ERROR
				delegate.configure(builder);
147
			}
148
			// @formatter:off
149
			builder
150
				.classpath()
151
					.pathPrefix()
152
						.properties("${ogham.email.freemarker.classpath.path-prefix}", 
153
									"${ogham.email.template.classpath.path-prefix}", 
154
									"${ogham.email.freemarker.path-prefix}", 
155
									"${ogham.email.template.path-prefix}", 
156
									"${ogham.template.path-prefix}")
157
						.and()
158
					.pathSuffix()
159
						.properties("${ogham.email.freemarker.classpath.path-suffix}", 
160
									"${ogham.email.template.classpath.path-suffix}", 
161
									"${ogham.email.freemarker.path-suffix}", 
162
									"${ogham.email.template.path-suffix}", 
163
									"${ogham.template.path-suffix}")
164
						.and()
165
					.and()
166
				.file()
167
					.pathPrefix()
168
						.properties("${ogham.email.freemarker.file.path-prefix}", 
169
									"${ogham.email.template.file.path-prefix}", 
170
									"${ogham.email.freemarker.path-prefix}", 
171
									"${ogham.email.template.path-prefix}", 
172
									"${ogham.template.path-prefix}")
173
						.and()
174
					.pathSuffix()
175
						.properties("${ogham.email.freemarker.file.path-suffix}", 
176
									"${ogham.email.template.file.path-suffix}", 
177
									"${ogham.email.freemarker.path-suffix}", 
178
									"${ogham.email.template.path-suffix}", 
179
									"${ogham.template.path-suffix}")
180
						.and()
181
					.and()
182
				.string()
183
					.and()
184
				.variant(EmailVariant.HTML, "html.ftl")
185
				.variant(EmailVariant.HTML, "html.ftlh")
186
				.variant(EmailVariant.TEXT, "txt.ftl")
187
				.variant(EmailVariant.TEXT, "txt.ftlh")
188
				.configuration()
189
					.defaultEncoding().properties("${ogham.freemarker.default-encoding}").defaultValue(overrideIfNotSet("UTF-8")).and()
190
					.templateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER)
191
					.enableStaticMethodAccess().properties("${ogham.freemarker.static-method-access.enable}").defaultValue(overrideIfNotSet(true)).and()
192
					.staticMethodAccessVariableName().properties("${ogham.freemarker.static-method-access.variable-name}").defaultValue(overrideIfNotSet("statics"));
193
			// @formatter:on
194
		}
195
196
		private static void checkCanUseFreemarker() throws ConfigureException {
197 1 1. checkCanUseFreemarker : negated conditional → RUN_ERROR
			if (!isFreemarkerPresent()) {
198
				throw new MissingImplementationException("Can't parse FreeMarker templates because FreeMarker implementation is not present in the classpath", "freemarker.template.Configuration", "freemarker.template.Template");
199
			}
200
		}
201
202
		private static boolean isFreemarkerPresent() {
203 3 1. isFreemarkerPresent : negated conditional → RUN_ERROR
2. isFreemarkerPresent : replaced boolean return with true for fr/sii/ogham/template/freemarker/configurer/DefaultFreemarkerEmailConfigurer$FreemakerConfigurer::isFreemarkerPresent → RUN_ERROR
3. isFreemarkerPresent : negated conditional → RUN_ERROR
			return ClasspathUtils.exists("freemarker.template.Configuration") && ClasspathUtils.exists("freemarker.template.Template");
204
		}
205
	}
206
207
	private DefaultFreemarkerEmailConfigurer() {
208
		super();
209
	}
210
}

Mutations

141

1.1
Location : configure
Killed by :
removed call to fr/sii/ogham/template/freemarker/configurer/DefaultFreemarkerEmailConfigurer$FreemakerConfigurer::checkCanUseFreemarker → RUN_ERROR

145

1.1
Location : configure
Killed by :
negated conditional → RUN_ERROR

146

1.1
Location : configure
Killed by :
removed call to fr/sii/ogham/core/builder/configurer/MessagingConfigurerAdapter::configure → RUN_ERROR

197

1.1
Location : checkCanUseFreemarker
Killed by :
negated conditional → RUN_ERROR

203

1.1
Location : isFreemarkerPresent
Killed by :
negated conditional → RUN_ERROR

2.2
Location : isFreemarkerPresent
Killed by :
replaced boolean return with true for fr/sii/ogham/template/freemarker/configurer/DefaultFreemarkerEmailConfigurer$FreemakerConfigurer::isFreemarkerPresent → RUN_ERROR

3.3
Location : isFreemarkerPresent
Killed by :
negated conditional → RUN_ERROR

Active mutators

Tests examined


Report generated by PIT 1.13.1