diff --git a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/MetadataCollector.java b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/MetadataCollector.java index ea06d3091b..c6fe7f81d7 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/MetadataCollector.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/MetadataCollector.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2020 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. @@ -98,7 +98,7 @@ public class MetadataCollector { List items = this.previousMetadata.getItems(); for (ItemMetadata item : items) { if (shouldBeMerged(item)) { - metadata.add(item); + metadata.addIfMissing(item); } } } 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 bc5f4fd5c5..4fb7481459 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 @@ -62,7 +62,15 @@ public class ConfigurationMetadata { * @param itemMetadata the meta-data to add */ public void add(ItemMetadata itemMetadata) { - add(this.items, itemMetadata.getName(), itemMetadata); + add(this.items, itemMetadata.getName(), itemMetadata, false); + } + + /** + * Add item meta-data if it's not already present. + * @param itemMetadata the meta-data to add + */ + public void addIfMissing(ItemMetadata itemMetadata) { + add(this.items, itemMetadata.getName(), itemMetadata, true); } /** @@ -70,7 +78,7 @@ public class ConfigurationMetadata { * @param itemHint the item hint to add */ public void add(ItemHint itemHint) { - add(this.hints, itemHint.getName(), itemHint); + add(this.hints, itemHint.getName(), itemHint, false); } /** @@ -131,13 +139,15 @@ public class ConfigurationMetadata { } } else { - add(this.items, metadata.getName(), metadata); + add(this.items, metadata.getName(), metadata, false); } } - private void add(Map> map, K key, V value) { + private void add(Map> map, K key, V value, boolean ifMissing) { List values = map.computeIfAbsent(key, (k) -> new ArrayList<>()); - values.add(value); + if (!ifMissing || values.isEmpty()) { + values.add(value); + } } private ItemMetadata findMatchingItemMetadata(ItemMetadata metadata) { 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 69e3d914cf..2657ec7afb 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 @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2020 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. @@ -25,6 +25,7 @@ import org.assertj.core.api.Condition; import org.hamcrest.collection.IsMapContaining; import org.springframework.boot.configurationprocessor.metadata.ItemMetadata.ItemType; +import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; /** @@ -131,7 +132,7 @@ public final class Metadata { @Override public boolean matches(ConfigurationMetadata value) { - ItemMetadata itemMetadata = getFirstItemWithName(value, this.name); + ItemMetadata itemMetadata = getItemWithName(value, this.name); if (itemMetadata == null) { return false; } @@ -207,13 +208,15 @@ public final class Metadata { this.description, this.defaultValue, null); } - private ItemMetadata getFirstItemWithName(ConfigurationMetadata metadata, String name) { + private ItemMetadata getItemWithName(ConfigurationMetadata metadata, String name) { + ItemMetadata result = null; for (ItemMetadata item : metadata.getItems()) { if (item.isOfItemType(this.itemType) && name.equals(item.getName())) { - return item; + Assert.state(result == null, () -> "Duplicate item found for " + name); + result = item; } } - return null; + return result; } }