Clover coverage report - PicoContainer - 1.0
Coverage timestamp: Sat Jun 5 2004 21:34:14 EDT
file stats: LOC: 134   Methods: 4
NCLOC: 97   Classes: 1
30 day Evaluation Version distributed via the Maven Jar Repository. Clover is not free. You have 30 days to evaluate it. Please visit http://www.thecortex.net/clover to obtain a licensed version of Clover
 
 Source file Conditionals Statements Methods TOTAL
BeanPropertyComponentAdapter.java 86.1% 94.2% 100% 91.3%
coverage coverage
 1   
 package org.picocontainer.defaults;
 2   
 
 3   
 import org.picocontainer.ComponentAdapter;
 4   
 import org.picocontainer.PicoInitializationException;
 5   
 import org.picocontainer.PicoIntrospectionException;
 6   
 
 7   
 import java.beans.BeanInfo;
 8   
 import java.beans.IntrospectionException;
 9   
 import java.beans.Introspector;
 10   
 import java.beans.PropertyDescriptor;
 11   
 import java.io.File;
 12   
 import java.lang.reflect.Method;
 13   
 import java.net.MalformedURLException;
 14   
 import java.net.URL;
 15   
 import java.util.HashMap;
 16   
 import java.util.Iterator;
 17   
 import java.util.Map;
 18   
 import java.util.Set;
 19   
 
 20   
 /**
 21   
  * Decorating component adapter that can be used to set additional properties
 22   
  * on a component. These properties must be managed manually by the user of the API,
 23   
  * and will not be managed by PicoContainer. This class is therefore <em>not</em>
 24   
  * the same as {@link SetterInjectionComponentAdapter}, which is a true Setter Injection adapter.
 25   
  * <p/>
 26   
  * This adapter is mostly handy for setting various primitive properties via setters.
 27   
  * <p/>
 28   
  * <em>
 29   
  * Note that this class doesn't cache instances. If you want caching,
 30   
  * use a {@link CachingComponentAdapter} around this one.
 31   
  * </em>
 32   
  *
 33   
  * @author Aslak Helles&oslash;y
 34   
  * @version $Revision: 1.7 $
 35   
  */
 36   
 public class BeanPropertyComponentAdapter extends DecoratingComponentAdapter {
 37   
     private Map properties;
 38   
     private PropertyDescriptor[] propertyDescriptors;
 39   
     private Map propertyDescriptorMap = new HashMap();
 40   
 
 41  9
     public BeanPropertyComponentAdapter(ComponentAdapter delegate) throws PicoInitializationException {
 42  9
         super(delegate);
 43   
 
 44  9
         try {
 45  9
             BeanInfo beanInfo = Introspector.getBeanInfo(delegate.getComponentImplementation());
 46  9
             propertyDescriptors = beanInfo.getPropertyDescriptors();
 47  9
             for (int i = 0; i < propertyDescriptors.length; i++) {
 48  23
                 PropertyDescriptor propertyDescriptor = propertyDescriptors[i];
 49  23
                 propertyDescriptorMap.put(propertyDescriptor.getName(), propertyDescriptor);
 50   
             }
 51   
         } catch (IntrospectionException e) {
 52   
             ///CLOVER:OFF
 53   
             throw new PicoInitializationException("Couldn't load BeanInfo for" + delegate.getComponentImplementation().getName(), e);
 54   
             ///CLOVER:ON
 55   
         }
 56   
     }
 57   
 
 58  5
     public Object getComponentInstance() throws PicoInitializationException, PicoIntrospectionException, AssignabilityRegistrationException, NotConcreteRegistrationException {
 59  5
         final Object componentInstance = super.getComponentInstance();
 60   
 
 61  5
         if (properties != null) {
 62  5
             Set propertyNames = properties.keySet();
 63  5
             for (Iterator iterator = propertyNames.iterator(); iterator.hasNext();) {
 64  14
                 final String propertyName = (String) iterator.next();
 65  14
                 final Object propertyValue = properties.get(propertyName);
 66  14
                 final PropertyDescriptor propertyDescriptor = (PropertyDescriptor) propertyDescriptorMap.get(propertyName);
 67  14
                 if (propertyDescriptor == null) {
 68  0
                     throw new PicoIntrospectionException("Unknown property '" + propertyName + "' in class " + componentInstance.getClass().getName() + " Existing properties:" + propertyDescriptorMap);
 69   
                 }
 70  14
                 Method setter = propertyDescriptor.getWriteMethod();
 71  14
                 if (setter == null) {
 72  0
                     throw new PicoInitializationException("There is no public setter method for property " + propertyName + " in " + componentInstance.getClass().getName() +
 73   
                             ". Setter: " + propertyDescriptor.getWriteMethod() +
 74   
                             ". Getter: " + propertyDescriptor.getReadMethod());
 75   
                 }
 76  14
                 try {
 77  14
                     setter.invoke(componentInstance, new Object[]{convertType(setter, propertyValue)});
 78   
                 } catch (final Exception e) {
 79  1
                     throw new PicoInitializationException("Failed to set property " + propertyName + " to " + propertyValue + ": " + e.getMessage(), e);
 80   
                 }
 81   
             }
 82   
         }
 83  4
         return componentInstance;
 84   
     }
 85   
 
 86  14
     private Object convertType(Method setter, Object propertyValue) throws MalformedURLException {
 87  14
         if (propertyValue == null) {
 88  0
             return null;
 89   
         }
 90  14
         Class type = setter.getParameterTypes()[0];
 91  14
         if (type.equals(Boolean.class) || type.equals(boolean.class)) {
 92  1
             return Boolean.valueOf(propertyValue.toString());
 93  13
         } else if (type.equals(Byte.class) || type.equals(byte.class)) {
 94  1
             return Byte.valueOf(propertyValue.toString());
 95  12
         } else if (type.equals(Short.class) || type.equals(short.class)) {
 96  1
             return Short.valueOf(propertyValue.toString());
 97  11
         } else if (type.equals(Integer.class) || type.equals(int.class)) {
 98  1
             return Integer.valueOf(propertyValue.toString());
 99  10
         } else if (type.equals(Long.class) || type.equals(long.class)) {
 100  1
             return Long.valueOf(propertyValue.toString());
 101  9
         } else if (type.equals(Float.class) || type.equals(float.class)) {
 102  1
             return Float.valueOf(propertyValue.toString());
 103  8
         } else if (type.equals(Double.class) || type.equals(double.class)) {
 104  1
             return Double.valueOf(propertyValue.toString());
 105  7
         } else if (type.equals(Character.class) || type.equals(char.class)) {
 106  1
             return new Character(propertyValue.toString().toCharArray()[0]);
 107  6
         } else if (File.class.isAssignableFrom(type)) {
 108  1
             return new File(propertyValue.toString());
 109  5
         } else if (URL.class.isAssignableFrom(type)) {
 110  1
             return new URL(propertyValue.toString());
 111   
         } else {
 112   
 
 113   
             // check if the propertyValue is a key of a component in the container
 114   
             // if so, the type of the component and the setters parameter type
 115   
             // have to be compatible
 116  4
             if (getContainer() != null) {
 117  1
                 Object component = getContainer().getComponentInstance(propertyValue);
 118  1
                 if (component != null && type.isAssignableFrom(component.getClass())) {
 119  1
                     return component;
 120   
                 }
 121   
             }
 122   
         }
 123  3
         return propertyValue;
 124   
     }
 125   
 
 126   
     /**
 127   
      * Sets the bean property values that should be set upon creation.
 128   
      *
 129   
      * @param properties bean properties
 130   
      */
 131  5
     public void setProperties(Map properties) {
 132  5
         this.properties = properties;
 133   
     }
 134   
 }