1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package ch.elca.el4j.util.socketstatistics;
18
19 import java.lang.reflect.Constructor;
20 import java.lang.reflect.Field;
21 import java.lang.reflect.InvocationTargetException;
22 import java.lang.reflect.Method;
23
24
25
26
27
28
29
30
31
32
33 public class ReflectiveDelegator {
34
35
36
37
38 private final Object m_source;
39
40
41
42
43 private final Object m_delegate;
44
45
46
47
48 private final Class m_superclass;
49
50
51
52
53
54
55
56
57
58
59
60 public ReflectiveDelegator(Object source, Class superclass, Object delegate) {
61 this.m_source = source;
62 this.m_superclass = superclass;
63 this.m_delegate = delegate;
64 }
65
66
67
68
69
70
71
72
73
74
75
76 public ReflectiveDelegator(Object source, Class superclass, String delegateClassName) {
77 try {
78 this.m_source = source;
79 this.m_superclass = superclass;
80 Class implCl = Class.forName(delegateClassName);
81 Constructor delegateConstructor = implCl.getDeclaredConstructor();
82 delegateConstructor.setAccessible(true);
83 this.m_delegate = delegateConstructor.newInstance();
84 } catch (RuntimeException e) {
85 throw e;
86 } catch (Exception e) {
87 throw new DelegationException("Could not make delegate object", e);
88 }
89 }
90
91
92
93
94
95
96
97
98
99
100 public final <T> T invoke(Object... args) {
101 try {
102 String methodName = extractMethodName();
103 Method method = findMethod(methodName, args);
104 @SuppressWarnings("unchecked")
105 T t = (T) invoke0(method, args);
106 return t;
107 } catch (NoSuchMethodException e) {
108 throw new DelegationException(e);
109 }
110 }
111
112
113
114
115
116
117
118
119
120
121 private Object invoke0(Method method, Object[] args) {
122 try {
123 writeFields(m_superclass, m_source, m_delegate);
124 method.setAccessible(true);
125 Object result = method.invoke(m_delegate, args);
126 writeFields(m_superclass, m_delegate, m_source);
127 return result;
128 } catch (RuntimeException e) {
129 throw e;
130 } catch (InvocationTargetException e) {
131 throw new DelegationException(e.getCause());
132 } catch (Exception e) {
133 throw new DelegationException(e);
134 }
135 }
136
137
138
139
140
141
142
143 private void writeFields(Class clazz, Object from, Object to) throws Exception {
144 for (Field field : clazz.getDeclaredFields()) {
145 field.setAccessible(true);
146 field.set(to, field.get(from));
147 }
148 }
149
150
151
152
153
154
155 private String extractMethodName() {
156 Throwable t = new Throwable();
157 String methodName = t.getStackTrace()[2].getMethodName();
158 return methodName;
159 }
160
161
162
163
164
165
166
167
168
169
170
171
172 private Method findMethod(String methodName, Object[] args) throws NoSuchMethodException {
173 Class<?> clazz = m_superclass;
174 if (args.length == 0) {
175 return clazz.getDeclaredMethod(methodName);
176 }
177 Method match = null;
178
179 next: for (Method method : clazz.getDeclaredMethods()) {
180 if (method.getName().equals(methodName)) {
181 Class<?>[] classes = method.getParameterTypes();
182 if (classes.length == args.length) {
183 for (int i = 0; i < classes.length; i++) {
184 Class<?> argType = classes[i];
185 argType = convertPrimitiveClass(argType);
186 if (!argType.isInstance(args[i])) {
187 continue next;
188 }
189 }
190 if (match == null) {
191 match = method;
192 } else {
193 throw new DelegationException("Duplicate matches");
194 }
195 }
196 }
197 }
198 if (match != null) {
199 return match;
200 }
201
202
203 next: for (Method method : clazz.getMethods()) {
204 if (method.getName().equals(methodName)) {
205 Class<?>[] classes = method.getParameterTypes();
206 if (classes.length == args.length) {
207 for (int i = 0; i < classes.length; i++) {
208 Class<?> argType = classes[i];
209 argType = convertPrimitiveClass(argType);
210 if (!argType.isInstance(args[i])) {
211 continue next;
212 }
213 }
214 if (match == null) {
215 match = method;
216 } else {
217 throw new DelegationException("Duplicate matches");
218 }
219 }
220 }
221 }
222 if (match != null) {
223 return match;
224 }
225
226
227 throw new DelegationException("Could not find method: " + methodName);
228 }
229
230
231
232
233
234
235
236
237 private Class<?> convertPrimitiveClass(Class<?> primitive) {
238 if (primitive.isPrimitive()) {
239 if (primitive == int.class) {
240 return Integer.class;
241 }
242 if (primitive == boolean.class) {
243 return Boolean.class;
244 }
245 if (primitive == float.class) {
246 return Float.class;
247 }
248 if (primitive == long.class) {
249 return Long.class;
250 }
251 if (primitive == double.class) {
252 return Double.class;
253 }
254 if (primitive == short.class) {
255 return Short.class;
256 }
257 if (primitive == byte.class) {
258 return Byte.class;
259 }
260 if (primitive == char.class) {
261 return Character.class;
262 }
263 }
264 return primitive;
265 }
266
267
268
269
270
271
272
273
274
275
276 public DelegatorMethodFinder delegateTo(String methodName, Class<?>... parameters) {
277 return new DelegatorMethodFinder(methodName, parameters);
278 }
279
280
281
282
283 public class DelegatorMethodFinder {
284
285
286
287 private final Method method;
288
289
290
291
292
293
294
295
296
297 public DelegatorMethodFinder(String methodName, Class<?>... parameterTypes) {
298 try {
299 method = m_superclass.getDeclaredMethod(methodName, parameterTypes);
300 } catch (RuntimeException e) {
301 throw e;
302 } catch (Exception e) {
303 throw new DelegationException(e);
304 }
305 }
306
307
308
309
310
311
312
313
314
315
316 public <T> T invoke(Object... parameters) {
317 @SuppressWarnings("unchecked")
318 T t = (T) ReflectiveDelegator.this.invoke0(method, parameters);
319 return t;
320 }
321 }
322 }