|
16 | 16 |
|
17 | 17 | package org.springframework.boot.autoconfigure.condition;
|
18 | 18 |
|
19 |
| -import java.io.IOException; |
20 | 19 | import java.util.ArrayList;
|
21 |
| -import java.util.Collections; |
22 | 20 | import java.util.List;
|
23 |
| -import java.util.Map; |
24 | 21 |
|
25 |
| -import org.springframework.beans.BeanUtils; |
26 | 22 | import org.springframework.context.annotation.Condition;
|
27 |
| -import org.springframework.context.annotation.ConditionContext; |
28 |
| -import org.springframework.context.annotation.Conditional; |
29 |
| -import org.springframework.context.annotation.ConfigurationCondition; |
30 | 23 | import org.springframework.core.Ordered;
|
31 | 24 | import org.springframework.core.annotation.Order;
|
32 |
| -import org.springframework.core.type.AnnotatedTypeMetadata; |
33 |
| -import org.springframework.core.type.AnnotationMetadata; |
34 |
| -import org.springframework.core.type.classreading.MetadataReaderFactory; |
35 |
| -import org.springframework.core.type.classreading.SimpleMetadataReaderFactory; |
36 |
| -import org.springframework.util.Assert; |
37 |
| -import org.springframework.util.ClassUtils; |
38 |
| -import org.springframework.util.LinkedMultiValueMap; |
39 |
| -import org.springframework.util.MultiValueMap; |
40 |
| -import org.springframework.util.StringUtils; |
41 | 25 |
|
42 | 26 | /**
|
43 |
| - * {@link Condition} that will match when any nested class condition matches. Can be used |
44 |
| - * to create composite conditions, for example: |
| 27 | + * {@link Condition} that will match when any nested class condition matches. |
| 28 | + * Can be used to create composite conditions, for example: |
45 | 29 | *
|
46 | 30 | * <pre class="code">
|
47 | 31 | * static class OnJndiOrProperty extends AnyNestedCondition {
|
|
61 | 45 | * @since 1.2.0
|
62 | 46 | */
|
63 | 47 | @Order(Ordered.LOWEST_PRECEDENCE - 20)
|
64 |
| -public abstract class AnyNestedCondition extends SpringBootCondition implements |
65 |
| - ConfigurationCondition { |
66 |
| - |
67 |
| - private final ConfigurationPhase configurationPhase; |
| 48 | +public abstract class AnyNestedCondition extends AbstractNestedCondition { |
68 | 49 |
|
69 | 50 | public AnyNestedCondition(ConfigurationPhase configurationPhase) {
|
70 |
| - Assert.notNull(configurationPhase, "ConfigurationPhase must not be null"); |
71 |
| - this.configurationPhase = configurationPhase; |
72 |
| - } |
73 |
| - |
74 |
| - @Override |
75 |
| - public ConfigurationPhase getConfigurationPhase() { |
76 |
| - return this.configurationPhase; |
| 51 | + super(configurationPhase); |
77 | 52 | }
|
78 | 53 |
|
79 | 54 | @Override
|
80 |
| - public ConditionOutcome getMatchOutcome(ConditionContext context, |
81 |
| - AnnotatedTypeMetadata metadata) { |
82 |
| - MemberConditions memberConditions = new MemberConditions(context, getClass() |
83 |
| - .getName()); |
84 |
| - List<ConditionOutcome> outcomes = memberConditions.getMatchOutcomes(); |
| 55 | + protected ConditionOutcome buildConditionOutcome(List<ConditionOutcome> outcomes) { |
85 | 56 | List<ConditionOutcome> match = new ArrayList<ConditionOutcome>();
|
86 | 57 | List<ConditionOutcome> nonMatch = new ArrayList<ConditionOutcome>();
|
87 | 58 | for (ConditionOutcome outcome : outcomes) {
|
88 | 59 | if (outcome.isMatch()) {
|
89 | 60 | match.add(outcome);
|
90 |
| - } |
91 |
| - else { |
| 61 | + } else { |
92 | 62 | nonMatch.add(outcome);
|
93 | 63 | }
|
94 | 64 | }
|
95 |
| - return new ConditionOutcome(match.size() > 0, "any match resulted in " + match |
96 |
| - + " matches and " + nonMatch + " non matches"); |
97 |
| - } |
98 |
| - |
99 |
| - private static class MemberConditions { |
100 |
| - |
101 |
| - private final ConditionContext context; |
102 |
| - |
103 |
| - private final MetadataReaderFactory readerFactory; |
104 |
| - |
105 |
| - private final Map<AnnotationMetadata, List<Condition>> memberConditions; |
106 |
| - |
107 |
| - public MemberConditions(ConditionContext context, String className) { |
108 |
| - this.context = context; |
109 |
| - this.readerFactory = new SimpleMetadataReaderFactory( |
110 |
| - context.getResourceLoader()); |
111 |
| - String[] members = getMetadata(className).getMemberClassNames(); |
112 |
| - this.memberConditions = getMemberConditions(members); |
113 |
| - } |
114 |
| - |
115 |
| - private Map<AnnotationMetadata, List<Condition>> getMemberConditions( |
116 |
| - String[] members) { |
117 |
| - MultiValueMap<AnnotationMetadata, Condition> memberConditions = new LinkedMultiValueMap<AnnotationMetadata, Condition>(); |
118 |
| - for (String member : members) { |
119 |
| - AnnotationMetadata metadata = getMetadata(member); |
120 |
| - for (String[] conditionClasses : getConditionClasses(metadata)) { |
121 |
| - for (String conditionClass : conditionClasses) { |
122 |
| - Condition condition = getCondition(conditionClass); |
123 |
| - memberConditions.add(metadata, condition); |
124 |
| - } |
125 |
| - } |
126 |
| - } |
127 |
| - return Collections.unmodifiableMap(memberConditions); |
128 |
| - } |
129 |
| - |
130 |
| - private AnnotationMetadata getMetadata(String className) { |
131 |
| - try { |
132 |
| - return this.readerFactory.getMetadataReader(className) |
133 |
| - .getAnnotationMetadata(); |
134 |
| - } |
135 |
| - catch (IOException ex) { |
136 |
| - throw new IllegalStateException(ex); |
137 |
| - } |
138 |
| - } |
139 |
| - |
140 |
| - @SuppressWarnings("unchecked") |
141 |
| - private List<String[]> getConditionClasses(AnnotatedTypeMetadata metadata) { |
142 |
| - MultiValueMap<String, Object> attributes = metadata |
143 |
| - .getAllAnnotationAttributes(Conditional.class.getName(), true); |
144 |
| - Object values = (attributes != null ? attributes.get("value") : null); |
145 |
| - return (List<String[]>) (values != null ? values : Collections.emptyList()); |
146 |
| - } |
147 |
| - |
148 |
| - private Condition getCondition(String conditionClassName) { |
149 |
| - Class<?> conditionClass = ClassUtils.resolveClassName(conditionClassName, |
150 |
| - this.context.getClassLoader()); |
151 |
| - return (Condition) BeanUtils.instantiateClass(conditionClass); |
152 |
| - } |
153 |
| - |
154 |
| - public List<ConditionOutcome> getMatchOutcomes() { |
155 |
| - List<ConditionOutcome> outcomes = new ArrayList<ConditionOutcome>(); |
156 |
| - for (Map.Entry<AnnotationMetadata, List<Condition>> entry : this.memberConditions |
157 |
| - .entrySet()) { |
158 |
| - AnnotationMetadata metadata = entry.getKey(); |
159 |
| - for (Condition condition : entry.getValue()) { |
160 |
| - outcomes.add(getConditionOutcome(metadata, condition)); |
161 |
| - } |
162 |
| - } |
163 |
| - return Collections.unmodifiableList(outcomes); |
164 |
| - } |
165 |
| - |
166 |
| - private ConditionOutcome getConditionOutcome(AnnotationMetadata metadata, |
167 |
| - Condition condition) { |
168 |
| - String messagePrefix = "member condition on " + metadata.getClassName(); |
169 |
| - if (condition instanceof SpringBootCondition) { |
170 |
| - ConditionOutcome outcome = ((SpringBootCondition) condition) |
171 |
| - .getMatchOutcome(this.context, metadata); |
172 |
| - String message = outcome.getMessage(); |
173 |
| - return new ConditionOutcome(outcome.isMatch(), messagePrefix |
174 |
| - + (StringUtils.hasLength(message) ? " : " + message : "")); |
175 |
| - } |
176 |
| - boolean matches = condition.matches(this.context, metadata); |
177 |
| - return new ConditionOutcome(matches, messagePrefix); |
178 |
| - } |
179 |
| - |
| 65 | + return new ConditionOutcome(match.size() > 0, "any match resulted in " + match + " matches and " + nonMatch |
| 66 | + + " non matches"); |
180 | 67 | }
|
181 | 68 |
|
182 | 69 | }
|
0 commit comments