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
265
266 } catch (NoSuchFieldException e) {
267
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
328
329 } catch (NoSuchMethodException e) {
330
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 }