Fix multi-annotation nested condition logic

Update `AbstractNestedCondition` to correctly group nested conditions
on members.

Fixes gh-6672
This commit is contained in:
Phillip Webb 2016-09-16 13:07:44 -07:00
parent 3172d434a7
commit a2e4127d4f
2 changed files with 54 additions and 12 deletions

View File

@ -162,25 +162,65 @@ abstract class AbstractNestedCondition extends SpringBootCondition
for (Map.Entry<AnnotationMetadata, List<Condition>> entry : this.memberConditions for (Map.Entry<AnnotationMetadata, List<Condition>> entry : this.memberConditions
.entrySet()) { .entrySet()) {
AnnotationMetadata metadata = entry.getKey(); AnnotationMetadata metadata = entry.getKey();
for (Condition condition : entry.getValue()) { List<Condition> conditions = entry.getValue();
outcomes.add(getConditionOutcome(metadata, condition)); outcomes.add(new MemberOutcomes(this.context, metadata, conditions)
} .getUltimateOutcome());
} }
return Collections.unmodifiableList(outcomes); return Collections.unmodifiableList(outcomes);
} }
}
private static class MemberOutcomes {
private final ConditionContext context;
private final AnnotationMetadata metadata;
private final List<ConditionOutcome> outcomes;
MemberOutcomes(ConditionContext context, AnnotationMetadata metadata,
List<Condition> conditions) {
this.context = context;
this.metadata = metadata;
this.outcomes = new ArrayList<ConditionOutcome>(conditions.size());
for (Condition condition : conditions) {
this.outcomes.add(getConditionOutcome(metadata, condition));
}
}
private ConditionOutcome getConditionOutcome(AnnotationMetadata metadata, private ConditionOutcome getConditionOutcome(AnnotationMetadata metadata,
Condition condition) { Condition condition) {
String messagePrefix = "member condition on " + metadata.getClassName();
if (condition instanceof SpringBootCondition) { if (condition instanceof SpringBootCondition) {
ConditionOutcome outcome = ((SpringBootCondition) condition) return ((SpringBootCondition) condition).getMatchOutcome(this.context,
.getMatchOutcome(this.context, metadata); metadata);
String message = outcome.getMessage();
return new ConditionOutcome(outcome.isMatch(), messagePrefix
+ (StringUtils.hasLength(message) ? " : " + message : ""));
} }
boolean matches = condition.matches(this.context, metadata); return new ConditionOutcome(condition.matches(this.context, metadata), null);
return new ConditionOutcome(matches, messagePrefix); }
public ConditionOutcome getUltimateOutcome() {
if (this.outcomes.size() == 1) {
ConditionOutcome outcome = this.outcomes.get(0);
StringBuilder message = new StringBuilder(
"member condition on " + this.metadata.getClassName());
if (StringUtils.hasLength(outcome.getMessage())) {
message.append(" " + outcome.getMessage());
}
return new ConditionOutcome(outcome.isMatch(), message.toString());
}
StringBuilder message = new StringBuilder(
"member conditions on " + this.metadata.getClassName());
boolean match = true;
boolean hasMessage = false;
for (ConditionOutcome outcome : this.outcomes) {
match &= outcome.isMatch();
if (StringUtils.hasLength(outcome.getMessage())) {
message.append(hasMessage ? ", " : " : ");
message.append(outcome.getMessage());
hasMessage = true;
}
}
return new ConditionOutcome(match, message.toString());
} }
} }

View File

@ -31,12 +31,13 @@ import static org.junit.Assert.assertThat;
* Tests for {@link AnyNestedCondition}. * Tests for {@link AnyNestedCondition}.
* *
* @author Phillip Webb * @author Phillip Webb
* @author Dave Syer
*/ */
public class AnyNestedConditionTests { public class AnyNestedConditionTests {
@Test @Test
public void neither() throws Exception { public void neither() throws Exception {
AnnotationConfigApplicationContext context = load(OnPropertyAorBCondition.class); AnnotationConfigApplicationContext context = load(Config.class);
assertThat(context.containsBean("myBean"), equalTo(false)); assertThat(context.containsBean("myBean"), equalTo(false));
context.close(); context.close();
} }
@ -92,6 +93,7 @@ public class AnyNestedConditionTests {
} }
@ConditionalOnExpression("true")
@ConditionalOnProperty("b") @ConditionalOnProperty("b")
static class HasPropertyB { static class HasPropertyB {