diff --git a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/configuration-metadata/format.adoc b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/configuration-metadata/format.adoc index 58985108426..b2ce6c5dae9 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/configuration-metadata/format.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/configuration-metadata/format.adoc @@ -198,6 +198,11 @@ The JSON object contained in the `deprecation` attribute of each `properties` el | String | The full name of the property that _replaces_ this deprecated property. If there is no replacement for this property, it may be omitted. + +| `since` +| String +| The version in which the property became deprecated. + Can be omitted. |=== NOTE: Prior to Spring Boot 1.3, a single `deprecated` boolean attribute can be used instead of the `deprecation` element. diff --git a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/ConfigurationMetadataAnnotationProcessor.java b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/ConfigurationMetadataAnnotationProcessor.java index 6c805144a8d..134422b11af 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/ConfigurationMetadataAnnotationProcessor.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/ConfigurationMetadataAnnotationProcessor.java @@ -57,6 +57,7 @@ import org.springframework.boot.configurationprocessor.metadata.ItemMetadata; * @author Phillip Webb * @author Kris De Volder * @author Jonas Keßler + * @author Scott Frederick * @since 1.2.0 */ @SupportedAnnotationTypes({ ConfigurationMetadataAnnotationProcessor.AUTO_CONFIGURATION_ANNOTATION, @@ -322,16 +323,11 @@ public class ConfigurationMetadataAnnotationProcessor extends AbstractProcessor } private String getPrefix(AnnotationMirror annotation) { - Map elementValues = this.metadataEnv.getAnnotationElementValues(annotation); - Object prefix = elementValues.get("prefix"); - if (prefix != null && !"".equals(prefix)) { - return (String) prefix; + String prefix = this.metadataEnv.getAnnotationElementStringValue(annotation, "prefix"); + if (prefix != null) { + return prefix; } - Object value = elementValues.get("value"); - if (value != null && !"".equals(value)) { - return (String) value; - } - return null; + return this.metadataEnv.getAnnotationElementStringValue(annotation, "value"); } protected ConfigurationMetadata writeMetadata() throws Exception { 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 5109ffed45d..6d4cc6c3d2a 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 @@ -49,6 +49,7 @@ import org.springframework.boot.configurationprocessor.metadata.ItemDeprecation; * Provide utilities to detect and validate configuration properties. * * @author Stephane Nicoll + * @author Scott Frederick */ class MetadataGenerationEnvironment { @@ -174,14 +175,13 @@ class MetadataGenerationEnvironment { AnnotationMirror annotation = getAnnotation(element, this.deprecatedConfigurationPropertyAnnotation); String reason = null; String replacement = null; + String since = null; if (annotation != null) { - Map elementValues = getAnnotationElementValues(annotation); - reason = (String) elementValues.get("reason"); - replacement = (String) elementValues.get("replacement"); + reason = getAnnotationElementStringValue(annotation, "reason"); + replacement = getAnnotationElementStringValue(annotation, "replacement"); + since = getAnnotationElementStringValue(annotation, "since"); } - reason = (reason == null || reason.isEmpty()) ? null : reason; - replacement = (replacement == null || replacement.isEmpty()) ? null : replacement; - return new ItemDeprecation(reason, replacement); + return new ItemDeprecation(reason, replacement, since); } boolean hasConstructorBindingAnnotation(ExecutableElement element) { @@ -279,6 +279,16 @@ class MetadataGenerationEnvironment { return values; } + String getAnnotationElementStringValue(AnnotationMirror annotation, String name) { + return annotation.getElementValues() + .entrySet() + .stream() + .filter((element) -> element.getKey().getSimpleName().toString().equals(name)) + .map((element) -> asString(getAnnotationValue(element.getValue()))) + .findFirst() + .orElse(null); + } + private Object getAnnotationValue(AnnotationValue annotationValue) { Object value = annotationValue.getValue(); if (value instanceof List) { @@ -289,6 +299,10 @@ class MetadataGenerationEnvironment { return value; } + private String asString(Object value) { + return (value == null || value.toString().isEmpty()) ? null : (String) value; + } + TypeElement getConfigurationPropertiesAnnotationElement() { return this.elements.getTypeElement(this.configurationPropertiesAnnotation); } diff --git a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/PropertyDescriptorResolver.java b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/PropertyDescriptorResolver.java index 31e5630a954..e71fb074eb2 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/PropertyDescriptorResolver.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/PropertyDescriptorResolver.java @@ -91,7 +91,7 @@ class PropertyDescriptorResolver { private String getParameterName(VariableElement parameter) { AnnotationMirror nameAnnotation = this.environment.getNameAnnotation(parameter); if (nameAnnotation != null) { - return (String) this.environment.getAnnotationElementValues(nameAnnotation).get("value"); + return this.environment.getAnnotationElementStringValue(nameAnnotation, "value"); } return parameter.getSimpleName().toString(); } diff --git a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/metadata/ConfigurationMetadata.java b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/metadata/ConfigurationMetadata.java index 1281954f591..a1fff60dffa 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/metadata/ConfigurationMetadata.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/metadata/ConfigurationMetadata.java @@ -136,6 +136,9 @@ public class ConfigurationMetadata { if (deprecation.getLevel() != null) { matchingDeprecation.setLevel(deprecation.getLevel()); } + if (deprecation.getSince() != null) { + matchingDeprecation.setSince(deprecation.getSince()); + } } } } diff --git a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/metadata/ItemDeprecation.java b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/metadata/ItemDeprecation.java index 2947e94f155..21ac303b394 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/metadata/ItemDeprecation.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/metadata/ItemDeprecation.java @@ -20,6 +20,7 @@ package org.springframework.boot.configurationprocessor.metadata; * Describe an item deprecation. * * @author Stephane Nicoll + * @author Scott Frederick * @since 1.3.0 */ public class ItemDeprecation { @@ -28,19 +29,22 @@ public class ItemDeprecation { private String replacement; + private String since; + private String level; public ItemDeprecation() { - this(null, null); + this(null, null, null); } - public ItemDeprecation(String reason, String replacement) { - this(reason, replacement, null); + public ItemDeprecation(String reason, String replacement, String since) { + this(reason, replacement, since, null); } - public ItemDeprecation(String reason, String replacement, String level) { + public ItemDeprecation(String reason, String replacement, String since, String level) { this.reason = reason; this.replacement = replacement; + this.since = since; this.level = level; } @@ -60,6 +64,14 @@ public class ItemDeprecation { this.replacement = replacement; } + public String getSince() { + return this.since; + } + + public void setSince(String since) { + this.since = since; + } + public String getLevel() { return this.level; } @@ -78,7 +90,7 @@ public class ItemDeprecation { } ItemDeprecation other = (ItemDeprecation) o; return nullSafeEquals(this.reason, other.reason) && nullSafeEquals(this.replacement, other.replacement) - && nullSafeEquals(this.level, other.level); + && nullSafeEquals(this.level, other.level) && nullSafeEquals(this.since, other.since); } @Override @@ -86,13 +98,14 @@ public class ItemDeprecation { int result = nullSafeHashCode(this.reason); result = 31 * result + nullSafeHashCode(this.replacement); result = 31 * result + nullSafeHashCode(this.level); + result = 31 * result + nullSafeHashCode(this.since); return result; } @Override public String toString() { return "ItemDeprecation{reason='" + this.reason + '\'' + ", replacement='" + this.replacement + '\'' - + ", level='" + this.level + '\'' + '}'; + + ", level='" + this.level + '\'' + ", since='" + this.since + '\'' + '}'; } private boolean nullSafeEquals(Object o1, Object o2) { diff --git a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/metadata/JsonConverter.java b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/metadata/JsonConverter.java index 4c4cfda98ab..3853a853fc2 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/metadata/JsonConverter.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/metadata/JsonConverter.java @@ -83,6 +83,9 @@ class JsonConverter { if (deprecation.getReplacement() != null) { deprecationJsonObject.put("replacement", deprecation.getReplacement()); } + if (deprecation.getSince() != null) { + deprecationJsonObject.put("since", deprecation.getSince()); + } jsonObject.put("deprecation", deprecationJsonObject); } return jsonObject; diff --git a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/metadata/JsonMarshaller.java b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/metadata/JsonMarshaller.java index 53370badb6d..3243adb1785 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/metadata/JsonMarshaller.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/metadata/JsonMarshaller.java @@ -105,6 +105,7 @@ public class JsonMarshaller { deprecation.setLevel(deprecationJsonObject.optString("level", null)); deprecation.setReason(deprecationJsonObject.optString("reason", null)); deprecation.setReplacement(deprecationJsonObject.optString("replacement", null)); + deprecation.setSince(deprecationJsonObject.optString("since", null)); return deprecation; } return object.optBoolean("deprecated") ? new ItemDeprecation() : null; diff --git a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/ConfigurationMetadataAnnotationProcessorTests.java b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/ConfigurationMetadataAnnotationProcessorTests.java index 93227ecf619..d1a831a9510 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/ConfigurationMetadataAnnotationProcessorTests.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/ConfigurationMetadataAnnotationProcessorTests.java @@ -104,12 +104,12 @@ class ConfigurationMetadataAnnotationProcessorTests extends AbstractMetadataGene .fromSource(SimpleProperties.class) .withDescription("The name of this simple properties.") .withDefaultValue("boot") - .withDeprecation(null, null)); + .withDeprecation()); assertThat(metadata).has(Metadata.withProperty("simple.flag", Boolean.class) .withDefaultValue(false) .fromSource(SimpleProperties.class) .withDescription("A simple flag.") - .withDeprecation(null, null)); + .withDeprecation()); assertThat(metadata).has(Metadata.withProperty("simple.comparator")); assertThat(metadata).doesNotHave(Metadata.withProperty("simple.counter")); assertThat(metadata).doesNotHave(Metadata.withProperty("simple.size")); @@ -188,10 +188,9 @@ class ConfigurationMetadataAnnotationProcessorTests extends AbstractMetadataGene ConfigurationMetadata metadata = compile(type); assertThat(metadata).has(Metadata.withGroup("deprecated").fromSource(type)); assertThat(metadata) - .has(Metadata.withProperty("deprecated.name", String.class).fromSource(type).withDeprecation(null, null)); - assertThat(metadata).has(Metadata.withProperty("deprecated.description", String.class) - .fromSource(type) - .withDeprecation(null, null)); + .has(Metadata.withProperty("deprecated.name", String.class).fromSource(type).withDeprecation()); + assertThat(metadata) + .has(Metadata.withProperty("deprecated.description", String.class).fromSource(type).withDeprecation()); } @Test @@ -202,7 +201,7 @@ class ConfigurationMetadataAnnotationProcessorTests extends AbstractMetadataGene assertThat(metadata).has(Metadata.withProperty("singledeprecated.new-name", String.class).fromSource(type)); assertThat(metadata).has(Metadata.withProperty("singledeprecated.name", String.class) .fromSource(type) - .withDeprecation("renamed", "singledeprecated.new-name")); + .withDeprecation("renamed", "singledeprecated.new-name", "1.2.3")); } @Test @@ -210,9 +209,8 @@ class ConfigurationMetadataAnnotationProcessorTests extends AbstractMetadataGene Class type = DeprecatedFieldSingleProperty.class; ConfigurationMetadata metadata = compile(type); assertThat(metadata).has(Metadata.withGroup("singlefielddeprecated").fromSource(type)); - assertThat(metadata).has(Metadata.withProperty("singlefielddeprecated.name", String.class) - .fromSource(type) - .withDeprecation(null, null)); + assertThat(metadata) + .has(Metadata.withProperty("singlefielddeprecated.name", String.class).fromSource(type).withDeprecation()); } @Test @@ -246,7 +244,7 @@ class ConfigurationMetadataAnnotationProcessorTests extends AbstractMetadataGene assertThat(metadata).has(Metadata.withGroup("deprecated-record").fromSource(type)); assertThat(metadata).has(Metadata.withProperty("deprecated-record.alpha", String.class) .fromSource(type) - .withDeprecation("some-reason", null)); + .withDeprecation("some-reason", null, null)); assertThat(metadata).has(Metadata.withProperty("deprecated-record.bravo", String.class).fromSource(type)); } diff --git a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/ImmutablePropertiesMetadataGenerationTests.java b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/ImmutablePropertiesMetadataGenerationTests.java index 6e3571539ff..5b87c0137ff 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/ImmutablePropertiesMetadataGenerationTests.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/ImmutablePropertiesMetadataGenerationTests.java @@ -43,7 +43,7 @@ class ImmutablePropertiesMetadataGenerationTests extends AbstractMetadataGenerat .withDefaultValue(false) .fromSource(ImmutableSimpleProperties.class) .withDescription("A simple flag.") - .withDeprecation(null, null)); + .withDeprecation()); assertThat(metadata).has(Metadata.withProperty("immutable.comparator")); assertThat(metadata).has(Metadata.withProperty("immutable.counter")); assertThat(metadata.getItems()).hasSize(5); diff --git a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/LombokMetadataGenerationTests.java b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/LombokMetadataGenerationTests.java index 69f0bb87184..2721f0c28a5 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/LombokMetadataGenerationTests.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/LombokMetadataGenerationTests.java @@ -139,10 +139,8 @@ class LombokMetadataGenerationTests extends AbstractMetadataGenerationTests { .withDescription("Name description.")); assertThat(metadata).has(Metadata.withProperty(prefix + ".description")); assertThat(metadata).has(Metadata.withProperty(prefix + ".counter")); - assertThat(metadata).has(Metadata.withProperty(prefix + ".number") - .fromSource(source) - .withDefaultValue(0) - .withDeprecation(null, null)); + assertThat(metadata) + .has(Metadata.withProperty(prefix + ".number").fromSource(source).withDefaultValue(0).withDeprecation()); assertThat(metadata).has(Metadata.withProperty(prefix + ".items")); assertThat(metadata).doesNotHave(Metadata.withProperty(prefix + ".ignored")); } diff --git a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/MergeMetadataGenerationTests.java b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/MergeMetadataGenerationTests.java index 167feb22f99..c35e74755c8 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/MergeMetadataGenerationTests.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/MergeMetadataGenerationTests.java @@ -74,7 +74,7 @@ class MergeMetadataGenerationTests extends AbstractMetadataGenerationTests { assertThat(metadata).has(Metadata.withProperty("simple.flag", Boolean.class) .fromSource(SimpleProperties.class) .withDescription("A simple flag.") - .withDeprecation(null, null) + .withDeprecation() .withDefaultValue(true)); assertThat(metadata.getItems()).hasSize(4); } @@ -125,36 +125,36 @@ class MergeMetadataGenerationTests extends AbstractMetadataGenerationTests { @Test void mergeExistingPropertyDeprecation() throws Exception { ItemMetadata property = ItemMetadata.newProperty("simple", "comparator", null, null, null, null, null, - new ItemDeprecation("Don't use this.", "simple.complex-comparator", "error")); + new ItemDeprecation("Don't use this.", "simple.complex-comparator", "1.2.3", "error")); String additionalMetadata = buildAdditionalMetadata(property); ConfigurationMetadata metadata = compile(additionalMetadata, SimpleProperties.class); assertThat(metadata).has(Metadata.withProperty("simple.comparator", "java.util.Comparator") .fromSource(SimpleProperties.class) - .withDeprecation("Don't use this.", "simple.complex-comparator", "error")); + .withDeprecation("Don't use this.", "simple.complex-comparator", "1.2.3", "error")); assertThat(metadata.getItems()).hasSize(4); } @Test void mergeExistingPropertyDeprecationOverride() throws Exception { ItemMetadata property = ItemMetadata.newProperty("singledeprecated", "name", null, null, null, null, null, - new ItemDeprecation("Don't use this.", "single.name")); + new ItemDeprecation("Don't use this.", "single.name", "1.2.3")); String additionalMetadata = buildAdditionalMetadata(property); ConfigurationMetadata metadata = compile(additionalMetadata, DeprecatedSingleProperty.class); assertThat(metadata).has(Metadata.withProperty("singledeprecated.name", String.class.getName()) .fromSource(DeprecatedSingleProperty.class) - .withDeprecation("Don't use this.", "single.name")); + .withDeprecation("Don't use this.", "single.name", "1.2.3")); assertThat(metadata.getItems()).hasSize(3); } @Test void mergeExistingPropertyDeprecationOverrideLevel() throws Exception { ItemMetadata property = ItemMetadata.newProperty("singledeprecated", "name", null, null, null, null, null, - new ItemDeprecation(null, null, "error")); + new ItemDeprecation(null, null, null, "error")); String additionalMetadata = buildAdditionalMetadata(property); ConfigurationMetadata metadata = compile(additionalMetadata, DeprecatedSingleProperty.class); assertThat(metadata).has(Metadata.withProperty("singledeprecated.name", String.class.getName()) .fromSource(DeprecatedSingleProperty.class) - .withDeprecation("renamed", "singledeprecated.new-name", "error")); + .withDeprecation("renamed", "singledeprecated.new-name", "1.2.3", "error")); assertThat(metadata.getItems()).hasSize(3); } @@ -175,7 +175,7 @@ class MergeMetadataGenerationTests extends AbstractMetadataGenerationTests { .fromSource(SimpleProperties.class) .withDescription("The name of this simple properties.") .withDefaultValue("boot") - .withDeprecation(null, null)); + .withDeprecation()); assertThat(metadata) .has(Metadata.withHint("simple.the-name").withValue(0, "boot", "Bla bla").withValue(1, "spring", null)); } @@ -189,7 +189,7 @@ class MergeMetadataGenerationTests extends AbstractMetadataGenerationTests { .fromSource(SimpleProperties.class) .withDescription("The name of this simple properties.") .withDefaultValue("boot") - .withDeprecation(null, null)); + .withDeprecation()); assertThat(metadata).has(Metadata.withHint("simple.the-name").withValue(0, "boot", "Bla bla")); } @@ -203,18 +203,19 @@ class MergeMetadataGenerationTests extends AbstractMetadataGenerationTests { .fromSource(SimpleProperties.class) .withDescription("The name of this simple properties.") .withDefaultValue("boot") - .withDeprecation(null, null)); + .withDeprecation()); assertThat(metadata).has( Metadata.withHint("simple.the-name").withProvider("first", "target", "org.foo").withProvider("second")); } @Test void mergingOfAdditionalDeprecation() throws Exception { - String deprecations = buildPropertyDeprecations(ItemMetadata.newProperty("simple", "wrongName", - "java.lang.String", null, null, null, null, new ItemDeprecation("Lame name.", "simple.the-name"))); + String deprecations = buildPropertyDeprecations( + ItemMetadata.newProperty("simple", "wrongName", "java.lang.String", null, null, null, null, + new ItemDeprecation("Lame name.", "simple.the-name", "1.2.3"))); ConfigurationMetadata metadata = compile(deprecations, SimpleProperties.class); assertThat(metadata).has(Metadata.withProperty("simple.wrong-name", String.class) - .withDeprecation("Lame name.", "simple.the-name")); + .withDeprecation("Lame name.", "simple.the-name", "1.2.3")); } @Test @@ -268,6 +269,9 @@ class MergeMetadataGenerationTests extends AbstractMetadataGenerationTests { if (deprecation.getReplacement() != null) { deprecationJson.put("replacement", deprecation.getReplacement()); } + if (deprecation.getSince() != null) { + deprecationJson.put("since", deprecation.getSince()); + } jsonObject.put("deprecation", deprecationJson); } propertiesArray.put(jsonObject); diff --git a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/MethodBasedMetadataGenerationTests.java b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/MethodBasedMetadataGenerationTests.java index e7391bf9808..591c410b16b 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/MethodBasedMetadataGenerationTests.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/MethodBasedMetadataGenerationTests.java @@ -114,11 +114,11 @@ class MethodBasedMetadataGenerationTests extends AbstractMetadataGenerationTests assertThat(metadata).has(Metadata.withGroup("foo").fromSource(type)); assertThat(metadata).has(Metadata.withProperty("foo.name", String.class) .fromSource(DeprecatedMethodConfig.Foo.class) - .withDeprecation(null, null)); + .withDeprecation()); assertThat(metadata).has(Metadata.withProperty("foo.flag", Boolean.class) .withDefaultValue(false) .fromSource(DeprecatedMethodConfig.Foo.class) - .withDeprecation(null, null)); + .withDeprecation()); } @Test @@ -129,11 +129,11 @@ class MethodBasedMetadataGenerationTests extends AbstractMetadataGenerationTests assertThat(metadata).has(Metadata.withGroup("foo").fromSource(type)); assertThat(metadata).has(Metadata.withProperty("foo.name", String.class) .fromSource(org.springframework.boot.configurationsample.method.DeprecatedClassMethodConfig.Foo.class) - .withDeprecation(null, null)); + .withDeprecation()); assertThat(metadata).has(Metadata.withProperty("foo.flag", Boolean.class) .withDefaultValue(false) .fromSource(org.springframework.boot.configurationsample.method.DeprecatedClassMethodConfig.Foo.class) - .withDeprecation(null, null)); + .withDeprecation()); } } diff --git a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/metadata/JsonMarshallerTests.java b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/metadata/JsonMarshallerTests.java index 2cbda570e8a..f7054f72120 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/metadata/JsonMarshallerTests.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/metadata/JsonMarshallerTests.java @@ -39,7 +39,7 @@ class JsonMarshallerTests { void marshallAndUnmarshal() throws Exception { ConfigurationMetadata metadata = new ConfigurationMetadata(); metadata.add(ItemMetadata.newProperty("a", "b", StringBuffer.class.getName(), InputStream.class.getName(), - "sourceMethod", "desc", "x", new ItemDeprecation("Deprecation comment", "b.c.d"))); + "sourceMethod", "desc", "x", new ItemDeprecation("Deprecation comment", "b.c.d", "1.2.3"))); metadata.add(ItemMetadata.newProperty("b.c.d", null, null, null, null, null, null, null)); metadata.add(ItemMetadata.newProperty("c", null, null, null, null, null, 123, null)); metadata.add(ItemMetadata.newProperty("d", null, null, null, null, null, true, null)); @@ -59,7 +59,7 @@ class JsonMarshallerTests { .fromSource(InputStream.class) .withDescription("desc") .withDefaultValue("x") - .withDeprecation("Deprecation comment", "b.c.d")); + .withDeprecation("Deprecation comment", "b.c.d", "1.2.3")); assertThat(read).has(Metadata.withProperty("b.c.d")); assertThat(read).has(Metadata.withProperty("c").withDefaultValue(123)); assertThat(read).has(Metadata.withProperty("d").withDefaultValue(true)); @@ -96,10 +96,10 @@ class JsonMarshallerTests { ConfigurationMetadata metadata = new ConfigurationMetadata(); metadata.add(ItemMetadata.newProperty("com.example.bravo", "bbb", null, null, null, null, null, null)); metadata.add(ItemMetadata.newProperty("com.example.bravo", "aaa", null, null, null, null, null, - new ItemDeprecation(null, null, "warning"))); + new ItemDeprecation(null, null, null, "warning"))); metadata.add(ItemMetadata.newProperty("com.example.alpha", "ddd", null, null, null, null, null, null)); metadata.add(ItemMetadata.newProperty("com.example.alpha", "ccc", null, null, null, null, null, - new ItemDeprecation(null, null, "warning"))); + new ItemDeprecation(null, null, null, "warning"))); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); JsonMarshaller marshaller = new JsonMarshaller(); marshaller.write(metadata, outputStream); diff --git a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/metadata/Metadata.java b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/metadata/Metadata.java index 39be910daf5..0930084cf4c 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/metadata/Metadata.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/metadata/Metadata.java @@ -193,13 +193,17 @@ public final class Metadata { this.description, defaultValue, this.deprecation); } - public MetadataItemCondition withDeprecation(String reason, String replacement) { - return withDeprecation(reason, replacement, null); + public MetadataItemCondition withDeprecation() { + return withDeprecation(null, null, null, null); } - public MetadataItemCondition withDeprecation(String reason, String replacement, String level) { + public MetadataItemCondition withDeprecation(String reason, String replacement, String since) { + return withDeprecation(reason, replacement, since, null); + } + + public MetadataItemCondition withDeprecation(String reason, String replacement, String since, String level) { return new MetadataItemCondition(this.itemType, this.name, this.type, this.sourceType, this.sourceMethod, - this.description, this.defaultValue, new ItemDeprecation(reason, replacement, level)); + this.description, this.defaultValue, new ItemDeprecation(reason, replacement, since, level)); } public MetadataItemCondition withNoDeprecation() { diff --git a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/DeprecatedConfigurationProperty.java b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/DeprecatedConfigurationProperty.java index 0853090e938..29116a50850 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/DeprecatedConfigurationProperty.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/DeprecatedConfigurationProperty.java @@ -50,4 +50,10 @@ public @interface DeprecatedConfigurationProperty { */ String replacement() default ""; + /** + * The version in which the property became deprecated. + * @return the version + */ + String since() default ""; + } diff --git a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/simple/DeprecatedSingleProperty.java b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/simple/DeprecatedSingleProperty.java index f8df3f7c4ae..904d3100af2 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/simple/DeprecatedSingleProperty.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/simple/DeprecatedSingleProperty.java @@ -30,7 +30,7 @@ public class DeprecatedSingleProperty { private String newName; @Deprecated - @DeprecatedConfigurationProperty(reason = "renamed", replacement = "singledeprecated.new-name") + @DeprecatedConfigurationProperty(reason = "renamed", replacement = "singledeprecated.new-name", since = "1.2.3") public String getName() { return getNewName(); } diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/DeprecatedConfigurationProperty.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/DeprecatedConfigurationProperty.java index 23940cde127..7ac7bc98592 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/DeprecatedConfigurationProperty.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/DeprecatedConfigurationProperty.java @@ -31,6 +31,7 @@ import java.lang.annotation.Target; * This annotation must be used on the getter of the deprecated element. * * @author Phillip Webb + * @author Scott Frederick * @since 1.3.0 */ @Target(ElementType.METHOD) @@ -50,4 +51,10 @@ public @interface DeprecatedConfigurationProperty { */ String replacement() default ""; + /** + * The version in which the property became deprecated. + * @return the version + */ + String since() default ""; + }