Merge branch '1.3.x'
This commit is contained in:
commit
c76621b34d
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2012-2014 the original author or authors.
|
* Copyright 2012-2016 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -17,8 +17,10 @@
|
||||||
package org.springframework.boot.autoconfigure.condition;
|
package org.springframework.boot.autoconfigure.condition;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
import org.springframework.boot.bind.RelaxedPropertyResolver;
|
import org.springframework.boot.bind.RelaxedPropertyResolver;
|
||||||
import org.springframework.context.annotation.Condition;
|
import org.springframework.context.annotation.Condition;
|
||||||
|
@ -27,6 +29,7 @@ import org.springframework.core.annotation.AnnotationAttributes;
|
||||||
import org.springframework.core.env.PropertyResolver;
|
import org.springframework.core.env.PropertyResolver;
|
||||||
import org.springframework.core.type.AnnotatedTypeMetadata;
|
import org.springframework.core.type.AnnotatedTypeMetadata;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
import org.springframework.util.MultiValueMap;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -35,6 +38,7 @@ import org.springframework.util.StringUtils;
|
||||||
* @author Maciej Walkowiak
|
* @author Maciej Walkowiak
|
||||||
* @author Phillip Webb
|
* @author Phillip Webb
|
||||||
* @author Stephane Nicoll
|
* @author Stephane Nicoll
|
||||||
|
* @author Andy Wilkinson
|
||||||
* @since 1.1.0
|
* @since 1.1.0
|
||||||
* @see ConditionalOnProperty
|
* @see ConditionalOnProperty
|
||||||
*/
|
*/
|
||||||
|
@ -43,10 +47,57 @@ class OnPropertyCondition extends SpringBootCondition {
|
||||||
@Override
|
@Override
|
||||||
public ConditionOutcome getMatchOutcome(ConditionContext context,
|
public ConditionOutcome getMatchOutcome(ConditionContext context,
|
||||||
AnnotatedTypeMetadata metadata) {
|
AnnotatedTypeMetadata metadata) {
|
||||||
|
List<AnnotationAttributes> allAnnotationAttributes = annotationAttributesFromMultiValueMap(
|
||||||
|
metadata.getAllAnnotationAttributes(
|
||||||
|
ConditionalOnProperty.class.getName()));
|
||||||
|
List<ConditionOutcome> noMatchOutcomes = findNoMatchOutcomes(
|
||||||
|
allAnnotationAttributes, context.getEnvironment());
|
||||||
|
if (noMatchOutcomes.isEmpty()) {
|
||||||
|
return ConditionOutcome.match();
|
||||||
|
}
|
||||||
|
return ConditionOutcome.noMatch(getCompositeMessage(noMatchOutcomes));
|
||||||
|
}
|
||||||
|
|
||||||
AnnotationAttributes annotationAttributes = AnnotationAttributes.fromMap(
|
private List<AnnotationAttributes> annotationAttributesFromMultiValueMap(
|
||||||
metadata.getAnnotationAttributes(ConditionalOnProperty.class.getName()));
|
MultiValueMap<String, Object> multiValueMap) {
|
||||||
|
List<Map<String, Object>> maps = new ArrayList<Map<String, Object>>();
|
||||||
|
for (Entry<String, List<Object>> entry : multiValueMap.entrySet()) {
|
||||||
|
for (int i = 0; i < entry.getValue().size(); i++) {
|
||||||
|
Map<String, Object> map;
|
||||||
|
if (i < maps.size()) {
|
||||||
|
map = maps.get(i);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
map = new HashMap<String, Object>();
|
||||||
|
maps.add(map);
|
||||||
|
}
|
||||||
|
map.put(entry.getKey(), entry.getValue().get(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
List<AnnotationAttributes> annotationAttributes = new ArrayList<AnnotationAttributes>(
|
||||||
|
maps.size());
|
||||||
|
for (Map<String, Object> map : maps) {
|
||||||
|
annotationAttributes.add(AnnotationAttributes.fromMap(map));
|
||||||
|
}
|
||||||
|
return annotationAttributes;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<ConditionOutcome> findNoMatchOutcomes(
|
||||||
|
List<AnnotationAttributes> allAnnotationAttributes,
|
||||||
|
PropertyResolver resolver) {
|
||||||
|
List<ConditionOutcome> noMatchOutcomes = new ArrayList<ConditionOutcome>(
|
||||||
|
allAnnotationAttributes.size());
|
||||||
|
for (AnnotationAttributes annotationAttributes : allAnnotationAttributes) {
|
||||||
|
ConditionOutcome outcome = determineOutcome(annotationAttributes, resolver);
|
||||||
|
if (!outcome.isMatch()) {
|
||||||
|
noMatchOutcomes.add(outcome);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return noMatchOutcomes;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ConditionOutcome determineOutcome(AnnotationAttributes annotationAttributes,
|
||||||
|
PropertyResolver resolver) {
|
||||||
String prefix = annotationAttributes.getString("prefix").trim();
|
String prefix = annotationAttributes.getString("prefix").trim();
|
||||||
if (StringUtils.hasText(prefix) && !prefix.endsWith(".")) {
|
if (StringUtils.hasText(prefix) && !prefix.endsWith(".")) {
|
||||||
prefix = prefix + ".";
|
prefix = prefix + ".";
|
||||||
|
@ -56,7 +107,6 @@ class OnPropertyCondition extends SpringBootCondition {
|
||||||
boolean relaxedNames = annotationAttributes.getBoolean("relaxedNames");
|
boolean relaxedNames = annotationAttributes.getBoolean("relaxedNames");
|
||||||
boolean matchIfMissing = annotationAttributes.getBoolean("matchIfMissing");
|
boolean matchIfMissing = annotationAttributes.getBoolean("matchIfMissing");
|
||||||
|
|
||||||
PropertyResolver resolver = context.getEnvironment();
|
|
||||||
if (relaxedNames) {
|
if (relaxedNames) {
|
||||||
resolver = new RelaxedPropertyResolver(resolver, prefix);
|
resolver = new RelaxedPropertyResolver(resolver, prefix);
|
||||||
}
|
}
|
||||||
|
@ -91,7 +141,6 @@ class OnPropertyCondition extends SpringBootCondition {
|
||||||
message.append("expected '").append(expected).append("' for properties ")
|
message.append("expected '").append(expected).append("' for properties ")
|
||||||
.append(expandNames(prefix, nonMatchingProperties));
|
.append(expandNames(prefix, nonMatchingProperties));
|
||||||
}
|
}
|
||||||
|
|
||||||
return ConditionOutcome.noMatch(message.toString());
|
return ConditionOutcome.noMatch(message.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,4 +171,15 @@ class OnPropertyCondition extends SpringBootCondition {
|
||||||
return expanded.toString();
|
return expanded.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String getCompositeMessage(List<ConditionOutcome> noMatchOutcomes) {
|
||||||
|
StringBuilder message = new StringBuilder();
|
||||||
|
for (ConditionOutcome noMatchOutcome : noMatchOutcomes) {
|
||||||
|
if (message.length() > 0) {
|
||||||
|
message.append(". ");
|
||||||
|
}
|
||||||
|
message.append(noMatchOutcome.getMessage().trim());
|
||||||
|
}
|
||||||
|
return message.toString();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,11 @@
|
||||||
|
|
||||||
package org.springframework.boot.autoconfigure.condition;
|
package org.springframework.boot.autoconfigure.condition;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Rule;
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
@ -36,6 +41,7 @@ import static org.junit.internal.matchers.ThrowableMessageMatcher.hasMessage;
|
||||||
* @author Maciej Walkowiak
|
* @author Maciej Walkowiak
|
||||||
* @author Stephane Nicoll
|
* @author Stephane Nicoll
|
||||||
* @author Phillip Webb
|
* @author Phillip Webb
|
||||||
|
* @author Andy Wilkinson
|
||||||
*/
|
*/
|
||||||
public class ConditionalOnPropertyTests {
|
public class ConditionalOnPropertyTests {
|
||||||
|
|
||||||
|
@ -226,6 +232,44 @@ public class ConditionalOnPropertyTests {
|
||||||
load(NameAndValueAttribute.class, "some.property");
|
load(NameAndValueAttribute.class, "some.property");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void metaAnnotationConditionMatchesWhenPropertyIsSet() throws Exception {
|
||||||
|
load(MetaAnnotation.class, "my.feature.enabled=true");
|
||||||
|
assertThat(this.context.containsBean("foo")).isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void metaAnnotationConditionDoesNotMatchWhenPropertyIsNotSet()
|
||||||
|
throws Exception {
|
||||||
|
load(MetaAnnotation.class);
|
||||||
|
assertThat(this.context.containsBean("foo")).isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void metaAndDirectAnnotationConditionDoesNotMatchWhenOnlyDirectPropertyIsSet() {
|
||||||
|
load(MetaAnnotationAndDirectAnnotation.class, "my.other.feature.enabled=true");
|
||||||
|
assertThat(this.context.containsBean("foo")).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void metaAndDirectAnnotationConditionDoesNotMatchWhenOnlyMetaPropertyIsSet() {
|
||||||
|
load(MetaAnnotationAndDirectAnnotation.class, "my.feature.enabled=true");
|
||||||
|
assertThat(this.context.containsBean("foo")).isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void metaAndDirectAnnotationConditionDoesNotMatchWhenNeitherPropertyIsSet() {
|
||||||
|
load(MetaAnnotationAndDirectAnnotation.class);
|
||||||
|
assertThat(this.context.containsBean("foo")).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void metaAndDirectAnnotationConditionMatchesWhenBothPropertiesAreSet() {
|
||||||
|
load(MetaAnnotationAndDirectAnnotation.class, "my.feature.enabled=true",
|
||||||
|
"my.other.feature.enabled=true");
|
||||||
|
assertThat(this.context.containsBean("foo")).isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
private void load(Class<?> config, String... environment) {
|
private void load(Class<?> config, String... environment) {
|
||||||
this.context = new AnnotationConfigApplicationContext();
|
this.context = new AnnotationConfigApplicationContext();
|
||||||
EnvironmentTestUtils.addEnvironment(this.context, environment);
|
EnvironmentTestUtils.addEnvironment(this.context, environment);
|
||||||
|
@ -389,4 +433,32 @@ public class ConditionalOnPropertyTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ConditionalOnMyFeature
|
||||||
|
protected static class MetaAnnotation {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public String foo() {
|
||||||
|
return "foo";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@ConditionalOnMyFeature
|
||||||
|
@ConditionalOnProperty(prefix = "my.other.feature", name = "enabled", havingValue = "true", matchIfMissing = false)
|
||||||
|
protected static class MetaAnnotationAndDirectAnnotation {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public String foo() {
|
||||||
|
return "foo";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Target({ ElementType.TYPE, ElementType.METHOD })
|
||||||
|
@ConditionalOnProperty(prefix = "my.feature", name = "enabled", havingValue = "true", matchIfMissing = false)
|
||||||
|
public @interface ConditionalOnMyFeature {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue