1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package ch.elca.el4j.core.context;
19
20 import java.io.IOException;
21 import java.util.ArrayList;
22 import java.util.Collections;
23 import java.util.Iterator;
24 import java.util.List;
25
26 import org.apache.commons.lang.ArrayUtils;
27 import org.slf4j.Logger;
28 import org.slf4j.LoggerFactory;
29 import org.springframework.beans.PropertyValue;
30 import org.springframework.beans.PropertyValues;
31 import org.springframework.beans.factory.NoSuchBeanDefinitionException;
32 import org.springframework.beans.factory.config.BeanDefinition;
33 import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
34 import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
35 import org.springframework.beans.factory.config.TypedStringValue;
36 import org.springframework.context.ApplicationContext;
37 import org.springframework.context.support.AbstractApplicationContext;
38 import org.springframework.core.OrderComparator;
39 import org.springframework.core.Ordered;
40 import org.springframework.core.PriorityOrdered;
41 import org.springframework.core.io.Resource;
42 import org.springframework.util.Assert;
43
44 import ch.elca.el4j.services.monitoring.notification.CoreNotificationHelper;
45
46
47
48
49
50
51
52
53 public class ModuleApplicationContextUtils {
54
55
56
57
58
59 private static final String MANDATORY = "mandatory/*.xml";
60
61
62 private static Logger s_logger = LoggerFactory.getLogger(
63 ModuleApplicationContextUtils.class);
64
65
66 private ApplicationContext m_appContext;
67
68
69
70
71 private boolean m_reverseConfigLocationResourceArray = false;
72
73
74
75
76
77
78
79
80 public ModuleApplicationContextUtils(ApplicationContext context) {
81 m_appContext = context;
82 }
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98 public String[] calculateInputFiles(String[] inclusiveConfigLocations,
99 String[] exclusiveConfigLocations,
100 boolean allowBeanDefinitionOverriding) {
101
102 if (ArrayUtils.isEmpty(inclusiveConfigLocations)) {
103 s_logger.warn("No inclusive configuration locations given!");
104 return null;
105 }
106
107
108
109 if (m_appContext.getParent() == null) {
110 checkConfigLocations(inclusiveConfigLocations[0]);
111 }
112
113 List<String> inclusiveFileNames
114 = getResolvedFileNames(inclusiveConfigLocations);
115
116 List<String> exclusiveFileNames
117 = getResolvedFileNames(exclusiveConfigLocations);
118
119
120
121 for (int i = 0; i < inclusiveFileNames.size(); i++) {
122 Object obj = inclusiveFileNames.get(i);
123 if (exclusiveFileNames.contains(obj)) {
124 inclusiveFileNames.remove(i);
125 i--;
126 }
127 }
128
129 String[] conLoc = new String[inclusiveFileNames.size()];
130
131 for (int i = 0; i < inclusiveFileNames.size(); i++) {
132 conLoc[i] = (String) inclusiveFileNames.get(i);
133 }
134
135 return conLoc;
136 }
137
138
139
140
141
142
143
144 protected void checkConfigLocations(String configLocation) {
145 if (!(configLocation.equals("classpath*:" + MANDATORY)
146 || (configLocation.equals("classpath*:/" + MANDATORY)))) {
147
148 s_logger.warn("The config location 'classpath*:" + MANDATORY
149 + "' is not loaded or is not the first config location"
150 + " which is loaded.");
151 }
152 }
153
154
155
156
157
158
159
160
161
162
163 protected List<String> getResolvedFileNames(String[] unresolvedFileNames) {
164
165 List<String> result = new ArrayList<String>();
166
167 if (unresolvedFileNames == null) {
168 return result;
169 }
170
171 for (int i = 0; i < unresolvedFileNames.length; i++) {
172 String[] resolvedFileNames = resolveAttribute(unresolvedFileNames[i]
173 .replace('\\', '/'));
174 for (int j = 0; j < resolvedFileNames.length; j++) {
175 if ((resolvedFileNames[j].startsWith("file:"))
176 && (!resolvedFileNames[j].startsWith("file:/"))) {
177 resolvedFileNames[j] = resolvedFileNames[j].replaceFirst(
178 "file:", "file:/");
179 }
180 result.add(resolvedFileNames[j]);
181 }
182 }
183 return result;
184 }
185
186
187
188
189
190
191
192
193
194
195 protected String[] resolveAttribute(String path) {
196 List<String> resolvedAttributes = new ArrayList<String>();
197
198 try {
199 Resource[] resLocal = m_appContext.getResources(path);
200 if (isReverseConfigLocationResourceArray()) {
201 ArrayUtils.reverse(resLocal);
202 }
203
204 for (int i = 0; i < resLocal.length; i++) {
205 if (resLocal[i].exists()) {
206 resolvedAttributes.add(resLocal[i].getURL().toString());
207 } else {
208 s_logger.warn("The file '" + resLocal[i].toString()
209 + "' does not exist.");
210 }
211 }
212 } catch (IOException e) {
213 String message = "An IOException has occurred.";
214 CoreNotificationHelper.notifyMisconfiguration(message, e);
215 }
216
217 String[] result = new String[resolvedAttributes.size()];
218
219 for (int i = 0; i < result.length; i++) {
220 result[i] = (String) resolvedAttributes.get(i);
221 }
222 return result;
223 }
224
225
226
227
228 public boolean isReverseConfigLocationResourceArray() {
229 return m_reverseConfigLocationResourceArray;
230 }
231
232
233
234
235
236
237
238
239 public void setReverseConfigLocationResourceArray(
240 boolean reverseConfigLocationResourceArray) {
241 m_reverseConfigLocationResourceArray
242 = reverseConfigLocationResourceArray;
243 }
244
245
246
247
248
249
250
251
252
253
254 @SuppressWarnings("unchecked")
255 public void invokeBeanFactoryPostProcessorsStrictlyOrdered(
256 ConfigurableListableBeanFactory beanFactory) {
257
258
259 Assert.isInstanceOf(AbstractApplicationContext.class, m_appContext);
260 AbstractApplicationContext ctx
261 = (AbstractApplicationContext) m_appContext;
262
263
264 for (Iterator it = ctx.getBeanFactoryPostProcessors().iterator();
265 it.hasNext();) {
266
267 BeanFactoryPostProcessor factoryProcessor
268 = (BeanFactoryPostProcessor) it.next();
269 factoryProcessor.postProcessBeanFactory(beanFactory);
270 }
271
272
273
274
275 String[] postProcessorNames
276 = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class,
277 true, false);
278
279
280
281 List<OrderedBeanNameHolder> priorityOrderedPostProcessorHolders
282 = new ArrayList<OrderedBeanNameHolder>();
283 List<OrderedBeanNameHolder> orderedPostProcessorHolders
284 = new ArrayList<OrderedBeanNameHolder>();
285 List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
286 for (int i = 0; i < postProcessorNames.length; i++) {
287 String postProcessorName = postProcessorNames[i];
288 if (ctx.isTypeMatch(postProcessorName, PriorityOrdered.class)) {
289 priorityOrderedPostProcessorHolders.add(
290 getOrderedBeanNameHolder(beanFactory, postProcessorName));
291 } else if (ctx.isTypeMatch(postProcessorName, Ordered.class)) {
292 orderedPostProcessorHolders.add(
293 getOrderedBeanNameHolder(beanFactory, postProcessorName));
294 } else {
295 nonOrderedPostProcessorNames.add(postProcessorName);
296 }
297 }
298
299
300
301 Collections.sort(priorityOrderedPostProcessorHolders,
302 new OrderComparator());
303 invokeBeanFactoryPostProcessors(beanFactory,
304 priorityOrderedPostProcessorHolders);
305
306
307 Collections.sort(orderedPostProcessorHolders,
308 new OrderComparator());
309 invokeBeanFactoryPostProcessors(beanFactory,
310 orderedPostProcessorHolders);
311
312
313 for (String nonOrderedPostProcessorName
314 : nonOrderedPostProcessorNames) {
315 Object bean = ctx.getBean(nonOrderedPostProcessorName);
316 BeanFactoryPostProcessor postProcessor
317 = (BeanFactoryPostProcessor) bean;
318 postProcessor.postProcessBeanFactory(beanFactory);
319 }
320 }
321
322
323
324
325
326
327
328
329
330
331 protected void invokeBeanFactoryPostProcessors(
332 ConfigurableListableBeanFactory beanFactory,
333 List<OrderedBeanNameHolder> postProcessorHolders) {
334 for (OrderedBeanNameHolder orderedBeanNameHolder
335 : postProcessorHolders) {
336 Object bean = m_appContext.getBean(
337 orderedBeanNameHolder.getBeanName());
338 BeanFactoryPostProcessor postProcessor
339 = (BeanFactoryPostProcessor) bean;
340 postProcessor.postProcessBeanFactory(beanFactory);
341 }
342 }
343
344
345
346
347
348
349
350
351
352
353
354
355 protected OrderedBeanNameHolder getOrderedBeanNameHolder(
356 ConfigurableListableBeanFactory beanFactory, String orderedBeanName)
357 throws NoSuchBeanDefinitionException {
358
359 BeanDefinition beanDefinition
360 = beanFactory.getBeanDefinition(orderedBeanName);
361 PropertyValues processorDefinitionProps
362 = beanDefinition.getPropertyValues();
363 PropertyValue order
364 = processorDefinitionProps.getPropertyValue("order");
365 int orderAsInt = 0;
366 if (order != null) {
367 try {
368 Object orderValue = order.getValue();
369 String orderAsString;
370 if (orderValue instanceof TypedStringValue) {
371 TypedStringValue orderValueString
372 = (TypedStringValue) order.getValue();
373 orderAsString = orderValueString.getValue();
374 } else {
375 orderAsString = orderValue.toString();
376 }
377 orderAsInt = Integer.parseInt(orderAsString);
378 } catch (NumberFormatException e) {
379 orderAsInt = 0;
380 }
381 }
382 return new OrderedBeanNameHolder(orderAsInt, orderedBeanName);
383 }
384 }