Coverage Report - org.trails.descriptor.ReflectionDescriptorFactory
 
Classes in this File Line Coverage Branch Coverage Complexity
ReflectionDescriptorFactory
74% 
100% 
0
 
 1  
 package org.trails.descriptor;
 2  
 
 3  
 import java.beans.BeanDescriptor;
 4  
 import java.beans.BeanInfo;
 5  
 import java.beans.Introspector;
 6  
 import java.beans.PropertyDescriptor;
 7  
 import java.lang.reflect.InvocationTargetException;
 8  
 import java.util.ArrayList;
 9  
 import java.util.List;
 10  
 
 11  
 import org.apache.commons.beanutils.BeanUtils;
 12  
 import org.apache.commons.logging.Log;
 13  
 import org.apache.commons.logging.LogFactory;
 14  
 import org.trails.component.Utils;
 15  
 
 16  
 /**
 17  
  * Generate descriptors using reflection on the underlying class.
 18  
  * ReflectionDescriptorFactory.buildClassDescriptor() is the only public method
 19  
  * here.
 20  
  */
 21  39
 public class ReflectionDescriptorFactory implements DescriptorFactory
 22  
 {
 23  1
         protected static final Log LOG = LogFactory.getLog(ReflectionDescriptorFactory.class);
 24  
 
 25  19
         private List propertyExcludes = new ArrayList();
 26  
 
 27  19
         private List methodExcludes = new ArrayList();
 28  
 
 29  
         /**
 30  
          * Given a type, build a property descriptor
 31  
          *
 32  
          * @param type The type to build for
 33  
          * @return a completed property descriptor
 34  
          */
 35  
         public IClassDescriptor buildClassDescriptor(Class type)
 36  
         {
 37  
                 try
 38  
                 {
 39  46
                         IClassDescriptor descriptor = new TrailsClassDescriptor(type);
 40  46
                         BeanInfo beanInfo = Introspector.getBeanInfo(type);
 41  46
                         BeanDescriptor beanDescriptor = beanInfo.getBeanDescriptor();
 42  
                         // Note there's various places and ways to uncamelcase the display name. However
 43  
                         // we don't want to un-camelcase the possibly customized displayName
 44  
                         // Also, because Introspector uses static methods, it's less clean to replace it 
 45  
                         // with a custom implementation. Proxy doesn't scale well and an aspect would 
 46  
                         // only work if it's run. So decided to deal with uncamelcasing displayname here
 47  46
                         beanDescriptor.setDisplayName(Utils.unCamelCase(beanDescriptor.getDisplayName()) );
 48  46
                         BeanUtils.copyProperties(descriptor, beanInfo.getBeanDescriptor());
 49  46
                         descriptor.setPropertyDescriptors(buildPropertyDescriptors(type,beanInfo, descriptor));
 50  46
                         return descriptor;
 51  
 
 52  0
                 } catch (IllegalAccessException e)
 53  
                 {
 54  0
                         LOG.error(e.getMessage());
 55  0
                         e.printStackTrace();
 56  0
                 } catch (InvocationTargetException e)
 57  
                 {
 58  0
                         LOG.error(e.getMessage());
 59  0
                         e.printStackTrace();
 60  0
                 } catch (Exception e)
 61  
                 {
 62  0
                         LOG.error(e.toString());
 63  0
                         e.printStackTrace();
 64  
                 }
 65  0
                 return null;
 66  
         }
 67  
 
 68  
         /**
 69  
          * Build the set of property descriptors for this type
 70  
          *
 71  
          * @param beanType                          the aggregating class
 72  
          * @param beanInfo                          the BeanInfo, already gathered
 73  
          * @param parentClassDescriptor reference to the aggregating class, used for recovery with
 74  
          *                              graph traversal
 75  
          * @return ObjectReferenceDescriptor if this property is an association,
 76  
          *         otherwise a TrailsPropertyDescriptor
 77  
          * @throws Exception
 78  
          */
 79  
         protected ArrayList<IPropertyDescriptor> buildPropertyDescriptors(
 80  
                 Class beanType, BeanInfo beanInfo,
 81  
                 IClassDescriptor parentClassDescriptor) throws Exception
 82  
         {
 83  46
                 ArrayList<IPropertyDescriptor> result = new ArrayList<IPropertyDescriptor>();
 84  249
                 for (PropertyDescriptor beanPropDescriptor : beanInfo.getPropertyDescriptors())
 85  
                 {
 86  203
                         if (!isExcluded(beanPropDescriptor.getName(), getPropertyExcludes()))
 87  
                         {
 88  195
                                 beanPropDescriptor.setDisplayName(Utils.unCamelCase(beanPropDescriptor.getDisplayName()) );
 89  
                                 
 90  
                                 TrailsPropertyDescriptor propDescriptor;
 91  195
                                 Class<?> propertyType = beanPropDescriptor.getPropertyType();
 92  195
                                 propDescriptor = new TrailsPropertyDescriptor(beanType,propertyType);
 93  195
                                 BeanUtils.copyProperties(propDescriptor, beanPropDescriptor);
 94  195
                                 TrailsPropertyDescriptor newPropertyDescriptor = propDescriptor;
 95  195
                                 result.add(newPropertyDescriptor);
 96  
                         }
 97  
                 }
 98  46
                 return result;
 99  
         }
 100  
 
 101  
         protected boolean isExcluded(String name, List excludes)
 102  
         {
 103  429
                 for (Object exclude1 : excludes)
 104  
                 {
 105  31
                         String exclude = (String) exclude1;
 106  
 
 107  31
                         if (name.matches(exclude))
 108  
                         {
 109  8
                                 return true;
 110  
                         }
 111  
                 }
 112  
 
 113  195
                 return false;
 114  
         }
 115  
 
 116  
         public List getMethodExcludes()
 117  
         {
 118  0
                 return methodExcludes;
 119  
         }
 120  
 
 121  
         public void setMethodExcludes(List methodExcludes)
 122  
         {
 123  4
                 this.methodExcludes = methodExcludes;
 124  4
         }
 125  
 
 126  
         public List getPropertyExcludes()
 127  
         {
 128  203
                 return propertyExcludes;
 129  
         }
 130  
 
 131  
         public void setPropertyExcludes(List propertyExcludes)
 132  
         {
 133  5
                 this.propertyExcludes = propertyExcludes;
 134  5
         }
 135  
 }