diff --git a/spring-boot-actuator/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-actuator/src/main/resources/META-INF/additional-spring-configuration-metadata.json index 943924932f..51f80ffbb6 100644 --- a/spring-boot-actuator/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ b/spring-boot-actuator/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -102,9 +102,11 @@ { "name": "spring.pidfile", "type": "java.lang.String", - "deprecated": true, "description": "Location of the PID file to write (if ApplicationPidFileWriter is used).", - "sourceType": "org.springframework.boot.actuate.system.ApplicationPidFileWriter" + "sourceType": "org.springframework.boot.actuate.system.ApplicationPidFileWriter", + "deprecation": { + "replacement": "spring.pid.file" + } } ],"hints": [ { diff --git a/spring-boot-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json index 521d4d158f..167a2dd756 100644 --- a/spring-boot-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ b/spring-boot-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -150,19 +150,25 @@ "name": "spring.view.prefix", "type": "java.lang.String", "description": "Spring MVC view prefix.", - "deprecated": true + "deprecation": { + "replacement": "spring.mvc.view.prefix" + } }, { "name": "spring.view.suffix", "type": "java.lang.String", "description": "Spring MVC view suffix.", - "deprecated": true + "deprecation": { + "replacement": "spring.mvc.view.suffix" + } }, { "name": "server.session-timeout", "type": "java.lang.Integer", "description": "Session timeout in seconds.", - "deprecated": true + "deprecation": { + "replacement": "server.session.timeout" + } } ],"hints": [ { 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 7b7aa785e3..c4d291f951 100644 --- a/spring-boot-docs/src/main/asciidoc/appendix-configuration-metadata.adoc +++ b/spring-boot-docs/src/main/asciidoc/appendix-configuration-metadata.adoc @@ -188,12 +188,36 @@ The JSON object contained in the `properties` array can contain the following at array of value(s) if the type of the property is an array. May be omitted if the default value is not known. -|`deprecated` -| boolean +|`deprecation` +| Deprecation | Specify if the property is deprecated. May be omitted if the field is not deprecated - or if that information is not known. + or if that information is not known. See below for more details. |=== +The JSON object contained in the `deprecation` attribute of each `properties` element can +contain the following attributes: + +[cols="1,1,4"] +|=== +|Name | Type |Purpose + +|`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 (`.`). + +|`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. +|=== + +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. [[configuration-metadata-hints-attributes]] diff --git a/spring-boot-tools/spring-boot-configuration-metadata/src/main/java/org/springframework/boot/configurationmetadata/ConfigurationMetadataProperty.java b/spring-boot-tools/spring-boot-configuration-metadata/src/main/java/org/springframework/boot/configurationmetadata/ConfigurationMetadataProperty.java index 4579cdc987..8cd281c7cd 100644 --- a/spring-boot-tools/spring-boot-configuration-metadata/src/main/java/org/springframework/boot/configurationmetadata/ConfigurationMetadataProperty.java +++ b/spring-boot-tools/spring-boot-configuration-metadata/src/main/java/org/springframework/boot/configurationmetadata/ConfigurationMetadataProperty.java @@ -46,7 +46,7 @@ public class ConfigurationMetadataProperty { private final List valueProviders = new ArrayList(); - private boolean deprecated; + private Deprecation deprecation; /** * The full identifier of the property, in lowercase dashed form (e.g. @@ -154,16 +154,26 @@ public class ConfigurationMetadataProperty { return this.valueProviders; } + /** + * The {@link Deprecation} for this property, if any. + * @return the deprecation + * @see #isDeprecated() + */ + public Deprecation getDeprecation() { + return deprecation; + } + + public void setDeprecation(Deprecation deprecation) { + this.deprecation = deprecation; + } + /** * Specify if the property is deprecated. * @return if the property is deprecated + * @see #getDeprecation() */ public boolean isDeprecated() { - return this.deprecated; - } - - public void setDeprecated(boolean deprecated) { - this.deprecated = deprecated; + return this.deprecation != null; } } 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 new file mode 100644 index 0000000000..b511e30b04 --- /dev/null +++ b/spring-boot-tools/spring-boot-configuration-metadata/src/main/java/org/springframework/boot/configurationmetadata/Deprecation.java @@ -0,0 +1,61 @@ +/* + * Copyright 2012-2015 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 + * + * http://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.configurationmetadata; + +/** + * Indicate that a property is deprecated. Provide additional information about the + * deprecation. + * + * @author Stephane Nicoll + * @since 1.3.0 + */ +public class Deprecation { + + private String reason; + + private String replacement; + + /** + * A reason why the related property is deprecated, if any. Can be multi-lines. + * @return the deprecation reason + */ + public String getReason() { + return reason; + } + + public void setReason(String reason) { + this.reason = reason; + } + + /** + * The full name of the property that replaces the related deprecated property, if any. + * @return the replacement property name + */ + public String getReplacement() { + return replacement; + } + + public void setReplacement(String replacement) { + this.replacement = replacement; + } + + @Override + public String toString() { + return "Deprecation{" + "reason='" + reason + '\'' + ", replacement='" + replacement + '\'' + '}'; + } + +} 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 17867aa687..3702a6afaf 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 @@ -109,7 +109,7 @@ class JsonReader { item.setShortDescription(this.descriptionExtractor .getShortDescription(description)); item.setDefaultValue(readItemValue(json.opt("defaultValue"))); - item.setDeprecated(json.optBoolean("deprecated", false)); + item.setDeprecation(parseDeprecation(json)); item.setSourceType(json.optString("sourceType", null)); item.setSourceMethod(json.optString("sourceMethod", null)); return item; @@ -152,6 +152,17 @@ class JsonReader { return hint; } + private Deprecation parseDeprecation(JSONObject object) { + if (object.has("deprecation")) { + JSONObject deprecationJsonObject = object.getJSONObject("deprecation"); + Deprecation deprecation = new Deprecation(); + deprecation.setReason(deprecationJsonObject.optString("reason", null)); + deprecation.setReplacement(deprecationJsonObject.optString("replacement", null)); + return deprecation; + } + return (object.optBoolean("deprecated") ? new Deprecation() : null); + } + private Object readItemValue(Object value) { 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 c099c17fb7..7286f5aa23 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 @@ -24,7 +24,9 @@ import org.json.JSONException; import org.junit.Test; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; /** * Tests for {@link JsonReader} @@ -130,6 +132,30 @@ public class JsonReaderTests extends AbstractConfigurationMetadataTests { assertProperty(item, "spring.root.name", "spring.root.name", String.class, null); } + @Test + public void deprecatedMetadata() throws IOException { + RawConfigurationMetadata rawMetadata = readFor("deprecated"); + List items = rawMetadata.getItems(); + assertEquals(3, items.size()); + + ConfigurationMetadataItem item = items.get(0); + assertProperty(item, "server.port", "server.port", Integer.class, null); + assertTrue(item.isDeprecated()); + assertEquals("Server namespace has moved to spring.server", item.getDeprecation().getReason()); + assertEquals("server.spring.port", item.getDeprecation().getReplacement()); + + ConfigurationMetadataItem item2 = items.get(1); + assertProperty(item2, "server.cluster-name", "server.cluster-name", String.class, null); + assertTrue(item2.isDeprecated()); + assertEquals(null, item2.getDeprecation().getReason()); + assertEquals(null, item2.getDeprecation().getReplacement()); + + ConfigurationMetadataItem item3 = items.get(2); + assertProperty(item3, "spring.server.name", "spring.server.name", String.class, null); + assertFalse(item3.isDeprecated()); + assertEquals(null, item3.getDeprecation()); + } + RawConfigurationMetadata readFor(String path) throws IOException { return this.reader.read(getInputStreamFor(path), DEFAULT_CHARSET); } 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 new file mode 100644 index 0000000000..1a2cdec82a --- /dev/null +++ b/spring-boot-tools/spring-boot-configuration-metadata/src/test/resources/metadata/configuration-metadata-deprecated.json @@ -0,0 +1,22 @@ +{ + "properties": [ + { + "name": "server.port", + "type": "java.lang.Integer", + "deprecation": { + "reason": "Server namespace has moved to spring.server", + "replacement": "server.spring.port" + } + }, + { + "name": "server.cluster-name", + "type": "java.lang.String", + "deprecated": true + }, + { + "name": "spring.server.name", + "type": "java.lang.String", + "deprecated": false + } + ] +} \ No newline at end of file diff --git a/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/ConfigurationMetadataAnnotationProcessor.java b/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/ConfigurationMetadataAnnotationProcessor.java index 8c3adb8263..f10c6b67b6 100644 --- a/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/ConfigurationMetadataAnnotationProcessor.java +++ b/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/ConfigurationMetadataAnnotationProcessor.java @@ -48,6 +48,7 @@ import org.springframework.boot.configurationprocessor.fieldvalues.FieldValuesPa import org.springframework.boot.configurationprocessor.fieldvalues.javac.JavaCompilerFieldValuesParser; import org.springframework.boot.configurationprocessor.metadata.ConfigurationMetadata; import org.springframework.boot.configurationprocessor.metadata.InvalidConfigurationMetadataException; +import org.springframework.boot.configurationprocessor.metadata.ItemDeprecation; import org.springframework.boot.configurationprocessor.metadata.ItemMetadata; /** @@ -211,7 +212,8 @@ public class ConfigurationMetadataAnnotationProcessor extends AbstractProcessor || hasDeprecateAnnotation(element); this.metadataCollector.add(ItemMetadata .newProperty(prefix, name, dataType, sourceType, null, - description, defaultValue, deprecated)); + description, defaultValue, + deprecated ? new ItemDeprecation() : null)); } } } @@ -240,7 +242,8 @@ public class ConfigurationMetadataAnnotationProcessor extends AbstractProcessor || hasDeprecateAnnotation(element); this.metadataCollector.add(ItemMetadata .newProperty(prefix, name, dataType, sourceType, null, - description, defaultValue, deprecated)); + description, defaultValue, + deprecated ? new ItemDeprecation() : null)); } } } diff --git a/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/metadata/ItemDeprecation.java b/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/metadata/ItemDeprecation.java new file mode 100644 index 0000000000..6ff9125959 --- /dev/null +++ b/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/metadata/ItemDeprecation.java @@ -0,0 +1,79 @@ +/* + * Copyright 2012-2015 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 + * + * http://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.configurationprocessor.metadata; + +/** + * Describe an item deprecation. + * + * @author Stephane Nicoll + * @since 1.3.0 + */ +public class ItemDeprecation { + + private String reason; + + private String replacement; + + public ItemDeprecation() { + } + + public ItemDeprecation(String reason, String replacement) { + this.reason = reason; + this.replacement = replacement; + } + + public String getReason() { + return reason; + } + + public void setReason(String reason) { + this.reason = reason; + } + + public String getReplacement() { + return replacement; + } + + public void setReplacement(String replacement) { + this.replacement = replacement; + } + + @Override + public String toString() { + return "ItemDeprecation{" + "reason='" + this.reason + '\'' + ", " + + "replacement='" + this.replacement + '\'' + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + ItemDeprecation that = (ItemDeprecation) o; + + if (reason != null ? !reason.equals(that.reason) : that.reason != null) return false; + return !(replacement != null ? !replacement.equals(that.replacement) : that.replacement != null); + + } + + @Override + public int hashCode() { + int result = reason != null ? reason.hashCode() : 0; + result = 31 * result + (replacement != null ? replacement.hashCode() : 0); + return result; + } +} diff --git a/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/metadata/ItemMetadata.java b/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/metadata/ItemMetadata.java index e2f749c662..2435d69df2 100644 --- a/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/metadata/ItemMetadata.java +++ b/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/metadata/ItemMetadata.java @@ -40,11 +40,11 @@ public class ItemMetadata implements Comparable { private final Object defaultValue; - private final boolean deprecated; + private final ItemDeprecation deprecation; ItemMetadata(ItemType itemType, String prefix, String name, String type, String sourceType, String sourceMethod, String description, - Object defaultValue, boolean deprecated) { + Object defaultValue, ItemDeprecation deprecation) { super(); this.itemType = itemType; this.name = buildName(prefix, name); @@ -53,7 +53,7 @@ public class ItemMetadata implements Comparable { this.sourceMethod = sourceMethod; this.description = description; this.defaultValue = defaultValue; - this.deprecated = deprecated; + this.deprecation = deprecation; } private String buildName(String prefix, String name) { @@ -96,8 +96,8 @@ public class ItemMetadata implements Comparable { return this.defaultValue; } - public boolean isDeprecated() { - return this.deprecated; + public ItemDeprecation getDeprecation() { + return deprecation; } @Override @@ -107,7 +107,7 @@ public class ItemMetadata implements Comparable { buildToStringProperty(string, "sourceType", this.sourceType); buildToStringProperty(string, "description", this.description); buildToStringProperty(string, "defaultValue", this.defaultValue); - buildToStringProperty(string, "deprecated", this.deprecated); + buildToStringProperty(string, "deprecation", this.deprecation); return string.toString(); } @@ -126,14 +126,14 @@ public class ItemMetadata implements Comparable { public static ItemMetadata newGroup(String name, String type, String sourceType, String sourceMethod) { return new ItemMetadata(ItemType.GROUP, name, null, type, sourceType, - sourceMethod, null, null, false); + sourceMethod, null, null, null); } public static ItemMetadata newProperty(String prefix, String name, String type, String sourceType, String sourceMethod, String description, - Object defaultValue, boolean deprecated) { + Object defaultValue, ItemDeprecation deprecation) { return new ItemMetadata(ItemType.PROPERTY, prefix, name, type, sourceType, - sourceMethod, description, defaultValue, deprecated); + sourceMethod, description, defaultValue, deprecation); } /** diff --git a/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/metadata/JsonMarshaller.java b/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/metadata/JsonMarshaller.java index 6649f20093..bb271fee54 100644 --- a/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/metadata/JsonMarshaller.java +++ b/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/metadata/JsonMarshaller.java @@ -86,8 +86,17 @@ public class JsonMarshaller { if (defaultValue != null) { putDefaultValue(jsonObject, defaultValue); } - if (item.isDeprecated()) { - jsonObject.put("deprecated", true); + ItemDeprecation deprecation = item.getDeprecation(); + if (deprecation != null) { + jsonObject.put("deprecated", true); // backward compat + JSONObject deprecationJsonObject = new JSONObject(); + if (deprecation.getReason() != null) { + deprecationJsonObject.put("reason", deprecation.getReason()); + } + if (deprecation.getReplacement() != null) { + deprecationJsonObject.put("replacement", deprecation.getReplacement()); + } + jsonObject.put("deprecation", deprecationJsonObject); } return jsonObject; } @@ -202,9 +211,20 @@ public class JsonMarshaller { String sourceType = object.optString("sourceType", null); String sourceMethod = object.optString("sourceMethod", null); Object defaultValue = readItemValue(object.opt("defaultValue")); - boolean deprecated = object.optBoolean("deprecated"); + ItemDeprecation deprecation = toItemDeprecation(object); return new ItemMetadata(itemType, name, null, type, sourceType, sourceMethod, - description, defaultValue, deprecated); + description, defaultValue, deprecation); + } + + private ItemDeprecation toItemDeprecation(JSONObject object) { + if (object.has("deprecation")) { + JSONObject deprecationJsonObject = object.getJSONObject("deprecation"); + ItemDeprecation deprecation = new ItemDeprecation(); + deprecation.setReason(deprecationJsonObject.optString("reason", null)); + deprecation.setReplacement(deprecationJsonObject.optString("replacement", null)); + return deprecation; + } + return (object.optBoolean("deprecated") ? new ItemDeprecation() : null); } private ItemHint toItemHint(JSONObject object) { diff --git a/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/ConfigurationMetadataAnnotationProcessorTests.java b/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/ConfigurationMetadataAnnotationProcessorTests.java index dd793ce8c0..04a242c2e8 100644 --- a/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/ConfigurationMetadataAnnotationProcessorTests.java +++ b/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/ConfigurationMetadataAnnotationProcessorTests.java @@ -30,7 +30,9 @@ import org.junit.Test; import org.junit.rules.ExpectedException; import org.junit.rules.TemporaryFolder; import org.springframework.boot.configurationprocessor.metadata.ConfigurationMetadata; +import org.springframework.boot.configurationprocessor.metadata.ItemDeprecation; import org.springframework.boot.configurationprocessor.metadata.ItemHint; +import org.springframework.boot.configurationprocessor.metadata.ItemMetadata; import org.springframework.boot.configurationsample.incremental.BarProperties; import org.springframework.boot.configurationsample.incremental.FooProperties; import org.springframework.boot.configurationsample.incremental.RenamedBarProperties; @@ -106,12 +108,12 @@ public class ConfigurationMetadataAnnotationProcessorTests { containsProperty("simple.the-name", String.class) .fromSource(SimpleProperties.class) .withDescription("The name of this simple properties.") - .withDefaultValue(is("boot")).withDeprecated()); + .withDefaultValue(is("boot")).withDeprecation(null, null)); assertThat( metadata, containsProperty("simple.flag", Boolean.class) .fromSource(SimpleProperties.class) - .withDescription("A simple flag.").withDeprecated()); + .withDescription("A simple flag.").withDeprecation(null, null)); assertThat(metadata, containsProperty("simple.comparator")); assertThat(metadata, not(containsProperty("simple.counter"))); assertThat(metadata, not(containsProperty("simple.size"))); @@ -181,9 +183,9 @@ public class ConfigurationMetadataAnnotationProcessorTests { ConfigurationMetadata metadata = compile(type); assertThat(metadata, containsGroup("deprecated").fromSource(type)); assertThat(metadata, containsProperty("deprecated.name", String.class) - .fromSource(type).withDeprecated()); + .fromSource(type).withDeprecation(null, null)); assertThat(metadata, containsProperty("deprecated.description", String.class) - .fromSource(type).withDeprecated()); + .fromSource(type).withDeprecation(null, null)); } @Test @@ -371,7 +373,7 @@ public class ConfigurationMetadataAnnotationProcessorTests { containsProperty("simple.the-name", String.class) .fromSource(SimpleProperties.class) .withDescription("The name of this simple properties.") - .withDefaultValue(is("boot")).withDeprecated()); + .withDefaultValue(is("boot")).withDeprecation(null, null)); assertThat(metadata, containsHint("simple.the-name").withValue(0, "boot", "Bla bla") .withValue(1, "spring", null)); @@ -387,7 +389,7 @@ public class ConfigurationMetadataAnnotationProcessorTests { containsProperty("simple.the-name", String.class) .fromSource(SimpleProperties.class) .withDescription("The name of this simple properties.") - .withDefaultValue(is("boot")).withDeprecated()); + .withDefaultValue(is("boot")).withDeprecation(null, null)); assertThat(metadata, containsHint("simple.the-name").withValue(0, "boot", "Bla bla")); } @@ -405,13 +407,24 @@ public class ConfigurationMetadataAnnotationProcessorTests { containsProperty("simple.the-name", String.class) .fromSource(SimpleProperties.class) .withDescription("The name of this simple properties.") - .withDefaultValue(is("boot")).withDeprecated()); + .withDefaultValue(is("boot")).withDeprecation(null, null)); assertThat(metadata, containsHint("simple.the-name") .withProvider("first", "target", "org.foo") .withProvider("second")); } + @Test + public void mergingOfAdditionalDeprecation() throws Exception { + writePropertyDeprecation(ItemMetadata.newProperty("simple", "wrongName", "java.lang.String", + null, null, null, null, new ItemDeprecation("Lame name.", "simple.the-name"))); + ConfigurationMetadata metadata = compile(SimpleProperties.class); + assertThat( + metadata, + containsProperty("simple.wrong-name", String.class) + .withDeprecation("Lame name.", "simple.the-name")); + } + @Test public void incrementalBuild() throws Exception { TestProject project = new TestProject(this.temporaryFolder, FooProperties.class, @@ -496,7 +509,7 @@ public class ConfigurationMetadataAnnotationProcessorTests { assertThat(metadata, containsProperty(prefix + ".description")); assertThat(metadata, containsProperty(prefix + ".counter")); assertThat(metadata, containsProperty(prefix + ".number").fromSource(source) - .withDefaultValue(is(0)).withDeprecated()); + .withDefaultValue(is(0)).withDeprecation(null, null)); assertThat(metadata, containsProperty(prefix + ".items")); assertThat(metadata, not(containsProperty(prefix + ".ignored"))); } @@ -510,26 +523,38 @@ public class ConfigurationMetadataAnnotationProcessorTests { private void writeAdditionalHints(ItemHint... hints) throws IOException { File additionalMetadataFile = createAdditionalMetadataFile(); + JSONObject additionalMetadata = new JSONObject(); + additionalMetadata.put("hints", hints); + writeMetadata(additionalMetadataFile, additionalMetadata); + } + + private void writePropertyDeprecation(ItemMetadata... items) throws IOException { + File additionalMetadataFile = createAdditionalMetadataFile(); - JSONArray hintsArray = new JSONArray(); - for (ItemHint hint : hints) { + JSONArray propertiesArray = new JSONArray(); + for (ItemMetadata item : items) { JSONObject jsonObject = new JSONObject(); - jsonObject.put("name", hint.getName()); - JSONArray valuesArray = new JSONArray(); - for (ItemHint.ValueHint valueHint : hint.getValues()) { - JSONObject valueJsonObject = new JSONObject(); - valueJsonObject.put("value", valueHint.getValue()); - String description = valueHint.getDescription(); - if (description != null) { - valueJsonObject.put("description", description); + jsonObject.put("name", item.getName()); + if (item.getType() != null) { + jsonObject.put("type", item.getType()); + } + ItemDeprecation deprecation = item.getDeprecation(); + if (deprecation != null) { + JSONObject deprecationJson = new JSONObject(); + if (deprecation.getReason() != null) { + deprecationJson.put("reason", deprecation.getReason()); + } + if (deprecation.getReplacement() != null) { + deprecationJson.put("replacement", deprecation.getReplacement()); } - valuesArray.put(valueJsonObject); + jsonObject.put("deprecation", deprecationJson); } - jsonObject.put("values", valuesArray); - hintsArray.put(jsonObject); + propertiesArray.put(jsonObject); + } JSONObject additionalMetadata = new JSONObject(); - additionalMetadata.put("hints", hints); + additionalMetadata.put("properties", propertiesArray); + System.out.println(additionalMetadata); writeMetadata(additionalMetadataFile, additionalMetadata); } diff --git a/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/ConfigurationMetadataMatchers.java b/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/ConfigurationMetadataMatchers.java index 5d5c53e796..699af63267 100644 --- a/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/ConfigurationMetadataMatchers.java +++ b/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/ConfigurationMetadataMatchers.java @@ -26,6 +26,7 @@ import org.hamcrest.Description; import org.hamcrest.Matcher; import org.hamcrest.collection.IsMapContaining; import org.springframework.boot.configurationprocessor.metadata.ConfigurationMetadata; +import org.springframework.boot.configurationprocessor.metadata.ItemDeprecation; import org.springframework.boot.configurationprocessor.metadata.ItemHint; import org.springframework.boot.configurationprocessor.metadata.ItemMetadata; import org.springframework.boot.configurationprocessor.metadata.ItemMetadata.ItemType; @@ -80,22 +81,22 @@ public class ConfigurationMetadataMatchers { private final Matcher defaultValue; - private final boolean deprecated; + private final ItemDeprecation deprecation; public ContainsItemMatcher(ItemType itemType, String name) { - this(itemType, name, null, null, null, null, false); + this(itemType, name, null, null, null, null, null); } public ContainsItemMatcher(ItemType itemType, String name, String type, Class sourceType, String description, Matcher defaultValue, - boolean deprecated) { + ItemDeprecation deprecation) { this.itemType = itemType; this.name = name; this.type = type; this.sourceType = sourceType; this.description = description; this.defaultValue = defaultValue; - this.deprecated = deprecated; + this.deprecation = deprecation; } @Override @@ -120,7 +121,8 @@ public class ConfigurationMetadataMatchers { && !this.description.equals(itemMetadata.getDescription())) { return false; } - if (this.deprecated != itemMetadata.isDeprecated()) { + if (this.deprecation != null + && !this.deprecation.equals(itemMetadata.getDeprecation())) { return false; } return true; @@ -156,39 +158,39 @@ public class ConfigurationMetadataMatchers { if (this.description != null) { description.appendText(" description ").appendValue(this.description); } - if (this.deprecated) { - description.appendText(" deprecated ").appendValue(true); + if (this.deprecation != null) { + description.appendText(" deprecation ").appendValue(this.deprecation); } } public ContainsItemMatcher ofType(Class dataType) { return new ContainsItemMatcher(this.itemType, this.name, dataType.getName(), - this.sourceType, this.description, this.defaultValue, this.deprecated); + this.sourceType, this.description, this.defaultValue, this.deprecation); } public ContainsItemMatcher ofType(String dataType) { return new ContainsItemMatcher(this.itemType, this.name, dataType, - this.sourceType, this.description, this.defaultValue, this.deprecated); + this.sourceType, this.description, this.defaultValue, this.deprecation); } public ContainsItemMatcher fromSource(Class sourceType) { return new ContainsItemMatcher(this.itemType, this.name, this.type, - sourceType, this.description, this.defaultValue, this.deprecated); + sourceType, this.description, this.defaultValue, this.deprecation); } public ContainsItemMatcher withDescription(String description) { return new ContainsItemMatcher(this.itemType, this.name, this.type, - this.sourceType, description, this.defaultValue, this.deprecated); + this.sourceType, description, this.defaultValue, this.deprecation); } public ContainsItemMatcher withDefaultValue(Matcher defaultValue) { return new ContainsItemMatcher(this.itemType, this.name, this.type, - this.sourceType, this.description, defaultValue, this.deprecated); + this.sourceType, this.description, defaultValue, this.deprecation); } - public ContainsItemMatcher withDeprecated() { + public ContainsItemMatcher withDeprecation(String reason, String replacement) { return new ContainsItemMatcher(this.itemType, this.name, this.type, - this.sourceType, this.description, this.defaultValue, true); + this.sourceType, this.description, this.defaultValue, new ItemDeprecation(reason, replacement)); } private ItemMetadata getFirstItemWithName(ConfigurationMetadata metadata, diff --git a/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/metadata/JsonMarshallerTests.java b/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/metadata/JsonMarshallerTests.java index 7a9bc9ffbb..db4d93dc86 100644 --- a/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/metadata/JsonMarshallerTests.java +++ b/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/metadata/JsonMarshallerTests.java @@ -43,17 +43,18 @@ public class JsonMarshallerTests { public void marshallAndUnmarshal() throws IOException { ConfigurationMetadata metadata = new ConfigurationMetadata(); metadata.add(ItemMetadata.newProperty("a", "b", StringBuffer.class.getName(), - InputStream.class.getName(), "sourceMethod", "desc", "x", true)); + InputStream.class.getName(), "sourceMethod", "desc", "x", + new ItemDeprecation("Deprecation comment", "b.c.d"))); metadata.add(ItemMetadata.newProperty("b.c.d", null, null, null, null, null, - null, false)); + null, null)); metadata.add(ItemMetadata.newProperty("c", null, null, null, null, null, 123, - false)); + null)); metadata.add(ItemMetadata.newProperty("d", null, null, null, null, null, true, - false)); + null)); metadata.add(ItemMetadata.newProperty("e", null, null, null, null, null, - new String[] { "y", "n" }, false)); + new String[] { "y", "n" }, null)); metadata.add(ItemMetadata.newProperty("f", null, null, null, null, null, - new Boolean[] { true, false }, false)); + new Boolean[] { true, false }, null)); metadata.add(ItemMetadata.newGroup("d", null, null, null)); metadata.add(ItemHint.newHint("a.b")); metadata.add(ItemHint.newHint("c", new ItemHint.ValueHint(123, "hey"), @@ -69,7 +70,7 @@ public class JsonMarshallerTests { assertThat(read, containsProperty("a.b", StringBuffer.class).fromSource(InputStream.class) .withDescription("desc").withDefaultValue(is("x")) - .withDeprecated()); + .withDeprecation("Deprecation comment", "b.c.d")); assertThat(read, containsProperty("b.c.d")); assertThat(read, containsProperty("c").withDefaultValue(is(123))); assertThat(read, containsProperty("d").withDefaultValue(is(true)));