@ -19,9 +19,15 @@ package org.springframework.boot.configurationprocessor.metadata;
import java.util.ArrayList ;
import java.util.Collections ;
import java.util.List ;
import java.util.ListIterator ;
import java.util.regex.Matcher ;
import java.util.regex.Pattern ;
import org.springframework.util.CollectionUtils ;
import org.springframework.util.LinkedMultiValueMap ;
import org.springframework.util.MultiValueMap ;
import org.springframework.util.ObjectUtils ;
/ * *
* Configuration meta - data .
*
@ -34,18 +40,18 @@ public class ConfigurationMetadata {
private static final Pattern CAMEL_CASE_PATTERN = Pattern . compile ( "([^A-Z-])([A-Z])" ) ;
private final List< ItemMetadata > items ;
private final MultiValueMap< String , ItemMetadata > items ;
private final List< ItemHint > hints ;
private final MultiValueMap< String , ItemHint > hints ;
public ConfigurationMetadata ( ) {
this . items = new ArrayList< ItemMetadata > ( ) ;
this . hints = new ArrayList< ItemHint > ( ) ;
this . items = new LinkedMultiValueMap< String , ItemMetadata > ( ) ;
this . hints = new LinkedMultiValueMap< String , ItemHint > ( ) ;
}
public ConfigurationMetadata ( ConfigurationMetadata metadata ) {
this . items = new ArrayList< ItemMetadata > ( metadata . getItems ( ) ) ;
this . hints = new ArrayList< ItemHint > ( metadata . getHints ( ) ) ;
this . items = new LinkedMultiValueMap< String , ItemMetadata > ( metadata . items ) ;
this . hints = new LinkedMultiValueMap< String , ItemHint > ( metadata . hints ) ;
}
/ * *
@ -53,39 +59,96 @@ public class ConfigurationMetadata {
* @param itemMetadata the meta - data to add
* /
public void add ( ItemMetadata itemMetadata ) {
this . items . add ( itemMetadata ) ;
Collections . sort ( this . items ) ;
this . items . add ( itemMetadata . getName ( ) , itemMetadata ) ;
}
/ * *
* Add item hint .
* @param itemHint the item hint to add
* /
public void add ( ItemHint itemHint ) {
this . hints . add ( itemHint ) ;
Collections . sort ( this . hints ) ;
this . hints . add ( itemHint . getName ( ) , itemHint ) ;
}
/ * *
* Add all properties from another { @link ConfigurationMetadata } .
* Merge the content from another { @link ConfigurationMetadata } .
* @param metadata the { @link ConfigurationMetadata } instance to merge
* /
public void addAll ( ConfigurationMetadata metadata ) {
this . items . addAll ( metadata . getItems ( ) ) ;
Collections . sort ( this . items ) ;
this . hints . addAll ( metadata . getHints ( ) ) ;
Collections . sort ( this . hints ) ;
public void merge ( ConfigurationMetadata metadata ) {
for ( ItemMetadata additionalItem : metadata . getItems ( ) ) {
mergeItemMetadata ( additionalItem ) ;
}
for ( ItemHint itemHint : metadata . getHints ( ) ) {
add ( itemHint ) ;
}
}
/ * *
* @return the meta - data properties .
* /
public List < ItemMetadata > getItems ( ) {
return Collections. unmodifiableList ( this . items ) ;
return flattenValues ( this . items ) ;
}
/ * *
* @return the meta - data hints .
* /
public List < ItemHint > getHints ( ) {
return Collections . unmodifiableList ( this . hints ) ;
return flattenValues ( this . hints ) ;
}
protected void mergeItemMetadata ( ItemMetadata metadata ) {
ItemMetadata matching = findMatchingItemMetadata ( metadata ) ;
if ( matching ! = null ) {
if ( metadata . getDescription ( ) ! = null ) {
matching . setDescription ( metadata . getDescription ( ) ) ;
}
if ( metadata . getDefaultValue ( ) ! = null ) {
matching . setDefaultValue ( metadata . getDefaultValue ( ) ) ;
}
ItemDeprecation deprecation = metadata . getDeprecation ( ) ;
ItemDeprecation matchingDeprecation = matching . getDeprecation ( ) ;
if ( deprecation ! = null ) {
if ( matchingDeprecation = = null ) {
matching . setDeprecation ( deprecation ) ;
}
else {
if ( deprecation . getReason ( ) ! = null ) {
matchingDeprecation . setReason ( deprecation . getReason ( ) ) ;
}
if ( deprecation . getReplacement ( ) ! = null ) {
matchingDeprecation . setReplacement ( deprecation . getReplacement ( ) ) ;
}
}
}
}
else {
this . items . add ( metadata . getName ( ) , metadata ) ;
}
}
private ItemMetadata findMatchingItemMetadata ( ItemMetadata metadata ) {
List < ItemMetadata > candidates = this . items . get ( metadata . getName ( ) ) ;
if ( CollectionUtils . isEmpty ( candidates ) ) {
return null ;
}
ListIterator < ItemMetadata > it = candidates . listIterator ( ) ;
while ( it . hasNext ( ) ) {
if ( ! it . next ( ) . hasSameType ( metadata ) ) {
it . remove ( ) ;
}
}
if ( candidates . size ( ) = = 1 ) {
return candidates . get ( 0 ) ;
}
for ( ItemMetadata candidate : candidates ) {
if ( ObjectUtils . nullSafeEquals ( candidate . getSourceType ( ) , metadata . getSourceType ( ) ) ) {
return candidate ;
}
}
return null ;
}
public static String nestedPrefix ( String prefix , String name ) {
String nestedPrefix = ( prefix = = null ? "" : prefix ) ;
@ -114,4 +177,13 @@ public class ConfigurationMetadata {
return first + "-" + second ;
}
private static < T extends Comparable > List < T > flattenValues ( MultiValueMap < ? , T > map ) {
List < T > content = new ArrayList < T > ( ) ;
for ( List < T > values : map . values ( ) ) {
content . addAll ( values ) ;
}
Collections . sort ( content ) ;
return content ;
}
}