1
1
package de .exlll .configlib ;
2
2
3
3
import java .lang .reflect .Type ;
4
- import java .util .Collections ;
5
- import java .util .HashMap ;
6
- import java .util .LinkedHashMap ;
7
- import java .util .Map ;
4
+ import java .util .*;
8
5
import java .util .function .Function ;
9
6
import java .util .function .Predicate ;
10
7
import java .util .function .UnaryOperator ;
@@ -28,6 +25,7 @@ public class ConfigurationProperties {
28
25
private final boolean outputNulls ;
29
26
private final boolean inputNulls ;
30
27
private final boolean serializeSetsAsLists ;
28
+ private final EnvVarResolutionConfiguration envVarResolutionConfiguration ;
31
29
32
30
/**
33
31
* Constructs a new instance of this class with values taken from the given builder.
@@ -49,6 +47,10 @@ protected ConfigurationProperties(Builder<?> builder) {
49
47
this .outputNulls = builder .outputNulls ;
50
48
this .inputNulls = builder .inputNulls ;
51
49
this .serializeSetsAsLists = builder .serializeSetsAsLists ;
50
+ this .envVarResolutionConfiguration = requireNonNull (
51
+ builder .envVarResolutionConfiguration ,
52
+ "environment variable resolution configuration"
53
+ );
52
54
}
53
55
54
56
/**
@@ -100,9 +102,18 @@ public static abstract class Builder<B extends Builder<B>> {
100
102
private boolean outputNulls = false ;
101
103
private boolean inputNulls = false ;
102
104
private boolean serializeSetsAsLists = true ;
105
+ private EnvVarResolutionConfiguration envVarResolutionConfiguration
106
+ = EnvVarResolutionConfiguration .disabled ();
103
107
108
+ /** Default constructor */
104
109
protected Builder () {}
105
110
111
+ /**
112
+ * A constructor that initializes the values of this builder with the values
113
+ * of the given {@code ConfigurationProperties} object.
114
+ *
115
+ * @param properties the properties used to initialize the values of this builder
116
+ */
106
117
protected Builder (ConfigurationProperties properties ) {
107
118
this .serializersByType .putAll (properties .serializersByType );
108
119
this .serializerFactoriesByType .putAll (properties .serializerFactoriesByType );
@@ -113,6 +124,7 @@ protected Builder(ConfigurationProperties properties) {
113
124
this .outputNulls = properties .outputNulls ;
114
125
this .inputNulls = properties .inputNulls ;
115
126
this .serializeSetsAsLists = properties .serializeSetsAsLists ;
127
+ this .envVarResolutionConfiguration = properties .envVarResolutionConfiguration ;
116
128
}
117
129
118
130
/**
@@ -289,6 +301,26 @@ final B serializeSetsAsLists(boolean serializeSetsAsLists) {
289
301
return getThis ();
290
302
}
291
303
304
+ /**
305
+ * Configures whether and how environment variables should be resolved.
306
+ * <p>
307
+ * The default is {@link EnvVarResolutionConfiguration#disabled()} which
308
+ * is a configuration that disables the resolution of environment variables.
309
+ *
310
+ * @param configuration the {@code EnvVarResolutionConfiguration}
311
+ * @return this builder
312
+ * @throws NullPointerException if {@code configuration} is null
313
+ */
314
+ public final B setEnvVarResolutionConfiguration (
315
+ EnvVarResolutionConfiguration configuration
316
+ ) {
317
+ this .envVarResolutionConfiguration = requireNonNull (
318
+ configuration ,
319
+ "environment variable resolution configuration"
320
+ );
321
+ return getThis ();
322
+ }
323
+
292
324
/**
293
325
* Builds a {@code ConfigurationProperties} instance.
294
326
*
@@ -304,6 +336,139 @@ final B serializeSetsAsLists(boolean serializeSetsAsLists) {
304
336
protected abstract B getThis ();
305
337
}
306
338
339
+ /**
340
+ * A collection of values used to configure the resolution of environment variables.
341
+ */
342
+ public static final class EnvVarResolutionConfiguration {
343
+ private static final EnvVarResolutionConfiguration DISABLED =
344
+ new EnvVarResolutionConfiguration ();
345
+ private final boolean resolveEnvVars ;
346
+ private final String prefix ;
347
+ private final boolean caseSensitive ;
348
+
349
+ /**
350
+ * Returns a configuration object that disables the resolution of
351
+ * environment variables.
352
+ *
353
+ * @return configuration object that disables the resolution of
354
+ * environment variables.
355
+ */
356
+ public static EnvVarResolutionConfiguration disabled () {
357
+ return DISABLED ;
358
+ }
359
+
360
+ /**
361
+ * Returns a configuration object that resolves environment variables
362
+ * that start with the given prefix. Specifying a non-empty prefix that
363
+ * is specific to your project is highly recommended.
364
+ * <p>
365
+ * On UNIX systems environment variables are case-sensitive.
366
+ * On Windows they are case-insensitive.
367
+ * <ul>
368
+ * <li>
369
+ * If you want to (or have to, because you are on Windows) target the
370
+ * values of your configuration using uppercase environment variables,
371
+ * then you have to disable case-sensitive resolution.
372
+ * <p>
373
+ * For example, if you have a YAML configuration with the following content
374
+ * <pre>
375
+ * alPHA:
376
+ * be_ta: 1
377
+ * ga_mma:
378
+ * dELTa: 2
379
+ * </pre>
380
+ * then, with {@code caseSensitive} set to {@code false}, you can overwrite
381
+ * the values 1 and 2 using the environment variables
382
+ * {@code ALPHA_BE_TA} and {@code GA_MMA_DELTA}, respectively.
383
+ * </li>
384
+ * <li>
385
+ * If your configuration contains paths that differ only in their case,
386
+ * but are otherwise the same, and if you want to target these paths
387
+ * individually, then you have to enable case-sensitive resolution.
388
+ * <p>
389
+ * For example, if you have a YAML configuration with the following content
390
+ * <pre>
391
+ * alpha:
392
+ * beta: 1
393
+ * ALPHA:
394
+ * BETA: 2
395
+ * </pre>
396
+ * and you want to target the values of {@code beta} and {@code BETA}
397
+ * individually, then you have to set {@code caseSensitive} to {@code true}.
398
+ * After doing so you can overwrite the values 1 and 2 by using the environment
399
+ * variables {@code alpha_beta} and {@code ALPHA_BETA}, respectively.
400
+ * </li>
401
+ * <li>
402
+ * If you specify a non-empty prefix, then all variables that you want to
403
+ * be resolved have to start with that prefix. For example, if you choose
404
+ * {@code MY_PREFIX_} as your prefix, then the four variables listed
405
+ * above have to be named {@code MY_PREFIX_ALPHA_BE_TA},
406
+ * {@code MY_PREFIX_GA_MMA_DELTA}, {@code MY_PREFIX_alpha_beta}, and
407
+ * {@code MY_PREFIX_ALPHA_BETA}, respectively.
408
+ * </li>
409
+ * </ul>
410
+ *
411
+ * @param prefix string the environment variables have to be prefixed with
412
+ * @param caseSensitive specifies whether the resolution should be case-sensitive
413
+ * @return configuration object that resolves environment variables
414
+ * that start with the given prefix
415
+ * @throws NullPointerException if {@code prefix} is null
416
+ */
417
+ public static EnvVarResolutionConfiguration resolveEnvVarsWithPrefix (
418
+ String prefix ,
419
+ boolean caseSensitive
420
+ ) {
421
+ return new EnvVarResolutionConfiguration (true , prefix , caseSensitive );
422
+ }
423
+
424
+ private EnvVarResolutionConfiguration () {
425
+ this (false , "" , false );
426
+ }
427
+
428
+ // create 'Builder' class if more configuration options are added
429
+ private EnvVarResolutionConfiguration (
430
+ boolean resolveEnvVars ,
431
+ String prefix ,
432
+ boolean caseSensitive
433
+ ) {
434
+ this .resolveEnvVars = resolveEnvVars ;
435
+ this .prefix = requireNonNull (prefix , "prefix" );
436
+ this .caseSensitive = caseSensitive ;
437
+ }
438
+
439
+ /**
440
+ * Returns whether environment variables should be resolved.
441
+ *
442
+ * @return whether environment variables should be resolved
443
+ */
444
+ public boolean resolveEnvVars () {
445
+ return resolveEnvVars ;
446
+ }
447
+
448
+ /**
449
+ * Returns the string with which the environment variables must begin
450
+ * in order to be resolved.
451
+ *
452
+ * @return the string environment variables have to begin with to be resolved
453
+ * @see EnvVarResolutionConfiguration#resolveEnvVarsWithPrefix(String, boolean)
454
+ */
455
+ public String prefix () {
456
+ return prefix ;
457
+ }
458
+
459
+ /**
460
+ * Returns whether the resolution of environment variables should be
461
+ * case-sensitive.
462
+ *
463
+ * @return whether the resolution of environment variables should be
464
+ * case-sensitive
465
+ * @see EnvVarResolutionConfiguration#resolveEnvVarsWithPrefix(String, boolean)
466
+ */
467
+ public boolean caseSensitive () {
468
+ return caseSensitive ;
469
+ }
470
+ }
471
+
307
472
/**
308
473
* Returns the field filter used to filter the fields of a configuration class.
309
474
*
@@ -388,4 +553,14 @@ public final boolean inputNulls() {
388
553
final boolean serializeSetsAsLists () {
389
554
return serializeSetsAsLists ;
390
555
}
556
+
557
+ /**
558
+ * Returns the configuration that determines whether and how environment
559
+ * variables should be resolved.
560
+ *
561
+ * @return the configuration
562
+ */
563
+ public final EnvVarResolutionConfiguration getEnvVarResolutionConfiguration () {
564
+ return envVarResolutionConfiguration ;
565
+ }
391
566
}
0 commit comments