1 | package fr.sii.ogham.template.freemarker.builder; | |
2 | ||
3 | import static freemarker.template.Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS; | |
4 | ||
5 | import java.io.Writer; | |
6 | import java.util.HashMap; | |
7 | import java.util.Locale; | |
8 | import java.util.Map; | |
9 | import java.util.Map.Entry; | |
10 | ||
11 | import fr.sii.ogham.core.builder.Builder; | |
12 | import fr.sii.ogham.core.builder.configuration.ConfigurationValueBuilder; | |
13 | import fr.sii.ogham.core.builder.configuration.ConfigurationValueBuilderHelper; | |
14 | import fr.sii.ogham.core.builder.configurer.Configurer; | |
15 | import fr.sii.ogham.core.builder.context.BuildContext; | |
16 | import fr.sii.ogham.core.builder.env.EnvironmentBuilder; | |
17 | import fr.sii.ogham.core.exception.builder.BuildException; | |
18 | import fr.sii.ogham.core.fluent.AbstractParent; | |
19 | import freemarker.core.Configurable; | |
20 | import freemarker.ext.beans.BeansWrapper; | |
21 | import freemarker.ext.beans.BeansWrapperBuilder; | |
22 | import freemarker.template.Configuration; | |
23 | import freemarker.template.ObjectWrapper; | |
24 | import freemarker.template.Template; | |
25 | import freemarker.template.TemplateExceptionHandler; | |
26 | import freemarker.template.TemplateHashModelEx; | |
27 | import freemarker.template.TemplateModel; | |
28 | import freemarker.template.TemplateModelException; | |
29 | import freemarker.template.Version; | |
30 | ||
31 | /** | |
32 | * Fluent builder to configure Freemarker configuration object. | |
33 | * | |
34 | * @author Aurélien Baudet | |
35 | * | |
36 | * @param <P> | |
37 | * the type of the parent builder (when calling {@link #and()} | |
38 | * method) | |
39 | */ | |
40 | public class FreemarkerConfigurationBuilder<P> extends AbstractParent<P> implements Builder<Configuration> { | |
41 | private final ConfigurationValueBuilderHelper<FreemarkerConfigurationBuilder<P>, String> defaultEncodingValueBuilder; | |
42 | private final ConfigurationValueBuilderHelper<FreemarkerConfigurationBuilder<P>, Boolean> enableStaticMethodAccessValueBuilder; | |
43 | private final ConfigurationValueBuilderHelper<FreemarkerConfigurationBuilder<P>, String> staticMethodAccessVariableNameValueBuilder; | |
44 | private final Map<String, Object> sharedVariables; | |
45 | private Configuration base; | |
46 | private Version version; | |
47 | private TemplateExceptionHandler templateExceptionHandler; | |
48 | private TemplateHashModelEx variablesHash; | |
49 | // TODO: handle all other options | |
50 | ||
51 | /** | |
52 | * Initializes the builder with a parent builder. The parent builder is used | |
53 | * when calling {@link #and()} method. The {@link EnvironmentBuilder} is | |
54 | * used to evaluate properties when {@link #build()} method is called. | |
55 | * | |
56 | * @param parent | |
57 | * the parent builder | |
58 | * @param buildContext | |
59 | * for registering instances and property evaluation | |
60 | */ | |
61 | public FreemarkerConfigurationBuilder(P parent, BuildContext buildContext) { | |
62 | super(parent); | |
63 | defaultEncodingValueBuilder = buildContext.newConfigurationValueBuilder(this, String.class); | |
64 | enableStaticMethodAccessValueBuilder = buildContext.newConfigurationValueBuilder(this, Boolean.class); | |
65 | staticMethodAccessVariableNameValueBuilder = buildContext.newConfigurationValueBuilder(this, String.class); | |
66 | sharedVariables = new HashMap<>(); | |
67 | } | |
68 | ||
69 | /** | |
70 | * Sets the base configuration that will be configured. | |
71 | * | |
72 | * If none is provided, a new configuration instance is created. | |
73 | * | |
74 | * @param base | |
75 | * the configuration to use and to configure | |
76 | * @return this instance for fluent chaining | |
77 | */ | |
78 | public FreemarkerConfigurationBuilder<P> base(Configuration base) { | |
79 | this.base = base; | |
80 |
2
1. base : replaced return value with null for fr/sii/ogham/template/freemarker/builder/FreemarkerConfigurationBuilder::base → SURVIVED 2. base : replaced return value with null for fr/sii/ogham/template/freemarker/builder/FreemarkerConfigurationBuilder::base → NO_COVERAGE |
return this; |
81 | } | |
82 | ||
83 | /** | |
84 | * Sets which of the non-backward-compatible bugfixes/improvements should be | |
85 | * enabled. | |
86 | * | |
87 | * See {@link Configuration#Configuration(Version)} for more information | |
88 | * about version and incompatible improvements. | |
89 | * | |
90 | * @see Configuration#Configuration(Version) | |
91 | * @param version | |
92 | * the non-backward-compatible bugfixes/improvements should be | |
93 | * enabled | |
94 | * @return this instance for fluent chaining | |
95 | */ | |
96 | public FreemarkerConfigurationBuilder<P> version(Version version) { | |
97 | this.version = version; | |
98 |
1
1. version : replaced return value with null for fr/sii/ogham/template/freemarker/builder/FreemarkerConfigurationBuilder::version → NO_COVERAGE |
return this; |
99 | } | |
100 | ||
101 | /** | |
102 | * * Sets the charset used for decoding byte sequences to character | |
103 | * sequences when reading template files in a locale for which no explicit | |
104 | * encoding was specified via | |
105 | * {@link Configuration#setEncoding(Locale, String)}. Note that by default | |
106 | * there is no locale specified for any locale, so the default encoding is | |
107 | * always in effect. | |
108 | * | |
109 | * <p> | |
110 | * Defaults to the default system encoding, which can change from one server | |
111 | * to another, so <b>you should always set this setting</b>. If you don't | |
112 | * know what charset your should chose, {@code "UTF-8"} is usually a good | |
113 | * choice. | |
114 | * | |
115 | * <p> | |
116 | * Note that individual templates may specify their own charset by starting | |
117 | * with {@code <#ftl encoding="...">} | |
118 | * | |
119 | * | |
120 | * <p> | |
121 | * The value set using this method takes precedence over any property and | |
122 | * default value configured using {@link #defaultEncoding()}. | |
123 | * | |
124 | * <pre> | |
125 | * .defaultEncoding("UTF-16") | |
126 | * .defaultEncoding() | |
127 | * .properties("${custom.property.high-priority}", "${custom.property.low-priority}") | |
128 | * .defaultValue("UTF-8") | |
129 | * </pre> | |
130 | * | |
131 | * <pre> | |
132 | * .defaultEncoding("UTF-16") | |
133 | * .defaultEncoding() | |
134 | * .properties("${custom.property.high-priority}", "${custom.property.low-priority}") | |
135 | * .defaultValue("UTF-8") | |
136 | * </pre> | |
137 | * | |
138 | * In both cases, {@code defaultEncoding("UTF-16")} is used. | |
139 | * | |
140 | * <p> | |
141 | * If this method is called several times, only the last value is used. | |
142 | * | |
143 | * <p> | |
144 | * If {@code null} value is set, it is like not setting a value at all. The | |
145 | * property/default value configuration is applied. | |
146 | * | |
147 | * @param charsetName | |
148 | * the name of the charset | |
149 | * @return this instance for fluent chaining | |
150 | */ | |
151 | public FreemarkerConfigurationBuilder<P> defaultEncoding(String charsetName) { | |
152 |
1
1. defaultEncoding : removed call to fr/sii/ogham/core/builder/configuration/ConfigurationValueBuilderHelper::setValue → NO_COVERAGE |
defaultEncodingValueBuilder.setValue(charsetName); |
153 |
1
1. defaultEncoding : replaced return value with null for fr/sii/ogham/template/freemarker/builder/FreemarkerConfigurationBuilder::defaultEncoding → NO_COVERAGE |
return this; |
154 | } | |
155 | ||
156 | /** | |
157 | * * Sets the charset used for decoding byte sequences to character | |
158 | * sequences when reading template files in a locale for which no explicit | |
159 | * encoding was specified via | |
160 | * {@link Configuration#setEncoding(Locale, String)}. Note that by default | |
161 | * there is no locale specified for any locale, so the default encoding is | |
162 | * always in effect. | |
163 | * | |
164 | * <p> | |
165 | * Defaults to the default system encoding, which can change from one server | |
166 | * to another, so <b>you should always set this setting</b>. If you don't | |
167 | * know what charset your should chose, {@code "UTF-8"} is usually a good | |
168 | * choice. | |
169 | * | |
170 | * <p> | |
171 | * Note that individual templates may specify their own charset by starting | |
172 | * with {@code <#ftl encoding="...">} | |
173 | * | |
174 | * | |
175 | * <p> | |
176 | * This method is mainly used by {@link Configurer}s to register some | |
177 | * property keys and/or a default value. The aim is to let developer be able | |
178 | * to externalize its configuration (using system properties, configuration | |
179 | * file or anything else). If the developer doesn't configure any value for | |
180 | * the registered properties, the default value is used (if set). | |
181 | * | |
182 | * <pre> | |
183 | * .defaultEncoding() | |
184 | * .properties("${custom.property.high-priority}", "${custom.property.low-priority}") | |
185 | * .defaultValue("UTF-8") | |
186 | * </pre> | |
187 | * | |
188 | * <p> | |
189 | * Non-null value set using {@link #defaultEncoding(String)} takes | |
190 | * precedence over property values and default value. | |
191 | * | |
192 | * <pre> | |
193 | * .defaultEncoding("UTF-16") | |
194 | * .defaultEncoding() | |
195 | * .properties("${custom.property.high-priority}", "${custom.property.low-priority}") | |
196 | * .defaultValue("UTF-8") | |
197 | * </pre> | |
198 | * | |
199 | * The value {@code "UTF-16"} is used regardless of the value of the | |
200 | * properties and default value. | |
201 | * | |
202 | * <p> | |
203 | * See {@link ConfigurationValueBuilder} for more information. | |
204 | * | |
205 | * | |
206 | * @return the builder to configure property keys/default value | |
207 | */ | |
208 | public ConfigurationValueBuilder<FreemarkerConfigurationBuilder<P>, String> defaultEncoding() { | |
209 |
4
1. defaultEncoding : replaced return value with null for fr/sii/ogham/template/freemarker/builder/FreemarkerConfigurationBuilder::defaultEncoding → NO_COVERAGE 2. defaultEncoding : replaced return value with null for fr/sii/ogham/template/freemarker/builder/FreemarkerConfigurationBuilder::defaultEncoding → KILLED 3. defaultEncoding : replaced return value with null for fr/sii/ogham/template/freemarker/builder/FreemarkerConfigurationBuilder::defaultEncoding → KILLED 4. defaultEncoding : replaced return value with null for fr/sii/ogham/template/freemarker/builder/FreemarkerConfigurationBuilder::defaultEncoding → KILLED |
return defaultEncodingValueBuilder; |
210 | } | |
211 | ||
212 | /** | |
213 | * Sets the exception handler used to handle exceptions occurring inside | |
214 | * templates. The default is {@link TemplateExceptionHandler#DEBUG_HANDLER}. | |
215 | * The recommended values are: | |
216 | * | |
217 | * <ul> | |
218 | * <li>In production systems: | |
219 | * {@link TemplateExceptionHandler#RETHROW_HANDLER} | |
220 | * <li>During development of HTML templates: | |
221 | * {@link TemplateExceptionHandler#HTML_DEBUG_HANDLER} | |
222 | * <li>During development of non-HTML templates: | |
223 | * {@link TemplateExceptionHandler#DEBUG_HANDLER} | |
224 | * </ul> | |
225 | * | |
226 | * <p> | |
227 | * All of these will let the exception propagate further, so that you can | |
228 | * catch it around {@link Template#process(Object, Writer)} for example. The | |
229 | * difference is in what they print on the output before they do that. | |
230 | * | |
231 | * <p> | |
232 | * Note that the {@link TemplateExceptionHandler} is not meant to be used | |
233 | * for generating HTTP error pages. Neither is it meant to be used to roll | |
234 | * back the printed output. These should be solved outside template | |
235 | * processing when the exception raises from | |
236 | * {@link Template#process(Object, Writer) Template.process}. | |
237 | * {@link TemplateExceptionHandler} meant to be used if you want to include | |
238 | * special content <em>in</em> the template output, or if you want to | |
239 | * suppress certain exceptions. | |
240 | * | |
241 | * @param exceptionHandler | |
242 | * the exception handler | |
243 | * @return this instance for fluent chaining | |
244 | */ | |
245 | public FreemarkerConfigurationBuilder<P> templateExceptionHandler(TemplateExceptionHandler exceptionHandler) { | |
246 | this.templateExceptionHandler = exceptionHandler; | |
247 |
4
1. templateExceptionHandler : replaced return value with null for fr/sii/ogham/template/freemarker/builder/FreemarkerConfigurationBuilder::templateExceptionHandler → NO_COVERAGE 2. templateExceptionHandler : replaced return value with null for fr/sii/ogham/template/freemarker/builder/FreemarkerConfigurationBuilder::templateExceptionHandler → KILLED 3. templateExceptionHandler : replaced return value with null for fr/sii/ogham/template/freemarker/builder/FreemarkerConfigurationBuilder::templateExceptionHandler → KILLED 4. templateExceptionHandler : replaced return value with null for fr/sii/ogham/template/freemarker/builder/FreemarkerConfigurationBuilder::templateExceptionHandler → KILLED |
return this; |
248 | } | |
249 | ||
250 | /** | |
251 | * Adds a shared variable to the configuration. Shared sharedVariables are | |
252 | * sharedVariables that are visible as top-level sharedVariables for all | |
253 | * templates which use this configuration, if the data model does not | |
254 | * contain a variable with the same name. | |
255 | * | |
256 | * <p> | |
257 | * Never use <code>TemplateModel</code> implementation that is not | |
258 | * thread-safe for shared sharedVariables, if the configuration is used by | |
259 | * multiple threads! It is the typical situation for Servlet based Web | |
260 | * sites. | |
261 | * | |
262 | * <p> | |
263 | * This method is <b>not</b> thread safe; use it with the same restrictions | |
264 | * as those that modify setting values. | |
265 | * | |
266 | * @param name | |
267 | * the name used to access the data object from your template. If | |
268 | * a shared variable with this name already exists, it will | |
269 | * replace that. | |
270 | * @param tm | |
271 | * the data object value directly available as a | |
272 | * {@link TemplateModel} | |
273 | * | |
274 | * @see #addSharedVariables | |
275 | * @see #addSharedVariable(String,Object) | |
276 | * @return this instance for fluent chaining | |
277 | */ | |
278 | public FreemarkerConfigurationBuilder<P> addSharedVariable(String name, TemplateModel tm) { | |
279 | this.sharedVariables.put(name, tm); | |
280 |
1
1. addSharedVariable : replaced return value with null for fr/sii/ogham/template/freemarker/builder/FreemarkerConfigurationBuilder::addSharedVariable → NO_COVERAGE |
return this; |
281 | } | |
282 | ||
283 | /** | |
284 | * Adds shared variable to the configuration; It uses | |
285 | * {@link Configurable#getObjectWrapper()} to wrap the {@code value}, so | |
286 | * it's important that the object wrapper is set before this. | |
287 | * | |
288 | * <p> | |
289 | * This method is <b>not</b> thread safe; use it with the same restrictions | |
290 | * as those that modify setting values. | |
291 | * | |
292 | * <p> | |
293 | * The added value should be thread safe, if you are running templates from | |
294 | * multiple threads with this configuration. | |
295 | * | |
296 | * @param name | |
297 | * the name used to access the data object from your template. If | |
298 | * a shared variable with this name already exists, it will | |
299 | * replace that. | |
300 | * @param value | |
301 | * the data object value | |
302 | * | |
303 | * @see #addSharedVariable(String,TemplateModel) | |
304 | * @see #addSharedVariables(TemplateHashModelEx) | |
305 | * @return this instance for fluent chaining | |
306 | */ | |
307 | public FreemarkerConfigurationBuilder<P> addSharedVariable(String name, Object value) { | |
308 | this.sharedVariables.put(name, value); | |
309 |
1
1. addSharedVariable : replaced return value with null for fr/sii/ogham/template/freemarker/builder/FreemarkerConfigurationBuilder::addSharedVariable → NO_COVERAGE |
return this; |
310 | } | |
311 | ||
312 | /** | |
313 | * Enable calls to static methods from templates: | |
314 | * | |
315 | * <pre> | |
316 | * ${statics['foo.bar.StringUtils'].capitalize(name)} | |
317 | * </pre> | |
318 | * | |
319 | * | |
320 | * <p> | |
321 | * The value set using this method takes precedence over any property and | |
322 | * default value configured using {@link #enableStaticMethodAccess()}. | |
323 | * | |
324 | * <pre> | |
325 | * .enableStaticMethodAccess(true) | |
326 | * .enableStaticMethodAccess() | |
327 | * .properties("${custom.property.high-priority}", "${custom.property.low-priority}") | |
328 | * .defaultValue(false) | |
329 | * </pre> | |
330 | * | |
331 | * <pre> | |
332 | * .enableStaticMethodAccess(true) | |
333 | * .enableStaticMethodAccess() | |
334 | * .properties("${custom.property.high-priority}", "${custom.property.low-priority}") | |
335 | * .defaultValue(false) | |
336 | * </pre> | |
337 | * | |
338 | * In both cases, {@code enableStaticMethodAccess(true)} is used. | |
339 | * | |
340 | * <p> | |
341 | * If this method is called several times, only the last value is used. | |
342 | * | |
343 | * <p> | |
344 | * If {@code null} value is set, it is like not setting a value at all. The | |
345 | * property/default value configuration is applied. | |
346 | * | |
347 | * @param enable | |
348 | * enable or disable static method access | |
349 | * @return this instance for fluent chaining | |
350 | */ | |
351 | public FreemarkerConfigurationBuilder<P> enableStaticMethodAccess(Boolean enable) { | |
352 |
2
1. enableStaticMethodAccess : removed call to fr/sii/ogham/core/builder/configuration/ConfigurationValueBuilderHelper::setValue → NO_COVERAGE 2. enableStaticMethodAccess : removed call to fr/sii/ogham/core/builder/configuration/ConfigurationValueBuilderHelper::setValue → SURVIVED |
enableStaticMethodAccessValueBuilder.setValue(enable); |
353 |
3
1. enableStaticMethodAccess : replaced return value with null for fr/sii/ogham/template/freemarker/builder/FreemarkerConfigurationBuilder::enableStaticMethodAccess → NO_COVERAGE 2. enableStaticMethodAccess : replaced return value with null for fr/sii/ogham/template/freemarker/builder/FreemarkerConfigurationBuilder::enableStaticMethodAccess → KILLED 3. enableStaticMethodAccess : replaced return value with null for fr/sii/ogham/template/freemarker/builder/FreemarkerConfigurationBuilder::enableStaticMethodAccess → KILLED |
return this; |
354 | } | |
355 | ||
356 | /** | |
357 | * Enable calls to static methods from templates: | |
358 | * | |
359 | * <pre> | |
360 | * ${statics['foo.bar.StringUtils'].capitalize(name)} | |
361 | * </pre> | |
362 | * | |
363 | * | |
364 | * <p> | |
365 | * This method is mainly used by {@link Configurer}s to register some | |
366 | * property keys and/or a default value. The aim is to let developer be able | |
367 | * to externalize its configuration (using system properties, configuration | |
368 | * file or anything else). If the developer doesn't configure any value for | |
369 | * the registered properties, the default value is used (if set). | |
370 | * | |
371 | * <pre> | |
372 | * .enableStaticMethodAccess() | |
373 | * .properties("${custom.property.high-priority}", "${custom.property.low-priority}") | |
374 | * .defaultValue(false) | |
375 | * </pre> | |
376 | * | |
377 | * <p> | |
378 | * Non-null value set using {@link #enableStaticMethodAccess(Boolean)} takes | |
379 | * precedence over property values and default value. | |
380 | * | |
381 | * <pre> | |
382 | * .enableStaticMethodAccess(true) | |
383 | * .enableStaticMethodAccess() | |
384 | * .properties("${custom.property.high-priority}", "${custom.property.low-priority}") | |
385 | * .defaultValue(false) | |
386 | * </pre> | |
387 | * | |
388 | * The value {@code true} is used regardless of the value of the properties | |
389 | * and default value. | |
390 | * | |
391 | * <p> | |
392 | * See {@link ConfigurationValueBuilder} for more information. | |
393 | * | |
394 | * | |
395 | * @return the builder to configure property keys/default value | |
396 | */ | |
397 | public ConfigurationValueBuilder<FreemarkerConfigurationBuilder<P>, Boolean> enableStaticMethodAccess() { | |
398 |
4
1. enableStaticMethodAccess : replaced return value with null for fr/sii/ogham/template/freemarker/builder/FreemarkerConfigurationBuilder::enableStaticMethodAccess → NO_COVERAGE 2. enableStaticMethodAccess : replaced return value with null for fr/sii/ogham/template/freemarker/builder/FreemarkerConfigurationBuilder::enableStaticMethodAccess → KILLED 3. enableStaticMethodAccess : replaced return value with null for fr/sii/ogham/template/freemarker/builder/FreemarkerConfigurationBuilder::enableStaticMethodAccess → KILLED 4. enableStaticMethodAccess : replaced return value with null for fr/sii/ogham/template/freemarker/builder/FreemarkerConfigurationBuilder::enableStaticMethodAccess → KILLED |
return enableStaticMethodAccessValueBuilder; |
399 | } | |
400 | ||
401 | /** | |
402 | * Change the name of the variable used to access static methods. | |
403 | * | |
404 | * <p> | |
405 | * The value set using this method takes precedence over any property and | |
406 | * default value configured using {@link #staticMethodAccessVariableName()}. | |
407 | * | |
408 | * <pre> | |
409 | * .staticMethodAccessVariableName("myStatics") | |
410 | * .staticMethodAccessVariableName() | |
411 | * .properties("${custom.property.high-priority}", "${custom.property.low-priority}") | |
412 | * .defaultValue("statics") | |
413 | * </pre> | |
414 | * | |
415 | * <pre> | |
416 | * .staticMethodAccessVariableName("myStatics") | |
417 | * .staticMethodAccessVariableName() | |
418 | * .properties("${custom.property.high-priority}", "${custom.property.low-priority}") | |
419 | * .defaultValue("statics") | |
420 | * </pre> | |
421 | * | |
422 | * In both cases, {@code staticMethodAccessVariableName("myStatics")} is | |
423 | * used. | |
424 | * | |
425 | * <p> | |
426 | * If this method is called several times, only the last value is used. | |
427 | * | |
428 | * <p> | |
429 | * If {@code null} value is set, it is like not setting a value at all. The | |
430 | * property/default value configuration is applied. | |
431 | * | |
432 | * @param variableName | |
433 | * the name of the variable used to access static methods from | |
434 | * templates | |
435 | * @return this instance for fluent chaining | |
436 | */ | |
437 | public FreemarkerConfigurationBuilder<P> staticMethodAccessVariableName(String variableName) { | |
438 |
2
1. staticMethodAccessVariableName : removed call to fr/sii/ogham/core/builder/configuration/ConfigurationValueBuilderHelper::setValue → NO_COVERAGE 2. staticMethodAccessVariableName : removed call to fr/sii/ogham/core/builder/configuration/ConfigurationValueBuilderHelper::setValue → SURVIVED |
staticMethodAccessVariableNameValueBuilder.setValue(variableName); |
439 |
2
1. staticMethodAccessVariableName : replaced return value with null for fr/sii/ogham/template/freemarker/builder/FreemarkerConfigurationBuilder::staticMethodAccessVariableName → NO_COVERAGE 2. staticMethodAccessVariableName : replaced return value with null for fr/sii/ogham/template/freemarker/builder/FreemarkerConfigurationBuilder::staticMethodAccessVariableName → SURVIVED |
return this; |
440 | } | |
441 | ||
442 | /** | |
443 | * Change the name of the variable used to access static methods. | |
444 | * | |
445 | * <p> | |
446 | * This method is mainly used by {@link Configurer}s to register some | |
447 | * property keys and/or a default value. The aim is to let developer be able | |
448 | * to externalize its configuration (using system properties, configuration | |
449 | * file or anything else). If the developer doesn't configure any value for | |
450 | * the registered properties, the default value is used (if set). | |
451 | * | |
452 | * <pre> | |
453 | * .staticMethodAccessVariableName() | |
454 | * .properties("${custom.property.high-priority}", "${custom.property.low-priority}") | |
455 | * .defaultValue("statics") | |
456 | * </pre> | |
457 | * | |
458 | * <p> | |
459 | * Non-null value set using {@link #staticMethodAccessVariableName(String)} | |
460 | * takes precedence over property values and default value. | |
461 | * | |
462 | * <pre> | |
463 | * .staticMethodAccessVariableName("myStatics") | |
464 | * .staticMethodAccessVariableName() | |
465 | * .properties("${custom.property.high-priority}", "${custom.property.low-priority}") | |
466 | * .defaultValue("statics") | |
467 | * </pre> | |
468 | * | |
469 | * The value {@code "myStatics"} is used regardless of the value of the | |
470 | * properties and default value. | |
471 | * | |
472 | * <p> | |
473 | * See {@link ConfigurationValueBuilder} for more information. | |
474 | * | |
475 | * | |
476 | * @return the builder to configure property keys/default value | |
477 | */ | |
478 | public ConfigurationValueBuilder<FreemarkerConfigurationBuilder<P>, String> staticMethodAccessVariableName() { | |
479 |
4
1. staticMethodAccessVariableName : replaced return value with null for fr/sii/ogham/template/freemarker/builder/FreemarkerConfigurationBuilder::staticMethodAccessVariableName → NO_COVERAGE 2. staticMethodAccessVariableName : replaced return value with null for fr/sii/ogham/template/freemarker/builder/FreemarkerConfigurationBuilder::staticMethodAccessVariableName → TIMED_OUT 3. staticMethodAccessVariableName : replaced return value with null for fr/sii/ogham/template/freemarker/builder/FreemarkerConfigurationBuilder::staticMethodAccessVariableName → KILLED 4. staticMethodAccessVariableName : replaced return value with null for fr/sii/ogham/template/freemarker/builder/FreemarkerConfigurationBuilder::staticMethodAccessVariableName → KILLED |
return staticMethodAccessVariableNameValueBuilder; |
480 | } | |
481 | ||
482 | /** | |
483 | * Adds all object in the hash as shared variable to the configuration; it's | |
484 | * like doing several {@link #addSharedVariable(String, Object)} calls, one | |
485 | * for each hash entry. It doesn't remove the already added shared variable | |
486 | * before doing this. | |
487 | * | |
488 | * <p> | |
489 | * Never use <code>TemplateModel</code> implementation that is not | |
490 | * thread-safe for shared shared variable values, if the configuration is | |
491 | * used by multiple threads! It is the typical situation for Servlet based | |
492 | * Web sites. | |
493 | * | |
494 | * <p> | |
495 | * This method is <b>not</b> thread safe; use it with the same restrictions | |
496 | * as those that modify setting values. | |
497 | * | |
498 | * @param variables | |
499 | * a hash model whose objects will be copied to the configuration | |
500 | * with same names as they are given in the hash. If a shared | |
501 | * variable with these names already exist, it will be replaced | |
502 | * with those from the map. | |
503 | * @return this instance for fluent chaining | |
504 | */ | |
505 | public FreemarkerConfigurationBuilder<P> addSharedVariables(TemplateHashModelEx variables) { | |
506 | this.variablesHash = variables; | |
507 |
2
1. addSharedVariables : replaced return value with null for fr/sii/ogham/template/freemarker/builder/FreemarkerConfigurationBuilder::addSharedVariables → SURVIVED 2. addSharedVariables : replaced return value with null for fr/sii/ogham/template/freemarker/builder/FreemarkerConfigurationBuilder::addSharedVariables → NO_COVERAGE |
return this; |
508 | } | |
509 | ||
510 | @Override | |
511 | public Configuration build() { | |
512 | Configuration configuration = getConfiguration(); | |
513 | String defaultEncoding = defaultEncodingValueBuilder.getValue(); | |
514 |
4
1. build : negated conditional → NO_COVERAGE 2. build : negated conditional → SURVIVED 3. build : negated conditional → KILLED 4. build : negated conditional → KILLED |
if (defaultEncoding != null) { |
515 |
4
1. build : removed call to freemarker/template/Configuration::setDefaultEncoding → NO_COVERAGE 2. build : removed call to freemarker/template/Configuration::setDefaultEncoding → SURVIVED 3. build : removed call to freemarker/template/Configuration::setDefaultEncoding → KILLED 4. build : removed call to freemarker/template/Configuration::setDefaultEncoding → KILLED |
configuration.setDefaultEncoding(defaultEncoding); |
516 | } | |
517 |
2
1. build : negated conditional → NO_COVERAGE 2. build : negated conditional → SURVIVED |
if (templateExceptionHandler != null) { |
518 |
2
1. build : removed call to freemarker/template/Configuration::setTemplateExceptionHandler → SURVIVED 2. build : removed call to freemarker/template/Configuration::setTemplateExceptionHandler → NO_COVERAGE |
configuration.setTemplateExceptionHandler(templateExceptionHandler); |
519 | } | |
520 |
4
1. build : removed call to fr/sii/ogham/template/freemarker/builder/FreemarkerConfigurationBuilder::buildSharedVariables → NO_COVERAGE 2. build : removed call to fr/sii/ogham/template/freemarker/builder/FreemarkerConfigurationBuilder::buildSharedVariables → SURVIVED 3. build : removed call to fr/sii/ogham/template/freemarker/builder/FreemarkerConfigurationBuilder::buildSharedVariables → KILLED 4. build : removed call to fr/sii/ogham/template/freemarker/builder/FreemarkerConfigurationBuilder::buildSharedVariables → KILLED |
buildSharedVariables(configuration); |
521 |
4
1. build : removed call to fr/sii/ogham/template/freemarker/builder/FreemarkerConfigurationBuilder::buildStaticMethodAccess → NO_COVERAGE 2. build : removed call to fr/sii/ogham/template/freemarker/builder/FreemarkerConfigurationBuilder::buildStaticMethodAccess → KILLED 3. build : removed call to fr/sii/ogham/template/freemarker/builder/FreemarkerConfigurationBuilder::buildStaticMethodAccess → KILLED 4. build : removed call to fr/sii/ogham/template/freemarker/builder/FreemarkerConfigurationBuilder::buildStaticMethodAccess → KILLED |
buildStaticMethodAccess(configuration); |
522 |
4
1. build : replaced return value with null for fr/sii/ogham/template/freemarker/builder/FreemarkerConfigurationBuilder::build → NO_COVERAGE 2. build : replaced return value with null for fr/sii/ogham/template/freemarker/builder/FreemarkerConfigurationBuilder::build → KILLED 3. build : replaced return value with null for fr/sii/ogham/template/freemarker/builder/FreemarkerConfigurationBuilder::build → KILLED 4. build : replaced return value with null for fr/sii/ogham/template/freemarker/builder/FreemarkerConfigurationBuilder::build → KILLED |
return configuration; |
523 | } | |
524 | ||
525 | private Configuration getConfiguration() { | |
526 |
3
1. getConfiguration : negated conditional → SURVIVED 2. getConfiguration : negated conditional → NO_COVERAGE 3. getConfiguration : negated conditional → KILLED |
if (base != null) { |
527 |
3
1. getConfiguration : negated conditional → NO_COVERAGE 2. getConfiguration : negated conditional → KILLED 3. getConfiguration : negated conditional → KILLED |
if (version != null) { |
528 |
1
1. getConfiguration : removed call to freemarker/template/Configuration::setIncompatibleImprovements → NO_COVERAGE |
base.setIncompatibleImprovements(version); |
529 | } | |
530 |
3
1. getConfiguration : replaced return value with null for fr/sii/ogham/template/freemarker/builder/FreemarkerConfigurationBuilder::getConfiguration → NO_COVERAGE 2. getConfiguration : replaced return value with null for fr/sii/ogham/template/freemarker/builder/FreemarkerConfigurationBuilder::getConfiguration → KILLED 3. getConfiguration : replaced return value with null for fr/sii/ogham/template/freemarker/builder/FreemarkerConfigurationBuilder::getConfiguration → KILLED |
return base; |
531 | } | |
532 |
4
1. getConfiguration : negated conditional → NO_COVERAGE 2. getConfiguration : replaced return value with null for fr/sii/ogham/template/freemarker/builder/FreemarkerConfigurationBuilder::getConfiguration → NO_COVERAGE 3. getConfiguration : negated conditional → KILLED 4. getConfiguration : replaced return value with null for fr/sii/ogham/template/freemarker/builder/FreemarkerConfigurationBuilder::getConfiguration → KILLED |
return version == null ? new Configuration(DEFAULT_INCOMPATIBLE_IMPROVEMENTS) : new Configuration(version); |
533 | } | |
534 | ||
535 | private void buildSharedVariables(Configuration configuration) { | |
536 | try { | |
537 |
4
1. buildSharedVariables : negated conditional → NO_COVERAGE 2. buildSharedVariables : negated conditional → KILLED 3. buildSharedVariables : negated conditional → KILLED 4. buildSharedVariables : negated conditional → KILLED |
if (variablesHash != null) { |
538 |
3
1. buildSharedVariables : removed call to freemarker/template/Configuration::setAllSharedVariables → NO_COVERAGE 2. buildSharedVariables : removed call to freemarker/template/Configuration::setAllSharedVariables → KILLED 3. buildSharedVariables : removed call to freemarker/template/Configuration::setAllSharedVariables → KILLED |
configuration.setAllSharedVariables(variablesHash); |
539 | } | |
540 | for (Entry<String, Object> entry : sharedVariables.entrySet()) { | |
541 |
1
1. buildSharedVariables : removed call to freemarker/template/Configuration::setSharedVariable → NO_COVERAGE |
configuration.setSharedVariable(entry.getKey(), entry.getValue()); |
542 | } | |
543 | } catch (TemplateModelException e) { | |
544 | throw new BuildException("Failed to configure FreeMarker shared variables", e); | |
545 | } | |
546 | } | |
547 | ||
548 | private void buildStaticMethodAccess(Configuration configuration) { | |
549 | boolean enableStaticMethods = enableStaticMethodAccessValueBuilder.getValue(false); | |
550 |
4
1. buildStaticMethodAccess : negated conditional → NO_COVERAGE 2. buildStaticMethodAccess : negated conditional → KILLED 3. buildStaticMethodAccess : negated conditional → KILLED 4. buildStaticMethodAccess : negated conditional → KILLED |
if (enableStaticMethods) { |
551 | String staticsVariableName = staticMethodAccessVariableNameValueBuilder.getValue(); | |
552 |
4
1. buildStaticMethodAccess : removed call to freemarker/template/Configuration::setSharedVariable → NO_COVERAGE 2. buildStaticMethodAccess : removed call to freemarker/template/Configuration::setSharedVariable → KILLED 3. buildStaticMethodAccess : removed call to freemarker/template/Configuration::setSharedVariable → KILLED 4. buildStaticMethodAccess : removed call to freemarker/template/Configuration::setSharedVariable → KILLED |
configuration.setSharedVariable(staticsVariableName, getBeansWrapper(configuration).getStaticModels()); |
553 | } | |
554 | } | |
555 | ||
556 | private static BeansWrapper getBeansWrapper(Configuration configuration) { | |
557 | ObjectWrapper objectWrapper = configuration.getObjectWrapper(); | |
558 |
2
1. getBeansWrapper : negated conditional → SURVIVED 2. getBeansWrapper : negated conditional → NO_COVERAGE |
if (objectWrapper instanceof BeansWrapper) { |
559 |
4
1. getBeansWrapper : replaced return value with null for fr/sii/ogham/template/freemarker/builder/FreemarkerConfigurationBuilder::getBeansWrapper → NO_COVERAGE 2. getBeansWrapper : replaced return value with null for fr/sii/ogham/template/freemarker/builder/FreemarkerConfigurationBuilder::getBeansWrapper → KILLED 3. getBeansWrapper : replaced return value with null for fr/sii/ogham/template/freemarker/builder/FreemarkerConfigurationBuilder::getBeansWrapper → KILLED 4. getBeansWrapper : replaced return value with null for fr/sii/ogham/template/freemarker/builder/FreemarkerConfigurationBuilder::getBeansWrapper → KILLED |
return (BeansWrapper) objectWrapper; |
560 | } | |
561 |
1
1. getBeansWrapper : replaced return value with null for fr/sii/ogham/template/freemarker/builder/FreemarkerConfigurationBuilder::getBeansWrapper → NO_COVERAGE |
return new BeansWrapperBuilder(configuration.getIncompatibleImprovements()).build(); |
562 | } | |
563 | ||
564 | } | |
Mutations | ||
80 |
1.1 2.2 |
|
98 |
1.1 |
|
152 |
1.1 |
|
153 |
1.1 |
|
209 |
1.1 2.2 3.3 4.4 |
|
247 |
1.1 2.2 3.3 4.4 |
|
280 |
1.1 |
|
309 |
1.1 |
|
352 |
1.1 2.2 |
|
353 |
1.1 2.2 3.3 |
|
398 |
1.1 2.2 3.3 4.4 |
|
438 |
1.1 2.2 |
|
439 |
1.1 2.2 |
|
479 |
1.1 2.2 3.3 4.4 |
|
507 |
1.1 2.2 |
|
514 |
1.1 2.2 3.3 4.4 |
|
515 |
1.1 2.2 3.3 4.4 |
|
517 |
1.1 2.2 |
|
518 |
1.1 2.2 |
|
520 |
1.1 2.2 3.3 4.4 |
|
521 |
1.1 2.2 3.3 4.4 |
|
522 |
1.1 2.2 3.3 4.4 |
|
526 |
1.1 2.2 3.3 |
|
527 |
1.1 2.2 3.3 |
|
528 |
1.1 |
|
530 |
1.1 2.2 3.3 |
|
532 |
1.1 2.2 3.3 4.4 |
|
537 |
1.1 2.2 3.3 4.4 |
|
538 |
1.1 2.2 3.3 |
|
541 |
1.1 |
|
550 |
1.1 2.2 3.3 4.4 |
|
552 |
1.1 2.2 3.3 4.4 |
|
558 |
1.1 2.2 |
|
559 |
1.1 2.2 3.3 4.4 |
|
561 |
1.1 |