Coverage Report - org.apache.commons.betwixt.digester.MappedPropertyRule

Classes in this File Line Coverage Branch Coverage Complexity
MappedPropertyRule
70% 
86% 
8

 1  
 /*
 2  
  * Copyright 2001-2004 The Apache Software Foundation.
 3  
  * 
 4  
  * Licensed under the Apache 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.apache.org/licenses/LICENSE-2.0
 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  
 package org.apache.commons.betwixt.digester;
 17  
 
 18  
 import java.beans.BeanInfo;
 19  
 import java.beans.Introspector;
 20  
 import java.beans.PropertyDescriptor;
 21  
 
 22  
 import org.apache.commons.logging.Log;
 23  
 import org.apache.commons.logging.LogFactory;
 24  
 
 25  
 /** <p>Factors out common code used by Betwixt rules that access bean properties.
 26  
   * Maybe a lot of this should be moved into <code>BeanUtils</code>.</p>
 27  
   *
 28  
   * @author Robert Burrell Donkin
 29  
   * @since 0.5
 30  
   */
 31  604
 public abstract class MappedPropertyRule extends RuleSupport {
 32  
 
 33  
     /** Logger */
 34  604
     private static final Log log = LogFactory.getLog( MappedPropertyRule.class );   
 35  
      /** Classloader used to load classes by name */
 36  
     private ClassLoader classLoader;
 37  
     /** Base constructor */
 38  3248
     public MappedPropertyRule() {
 39  3248
         this.classLoader = getClass().getClassLoader();
 40  3248
     }
 41  
     
 42  
     
 43  
 
 44  
     // Implementation methods
 45  
     //-------------------------------------------------------------------------    
 46  
 
 47  
     /** 
 48  
      * Returns the property descriptor for the class and property name.
 49  
      * Note that some caching could be used to improve performance of 
 50  
      * this method. Or this method could be added to PropertyUtils.
 51  
      *
 52  
      * @param beanClass descriptor for property in this class
 53  
      * @param propertyName descriptor for property with this name
 54  
      * @return property descriptor for the named property in the given class 
 55  
      */
 56  
     protected PropertyDescriptor getPropertyDescriptor( Class beanClass, 
 57  
                                                         String propertyName ) {
 58  12894
         if ( beanClass != null && propertyName != null ) {
 59  8151
             if (log.isTraceEnabled()) {
 60  0
                 log.trace("Searching for property " + propertyName + " on " + beanClass);
 61  
             }
 62  
             try {
 63  
                 // TODO: replace this call to introspector to an object call
 64  
                 // which finds all property descriptors for a class
 65  
                 // this allows extra property descriptors to be added 
 66  
                 BeanInfo beanInfo;
 67  8151
                 if( getXMLIntrospector().getConfiguration().ignoreAllBeanInfo() ) {
 68  0
                     beanInfo = Introspector.getBeanInfo( beanClass, Introspector.IGNORE_ALL_BEANINFO );
 69  
                 }
 70  
                 else {
 71  8151
                     beanInfo = Introspector.getBeanInfo( beanClass );
 72  
                 }
 73  8151
                 PropertyDescriptor[] descriptors = 
 74  8151
                     beanInfo.getPropertyDescriptors();
 75  8151
                 if ( descriptors != null ) {
 76  34983
                     for ( int i = 0, size = descriptors.length; i < size; i++ ) {
 77  34931
                         PropertyDescriptor descriptor = descriptors[i];
 78  34931
                         if ( propertyName.equals( descriptor.getName() ) ) {
 79  8099
                             log.trace("Found matching method.");
 80  8099
                             return descriptor;
 81  
                         }
 82  
                     }
 83  
                 }
 84  
                 // for interfaces, check all super interfaces
 85  52
                 if (beanClass.isInterface()) {
 86  26
                     Class[] superinterfaces = beanClass.getInterfaces();
 87  26
                     for (int i=0, size=superinterfaces.length; i<size; i++) {
 88  26
                         PropertyDescriptor descriptor = getPropertyDescriptor(superinterfaces[i], propertyName);
 89  26
                         if (descriptor != null)
 90  
                         {
 91  26
                             return descriptor;
 92  
                         }
 93  
                     }
 94  
                 }
 95  
                 
 96  26
                 log.trace("No match found.");
 97  26
                 return null;
 98  0
             } catch (Exception e) {
 99  0
                 log.warn( "Caught introspection exception", e );
 100  
             }
 101  
         }
 102  4743
         return null;
 103  
     }
 104  
     
 105  
     
 106  
     /**
 107  
      * Gets the type of a property
 108  
      *
 109  
      * @param propertyClassName class name for property type (may be null)
 110  
      * @param beanClass class that has property 
 111  
      * @param propertyName the name of the property whose type is to be determined
 112  
      * @return property type 
 113  
      */
 114  
     protected Class getPropertyType( String propertyClassName, 
 115  
                                      Class beanClass, String propertyName ) {
 116  
         // XXX: should use a ClassLoader to handle 
 117  
         //      complex class loading situations
 118  8812
         if ( propertyClassName != null ) {
 119  
             try {
 120  0
                 Class answer = classLoader.loadClass(propertyClassName);
 121  0
                 if (answer != null) {
 122  0
                     if (log.isTraceEnabled()) {
 123  0
                         log.trace("Used specified type " + answer);
 124  
                     }
 125  0
                     return answer;
 126  
                 }
 127  0
             } catch (Exception e) {
 128  0
                 log.warn("Cannot load specified type", e);
 129  
             }
 130  
         }
 131  
         
 132  8812
         PropertyDescriptor descriptor = 
 133  8812
             getPropertyDescriptor( beanClass, propertyName );        
 134  8812
         if ( descriptor != null ) { 
 135  4056
             return descriptor.getPropertyType();
 136  
         }
 137  
         
 138  4756
         if (log.isTraceEnabled()) {
 139  0
             log.trace("Cannot find property type.");
 140  0
             log.trace("  className=" + propertyClassName 
 141  0
                         + " base=" + beanClass + " name=" + propertyName);
 142  
         }
 143  4756
         return null;            
 144  
     }
 145  
 }