Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Check property name variations #27

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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):
* <ul>
* <li>requested name</li>
* <li>requested name replacing dots, dashes or both by underscores</li>
* <li>requested name in uppercase</li>
* <li>requested name in uppercase replacing dots, dashes or both by underscores</li>
* </ul>
*
* @param name the property to find
* @see PropertyResolver#getRequiredProperty(String)
Expand All @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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");
}
}