1616
1717package org .springframework .boot .autoconfigure .condition ;
1818
19+ import java .lang .annotation .Annotation ;
1920import java .util .ArrayList ;
2021import java .util .List ;
21- import java .util .Map ;
2222import java .util .stream .Stream ;
2323
2424import org .springframework .boot .autoconfigure .condition .ConditionMessage .Style ;
3333import org .springframework .core .env .PropertyResolver ;
3434import org .springframework .core .type .AnnotatedTypeMetadata ;
3535import org .springframework .util .Assert ;
36+ import org .springframework .util .ClassUtils ;
3637import org .springframework .util .StringUtils ;
3738
3839/**
4344 * @author Stephane Nicoll
4445 * @author Andy Wilkinson
4546 * @see ConditionalOnProperty
47+ * @see ConditionalOnBooleanProperty
4648 */
4749@ Order (Ordered .HIGHEST_PRECEDENCE + 40 )
4850class OnPropertyCondition extends SpringBootCondition {
4951
5052 @ Override
5153 public ConditionOutcome getMatchOutcome (ConditionContext context , AnnotatedTypeMetadata metadata ) {
5254 MergedAnnotations annotations = metadata .getAnnotations ();
53- List <AnnotationAttributes > allAnnotationAttributes = Stream
55+ List <MergedAnnotation < Annotation >> allAnnotations = Stream
5456 .concat (annotations .stream (ConditionalOnProperty .class .getName ()),
5557 annotations .stream (ConditionalOnBooleanProperty .class .getName ()))
5658 .filter (MergedAnnotationPredicates .unique (MergedAnnotation ::getMetaTypes ))
57- .map (MergedAnnotation ::asAnnotationAttributes )
5859 .toList ();
5960 List <ConditionMessage > noMatch = new ArrayList <>();
6061 List <ConditionMessage > match = new ArrayList <>();
61- for (AnnotationAttributes annotationAttributes : allAnnotationAttributes ) {
62- ConditionOutcome outcome = determineOutcome (annotationAttributes , context .getEnvironment ());
62+ for (MergedAnnotation < Annotation > annotation : allAnnotations ) {
63+ ConditionOutcome outcome = determineOutcome (annotation , context .getEnvironment ());
6364 (outcome .isMatch () ? match : noMatch ).add (outcome .getConditionMessage ());
6465 }
6566 if (!noMatch .isEmpty ()) {
@@ -68,27 +69,29 @@ public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeM
6869 return ConditionOutcome .match (ConditionMessage .of (match ));
6970 }
7071
71- private ConditionOutcome determineOutcome (AnnotationAttributes annotationAttributes , PropertyResolver resolver ) {
72- Spec spec = new Spec (annotationAttributes );
72+ private ConditionOutcome determineOutcome (MergedAnnotation <Annotation > annotation , PropertyResolver resolver ) {
73+ Class <Annotation > annotationType = annotation .getType ();
74+ Spec spec = new Spec (annotationType , annotation .asAnnotationAttributes ());
7375 List <String > missingProperties = new ArrayList <>();
7476 List <String > nonMatchingProperties = new ArrayList <>();
7577 spec .collectProperties (resolver , missingProperties , nonMatchingProperties );
7678 if (!missingProperties .isEmpty ()) {
77- return ConditionOutcome .noMatch (ConditionMessage .forCondition (ConditionalOnProperty . class , spec )
79+ return ConditionOutcome .noMatch (ConditionMessage .forCondition (annotationType , spec )
7880 .didNotFind ("property" , "properties" )
7981 .items (Style .QUOTE , missingProperties ));
8082 }
8183 if (!nonMatchingProperties .isEmpty ()) {
82- return ConditionOutcome .noMatch (ConditionMessage .forCondition (ConditionalOnProperty . class , spec )
84+ return ConditionOutcome .noMatch (ConditionMessage .forCondition (annotationType , spec )
8385 .found ("different value in property" , "different value in properties" )
8486 .items (Style .QUOTE , nonMatchingProperties ));
8587 }
86- return ConditionOutcome
87- .match (ConditionMessage .forCondition (ConditionalOnProperty .class , spec ).because ("matched" ));
88+ return ConditionOutcome .match (ConditionMessage .forCondition (annotationType , spec ).because ("matched" ));
8889 }
8990
9091 private static class Spec {
9192
93+ private final Class <? extends Annotation > annotationType ;
94+
9295 private final String prefix ;
9396
9497 private final String [] names ;
@@ -97,7 +100,8 @@ private static class Spec {
97100
98101 private final boolean matchIfMissing ;
99102
100- Spec (AnnotationAttributes annotationAttributes ) {
103+ Spec (Class <? extends Annotation > annotationType , AnnotationAttributes annotationAttributes ) {
104+ this .annotationType = annotationType ;
101105 this .prefix = (!annotationAttributes .containsKey ("prefix" )) ? "" : getPrefix (annotationAttributes );
102106 this .names = getNames (annotationAttributes );
103107 this .havingValue = annotationAttributes .get ("havingValue" ).toString ();
@@ -112,13 +116,13 @@ private String getPrefix(AnnotationAttributes annotationAttributes) {
112116 return prefix ;
113117 }
114118
115- private String [] getNames (Map < String , Object > annotationAttributes ) {
119+ private String [] getNames (AnnotationAttributes annotationAttributes ) {
116120 String [] value = (String []) annotationAttributes .get ("value" );
117121 String [] name = (String []) annotationAttributes .get ("name" );
118- Assert .state (value .length > 0 || name .length > 0 ,
119- "The name or value attribute of @ConditionalOnProperty must be specified" );
120- Assert .state (value .length == 0 || name .length == 0 ,
121- "The name and value attributes of @ConditionalOnProperty are exclusive" );
122+ Assert .state (value .length > 0 || name .length > 0 , "The name or value attribute of @%s must be specified"
123+ . formatted ( ClassUtils . getShortName ( this . annotationType )) );
124+ Assert .state (value .length == 0 || name .length == 0 , "The name and value attributes of @%s are exclusive"
125+ . formatted ( ClassUtils . getShortName ( this . annotationType )) );
122126 return (value .length > 0 ) ? value : name ;
123127 }
124128
0 commit comments