| 1 | package pro.verron.officestamper.core; | |
| 2 | ||
| 3 | ||
| 4 | import org.springframework.expression.EvaluationContext; | |
| 5 | import org.springframework.expression.spel.SpelParserConfiguration; | |
| 6 | import org.springframework.expression.spel.standard.SpelExpressionParser; | |
| 7 | import pro.verron.officestamper.api.*; | |
| 8 | import pro.verron.officestamper.api.CustomFunction.NeedsBiFunctionImpl; | |
| 9 | import pro.verron.officestamper.api.CustomFunction.NeedsFunctionImpl; | |
| 10 | import pro.verron.officestamper.api.CustomFunction.NeedsTriFunctionImpl; | |
| 11 | import pro.verron.officestamper.core.functions.BiFunctionBuilder; | |
| 12 | import pro.verron.officestamper.core.functions.FunctionBuilder; | |
| 13 | import pro.verron.officestamper.core.functions.TriFunctionBuilder; | |
| 14 | import pro.verron.officestamper.preset.OfficeStamperConfigurations; | |
| 15 | ||
| 16 | import java.util.ArrayList; | |
| 17 | import java.util.HashMap; | |
| 18 | import java.util.List; | |
| 19 | import java.util.Map; | |
| 20 | import java.util.function.Supplier; | |
| 21 | ||
| 22 | /// The [DocxStamperConfiguration] class represents the configuration for the [DocxStamper] class. | |
| 23 | /// | |
| 24 | /// It provides methods to customize the behavior of the stamper. | |
| 25 | /// | |
| 26 | /// @author Joseph Verron | |
| 27 | /// @author Tom Hombergs | |
| 28 | /// @since 1.0.3 | |
| 29 | public class DocxStamperConfiguration | |
| 30 | implements OfficeStamperConfiguration { | |
| 31 | private final Map<Class<?>, CommentProcessorFactory> commentProcessors; | |
| 32 | private final List<ObjectResolver> resolvers; | |
| 33 | private final Map<Class<?>, Object> expressionFunctions; | |
| 34 | private final List<PreProcessor> preprocessors; | |
| 35 | private final List<PostProcessor> postprocessors; | |
| 36 | private final List<CustomFunction> functions; | |
| 37 | private EvaluationContextFactory evaluationContextFactory; | |
| 38 | private SpelParserConfiguration parserConfiguration; | |
| 39 | private ExceptionResolver exceptionResolver; | |
| 40 | private SecurityMode svgSecurityMode = SecurityMode.RESTRICTED; | |
| 41 | private SecurityMode spelSecurityMode = SecurityMode.RESTRICTED; | |
| 42 | private TraceabilityReporter traceabilityReporter = TraceabilityReporter.noop(); | |
| 43 | ||
| 44 | /// Constructs a new instance of the [DocxStamperConfiguration] class and initializes its default configuration | |
| 45 | /// settings. | |
| 46 | /// | |
| 47 | /// This constructor sets up internal structures and default behaviors for managing document stamping | |
| 48 | /// configurations, including: | |
| 49 | /// - Initializing collections for processors, resolvers, and functions. | |
| 50 | /// - Setting default values for expression handling and evaluation. | |
| 51 | /// - Creating and configuring a default [SpelParserConfiguration]. | |
| 52 | /// - Establishing resolvers and exception handling strategies. | |
| 53 | /// | |
| 54 | /// @param evaluationContextFactory the factory used to create [EvaluationContext] instances. | |
| 55 | /// @param exceptionResolver the exception resolver to use for handling exceptions during stamping. | |
| 56 | public DocxStamperConfiguration( | |
| 57 | EvaluationContextFactory evaluationContextFactory, | |
| 58 | ExceptionResolver exceptionResolver | |
| 59 | ) { | |
| 60 | this.commentProcessors = new HashMap<>(); | |
| 61 | this.resolvers = new ArrayList<>(); | |
| 62 | this.expressionFunctions = new HashMap<>(); | |
| 63 | this.preprocessors = new ArrayList<>(); | |
| 64 | this.postprocessors = new ArrayList<>(); | |
| 65 | this.functions = new ArrayList<>(); | |
| 66 | this.evaluationContextFactory = evaluationContextFactory; | |
| 67 | this.parserConfiguration = new SpelParserConfiguration(); | |
| 68 | this.exceptionResolver = exceptionResolver; | |
| 69 | } | |
| 70 | ||
| 71 | /// Exposes all methods of a given interface to the expression language. | |
| 72 | /// | |
| 73 | /// @param interfaceClass the interface holding methods to expose in the expression language. | |
| 74 | /// @param implementation the implementation to call to evaluate invocations of those methods, it must | |
| 75 | /// implement the mentioned interface. | |
| 76 | /// | |
| 77 | /// @return a [DocxStamperConfiguration] object | |
| 78 | @Override | |
| 79 | public DocxStamperConfiguration exposeInterfaceToExpressionLanguage( | |
| 80 | Class<?> interfaceClass, | |
| 81 | Object implementation | |
| 82 | ) { | |
| 83 | this.expressionFunctions.put(interfaceClass, implementation); | |
| 84 |
1
1. exposeInterfaceToExpressionLanguage : replaced return value with null for pro/verron/officestamper/core/DocxStamperConfiguration::exposeInterfaceToExpressionLanguage → KILLED |
return this; |
| 85 | } | |
| 86 | ||
| 87 | /// Registers the specified [CommentProcessor] as an implementation of the specified interface. | |
| 88 | /// | |
| 89 | /// @param interfaceClass the interface, implemented by the commentProcessor. | |
| 90 | /// @param commentProcessorFactory the commentProcessor factory generating instances of the specified | |
| 91 | /// interface. | |
| 92 | /// | |
| 93 | /// @return a [DocxStamperConfiguration] object | |
| 94 | @Override | |
| 95 | public DocxStamperConfiguration addCommentProcessor( | |
| 96 | Class<?> interfaceClass, | |
| 97 | CommentProcessorFactory commentProcessorFactory | |
| 98 | ) { | |
| 99 | this.commentProcessors.put(interfaceClass, commentProcessorFactory); | |
| 100 |
1
1. addCommentProcessor : replaced return value with null for pro/verron/officestamper/core/DocxStamperConfiguration::addCommentProcessor → KILLED |
return this; |
| 101 | } | |
| 102 | ||
| 103 | /// Adds a preprocessor to the configuration. | |
| 104 | /// | |
| 105 | /// @param preprocessor the preprocessor to add. | |
| 106 | @Override | |
| 107 | public void addPreprocessor(PreProcessor preprocessor) { | |
| 108 | preprocessors.add(preprocessor); | |
| 109 | } | |
| 110 | ||
| 111 | /// Retrieves the configured [EvaluationContextFactory] instance. | |
| 112 | /// | |
| 113 | /// @return an instance of [EvaluationContextFactory] used for creating evaluation contexts | |
| 114 | @Override | |
| 115 | public EvaluationContextFactory getEvaluationContextFactory() { | |
| 116 |
1
1. getEvaluationContextFactory : replaced return value with null for pro/verron/officestamper/core/DocxStamperConfiguration::getEvaluationContextFactory → KILLED |
return evaluationContextFactory; |
| 117 | } | |
| 118 | ||
| 119 | /// Sets the [EvaluationContextFactory] which creates Spring [EvaluationContext] instances used for evaluating | |
| 120 | /// expressions in comments and text. | |
| 121 | /// | |
| 122 | /// @param evaluationContextFactory the factory to use. | |
| 123 | /// @return the configuration object for chaining. | |
| 124 | @Override | |
| 125 | public DocxStamperConfiguration setEvaluationContextFactory(EvaluationContextFactory evaluationContextFactory) { | |
| 126 | this.evaluationContextFactory = evaluationContextFactory; | |
| 127 |
1
1. setEvaluationContextFactory : replaced return value with null for pro/verron/officestamper/core/DocxStamperConfiguration::setEvaluationContextFactory → KILLED |
return this; |
| 128 | } | |
| 129 | ||
| 130 | /// Retrieves the mapping of expression function classes to their corresponding function instances. | |
| 131 | /// | |
| 132 | /// @return a map where the keys are classes representing the function types, and the values are the function | |
| 133 | /// instances. | |
| 134 | @Override | |
| 135 | public Map<Class<?>, Object> getExpressionFunctions() { | |
| 136 |
1
1. getExpressionFunctions : replaced return value with Collections.emptyMap for pro/verron/officestamper/core/DocxStamperConfiguration::getExpressionFunctions → KILLED |
return expressionFunctions; |
| 137 | } | |
| 138 | ||
| 139 | /// Retrieves the map of comment processors associated with specific classes. | |
| 140 | /// | |
| 141 | /// @return a map where the key is the class associated with a specific type of placeholder, and the value is a | |
| 142 | /// function that creates a [CommentProcessor] for that placeholder. | |
| 143 | @Override | |
| 144 | public Map<Class<?>, CommentProcessorFactory> getCommentProcessors() { | |
| 145 |
1
1. getCommentProcessors : replaced return value with Collections.emptyMap for pro/verron/officestamper/core/DocxStamperConfiguration::getCommentProcessors → KILLED |
return commentProcessors; |
| 146 | } | |
| 147 | ||
| 148 | /// Retrieves the list of preprocessors. | |
| 149 | /// | |
| 150 | /// @return a list of [PreProcessor] objects. | |
| 151 | @Override | |
| 152 | public List<PreProcessor> getPreprocessors() { | |
| 153 |
1
1. getPreprocessors : replaced return value with Collections.emptyList for pro/verron/officestamper/core/DocxStamperConfiguration::getPreprocessors → KILLED |
return preprocessors; |
| 154 | } | |
| 155 | ||
| 156 | /// Retrieves the list of object resolvers. | |
| 157 | /// | |
| 158 | /// @return a list of [ObjectResolver] instances. | |
| 159 | @Override | |
| 160 | public List<ObjectResolver> getResolvers() { | |
| 161 |
1
1. getResolvers : replaced return value with Collections.emptyList for pro/verron/officestamper/core/DocxStamperConfiguration::getResolvers → KILLED |
return resolvers; |
| 162 | } | |
| 163 | ||
| 164 | /// Sets resolvers for resolving objects in the [DocxStamperConfiguration]. | |
| 165 | /// | |
| 166 | /// This method is the evolution of the method [#addResolver(ObjectResolver)], and the order in which the resolvers | |
| 167 | /// are ordered is determinant; the first resolvers in the list will be tried first. | |
| 168 | /// | |
| 169 | /// If a fallback resolver is desired, it should be placed last in the list. | |
| 170 | /// | |
| 171 | /// @param resolvers The list of [ObjectResolver] to be set. | |
| 172 | /// @return the configuration object for chaining. | |
| 173 | @Override | |
| 174 | public DocxStamperConfiguration setResolvers(List<ObjectResolver> resolvers) { | |
| 175 |
1
1. setResolvers : removed call to java/util/List::clear → KILLED |
this.resolvers.clear(); |
| 176 | this.resolvers.addAll(resolvers); | |
| 177 |
1
1. setResolvers : replaced return value with null for pro/verron/officestamper/core/DocxStamperConfiguration::setResolvers → KILLED |
return this; |
| 178 | } | |
| 179 | ||
| 180 | /// Adds a resolver to the list of resolvers in the [DocxStamperConfiguration] object. | |
| 181 | /// | |
| 182 | /// Resolvers are used to resolve objects during the stamping process. | |
| 183 | /// | |
| 184 | /// @param resolver The resolver to be added. | |
| 185 | /// @return The modified [DocxStamperConfiguration] object, with the resolver added to the beginning of the resolver | |
| 186 | /// list. | |
| 187 | @Override | |
| 188 | public DocxStamperConfiguration addResolver(ObjectResolver resolver) { | |
| 189 |
1
1. addResolver : removed call to java/util/List::addFirst → KILLED |
resolvers.addFirst(resolver); |
| 190 |
1
1. addResolver : replaced return value with null for pro/verron/officestamper/core/DocxStamperConfiguration::addResolver → KILLED |
return this; |
| 191 | } | |
| 192 | ||
| 193 | /// Retrieves the exception resolver. | |
| 194 | /// | |
| 195 | /// @return the current instance of [ExceptionResolver]. | |
| 196 | @Override | |
| 197 | public ExceptionResolver getExceptionResolver() { | |
| 198 |
1
1. getExceptionResolver : replaced return value with null for pro/verron/officestamper/core/DocxStamperConfiguration::getExceptionResolver → KILLED |
return exceptionResolver; |
| 199 | } | |
| 200 | ||
| 201 | /// Configures the exception resolver for the [DocxStamperConfiguration]. | |
| 202 | /// | |
| 203 | /// @param exceptionResolver the [ExceptionResolver] to handle exceptions during processing | |
| 204 | /// @return the current instance of [DocxStamperConfiguration] | |
| 205 | @Override | |
| 206 | public DocxStamperConfiguration setExceptionResolver(ExceptionResolver exceptionResolver) { | |
| 207 | this.exceptionResolver = exceptionResolver; | |
| 208 |
1
1. setExceptionResolver : replaced return value with null for pro/verron/officestamper/core/DocxStamperConfiguration::setExceptionResolver → KILLED |
return this; |
| 209 | } | |
| 210 | ||
| 211 | /// Retrieves a list of custom functions. | |
| 212 | /// | |
| 213 | /// @return a List containing [CustomFunction] objects. | |
| 214 | @Override | |
| 215 | public List<CustomFunction> customFunctions() { | |
| 216 |
1
1. customFunctions : replaced return value with Collections.emptyList for pro/verron/officestamper/core/DocxStamperConfiguration::customFunctions → KILLED |
return functions; |
| 217 | } | |
| 218 | ||
| 219 | /// Adds a custom function to the system, allowing integration of user-defined functionality. | |
| 220 | /// | |
| 221 | /// @param name The name of the custom function being added. This is used as the identifier for the function | |
| 222 | /// and must be unique across all defined functions. | |
| 223 | /// @param implementation A [Supplier] functional interface that provides the implementation of the custom | |
| 224 | /// function. When the function is called, the supplier's get method will be executed to return the result | |
| 225 | /// of the function. | |
| 226 | @Override | |
| 227 | public void addCustomFunction(String name, Supplier<?> implementation) { | |
| 228 |
2
1. lambda$addCustomFunction$0 : replaced return value with null for pro/verron/officestamper/core/DocxStamperConfiguration::lambda$addCustomFunction$0 → KILLED 2. addCustomFunction : removed call to pro/verron/officestamper/core/DocxStamperConfiguration::addCustomFunction → KILLED |
this.addCustomFunction(new CustomFunction(name, List.of(), _ -> implementation.get())); |
| 229 | } | |
| 230 | ||
| 231 | /// Adds a custom function to the list of functions. | |
| 232 | /// | |
| 233 | /// @param function the [CustomFunction] object to be added | |
| 234 | public void addCustomFunction(CustomFunction function) { | |
| 235 | this.functions.add(function); | |
| 236 | } | |
| 237 | ||
| 238 | /// Adds a custom function to the context with the specified name and type. | |
| 239 | /// | |
| 240 | /// @param name the name of the custom function | |
| 241 | /// @param class0 the class type of the custom function | |
| 242 | /// @param <T> the type of the input parameter | |
| 243 | /// @return an instance of [NeedsFunctionImpl] configured with the custom function | |
| 244 | @Override | |
| 245 | public <T> NeedsFunctionImpl<T> addCustomFunction(String name, Class<T> class0) { | |
| 246 |
1
1. addCustomFunction : replaced return value with null for pro/verron/officestamper/core/DocxStamperConfiguration::addCustomFunction → KILLED |
return new FunctionBuilder<>(this, name, class0); |
| 247 | } | |
| 248 | ||
| 249 | /// Adds a custom function with the specified name and input types. | |
| 250 | /// | |
| 251 | /// @param name the name of the custom function to be added | |
| 252 | /// @param class0 the class type of the first input parameter of the custom function. | |
| 253 | /// @param class1 the class type of the second input parameter of the custom function. | |
| 254 | /// @param <T> the type of the first input parameter | |
| 255 | /// @param <U> the type of the second input parameter | |
| 256 | /// @return an instance of [NeedsBiFunctionImpl] for further configuration or usage of the custom function. | |
| 257 | @Override | |
| 258 | public <T, U> NeedsBiFunctionImpl<T, U> addCustomFunction(String name, Class<T> class0, Class<U> class1) { | |
| 259 |
1
1. addCustomFunction : replaced return value with null for pro/verron/officestamper/core/DocxStamperConfiguration::addCustomFunction → KILLED |
return new BiFunctionBuilder<>(this, name, class0, class1); |
| 260 | } | |
| 261 | ||
| 262 | /// Adds a custom function to the current context by defining its name, and the classes associated with its argument | |
| 263 | /// types. | |
| 264 | /// | |
| 265 | /// @param name the name to assign to the custom function | |
| 266 | /// @param class0 the class of the first argument type | |
| 267 | /// @param class1 the class of the second argument type | |
| 268 | /// @param class2 the class of the third argument type | |
| 269 | /// @param <T> the type of the first argument | |
| 270 | /// @param <U> the type of the second argument | |
| 271 | /// @param <V> the type of the third argument | |
| 272 | /// @return an instance of [NeedsTriFunctionImpl] indicating the custom function implementation and usage context. | |
| 273 | @Override | |
| 274 | public <T, U, V> NeedsTriFunctionImpl<T, U, V> addCustomFunction( | |
| 275 | String name, | |
| 276 | Class<T> class0, | |
| 277 | Class<U> class1, | |
| 278 | Class<V> class2 | |
| 279 | ) { | |
| 280 |
1
1. addCustomFunction : replaced return value with null for pro/verron/officestamper/core/DocxStamperConfiguration::addCustomFunction → KILLED |
return new TriFunctionBuilder<>(this, name, class0, class1, class2); |
| 281 | } | |
| 282 | ||
| 283 | /// Retrieves the list of postprocessors. | |
| 284 | /// | |
| 285 | /// @return a List of [PostProcessor] objects. | |
| 286 | @Override | |
| 287 | public List<PostProcessor> getPostprocessors() { | |
| 288 |
1
1. getPostprocessors : replaced return value with Collections.emptyList for pro/verron/officestamper/core/DocxStamperConfiguration::getPostprocessors → KILLED |
return postprocessors; |
| 289 | } | |
| 290 | ||
| 291 | /// Adds a given postprocessor to the list of postprocessors. | |
| 292 | /// | |
| 293 | /// @param postprocessor the [PostProcessor] instance to be added | |
| 294 | @Override | |
| 295 | public void addPostprocessor(PostProcessor postprocessor) { | |
| 296 | postprocessors.add(postprocessor); | |
| 297 | } | |
| 298 | ||
| 299 | @Override | |
| 300 | public SpelParserConfiguration getParserConfiguration() { | |
| 301 |
1
1. getParserConfiguration : replaced return value with null for pro/verron/officestamper/core/DocxStamperConfiguration::getParserConfiguration → KILLED |
return parserConfiguration; |
| 302 | } | |
| 303 | ||
| 304 | /// Sets the parser configuration used for expression evaluation. | |
| 305 | /// | |
| 306 | /// Note that the provided parser configuration will be used for all expressions in the document, including | |
| 307 | /// expressions in comments. If you use SpEL, construct a [SpelExpressionParser] (optionally with a | |
| 308 | /// [SpelParserConfiguration]) and | |
| 309 | /// pass it here. | |
| 310 | /// | |
| 311 | /// @param parserConfiguration the parser to use. | |
| 312 | /// @return the configuration object for chaining. | |
| 313 | @Override | |
| 314 | public DocxStamperConfiguration setParserConfiguration(SpelParserConfiguration parserConfiguration) { | |
| 315 | this.parserConfiguration = parserConfiguration; | |
| 316 |
1
1. setParserConfiguration : replaced return value with null for pro/verron/officestamper/core/DocxStamperConfiguration::setParserConfiguration → KILLED |
return this; |
| 317 | } | |
| 318 | ||
| 319 | /// Gets the current SpEL security mode. | |
| 320 | @Override | |
| 321 | public SecurityMode getSpelSecurityMode() { | |
| 322 |
1
1. getSpelSecurityMode : replaced return value with null for pro/verron/officestamper/core/DocxStamperConfiguration::getSpelSecurityMode → NO_COVERAGE |
return spelSecurityMode; |
| 323 | } | |
| 324 | ||
| 325 | /// Sets the SpEL security mode. | |
| 326 | /// | |
| 327 | /// Note: The actual [EvaluationContextFactory] selection is handled by presets | |
| 328 | /// (e.g., in [OfficeStamperConfigurations]). This setter only stores the mode on the | |
| 329 | /// configuration to be honored by the stamping engine. | |
| 330 | @Override | |
| 331 | public DocxStamperConfiguration setSpelSecurityMode(SecurityMode mode) { | |
| 332 | this.spelSecurityMode = mode; | |
| 333 | // Adjust the EvaluationContextFactory here directly to honor the selected mode. | |
| 334 | this.evaluationContextFactory = switch (this.spelSecurityMode) { | |
| 335 | case RESTRICTED -> EvaluationContextFactories.restrictedFactory(); | |
| 336 | case PERMISSIVE -> EvaluationContextFactories.permissiveFactory(); | |
| 337 | }; | |
| 338 |
1
1. setSpelSecurityMode : replaced return value with null for pro/verron/officestamper/core/DocxStamperConfiguration::setSpelSecurityMode → KILLED |
return this; |
| 339 | } | |
| 340 | ||
| 341 | /// Indicates whether SVG safe mode is enabled. | |
| 342 | /// | |
| 343 | /// When enabled (default), SVG parsing is performed with hardened XML parser settings to mitigate XXE/DTD and | |
| 344 | /// related risks. When disabled, a more permissive parser is used. | |
| 345 | /// | |
| 346 | /// @return the current SVG security mode | |
| 347 | @Override | |
| 348 | public SecurityMode getSvgSecurityMode() { | |
| 349 |
1
1. getSvgSecurityMode : replaced return value with null for pro/verron/officestamper/core/DocxStamperConfiguration::getSvgSecurityMode → TIMED_OUT |
return svgSecurityMode; |
| 350 | } | |
| 351 | ||
| 352 | /// Enables or disables SVG safe mode. | |
| 353 | /// | |
| 354 | /// Safe mode is enabled by default to ensure secure SVG parsing. Disable only if you fully trust the SVG inputs | |
| 355 | /// and need permissive behavior. | |
| 356 | /// | |
| 357 | /// @param mode the SVG security mode to set | |
| 358 | /// @return the current instance of [DocxStamperConfiguration] | |
| 359 | @Override | |
| 360 | public DocxStamperConfiguration setSvgSecurityMode(SecurityMode mode) { | |
| 361 | this.svgSecurityMode = mode; | |
| 362 |
1
1. setSvgSecurityMode : replaced return value with null for pro/verron/officestamper/core/DocxStamperConfiguration::setSvgSecurityMode → TIMED_OUT |
return this; |
| 363 | } | |
| 364 | ||
| 365 | @Override | |
| 366 | public TraceabilityReporter getTraceabilityReporter() { | |
| 367 |
1
1. getTraceabilityReporter : replaced return value with null for pro/verron/officestamper/core/DocxStamperConfiguration::getTraceabilityReporter → KILLED |
return traceabilityReporter; |
| 368 | } | |
| 369 | ||
| 370 | @Override | |
| 371 | public OfficeStamperConfiguration setTraceabilityReporter(TraceabilityReporter traceabilityReporter) { | |
| 372 | this.traceabilityReporter = traceabilityReporter; | |
| 373 |
1
1. setTraceabilityReporter : replaced return value with null for pro/verron/officestamper/core/DocxStamperConfiguration::setTraceabilityReporter → NO_COVERAGE |
return this; |
| 374 | } | |
| 375 | } | |
Mutations | ||
| 84 |
1.1 |
|
| 100 |
1.1 |
|
| 116 |
1.1 |
|
| 127 |
1.1 |
|
| 136 |
1.1 |
|
| 145 |
1.1 |
|
| 153 |
1.1 |
|
| 161 |
1.1 |
|
| 175 |
1.1 |
|
| 177 |
1.1 |
|
| 189 |
1.1 |
|
| 190 |
1.1 |
|
| 198 |
1.1 |
|
| 208 |
1.1 |
|
| 216 |
1.1 |
|
| 228 |
1.1 2.2 |
|
| 246 |
1.1 |
|
| 259 |
1.1 |
|
| 280 |
1.1 |
|
| 288 |
1.1 |
|
| 301 |
1.1 |
|
| 316 |
1.1 |
|
| 322 |
1.1 |
|
| 338 |
1.1 |
|
| 349 |
1.1 |
|
| 362 |
1.1 |
|
| 367 |
1.1 |
|
| 373 |
1.1 |