Skip to content

Commit a2e4127

Browse files
committed
Fix multi-annotation nested condition logic
Update `AbstractNestedCondition` to correctly group nested conditions on members. Fixes gh-6672
1 parent 3172d43 commit a2e4127

File tree

2 files changed

+54
-12
lines changed

2 files changed

+54
-12
lines changed

spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/AbstractNestedCondition.java

Lines changed: 51 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -162,25 +162,65 @@ public List<ConditionOutcome> getMatchOutcomes() {
162162
for (Map.Entry<AnnotationMetadata, List<Condition>> entry : this.memberConditions
163163
.entrySet()) {
164164
AnnotationMetadata metadata = entry.getKey();
165-
for (Condition condition : entry.getValue()) {
166-
outcomes.add(getConditionOutcome(metadata, condition));
167-
}
165+
List<Condition> conditions = entry.getValue();
166+
outcomes.add(new MemberOutcomes(this.context, metadata, conditions)
167+
.getUltimateOutcome());
168168
}
169169
return Collections.unmodifiableList(outcomes);
170170
}
171171

172+
}
173+
174+
private static class MemberOutcomes {
175+
176+
private final ConditionContext context;
177+
178+
private final AnnotationMetadata metadata;
179+
180+
private final List<ConditionOutcome> outcomes;
181+
182+
MemberOutcomes(ConditionContext context, AnnotationMetadata metadata,
183+
List<Condition> conditions) {
184+
this.context = context;
185+
this.metadata = metadata;
186+
this.outcomes = new ArrayList<ConditionOutcome>(conditions.size());
187+
for (Condition condition : conditions) {
188+
this.outcomes.add(getConditionOutcome(metadata, condition));
189+
}
190+
}
191+
172192
private ConditionOutcome getConditionOutcome(AnnotationMetadata metadata,
173193
Condition condition) {
174-
String messagePrefix = "member condition on " + metadata.getClassName();
175194
if (condition instanceof SpringBootCondition) {
176-
ConditionOutcome outcome = ((SpringBootCondition) condition)
177-
.getMatchOutcome(this.context, metadata);
178-
String message = outcome.getMessage();
179-
return new ConditionOutcome(outcome.isMatch(), messagePrefix
180-
+ (StringUtils.hasLength(message) ? " : " + message : ""));
195+
return ((SpringBootCondition) condition).getMatchOutcome(this.context,
196+
metadata);
197+
}
198+
return new ConditionOutcome(condition.matches(this.context, metadata), null);
199+
}
200+
201+
public ConditionOutcome getUltimateOutcome() {
202+
if (this.outcomes.size() == 1) {
203+
ConditionOutcome outcome = this.outcomes.get(0);
204+
StringBuilder message = new StringBuilder(
205+
"member condition on " + this.metadata.getClassName());
206+
if (StringUtils.hasLength(outcome.getMessage())) {
207+
message.append(" " + outcome.getMessage());
208+
}
209+
return new ConditionOutcome(outcome.isMatch(), message.toString());
210+
}
211+
StringBuilder message = new StringBuilder(
212+
"member conditions on " + this.metadata.getClassName());
213+
boolean match = true;
214+
boolean hasMessage = false;
215+
for (ConditionOutcome outcome : this.outcomes) {
216+
match &= outcome.isMatch();
217+
if (StringUtils.hasLength(outcome.getMessage())) {
218+
message.append(hasMessage ? ", " : " : ");
219+
message.append(outcome.getMessage());
220+
hasMessage = true;
221+
}
181222
}
182-
boolean matches = condition.matches(this.context, metadata);
183-
return new ConditionOutcome(matches, messagePrefix);
223+
return new ConditionOutcome(match, message.toString());
184224
}
185225

186226
}

spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/condition/AnyNestedConditionTests.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,13 @@
3131
* Tests for {@link AnyNestedCondition}.
3232
*
3333
* @author Phillip Webb
34+
* @author Dave Syer
3435
*/
3536
public class AnyNestedConditionTests {
3637

3738
@Test
3839
public void neither() throws Exception {
39-
AnnotationConfigApplicationContext context = load(OnPropertyAorBCondition.class);
40+
AnnotationConfigApplicationContext context = load(Config.class);
4041
assertThat(context.containsBean("myBean"), equalTo(false));
4142
context.close();
4243
}
@@ -92,6 +93,7 @@ static class HasPropertyA {
9293

9394
}
9495

96+
@ConditionalOnExpression("true")
9597
@ConditionalOnProperty("b")
9698
static class HasPropertyB {
9799

0 commit comments

Comments
 (0)