Clover coverage report - angkor - 0.4
Coverage timestamp: ti okt 15 2002 22:32:48 CEST
file stats: LOC: 325   Methods: 17
NCLOC: 282   Classes: 2
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
PropertySupport.java 62% 74,8% 76,5% 71,5%
 1   
 /*
 2   
  * Angkor Web Framework
 3   
  *
 4   
  * Distributable under LGPL license.
 5   
  * See terms of license at gnu.org.
 6   
  */
 7   
 
 8   
 package com.tirsen.angkor.beans;
 9   
 
 10   
 import com.tirsen.angkor.Debug;
 11   
 import org.apache.log4j.Category;
 12   
 
 13   
 import java.beans.IndexedPropertyDescriptor;
 14   
 import java.beans.IntrospectionException;
 15   
 import java.beans.Introspector;
 16   
 import java.beans.PropertyDescriptor;
 17   
 import java.beans.PropertyEditor;
 18   
 import java.beans.PropertyEditorManager;
 19   
 import java.lang.reflect.Array;
 20   
 import java.lang.reflect.InvocationTargetException;
 21   
 import java.util.AbstractList;
 22   
 import java.util.Collection;
 23   
 import java.util.Iterator;
 24   
 import java.util.List;
 25   
 
 26   
 /**
 27   
  *
 28   
  * <!-- $Id: PropertySupport.java,v 1.2 2002/10/09 21:37:37 tirsen Exp $ -->
 29   
  *
 30   
  * @author $Author: tirsen $
 31   
  * @version $Revision: 1.2 $
 32   
  */
 33   
 class PropertySupport
 34   
 {
 35   
     private static final Category logger = Debug.getCategory();
 36   
 
 37   
     private BeanModel beanModel;
 38   
     private PropertyDescriptor property;
 39   
     private Class propertyClass;
 40   
 
 41  6
     public PropertySupport(BeanModel proxy, String property, Class propertyClass)
 42   
     {
 43  6
         this.beanModel = proxy;
 44  6
         this.propertyClass = propertyClass;
 45  6
         this.property = findPropertyDescriptor(proxy.getObjectClass(), property);
 46   
     }
 47   
 
 48  6
     private static PropertyDescriptor findPropertyDescriptor(Class klass, String property)
 49   
     {
 50  6
         PropertyDescriptor[] properties;
 51  6
         try
 52   
         {
 53  6
             properties = Introspector.getBeanInfo(klass).getPropertyDescriptors();
 54   
         }
 55   
         catch (IntrospectionException e)
 56   
         {
 57  0
             throw new RuntimeException(e.getMessage());
 58   
         }
 59   
 
 60  6
         PropertyDescriptor propertyDesc = null;
 61  28
         for (int i = 0; i < properties.length; i++)
 62   
         {
 63  28
             if (properties[i].getName().equals(property))
 64   
             {
 65  6
                 propertyDesc = properties[i];
 66  6
                 break;
 67   
             }
 68   
         }
 69  0
         if (propertyDesc == null) throw new RuntimeException("No property " + property + " in bean of type " + klass.getName());
 70   
 
 71  6
         return propertyDesc;
 72   
     }
 73   
 
 74  101
     Object getBean()
 75   
     {
 76  101
         return beanModel.getBean();
 77   
     }
 78   
 
 79  64
     public Object getValue()
 80   
     {
 81  64
         Object bean = getBean();
 82  64
         try
 83   
         {
 84  64
             System.out.println("getPropertyDescriptor().getReadMethod() = " + getPropertyDescriptor().getReadMethod());
 85  64
             System.out.println("bean = " + bean);
 86  64
             return getPropertyDescriptor().getReadMethod().invoke(bean, null);
 87   
         }
 88   
         catch (IllegalAccessException e)
 89   
         {
 90  0
             throw new IllegalAccessError(e.getMessage());
 91   
         }
 92   
         catch (InvocationTargetException e)
 93   
         {
 94   
             // handle this better?
 95  0
             throw new RuntimeException(e.getMessage());
 96   
         }
 97   
     }
 98   
 
 99  0
     public boolean isReadOnly()
 100   
     {
 101  0
         return property.getWriteMethod() == null || getPropertyEditor() == null;
 102   
     }
 103   
 
 104  0
     public void setValue(Object value)
 105   
     {
 106  0
         if (isReadOnly()) throw new IllegalStateException("Trying to update a read-only property.");
 107  0
         try
 108   
         {
 109  0
             property.getWriteMethod().invoke(getBean(), new Object[]{value});
 110   
         }
 111   
         catch (IllegalAccessException e)
 112   
         {
 113  0
             throw new IllegalAccessError("Could not access property \"" + property.getName() + "\"." +
 114   
                     "Note: If you are using inner classes as models they need to be public.");
 115   
         }
 116   
         catch (InvocationTargetException e)
 117   
         {
 118   
             // handle this better?
 119  0
             throw new RuntimeException(e.getMessage());
 120   
         }
 121   
     }
 122   
 
 123  0
     public PropertyEditor getPropertyEditor()
 124   
     {
 125  0
         PropertyEditor editor = null;
 126   
 
 127  0
         Class editorClass = property.getPropertyEditorClass();
 128  0
         if (editorClass != null)
 129   
         {
 130  0
             try
 131   
             {
 132  0
                 editor = (PropertyEditor) editorClass.newInstance();
 133   
             }
 134   
             catch (InstantiationException ignore)
 135   
             {
 136   
             }
 137   
             catch (IllegalAccessException ignore)
 138   
             {
 139   
             }
 140   
         }
 141   
 
 142  0
         if (editor == null)
 143   
         {
 144  0
             editor = PropertyEditorManager.findEditor(getPropertyDescriptor().getPropertyType());
 145   
         }
 146   
 
 147  0
         return editor;
 148   
     }
 149   
 
 150  296
     public PropertyDescriptor getPropertyDescriptor()
 151   
     {
 152  296
         return property;
 153   
     }
 154   
 
 155   
     private class MultiValueList extends AbstractList
 156   
     {
 157  16
         public Object get(int index)
 158   
         {
 159  16
             return getValue(index);
 160   
         }
 161   
 
 162  0
         public int size()
 163   
         {
 164  0
             return PropertySupport.this.size();
 165   
         }
 166   
     }
 167   
 
 168  16
     public List getList()
 169   
     {
 170  16
         return new MultiValueList();
 171   
     }
 172   
 
 173  16
     public Object getValue(int index)
 174   
     {
 175  16
         PropertyDescriptor property = getPropertyDescriptor();
 176  3
         if (property instanceof IndexedPropertyDescriptor) return indexedGetValue(index);
 177  13
         Class type = property.getPropertyType();
 178  13
         Object value;
 179  13
         if (type.isArray())
 180   
         {
 181  4
             value = Array.get(getValue(), index);
 182   
         }
 183  9
         else if (List.class.isAssignableFrom(type))
 184   
         {
 185  3
             List list = (List) getValue();
 186  3
             value = list.get(index);
 187   
         }
 188  6
         else if (Iterator.class.isAssignableFrom(type))
 189   
         {
 190  3
             Iterator iterator = (Iterator) getValue();
 191  3
             value = getComponentFromIterator(iterator, index);
 192   
         }
 193  3
         else if (Collection.class.isAssignableFrom(type))
 194   
         {
 195  3
             Collection collection = (Collection) getValue();
 196  3
             Iterator iterator = collection.iterator();
 197  3
             value = getComponentFromIterator(iterator, index);
 198   
         }
 199   
         else
 200   
         {
 201  0
             throw new IllegalStateException("Unsupported type of multi-valued property: " + type.getName());
 202   
         }
 203  13
         return value;
 204   
     }
 205   
 
 206  6
     private Object getComponentFromIterator(Iterator iterator, int index)
 207   
     {
 208  6
         Object value;
 209  6
         value = null;
 210  6
         int currentIndex = 0;
 211  6
         while (currentIndex <= index)
 212   
         {
 213  6
             value = iterator.next();
 214  6
             currentIndex++;
 215   
         }
 216  0
         if (value == null) throw new IndexOutOfBoundsException("Property " + getPropertyDescriptor().getName() + " does not have value at index " + index);
 217  6
         return value;
 218   
     }
 219   
 
 220  37
     public Object indexedGetValue(int index)
 221   
     {
 222  37
         Object bean = getBean();
 223  37
         try
 224   
         {
 225  37
             System.out.println("getPropertyDescriptor().getReadMethod() = " + getPropertyDescriptor().getReadMethod());
 226  37
             System.out.println("bean = " + bean);
 227  37
             IndexedPropertyDescriptor property = (IndexedPropertyDescriptor) getPropertyDescriptor();
 228  37
             return property.getIndexedReadMethod().invoke(bean, new Object[]{new Integer(index)});
 229   
         }
 230   
         catch (IllegalAccessException e)
 231   
         {
 232  0
             throw new IllegalAccessError(e.getMessage());
 233   
         }
 234   
         catch (InvocationTargetException e)
 235   
         {
 236  12
             if (e.getTargetException() instanceof RuntimeException)
 237   
             {
 238  12
                 throw (RuntimeException) e.getTargetException();
 239   
             }
 240  0
             if (e.getTargetException() instanceof Error)
 241   
             {
 242  0
                 throw (Error) e.getTargetException();
 243   
             }
 244  0
             throw new RuntimeException(e.getMessage());
 245   
         }
 246   
     }
 247   
 
 248  12
     private int indexedSize()
 249   
     {
 250  12
         IndexedPropertyDescriptor descriptor = (IndexedPropertyDescriptor) getPropertyDescriptor();
 251  12
         int size = 0;
 252  12
         try
 253   
         {
 254  34
             while (size < Integer.MAX_VALUE)
 255   
             {
 256  34
                 indexedGetValue(size);
 257  22
                 size++;
 258   
             }
 259   
         }
 260   
         catch (IndexOutOfBoundsException expected)
 261   
         {
 262   
         }
 263  12
         return size;
 264   
     }
 265   
 
 266  63
     public int size()
 267   
     {
 268  63
         PropertyDescriptor property = getPropertyDescriptor();
 269  12
         if (property instanceof IndexedPropertyDescriptor) return indexedSize();
 270  51
         Class type = property.getPropertyType();
 271  51
         int size;
 272  51
         if (type.isArray())
 273   
         {
 274  15
             Object value = getValue();
 275  15
             if (value == null)
 276  0
                 return 0;
 277   
             else
 278  15
                 size = Array.getLength(value);
 279   
         }
 280  36
         else if (Collection.class.isAssignableFrom(type))
 281   
         {
 282  24
             Collection collection = (Collection) getValue();
 283  24
             size = collection.size();
 284   
         }
 285  12
         else if (Iterator.class.isAssignableFrom(type))
 286   
         {
 287  12
             Iterator iterator = (Iterator) getValue();
 288  12
             size = 0;
 289  12
             while (iterator.hasNext())
 290   
             {
 291  22
                 iterator.next();
 292  22
                 size++;
 293   
             }
 294   
         }
 295   
         else
 296   
         {
 297  0
             throw new IllegalStateException("Unsupported type of multi-valued property: " + type.getName());
 298   
         }
 299  51
         return size;
 300   
     }
 301   
 
 302  11
     public Class getComponentType()
 303   
     {
 304  11
         Class type;
 305  11
         if (propertyClass != null)
 306   
         {
 307  8
             type = propertyClass;
 308   
         }
 309   
         else
 310   
         {
 311  3
             type = getPropertyDescriptor().getPropertyType();
 312  3
             if (type.isArray())
 313   
             {
 314  3
                 type = type.getComponentType();
 315   
             }
 316  0
             else if (type == List.class)
 317   
             {
 318  0
                 throw new RuntimeException("Could not determine component type of " + property + " with type " + type + "." +
 319   
                         "You have to specify it manually.");
 320   
             }
 321   
         }
 322  11
         return type;
 323   
     }
 324   
 }
 325