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