1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.supercsv.util;
17
18 import java.lang.reflect.Method;
19 import java.util.HashMap;
20 import java.util.Map;
21
22 import org.supercsv.exception.SuperCsvReflectionException;
23
24
25
26
27
28
29
30 public final class ReflectionUtils {
31
32 public static final String SET_PREFIX = "set";
33 public static final String GET_PREFIX = "get";
34 public static final String IS_PREFIX = "is";
35
36
37
38
39 private static final Map<Class<?>, Class<?>> AUTOBOXING_CONVERTER = new HashMap<Class<?>, Class<?>>();
40 static {
41 AUTOBOXING_CONVERTER.put(long.class, Long.class);
42 AUTOBOXING_CONVERTER.put(Long.class, long.class);
43 AUTOBOXING_CONVERTER.put(int.class, Integer.class);
44 AUTOBOXING_CONVERTER.put(Integer.class, int.class);
45 AUTOBOXING_CONVERTER.put(char.class, Character.class);
46 AUTOBOXING_CONVERTER.put(Character.class, char.class);
47 AUTOBOXING_CONVERTER.put(byte.class, Byte.class);
48 AUTOBOXING_CONVERTER.put(Byte.class, byte.class);
49 AUTOBOXING_CONVERTER.put(short.class, Short.class);
50 AUTOBOXING_CONVERTER.put(Short.class, short.class);
51 AUTOBOXING_CONVERTER.put(boolean.class, Boolean.class);
52 AUTOBOXING_CONVERTER.put(Boolean.class, boolean.class);
53 AUTOBOXING_CONVERTER.put(double.class, Double.class);
54 AUTOBOXING_CONVERTER.put(Double.class, double.class);
55 AUTOBOXING_CONVERTER.put(float.class, Float.class);
56 AUTOBOXING_CONVERTER.put(Float.class, float.class);
57 }
58
59
60 private ReflectionUtils() {
61 }
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76 public static Method findGetter(final Object object, final String fieldName) {
77 if( object == null ) {
78 throw new NullPointerException("object should not be null");
79 } else if( fieldName == null ) {
80 throw new NullPointerException("fieldName should not be null");
81 }
82
83 final Class<?> clazz = object.getClass();
84
85
86 final String standardGetterName = getMethodNameForField(GET_PREFIX, fieldName);
87 Method getter = findGetterWithCompatibleReturnType(standardGetterName, clazz, false);
88
89
90 if( getter == null ) {
91 final String booleanGetterName = getMethodNameForField(IS_PREFIX, fieldName);
92 getter = findGetterWithCompatibleReturnType(booleanGetterName, clazz, true);
93 }
94
95 if( getter == null ) {
96 throw new SuperCsvReflectionException(
97 String
98 .format(
99 "unable to find getter for field %s in class %s - check that the corresponding nameMapping element matches the field name in the bean",
100 fieldName, clazz.getName()));
101 }
102
103 return getter;
104 }
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120 private static Method findGetterWithCompatibleReturnType(final String getterName, final Class<?> clazz,
121 final boolean enforceBooleanReturnType) {
122
123 for( final Method method : clazz.getMethods() ) {
124
125 if( !getterName.equalsIgnoreCase(method.getName()) || method.getParameterTypes().length != 0
126 || method.getReturnType().equals(void.class) ) {
127 continue;
128 }
129
130 if( !enforceBooleanReturnType || boolean.class.equals(method.getReturnType())
131 || Boolean.class.equals(method.getReturnType()) ) {
132 return method;
133 }
134
135 }
136
137 return null;
138 }
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162 public static Method findSetter(final Object object, final String fieldName, final Class<?> argumentType) {
163 if( object == null ) {
164 throw new NullPointerException("object should not be null");
165 } else if( fieldName == null ) {
166 throw new NullPointerException("fieldName should not be null");
167 } else if( argumentType == null ) {
168 throw new NullPointerException("argumentType should not be null");
169 }
170
171 final String setterName = getMethodNameForField(SET_PREFIX, fieldName);
172 final Class<?> clazz = object.getClass();
173
174
175 Method setter = findSetterWithCompatibleParamType(clazz, setterName, argumentType);
176
177
178 if( setter == null && AUTOBOXING_CONVERTER.containsKey(argumentType) ) {
179 setter = findSetterWithCompatibleParamType(clazz, setterName, AUTOBOXING_CONVERTER.get(argumentType));
180 }
181
182 if( setter == null ) {
183 throw new SuperCsvReflectionException(
184 String
185 .format(
186 "unable to find method %s(%s) in class %s - check that the corresponding nameMapping element matches the field name in the bean, "
187 + "and the cell processor returns a type compatible with the field", setterName,
188 argumentType.getName(), clazz.getName()));
189 }
190
191 return setter;
192 }
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208 private static Method findSetterWithCompatibleParamType(final Class<?> clazz, final String setterName,
209 final Class<?> argumentType) {
210
211 Method compatibleSetter = null;
212 for( final Method method : clazz.getMethods() ) {
213
214 if( !setterName.equalsIgnoreCase(method.getName()) || method.getParameterTypes().length != 1 ) {
215 continue;
216 }
217
218 final Class<?> parameterType = method.getParameterTypes()[0];
219 if( parameterType.equals(argumentType) ) {
220 compatibleSetter = method;
221 break;
222
223 } else if( parameterType.isAssignableFrom(argumentType) ) {
224 compatibleSetter = method;
225 }
226
227 }
228
229 return compatibleSetter;
230 }
231
232
233
234
235
236
237
238
239
240
241 private static String getMethodNameForField(final String prefix, final String fieldName) {
242 return prefix + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
243 }
244 }