Coverage Report - org.kuali.rice.kns.datadictionary.DataDictionary
 
Classes in this File Line Coverage Branch Coverage Complexity
DataDictionary
0%
0/215
0%
0/102
3.633
 
 1  
 /*
 2  
  * Copyright 2005-2007 The Kuali Foundation
 3  
  * 
 4  
  * Licensed under the Educational Community License, Version 2.0 (the "License");
 5  
  * you may not use this file except in compliance with the License.
 6  
  * You may obtain a copy of the License at
 7  
  * 
 8  
  * http://www.opensource.org/licenses/ecl2.php
 9  
  * 
 10  
  * Unless required by applicable law or agreed to in writing, software
 11  
  * distributed under the License is distributed on an "AS IS" BASIS,
 12  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13  
  * See the License for the specific language governing permissions and
 14  
  * limitations under the License.
 15  
  */
 16  
 
 17  
 package org.kuali.rice.kns.datadictionary;
 18  
 
 19  
 import java.beans.IntrospectionException;
 20  
 import java.beans.PropertyDescriptor;
 21  
 import java.io.File;
 22  
 import java.io.IOException;
 23  
 import java.util.ArrayList;
 24  
 import java.util.Collection;
 25  
 import java.util.Collections;
 26  
 import java.util.HashMap;
 27  
 import java.util.HashSet;
 28  
 import java.util.List;
 29  
 import java.util.Map;
 30  
 import java.util.Set;
 31  
 import java.util.TreeMap;
 32  
 
 33  
 import org.apache.commons.lang.StringUtils;
 34  
 import org.apache.commons.logging.Log;
 35  
 import org.apache.commons.logging.LogFactory;
 36  
 import org.kuali.rice.core.util.ClassLoaderUtils;
 37  
 import org.kuali.rice.kns.bo.BusinessObject;
 38  
 import org.kuali.rice.kns.bo.PersistableBusinessObjectExtension;
 39  
 import org.kuali.rice.kns.datadictionary.exception.AttributeValidationException;
 40  
 import org.kuali.rice.kns.datadictionary.exception.CompletionException;
 41  
 import org.kuali.rice.kns.service.KNSServiceLocator;
 42  
 import org.kuali.rice.kns.service.ModuleService;
 43  
 import org.kuali.rice.kns.service.PersistenceStructureService;
 44  
 import org.kuali.rice.kns.util.ObjectUtils;
 45  
 import org.springframework.beans.factory.support.DefaultListableBeanFactory;
 46  
 import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
 47  
 import org.springframework.core.io.DefaultResourceLoader;
 48  
 import org.springframework.core.io.Resource;
 49  
 
 50  
 /**
 51  
  * Collection of named BusinessObjectEntry objects, each of which contains
 52  
  * information relating to the display, validation, and general maintenance of a
 53  
  * BusinessObject.
 54  
  * 
 55  
  * 
 56  
  */
 57  
 public class DataDictionary {
 58  
 
 59  0
     private DefaultListableBeanFactory ddBeans = new DefaultListableBeanFactory();
 60  0
     private XmlBeanDefinitionReader xmlReader = new XmlBeanDefinitionReader(ddBeans);
 61  
 
 62  
         // logger
 63  0
         private static final Log LOG = LogFactory.getLog(DataDictionary.class);
 64  
 
 65  
         /**
 66  
          * The encapsulation of DataDictionary indices
 67  
          */
 68  0
         private DataDictionaryIndex ddIndex = new DataDictionaryIndex(ddBeans);
 69  
 
 70  
         /**
 71  
          * The DataDictionaryMapper
 72  
          * The default mapper simply consults the initialized indices
 73  
          * on workflow document type
 74  
          */
 75  0
         private DataDictionaryMapper ddMapper = new DataDictionaryIndexMapper();
 76  
 
 77  0
         private List<String> configFileLocations = new ArrayList<String>();
 78  
 
 79  0
     public DataDictionary() { }
 80  
     
 81  
         public List<String> getConfigFileLocations() {
 82  0
         return this.configFileLocations;
 83  
     }
 84  
 
 85  
     public void setConfigFileLocations(List<String> configFileLocations) {
 86  0
         this.configFileLocations = configFileLocations;
 87  0
     }
 88  
     
 89  
     public void addConfigFileLocation( String location ) throws IOException {
 90  0
         indexSource( location );
 91  0
     }
 92  
 
 93  
     /**
 94  
      * Sets the DataDictionaryMapper
 95  
      * @param mapper the datadictionary mapper
 96  
      */
 97  
     public void setDataDictionaryMapper(DataDictionaryMapper mapper) {
 98  0
             this.ddMapper = mapper;
 99  0
     }
 100  
     
 101  
     private void indexSource(String sourceName) throws IOException {        
 102  0
         if (sourceName == null) {
 103  0
             throw new DataDictionaryException("Source Name given is null");
 104  
         }
 105  
 
 106  0
         if (!sourceName.endsWith(".xml") ) {
 107  0
             Resource resource = getFileResource(sourceName);
 108  0
             if (resource.exists()) {
 109  0
                 indexSource(resource.getFile());
 110  
             } else {
 111  0
                 LOG.warn("Could not find " + sourceName);
 112  0
                 throw new DataDictionaryException("DD Resource " + sourceName + " not found");
 113  
             }
 114  0
         } else {
 115  0
             if ( LOG.isDebugEnabled() ) {
 116  0
                 LOG.debug("adding sourceName " + sourceName + " ");
 117  
             }
 118  0
             Resource resource = getFileResource(sourceName);
 119  0
             if (! resource.exists()) {
 120  0
                 throw new DataDictionaryException("DD Resource " + sourceName + " not found");  
 121  
             }
 122  0
             String indexName = sourceName.substring(sourceName.lastIndexOf("/") + 1, sourceName.indexOf(".xml"));
 123  0
             configFileLocations.add( sourceName );
 124  
         }
 125  0
     }    
 126  
 
 127  
     private Resource getFileResource(String sourceName) {
 128  0
         DefaultResourceLoader resourceLoader = new DefaultResourceLoader(ClassLoaderUtils.getDefaultClassLoader());
 129  0
         return resourceLoader.getResource(sourceName);
 130  
     }
 131  
 
 132  
     private void indexSource(File dir) {
 133  0
         for (File file : dir.listFiles()) {
 134  0
             if (file.isDirectory()) {
 135  0
                 indexSource(file);
 136  0
             } else if (file.getName().endsWith(".xml") ) {
 137  0
                 configFileLocations.add( "file:" + file.getAbsolutePath());
 138  
             } else {
 139  0
                 if ( LOG.isDebugEnabled() ) {
 140  0
                     LOG.debug("Skipping non xml file " + file.getAbsolutePath() + " in DD load");
 141  
                 }
 142  
             }
 143  
         }
 144  0
     }
 145  
     
 146  
     public void parseDataDictionaryConfigurationFiles( boolean allowConcurrentValidation ) {
 147  
         // expand configuration locations into files
 148  
 
 149  0
         LOG.info( "Starting DD XML File Load" );
 150  0
         String[] configFileLocationsArray = new String[configFileLocations.size()];
 151  0
         configFileLocationsArray = configFileLocations.toArray( configFileLocationsArray );
 152  0
         configFileLocations.clear(); // empty the list out so other items can be added
 153  
         try {
 154  0
             xmlReader.loadBeanDefinitions( configFileLocationsArray );
 155  0
         } catch (Exception e) {
 156  0
             LOG.error("Error loading bean definitions", e);
 157  0
             throw new DataDictionaryException("Error loading bean definitions: " + e.getLocalizedMessage());
 158  0
         }
 159  0
         LOG.info( "Completed DD XML File Load" );
 160  0
         if ( allowConcurrentValidation ) {
 161  0
             Thread t = new Thread(ddIndex);
 162  0
             t.start();
 163  0
         } else {
 164  0
             ddIndex.run();
 165  
         }
 166  0
     }
 167  
             
 168  0
     static boolean validateEBOs = true;
 169  
     
 170  
     public void validateDD( boolean validateEbos ) {
 171  0
             DataDictionary.validateEBOs = validateEbos;
 172  0
         Map<String,BusinessObjectEntry> boBeans = ddBeans.getBeansOfType(BusinessObjectEntry.class);
 173  0
         for ( BusinessObjectEntry entry : boBeans.values() ) {
 174  0
             entry.completeValidation();
 175  
         }
 176  0
         Map<String,DocumentEntry> docBeans = ddBeans.getBeansOfType(DocumentEntry.class);
 177  0
         for ( DocumentEntry entry : docBeans.values() ) {
 178  0
             entry.completeValidation();
 179  
         }
 180  0
     }
 181  
     
 182  
     public void validateDD() {
 183  0
             DataDictionary.validateEBOs = true;
 184  0
         Map<String,BusinessObjectEntry> boBeans = ddBeans.getBeansOfType(BusinessObjectEntry.class);
 185  0
         for ( BusinessObjectEntry entry : boBeans.values() ) {
 186  0
             entry.completeValidation();
 187  
         }
 188  0
         Map<String,DocumentEntry> docBeans = ddBeans.getBeansOfType(DocumentEntry.class);
 189  0
         for ( DocumentEntry entry : docBeans.values() ) {
 190  0
             entry.completeValidation();
 191  
         }
 192  0
     }
 193  
 
 194  
         /**
 195  
          * @param className
 196  
          * @return BusinessObjectEntry for the named class, or null if none exists
 197  
          */
 198  
         public BusinessObjectEntry getBusinessObjectEntry(String className ) {
 199  0
                 return ddMapper.getBusinessObjectEntry(ddIndex, className);
 200  
         }
 201  
 
 202  
         /**
 203  
          * This method gets the business object entry for a concrete class
 204  
          * 
 205  
          * @param className
 206  
          * @return
 207  
          */
 208  
         public BusinessObjectEntry getBusinessObjectEntryForConcreteClass(String className){
 209  0
                 return ddMapper.getBusinessObjectEntryForConcreteClass(ddIndex, className);
 210  
         }
 211  
         
 212  
         /**
 213  
          * @return List of businessObject classnames
 214  
          */
 215  
         public List<String> getBusinessObjectClassNames() {
 216  0
                 return ddMapper.getBusinessObjectClassNames(ddIndex);
 217  
         }
 218  
 
 219  
         /**
 220  
          * @return Map of (classname, BusinessObjectEntry) pairs
 221  
          */
 222  
         public Map<String, BusinessObjectEntry> getBusinessObjectEntries() {
 223  0
                 return ddMapper.getBusinessObjectEntries(ddIndex);
 224  
         }
 225  
 
 226  
         /**
 227  
          * @param className
 228  
          * @return DataDictionaryEntryBase for the named class, or null if none
 229  
          *         exists
 230  
          */
 231  
         public DataDictionaryEntry getDictionaryObjectEntry(String className) {
 232  0
                 return ddMapper.getDictionaryObjectEntry(ddIndex, className);
 233  
         }
 234  
 
 235  
         /**
 236  
          * Returns the KNS document entry for the given lookup key.  The documentTypeDDKey is interpreted
 237  
          * successively in the following ways until a mapping is found (or none if found):
 238  
          * <ol>
 239  
          * <li>KEW/workflow document type</li>
 240  
          * <li>business object class name</li>
 241  
          * <li>maintainable class name</li>
 242  
          * </ol>
 243  
          * This mapping is compiled when DataDictionary files are parsed on startup (or demand).  Currently this
 244  
          * means the mapping is static, and one-to-one (one KNS document maps directly to one and only
 245  
          * one key).
 246  
          * 
 247  
          * @param documentTypeDDKey the KEW/workflow document type name
 248  
          * @return the KNS DocumentEntry if it exists
 249  
          */
 250  
         public DocumentEntry getDocumentEntry(String documentTypeDDKey ) {
 251  0
                 return ddMapper.getDocumentEntry(ddIndex, documentTypeDDKey);
 252  
         }
 253  
 
 254  
         /**
 255  
          * Note: only MaintenanceDocuments are indexed by businessObject Class
 256  
          * 
 257  
          * This is a special case that is referenced in one location. Do we need
 258  
          * another map for this stuff??
 259  
          * 
 260  
          * @param businessObjectClass
 261  
          * @return DocumentEntry associated with the given Class, or null if there
 262  
          *         is none
 263  
          */
 264  
         public MaintenanceDocumentEntry getMaintenanceDocumentEntryForBusinessObjectClass(Class businessObjectClass) {
 265  0
                 return ddMapper.getMaintenanceDocumentEntryForBusinessObjectClass(ddIndex, businessObjectClass);
 266  
         }
 267  
 
 268  
         public Map<String, DocumentEntry> getDocumentEntries() {
 269  0
                 return ddMapper.getDocumentEntries(ddIndex);
 270  
         }
 271  
 
 272  
     /**
 273  
      * @param clazz
 274  
      * @param propertyName
 275  
      * @return true if the given propertyName names a property of the given class
 276  
      * @throws CompletionException if there is a problem accessing the named property on the given class
 277  
      */
 278  
     public static boolean isPropertyOf(Class targetClass, String propertyName) {
 279  0
         if (targetClass == null) {
 280  0
             throw new IllegalArgumentException("invalid (null) targetClass");
 281  
         }
 282  0
         if (StringUtils.isBlank(propertyName)) {
 283  0
             throw new IllegalArgumentException("invalid (blank) propertyName");
 284  
         }
 285  
 
 286  0
         PropertyDescriptor propertyDescriptor = buildReadDescriptor(targetClass, propertyName);
 287  
 
 288  0
         boolean isPropertyOf = (propertyDescriptor != null);
 289  0
         return isPropertyOf;
 290  
     }
 291  
 
 292  
     /**
 293  
      * @param clazz
 294  
      * @param propertyName
 295  
      * @return true if the given propertyName names a Collection property of the given class
 296  
      * @throws CompletionException if there is a problem accessing the named property on the given class
 297  
      */
 298  
     public static boolean isCollectionPropertyOf(Class targetClass, String propertyName) {
 299  0
         boolean isCollectionPropertyOf = false;
 300  
 
 301  0
         PropertyDescriptor propertyDescriptor = buildReadDescriptor(targetClass, propertyName);
 302  0
         if (propertyDescriptor != null) {
 303  0
             Class clazz = propertyDescriptor.getPropertyType();
 304  
 
 305  0
             if ((clazz != null) && Collection.class.isAssignableFrom(clazz)) {
 306  0
                 isCollectionPropertyOf = true;
 307  
             }
 308  
         }
 309  
 
 310  0
         return isCollectionPropertyOf;
 311  
     }
 312  
 
 313  
     public static PersistenceStructureService persistenceStructureService;
 314  
     
 315  
     /**
 316  
      * @return the persistenceStructureService
 317  
      */
 318  
     public static PersistenceStructureService getPersistenceStructureService() {
 319  0
         if ( persistenceStructureService == null ) {
 320  0
             persistenceStructureService = KNSServiceLocator.getPersistenceStructureService();
 321  
         }
 322  0
         return persistenceStructureService;
 323  
     }
 324  
     
 325  
     /**
 326  
      * This method determines the Class of the attributeName passed in. Null will be returned if the member is not available, or if
 327  
      * a reflection exception is thrown.
 328  
      * 
 329  
      * @param rootClass - Class that the attributeName property exists in.
 330  
      * @param attributeName - Name of the attribute you want a class for.
 331  
      * @return The Class of the attributeName, if the attribute exists on the rootClass. Null otherwise.
 332  
      */
 333  
     public static Class getAttributeClass(Class boClass, String attributeName) {
 334  
 
 335  
         // fail loudly if the attributeName isnt a member of rootClass
 336  0
         if (!isPropertyOf(boClass, attributeName)) {
 337  0
             throw new AttributeValidationException("unable to find attribute '" + attributeName + "' in rootClass '" + boClass.getName() + "'");
 338  
         }
 339  
 
 340  
             //Implementing Externalizable Business Object Services...
 341  
         //The boClass can be an interface, hence handling this separately, 
 342  
         //since the original method was throwing exception if the class could not be instantiated.
 343  0
         if(boClass.isInterface())
 344  0
                 return getAttributeClassWhenBOIsInterface(boClass, attributeName);
 345  
         else
 346  0
                 return getAttributeClassWhenBOIsClass(boClass, attributeName);                
 347  
 
 348  
     }
 349  
 
 350  
     /**
 351  
      * 
 352  
      * This method gets the property type of the given attributeName when the bo class is a concrete class
 353  
      * 
 354  
      * @param boClass
 355  
      * @param attributeName
 356  
      * @return
 357  
      */
 358  
     private static Class getAttributeClassWhenBOIsClass(Class boClass, String attributeName){
 359  
             BusinessObject boInstance;
 360  
         try {
 361  0
             boInstance = (BusinessObject) boClass.newInstance();
 362  0
         } catch (Exception e) {
 363  0
                 throw new RuntimeException("Unable to instantiate BO: " + boClass, e);
 364  0
         }
 365  
 
 366  
         // attempt to retrieve the class of the property
 367  
         try {
 368  0
             return ObjectUtils.getPropertyType(boInstance, attributeName, getPersistenceStructureService());
 369  0
         } catch (Exception e) {
 370  0
             throw new RuntimeException("Unable to determine property type for: " + boClass.getName() + "." + attributeName, e);
 371  
         }
 372  
     }
 373  
 
 374  
     /**
 375  
      * 
 376  
      * This method gets the property type of the given attributeName when the bo class is an interface
 377  
      * This method will also work if the bo class is not an interface, 
 378  
      * but that case requires special handling, hence a separate method getAttributeClassWhenBOIsClass 
 379  
      * 
 380  
      * @param boClass
 381  
      * @param attributeName
 382  
      * @return
 383  
      */
 384  
     private static Class getAttributeClassWhenBOIsInterface(Class boClass, String attributeName){
 385  0
         if (boClass == null) {
 386  0
             throw new IllegalArgumentException("invalid (null) boClass");
 387  
         }
 388  0
         if (StringUtils.isBlank(attributeName)) {
 389  0
             throw new IllegalArgumentException("invalid (blank) attributeName");
 390  
         }
 391  
 
 392  0
         PropertyDescriptor propertyDescriptor = null;
 393  
 
 394  0
         String[] intermediateProperties = attributeName.split("\\.");
 395  0
         int lastLevel = intermediateProperties.length - 1;
 396  0
         Class currentClass = boClass;
 397  
 
 398  0
         for (int i = 0; i <= lastLevel; ++i) {
 399  
 
 400  0
             String currentPropertyName = intermediateProperties[i];
 401  0
             propertyDescriptor = buildSimpleReadDescriptor(currentClass, currentPropertyName);
 402  
 
 403  0
             if (propertyDescriptor != null) {
 404  
 
 405  0
                 Class propertyType = propertyDescriptor.getPropertyType();
 406  0
                 if ( propertyType.equals( PersistableBusinessObjectExtension.class ) ) {
 407  0
                     propertyType = getPersistenceStructureService().getBusinessObjectAttributeClass( currentClass, currentPropertyName );                    
 408  
                 }
 409  0
                 if (Collection.class.isAssignableFrom(propertyType)) {
 410  
                         // TODO: determine property type using generics type definition
 411  0
                         throw new AttributeValidationException("Can't determine the Class of Collection elements because when the business object is an (possibly ExternalizableBusinessObject) interface.");
 412  
                 }
 413  
                 else {
 414  0
                     currentClass = propertyType;
 415  
                 }
 416  0
             }
 417  
             else {
 418  0
                     throw new AttributeValidationException("Can't find getter method of " + boClass.getName() + " for property " + attributeName);
 419  
             }
 420  
         }
 421  0
         return currentClass;
 422  
     }
 423  
     
 424  
     /**
 425  
      * This method determines the Class of the elements in the collectionName passed in.
 426  
      * 
 427  
      * @param boClass Class that the collectionName collection exists in.
 428  
      * @param collectionName the name of the collection you want the element class for
 429  
      * @return
 430  
      */
 431  
     public static Class getCollectionElementClass(Class boClass, String collectionName) {
 432  0
         if (boClass == null) {
 433  0
             throw new IllegalArgumentException("invalid (null) boClass");
 434  
         }
 435  0
         if (StringUtils.isBlank(collectionName)) {
 436  0
             throw new IllegalArgumentException("invalid (blank) collectionName");
 437  
         }
 438  
 
 439  0
         PropertyDescriptor propertyDescriptor = null;
 440  
 
 441  0
         String[] intermediateProperties = collectionName.split("\\.");
 442  0
         Class currentClass = boClass;
 443  
 
 444  0
         for (int i = 0; i <intermediateProperties.length; ++i) {
 445  
 
 446  0
             String currentPropertyName = intermediateProperties[i];
 447  0
             propertyDescriptor = buildSimpleReadDescriptor(currentClass, currentPropertyName);
 448  
 
 449  
 
 450  0
                 if (propertyDescriptor != null) {
 451  
 
 452  0
                     Class type = propertyDescriptor.getPropertyType();
 453  0
                     if (Collection.class.isAssignableFrom(type)) {
 454  
 
 455  0
                         if (getPersistenceStructureService().isPersistable(currentClass)) {
 456  
 
 457  0
                             Map<String, Class> collectionClasses = new HashMap<String, Class>();
 458  0
                             collectionClasses = getPersistenceStructureService().listCollectionObjectTypes(currentClass);
 459  0
                             currentClass = collectionClasses.get(currentPropertyName);
 460  
 
 461  0
                         }
 462  
                         else {
 463  0
                             throw new RuntimeException("Can't determine the Class of Collection elements because persistenceStructureService.isPersistable(" + currentClass.getName() + ") returns false.");
 464  
                         }
 465  
 
 466  
                     }
 467  
                     else {
 468  
 
 469  0
                         currentClass = propertyDescriptor.getPropertyType();
 470  
 
 471  
                     }
 472  
                 }
 473  
             }
 474  
 
 475  0
         return currentClass;
 476  
     }
 477  
 
 478  0
     static private Map<String, Map<String, PropertyDescriptor>> cache = new TreeMap<String, Map<String, PropertyDescriptor>>();
 479  
 
 480  
     /**
 481  
      * @param propertyClass
 482  
      * @param propertyName
 483  
      * @return PropertyDescriptor for the getter for the named property of the given class, if one exists.
 484  
      */
 485  
     public static PropertyDescriptor buildReadDescriptor(Class propertyClass, String propertyName) {
 486  0
         if (propertyClass == null) {
 487  0
             throw new IllegalArgumentException("invalid (null) propertyClass");
 488  
         }
 489  0
         if (StringUtils.isBlank(propertyName)) {
 490  0
             throw new IllegalArgumentException("invalid (blank) propertyName");
 491  
         }
 492  
 
 493  0
         PropertyDescriptor propertyDescriptor = null;
 494  
 
 495  0
         String[] intermediateProperties = propertyName.split("\\.");
 496  0
         int lastLevel = intermediateProperties.length - 1;
 497  0
         Class currentClass = propertyClass;
 498  
 
 499  0
         for (int i = 0; i <= lastLevel; ++i) {
 500  
 
 501  0
             String currentPropertyName = intermediateProperties[i];
 502  0
             propertyDescriptor = buildSimpleReadDescriptor(currentClass, currentPropertyName);
 503  
 
 504  0
             if (i < lastLevel) {
 505  
 
 506  0
                 if (propertyDescriptor != null) {
 507  
 
 508  0
                     Class propertyType = propertyDescriptor.getPropertyType();
 509  0
                     if ( propertyType.equals( PersistableBusinessObjectExtension.class ) ) {
 510  0
                         propertyType = getPersistenceStructureService().getBusinessObjectAttributeClass( currentClass, currentPropertyName );                    
 511  
                     }
 512  0
                     if (Collection.class.isAssignableFrom(propertyType)) {
 513  
 
 514  0
                         if (getPersistenceStructureService().isPersistable(currentClass)) {
 515  
 
 516  0
                             Map<String, Class> collectionClasses = new HashMap<String, Class>();
 517  0
                             collectionClasses = getPersistenceStructureService().listCollectionObjectTypes(currentClass);
 518  0
                             currentClass = collectionClasses.get(currentPropertyName);
 519  
 
 520  0
                         }
 521  
                         else {
 522  
 
 523  0
                             throw new RuntimeException("Can't determine the Class of Collection elements because persistenceStructureService.isPersistable(" + currentClass.getName() + ") returns false.");
 524  
 
 525  
                         }
 526  
 
 527  
                     }
 528  
                     else {
 529  
 
 530  0
                         currentClass = propertyType;
 531  
 
 532  
                     }
 533  
 
 534  
                 }
 535  
 
 536  
             }
 537  
 
 538  
         }
 539  
 
 540  0
         return propertyDescriptor;
 541  
     }
 542  
 
 543  
     /**
 544  
      * @param propertyClass
 545  
      * @param propertyName
 546  
      * @return PropertyDescriptor for the getter for the named property of the given class, if one exists.
 547  
      */
 548  
     public static PropertyDescriptor buildSimpleReadDescriptor(Class propertyClass, String propertyName) {
 549  0
         if (propertyClass == null) {
 550  0
             throw new IllegalArgumentException("invalid (null) propertyClass");
 551  
         }
 552  0
         if (StringUtils.isBlank(propertyName)) {
 553  0
             throw new IllegalArgumentException("invalid (blank) propertyName");
 554  
         }
 555  
 
 556  0
         PropertyDescriptor p = null;
 557  
 
 558  
         // check to see if we've cached this descriptor already. if yes, return true.
 559  0
         String propertyClassName = propertyClass.getName();
 560  0
         Map<String, PropertyDescriptor> m = cache.get(propertyClassName);
 561  0
         if (null != m) {
 562  0
             p = m.get(propertyName);
 563  0
             if (null != p) {
 564  0
                 return p;
 565  
             }
 566  
         }
 567  
 
 568  0
         String prefix = StringUtils.capitalize(propertyName);
 569  0
         String getName = "get" + prefix;
 570  0
         String isName = "is" + prefix;
 571  
 
 572  
         try {
 573  
 
 574  0
             p = new PropertyDescriptor(propertyName, propertyClass, getName, null);
 575  
 
 576  
         }
 577  0
         catch (IntrospectionException e) {
 578  
             try {
 579  
 
 580  0
                 p = new PropertyDescriptor(propertyName, propertyClass, isName, null);
 581  
 
 582  
             }
 583  0
             catch (IntrospectionException f) {
 584  
                 // ignore it
 585  0
             }
 586  0
         }
 587  
 
 588  
         // cache the property descriptor if we found it.
 589  0
         if (null != p) {
 590  
 
 591  0
             if (null == m) {
 592  
 
 593  0
                 m = new TreeMap<String, PropertyDescriptor>();
 594  0
                 cache.put(propertyClassName, m);
 595  
 
 596  
             }
 597  
 
 598  0
             m.put(propertyName, p);
 599  
 
 600  
         }
 601  
 
 602  0
         return p;
 603  
     }
 604  
 
 605  
     public Set<InactivationBlockingMetadata> getAllInactivationBlockingMetadatas(Class blockedClass) {
 606  0
             return ddMapper.getAllInactivationBlockingMetadatas(ddIndex, blockedClass);
 607  
     }
 608  
     
 609  
     /**
 610  
      * This method gathers beans of type BeanOverride and invokes each one's performOverride() method.
 611  
      */
 612  
     // KULRICE-4513
 613  
     public void performBeanOverrides()
 614  
     {
 615  0
             Collection<BeanOverride> beanOverrides = ddBeans.getBeansOfType(BeanOverride.class).values();
 616  
             
 617  0
             if (beanOverrides.isEmpty()){
 618  0
                     LOG.info("DataDictionary.performOverrides(): No beans to override");
 619  
             }
 620  0
                 for (BeanOverride beanOverride : beanOverrides) {
 621  
                         
 622  0
                         Object bean = ddBeans.getBean(beanOverride.getBeanName());
 623  0
                         beanOverride.performOverride(bean);
 624  0
                         LOG.info("DataDictionary.performOverrides(): Performing override on bean: " + bean.toString());
 625  0
                 }
 626  0
     }
 627  
 }