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.beanutils.PropertyUtils;
19 import org.apache.commons.collections.ListUtils;
20 import org.apache.commons.lang.ArrayUtils;
21 import org.apache.commons.lang.StringUtils;
22 import org.apache.commons.logging.Log;
23 import org.apache.commons.logging.LogFactory;
24 import org.kuali.rice.core.api.util.ClassLoaderUtils;
25 import org.kuali.rice.krad.bo.PersistableBusinessObjectExtension;
26 import org.kuali.rice.krad.datadictionary.exception.AttributeValidationException;
27 import org.kuali.rice.krad.datadictionary.exception.CompletionException;
28 import org.kuali.rice.krad.datadictionary.parse.StringListConverter;
29 import org.kuali.rice.krad.datadictionary.parse.StringMapConverter;
30 import org.kuali.rice.krad.datadictionary.uif.UifDictionaryIndex;
31 import org.kuali.rice.krad.service.KRADServiceLocator;
32 import org.kuali.rice.krad.service.PersistenceStructureService;
33 import org.kuali.rice.krad.uif.UifConstants.ViewType;
34 import org.kuali.rice.krad.uif.util.ComponentBeanPostProcessor;
35 import org.kuali.rice.krad.uif.util.UifBeanFactoryPostProcessor;
36 import org.kuali.rice.krad.uif.view.View;
37 import org.kuali.rice.krad.util.ObjectUtils;
38 import org.springframework.beans.PropertyValues;
39 import org.springframework.beans.factory.config.BeanPostProcessor;
40 import org.springframework.beans.factory.support.KualiDefaultListableBeanFactory;
41 import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
42 import org.springframework.context.expression.StandardBeanExpressionResolver;
43 import org.springframework.core.convert.support.GenericConversionService;
44 import org.springframework.core.io.DefaultResourceLoader;
45 import org.springframework.core.io.Resource;
46
47 import java.beans.PropertyDescriptor;
48 import java.io.File;
49 import java.io.IOException;
50 import java.util.ArrayList;
51 import java.util.Arrays;
52 import java.util.Collection;
53 import java.util.HashMap;
54 import java.util.List;
55 import java.util.Map;
56 import java.util.Set;
57 import java.util.TreeMap;
58
59
60
61
62
63
64
65 public class DataDictionary {
66 private static final Log LOG = LogFactory.getLog(DataDictionary.class);
67
68 protected static boolean validateEBOs = true;
69
70 protected KualiDefaultListableBeanFactory ddBeans = new KualiDefaultListableBeanFactory();
71 protected XmlBeanDefinitionReader xmlReader = new XmlBeanDefinitionReader(ddBeans);
72
73 protected DataDictionaryIndex ddIndex = new DataDictionaryIndex(ddBeans);
74 protected UifDictionaryIndex uifIndex = new UifDictionaryIndex(ddBeans);
75
76 protected DataDictionaryMapper ddMapper = new DataDictionaryIndexMapper();
77
78 protected Map<String, List<String>> moduleDictionaryFiles = new HashMap<String, List<String>>();
79 protected List<String> moduleLoadOrder = new ArrayList<String>();
80
81 protected ArrayList<String> beanValidationFiles = new ArrayList<String>();
82
83
84
85
86
87
88
89
90 public void parseDataDictionaryConfigurationFiles(boolean allowConcurrentValidation) {
91 setupProcessor(ddBeans);
92
93 loadDictionaryBeans(ddBeans, moduleDictionaryFiles, ddIndex, beanValidationFiles);
94
95 performDictionaryPostProcessing(allowConcurrentValidation);
96 }
97
98
99
100
101
102
103 public static void setupProcessor(KualiDefaultListableBeanFactory beans) {
104 try {
105
106 BeanPostProcessor idPostProcessor = ComponentBeanPostProcessor.class.newInstance();
107 beans.addBeanPostProcessor(idPostProcessor);
108 beans.setBeanExpressionResolver(new StandardBeanExpressionResolver());
109
110
111 GenericConversionService conversionService = new GenericConversionService();
112 conversionService.addConverter(new StringMapConverter());
113 conversionService.addConverter(new StringListConverter());
114
115 beans.setConversionService(conversionService);
116 } catch (Exception e1) {
117 throw new DataDictionaryException("Cannot create component decorator post processor: " + e1.getMessage(),
118 e1);
119 }
120 }
121
122
123
124
125
126
127
128
129
130 public void loadDictionaryBeans(KualiDefaultListableBeanFactory beans,
131 Map<String, List<String>> moduleDictionaryFiles, DataDictionaryIndex index,
132 ArrayList<String> validationFiles) {
133
134 LOG.info("Starting DD XML File Load");
135
136 List<String> allBeanNames = new ArrayList<String>();
137 for (String namespaceCode : moduleLoadOrder) {
138 List<String> moduleDictionaryLocations = moduleDictionaryFiles.get(namespaceCode);
139
140 XmlBeanDefinitionReader xmlReader = new XmlBeanDefinitionReader(beans);
141
142 String configFileLocationsArray[] = new String[moduleDictionaryLocations.size()];
143 configFileLocationsArray = moduleDictionaryLocations.toArray(configFileLocationsArray);
144 for (int i = 0; i < configFileLocationsArray.length; i++) {
145 validationFiles.add(configFileLocationsArray[i]);
146 }
147
148 try {
149 xmlReader.loadBeanDefinitions(configFileLocationsArray);
150
151
152
153 List<String> addedBeanNames = Arrays.asList(beans.getBeanDefinitionNames());
154 addedBeanNames = ListUtils.removeAll(addedBeanNames, allBeanNames);
155 index.addBeanNamesToNamespace(namespaceCode, addedBeanNames);
156
157 allBeanNames.addAll(addedBeanNames);
158 } catch (Exception e) {
159 throw new DataDictionaryException("Error loading bean definitions: " + e.getLocalizedMessage());
160 }
161 }
162
163 LOG.info("Completed DD XML File Load");
164 }
165
166
167
168
169
170
171
172 public void performDictionaryPostProcessing(boolean allowConcurrentValidation) {
173
174 DictionaryBeanFactoryPostProcessor dictionaryBeanPostProcessor = new DictionaryBeanFactoryPostProcessor(this,
175 ddBeans);
176 dictionaryBeanPostProcessor.postProcessBeanFactory();
177
178
179 UifBeanFactoryPostProcessor factoryPostProcessor = new UifBeanFactoryPostProcessor();
180 factoryPostProcessor.postProcessBeanFactory(ddBeans);
181
182 if (allowConcurrentValidation) {
183 Thread t = new Thread(ddIndex);
184 t.start();
185
186 Thread t2 = new Thread(uifIndex);
187 t2.start();
188 } else {
189 ddIndex.run();
190 uifIndex.run();
191 }
192 }
193
194 public void validateDD(boolean validateEbos) {
195 DataDictionary.validateEBOs = validateEbos;
196
197
198
199
200
201
202 Map<String, DataObjectEntry> doBeans = ddBeans.getBeansOfType(DataObjectEntry.class);
203 for (DataObjectEntry entry : doBeans.values()) {
204 entry.completeValidation();
205 }
206
207 Map<String, DocumentEntry> docBeans = ddBeans.getBeansOfType(DocumentEntry.class);
208 for (DocumentEntry entry : docBeans.values()) {
209 entry.completeValidation();
210 }
211 }
212
213 public void validateDD() {
214 validateDD(true);
215 }
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230 public void addConfigFileLocation(String namespaceCode, String location) throws IOException {
231
232 if (!moduleLoadOrder.contains(namespaceCode)) {
233 moduleLoadOrder.add(namespaceCode);
234 }
235
236 indexSource(namespaceCode, location);
237 }
238
239
240
241
242
243
244
245
246 protected void indexSource(String namespaceCode, String sourceName) throws IOException {
247 if (sourceName == null) {
248 throw new DataDictionaryException("Source Name given is null");
249 }
250
251 if (!sourceName.endsWith(".xml")) {
252 Resource resource = getFileResource(sourceName);
253 if (resource.exists()) {
254 try {
255 indexSource(namespaceCode, resource.getFile());
256 } catch (IOException e) {
257
258
259 LOG.debug("Skipped existing resource without absolute file path");
260 }
261 } else {
262 LOG.warn("Could not find " + sourceName);
263 throw new DataDictionaryException("DD Resource " + sourceName + " not found");
264 }
265 } else {
266 if (LOG.isDebugEnabled()) {
267 LOG.debug("adding sourceName " + sourceName + " ");
268 }
269
270 Resource resource = getFileResource(sourceName);
271 if (!resource.exists()) {
272 throw new DataDictionaryException("DD Resource " + sourceName + " not found");
273 }
274
275 addModuleDictionaryFile(namespaceCode, sourceName);
276 }
277 }
278
279 protected Resource getFileResource(String sourceName) {
280 DefaultResourceLoader resourceLoader = new DefaultResourceLoader(ClassLoaderUtils.getDefaultClassLoader());
281
282 return resourceLoader.getResource(sourceName);
283 }
284
285 protected void indexSource(String namespaceCode, File dir) {
286 for (File file : dir.listFiles()) {
287 if (file.isDirectory()) {
288 indexSource(namespaceCode, file);
289 } else if (file.getName().endsWith(".xml")) {
290 addModuleDictionaryFile(namespaceCode, "file:" + file.getAbsolutePath());
291 } else {
292 if (LOG.isDebugEnabled()) {
293 LOG.debug("Skipping non xml file " + file.getAbsolutePath() + " in DD load");
294 }
295 }
296 }
297 }
298
299
300
301
302
303
304
305 protected void addModuleDictionaryFile(String namespaceCode, String location) {
306 List<String> moduleFileLocations = new ArrayList<String>();
307 if (moduleDictionaryFiles.containsKey(namespaceCode)) {
308 moduleFileLocations = moduleDictionaryFiles.get(namespaceCode);
309 }
310 moduleFileLocations.add(location);
311
312 moduleDictionaryFiles.put(namespaceCode, moduleFileLocations);
313 }
314
315
316
317
318
319
320
321
322 public Map<String, List<String>> getModuleDictionaryFiles() {
323 return moduleDictionaryFiles;
324 }
325
326
327
328
329
330
331 public void setModuleDictionaryFiles(Map<String, List<String>> moduleDictionaryFiles) {
332 this.moduleDictionaryFiles = moduleDictionaryFiles;
333 }
334
335
336
337
338
339
340
341
342
343
344
345 public List<String> getModuleLoadOrder() {
346 return moduleLoadOrder;
347 }
348
349
350
351
352
353
354 public void setModuleLoadOrder(List<String> moduleLoadOrder) {
355 this.moduleLoadOrder = moduleLoadOrder;
356 }
357
358
359
360
361
362
363 public void setDataDictionaryMapper(DataDictionaryMapper mapper) {
364 this.ddMapper = mapper;
365 }
366
367
368
369
370
371 @Deprecated
372 public BusinessObjectEntry getBusinessObjectEntry(String className) {
373 return ddMapper.getBusinessObjectEntry(ddIndex, className);
374 }
375
376
377
378
379
380 public DataObjectEntry getDataObjectEntry(String className) {
381 return ddMapper.getDataObjectEntry(ddIndex, className);
382 }
383
384
385
386
387
388
389
390 public BusinessObjectEntry getBusinessObjectEntryForConcreteClass(String className) {
391 return ddMapper.getBusinessObjectEntryForConcreteClass(ddIndex, className);
392 }
393
394
395
396
397 public List<String> getBusinessObjectClassNames() {
398 return ddMapper.getBusinessObjectClassNames(ddIndex);
399 }
400
401
402
403
404 public Map<String, BusinessObjectEntry> getBusinessObjectEntries() {
405 return ddMapper.getBusinessObjectEntries(ddIndex);
406 }
407
408
409
410
411
412
413 public DataDictionaryEntry getDictionaryObjectEntry(String className) {
414 return ddMapper.getDictionaryObjectEntry(ddIndex, className);
415 }
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432 public DocumentEntry getDocumentEntry(String documentTypeDDKey) {
433 return ddMapper.getDocumentEntry(ddIndex, documentTypeDDKey);
434 }
435
436
437
438
439
440
441
442
443
444
445
446 public MaintenanceDocumentEntry getMaintenanceDocumentEntryForBusinessObjectClass(Class<?> businessObjectClass) {
447 return ddMapper.getMaintenanceDocumentEntryForBusinessObjectClass(ddIndex, businessObjectClass);
448 }
449
450 public Map<String, DocumentEntry> getDocumentEntries() {
451 return ddMapper.getDocumentEntries(ddIndex);
452 }
453
454
455
456
457
458
459
460 public View getViewById(String viewId) {
461 return ddMapper.getViewById(uifIndex, viewId);
462 }
463
464
465
466
467
468
469
470
471
472
473 public View getViewByTypeIndex(ViewType viewTypeName, Map<String, String> indexKey) {
474 return ddMapper.getViewByTypeIndex(uifIndex, viewTypeName, indexKey);
475 }
476
477
478
479
480
481
482
483
484
485
486 public boolean viewByTypeExist(ViewType viewTypeName, Map<String, String> indexKey) {
487 return ddMapper.viewByTypeExist(uifIndex, viewTypeName, indexKey);
488 }
489
490
491
492
493
494
495
496
497
498 public List<View> getViewsForType(ViewType viewTypeName) {
499 return ddMapper.getViewsForType(uifIndex, viewTypeName);
500 }
501
502
503
504
505
506
507
508 public Object getDictionaryObject(String beanName) {
509 return ddBeans.getBean(beanName);
510 }
511
512
513
514
515
516
517
518 public boolean containsDictionaryObject(String id) {
519 return ddBeans.containsBean(id);
520 }
521
522
523
524
525
526
527
528
529
530
531
532
533 public PropertyValues getViewPropertiesById(String viewId) {
534 return ddMapper.getViewPropertiesById(uifIndex, viewId);
535 }
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551 public PropertyValues getViewPropertiesByType(ViewType viewTypeName, Map<String, String> indexKey) {
552 return ddMapper.getViewPropertiesByType(uifIndex, viewTypeName, indexKey);
553 }
554
555
556
557
558
559
560
561 public List<String> getBeanNamesForNamespace(String namespaceCode) {
562 List<String> namespaceBeans = new ArrayList<String>();
563
564 Map<String, List<String>> dictionaryBeansByNamespace = ddIndex.getDictionaryBeansByNamespace();
565 if (dictionaryBeansByNamespace.containsKey(namespaceCode)) {
566 namespaceBeans = dictionaryBeansByNamespace.get(namespaceCode);
567 }
568
569 return namespaceBeans;
570 }
571
572
573
574
575
576
577
578 public String getNamespaceForBeanDefinition(String beanName) {
579 String beanNamespace = null;
580
581 Map<String, List<String>> dictionaryBeansByNamespace = ddIndex.getDictionaryBeansByNamespace();
582 for (Map.Entry<String, List<String>> moduleDefinitions : dictionaryBeansByNamespace.entrySet()) {
583 List<String> namespaceBeans = moduleDefinitions.getValue();
584 if (namespaceBeans.contains(beanName)) {
585 beanNamespace = moduleDefinitions.getKey();
586 break;
587 }
588 }
589
590 return beanNamespace;
591 }
592
593
594
595
596
597
598
599 public static boolean isPropertyOf(Class targetClass, String propertyName) {
600 if (targetClass == null) {
601 throw new IllegalArgumentException("invalid (null) targetClass");
602 }
603 if (StringUtils.isBlank(propertyName)) {
604 throw new IllegalArgumentException("invalid (blank) propertyName");
605 }
606
607 PropertyDescriptor propertyDescriptor = buildReadDescriptor(targetClass, propertyName);
608
609 boolean isPropertyOf = (propertyDescriptor != null);
610 return isPropertyOf;
611 }
612
613
614
615
616
617
618
619 public static boolean isCollectionPropertyOf(Class targetClass, String propertyName) {
620 boolean isCollectionPropertyOf = false;
621
622 PropertyDescriptor propertyDescriptor = buildReadDescriptor(targetClass, propertyName);
623 if (propertyDescriptor != null) {
624 Class clazz = propertyDescriptor.getPropertyType();
625
626 if ((clazz != null) && Collection.class.isAssignableFrom(clazz)) {
627 isCollectionPropertyOf = true;
628 }
629 }
630
631 return isCollectionPropertyOf;
632 }
633
634 public static PersistenceStructureService persistenceStructureService;
635
636
637
638
639 public static PersistenceStructureService getPersistenceStructureService() {
640 if (persistenceStructureService == null) {
641 persistenceStructureService = KRADServiceLocator.getPersistenceStructureService();
642 }
643 return persistenceStructureService;
644 }
645
646
647
648
649
650
651
652
653
654
655 public static Class getAttributeClass(Class boClass, String attributeName) {
656
657
658 if (!isPropertyOf(boClass, attributeName)) {
659 throw new AttributeValidationException(
660 "unable to find attribute '" + attributeName + "' in rootClass '" + boClass.getName() + "'");
661 }
662
663
664
665
666 if (boClass.isInterface()) {
667 return getAttributeClassWhenBOIsInterface(boClass, attributeName);
668 } else {
669 return getAttributeClassWhenBOIsClass(boClass, attributeName);
670 }
671
672 }
673
674
675
676
677
678
679
680
681 private static Class getAttributeClassWhenBOIsClass(Class boClass, String attributeName) {
682 Object boInstance;
683 try {
684 boInstance = boClass.newInstance();
685 } catch (Exception e) {
686 throw new RuntimeException("Unable to instantiate Data Object: " + boClass, e);
687 }
688
689
690 try {
691 return ObjectUtils.getPropertyType(boInstance, attributeName, getPersistenceStructureService());
692 } catch (Exception e) {
693 throw new RuntimeException(
694 "Unable to determine property type for: " + boClass.getName() + "." + attributeName, e);
695 }
696 }
697
698
699
700
701
702
703
704
705
706
707 private static Class getAttributeClassWhenBOIsInterface(Class boClass, String attributeName) {
708 if (boClass == null) {
709 throw new IllegalArgumentException("invalid (null) boClass");
710 }
711 if (StringUtils.isBlank(attributeName)) {
712 throw new IllegalArgumentException("invalid (blank) attributeName");
713 }
714
715 PropertyDescriptor propertyDescriptor = null;
716
717 String[] intermediateProperties = attributeName.split("\\.");
718 int lastLevel = intermediateProperties.length - 1;
719 Class currentClass = boClass;
720
721 for (int i = 0; i <= lastLevel; ++i) {
722
723 String currentPropertyName = intermediateProperties[i];
724 propertyDescriptor = buildSimpleReadDescriptor(currentClass, currentPropertyName);
725
726 if (propertyDescriptor != null) {
727
728 Class propertyType = propertyDescriptor.getPropertyType();
729 if (propertyType.equals(PersistableBusinessObjectExtension.class)) {
730 propertyType = getPersistenceStructureService().getBusinessObjectAttributeClass(currentClass,
731 currentPropertyName);
732 }
733 if (Collection.class.isAssignableFrom(propertyType)) {
734
735 throw new AttributeValidationException(
736 "Can't determine the Class of Collection elements because when the business object is an (possibly ExternalizableBusinessObject) interface.");
737 } else {
738 currentClass = propertyType;
739 }
740 } else {
741 throw new AttributeValidationException(
742 "Can't find getter method of " + boClass.getName() + " for property " + attributeName);
743 }
744 }
745 return currentClass;
746 }
747
748
749
750
751
752
753
754
755 public static Class getCollectionElementClass(Class boClass, String collectionName) {
756 if (boClass == null) {
757 throw new IllegalArgumentException("invalid (null) boClass");
758 }
759 if (StringUtils.isBlank(collectionName)) {
760 throw new IllegalArgumentException("invalid (blank) collectionName");
761 }
762
763 PropertyDescriptor propertyDescriptor = null;
764
765 String[] intermediateProperties = collectionName.split("\\.");
766 Class currentClass = boClass;
767
768 for (int i = 0; i < intermediateProperties.length; ++i) {
769
770 String currentPropertyName = intermediateProperties[i];
771 propertyDescriptor = buildSimpleReadDescriptor(currentClass, currentPropertyName);
772
773 if (propertyDescriptor != null) {
774
775 Class type = propertyDescriptor.getPropertyType();
776 if (Collection.class.isAssignableFrom(type)) {
777
778 if (getPersistenceStructureService().isPersistable(currentClass)) {
779
780 Map<String, Class> collectionClasses = new HashMap<String, Class>();
781 collectionClasses = getPersistenceStructureService().listCollectionObjectTypes(currentClass);
782 currentClass = collectionClasses.get(currentPropertyName);
783
784 } else {
785 throw new RuntimeException(
786 "Can't determine the Class of Collection elements because persistenceStructureService.isPersistable("
787 +
788 currentClass.getName()
789 +
790 ") returns false.");
791 }
792
793 } else {
794
795 currentClass = propertyDescriptor.getPropertyType();
796
797 }
798 }
799 }
800
801 return currentClass;
802 }
803
804 static private Map<String, Map<String, PropertyDescriptor>> cache =
805 new TreeMap<String, Map<String, PropertyDescriptor>>();
806
807
808
809
810
811
812 public static PropertyDescriptor buildReadDescriptor(Class propertyClass, String propertyName) {
813 if (propertyClass == null) {
814 throw new IllegalArgumentException("invalid (null) propertyClass");
815 }
816 if (StringUtils.isBlank(propertyName)) {
817 throw new IllegalArgumentException("invalid (blank) propertyName");
818 }
819
820 PropertyDescriptor propertyDescriptor = null;
821
822 String[] intermediateProperties = propertyName.split("\\.");
823 int lastLevel = intermediateProperties.length - 1;
824 Class currentClass = propertyClass;
825
826 for (int i = 0; i <= lastLevel; ++i) {
827
828 String currentPropertyName = intermediateProperties[i];
829 propertyDescriptor = buildSimpleReadDescriptor(currentClass, currentPropertyName);
830
831 if (i < lastLevel) {
832
833 if (propertyDescriptor != null) {
834
835 Class propertyType = propertyDescriptor.getPropertyType();
836 if (propertyType.equals(PersistableBusinessObjectExtension.class)) {
837 propertyType = getPersistenceStructureService().getBusinessObjectAttributeClass(currentClass,
838 currentPropertyName);
839 }
840 if (Collection.class.isAssignableFrom(propertyType)) {
841
842 if (getPersistenceStructureService().isPersistable(currentClass)) {
843
844 Map<String, Class> collectionClasses = new HashMap<String, Class>();
845 collectionClasses = getPersistenceStructureService().listCollectionObjectTypes(
846 currentClass);
847 currentClass = collectionClasses.get(currentPropertyName);
848
849 } else {
850
851 throw new RuntimeException(
852 "Can't determine the Class of Collection elements because persistenceStructureService.isPersistable("
853 +
854 currentClass.getName()
855 +
856 ") returns false.");
857
858 }
859
860 } else {
861
862 currentClass = propertyType;
863
864 }
865
866 }
867
868 }
869
870 }
871
872 return propertyDescriptor;
873 }
874
875
876
877
878
879
880 public static PropertyDescriptor buildSimpleReadDescriptor(Class propertyClass, String propertyName) {
881 if (propertyClass == null) {
882 throw new IllegalArgumentException("invalid (null) propertyClass");
883 }
884 if (StringUtils.isBlank(propertyName)) {
885 throw new IllegalArgumentException("invalid (blank) propertyName");
886 }
887
888 PropertyDescriptor p = null;
889
890
891 String propertyClassName = propertyClass.getName();
892 Map<String, PropertyDescriptor> m = cache.get(propertyClassName);
893 if (null != m) {
894 p = m.get(propertyName);
895 if (null != p) {
896 return p;
897 }
898 }
899
900
901
902
903
904 PropertyDescriptor[] descriptors = PropertyUtils.getPropertyDescriptors(propertyClass);
905 if (ArrayUtils.isNotEmpty(descriptors)) {
906 for (PropertyDescriptor descriptor : descriptors) {
907 if (descriptor.getName().equals(propertyName)) {
908 p = descriptor;
909 }
910 }
911 }
912
913
914 if (p != null) {
915 if (m == null) {
916 m = new TreeMap<String, PropertyDescriptor>();
917 cache.put(propertyClassName, m);
918 }
919 m.put(propertyName, p);
920 }
921
922 return p;
923 }
924
925 public Set<InactivationBlockingMetadata> getAllInactivationBlockingMetadatas(Class blockedClass) {
926 return ddMapper.getAllInactivationBlockingMetadatas(ddIndex, blockedClass);
927 }
928
929
930
931
932
933 public void performBeanOverrides() {
934 Collection<BeanOverride> beanOverrides = ddBeans.getBeansOfType(BeanOverride.class).values();
935
936 if (beanOverrides.isEmpty()) {
937 LOG.info("DataDictionary.performOverrides(): No beans to override");
938 }
939 for (BeanOverride beanOverride : beanOverrides) {
940
941 Object bean = ddBeans.getBean(beanOverride.getBeanName());
942 beanOverride.performOverride(bean);
943 LOG.info("DataDictionary.performOverrides(): Performing override on bean: " + bean.toString());
944 }
945 }
946
947 }