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 }