Use deterministic order for configuration properties metadata
This commit updates the annotation processor to write metadata in a consistent way. Groups, properties and hints are written and each item is ordered alphabetically based on its name. Also, deprecated items are written last. Closes gh-14347
This commit is contained in:
@@ -1,48 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2018 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;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.boot.configurationprocessor.json.JSONException;
|
||||
import org.springframework.boot.configurationprocessor.json.JSONObject;
|
||||
|
||||
/**
|
||||
* Extension to {@link JSONObject} that remembers the order of inserts.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
class JSONOrderedObject extends JSONObject {
|
||||
|
||||
private Set<String> keys = new LinkedHashSet<>();
|
||||
|
||||
@Override
|
||||
public JSONObject put(String key, Object value) throws JSONException {
|
||||
this.keys.add(key);
|
||||
return super.put(key, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator keys() {
|
||||
return this.keys.iterator();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -18,7 +18,10 @@ package org.springframework.boot.configurationprocessor.metadata;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.Collection;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.springframework.boot.configurationprocessor.json.JSONArray;
|
||||
import org.springframework.boot.configurationprocessor.json.JSONObject;
|
||||
@@ -32,10 +35,15 @@ import org.springframework.boot.configurationprocessor.metadata.ItemMetadata.Ite
|
||||
*/
|
||||
class JsonConverter {
|
||||
|
||||
private static final ItemMetadataComparator ITEM_COMPARATOR = new ItemMetadataComparator();
|
||||
|
||||
public JSONArray toJsonArray(ConfigurationMetadata metadata, ItemType itemType)
|
||||
throws Exception {
|
||||
JSONArray jsonArray = new JSONArray();
|
||||
for (ItemMetadata item : metadata.getItems()) {
|
||||
List<ItemMetadata> items = metadata.getItems().stream()
|
||||
.filter((item) -> item.isOfItemType(itemType)).sorted(ITEM_COMPARATOR)
|
||||
.collect(Collectors.toList());
|
||||
for (ItemMetadata item : items) {
|
||||
if (item.isOfItemType(itemType)) {
|
||||
jsonArray.put(toJsonObject(item));
|
||||
}
|
||||
@@ -52,7 +60,7 @@ class JsonConverter {
|
||||
}
|
||||
|
||||
public JSONObject toJsonObject(ItemMetadata item) throws Exception {
|
||||
JSONObject jsonObject = new JSONOrderedObject();
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("name", item.getName());
|
||||
putIfPresent(jsonObject, "type", item.getType());
|
||||
putIfPresent(jsonObject, "description", item.getDescription());
|
||||
@@ -81,7 +89,7 @@ class JsonConverter {
|
||||
}
|
||||
|
||||
private JSONObject toJsonObject(ItemHint hint) throws Exception {
|
||||
JSONObject jsonObject = new JSONOrderedObject();
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("name", hint.getName());
|
||||
if (!hint.getValues().isEmpty()) {
|
||||
jsonObject.put("values", getItemHintValues(hint));
|
||||
@@ -101,7 +109,7 @@ class JsonConverter {
|
||||
}
|
||||
|
||||
private JSONObject getItemHintValue(ItemHint.ValueHint value) throws Exception {
|
||||
JSONObject result = new JSONOrderedObject();
|
||||
JSONObject result = new JSONObject();
|
||||
putHintValue(result, value.getValue());
|
||||
putIfPresent(result, "description", value.getDescription());
|
||||
return result;
|
||||
@@ -117,10 +125,10 @@ class JsonConverter {
|
||||
|
||||
private JSONObject getItemHintProvider(ItemHint.ValueProvider provider)
|
||||
throws Exception {
|
||||
JSONObject result = new JSONOrderedObject();
|
||||
JSONObject result = new JSONObject();
|
||||
result.put("name", provider.getName());
|
||||
if (provider.getParameters() != null && !provider.getParameters().isEmpty()) {
|
||||
JSONObject parameters = new JSONOrderedObject();
|
||||
JSONObject parameters = new JSONObject();
|
||||
for (Map.Entry<String, Object> entry : provider.getParameters().entrySet()) {
|
||||
parameters.put(entry.getKey(), extractItemValue(entry.getValue()));
|
||||
}
|
||||
@@ -160,4 +168,34 @@ class JsonConverter {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
private static class ItemMetadataComparator implements Comparator<ItemMetadata> {
|
||||
|
||||
@Override
|
||||
public int compare(ItemMetadata o1, ItemMetadata o2) {
|
||||
if (o1.isOfItemType(ItemType.GROUP)) {
|
||||
return compareGroup(o1, o2);
|
||||
}
|
||||
return compareProperty(o1, o2);
|
||||
}
|
||||
|
||||
private int compareGroup(ItemMetadata o1, ItemMetadata o2) {
|
||||
return o1.getName().compareTo(o2.getName());
|
||||
}
|
||||
|
||||
private int compareProperty(ItemMetadata o1, ItemMetadata o2) {
|
||||
if (isDeprecated(o1) && !isDeprecated(o2)) {
|
||||
return 1;
|
||||
}
|
||||
if (isDeprecated(o2) && !isDeprecated(o1)) {
|
||||
return -1;
|
||||
}
|
||||
return o1.getName().compareTo(o2.getName());
|
||||
}
|
||||
|
||||
private boolean isDeprecated(ItemMetadata item) {
|
||||
return item.getDeprecation() != null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ public class JsonMarshaller {
|
||||
public void write(ConfigurationMetadata metadata, OutputStream outputStream)
|
||||
throws IOException {
|
||||
try {
|
||||
JSONObject object = new JSONOrderedObject();
|
||||
JSONObject object = new JSONObject();
|
||||
JsonConverter converter = new JsonConverter();
|
||||
object.put("groups", converter.toJsonArray(metadata, ItemType.GROUP));
|
||||
object.put("properties", converter.toJsonArray(metadata, ItemType.PROPERTY));
|
||||
|
||||
Reference in New Issue
Block a user