diff --git a/buildSrc/src/main/java/org/springframework/boot/build/architecture/ArchitectureCheck.java b/buildSrc/src/main/java/org/springframework/boot/build/architecture/ArchitectureCheck.java index 8fd11ee1286d..2995bdff9928 100644 --- a/buildSrc/src/main/java/org/springframework/boot/build/architecture/ArchitectureCheck.java +++ b/buildSrc/src/main/java/org/springframework/boot/build/architecture/ArchitectureCheck.java @@ -87,6 +87,8 @@ public ArchitectureCheck() { .classFor(getAnnotationClasses().get(), ArchitectureCheckAnnotation.CONDITIONAL_ON_MISSING_BEAN)))); getRules().addAll(whenMainSources(() -> ArchitectureRules.configurationProperties(ArchitectureCheckAnnotation .classFor(getAnnotationClasses().get(), ArchitectureCheckAnnotation.CONFIGURATION_PROPERTIES)))); + getRules().addAll(whenMainSources(() -> ArchitectureRules.configurationProperties(ArchitectureCheckAnnotation + .classFor(getAnnotationClasses().get(), ArchitectureCheckAnnotation.CONFIGURATION_PROPERTIES_SOURCE)))); getRules().addAll(whenMainSources( () -> ArchitectureRules.configurationPropertiesBinding(ArchitectureCheckAnnotation.classFor( getAnnotationClasses().get(), ArchitectureCheckAnnotation.CONFIGURATION_PROPERTIES_BINDING)))); diff --git a/buildSrc/src/main/java/org/springframework/boot/build/architecture/ArchitectureCheckAnnotation.java b/buildSrc/src/main/java/org/springframework/boot/build/architecture/ArchitectureCheckAnnotation.java index 991bdaa7c27a..bd7ff6d6ea75 100644 --- a/buildSrc/src/main/java/org/springframework/boot/build/architecture/ArchitectureCheckAnnotation.java +++ b/buildSrc/src/main/java/org/springframework/boot/build/architecture/ArchitectureCheckAnnotation.java @@ -42,6 +42,11 @@ public enum ArchitectureCheckAnnotation { */ CONFIGURATION_PROPERTIES, + /** + * Configuration properties source. + */ + CONFIGURATION_PROPERTIES_SOURCE, + /** * Deprecated configuration property. */ @@ -56,6 +61,8 @@ public enum ArchitectureCheckAnnotation { "org.springframework.boot.autoconfigure.condition.ConditionalOnClass", CONDITIONAL_ON_MISSING_BEAN.name(), "org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean", CONFIGURATION_PROPERTIES.name(), "org.springframework.boot.context.properties.ConfigurationProperties", + CONFIGURATION_PROPERTIES_SOURCE.name(), + "org.springframework.boot.context.properties.ConfigurationPropertiesSource", DEPRECATED_CONFIGURATION_PROPERTY.name(), "org.springframework.boot.context.properties.DeprecatedConfigurationProperty", CONFIGURATION_PROPERTIES_BINDING.name(), diff --git a/buildSrc/src/main/java/org/springframework/boot/build/architecture/ArchitectureRules.java b/buildSrc/src/main/java/org/springframework/boot/build/architecture/ArchitectureRules.java index bfb0460d68a8..b6c2440c4e97 100644 --- a/buildSrc/src/main/java/org/springframework/boot/build/architecture/ArchitectureRules.java +++ b/buildSrc/src/main/java/org/springframework/boot/build/architecture/ArchitectureRules.java @@ -37,7 +37,10 @@ import com.tngtech.archunit.core.domain.JavaClass.Predicates; import com.tngtech.archunit.core.domain.JavaClasses; import com.tngtech.archunit.core.domain.JavaConstructor; +import com.tngtech.archunit.core.domain.JavaConstructorCall; import com.tngtech.archunit.core.domain.JavaField; +import com.tngtech.archunit.core.domain.JavaFieldAccess; +import com.tngtech.archunit.core.domain.JavaFieldAccess.AccessType; import com.tngtech.archunit.core.domain.JavaMember; import com.tngtech.archunit.core.domain.JavaMethod; import com.tngtech.archunit.core.domain.JavaModifier; @@ -77,6 +80,7 @@ * @author Ngoc Nhan * @author Moritz Halbritter * @author Stefano Cordio + * @author Venkata Naga Sai Srikanth Gollapudi */ final class ArchitectureRules { @@ -126,7 +130,11 @@ static List conditionalOnMissingBean(String annotationClass) { static List configurationProperties(String annotationClass) { return List.of(classLevelConfigurationPropertiesShouldNotSpecifyOnlyPrefixAttribute(annotationClass), - methodLevelConfigurationPropertiesShouldNotSpecifyOnlyPrefixAttribute(annotationClass)); + methodLevelConfigurationPropertiesShouldNotSpecifyOnlyPrefixAttribute(annotationClass), + configurationPropertyOfTypeShouldUseImplementation(annotationClass, "java.util.Set", + List.of("java.util.LinkedHashSet")), + configurationPropertyOfTypeShouldUseImplementation(annotationClass, "java.util.Map", + List.of("java.util.LinkedHashMap", "java.util.EnumMap"))); } static List configurationPropertiesBinding(String annotationClass) { @@ -428,6 +436,54 @@ private static ArchRule allDeprecatedConfigurationPropertiesShouldIncludeSince(S .allowEmptyShould(true); } + private static ArchRule configurationPropertyOfTypeShouldUseImplementation(String annotationClass, + String propertyType, List allowedImplementations) { + return ArchRuleDefinition.classes() + .that() + .areAnnotatedWith(annotationClass) + .or(areNestedInClassAnnotatedWith(annotationClass)) + .should(useAllowedImplementationForProperties(propertyType, allowedImplementations)) + .allowEmptyShould(true); + } + + private static ArchCondition useAllowedImplementationForProperties(String propertyType, + List allowedImplementations) { + return check( + "use %s for properties of type %s".formatted(String.join(" or ", allowedImplementations), propertyType), + (javaClass, events) -> javaClass.getFields() + .stream() + .filter((field) -> propertyType.equals(field.getRawType().getName())) + .forEach((field) -> checkPropertyImplementation(field, allowedImplementations, events))); + } + + private static void checkPropertyImplementation(JavaField field, List allowedImplementations, + ConditionEvents events) { + field.getAccessesToSelf() + .stream() + .filter((access) -> access.getAccessType() == AccessType.SET) + .flatMap((access) -> initializerConstructorCalls(access).stream()) + .filter((call) -> !allowedImplementations.contains(call.getTargetOwner().getName())) + .forEach((call) -> addViolation(events, field, + "%s should be initialized with %s instead of %s".formatted(field.getDescription(), + String.join(" or ", allowedImplementations), call.getTargetOwner().getName()))); + } + + private static List initializerConstructorCalls(JavaFieldAccess fieldAccess) { + return fieldAccess.getOrigin() + .getConstructorCallsFromSelf() + .stream() + .filter((call) -> call.getLineNumber() == fieldAccess.getLineNumber()) + .toList(); + } + + private static DescribedPredicate areNestedInClassAnnotatedWith(String annotationClass) { + return DescribedPredicate.describe("one of its inner class", + (javaClass) -> javaClass.getEnclosingClass() + .map((enclosing) -> enclosing.isAnnotatedWith(annotationClass) + || areNestedInClassAnnotatedWith(annotationClass).test(enclosing)) + .orElse(false)); + } + private static ArchRule autoConfigurationClassesShouldBePublicAndFinal() { return ArchRuleDefinition.classes() .that(areRegularAutoConfiguration()) diff --git a/buildSrc/src/test/java/org/springframework/boot/build/architecture/ArchitectureCheckTests.java b/buildSrc/src/test/java/org/springframework/boot/build/architecture/ArchitectureCheckTests.java index 0686e00a60fe..62224bcefa95 100644 --- a/buildSrc/src/test/java/org/springframework/boot/build/architecture/ArchitectureCheckTests.java +++ b/buildSrc/src/test/java/org/springframework/boot/build/architecture/ArchitectureCheckTests.java @@ -47,6 +47,7 @@ import org.springframework.boot.build.architecture.annotations.TestConditionalOnMissingBean; import org.springframework.boot.build.architecture.annotations.TestConfigurationProperties; import org.springframework.boot.build.architecture.annotations.TestConfigurationPropertiesBinding; +import org.springframework.boot.build.architecture.annotations.TestConfigurationPropertiesSource; import org.springframework.boot.build.architecture.annotations.TestDeprecatedConfigurationProperty; import org.springframework.util.ClassUtils; import org.springframework.util.FileSystemUtils; @@ -62,6 +63,7 @@ * @author Ivan Malutin * @author Dmytro Nosan * @author Stefano Cordio + * @author Venkata Naga Sai Srikanth Gollapudi */ class ArchitectureCheckTests { @@ -331,6 +333,76 @@ void whenMethodLevelConfigurationPropertiesContainsOnlyValueShouldSucceedAndWrit Task.CHECK_ARCHITECTURE_MAIN); } + @Test + void whenConfigurationPropertiesUsesHashMapShouldFailAndWriteReport() throws IOException { + prepareTask(Task.CHECK_ARCHITECTURE_MAIN, "configurationproperties/hashmap", "annotations"); + buildAndFail(this.gradleBuild.withDependencies(SPRING_CONTEXT).withConfigurationPropertiesAnnotation(), + Task.CHECK_ARCHITECTURE_MAIN, "should be initialized with java.util.LinkedHashMap"); + } + + @Test + void whenConfigurationPropertiesSourceUsesHashMapShouldFailAndWriteReport() throws IOException { + prepareTask(Task.CHECK_ARCHITECTURE_MAIN, "configurationpropertiessource/hashmap", "annotations"); + buildAndFail(this.gradleBuild.withDependencies(SPRING_CONTEXT).withConfigurationPropertiesSourceAnnotation(), + Task.CHECK_ARCHITECTURE_MAIN, "should be initialized with java.util.LinkedHashMap"); + } + + @Test + void whenConfigurationPropertiesUsesHashSetShouldFailAndWriteReport() throws IOException { + prepareTask(Task.CHECK_ARCHITECTURE_MAIN, "configurationproperties/hashset", "annotations"); + buildAndFail(this.gradleBuild.withDependencies(SPRING_CONTEXT).withConfigurationPropertiesAnnotation(), + Task.CHECK_ARCHITECTURE_MAIN, "should be initialized with java.util.LinkedHashSet"); + } + + @Test + void whenConfigurationPropertiesSourceUsesHashSetShouldFailAndWriteReport() throws IOException { + prepareTask(Task.CHECK_ARCHITECTURE_MAIN, "configurationpropertiessource/hashset", "annotations"); + buildAndFail(this.gradleBuild.withDependencies(SPRING_CONTEXT).withConfigurationPropertiesSourceAnnotation(), + Task.CHECK_ARCHITECTURE_MAIN, "should be initialized with java.util.LinkedHashSet"); + } + + @Test + void whenConfigurationPropertiesUsesLinkedHashMapShouldSucceedAndWriteEmptyReport() throws IOException { + prepareTask(Task.CHECK_ARCHITECTURE_MAIN, "configurationproperties/linkedhashmap", "annotations"); + build(this.gradleBuild.withDependencies(SPRING_CONTEXT).withConfigurationPropertiesAnnotation(), + Task.CHECK_ARCHITECTURE_MAIN); + } + + @Test + void whenConfigurationPropertiesSourceUsesLinkedHashMapShouldSucceedAndWriteEmptyReport() throws IOException { + prepareTask(Task.CHECK_ARCHITECTURE_MAIN, "configurationpropertiessource/linkedhashmap", "annotations"); + build(this.gradleBuild.withDependencies(SPRING_CONTEXT).withConfigurationPropertiesSourceAnnotation(), + Task.CHECK_ARCHITECTURE_MAIN); + } + + @Test + void whenConfigurationPropertiesUsesEnumMapShouldSucceedAndWriteEmptyReport() throws IOException { + prepareTask(Task.CHECK_ARCHITECTURE_MAIN, "configurationproperties/enummap", "annotations"); + build(this.gradleBuild.withDependencies(SPRING_CONTEXT).withConfigurationPropertiesAnnotation(), + Task.CHECK_ARCHITECTURE_MAIN); + } + + @Test + void whenConfigurationPropertiesSourceUsesEnumMapShouldSucceedAndWriteEmptyReport() throws IOException { + prepareTask(Task.CHECK_ARCHITECTURE_MAIN, "configurationpropertiessource/enummap", "annotations"); + build(this.gradleBuild.withDependencies(SPRING_CONTEXT).withConfigurationPropertiesSourceAnnotation(), + Task.CHECK_ARCHITECTURE_MAIN); + } + + @Test + void whenConfigurationPropertiesUsesLinkedHashSetShouldSucceedAndWriteEmptyReport() throws IOException { + prepareTask(Task.CHECK_ARCHITECTURE_MAIN, "configurationproperties/linkedhashset", "annotations"); + build(this.gradleBuild.withDependencies(SPRING_CONTEXT).withConfigurationPropertiesAnnotation(), + Task.CHECK_ARCHITECTURE_MAIN); + } + + @Test + void whenConfigurationPropertiesSourceUsesLinkedHashSetShouldSucceedAndWriteEmptyReport() throws IOException { + prepareTask(Task.CHECK_ARCHITECTURE_MAIN, "configurationpropertiessource/linkedhashset", "annotations"); + build(this.gradleBuild.withDependencies(SPRING_CONTEXT).withConfigurationPropertiesSourceAnnotation(), + Task.CHECK_ARCHITECTURE_MAIN); + } + @Test void whenConfigurationPropertiesBindingBeanMethodIsNotStaticShouldFailAndWriteReport() throws IOException { prepareTask(Task.CHECK_ARCHITECTURE_MAIN, "configurationproperties/bindingnonstatic", "annotations"); @@ -568,6 +640,12 @@ GradleBuild withConfigurationPropertiesAnnotation() { return this; } + GradleBuild withConfigurationPropertiesSourceAnnotation() { + configureTasks(ArchitectureCheckAnnotation.CONFIGURATION_PROPERTIES_SOURCE.name(), + TestConfigurationPropertiesSource.class.getName()); + return this; + } + GradleBuild withConfigurationPropertiesBindingAnnotation() { configureTasks(ArchitectureCheckAnnotation.CONFIGURATION_PROPERTIES_BINDING.name(), TestConfigurationPropertiesBinding.class.getName()); diff --git a/buildSrc/src/test/java/org/springframework/boot/build/architecture/annotations/TestConfigurationPropertiesSource.java b/buildSrc/src/test/java/org/springframework/boot/build/architecture/annotations/TestConfigurationPropertiesSource.java new file mode 100644 index 000000000000..d4529eceef43 --- /dev/null +++ b/buildSrc/src/test/java/org/springframework/boot/build/architecture/annotations/TestConfigurationPropertiesSource.java @@ -0,0 +1,28 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.build.architecture.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ ElementType.TYPE, ElementType.METHOD }) +@Retention(RetentionPolicy.RUNTIME) +public @interface TestConfigurationPropertiesSource { + +} diff --git a/buildSrc/src/test/java/org/springframework/boot/build/architecture/configurationproperties/enummap/ConfigurationPropertiesWithEnumMap.java b/buildSrc/src/test/java/org/springframework/boot/build/architecture/configurationproperties/enummap/ConfigurationPropertiesWithEnumMap.java new file mode 100644 index 000000000000..f3fa73b9cb30 --- /dev/null +++ b/buildSrc/src/test/java/org/springframework/boot/build/architecture/configurationproperties/enummap/ConfigurationPropertiesWithEnumMap.java @@ -0,0 +1,48 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.build.architecture.configurationproperties.enummap; + +import java.util.EnumMap; +import java.util.Map; + +import org.springframework.boot.build.architecture.annotations.TestConfigurationProperties; + +/** + * Test {@link TestConfigurationProperties} using {@link EnumMap}. + * + * @author Venkata Naga Sai Srikanth Gollapudi + */ +@TestConfigurationProperties("testing") +public class ConfigurationPropertiesWithEnumMap { + + private Map properties = new EnumMap<>(Example.class); + + public Map getProperties() { + return this.properties; + } + + public void setProperties(Map properties) { + this.properties = properties; + } + + enum Example { + + ONE + + } + +} diff --git a/buildSrc/src/test/java/org/springframework/boot/build/architecture/configurationproperties/hashmap/ConfigurationPropertiesWithHashMap.java b/buildSrc/src/test/java/org/springframework/boot/build/architecture/configurationproperties/hashmap/ConfigurationPropertiesWithHashMap.java new file mode 100644 index 000000000000..1668ccc84af7 --- /dev/null +++ b/buildSrc/src/test/java/org/springframework/boot/build/architecture/configurationproperties/hashmap/ConfigurationPropertiesWithHashMap.java @@ -0,0 +1,42 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.build.architecture.configurationproperties.hashmap; + +import java.util.HashMap; +import java.util.Map; + +import org.springframework.boot.build.architecture.annotations.TestConfigurationProperties; + +/** + * Test {@link TestConfigurationProperties} using {@link HashMap}. + * + * @author Venkata Naga Sai Srikanth Gollapudi + */ +@TestConfigurationProperties("testing") +public class ConfigurationPropertiesWithHashMap { + + private Map properties = new HashMap<>(); + + public Map getProperties() { + return this.properties; + } + + public void setProperties(Map properties) { + this.properties = properties; + } + +} diff --git a/buildSrc/src/test/java/org/springframework/boot/build/architecture/configurationproperties/hashset/ConfigurationPropertiesWithHashSet.java b/buildSrc/src/test/java/org/springframework/boot/build/architecture/configurationproperties/hashset/ConfigurationPropertiesWithHashSet.java new file mode 100644 index 000000000000..f8bfc8497d91 --- /dev/null +++ b/buildSrc/src/test/java/org/springframework/boot/build/architecture/configurationproperties/hashset/ConfigurationPropertiesWithHashSet.java @@ -0,0 +1,42 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.build.architecture.configurationproperties.hashset; + +import java.util.HashSet; +import java.util.Set; + +import org.springframework.boot.build.architecture.annotations.TestConfigurationProperties; + +/** + * Test {@link TestConfigurationProperties} using {@link HashSet}. + * + * @author Venkata Naga Sai Srikanth Gollapudi + */ +@TestConfigurationProperties("testing") +public class ConfigurationPropertiesWithHashSet { + + private Set items = new HashSet<>(); + + public Set getItems() { + return this.items; + } + + public void setItems(Set items) { + this.items = items; + } + +} diff --git a/buildSrc/src/test/java/org/springframework/boot/build/architecture/configurationproperties/linkedhashmap/ConfigurationPropertiesWithLinkedHashMap.java b/buildSrc/src/test/java/org/springframework/boot/build/architecture/configurationproperties/linkedhashmap/ConfigurationPropertiesWithLinkedHashMap.java new file mode 100644 index 000000000000..b8a8ed38a98f --- /dev/null +++ b/buildSrc/src/test/java/org/springframework/boot/build/architecture/configurationproperties/linkedhashmap/ConfigurationPropertiesWithLinkedHashMap.java @@ -0,0 +1,42 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.build.architecture.configurationproperties.linkedhashmap; + +import java.util.LinkedHashMap; +import java.util.Map; + +import org.springframework.boot.build.architecture.annotations.TestConfigurationProperties; + +/** + * Test {@link TestConfigurationProperties} using {@link LinkedHashMap}. + * + * @author Venkata Naga Sai Srikanth Gollapudi + */ +@TestConfigurationProperties("testing") +public class ConfigurationPropertiesWithLinkedHashMap { + + private Map properties = new LinkedHashMap<>(); + + public Map getProperties() { + return this.properties; + } + + public void setProperties(Map properties) { + this.properties = properties; + } + +} diff --git a/buildSrc/src/test/java/org/springframework/boot/build/architecture/configurationproperties/linkedhashset/ConfigurationPropertiesWithLinkedHashSet.java b/buildSrc/src/test/java/org/springframework/boot/build/architecture/configurationproperties/linkedhashset/ConfigurationPropertiesWithLinkedHashSet.java new file mode 100644 index 000000000000..d75c7db3f797 --- /dev/null +++ b/buildSrc/src/test/java/org/springframework/boot/build/architecture/configurationproperties/linkedhashset/ConfigurationPropertiesWithLinkedHashSet.java @@ -0,0 +1,42 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.build.architecture.configurationproperties.linkedhashset; + +import java.util.LinkedHashSet; +import java.util.Set; + +import org.springframework.boot.build.architecture.annotations.TestConfigurationProperties; + +/** + * Test {@link TestConfigurationProperties} using {@link LinkedHashSet}. + * + * @author Venkata Naga Sai Srikanth Gollapudi + */ +@TestConfigurationProperties("testing") +public class ConfigurationPropertiesWithLinkedHashSet { + + private Set items = new LinkedHashSet<>(); + + public Set getItems() { + return this.items; + } + + public void setItems(Set items) { + this.items = items; + } + +} diff --git a/buildSrc/src/test/java/org/springframework/boot/build/architecture/configurationpropertiessource/enummap/ConfigurationPropertiesWithEnumMap.java b/buildSrc/src/test/java/org/springframework/boot/build/architecture/configurationpropertiessource/enummap/ConfigurationPropertiesWithEnumMap.java new file mode 100644 index 000000000000..1c5534177a25 --- /dev/null +++ b/buildSrc/src/test/java/org/springframework/boot/build/architecture/configurationpropertiessource/enummap/ConfigurationPropertiesWithEnumMap.java @@ -0,0 +1,48 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.build.architecture.configurationpropertiessource.enummap; + +import java.util.EnumMap; +import java.util.Map; + +import org.springframework.boot.build.architecture.annotations.TestConfigurationPropertiesSource; + +/** + * Test {@link TestConfigurationPropertiesSource} using {@link EnumMap}. + * + * @author Stephane Nicoll + */ +@TestConfigurationPropertiesSource +public class ConfigurationPropertiesWithEnumMap { + + private Map properties = new EnumMap<>(Example.class); + + public Map getProperties() { + return this.properties; + } + + public void setProperties(Map properties) { + this.properties = properties; + } + + enum Example { + + ONE + + } + +} diff --git a/buildSrc/src/test/java/org/springframework/boot/build/architecture/configurationpropertiessource/hashmap/ConfigurationPropertiesWithHashMap.java b/buildSrc/src/test/java/org/springframework/boot/build/architecture/configurationpropertiessource/hashmap/ConfigurationPropertiesWithHashMap.java new file mode 100644 index 000000000000..98d6b4e26b4b --- /dev/null +++ b/buildSrc/src/test/java/org/springframework/boot/build/architecture/configurationpropertiessource/hashmap/ConfigurationPropertiesWithHashMap.java @@ -0,0 +1,42 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.build.architecture.configurationpropertiessource.hashmap; + +import java.util.HashMap; +import java.util.Map; + +import org.springframework.boot.build.architecture.annotations.TestConfigurationPropertiesSource; + +/** + * Test {@link TestConfigurationPropertiesSource} using {@link HashMap}. + * + * @author Stephane Nicoll + */ +@TestConfigurationPropertiesSource +public class ConfigurationPropertiesWithHashMap { + + private Map properties = new HashMap<>(); + + public Map getProperties() { + return this.properties; + } + + public void setProperties(Map properties) { + this.properties = properties; + } + +} diff --git a/buildSrc/src/test/java/org/springframework/boot/build/architecture/configurationpropertiessource/hashset/ConfigurationPropertiesWithHashSet.java b/buildSrc/src/test/java/org/springframework/boot/build/architecture/configurationpropertiessource/hashset/ConfigurationPropertiesWithHashSet.java new file mode 100644 index 000000000000..c7b4011f9d99 --- /dev/null +++ b/buildSrc/src/test/java/org/springframework/boot/build/architecture/configurationpropertiessource/hashset/ConfigurationPropertiesWithHashSet.java @@ -0,0 +1,42 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.build.architecture.configurationpropertiessource.hashset; + +import java.util.HashSet; +import java.util.Set; + +import org.springframework.boot.build.architecture.annotations.TestConfigurationPropertiesSource; + +/** + * Test {@link TestConfigurationPropertiesSource} using {@link HashSet}. + * + * @author Stephane Nicoll + */ +@TestConfigurationPropertiesSource +public class ConfigurationPropertiesWithHashSet { + + private Set items = new HashSet<>(); + + public Set getItems() { + return this.items; + } + + public void setItems(Set items) { + this.items = items; + } + +} diff --git a/buildSrc/src/test/java/org/springframework/boot/build/architecture/configurationpropertiessource/linkedhashmap/ConfigurationPropertiesWithLinkedHashMap.java b/buildSrc/src/test/java/org/springframework/boot/build/architecture/configurationpropertiessource/linkedhashmap/ConfigurationPropertiesWithLinkedHashMap.java new file mode 100644 index 000000000000..d300433a0429 --- /dev/null +++ b/buildSrc/src/test/java/org/springframework/boot/build/architecture/configurationpropertiessource/linkedhashmap/ConfigurationPropertiesWithLinkedHashMap.java @@ -0,0 +1,42 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.build.architecture.configurationpropertiessource.linkedhashmap; + +import java.util.LinkedHashMap; +import java.util.Map; + +import org.springframework.boot.build.architecture.annotations.TestConfigurationPropertiesSource; + +/** + * Test {@link TestConfigurationPropertiesSource} using {@link LinkedHashMap}. + * + * @author Stephane Nicoll + */ +@TestConfigurationPropertiesSource +public class ConfigurationPropertiesWithLinkedHashMap { + + private Map properties = new LinkedHashMap<>(); + + public Map getProperties() { + return this.properties; + } + + public void setProperties(Map properties) { + this.properties = properties; + } + +} diff --git a/buildSrc/src/test/java/org/springframework/boot/build/architecture/configurationpropertiessource/linkedhashset/ConfigurationPropertiesWithLinkedHashSet.java b/buildSrc/src/test/java/org/springframework/boot/build/architecture/configurationpropertiessource/linkedhashset/ConfigurationPropertiesWithLinkedHashSet.java new file mode 100644 index 000000000000..085fea8b58df --- /dev/null +++ b/buildSrc/src/test/java/org/springframework/boot/build/architecture/configurationpropertiessource/linkedhashset/ConfigurationPropertiesWithLinkedHashSet.java @@ -0,0 +1,42 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.build.architecture.configurationpropertiessource.linkedhashset; + +import java.util.LinkedHashSet; +import java.util.Set; + +import org.springframework.boot.build.architecture.annotations.TestConfigurationPropertiesSource; + +/** + * Test {@link TestConfigurationPropertiesSource} using {@link LinkedHashSet}. + * + * @author Stephane Nicoll + */ +@TestConfigurationPropertiesSource +public class ConfigurationPropertiesWithLinkedHashSet { + + private Set items = new LinkedHashSet<>(); + + public Set getItems() { + return this.items; + } + + public void setItems(Set items) { + this.items = items; + } + +} diff --git a/documentation/spring-boot-docs/src/main/java/org/springframework/boot/docs/features/externalconfig/typesafeconfigurationproperties/relaxedbinding/mapsfromenvironmentvariables/MyMapsProperties.java b/documentation/spring-boot-docs/src/main/java/org/springframework/boot/docs/features/externalconfig/typesafeconfigurationproperties/relaxedbinding/mapsfromenvironmentvariables/MyMapsProperties.java index 71b7cb4c1b9d..441f57b726c8 100644 --- a/documentation/spring-boot-docs/src/main/java/org/springframework/boot/docs/features/externalconfig/typesafeconfigurationproperties/relaxedbinding/mapsfromenvironmentvariables/MyMapsProperties.java +++ b/documentation/spring-boot-docs/src/main/java/org/springframework/boot/docs/features/externalconfig/typesafeconfigurationproperties/relaxedbinding/mapsfromenvironmentvariables/MyMapsProperties.java @@ -16,7 +16,7 @@ package org.springframework.boot.docs.features.externalconfig.typesafeconfigurationproperties.relaxedbinding.mapsfromenvironmentvariables; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; import org.springframework.boot.context.properties.ConfigurationProperties; @@ -24,7 +24,7 @@ @ConfigurationProperties("my.props") public class MyMapsProperties { - private final Map values = new HashMap<>(); + private final Map values = new LinkedHashMap<>(); public Map getValues() { return this.values; diff --git a/documentation/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/features/externalconfig/typesafeconfigurationproperties/relaxedbinding/mapsfromenvironmentvariables/MyMapsProperties.kt b/documentation/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/features/externalconfig/typesafeconfigurationproperties/relaxedbinding/mapsfromenvironmentvariables/MyMapsProperties.kt index 057295216fd1..1e21315e2eb3 100644 --- a/documentation/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/features/externalconfig/typesafeconfigurationproperties/relaxedbinding/mapsfromenvironmentvariables/MyMapsProperties.kt +++ b/documentation/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/features/externalconfig/typesafeconfigurationproperties/relaxedbinding/mapsfromenvironmentvariables/MyMapsProperties.kt @@ -21,7 +21,7 @@ import org.springframework.boot.context.properties.ConfigurationProperties @ConfigurationProperties("my.props") class MyMapsProperties { - val values: Map = HashMap() + val values: Map = LinkedHashMap() } diff --git a/module/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/context/properties/ConfigurationPropertiesReportEndpointProperties.java b/module/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/context/properties/ConfigurationPropertiesReportEndpointProperties.java index 8bc6c645f7f6..6f594812072c 100644 --- a/module/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/context/properties/ConfigurationPropertiesReportEndpointProperties.java +++ b/module/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/context/properties/ConfigurationPropertiesReportEndpointProperties.java @@ -16,7 +16,7 @@ package org.springframework.boot.actuate.autoconfigure.context.properties; -import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.Set; import org.springframework.boot.actuate.context.properties.ConfigurationPropertiesReportEndpoint; @@ -42,7 +42,7 @@ public class ConfigurationPropertiesReportEndpointProperties { * Roles used to determine whether a user is authorized to be shown unsanitized * values. When empty, all authenticated users are authorized. */ - private final Set roles = new HashSet<>(); + private final Set roles = new LinkedHashSet<>(); public Show getShowValues() { return this.showValues; diff --git a/module/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/env/EnvironmentEndpointProperties.java b/module/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/env/EnvironmentEndpointProperties.java index 301276abb59a..d2de960491f9 100644 --- a/module/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/env/EnvironmentEndpointProperties.java +++ b/module/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/env/EnvironmentEndpointProperties.java @@ -16,7 +16,7 @@ package org.springframework.boot.actuate.autoconfigure.env; -import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.Set; import org.springframework.boot.actuate.endpoint.Show; @@ -41,7 +41,7 @@ public class EnvironmentEndpointProperties { * Roles used to determine whether a user is authorized to be shown unsanitized * values. When empty, all authenticated users are authorized. */ - private final Set roles = new HashSet<>(); + private final Set roles = new LinkedHashSet<>(); public Show getShowValues() { return this.showValues; diff --git a/module/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/exchanges/HttpExchangesProperties.java b/module/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/exchanges/HttpExchangesProperties.java index 70883127d22a..fc049e7b0723 100644 --- a/module/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/exchanges/HttpExchangesProperties.java +++ b/module/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/exchanges/HttpExchangesProperties.java @@ -16,7 +16,7 @@ package org.springframework.boot.actuate.autoconfigure.web.exchanges; -import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.Set; import org.springframework.boot.actuate.web.exchanges.Include; @@ -53,7 +53,7 @@ public static class Recording { * (excluding Authorization and Cookie), response headers (excluding Set-Cookie), * and time taken. */ - private Set include = new HashSet<>(Include.defaultIncludes()); + private Set include = new LinkedHashSet<>(Include.defaultIncludes()); public Set getInclude() { return this.include; diff --git a/module/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/sbom/SbomProperties.java b/module/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/sbom/SbomProperties.java index 94d6424eed98..3c05315caa6c 100644 --- a/module/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/sbom/SbomProperties.java +++ b/module/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/sbom/SbomProperties.java @@ -16,7 +16,7 @@ package org.springframework.boot.actuate.sbom; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; import org.jspecify.annotations.Nullable; @@ -41,7 +41,7 @@ public class SbomProperties { /** * Additional SBOMs. */ - private Map additional = new HashMap<>(); + private Map additional = new LinkedHashMap<>(); public Sbom getApplication() { return this.application; diff --git a/module/spring-boot-artemis/src/main/java/org/springframework/boot/artemis/autoconfigure/ArtemisProperties.java b/module/spring-boot-artemis/src/main/java/org/springframework/boot/artemis/autoconfigure/ArtemisProperties.java index 94c681c3a0a1..3add6adba385 100644 --- a/module/spring-boot-artemis/src/main/java/org/springframework/boot/artemis/autoconfigure/ArtemisProperties.java +++ b/module/spring-boot-artemis/src/main/java/org/springframework/boot/artemis/autoconfigure/ArtemisProperties.java @@ -16,7 +16,7 @@ package org.springframework.boot.artemis.autoconfigure; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; import java.util.UUID; import java.util.concurrent.atomic.AtomicInteger; @@ -216,7 +216,7 @@ public boolean isDefaultClusterPassword() { * @see TransportConstants#SERVER_ID_PROP_NAME */ public Map generateTransportParameters() { - Map parameters = new HashMap<>(); + Map parameters = new LinkedHashMap<>(); parameters.put(TransportConstants.SERVER_ID_PROP_NAME, getServerId()); return parameters; } diff --git a/module/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/autoconfigure/FlywayProperties.java b/module/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/autoconfigure/FlywayProperties.java index 9af24f3261a0..44ef3c2ac3ba 100644 --- a/module/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/autoconfigure/FlywayProperties.java +++ b/module/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/autoconfigure/FlywayProperties.java @@ -23,7 +23,7 @@ import java.time.temporal.ChronoUnit; import java.util.ArrayList; import java.util.Collections; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -137,7 +137,7 @@ public class FlywayProperties { /** * Placeholders and their replacements to apply to sql migration scripts. */ - private Map placeholders = new HashMap<>(); + private Map placeholders = new LinkedHashMap<>(); /** * Prefix of placeholders in migration scripts. @@ -310,7 +310,7 @@ public class FlywayProperties { /** * Properties to pass to the JDBC driver. */ - private Map jdbcProperties = new HashMap<>(); + private Map jdbcProperties = new LinkedHashMap<>(); /** * Path of the Kerberos config file. Requires Flyway Teams. diff --git a/module/spring-boot-freemarker/src/main/java/org/springframework/boot/freemarker/autoconfigure/FreeMarkerProperties.java b/module/spring-boot-freemarker/src/main/java/org/springframework/boot/freemarker/autoconfigure/FreeMarkerProperties.java index 89afd1946e84..ba0082af1f9a 100644 --- a/module/spring-boot-freemarker/src/main/java/org/springframework/boot/freemarker/autoconfigure/FreeMarkerProperties.java +++ b/module/spring-boot-freemarker/src/main/java/org/springframework/boot/freemarker/autoconfigure/FreeMarkerProperties.java @@ -18,7 +18,6 @@ import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; -import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; @@ -123,7 +122,7 @@ public class FreeMarkerProperties { /** * Well-known FreeMarker keys which are passed to FreeMarker's Configuration. */ - private Map settings = new HashMap<>(); + private Map settings = new LinkedHashMap<>(); /** * List of template paths. diff --git a/module/spring-boot-grpc-server/src/main/java/org/springframework/boot/grpc/server/autoconfigure/health/GrpcServerHealthProperties.java b/module/spring-boot-grpc-server/src/main/java/org/springframework/boot/grpc/server/autoconfigure/health/GrpcServerHealthProperties.java index 2912cad3669b..c2be3e85eed0 100644 --- a/module/spring-boot-grpc-server/src/main/java/org/springframework/boot/grpc/server/autoconfigure/health/GrpcServerHealthProperties.java +++ b/module/spring-boot-grpc-server/src/main/java/org/springframework/boot/grpc/server/autoconfigure/health/GrpcServerHealthProperties.java @@ -19,7 +19,6 @@ import java.time.Duration; import java.time.temporal.ChronoUnit; import java.util.ArrayList; -import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -177,7 +176,7 @@ public static class Status { * Mapping of health statuses to gRPC service status. By default, registered * health statuses map to sensible defaults (for example, UP maps to SERVING). */ - private final Map mapping = new HashMap<>(); + private final Map mapping = new LinkedHashMap<>(); public List getOrder() { return this.order; diff --git a/module/spring-boot-hibernate/src/main/java/org/springframework/boot/hibernate/autoconfigure/HibernateProperties.java b/module/spring-boot-hibernate/src/main/java/org/springframework/boot/hibernate/autoconfigure/HibernateProperties.java index ae00735c58cf..e9299e4e720a 100644 --- a/module/spring-boot-hibernate/src/main/java/org/springframework/boot/hibernate/autoconfigure/HibernateProperties.java +++ b/module/spring-boot-hibernate/src/main/java/org/springframework/boot/hibernate/autoconfigure/HibernateProperties.java @@ -17,7 +17,7 @@ package org.springframework.boot.hibernate.autoconfigure; import java.util.Collection; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; import java.util.function.Supplier; @@ -85,7 +85,7 @@ public Map determineHibernateProperties(Map jpaP } private Map getAdditionalProperties(Map existing, HibernateSettings settings) { - Map result = new HashMap<>(existing); + Map result = new LinkedHashMap<>(existing); applyScanner(result); getNaming().applyNamingStrategies(result); String ddlAuto = determineDdlAuto(existing, settings::getDdlAuto); diff --git a/module/spring-boot-jersey/src/main/java/org/springframework/boot/jersey/autoconfigure/JerseyProperties.java b/module/spring-boot-jersey/src/main/java/org/springframework/boot/jersey/autoconfigure/JerseyProperties.java index 2a858ad353aa..cc3906d936af 100644 --- a/module/spring-boot-jersey/src/main/java/org/springframework/boot/jersey/autoconfigure/JerseyProperties.java +++ b/module/spring-boot-jersey/src/main/java/org/springframework/boot/jersey/autoconfigure/JerseyProperties.java @@ -16,7 +16,7 @@ package org.springframework.boot.jersey.autoconfigure; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; import org.jspecify.annotations.Nullable; @@ -42,7 +42,7 @@ public class JerseyProperties { /** * Init parameters to pass to Jersey through the servlet or filter. */ - private Map init = new HashMap<>(); + private Map init = new LinkedHashMap<>(); private final Filter filter = new Filter(); diff --git a/module/spring-boot-jpa/src/main/java/org/springframework/boot/jpa/autoconfigure/JpaProperties.java b/module/spring-boot-jpa/src/main/java/org/springframework/boot/jpa/autoconfigure/JpaProperties.java index 5bcbc156318e..fcd8631c5008 100644 --- a/module/spring-boot-jpa/src/main/java/org/springframework/boot/jpa/autoconfigure/JpaProperties.java +++ b/module/spring-boot-jpa/src/main/java/org/springframework/boot/jpa/autoconfigure/JpaProperties.java @@ -17,7 +17,7 @@ package org.springframework.boot.jpa.autoconfigure; import java.util.ArrayList; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -42,7 +42,7 @@ public class JpaProperties { /** * Additional native properties to set on the JPA provider. */ - private Map properties = new HashMap<>(); + private Map properties = new LinkedHashMap<>(); /** * Mapping resources (equivalent to "mapping-file" entries in persistence.xml). diff --git a/module/spring-boot-kafka/src/main/java/org/springframework/boot/kafka/autoconfigure/KafkaProperties.java b/module/spring-boot-kafka/src/main/java/org/springframework/boot/kafka/autoconfigure/KafkaProperties.java index 172ffd707808..d622810b5fee 100644 --- a/module/spring-boot-kafka/src/main/java/org/springframework/boot/kafka/autoconfigure/KafkaProperties.java +++ b/module/spring-boot-kafka/src/main/java/org/springframework/boot/kafka/autoconfigure/KafkaProperties.java @@ -21,7 +21,7 @@ import java.time.temporal.ChronoUnit; import java.util.ArrayList; import java.util.Collections; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; import java.util.Locale; import java.util.Map; @@ -79,7 +79,7 @@ public class KafkaProperties { * Additional properties, common to producers and consumers, used to configure the * client. */ - private final Map properties = new HashMap<>(); + private final Map properties = new LinkedHashMap<>(); private final Consumer consumer = new Consumer(); @@ -162,7 +162,7 @@ public Retry getRetry() { } private Map buildCommonProperties() { - Map properties = new HashMap<>(); + Map properties = new LinkedHashMap<>(); if (this.bootstrapServers != null) { properties.put(CommonClientConfigs.BOOTSTRAP_SERVERS_CONFIG, this.bootstrapServers); } @@ -318,7 +318,7 @@ public static class Consumer { /** * Additional consumer-specific properties used to configure the client. */ - private final Map properties = new HashMap<>(); + private final Map properties = new LinkedHashMap<>(); public Ssl getSsl() { return this.ssl; @@ -540,7 +540,7 @@ public static class Producer { /** * Additional producer-specific properties used to configure the client. */ - private final Map properties = new HashMap<>(); + private final Map properties = new LinkedHashMap<>(); public Ssl getSsl() { return this.ssl; @@ -667,7 +667,7 @@ public static class Admin { /** * Additional admin-specific properties used to configure the client. */ - private final Map properties = new HashMap<>(); + private final Map properties = new LinkedHashMap<>(); /** * Close timeout. @@ -815,7 +815,7 @@ public static class Streams { /** * Additional Kafka properties used to configure the streams. */ - private final Map properties = new HashMap<>(); + private final Map properties = new LinkedHashMap<>(); public Ssl getSsl() { return this.ssl; @@ -1510,7 +1510,7 @@ public static class Jaas { /** * Additional JAAS options. */ - private final Map options = new HashMap<>(); + private final Map options = new LinkedHashMap<>(); public boolean isEnabled() { return this.enabled; @@ -1741,7 +1741,7 @@ public byte id() { } @SuppressWarnings("serial") - private static final class Properties extends HashMap { + private static final class Properties extends LinkedHashMap { java.util.function.Consumer in(String key) { return (value) -> put(key, value); diff --git a/module/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/autoconfigure/LdapProperties.java b/module/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/autoconfigure/LdapProperties.java index 636834cf6cf5..9bbb9bde845d 100644 --- a/module/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/autoconfigure/LdapProperties.java +++ b/module/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/autoconfigure/LdapProperties.java @@ -16,7 +16,7 @@ package org.springframework.boot.ldap.autoconfigure; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; import org.jspecify.annotations.Nullable; @@ -74,7 +74,7 @@ public class LdapProperties { /** * LDAP specification settings. */ - private final Map baseEnvironment = new HashMap<>(); + private final Map baseEnvironment = new LinkedHashMap<>(); private final Template template = new Template(); diff --git a/module/spring-boot-mail/src/main/java/org/springframework/boot/mail/autoconfigure/MailProperties.java b/module/spring-boot-mail/src/main/java/org/springframework/boot/mail/autoconfigure/MailProperties.java index de62fda00cf1..6f2fd0bc7240 100644 --- a/module/spring-boot-mail/src/main/java/org/springframework/boot/mail/autoconfigure/MailProperties.java +++ b/module/spring-boot-mail/src/main/java/org/springframework/boot/mail/autoconfigure/MailProperties.java @@ -18,7 +18,7 @@ import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; import org.jspecify.annotations.Nullable; @@ -71,7 +71,7 @@ public class MailProperties { /** * Additional JavaMail Session properties. */ - private final Map properties = new HashMap<>(); + private final Map properties = new LinkedHashMap<>(); /** * Session JNDI name. When set, takes precedence over other Session settings. diff --git a/module/spring-boot-micrometer-metrics/src/main/java/org/springframework/boot/micrometer/metrics/autoconfigure/export/humio/HumioProperties.java b/module/spring-boot-micrometer-metrics/src/main/java/org/springframework/boot/micrometer/metrics/autoconfigure/export/humio/HumioProperties.java index befa265456f0..ede0cdb5cf78 100644 --- a/module/spring-boot-micrometer-metrics/src/main/java/org/springframework/boot/micrometer/metrics/autoconfigure/export/humio/HumioProperties.java +++ b/module/spring-boot-micrometer-metrics/src/main/java/org/springframework/boot/micrometer/metrics/autoconfigure/export/humio/HumioProperties.java @@ -17,7 +17,7 @@ package org.springframework.boot.micrometer.metrics.autoconfigure.export.humio; import java.time.Duration; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; import org.jspecify.annotations.Nullable; @@ -50,7 +50,7 @@ public class HumioProperties extends StepRegistryProperties { * are a distinct concept from Micrometer's tags. Micrometer's tags are used to divide * metrics along dimensional boundaries. */ - private Map tags = new HashMap<>(); + private Map tags = new LinkedHashMap<>(); /** * URI to ship metrics to. If you need to publish metrics to an internal proxy diff --git a/module/spring-boot-micrometer-metrics/src/main/java/org/springframework/boot/micrometer/metrics/autoconfigure/export/prometheus/PrometheusProperties.java b/module/spring-boot-micrometer-metrics/src/main/java/org/springframework/boot/micrometer/metrics/autoconfigure/export/prometheus/PrometheusProperties.java index d7ca355cf0c3..7d7de22eb3a9 100644 --- a/module/spring-boot-micrometer-metrics/src/main/java/org/springframework/boot/micrometer/metrics/autoconfigure/export/prometheus/PrometheusProperties.java +++ b/module/spring-boot-micrometer-metrics/src/main/java/org/springframework/boot/micrometer/metrics/autoconfigure/export/prometheus/PrometheusProperties.java @@ -17,7 +17,7 @@ package org.springframework.boot.micrometer.metrics.autoconfigure.export.prometheus; import java.time.Duration; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; import org.jspecify.annotations.Nullable; @@ -56,7 +56,7 @@ public class PrometheusProperties { /** * Additional properties to pass to the Prometheus client. */ - private final Map properties = new HashMap<>(); + private final Map properties = new LinkedHashMap<>(); /** * Step size (i.e. reporting frequency) to use. @@ -148,7 +148,7 @@ public static class Pushgateway { /** * Grouping key for the pushed metrics. */ - private Map groupingKey = new HashMap<>(); + private Map groupingKey = new LinkedHashMap<>(); /** * Operation that should be performed on shutdown. diff --git a/module/spring-boot-micrometer-tracing-opentelemetry/src/main/java/org/springframework/boot/micrometer/tracing/opentelemetry/autoconfigure/otlp/OtlpTracingProperties.java b/module/spring-boot-micrometer-tracing-opentelemetry/src/main/java/org/springframework/boot/micrometer/tracing/opentelemetry/autoconfigure/otlp/OtlpTracingProperties.java index edf073fa3494..b76c63cb6106 100644 --- a/module/spring-boot-micrometer-tracing-opentelemetry/src/main/java/org/springframework/boot/micrometer/tracing/opentelemetry/autoconfigure/otlp/OtlpTracingProperties.java +++ b/module/spring-boot-micrometer-tracing-opentelemetry/src/main/java/org/springframework/boot/micrometer/tracing/opentelemetry/autoconfigure/otlp/OtlpTracingProperties.java @@ -17,7 +17,7 @@ package org.springframework.boot.micrometer.tracing.opentelemetry.autoconfigure.otlp; import java.time.Duration; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; import org.jspecify.annotations.Nullable; @@ -64,7 +64,7 @@ public class OtlpTracingProperties { /** * Custom HTTP headers you want to pass to the collector, for example auth headers. */ - private Map headers = new HashMap<>(); + private Map headers = new LinkedHashMap<>(); private final Ssl ssl = new Ssl(); diff --git a/module/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/OpenTelemetryProperties.java b/module/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/OpenTelemetryProperties.java index a900b3e373ae..6e1f003677c6 100644 --- a/module/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/OpenTelemetryProperties.java +++ b/module/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/OpenTelemetryProperties.java @@ -16,7 +16,7 @@ package org.springframework.boot.opentelemetry.autoconfigure; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; import org.springframework.boot.context.properties.ConfigurationProperties; @@ -40,7 +40,7 @@ public class OpenTelemetryProperties { /** * Resource attributes. */ - private Map resourceAttributes = new HashMap<>(); + private Map resourceAttributes = new LinkedHashMap<>(); public boolean isEnabled() { return this.enabled; diff --git a/module/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/logging/otlp/OtlpLoggingProperties.java b/module/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/logging/otlp/OtlpLoggingProperties.java index 569935763a66..ebb114ae24b6 100644 --- a/module/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/logging/otlp/OtlpLoggingProperties.java +++ b/module/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/logging/otlp/OtlpLoggingProperties.java @@ -17,7 +17,7 @@ package org.springframework.boot.opentelemetry.autoconfigure.logging.otlp; import java.time.Duration; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; import org.jspecify.annotations.Nullable; @@ -64,7 +64,7 @@ public class OtlpLoggingProperties { /** * Custom HTTP headers you want to pass to the collector, for example auth headers. */ - private final Map headers = new HashMap<>(); + private final Map headers = new LinkedHashMap<>(); private final Ssl ssl = new Ssl(); diff --git a/module/spring-boot-quartz/src/main/java/org/springframework/boot/quartz/autoconfigure/QuartzEndpointProperties.java b/module/spring-boot-quartz/src/main/java/org/springframework/boot/quartz/autoconfigure/QuartzEndpointProperties.java index 176dd4b6e600..053b7ff7901d 100644 --- a/module/spring-boot-quartz/src/main/java/org/springframework/boot/quartz/autoconfigure/QuartzEndpointProperties.java +++ b/module/spring-boot-quartz/src/main/java/org/springframework/boot/quartz/autoconfigure/QuartzEndpointProperties.java @@ -16,7 +16,7 @@ package org.springframework.boot.quartz.autoconfigure; -import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.Set; import org.springframework.boot.actuate.endpoint.Show; @@ -41,7 +41,7 @@ public class QuartzEndpointProperties { * Roles used to determine whether a user is authorized to be shown unsanitized job or * trigger values. When empty, all authenticated users are authorized. */ - private final Set roles = new HashSet<>(); + private final Set roles = new LinkedHashSet<>(); public Show getShowValues() { return this.showValues; diff --git a/module/spring-boot-quartz/src/main/java/org/springframework/boot/quartz/autoconfigure/QuartzProperties.java b/module/spring-boot-quartz/src/main/java/org/springframework/boot/quartz/autoconfigure/QuartzProperties.java index 14c405cb9e66..73fbbc77ffc7 100644 --- a/module/spring-boot-quartz/src/main/java/org/springframework/boot/quartz/autoconfigure/QuartzProperties.java +++ b/module/spring-boot-quartz/src/main/java/org/springframework/boot/quartz/autoconfigure/QuartzProperties.java @@ -17,7 +17,7 @@ package org.springframework.boot.quartz.autoconfigure; import java.time.Duration; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; import org.jspecify.annotations.Nullable; @@ -69,7 +69,7 @@ public class QuartzProperties { /** * Additional Quartz Scheduler properties. */ - private final Map properties = new HashMap<>(); + private final Map properties = new LinkedHashMap<>(); public JobStoreType getJobStoreType() { return this.jobStoreType; diff --git a/module/spring-boot-security-oauth2-authorization-server/src/main/java/org/springframework/boot/security/oauth2/server/authorization/autoconfigure/servlet/OAuth2AuthorizationServerProperties.java b/module/spring-boot-security-oauth2-authorization-server/src/main/java/org/springframework/boot/security/oauth2/server/authorization/autoconfigure/servlet/OAuth2AuthorizationServerProperties.java index ede513ef61a4..b44e870f8102 100644 --- a/module/spring-boot-security-oauth2-authorization-server/src/main/java/org/springframework/boot/security/oauth2/server/authorization/autoconfigure/servlet/OAuth2AuthorizationServerProperties.java +++ b/module/spring-boot-security-oauth2-authorization-server/src/main/java/org/springframework/boot/security/oauth2/server/authorization/autoconfigure/servlet/OAuth2AuthorizationServerProperties.java @@ -17,8 +17,8 @@ package org.springframework.boot.security.oauth2.server.authorization.autoconfigure.servlet; import java.time.Duration; -import java.util.HashMap; -import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; import java.util.Map; import java.util.Set; @@ -55,7 +55,7 @@ public class OAuth2AuthorizationServerProperties implements InitializingBean { /** * Registered clients of the Authorization Server. */ - private final Map client = new HashMap<>(); + private final Map client = new LinkedHashMap<>(); /** * Authorization Server endpoints. @@ -380,27 +380,27 @@ public static class Registration { /** * Client authentication method(s) that the client may use. */ - private Set clientAuthenticationMethods = new HashSet<>(); + private Set clientAuthenticationMethods = new LinkedHashSet<>(); /** * Authorization grant type(s) that the client may use. */ - private Set authorizationGrantTypes = new HashSet<>(); + private Set authorizationGrantTypes = new LinkedHashSet<>(); /** * Redirect URI(s) that the client may use in redirect-based flows. */ - private Set redirectUris = new HashSet<>(); + private Set redirectUris = new LinkedHashSet<>(); /** * Redirect URI(s) that the client may use for logout. */ - private Set postLogoutRedirectUris = new HashSet<>(); + private Set postLogoutRedirectUris = new LinkedHashSet<>(); /** * Scope(s) that the client may use. */ - private Set scopes = new HashSet<>(); + private Set scopes = new LinkedHashSet<>(); public @Nullable String getClientId() { return this.clientId; diff --git a/module/spring-boot-security-oauth2-client/src/main/java/org/springframework/boot/security/oauth2/client/autoconfigure/OAuth2ClientProperties.java b/module/spring-boot-security-oauth2-client/src/main/java/org/springframework/boot/security/oauth2/client/autoconfigure/OAuth2ClientProperties.java index f57b8a81f74c..18d0fe7a0d7c 100644 --- a/module/spring-boot-security-oauth2-client/src/main/java/org/springframework/boot/security/oauth2/client/autoconfigure/OAuth2ClientProperties.java +++ b/module/spring-boot-security-oauth2-client/src/main/java/org/springframework/boot/security/oauth2/client/autoconfigure/OAuth2ClientProperties.java @@ -16,7 +16,7 @@ package org.springframework.boot.security.oauth2.client.autoconfigure; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; import java.util.Set; @@ -42,12 +42,12 @@ public class OAuth2ClientProperties implements InitializingBean { /** * OAuth provider details. */ - private final Map provider = new HashMap<>(); + private final Map provider = new LinkedHashMap<>(); /** * OAuth client registrations. */ - private final Map registration = new HashMap<>(); + private final Map registration = new LinkedHashMap<>(); public Map getProvider() { return this.provider; diff --git a/module/spring-boot-session/src/main/java/org/springframework/boot/session/autoconfigure/SessionProperties.java b/module/spring-boot-session/src/main/java/org/springframework/boot/session/autoconfigure/SessionProperties.java index 0f7c500b41b2..30216c894aba 100644 --- a/module/spring-boot-session/src/main/java/org/springframework/boot/session/autoconfigure/SessionProperties.java +++ b/module/spring-boot-session/src/main/java/org/springframework/boot/session/autoconfigure/SessionProperties.java @@ -19,7 +19,7 @@ import java.time.Duration; import java.time.temporal.ChronoUnit; import java.util.Arrays; -import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.Set; import java.util.function.Supplier; @@ -90,7 +90,7 @@ public static class Servlet { /** * Session repository filter dispatcher types. */ - private Set filterDispatcherTypes = new HashSet<>( + private Set filterDispatcherTypes = new LinkedHashSet<>( Arrays.asList(DispatcherType.ASYNC, DispatcherType.ERROR, DispatcherType.REQUEST)); public int getFilterOrder() { diff --git a/module/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/autoconfigure/ServerProperties.java b/module/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/autoconfigure/ServerProperties.java index 32629886c8a2..415b7bc54a1b 100644 --- a/module/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/autoconfigure/ServerProperties.java +++ b/module/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/autoconfigure/ServerProperties.java @@ -20,7 +20,7 @@ import java.nio.charset.Charset; import java.time.Duration; import java.time.temporal.ChronoUnit; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Locale; import java.util.Map; @@ -212,7 +212,7 @@ public static class Servlet { /** * Servlet context init parameters. */ - private final Map contextParameters = new HashMap<>(); + private final Map contextParameters = new LinkedHashMap<>(); /** * Context path of the application. diff --git a/module/spring-boot-webservices/src/main/java/org/springframework/boot/webservices/autoconfigure/WebServicesProperties.java b/module/spring-boot-webservices/src/main/java/org/springframework/boot/webservices/autoconfigure/WebServicesProperties.java index a93dd86a9d21..847c3de30d7e 100644 --- a/module/spring-boot-webservices/src/main/java/org/springframework/boot/webservices/autoconfigure/WebServicesProperties.java +++ b/module/spring-boot-webservices/src/main/java/org/springframework/boot/webservices/autoconfigure/WebServicesProperties.java @@ -16,7 +16,7 @@ package org.springframework.boot.webservices.autoconfigure; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; import org.springframework.boot.context.properties.ConfigurationProperties; @@ -59,7 +59,7 @@ public static class Servlet { /** * Servlet init parameters to pass to Spring Web Services. */ - private Map init = new HashMap<>(); + private Map init = new LinkedHashMap<>(); /** * Load on startup priority of the Spring Web Services servlet.