Add support for property deprecation
Previously, an item could only have a 'deprecated' boolean flag to indicate that the property is deprecated. It is desirable to provide an additional description for the deprecation as well as the name of the property to use instead. The `deprecated` boolean flag is now supported. Instead, a `deprecated` object can be specified with two optional attributes: `reason` to provide an explanation for the deprecation and `replacement` to refer to the property that should be used instead. If none of them is present, an empty deprecation object should be set. For backward compatibility, the `deprecated` field is still set. Deprecation information can only set via manual meta-data. Closes gh-3449
This commit is contained in:
@@ -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,29 +523,41 @@ public class ConfigurationMetadataAnnotationProcessorTests {
|
||||
|
||||
private void writeAdditionalHints(ItemHint... hints) throws IOException {
|
||||
File additionalMetadataFile = createAdditionalMetadataFile();
|
||||
|
||||
JSONArray hintsArray = new JSONArray();
|
||||
for (ItemHint hint : hints) {
|
||||
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);
|
||||
}
|
||||
valuesArray.put(valueJsonObject);
|
||||
}
|
||||
jsonObject.put("values", valuesArray);
|
||||
hintsArray.put(jsonObject);
|
||||
}
|
||||
JSONObject additionalMetadata = new JSONObject();
|
||||
additionalMetadata.put("hints", hints);
|
||||
writeMetadata(additionalMetadataFile, additionalMetadata);
|
||||
}
|
||||
|
||||
private void writePropertyDeprecation(ItemMetadata... items) throws IOException {
|
||||
File additionalMetadataFile = createAdditionalMetadataFile();
|
||||
|
||||
JSONArray propertiesArray = new JSONArray();
|
||||
for (ItemMetadata item : items) {
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
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());
|
||||
}
|
||||
jsonObject.put("deprecation", deprecationJson);
|
||||
}
|
||||
propertiesArray.put(jsonObject);
|
||||
|
||||
}
|
||||
JSONObject additionalMetadata = new JSONObject();
|
||||
additionalMetadata.put("properties", propertiesArray);
|
||||
System.out.println(additionalMetadata);
|
||||
writeMetadata(additionalMetadataFile, additionalMetadata);
|
||||
}
|
||||
|
||||
private File createAdditionalMetadataFile() throws IOException {
|
||||
File metaInfFolder = new File(this.compiler.getOutputLocation(), "META-INF");
|
||||
metaInfFolder.mkdirs();
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)));
|
||||
|
||||
Reference in New Issue
Block a user