diff --git a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/JavaBeanPropertyDescriptor.java b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/JavaBeanPropertyDescriptor.java index e3aeefd343b..59394af020e 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/JavaBeanPropertyDescriptor.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/JavaBeanPropertyDescriptor.java @@ -64,7 +64,7 @@ class JavaBeanPropertyDescriptor extends PropertyDescriptor { @Override protected Object resolveDefaultValue(MetadataGenerationEnvironment environment) { - return environment.getFieldDefaultValue(getDeclaringElement(), getName()); + return environment.getFieldDefaultValue(getDeclaringElement(), this.field); } @Override diff --git a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/LombokPropertyDescriptor.java b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/LombokPropertyDescriptor.java index 1d42192db29..3895aa57686 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/LombokPropertyDescriptor.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/LombokPropertyDescriptor.java @@ -76,7 +76,7 @@ class LombokPropertyDescriptor extends PropertyDescriptor { @Override protected Object resolveDefaultValue(MetadataGenerationEnvironment environment) { - return environment.getFieldDefaultValue(getDeclaringElement(), getName()); + return environment.getFieldDefaultValue(getDeclaringElement(), this.field); } @Override diff --git a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/MetadataGenerationEnvironment.java b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/MetadataGenerationEnvironment.java index 1de547e1887..148233800ef 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/MetadataGenerationEnvironment.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/MetadataGenerationEnvironment.java @@ -132,14 +132,15 @@ class MetadataGenerationEnvironment { } /** - * Return the default value of the field with the specified {@code name}. + * Return the default value of the given {@code field}. * @param type the type to consider - * @param name the name of the field + * @param field the field or {@code null} if it is not available * @return the default value or {@code null} if the field does not exist or no default * value has been detected */ - Object getFieldDefaultValue(TypeElement type, String name) { - return this.defaultValues.computeIfAbsent(type, this::resolveFieldValues).get(name); + Object getFieldDefaultValue(TypeElement type, VariableElement field) { + return (field != null) ? this.defaultValues.computeIfAbsent(type, this::resolveFieldValues) + .get(field.getSimpleName().toString()) : null; } boolean isExcluded(TypeMirror type) { diff --git a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/NameAnnotationPropertiesTests.java b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/NameAnnotationPropertiesTests.java index 864dd3eabd5..440a876252a 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/NameAnnotationPropertiesTests.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/NameAnnotationPropertiesTests.java @@ -20,9 +20,10 @@ import org.junit.jupiter.api.Test; import org.springframework.boot.configurationprocessor.metadata.ConfigurationMetadata; import org.springframework.boot.configurationprocessor.metadata.Metadata; -import org.springframework.boot.configurationsample.immutable.ConstructorParameterNameAnnotationProperties; -import org.springframework.boot.configurationsample.immutable.JavaBeanNameAnnotationProperties; -import org.springframework.boot.configurationsample.immutable.RecordComponentNameAnnotationProperties; +import org.springframework.boot.configurationsample.name.ConstructorParameterNameAnnotationProperties; +import org.springframework.boot.configurationsample.name.JavaBeanNameAnnotationProperties; +import org.springframework.boot.configurationsample.name.LombokNameAnnotationProperties; +import org.springframework.boot.configurationsample.name.RecordComponentNameAnnotationProperties; import static org.assertj.core.api.Assertions.assertThat; @@ -30,28 +31,60 @@ import static org.assertj.core.api.Assertions.assertThat; * Metadata generation tests for using {@code @Name}. * * @author Phillip Webb + * @author Stephane Nicoll */ class NameAnnotationPropertiesTests extends AbstractMetadataGenerationTests { @Test void constructorParameterNameAnnotationProperties() { ConfigurationMetadata metadata = compile(ConstructorParameterNameAnnotationProperties.class); - assertThat(metadata).has(Metadata.withProperty("named.import", String.class) - .fromSource(ConstructorParameterNameAnnotationProperties.class)); + assertThat(metadata) + .has(Metadata.withProperty("named.import", String.class) + .fromSource(ConstructorParameterNameAnnotationProperties.class) + .withDescription("Imports to apply.")) + .has(Metadata.withProperty("named.default", Boolean.class) + .fromSource(ConstructorParameterNameAnnotationProperties.class) + .withDefaultValue("Whether default mode is enabled.") + .withDefaultValue(true)); } @Test void recordComponentNameAnnotationProperties() { ConfigurationMetadata metadata = compile(RecordComponentNameAnnotationProperties.class); - assertThat(metadata).has(Metadata.withProperty("named.import", String.class) - .fromSource(RecordComponentNameAnnotationProperties.class)); + assertThat(metadata) + .has(Metadata.withProperty("named.import", String.class) + .fromSource(RecordComponentNameAnnotationProperties.class) + .withDescription("Imports to apply.")) + .has(Metadata.withProperty("named.default", Boolean.class) + .fromSource(RecordComponentNameAnnotationProperties.class) + .withDefaultValue("Whether default mode is enabled.") + .withDefaultValue(true)); } @Test void javaBeanNameAnnotationProperties() { ConfigurationMetadata metadata = compile(JavaBeanNameAnnotationProperties.class); - assertThat(metadata).has( - Metadata.withProperty("named.import", String.class).fromSource(JavaBeanNameAnnotationProperties.class)); + assertThat(metadata) + .has(Metadata.withProperty("named.import", String.class) + .fromSource(JavaBeanNameAnnotationProperties.class) + .withDescription("Imports to apply.")) + .has(Metadata.withProperty("named.default", Boolean.class) + .fromSource(JavaBeanNameAnnotationProperties.class) + .withDefaultValue("Whether default mode is enabled.") + .withDefaultValue(true)); + } + + @Test + void lombokNameAnnotationProperties() { + ConfigurationMetadata metadata = compile(LombokNameAnnotationProperties.class); + assertThat(metadata) + .has(Metadata.withProperty("named.import", String.class) + .fromSource(LombokNameAnnotationProperties.class) + .withDescription("Imports to apply.")) + .has(Metadata.withProperty("named.default", Boolean.class) + .fromSource(LombokNameAnnotationProperties.class) + .withDefaultValue("Whether default mode is enabled.") + .withDefaultValue(true)); } } diff --git a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/PropertyDescriptorResolverTests.java b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/PropertyDescriptorResolverTests.java index f66da225a63..1d476ee3bd2 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/PropertyDescriptorResolverTests.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/PropertyDescriptorResolverTests.java @@ -31,17 +31,18 @@ import org.junit.jupiter.api.Test; import org.springframework.boot.configurationprocessor.metadata.ItemMetadata; import org.springframework.boot.configurationprocessor.test.RoundEnvironmentTester; import org.springframework.boot.configurationprocessor.test.TestableAnnotationProcessor; -import org.springframework.boot.configurationsample.immutable.ConstructorParameterNameAnnotationProperties; import org.springframework.boot.configurationsample.immutable.ImmutableClassConstructorBindingProperties; import org.springframework.boot.configurationsample.immutable.ImmutableDeducedConstructorBindingProperties; import org.springframework.boot.configurationsample.immutable.ImmutableMultiConstructorProperties; import org.springframework.boot.configurationsample.immutable.ImmutableSimpleProperties; -import org.springframework.boot.configurationsample.immutable.JavaBeanNameAnnotationProperties; -import org.springframework.boot.configurationsample.immutable.RecordComponentNameAnnotationProperties; import org.springframework.boot.configurationsample.lombok.LombokExplicitProperties; import org.springframework.boot.configurationsample.lombok.LombokSimpleDataProperties; import org.springframework.boot.configurationsample.lombok.LombokSimpleProperties; import org.springframework.boot.configurationsample.lombok.LombokSimpleValueProperties; +import org.springframework.boot.configurationsample.name.ConstructorParameterNameAnnotationProperties; +import org.springframework.boot.configurationsample.name.JavaBeanNameAnnotationProperties; +import org.springframework.boot.configurationsample.name.LombokNameAnnotationProperties; +import org.springframework.boot.configurationsample.name.RecordComponentNameAnnotationProperties; import org.springframework.boot.configurationsample.simple.AutowiredProperties; import org.springframework.boot.configurationsample.simple.HierarchicalProperties; import org.springframework.boot.configurationsample.simple.HierarchicalPropertiesGrandparent; @@ -162,21 +163,27 @@ class PropertyDescriptorResolverTests { } @Test - void contructorParameterPropertyWithNameAnnotationParameter() { + void constructorParameterPropertyWithNameAnnotationParameter() { process(ConstructorParameterNameAnnotationProperties.class, - propertyNames((stream) -> assertThat(stream).containsExactly("import"))); + propertyNames((stream) -> assertThat(stream).containsOnly("import", "default"))); } @Test void recordComponentPropertyWithNameAnnotationParameter() { process(RecordComponentNameAnnotationProperties.class, - propertyNames((stream) -> assertThat(stream).containsExactly("import"))); + propertyNames((stream) -> assertThat(stream).containsOnly("import", "default"))); } @Test void javaBeanPropertyWithNameAnnotationParameter() { process(JavaBeanNameAnnotationProperties.class, - propertyNames((stream) -> assertThat(stream).containsExactly("import"))); + propertyNames((stream) -> assertThat(stream).containsOnly("import", "default"))); + } + + @Test + void lombokPropertyWithNameAnnotationParameter() { + process(LombokNameAnnotationProperties.class, + propertyNames((stream) -> assertThat(stream).containsOnly("import", "default"))); } private BiConsumer properties( diff --git a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/immutable/ConstructorParameterNameAnnotationProperties.java b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/name/ConstructorParameterNameAnnotationProperties.java similarity index 67% rename from spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/immutable/ConstructorParameterNameAnnotationProperties.java rename to spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/name/ConstructorParameterNameAnnotationProperties.java index 636271beb85..cc966345f91 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/immutable/ConstructorParameterNameAnnotationProperties.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/name/ConstructorParameterNameAnnotationProperties.java @@ -14,27 +14,43 @@ * limitations under the License. */ -package org.springframework.boot.configurationsample.immutable; +package org.springframework.boot.configurationsample.name; import org.springframework.boot.configurationsample.ConfigurationProperties; +import org.springframework.boot.configurationsample.DefaultValue; import org.springframework.boot.configurationsample.Name; /** - * Immutable class properties making use of {@code @Name}. + * Constructor properties making use of {@code @Name}. * * @author Phillip Webb + * @author Stephane Nicoll */ @ConfigurationProperties("named") public class ConstructorParameterNameAnnotationProperties { + /** + * Imports to apply. + */ private final String imports; - public ConstructorParameterNameAnnotationProperties(@Name("import") String imports) { + /** + * Whether default mode is enabled. + */ + private final boolean defaultValue; + + public ConstructorParameterNameAnnotationProperties(@Name("import") String imports, + @Name("default") @DefaultValue("true") boolean defaultValue) { this.imports = imports; + this.defaultValue = defaultValue; } public String getImports() { return this.imports; } + public boolean isDefaultValue() { + return this.defaultValue; + } + } diff --git a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/immutable/JavaBeanNameAnnotationProperties.java b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/name/JavaBeanNameAnnotationProperties.java similarity index 74% rename from spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/immutable/JavaBeanNameAnnotationProperties.java rename to spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/name/JavaBeanNameAnnotationProperties.java index 427296485c8..2e5b850df08 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/immutable/JavaBeanNameAnnotationProperties.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/name/JavaBeanNameAnnotationProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.configurationsample.immutable; +package org.springframework.boot.configurationsample.name; import org.springframework.boot.configurationsample.ConfigurationProperties; import org.springframework.boot.configurationsample.Name; @@ -23,13 +23,23 @@ import org.springframework.boot.configurationsample.Name; * Java bean properties making use of {@code @Name}. * * @author Andy Wilkinson + * @author Stephane Nicoll */ @ConfigurationProperties("named") public class JavaBeanNameAnnotationProperties { + /** + * Imports to apply. + */ @Name("import") private String imports; + /** + * Whether default mode is enabled. + */ + @Name("default") + private boolean defaultValue = true; + public String getImports() { return this.imports; } @@ -38,4 +48,12 @@ public class JavaBeanNameAnnotationProperties { this.imports = imports; } + public boolean isDefaultValue() { + return this.defaultValue; + } + + public void setDefaultValue(boolean defaultValue) { + this.defaultValue = defaultValue; + } + } diff --git a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/name/LombokNameAnnotationProperties.java b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/name/LombokNameAnnotationProperties.java new file mode 100644 index 00000000000..a469852f221 --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/name/LombokNameAnnotationProperties.java @@ -0,0 +1,47 @@ +/* + * 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.configurationsample.name; + +import lombok.Getter; +import lombok.Setter; + +import org.springframework.boot.configurationsample.ConfigurationProperties; +import org.springframework.boot.configurationsample.Name; + +/** + * Lombok properties making use of {@code @Name}. + * + * @author Stephane Nicoll + */ +@Getter +@Setter +@ConfigurationProperties("named") +public class LombokNameAnnotationProperties { + + /** + * Imports to apply. + */ + @Name("import") + private String imports; + + /** + * Whether default mode is enabled. + */ + @Name("default") + private boolean defaultValue = true; + +} diff --git a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/immutable/RecordComponentNameAnnotationProperties.java b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/name/RecordComponentNameAnnotationProperties.java similarity index 70% rename from spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/immutable/RecordComponentNameAnnotationProperties.java rename to spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/name/RecordComponentNameAnnotationProperties.java index 16d0b1b3f46..d5fb3936e5f 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/immutable/RecordComponentNameAnnotationProperties.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/name/RecordComponentNameAnnotationProperties.java @@ -14,18 +14,22 @@ * limitations under the License. */ -package org.springframework.boot.configurationsample.immutable; +package org.springframework.boot.configurationsample.name; import org.springframework.boot.configurationsample.ConfigurationProperties; +import org.springframework.boot.configurationsample.DefaultValue; import org.springframework.boot.configurationsample.Name; /** - * Immutable record properties making use of {@code @Name}. + * Record properties making use of {@code @Name}. * - * @param imports some imports + * @param imports Imports to apply. + * @param defaultValue Whether default mode is enabled. * @author Andy Wilkinson + * @author Stephane Nicoll */ @ConfigurationProperties("named") -public record RecordComponentNameAnnotationProperties(@Name("import") String imports) { +public record RecordComponentNameAnnotationProperties(@Name("import") String imports, + @Name("default") @DefaultValue("true") boolean defaultValue) { }