View Javadoc

    1   package sharin.util;
    2
    3   import java.lang.reflect.Field;
    4   import java.lang.reflect.Method;
    5   import java.lang.reflect.Modifier;
    6   import java.util.HashMap;
    7   import java.util.Map;
    8
    9   public class PropertyUtils {
    10
    11      private static final Map<Class<?>, Object> defaultValueMap = new HashMap<Class<?>, Object>();
    12
    13      static {
    14          defaultValueMap.put(boolean.class, Boolean.FALSE);
    15          defaultValueMap.put(byte.class, new Byte((byte) 0));
    16          defaultValueMap.put(char.class, new Character((char) 0));
    17          defaultValueMap.put(double.class, new Double(0));
    18          defaultValueMap.put(float.class, new Float(0));
    19          defaultValueMap.put(int.class, new Integer(0));
    20          defaultValueMap.put(long.class, new Long(0));
    21          defaultValueMap.put(short.class, new Short((short) 0));
    22      }
    23
    24      public static Class<?> getSimplePropertyType(Class<?> clazz,
    25              String simpleName) {
    26
    27          Class<?> result = null;
    28          Field field = findField(clazz, simpleName);
    29
    30          if (field != null) {
    31              result = field.getType();
    32
    33          } else {
    34              Method getter = findGetter(clazz, simpleName);
    35
    36              if (getter != null) {
    37                  result = getter.getReturnType();
    38              }
    39          }
    40
    41          return result;
    42      }
    43
    44      @SuppressWarnings("unchecked")
    45      public static boolean hasSimpleProperty(Object object, String simpleName) {
    46
    47          if (object instanceof Map) {
    48              return ((Map) object).containsKey(simpleName);
    49          }
    50
    51          Field field = findField(object.getClass(), simpleName);
    52
    53          if (field != null) {
    54              return true;
    55          }
    56
    57          return findGetter(object.getClass(), simpleName) != null;
    58      }
    59
    60      @SuppressWarnings("unchecked")
    61      public static <T> T getSimplePropertyValue(Object object, String simpleName) {
    62
    63          if (object instanceof Map) {
    64              return (T) ((Map) object).get(simpleName);
    65          }
    66
    67          Field field = findField(object.getClass(), simpleName);
    68
    69          if (field != null) {
    70              return (T) ReflectUtils.get(field, object);
    71          }
    72
    73          Method getter = findGetter(object.getClass(), simpleName);
    74
    75          if (getter != null) {
    76              return (T) ReflectUtils.invoke(getter, object);
    77          }
    78
    79          return null;
    80      }
    81
    82      @SuppressWarnings("unchecked")
    83      public static void setSimplePropertyValue(Object object, String simpleName,
    84              Object value) {
    85
    86          if (object instanceof Map) {
    87              ((Map) object).put(simpleName, value);
    88          }
    89
    90          Field field = findField(object.getClass(), simpleName);
    91
    92          if (field != null) {
    93
    94              if (value == null) {
    95                  value = defaultValueMap.get(field.getType());
    96              }
    97
    98              ReflectUtils.set(field, object, value);
    99          }
    100
    101         Method setter = findSetter(object.getClass(), simpleName, value);
    102
    103         if (setter != null) {
    104
    105             if (value == null) {
    106                 value = defaultValueMap.get(setter.getParameterTypes()[0]);
    107             }
    108
    109             ReflectUtils.invoke(setter, object, value);
    110         }
    111     }
    112
    113     public static Class<?> getNestedPropertyType(Class<?> clazz,
    114             String nestedName) {
    115
    116         Class<?> result = null;
    117         int p = nestedName.indexOf('.');
    118
    119         if (p == -1) {
    120             result = getSimplePropertyType(clazz, nestedName);
    121
    122         } else {
    123             Class<?> child = getSimplePropertyType(clazz, nestedName.substring(
    124                     0, p));
    125
    126             if (child != null) {
    127                 result = getNestedPropertyType(child, nestedName
    128                         .substring(p + 1));
    129             }
    130         }
    131
    132         return result;
    133     }
    134
    135     @SuppressWarnings("unchecked")
    136     public static boolean hasNestedProperty(Object object, String nestedName) {
    137         int p = nestedName.indexOf('.');
    138
    139         if (p == -1) {
    140             return hasSimpleProperty(object, nestedName);
    141         }
    142
    143         if (object instanceof Map) {
    144
    145             if (((Map) object).containsKey(nestedName)) {
    146                 return true;
    147             }
    148         }
    149
    150         Object child = getSimplePropertyValue(object, nestedName
    151                 .substring(0, p));
    152
    153         if (child != null) {
    154             return hasNestedProperty(child, nestedName.substring(p + 1));
    155         }
    156
    157         return false;
    158     }
    159
    160     @SuppressWarnings("unchecked")
    161     public static <T> T getNestedPropertyValue(Object object, String nestedName) {
    162         int p = nestedName.indexOf('.');
    163
    164         if (p == -1) {
    165             return (T) getSimplePropertyValue(object, nestedName);
    166         }
    167
    168         if (object instanceof Map) {
    169             Map map = (Map) object;
    170             Object value = map.get(nestedName);
    171
    172             if (value != null) {
    173                 return (T) value;
    174             }
    175
    176             if (map.containsKey(nestedName)) {
    177                 return null;
    178             }
    179         }
    180
    181         Object child = getSimplePropertyValue(object, nestedName
    182                 .substring(0, p));
    183
    184         if (child != null) {
    185             return (T) getNestedPropertyValue(child, nestedName
    186                     .substring(p + 1));
    187         }
    188
    189         return null;
    190     }
    191
    192     @SuppressWarnings("unchecked")
    193     public static void setNestedPropertyValue(Object object, String nestedName,
    194             Object value) {
    195
    196         int p = nestedName.indexOf('.');
    197
    198         if (p == -1) {
    199             setSimplePropertyValue(object, nestedName, value);
    200             return;
    201         }
    202
    203         String childName = nestedName.substring(0, p);
    204
    205         if (object instanceof Map) {
    206             Map map = ((Map) object);
    207             Object child = map.get(childName);
    208
    209             if (child == null) {
    210
    211                 if (map.containsKey(nestedName)) {
    212                     map.put(nestedName, value);
    213                     return;
    214                 }
    215
    216                 child = new HashMap();
    217                 map.put(childName, child);
    218             }
    219
    220             if (child != null) {
    221                 setNestedPropertyValue(child, nestedName.substring(p + 1),
    222                         value);
    223             }
    224
    225             return;
    226         }
    227
    228         Object child = getSimplePropertyValue(object, childName);
    229
    230         if (child == null) {
    231             Class<?> childType = getSimplePropertyType(object.getClass(),
    232                     childName);
    233
    234             if (childType != null) {
    235
    236                 if (!Modifier.isAbstract(childType.getModifiers())) {
    237                     child = ReflectUtils.newInstance(childType);
    238
    239                 } else if (childType.equals(Map.class)) {
    240                     child = new HashMap();
    241                 }
    242             }
    243         }
    244
    245         if (child != null) {
    246             setSimplePropertyValue(object, childName, child);
    247             setNestedPropertyValue(child, nestedName.substring(p + 1), value);
    248         }
    249     }
    250
    251     private static Field findField(Class<?> clazz, String name) {
    252         Field result = null;
    253
    254         try {
    255             Field field = clazz.getField(name);
    256
    257             if (field != null) {
    258                 if (isInstancePublic(field.getModifiers())) {
    259                     result = field;
    260                 }
    261             }
    262
    263         } catch (SecurityException e) {
    264             /* do nothing */
    265
    266         } catch (NoSuchFieldException e) {
    267             /* do nothing */
    268         }
    269
    270         return result;
    271     }
    272
    273     private static Method findGetter(Class<?> clazz, String name) {
    274         String getterName = getAccessorName("get", name);
    275         return getAccessor(clazz, getterName);
    276     }
    277
    278     private static Method findSetter(Class<?> clazz, String name, Object value) {
    279         Method setter = null;
    280         String setterName = getAccessorName("set", name);
    281
    282         if (value != null) {
    283             setter = getAccessor(clazz, setterName, value.getClass());
    284         }
    285
    286         if (setter == null) {
    287
    288             for (Method method : clazz.getMethods()) {
    289
    290                 if (!isInstancePublic(method.getModifiers())) {
    291                     continue;
    292                 }
    293
    294                 if (method.getParameterTypes().length != 1) {
    295                     continue;
    296                 }
    297
    298                 if (method.getName().equals(setterName)) {
    299                     setter = method;
    300                     break;
    301                 }
    302             }
    303         }
    304
    305         return setter;
    306     }
    307
    308     private static String getAccessorName(String prefix, String name) {
    309         return prefix + Character.toUpperCase(name.charAt(0))
    310                 + name.substring(1);
    311     }
    312
    313     private static Method getAccessor(Class<?> clazz, String name,
    314             Class<?>... paramTypes) {
    315
    316         try {
    317             Method method = clazz.getMethod(name, paramTypes);
    318
    319             if (method != null) {
    320
    321                 if (isInstancePublic(method.getModifiers())) {
    322                     return method;
    323                 }
    324             }
    325
    326         } catch (SecurityException e) {
    327             /* do nothing */
    328
    329         } catch (NoSuchMethodException e) {
    330             /* do nothing */
    331         }
    332
    333         return null;
    334     }
    335
    336     private static boolean isInstancePublic(int modifiers) {
    337
    338         if (Modifier.isStatic(modifiers)) {
    339             return false;
    340         }
    341
    342         return Modifier.isPublic(modifiers);
    343     }
    344 }