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