| 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 |