diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/source/ConfigurationPropertyName.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/source/ConfigurationPropertyName.java index 584fa8c188d..87d237bc236 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/source/ConfigurationPropertyName.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/source/ConfigurationPropertyName.java @@ -20,8 +20,10 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.function.Function; +import java.util.function.IntFunction; import org.springframework.util.Assert; import org.springframework.util.StringUtils; @@ -63,10 +65,14 @@ public final class ConfigurationPropertyName implements Comparable getElement(i, Form.DASHED).replace('-', '.'))); + this.systemEnvironmentLegacyName = (name != null) ? name : EMPTY; } - return this.string; + return (name != EMPTY) ? name : null; } - private String buildToString() { + @Override + public String toString() { + return toString(ToStringFormat.DEFAULT); + } + + String toString(ToStringFormat format) { + String string = this.string[format.ordinal()]; + if (string == null) { + string = buildToString(format); + this.string[format.ordinal()] = string; + } + return string; + } + + private String buildToString(ToStringFormat format) { + return switch (format) { + case DEFAULT -> buildDefaultToString(); + case SYSTEM_ENVIRONMENT -> + buildSimpleToString('_', (i) -> getElement(i, Form.UNIFORM).toUpperCase(Locale.ENGLISH)); + case LEGACY_SYSTEM_ENVIRONMENT -> buildSimpleToString('_', + (i) -> getElement(i, Form.ORIGINAL).replace('-', '_').toUpperCase(Locale.ENGLISH)); + }; + } + + private String buildDefaultToString() { if (this.elements.canShortcutWithSource(ElementType.UNIFORM, ElementType.DASHED)) { return this.elements.getSource().toString(); } @@ -556,6 +588,32 @@ public final class ConfigurationPropertyName implements Comparable elementConverter) { + StringBuilder result = new StringBuilder(); + for (int i = 0; i < getNumberOfElements(); i++) { + if (!result.isEmpty()) { + result.append(joinChar); + } + result.append(elementConverter.apply(i)); + } + return result.toString(); + } + + boolean hasDashedElement() { + Boolean hasDashedElement = this.hasDashedElement; + if (hasDashedElement != null) { + return hasDashedElement; + } + for (int i = 0; i < getNumberOfElements(); i++) { + if (getElement(i, Form.DASHED).indexOf('-') != -1) { + this.hasDashedElement = true; + return true; + } + } + this.hasDashedElement = false; + return false; + } + /** * Returns if the given name is valid. If this method returns {@code true} then the * name may be used with {@link #of(CharSequence)} without throwing an exception. @@ -1132,4 +1190,13 @@ public final class ConfigurationPropertyName implements Comparable map(ConfigurationPropertyName configurationPropertyName) { - String name = convertName(configurationPropertyName); - String legacyName = convertLegacyName(configurationPropertyName); + String name = configurationPropertyName.toString(ToStringFormat.SYSTEM_ENVIRONMENT); + String legacyName = configurationPropertyName.toString(ToStringFormat.LEGACY_SYSTEM_ENVIRONMENT); if (name.equals(legacyName)) { return Collections.singletonList(name); } return Arrays.asList(name, legacyName); } - private String convertName(ConfigurationPropertyName name) { - return convertName(name, name.getNumberOfElements()); - } - - private String convertName(ConfigurationPropertyName name, int numberOfElements) { - StringBuilder result = new StringBuilder(); - for (int i = 0; i < numberOfElements; i++) { - if (!result.isEmpty()) { - result.append('_'); - } - result.append(name.getElement(i, Form.UNIFORM).toUpperCase(Locale.ENGLISH)); - } - return result.toString(); - } - - private String convertLegacyName(ConfigurationPropertyName name) { - StringBuilder result = new StringBuilder(); - for (int i = 0; i < name.getNumberOfElements(); i++) { - if (!result.isEmpty()) { - result.append('_'); - } - result.append(convertLegacyNameElement(name.getElement(i, Form.ORIGINAL))); - } - return result.toString(); - } - - private Object convertLegacyNameElement(String element) { - return element.replace('-', '_').toUpperCase(Locale.ENGLISH); - } - @Override public ConfigurationPropertyName map(String propertySourceName) { return convertName(propertySourceName); @@ -113,31 +83,11 @@ final class SystemEnvironmentPropertyMapper implements PropertyMapper { } private boolean isLegacyAncestorOf(ConfigurationPropertyName name, ConfigurationPropertyName candidate) { - if (!hasDashedEntries(name)) { + if (!name.hasDashedElement()) { return false; } - ConfigurationPropertyName legacyCompatibleName = buildLegacyCompatibleName(name); + ConfigurationPropertyName legacyCompatibleName = name.asSystemEnvironmentLegacyName(); return legacyCompatibleName != null && legacyCompatibleName.isAncestorOf(candidate); } - private ConfigurationPropertyName buildLegacyCompatibleName(ConfigurationPropertyName name) { - StringBuilder legacyCompatibleName = new StringBuilder(); - for (int i = 0; i < name.getNumberOfElements(); i++) { - if (i != 0) { - legacyCompatibleName.append('.'); - } - legacyCompatibleName.append(name.getElement(i, Form.DASHED).replace('-', '.')); - } - return ConfigurationPropertyName.ofIfValid(legacyCompatibleName); - } - - boolean hasDashedEntries(ConfigurationPropertyName name) { - for (int i = 0; i < name.getNumberOfElements(); i++) { - if (name.getElement(i, Form.DASHED).indexOf('-') != -1) { - return true; - } - } - return false; - } - }