1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.krad.datadictionary;
17
18 import org.apache.commons.lang.StringUtils;
19 import org.apache.commons.logging.Log;
20 import org.apache.commons.logging.LogFactory;
21 import org.kuali.rice.krad.service.DataDictionaryService;
22 import org.kuali.rice.krad.service.KRADServiceLocator;
23 import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
24 import org.springframework.beans.BeansException;
25 import org.springframework.beans.MutablePropertyValues;
26 import org.springframework.beans.PropertyValue;
27 import org.springframework.beans.factory.config.BeanDefinition;
28 import org.springframework.beans.factory.config.BeanDefinitionHolder;
29 import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
30 import org.springframework.beans.factory.config.TypedStringValue;
31 import org.springframework.beans.factory.support.BeanDefinitionRegistry;
32 import org.springframework.beans.factory.support.ManagedArray;
33 import org.springframework.beans.factory.support.ManagedList;
34 import org.springframework.beans.factory.support.ManagedMap;
35 import org.springframework.beans.factory.support.ManagedSet;
36
37 import java.util.ArrayList;
38 import java.util.List;
39 import java.util.Map;
40 import java.util.Set;
41 import java.util.Stack;
42
43
44
45
46
47
48
49
50
51
52
53 public class DictionaryBeanFactoryPostProcessor {
54 private static final Log LOG = LogFactory.getLog(DictionaryBeanFactoryPostProcessor.class);
55
56 private DataDictionary dataDictionary;
57 private ConfigurableListableBeanFactory beanFactory;
58
59 private List<DictionaryBeanProcessor> beanProcessors;
60
61
62
63
64
65
66
67 public DictionaryBeanFactoryPostProcessor(DataDictionary dataDictionary,
68 ConfigurableListableBeanFactory beanFactory) {
69 this.dataDictionary = dataDictionary;
70 this.beanFactory = beanFactory;
71
72 this.beanProcessors = new ArrayList<DictionaryBeanProcessor>();
73 this.beanProcessors.add(new MessageBeanProcessor(dataDictionary, beanFactory));
74 }
75
76
77
78
79
80
81 public void postProcessBeanFactory() throws BeansException {
82
83 boolean loadExternalMessages = KRADServiceLocator.getKualiConfigurationService().getPropertyValueAsBoolean(
84 "load.dictionary.external.messages");
85 if (!loadExternalMessages) {
86 return;
87 }
88
89 LOG.info("Beginning dictionary bean post processing");
90
91 List<DictionaryBeanProcessor> beanProcessors = new ArrayList<DictionaryBeanProcessor>();
92 beanProcessors.add(new MessageBeanProcessor(dataDictionary, beanFactory));
93
94 String[] beanNames = beanFactory.getBeanDefinitionNames();
95 for (int i = 0; i < beanNames.length; i++) {
96 String beanName = beanNames[i];
97 BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName);
98
99 processRootBeanDefinition(beanName, beanDefinition);
100 }
101
102 LOG.info("Finished dictionary bean post processing");
103 }
104
105
106
107
108
109
110
111 protected void processRootBeanDefinition(String beanName, BeanDefinition beanDefinition) {
112 for (DictionaryBeanProcessor beanProcessor : beanProcessors) {
113 beanProcessor.processRootBeanDefinition(beanName, beanDefinition);
114 }
115
116 Stack<BeanDefinitionHolder> nestedBeanStack = new Stack<BeanDefinitionHolder>();
117 nestedBeanStack.push(new BeanDefinitionHolder(beanDefinition, beanName));
118
119 processBeanProperties(beanDefinition, nestedBeanStack);
120 }
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137 public void processNestedBeanDefinition(String beanName, BeanDefinition beanDefinition, String nestedPropertyPath,
138 boolean isCollectionBean, Stack<BeanDefinitionHolder> nestedBeanStack) {
139
140
141 if (StringUtils.isNotBlank(beanName) && !StringUtils.contains(beanName, "$") && !StringUtils.contains(beanName,
142 "#") && !beanFactory.containsBean(beanName)) {
143 ((BeanDefinitionRegistry) beanFactory).registerBeanDefinition(beanName, beanDefinition);
144 }
145
146
147 for (DictionaryBeanProcessor beanProcessor : beanProcessors) {
148 if (isCollectionBean) {
149 beanProcessor.processCollectionBeanDefinition(beanName, beanDefinition, nestedPropertyPath,
150 nestedBeanStack);
151 } else {
152 beanProcessor.processNestedBeanDefinition(beanName, beanDefinition, nestedPropertyPath,
153 nestedBeanStack);
154 }
155 }
156
157 BeanDefinitionHolder nestedBeanDefinitionHolder = new BeanDefinitionHolder(beanDefinition, beanName);
158 nestedBeanStack.push(nestedBeanDefinitionHolder);
159
160 processBeanProperties(beanDefinition, nestedBeanStack);
161
162 nestedBeanStack.pop();
163 }
164
165
166
167
168
169
170
171
172
173 protected String processStringPropertyValue(String propertyName, String propertyValue,
174 Stack<BeanDefinitionHolder> nestedBeanStack) {
175 String processedStringValue = propertyValue;
176
177 for (DictionaryBeanProcessor beanProcessor : beanProcessors) {
178 processedStringValue = beanProcessor.processStringPropertyValue(propertyName, processedStringValue,
179 nestedBeanStack);
180 }
181
182 return processedStringValue;
183 }
184
185
186
187
188
189
190
191
192
193
194
195 protected String processArrayStringPropertyValue(String propertyName, Object[] propertyValue, String elementValue,
196 int elementIndex, Stack<BeanDefinitionHolder> nestedBeanStack,
197 List<DictionaryBeanProcessor> beanProcessors) {
198 String processedStringValue = elementValue;
199
200 for (DictionaryBeanProcessor beanProcessor : beanProcessors) {
201 processedStringValue = beanProcessor.processArrayStringPropertyValue(propertyName, propertyValue,
202 elementValue, elementIndex, nestedBeanStack);
203 }
204
205 return processedStringValue;
206 }
207
208
209
210
211
212
213
214
215
216
217
218 protected String processListStringPropertyValue(String propertyName, List<?> propertyValue, String elementValue,
219 int elementIndex, Stack<BeanDefinitionHolder> nestedBeanStack,
220 List<DictionaryBeanProcessor> beanProcessors) {
221 String processedStringValue = elementValue;
222
223 for (DictionaryBeanProcessor beanProcessor : beanProcessors) {
224 processedStringValue = beanProcessor.processListStringPropertyValue(propertyName, propertyValue,
225 elementValue, elementIndex, nestedBeanStack);
226 }
227
228 return processedStringValue;
229 }
230
231
232
233
234
235
236
237
238
239
240 protected String processSetStringPropertyValue(String propertyName, Set<?> propertyValue, String elementValue,
241 Stack<BeanDefinitionHolder> nestedBeanStack, List<DictionaryBeanProcessor> beanProcessors) {
242 String processedStringValue = elementValue;
243
244 for (DictionaryBeanProcessor beanProcessor : beanProcessors) {
245 processedStringValue = beanProcessor.processSetStringPropertyValue(propertyName, propertyValue,
246 elementValue, nestedBeanStack);
247 }
248
249 return processedStringValue;
250 }
251
252
253
254
255
256
257
258
259
260
261
262 protected String processMapStringPropertyValue(String propertyName, Map<?, ?> propertyValue, String elementValue,
263 Object elementKey, Stack<BeanDefinitionHolder> nestedBeanStack,
264 List<DictionaryBeanProcessor> beanProcessors) {
265 String processedStringValue = elementValue;
266
267 for (DictionaryBeanProcessor beanProcessor : beanProcessors) {
268 processedStringValue = beanProcessor.processMapStringPropertyValue(propertyName, propertyValue,
269 elementValue, elementKey, nestedBeanStack);
270 }
271
272 return processedStringValue;
273 }
274
275
276
277
278
279
280
281
282 protected void processBeanProperties(BeanDefinition beanDefinition, Stack<BeanDefinitionHolder> nestedBeanStack) {
283
284 MutablePropertyValues pvs = beanDefinition.getPropertyValues();
285 PropertyValue[] pvArray = pvs.getPropertyValues();
286 for (PropertyValue pv : pvArray) {
287 Object newPropertyValue = null;
288 if (isStringValue(pv.getValue())) {
289 newPropertyValue = processStringPropertyValue(pv.getName(), getString(pv.getValue()), nestedBeanStack);
290 } else {
291 newPropertyValue = visitPropertyValue(pv.getName(), pv.getValue(), nestedBeanStack);
292 }
293
294 pvs.removePropertyValue(pv.getName());
295 pvs.addPropertyValue(pv.getName(), newPropertyValue);
296 }
297 }
298
299
300
301
302
303
304
305
306
307
308 protected Object visitPropertyValue(String propertyName, Object propertyValue,
309 Stack<BeanDefinitionHolder> nestedBeanStack) {
310 if (isBeanDefinitionValue(propertyValue)) {
311 String beanName = getBeanName(propertyValue);
312 BeanDefinition beanDefinition = getBeanDefinition(propertyValue);
313
314 processNestedBeanDefinition(beanName, beanDefinition, propertyName, false, nestedBeanStack);
315 } else if (isCollectionValue(propertyValue)) {
316 visitCollection(propertyValue, propertyName, nestedBeanStack);
317 }
318
319 return propertyValue;
320 }
321
322
323
324
325
326
327
328
329 protected void visitCollection(Object value, String propertyName, Stack<BeanDefinitionHolder> nestedBeanStack) {
330 if (value instanceof Object[] || (value instanceof ManagedArray)) {
331 visitArray(value, propertyName, nestedBeanStack);
332 } else if (value instanceof List) {
333 visitList((List<?>) value, propertyName, nestedBeanStack);
334 } else if (value instanceof Set) {
335 visitSet((Set<?>) value, propertyName, nestedBeanStack);
336 } else if (value instanceof Map) {
337 visitMap((Map<?, ?>) value, propertyName, nestedBeanStack);
338 }
339 }
340
341
342
343
344
345
346
347
348 protected void visitArray(Object array, String propertyName, Stack<BeanDefinitionHolder> nestedBeanStack) {
349 Object[] arrayVal = null;
350 if (array instanceof ManagedArray) {
351 arrayVal = (Object[]) ((ManagedArray) array).getSource();
352 } else {
353 arrayVal = (Object[]) array;
354 }
355
356 Object[] newArray = new Object[arrayVal.length];
357 for (int i = 0; i < arrayVal.length; i++) {
358 Object elem = arrayVal[i];
359
360 if (isStringValue(elem)) {
361 elem = processArrayStringPropertyValue(propertyName, arrayVal, getString(elem), i, nestedBeanStack,
362 beanProcessors);
363 } else {
364 elem = visitPropertyValue(propertyName, elem, nestedBeanStack);
365 }
366
367 newArray[i] = elem;
368 }
369
370 if (array instanceof ManagedArray) {
371 ((ManagedArray) array).setSource(newArray);
372 } else {
373 array = newArray;
374 }
375 }
376
377
378
379
380
381
382
383
384 protected void visitList(List<?> listVal, String propertyName, Stack<BeanDefinitionHolder> nestedBeanStack) {
385 boolean isMergeEnabled = false;
386 if (listVal instanceof ManagedList) {
387 isMergeEnabled = ((ManagedList) listVal).isMergeEnabled();
388 }
389
390 ManagedList newList = new ManagedList();
391 newList.setMergeEnabled(isMergeEnabled);
392
393 for (int i = 0; i < listVal.size(); i++) {
394 Object elem = listVal.get(i);
395
396 if (isStringValue(elem)) {
397 elem = processListStringPropertyValue(propertyName, listVal, getString(elem), i, nestedBeanStack,
398 beanProcessors);
399 } else {
400 elem = visitPropertyValue(propertyName, elem, nestedBeanStack);
401 }
402
403 newList.add(i, elem);
404 }
405
406 listVal.clear();
407 listVal.addAll(newList);
408 }
409
410
411
412
413
414
415
416
417 protected void visitSet(Set setVal, String propertyName, Stack<BeanDefinitionHolder> nestedBeanStack) {
418 boolean isMergeEnabled = false;
419 if (setVal instanceof ManagedSet) {
420 isMergeEnabled = ((ManagedSet) setVal).isMergeEnabled();
421 }
422
423 ManagedSet newSet = new ManagedSet();
424 newSet.setMergeEnabled(isMergeEnabled);
425
426 for (Object elem : setVal) {
427 if (isStringValue(elem)) {
428 elem = processSetStringPropertyValue(propertyName, setVal, getString(elem), nestedBeanStack,
429 beanProcessors);
430 } else {
431 elem = visitPropertyValue(propertyName, elem, nestedBeanStack);
432 }
433
434 newSet.add(elem);
435 }
436
437 setVal.clear();
438 setVal.addAll(newSet);
439 }
440
441
442
443
444
445
446
447
448 protected void visitMap(Map<?, ?> mapVal, String propertyName, Stack<BeanDefinitionHolder> nestedBeanStack) {
449 boolean isMergeEnabled = false;
450 if (mapVal instanceof ManagedMap) {
451 isMergeEnabled = ((ManagedMap) mapVal).isMergeEnabled();
452 }
453
454 ManagedMap newMap = new ManagedMap();
455 newMap.setMergeEnabled(isMergeEnabled);
456
457 for (Map.Entry entry : mapVal.entrySet()) {
458 Object key = entry.getKey();
459 Object val = entry.getValue();
460
461 if (isStringValue(val)) {
462 val = processMapStringPropertyValue(propertyName, mapVal, getString(val), key, nestedBeanStack,
463 beanProcessors);
464 } else {
465 val = visitPropertyValue(propertyName, val, nestedBeanStack);
466 }
467
468 newMap.put(key, val);
469 }
470
471 mapVal.clear();
472 mapVal.putAll(newMap);
473 }
474
475
476
477
478
479
480
481 protected boolean isStringValue(Object value) {
482 boolean isString = false;
483
484 if (value instanceof TypedStringValue || (value instanceof String)) {
485 isString = true;
486 }
487
488 return isString;
489 }
490
491
492
493
494
495
496
497 protected String getString(Object value) {
498 String stringValue = null;
499
500 if (value instanceof TypedStringValue || (value instanceof String)) {
501 if (value instanceof TypedStringValue) {
502 TypedStringValue typedStringValue = (TypedStringValue) value;
503 stringValue = typedStringValue.getValue();
504 } else {
505 stringValue = (String) value;
506 }
507 }
508
509 return stringValue;
510 }
511
512
513
514
515
516
517
518 protected boolean isBeanDefinitionValue(Object value) {
519 boolean isBean = false;
520
521 if ((value instanceof BeanDefinition) || (value instanceof BeanDefinitionHolder)) {
522 isBean = true;
523 }
524
525 return isBean;
526 }
527
528
529
530
531
532
533
534 protected BeanDefinition getBeanDefinition(Object value) {
535 BeanDefinition beanDefinition = null;
536
537 if ((value instanceof BeanDefinition) || (value instanceof BeanDefinitionHolder)) {
538 if (value instanceof BeanDefinition) {
539 beanDefinition = (BeanDefinition) value;
540 } else {
541 beanDefinition = ((BeanDefinitionHolder) value).getBeanDefinition();
542 }
543 }
544
545 return beanDefinition;
546 }
547
548
549
550
551
552
553
554 protected String getBeanName(Object value) {
555 String beanName = null;
556
557 if (value instanceof BeanDefinitionHolder) {
558 beanName = ((BeanDefinitionHolder) value).getBeanName();
559 }
560
561 return beanName;
562 }
563
564
565
566
567
568
569
570 protected boolean isCollectionValue(Object value) {
571 boolean isCollection = false;
572
573 if (value instanceof Object[] || (value instanceof ManagedArray) || (value instanceof List) ||
574 (value instanceof Set) || (value instanceof Map)) {
575 isCollection = true;
576 }
577
578 return isCollection;
579 }
580
581
582
583
584
585
586 protected DataDictionaryService getDataDictionaryService() {
587 return KRADServiceLocatorWeb.getDataDictionaryService();
588 }
589
590 }