From 9e05e1dcaa8204cc05314f48798f674e4415f660 Mon Sep 17 00:00:00 2001 From: Pascal Verdage Date: Mon, 16 Oct 2023 11:21:55 +0200 Subject: [PATCH] Check property name variations Apply relaxed binding as spring boot implementations --- .../springdotenv/DotenvPropertyLoader.java | 4 ++ .../springdotenv/DotenvPropertySource.java | 60 ++++++++++++++++++- .../DotenvPropertySourceTest.java | 15 +++++ 3 files changed, 77 insertions(+), 2 deletions(-) diff --git a/library/src/main/java/me/paulschwarz/springdotenv/DotenvPropertyLoader.java b/library/src/main/java/me/paulschwarz/springdotenv/DotenvPropertyLoader.java index 43b6c55..dd26326 100644 --- a/library/src/main/java/me/paulschwarz/springdotenv/DotenvPropertyLoader.java +++ b/library/src/main/java/me/paulschwarz/springdotenv/DotenvPropertyLoader.java @@ -32,4 +32,8 @@ public DotenvPropertyLoader(DotenvConfig dotenvConfig) { public Object getValue(String key) { return dotenv.get(key); } + + boolean containsProperty(String key) { + return getValue(key) != null; + } } diff --git a/library/src/main/java/me/paulschwarz/springdotenv/DotenvPropertySource.java b/library/src/main/java/me/paulschwarz/springdotenv/DotenvPropertySource.java index 8a45009..cb982df 100644 --- a/library/src/main/java/me/paulschwarz/springdotenv/DotenvPropertySource.java +++ b/library/src/main/java/me/paulschwarz/springdotenv/DotenvPropertySource.java @@ -48,6 +48,14 @@ public DotenvPropertySource(DotenvConfig dotenvConfig) { /** * Return the value associated with the given name, or {@code null} if not found. + * Handles Spring Boot relaxed binding by allowing multiple naming conventions + * for the property name (omitting the preifx): + * * * @param name the property to find * @see PropertyResolver#getRequiredProperty(String) @@ -58,15 +66,63 @@ public Object getProperty(String name) { return null; } - Object value = getSource().getValue(name.substring(prefix.length())); + String noPrefix = name.substring(prefix.length()); - if (Objects.nonNull(value)) { + String actualName = resolvePropertyName(noPrefix); + if (log.isTraceEnabled() && !name.equals(actualName)) { + logger.trace(LogMessage.format("PropertySource \"%s\" does not contain " + + "property \"%s\", but found equivalent \"%s\"", getName(), name, actualName)); + } + Object value = getSource().getValue(actualName); + + if (Objects.nonNull(value) && log.isTraceEnabled()) { log.trace(LogMessage.format("Got env property for \"%s\"", name)); } return value; } + protected final String resolvePropertyName(String name) { + Objects.requireNonNull(name, "Property name must not be null"); + String resolvedName = checkPropertySymbolVariants(name); + if (resolvedName != null) { + return resolvedName; + } + String uppercaseName = name.toUpperCase(); + if (!name.equals(uppercaseName)) { + resolvedName = checkPropertySymbolVariants(uppercaseName); + if (resolvedName != null) { + return resolvedName; + } + } + return name; + } + + @Nullable + private String checkPropertySymbolVariants(String name) { + // Check name as-is + if (this.getSource().containsProperty(name)) { + return name; + } + // Check name with just dots replaced + String noDotName = name.replace('.', '_'); + if (!name.equals(noDotName) && this.source.containsProperty(noDotName)) { + return noDotName; + } + // Check name with just hyphens replaced + String noHyphenName = name.replace('-', '_'); + if (!name.equals(noHyphenName) && this.source.containsProperty(noHyphenName)) { + return noHyphenName; + } + // Check name with dots and hyphens replaced + String noDotNoHyphenName = noDotName.replace('-', '_'); + if (!noDotName.equals(noDotNoHyphenName) && this.source.containsProperty(noDotNoHyphenName)) { + return noDotNoHyphenName; + } + // Give up + return null; + } + public static void addToEnvironment(ConfigurableEnvironment environment) { DotenvConfig dotenvConfig = new DotenvConfig(DotenvConfigProperties.loadProperties()); DotenvPropertySource dotenvPropertySource = new DotenvPropertySource(dotenvConfig); diff --git a/library/src/test/java/me/paulschwarz/springdotenv/DotenvPropertySourceTest.java b/library/src/test/java/me/paulschwarz/springdotenv/DotenvPropertySourceTest.java index 7dd2b62..c7509c4 100644 --- a/library/src/test/java/me/paulschwarz/springdotenv/DotenvPropertySourceTest.java +++ b/library/src/test/java/me/paulschwarz/springdotenv/DotenvPropertySourceTest.java @@ -40,4 +40,19 @@ void valueFromEnvironment() { void valueFromEnvironmentOverride() { assertThat(source.getProperty("EXAMPLE_MESSAGE_3")).isEqualTo("Message 3 from system environment"); } + + @Test + void valueFromEnvironmentAsLowerCaseWithDots() { + assertThat(source.getProperty("example.message.2")).isEqualTo("Message 2 from system environment"); + } + + @Test + void valueFromEnvironmentAsLowerCaseWithDashes() { + assertThat(source.getProperty("example-message-2")).isEqualTo("Message 2 from system environment"); + } + + @Test + void valueFromEnvironmentAsLowerCaseWithDotsAndDashes() { + assertThat(source.getProperty("example.message-2")).isEqualTo("Message 2 from system environment"); + } }