16
16
17
17
package org .springframework .boot .autoconfigure .condition ;
18
18
19
+ import java .lang .annotation .Annotation ;
19
20
import java .util .ArrayList ;
20
21
import java .util .List ;
21
- import java .util .Map ;
22
22
import java .util .stream .Stream ;
23
23
24
24
import org .springframework .boot .autoconfigure .condition .ConditionMessage .Style ;
28
28
import org .springframework .core .annotation .AnnotationAttributes ;
29
29
import org .springframework .core .annotation .MergedAnnotation ;
30
30
import org .springframework .core .annotation .MergedAnnotationPredicates ;
31
- import org .springframework .core .annotation .MergedAnnotations ;
32
31
import org .springframework .core .annotation .Order ;
33
32
import org .springframework .core .env .PropertyResolver ;
34
33
import org .springframework .core .type .AnnotatedTypeMetadata ;
35
34
import org .springframework .util .Assert ;
35
+ import org .springframework .util .ClassUtils ;
36
36
import org .springframework .util .StringUtils ;
37
37
38
38
/**
43
43
* @author Stephane Nicoll
44
44
* @author Andy Wilkinson
45
45
* @see ConditionalOnProperty
46
+ * @see ConditionalOnBooleanProperty
46
47
*/
47
48
@ Order (Ordered .HIGHEST_PRECEDENCE + 40 )
48
49
class OnPropertyCondition extends SpringBootCondition {
49
50
50
51
@ Override
51
52
public ConditionOutcome getMatchOutcome (ConditionContext context , AnnotatedTypeMetadata metadata ) {
52
- MergedAnnotations annotations = metadata .getAnnotations ();
53
- List <AnnotationAttributes > allAnnotationAttributes = Stream
54
- .concat (annotations .stream (ConditionalOnProperty .class .getName ()),
55
- annotations .stream (ConditionalOnBooleanProperty .class .getName ()))
53
+ List <MergedAnnotation <Annotation >> annotations = Stream
54
+ .concat (metadata .getAnnotations ().stream (ConditionalOnProperty .class .getName ()),
55
+ metadata .getAnnotations ().stream (ConditionalOnBooleanProperty .class .getName ()))
56
56
.filter (MergedAnnotationPredicates .unique (MergedAnnotation ::getMetaTypes ))
57
- .map (MergedAnnotation ::asAnnotationAttributes )
58
57
.toList ();
59
58
List <ConditionMessage > noMatch = new ArrayList <>();
60
59
List <ConditionMessage > match = new ArrayList <>();
61
- for (AnnotationAttributes annotationAttributes : allAnnotationAttributes ) {
62
- ConditionOutcome outcome = determineOutcome (annotationAttributes , context .getEnvironment ());
60
+ for (MergedAnnotation < Annotation > annotation : annotations ) {
61
+ ConditionOutcome outcome = determineOutcome (annotation , context .getEnvironment ());
63
62
(outcome .isMatch () ? match : noMatch ).add (outcome .getConditionMessage ());
64
63
}
65
64
if (!noMatch .isEmpty ()) {
@@ -68,27 +67,29 @@ public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeM
68
67
return ConditionOutcome .match (ConditionMessage .of (match ));
69
68
}
70
69
71
- private ConditionOutcome determineOutcome (AnnotationAttributes annotationAttributes , PropertyResolver resolver ) {
72
- Spec spec = new Spec (annotationAttributes );
70
+ private ConditionOutcome determineOutcome (MergedAnnotation <Annotation > annotation , PropertyResolver resolver ) {
71
+ Class <Annotation > annotationType = annotation .getType ();
72
+ Spec spec = new Spec (annotationType , annotation .asAnnotationAttributes ());
73
73
List <String > missingProperties = new ArrayList <>();
74
74
List <String > nonMatchingProperties = new ArrayList <>();
75
75
spec .collectProperties (resolver , missingProperties , nonMatchingProperties );
76
76
if (!missingProperties .isEmpty ()) {
77
- return ConditionOutcome .noMatch (ConditionMessage .forCondition (ConditionalOnProperty . class , spec )
77
+ return ConditionOutcome .noMatch (ConditionMessage .forCondition (annotationType , spec )
78
78
.didNotFind ("property" , "properties" )
79
79
.items (Style .QUOTE , missingProperties ));
80
80
}
81
81
if (!nonMatchingProperties .isEmpty ()) {
82
- return ConditionOutcome .noMatch (ConditionMessage .forCondition (ConditionalOnProperty . class , spec )
82
+ return ConditionOutcome .noMatch (ConditionMessage .forCondition (annotationType , spec )
83
83
.found ("different value in property" , "different value in properties" )
84
84
.items (Style .QUOTE , nonMatchingProperties ));
85
85
}
86
- return ConditionOutcome
87
- .match (ConditionMessage .forCondition (ConditionalOnProperty .class , spec ).because ("matched" ));
86
+ return ConditionOutcome .match (ConditionMessage .forCondition (annotationType , spec ).because ("matched" ));
88
87
}
89
88
90
89
private static class Spec {
91
90
91
+ private final Class <? extends Annotation > annotationType ;
92
+
92
93
private final String prefix ;
93
94
94
95
private final String [] names ;
@@ -97,7 +98,8 @@ private static class Spec {
97
98
98
99
private final boolean matchIfMissing ;
99
100
100
- Spec (AnnotationAttributes annotationAttributes ) {
101
+ Spec (Class <? extends Annotation > annotationType , AnnotationAttributes annotationAttributes ) {
102
+ this .annotationType = annotationType ;
101
103
this .prefix = (!annotationAttributes .containsKey ("prefix" )) ? "" : getPrefix (annotationAttributes );
102
104
this .names = getNames (annotationAttributes );
103
105
this .havingValue = annotationAttributes .get ("havingValue" ).toString ();
@@ -112,13 +114,13 @@ private String getPrefix(AnnotationAttributes annotationAttributes) {
112
114
return prefix ;
113
115
}
114
116
115
- private String [] getNames (Map < String , Object > annotationAttributes ) {
117
+ private String [] getNames (AnnotationAttributes annotationAttributes ) {
116
118
String [] value = (String []) annotationAttributes .get ("value" );
117
119
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" );
120
+ Assert .state (value .length > 0 || name .length > 0 , "The name or value attribute of @%s must be specified"
121
+ . formatted ( ClassUtils . getShortName ( this . annotationType )) );
122
+ Assert .state (value .length == 0 || name .length == 0 , "The name and value attributes of @%s are exclusive"
123
+ . formatted ( ClassUtils . getShortName ( this . annotationType )) );
122
124
return (value .length > 0 ) ? value : name ;
123
125
}
124
126
0 commit comments