diff --git a/spring-boot-docs/src/main/asciidoc/appendix-configuration-metadata.adoc b/spring-boot-docs/src/main/asciidoc/appendix-configuration-metadata.adoc index 43c12ed9cb..464e82701d 100644 --- a/spring-boot-docs/src/main/asciidoc/appendix-configuration-metadata.adoc +++ b/spring-boot-docs/src/main/asciidoc/appendix-configuration-metadata.adoc @@ -205,23 +205,30 @@ contain the following attributes: |=== |Name | Type |Purpose +|`level` +|String +|The level of deprecation, can be either `warning` (default) or `error`. When a property + has a `warning` deprecation level it should still be bound in the environment. When it + has an `error` deprecation level however, the property is no longer managed and will not + be bound. + |`reason` -| String -| A short description of the reason why the property was deprecated. May be omitted if no - reason is available. It is recommended that descriptions are a short paragraphs, - with the first line providing a concise summary. The last line in the description should - end with a period (`.`). +|String +|A short description of the reason why the property was deprecated. May be omitted if no + reason is available. It is recommended that descriptions are a short paragraphs, + with the first line providing a concise summary. The last line in the description should + end with a period (`.`). |`replacement` -| String -| The full name of the property that is _replacing_ this deprecated property. May be omitted - if there is no replacement for this property. +|String +|The full name of the property that is _replacing_ this deprecated property. May be omitted + if there is no replacement for this property. |=== -NOTE: Prior to Spring Boot 1.3, a single `deprecated` boolean attribute can be used instead of -the `deprecation` element. This is still supported in a deprecated fashion and should no longer -be used. If no reason and replacement are available, an empty `deprecation` object should be -set. +NOTE: Prior to Spring Boot 1.3, a single `deprecated` boolean attribute can be used +instead of the `deprecation` element. This is still supported in a deprecated fashion and +should no longer be used. If no reason and replacement are available, an empty +`deprecation` object should be set. Deprecation can also be specified declaratively in code by adding the `@DeprecatedConfigurationProperty` annotation to the getter exposing the deprecated @@ -252,10 +259,15 @@ was renamed to `app.foo.name` } ---- +NOTE: There is no way to set a `level` as `warning` is always assumed since code is still +handling the property. + The code above makes sure that the deprecated property still works (delegating to the `name` property behind the scenes). Once the `getTarget` and `setTarget` methods can be removed from your public API, the automatic deprecation hint in the -meta-data will go away as well. +meta-data will go away as well. If you want to keep a hint, adding manual meta-data with +an `error` deprecation level ensures that users are still informed about that property and +is particularly useful when a `replacement` is provided. diff --git a/spring-boot-tools/spring-boot-configuration-metadata/src/main/java/org/springframework/boot/configurationmetadata/Deprecation.java b/spring-boot-tools/spring-boot-configuration-metadata/src/main/java/org/springframework/boot/configurationmetadata/Deprecation.java index 8261a2a85b..061d7a4629 100644 --- a/spring-boot-tools/spring-boot-configuration-metadata/src/main/java/org/springframework/boot/configurationmetadata/Deprecation.java +++ b/spring-boot-tools/spring-boot-configuration-metadata/src/main/java/org/springframework/boot/configurationmetadata/Deprecation.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2015 the original author or authors. + * Copyright 2012-2017 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. @@ -28,10 +28,24 @@ import java.io.Serializable; @SuppressWarnings("serial") public class Deprecation implements Serializable { + private Level level = Level.WARNING; + private String reason; private String replacement; + /** + * Define the {@link Level} of deprecation. + * @return the deprecation level + */ + public Level getLevel() { + return this.level; + } + + public void setLevel(Level level) { + this.level = level; + } + /** * A reason why the related property is deprecated, if any. Can be multi-lines. * @return the deprecation reason @@ -59,8 +73,25 @@ public class Deprecation implements Serializable { @Override public String toString() { - return "Deprecation{" + "reason='" + this.reason + '\'' + ", replacement='" - + this.replacement + '\'' + '}'; + return "Deprecation{" + "level='" + this.level + '\'' + ", reason='" + + this.reason + '\'' + ", replacement='" + this.replacement + '\'' + '}'; + } + + /** + * Define the deprecation level. + */ + public enum Level { + + /** + * The property is still bound. + */ + WARNING, + + /** + * The property has been removed and is no longer bound. + */ + ERROR + } } diff --git a/spring-boot-tools/spring-boot-configuration-metadata/src/main/java/org/springframework/boot/configurationmetadata/JsonReader.java b/spring-boot-tools/spring-boot-configuration-metadata/src/main/java/org/springframework/boot/configurationmetadata/JsonReader.java index 442df6ec35..732b3b9ba6 100644 --- a/spring-boot-tools/spring-boot-configuration-metadata/src/main/java/org/springframework/boot/configurationmetadata/JsonReader.java +++ b/spring-boot-tools/spring-boot-configuration-metadata/src/main/java/org/springframework/boot/configurationmetadata/JsonReader.java @@ -170,6 +170,8 @@ class JsonReader { if (object.has("deprecation")) { JSONObject deprecationJsonObject = object.getJSONObject("deprecation"); Deprecation deprecation = new Deprecation(); + deprecation.setLevel(parseDeprecationLevel( + deprecationJsonObject.optString("level", null))); deprecation.setReason(deprecationJsonObject.optString("reason", null)); deprecation .setReplacement(deprecationJsonObject.optString("replacement", null)); @@ -178,6 +180,18 @@ class JsonReader { return (object.optBoolean("deprecated") ? new Deprecation() : null); } + private Deprecation.Level parseDeprecationLevel(String value) { + if (value != null) { + try { + return Deprecation.Level.valueOf(value.toUpperCase()); + } + catch (IllegalArgumentException e) { + // let's use the default + } + } + return Deprecation.Level.WARNING; + } + private Object readItemValue(Object value) throws Exception { if (value instanceof JSONArray) { JSONArray array = (JSONArray) value; diff --git a/spring-boot-tools/spring-boot-configuration-metadata/src/test/java/org/springframework/boot/configurationmetadata/JsonReaderTests.java b/spring-boot-tools/spring-boot-configuration-metadata/src/test/java/org/springframework/boot/configurationmetadata/JsonReaderTests.java index fce621433c..567c341daa 100644 --- a/spring-boot-tools/spring-boot-configuration-metadata/src/test/java/org/springframework/boot/configurationmetadata/JsonReaderTests.java +++ b/spring-boot-tools/spring-boot-configuration-metadata/src/test/java/org/springframework/boot/configurationmetadata/JsonReaderTests.java @@ -148,7 +148,7 @@ public class JsonReaderTests extends AbstractConfigurationMetadataTests { public void deprecatedMetadata() throws IOException { RawConfigurationMetadata rawMetadata = readFor("deprecated"); List items = rawMetadata.getItems(); - assertThat(items).hasSize(3); + assertThat(items).hasSize(5); ConfigurationMetadataItem item = items.get(0); assertProperty(item, "server.port", "server.port", Integer.class, null); @@ -157,19 +157,41 @@ public class JsonReaderTests extends AbstractConfigurationMetadataTests { .isEqualTo("Server namespace has moved to spring.server"); assertThat(item.getDeprecation().getReplacement()) .isEqualTo("server.spring.port"); + assertThat(item.getDeprecation().getLevel()) + .isEqualTo(Deprecation.Level.WARNING); ConfigurationMetadataItem item2 = items.get(1); assertProperty(item2, "server.cluster-name", "server.cluster-name", String.class, null); assertThat(item2.isDeprecated()).isTrue(); - assertThat(item2.getDeprecation().getReason()).isEqualTo(null); - assertThat(item2.getDeprecation().getReplacement()).isEqualTo(null); + assertThat(item2.getDeprecation().getReason()).isNull(); + assertThat(item2.getDeprecation().getReplacement()).isNull(); + assertThat(item.getDeprecation().getLevel()) + .isEqualTo(Deprecation.Level.WARNING); ConfigurationMetadataItem item3 = items.get(2); assertProperty(item3, "spring.server.name", "spring.server.name", String.class, null); assertThat(item3.isDeprecated()).isFalse(); assertThat(item3.getDeprecation()).isEqualTo(null); + + ConfigurationMetadataItem item4 = items.get(3); + assertProperty(item4, "spring.server-name", "spring.server-name", String.class, null); + assertThat(item4.isDeprecated()).isTrue(); + assertThat(item4.getDeprecation().getReason()).isNull(); + assertThat(item4.getDeprecation().getReplacement()) + .isEqualTo("spring.server.name"); + assertThat(item4.getDeprecation().getLevel()) + .isEqualTo(Deprecation.Level.ERROR); + + ConfigurationMetadataItem item5 = items.get(4); + assertProperty(item5, "spring.server-name2", "spring.server-name2", String.class, null); + assertThat(item5.isDeprecated()).isTrue(); + assertThat(item5.getDeprecation().getReason()).isNull(); + assertThat(item5.getDeprecation().getReplacement()) + .isEqualTo("spring.server.name"); + assertThat(item5.getDeprecation().getLevel()) + .isEqualTo(Deprecation.Level.WARNING); } RawConfigurationMetadata readFor(String path) throws IOException { diff --git a/spring-boot-tools/spring-boot-configuration-metadata/src/test/resources/metadata/configuration-metadata-deprecated.json b/spring-boot-tools/spring-boot-configuration-metadata/src/test/resources/metadata/configuration-metadata-deprecated.json index 1a2cdec82a..af288967e1 100644 --- a/spring-boot-tools/spring-boot-configuration-metadata/src/test/resources/metadata/configuration-metadata-deprecated.json +++ b/spring-boot-tools/spring-boot-configuration-metadata/src/test/resources/metadata/configuration-metadata-deprecated.json @@ -17,6 +17,22 @@ "name": "spring.server.name", "type": "java.lang.String", "deprecated": false - } + }, + { + "name": "spring.server-name", + "type": "java.lang.String", + "deprecation": { + "level": "error", + "replacement": "spring.server.name" + } + }, + { + "name": "spring.server-name2", + "type": "java.lang.String", + "deprecation": { + "level": "INVALID", + "replacement": "spring.server.name" + } + } ] } \ No newline at end of file