|
| 1 | +package dev.openfeature.contrib.providers.envvar; |
| 2 | + |
| 3 | +import java.util.function.*; |
| 4 | + |
| 5 | +import lombok.RequiredArgsConstructor; |
| 6 | +import org.apache.commons.lang3.StringUtils; |
| 7 | +import org.apache.commons.text.CaseUtils; |
| 8 | + |
| 9 | +/** |
| 10 | + * This class provides a way to transform any given key to another value. This is helpful, if keys in the code have a |
| 11 | + * different representation as in the actual environment, e.g. SCREAMING_SNAKE_CASE env vars vs. hyphen-case keys |
| 12 | + * for feature flags. |
| 13 | + * |
| 14 | + * <p>This class also supports chaining/combining different transformers incl. self-written ones by providing |
| 15 | + * a transforming function in the constructor. <br> |
| 16 | + * Currently, the following transformations are supported out of the box: |
| 17 | + * <ul> |
| 18 | + * <li>{@link #toLowerCaseTransformer() converting to lower case}</li> |
| 19 | + * <li>{@link #toUpperCaseTransformer() converting to UPPER CASE}</li> |
| 20 | + * <li>{@link #hyphenCaseToScreamingSnake() converting hyphen-case to SCREAMING_SNAKE_CASE}</li> |
| 21 | + * <li>{@link #toCamelCaseTransformer() convert to camelCase}</li> |
| 22 | + * <li>{@link #replaceUnderscoreWithDotTransformer() replace '_' with '.'}</li> |
| 23 | + * <li>{@link #replaceDotWithUnderscoreTransformer() replace '.' with '_'}</li> |
| 24 | + * </ul> |
| 25 | + * |
| 26 | + * <p><strong>Examples:</strong> |
| 27 | + * |
| 28 | + * <p>1. hyphen-case feature flag names to screaming snake-case environment variables: |
| 29 | + * <pre> |
| 30 | + * {@code |
| 31 | + * // Definition of the EnvVarProvider: |
| 32 | + * EnvironmentKeyTransformer transformer = EnvironmentKeyTransformer |
| 33 | + * .hyphenCaseToScreamingSnake(); |
| 34 | + * |
| 35 | + * FeatureProvider provider = new EnvVarProvider(transformer); |
| 36 | + * } |
| 37 | + * </pre> |
| 38 | + * 2. chained/composed transformations: |
| 39 | + * <pre> |
| 40 | + * {@code |
| 41 | + * // Definition of the EnvVarProvider: |
| 42 | + * EnvironmentKeyTransformer transformer = EnvironmentKeyTransformer |
| 43 | + * .toLowerCaseTransformer() |
| 44 | + * .andThen(EnvironmentKeyTransformer.replaceUnderscoreWithDotTransformer()); |
| 45 | + * |
| 46 | + * FeatureProvider provider = new EnvVarProvider(transformer); |
| 47 | + * } |
| 48 | + * </pre> |
| 49 | + * 3. freely defined transformation function: |
| 50 | + * <pre> |
| 51 | + * {@code |
| 52 | + * |
| 53 | + * // Definition of the EnvVarProvider: |
| 54 | + * EnvironmentKeyTransformer transformer = new EnvironmentKeyTransformer(key -> "constant"); |
| 55 | + * |
| 56 | + * FeatureProvider provider = new EnvVarProvider(keyTransformer); |
| 57 | + * } |
| 58 | + * </pre> |
| 59 | + */ |
| 60 | +@RequiredArgsConstructor |
| 61 | +public class EnvironmentKeyTransformer { |
| 62 | + |
| 63 | + private static final UnaryOperator<String> TO_LOWER_CASE = StringUtils::lowerCase; |
| 64 | + private static final UnaryOperator<String> TO_UPPER_CASE = StringUtils::upperCase; |
| 65 | + private static final UnaryOperator<String> TO_CAMEL_CASE = s -> CaseUtils.toCamelCase(s, false, '_'); |
| 66 | + private static final UnaryOperator<String> REPLACE_DOT_WITH_UNDERSCORE = s -> StringUtils.replaceChars(s, ".", "_"); |
| 67 | + private static final UnaryOperator<String> REPLACE_UNDERSCORE_WITH_DOT = s -> StringUtils.replaceChars(s, "_", "."); |
| 68 | + private static final UnaryOperator<String> REPLACE_HYPHEN_WITH_UNDERSCORE = |
| 69 | + s -> StringUtils.replaceChars(s, "-", "_"); |
| 70 | + |
| 71 | + private final Function<String, String> transformation; |
| 72 | + |
| 73 | + public String transformKey(String key) { |
| 74 | + return transformation.apply(key); |
| 75 | + } |
| 76 | + |
| 77 | + public EnvironmentKeyTransformer andThen(EnvironmentKeyTransformer another) { |
| 78 | + return new EnvironmentKeyTransformer(transformation.andThen(another::transformKey)); |
| 79 | + } |
| 80 | + |
| 81 | + public static EnvironmentKeyTransformer toLowerCaseTransformer() { |
| 82 | + return new EnvironmentKeyTransformer(TO_LOWER_CASE); |
| 83 | + } |
| 84 | + |
| 85 | + public static EnvironmentKeyTransformer toUpperCaseTransformer() { |
| 86 | + return new EnvironmentKeyTransformer(TO_UPPER_CASE); |
| 87 | + } |
| 88 | + |
| 89 | + public static EnvironmentKeyTransformer toCamelCaseTransformer() { |
| 90 | + return new EnvironmentKeyTransformer(TO_CAMEL_CASE); |
| 91 | + } |
| 92 | + |
| 93 | + public static EnvironmentKeyTransformer replaceUnderscoreWithDotTransformer() { |
| 94 | + return new EnvironmentKeyTransformer(REPLACE_UNDERSCORE_WITH_DOT); |
| 95 | + } |
| 96 | + |
| 97 | + public static EnvironmentKeyTransformer replaceDotWithUnderscoreTransformer() { |
| 98 | + return new EnvironmentKeyTransformer(REPLACE_DOT_WITH_UNDERSCORE); |
| 99 | + } |
| 100 | + |
| 101 | + public static EnvironmentKeyTransformer hyphenCaseToScreamingSnake() { |
| 102 | + return new EnvironmentKeyTransformer(REPLACE_HYPHEN_WITH_UNDERSCORE) |
| 103 | + .andThen(EnvironmentKeyTransformer.toUpperCaseTransformer()); |
| 104 | + } |
| 105 | + |
| 106 | + public static EnvironmentKeyTransformer doNothing() { |
| 107 | + return new EnvironmentKeyTransformer(s -> s); |
| 108 | + } |
| 109 | +} |
0 commit comments