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