1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.proxy2.jdk;
19
20 import java.io.Serializable;
21 import java.lang.reflect.InvocationHandler;
22 import java.lang.reflect.InvocationTargetException;
23 import java.lang.reflect.Method;
24 import java.lang.reflect.Proxy;
25
26 import org.apache.commons.lang3.ArrayUtils;
27 import org.apache.commons.lang3.ObjectUtils;
28 import org.apache.commons.proxy2.Interceptor;
29 import org.apache.commons.proxy2.Invocation;
30 import org.apache.commons.proxy2.Invoker;
31 import org.apache.commons.proxy2.ObjectProvider;
32 import org.apache.commons.proxy2.ProxyUtils;
33 import org.apache.commons.proxy2.impl.AbstractProxyFactory;
34
35
36
37
38 public class JdkProxyFactory extends AbstractProxyFactory
39 {
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55 @Override
56 public <T> T createDelegatorProxy(ClassLoader classLoader, ObjectProvider<?> delegateProvider,
57 Class<?>... proxyClasses)
58 {
59 @SuppressWarnings("unchecked")
60 final T result = (T) Proxy.newProxyInstance(classLoader, proxyClasses, new DelegatorInvocationHandler(
61 delegateProvider));
62 return result;
63 }
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80 @Override
81 public <T> T createInterceptorProxy(ClassLoader classLoader, Object target, Interceptor interceptor,
82 Class<?>... proxyClasses)
83 {
84 @SuppressWarnings("unchecked")
85 final T result = (T) Proxy.newProxyInstance(classLoader, proxyClasses, new InterceptorInvocationHandler(target,
86 interceptor));
87 return result;
88 }
89
90
91
92
93
94
95
96
97
98
99
100
101 @Override
102 public <T> T createInvokerProxy(ClassLoader classLoader, Invoker invoker, Class<?>... proxyClasses)
103 {
104 @SuppressWarnings("unchecked")
105 final T result = (T) Proxy.newProxyInstance(classLoader, proxyClasses, new InvokerInvocationHandler(invoker));
106 return result;
107 }
108
109
110
111
112
113 private abstract static class AbstractInvocationHandler implements InvocationHandler, Serializable
114 {
115
116 private static final long serialVersionUID = 1L;
117
118 @Override
119 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
120 {
121 if (ProxyUtils.isHashCode(method))
122 {
123 return Integer.valueOf(System.identityHashCode(proxy));
124 }
125 else if (ProxyUtils.isEqualsMethod(method))
126 {
127 return Boolean.valueOf(proxy == args[0]);
128 }
129 else
130 {
131 return invokeImpl(proxy, method, args);
132 }
133 }
134
135 protected abstract Object invokeImpl(Object proxy, Method method, Object[] args) throws Throwable;
136 }
137
138 private static class DelegatorInvocationHandler extends AbstractInvocationHandler
139 {
140
141 private static final long serialVersionUID = 1L;
142
143 private final ObjectProvider<?> delegateProvider;
144
145 protected DelegatorInvocationHandler(ObjectProvider<?> delegateProvider)
146 {
147 this.delegateProvider = delegateProvider;
148 }
149
150 @Override
151 public Object invokeImpl(Object proxy, Method method, Object[] args) throws Throwable
152 {
153 try
154 {
155 return method.invoke(delegateProvider.getObject(), args);
156 }
157 catch (InvocationTargetException e)
158 {
159 throw e.getTargetException();
160 }
161 }
162 }
163
164 private static class InterceptorInvocationHandler extends AbstractInvocationHandler
165 {
166
167 private static final long serialVersionUID = 1L;
168
169 private final Object target;
170 private final Interceptor methodInterceptor;
171
172 public InterceptorInvocationHandler(Object target, Interceptor methodInterceptor)
173 {
174 this.target = target;
175 this.methodInterceptor = methodInterceptor;
176 }
177
178 @Override
179 public Object invokeImpl(Object proxy, Method method, Object[] args) throws Throwable
180 {
181 final ReflectionInvocation invocation = new ReflectionInvocation(proxy, target, method, args);
182 return methodInterceptor.intercept(invocation);
183 }
184 }
185
186 private static class InvokerInvocationHandler extends AbstractInvocationHandler
187 {
188
189 private static final long serialVersionUID = 1L;
190
191 private final Invoker invoker;
192
193 public InvokerInvocationHandler(Invoker invoker)
194 {
195 this.invoker = invoker;
196 }
197
198 @Override
199 public Object invokeImpl(Object proxy, Method method, Object[] args) throws Throwable
200 {
201 return invoker.invoke(proxy, method, args);
202 }
203 }
204
205 private static class ReflectionInvocation implements Invocation
206 {
207 private final Object proxy;
208 private final Object target;
209 private final Method method;
210 private final Object[] arguments;
211
212 public ReflectionInvocation(Object proxy, Object target, Method method, Object[] arguments)
213 {
214 this.proxy = proxy;
215 this.target = target;
216 this.method = method;
217 this.arguments = ObjectUtils.defaultIfNull(ArrayUtils.clone(arguments), ProxyUtils.EMPTY_ARGUMENTS);
218 }
219
220 @Override
221 public Object[] getArguments()
222 {
223 return arguments;
224 }
225
226 @Override
227 public Method getMethod()
228 {
229 return method;
230 }
231
232 @Override
233 public Object getProxy()
234 {
235 return proxy;
236 }
237
238 @Override
239 public Object proceed() throws Throwable
240 {
241 try
242 {
243 return method.invoke(target, arguments);
244 }
245 catch (InvocationTargetException e)
246 {
247 throw e.getTargetException();
248 }
249 }
250 }
251 }