Coverage Report - org.ini4j.spi.AbstractBeanInvocationHandler
 
Classes in this File Line Coverage Branch Coverage Complexity
AbstractBeanInvocationHandler
100%
83/83
98%
60/61
2.714
AbstractBeanInvocationHandler$1
100%
1/1
N/A
2.714
AbstractBeanInvocationHandler$Prefix
100%
21/21
100%
4/4
2.714
 
 1  
 /*
 2  
  * Copyright 2005,2009 Ivan SZKIBA
 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.ini4j.spi;
 17  
 
 18  
 import java.beans.Introspector;
 19  
 import java.beans.PropertyChangeListener;
 20  
 import java.beans.PropertyChangeSupport;
 21  
 import java.beans.PropertyVetoException;
 22  
 import java.beans.VetoableChangeListener;
 23  
 import java.beans.VetoableChangeSupport;
 24  
 
 25  
 import java.lang.reflect.Array;
 26  
 import java.lang.reflect.InvocationHandler;
 27  
 import java.lang.reflect.Method;
 28  
 
 29  213
 public abstract class AbstractBeanInvocationHandler implements InvocationHandler
 30  
 {
 31  
     private static final String PROPERTY_CHANGE_LISTENER = "PropertyChangeListener";
 32  
     private static final String VETOABLE_CHANGE_LISTENER = "VetoableChangeListener";
 33  
     private static final String ADD_PREFIX = "add";
 34  
     private static final String READ_PREFIX = "get";
 35  
     private static final String REMOVE_PREFIX = "remove";
 36  
     private static final String READ_BOOLEAN_PREFIX = "is";
 37  
     private static final String WRITE_PREFIX = "set";
 38  
     private static final String HAS_PREFIX = "has";
 39  
 
 40  213
     private static enum Prefix
 41  
     {
 42  1
         READ(READ_PREFIX),
 43  1
         READ_BOOLEAN(READ_BOOLEAN_PREFIX),
 44  1
         WRITE(WRITE_PREFIX),
 45  1
         ADD_CHANGE(ADD_PREFIX + PROPERTY_CHANGE_LISTENER),
 46  1
         ADD_VETO(ADD_PREFIX + VETOABLE_CHANGE_LISTENER),
 47  1
         REMOVE_CHANGE(REMOVE_PREFIX + PROPERTY_CHANGE_LISTENER),
 48  1
         REMOVE_VETO(REMOVE_PREFIX + VETOABLE_CHANGE_LISTENER),
 49  1
         HAS(HAS_PREFIX);
 50  
         private int _len;
 51  
         private String _value;
 52  
 
 53  
         private Prefix(String value)
 54  8
         {
 55  8
             _value = value;
 56  8
             _len = value.length();
 57  8
         }
 58  
 
 59  
         public static Prefix parse(String str)
 60  
         {
 61  1961
             Prefix ret = null;
 62  
 
 63  7456
             for (Prefix p : values())
 64  
             {
 65  7453
                 if (str.startsWith(p.getValue()))
 66  
                 {
 67  1958
                     ret = p;
 68  
 
 69  1958
                     break;
 70  
                 }
 71  
             }
 72  
 
 73  1961
             return ret;
 74  
         }
 75  
 
 76  
         public String getTail(String input)
 77  
         {
 78  3790
             return Introspector.decapitalize(input.substring(_len));
 79  
         }
 80  
 
 81  
         public String getValue()
 82  
         {
 83  7453
             return _value;
 84  
         }
 85  
     }
 86  
 
 87  
     private PropertyChangeSupport _pcSupport;
 88  
     private Object _proxy;
 89  
     private VetoableChangeSupport _vcSupport;
 90  
 
 91  
     @Override public Object invoke(Object proxy, Method method, Object[] args) throws PropertyVetoException
 92  
     {
 93  1961
         Object ret = null;
 94  1961
         Prefix prefix = Prefix.parse(method.getName());
 95  
 
 96  1961
         if (prefix != null)
 97  
         {
 98  1958
             String tail = prefix.getTail(method.getName());
 99  
 
 100  1958
             updateProxy(proxy);
 101  1958
             switch (prefix)
 102  
             {
 103  
 
 104  
                 case READ:
 105  1092
                     ret = getProperty(prefix.getTail(method.getName()), method.getReturnType());
 106  1092
                     break;
 107  
 
 108  
                 case READ_BOOLEAN:
 109  1
                     ret = getProperty(prefix.getTail(method.getName()), method.getReturnType());
 110  1
                     break;
 111  
 
 112  
                 case WRITE:
 113  109
                     setProperty(tail, args[0], method.getParameterTypes()[0]);
 114  108
                     break;
 115  
 
 116  
                 case HAS:
 117  739
                     ret = Boolean.valueOf(hasProperty(prefix.getTail(method.getName())));
 118  739
                     break;
 119  
 
 120  
                 case ADD_CHANGE:
 121  4
                     addPropertyChangeListener((String) args[0], (PropertyChangeListener) args[1]);
 122  4
                     break;
 123  
 
 124  
                 case ADD_VETO:
 125  3
                     addVetoableChangeListener((String) args[0], (VetoableChangeListener) args[1]);
 126  3
                     break;
 127  
 
 128  
                 case REMOVE_CHANGE:
 129  5
                     removePropertyChangeListener((String) args[0], (PropertyChangeListener) args[1]);
 130  5
                     break;
 131  
 
 132  
                 case REMOVE_VETO:
 133  5
                     removeVetoableChangeListener((String) args[0], (VetoableChangeListener) args[1]);
 134  5
                     break;
 135  
 
 136  
                 default:
 137  
                     break;
 138  
             }
 139  
         }
 140  
 
 141  1960
         return ret;
 142  
     }
 143  
 
 144  
     protected abstract Object getPropertySpi(String property, Class<?> clazz);
 145  
 
 146  
     protected abstract void setPropertySpi(String property, Object value, Class<?> clazz);
 147  
 
 148  
     protected abstract boolean hasPropertySpi(String property);
 149  
 
 150  
     protected synchronized Object getProperty(String property, Class<?> clazz)
 151  
     {
 152  
         Object o;
 153  
 
 154  
         try
 155  
         {
 156  1102
             o = getPropertySpi(property, clazz);
 157  1102
             if (o == null)
 158  
             {
 159  7
                 o = zero(clazz);
 160  
             }
 161  1095
             else if (clazz.isArray() && (o instanceof String[]) && !clazz.equals(String[].class))
 162  
             {
 163  10
                 String[] str = (String[]) o;
 164  
 
 165  10
                 o = Array.newInstance(clazz.getComponentType(), str.length);
 166  38
                 for (int i = 0; i < str.length; i++)
 167  
                 {
 168  28
                     Array.set(o, i, parse(str[i], clazz.getComponentType()));
 169  
                 }
 170  10
             }
 171  1085
             else if ((o instanceof String) && !clazz.equals(String.class))
 172  
             {
 173  764
                 o = parse((String) o, clazz);
 174  
             }
 175  
         }
 176  1
         catch (Exception x)
 177  
         {
 178  1
             o = zero(clazz);
 179  1101
         }
 180  
 
 181  1102
         return o;
 182  
     }
 183  
 
 184  
     protected synchronized void setProperty(String property, Object value, Class<?> clazz) throws PropertyVetoException
 185  
     {
 186  110
         boolean pc = (_pcSupport != null) && _pcSupport.hasListeners(property);
 187  110
         boolean vc = (_vcSupport != null) && _vcSupport.hasListeners(property);
 188  110
         Object oldVal = null;
 189  110
         Object newVal = ((value != null) && clazz.equals(String.class) && !(value instanceof String)) ? value.toString() : value;
 190  
 
 191  110
         if (pc || vc)
 192  
         {
 193  5
             oldVal = getProperty(property, clazz);
 194  
         }
 195  
 
 196  110
         if (vc)
 197  
         {
 198  2
             fireVetoableChange(property, oldVal, value);
 199  
         }
 200  
 
 201  109
         setPropertySpi(property, newVal, clazz);
 202  109
         if (pc)
 203  
         {
 204  3
             firePropertyChange(property, oldVal, value);
 205  
         }
 206  109
     }
 207  
 
 208  
     protected synchronized Object getProxy()
 209  
     {
 210  2
         return _proxy;
 211  
     }
 212  
 
 213  
     protected synchronized void addPropertyChangeListener(String property, PropertyChangeListener listener)
 214  
     {
 215  4
         if (_pcSupport == null)
 216  
         {
 217  2
             _pcSupport = new PropertyChangeSupport(_proxy);
 218  
         }
 219  
 
 220  4
         _pcSupport.addPropertyChangeListener(property, listener);
 221  4
     }
 222  
 
 223  
     protected synchronized void addVetoableChangeListener(String property, VetoableChangeListener listener)
 224  
     {
 225  3
         if (_vcSupport == null)
 226  
         {
 227  1
             _vcSupport = new VetoableChangeSupport(_proxy);
 228  
         }
 229  
 
 230  3
         _vcSupport.addVetoableChangeListener(property, listener);
 231  3
     }
 232  
 
 233  
     protected synchronized void firePropertyChange(String property, Object oldValue, Object newValue)
 234  
     {
 235  4
         if (_pcSupport != null)
 236  
         {
 237  3
             _pcSupport.firePropertyChange(property, oldValue, newValue);
 238  
         }
 239  4
     }
 240  
 
 241  
     protected synchronized void fireVetoableChange(String property, Object oldValue, Object newValue) throws PropertyVetoException
 242  
     {
 243  3
         if (_vcSupport != null)
 244  
         {
 245  2
             _vcSupport.fireVetoableChange(property, oldValue, newValue);
 246  
         }
 247  2
     }
 248  
 
 249  
     protected synchronized boolean hasProperty(String property)
 250  
     {
 251  
         boolean ret;
 252  
 
 253  
         try
 254  
         {
 255  742
             ret = hasPropertySpi(property);
 256  
         }
 257  1
         catch (Exception x)
 258  
         {
 259  1
             ret = false;
 260  741
         }
 261  
 
 262  742
         return ret;
 263  
     }
 264  
 
 265  
     protected Object parse(String value, Class<?> clazz) throws IllegalArgumentException
 266  
     {
 267  792
         return BeanTool.getInstance().parse(value, clazz);
 268  
     }
 269  
 
 270  
     protected synchronized void removePropertyChangeListener(String property, PropertyChangeListener listener)
 271  
     {
 272  5
         if (_pcSupport != null)
 273  
         {
 274  4
             _pcSupport.removePropertyChangeListener(property, listener);
 275  
         }
 276  5
     }
 277  
 
 278  
     protected synchronized void removeVetoableChangeListener(String property, VetoableChangeListener listener)
 279  
     {
 280  5
         if (_vcSupport != null)
 281  
         {
 282  4
             _vcSupport.removeVetoableChangeListener(property, listener);
 283  
         }
 284  5
     }
 285  
 
 286  
     protected Object zero(Class<?> clazz)
 287  
     {
 288  8
         return BeanTool.getInstance().zero(clazz);
 289  
     }
 290  
 
 291  
     private synchronized void updateProxy(Object value)
 292  
     {
 293  1958
         if (_proxy == null)
 294  
         {
 295  205
             _proxy = value;
 296  
         }
 297  1958
     }
 298  
 }