1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.springframework.context.annotation;
18
19 import java.util.HashSet;
20 import java.util.LinkedHashMap;
21 import java.util.LinkedHashSet;
22 import java.util.Map;
23 import java.util.Set;
24
25 import org.springframework.beans.factory.parsing.Location;
26 import org.springframework.beans.factory.parsing.Problem;
27 import org.springframework.beans.factory.parsing.ProblemReporter;
28 import org.springframework.beans.factory.support.BeanDefinitionReader;
29 import org.springframework.core.io.DescriptiveResource;
30 import org.springframework.core.io.Resource;
31 import org.springframework.core.type.AnnotationMetadata;
32 import org.springframework.core.type.StandardAnnotationMetadata;
33 import org.springframework.core.type.classreading.MetadataReader;
34 import org.springframework.util.Assert;
35 import org.springframework.util.ClassUtils;
36
37
38
39
40
41
42
43
44
45
46
47
48
49 final class ConfigurationClass {
50
51 private final AnnotationMetadata metadata;
52
53 private final Resource resource;
54
55 private String beanName;
56
57 private final Set<ConfigurationClass> importedBy = new LinkedHashSet<ConfigurationClass>(1);
58
59 private final Set<BeanMethod> beanMethods = new LinkedHashSet<BeanMethod>();
60
61 private final Map<String, Class<? extends BeanDefinitionReader>> importedResources =
62 new LinkedHashMap<String, Class<? extends BeanDefinitionReader>>();
63
64 private final Map<ImportBeanDefinitionRegistrar, AnnotationMetadata> importBeanDefinitionRegistrars =
65 new LinkedHashMap<ImportBeanDefinitionRegistrar, AnnotationMetadata>();
66
67 final Set<String> skippedBeanMethods = new HashSet<String>();
68
69
70
71
72
73
74
75
76 public ConfigurationClass(MetadataReader metadataReader, String beanName) {
77 Assert.hasText(beanName, "Bean name must not be null");
78 this.metadata = metadataReader.getAnnotationMetadata();
79 this.resource = metadataReader.getResource();
80 this.beanName = beanName;
81 }
82
83
84
85
86
87
88
89
90
91 public ConfigurationClass(MetadataReader metadataReader, ConfigurationClass importedBy) {
92 this.metadata = metadataReader.getAnnotationMetadata();
93 this.resource = metadataReader.getResource();
94 this.importedBy.add(importedBy);
95 }
96
97
98
99
100
101
102
103 public ConfigurationClass(Class<?> clazz, String beanName) {
104 Assert.hasText(beanName, "Bean name must not be null");
105 this.metadata = new StandardAnnotationMetadata(clazz, true);
106 this.resource = new DescriptiveResource(clazz.toString());
107 this.beanName = beanName;
108 }
109
110
111
112
113
114
115
116
117
118 public ConfigurationClass(Class<?> clazz, ConfigurationClass importedBy) {
119 this.metadata = new StandardAnnotationMetadata(clazz, true);
120 this.resource = new DescriptiveResource(clazz.toString());
121 this.importedBy.add(importedBy);
122 }
123
124
125
126
127
128
129
130 public ConfigurationClass(AnnotationMetadata metadata, String beanName) {
131 Assert.hasText(beanName, "Bean name must not be null");
132 this.metadata = metadata;
133 this.resource = new DescriptiveResource(metadata.getClassName());
134 this.beanName = beanName;
135 }
136
137
138 public AnnotationMetadata getMetadata() {
139 return this.metadata;
140 }
141
142 public Resource getResource() {
143 return this.resource;
144 }
145
146 public String getSimpleName() {
147 return ClassUtils.getShortName(getMetadata().getClassName());
148 }
149
150 public void setBeanName(String beanName) {
151 this.beanName = beanName;
152 }
153
154 public String getBeanName() {
155 return this.beanName;
156 }
157
158
159
160
161
162
163
164 public boolean isImported() {
165 return !this.importedBy.isEmpty();
166 }
167
168
169
170
171
172 public void mergeImportedBy(ConfigurationClass otherConfigClass) {
173 this.importedBy.addAll(otherConfigClass.importedBy);
174 }
175
176
177
178
179
180
181
182 public Set<ConfigurationClass> getImportedBy() {
183 return this.importedBy;
184 }
185
186 public void addBeanMethod(BeanMethod method) {
187 this.beanMethods.add(method);
188 }
189
190 public Set<BeanMethod> getBeanMethods() {
191 return this.beanMethods;
192 }
193
194 public void addImportedResource(String importedResource, Class<? extends BeanDefinitionReader> readerClass) {
195 this.importedResources.put(importedResource, readerClass);
196 }
197
198 public void addImportBeanDefinitionRegistrar(ImportBeanDefinitionRegistrar registrar, AnnotationMetadata importingClassMetadata) {
199 this.importBeanDefinitionRegistrars.put(registrar, importingClassMetadata);
200 }
201
202 public Map<ImportBeanDefinitionRegistrar, AnnotationMetadata> getImportBeanDefinitionRegistrars() {
203 return this.importBeanDefinitionRegistrars;
204 }
205
206 public Map<String, Class<? extends BeanDefinitionReader>> getImportedResources() {
207 return this.importedResources;
208 }
209
210 public void validate(ProblemReporter problemReporter) {
211
212 if (getMetadata().isAnnotated(Configuration.class.getName())) {
213 if (getMetadata().isFinal()) {
214 problemReporter.error(new FinalConfigurationProblem());
215 }
216 }
217
218 for (BeanMethod beanMethod : this.beanMethods) {
219 beanMethod.validate(problemReporter);
220 }
221 }
222
223 @Override
224 public boolean equals(Object other) {
225 return (this == other || (other instanceof ConfigurationClass &&
226 getMetadata().getClassName().equals(((ConfigurationClass) other).getMetadata().getClassName())));
227 }
228
229 @Override
230 public int hashCode() {
231 return getMetadata().getClassName().hashCode();
232 }
233
234 @Override
235 public String toString() {
236 return "ConfigurationClass:beanName=" + this.beanName + ",resource=" + this.resource;
237 }
238
239
240
241
242
243 private class FinalConfigurationProblem extends Problem {
244
245 public FinalConfigurationProblem() {
246 super(String.format("@Configuration class '%s' may not be final. Remove the final modifier to continue.",
247 getSimpleName()), new Location(getResource(), getMetadata()));
248 }
249 }
250
251 }