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