1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.proxy2;
19
20 import static org.junit.Assert.assertEquals;
21 import static org.junit.Assert.assertFalse;
22 import static org.junit.Assert.assertNotNull;
23 import static org.junit.Assert.assertNotSame;
24 import static org.junit.Assert.assertSame;
25 import static org.junit.Assert.assertTrue;
26
27 import java.io.IOException;
28 import java.io.Serializable;
29 import java.lang.reflect.Method;
30 import java.util.Arrays;
31 import java.util.Date;
32 import java.util.Iterator;
33 import java.util.LinkedList;
34 import java.util.List;
35 import java.util.ServiceLoader;
36 import java.util.SortedSet;
37 import java.util.TreeSet;
38
39 import org.apache.commons.proxy2.provider.BeanProvider;
40 import org.apache.commons.proxy2.provider.ConstantProvider;
41 import org.apache.commons.proxy2.provider.SingletonProvider;
42 import org.apache.commons.proxy2.util.AbstractTestCase;
43 import org.apache.commons.proxy2.util.DuplicateEcho;
44 import org.apache.commons.proxy2.util.Echo;
45 import org.apache.commons.proxy2.util.EchoImpl;
46 import org.apache.commons.proxy2.util.SuffixInterceptor;
47 import org.junit.Test;
48
49 @SuppressWarnings("serial")
50 public abstract class AbstractProxyFactoryTestCase extends AbstractTestCase
51 {
52
53
54
55
56 private static final Class<?>[] ECHO_ONLY = new Class[] { Echo.class };
57 protected final ProxyFactory factory;
58 private static final Class<?>[] COMPARABLE_ONLY = new Class[] { Comparable.class };
59
60
61
62
63
64 protected AbstractProxyFactoryTestCase()
65 {
66 final ServiceLoader<ProxyFactory> serviceLoader = ServiceLoader.load(ProxyFactory.class);
67 Iterator<ProxyFactory> iter = serviceLoader.iterator();
68 if (iter.hasNext())
69 {
70 this.factory = iter.next();
71 }
72 else
73 {
74 throw new RuntimeException("Unable to find proxy factory implementation.");
75 }
76
77 }
78
79
80
81
82
83 private ObjectProvider<Echo> createSingletonEcho()
84 {
85 return new SingletonProvider<Echo>(new BeanProvider<Echo>(EchoImpl.class));
86 }
87
88 @Test
89 public void testInterceptorHashCode()
90 {
91 final Echo proxy = factory.createInterceptorProxy(new EchoImpl(), new NoOpMethodInterceptor(), ECHO_ONLY);
92 assertEquals(proxy.hashCode(), System.identityHashCode(proxy));
93 }
94
95 @Test
96 public void testInvokerHashCode() throws Exception
97 {
98 final Echo proxy = factory.createInvokerProxy(new InvokerTester(), ECHO_ONLY);
99 assertEquals(proxy.hashCode(), System.identityHashCode(proxy));
100 }
101
102 @Test
103 public void testDelegatorHashCode() throws Exception
104 {
105 final Echo proxy = factory.createDelegatorProxy(new ConstantProvider<Echo>(new EchoImpl()), Echo.class);
106 assertEquals(proxy.hashCode(), System.identityHashCode(proxy));
107 }
108
109 @Test
110 public void testInterceptorEquals()
111 {
112 final Date date = new Date();
113 final Comparable<?> proxy1 = factory.createInterceptorProxy(date, new NoOpMethodInterceptor(), COMPARABLE_ONLY);
114 final Comparable<?> proxy2 = factory.createInterceptorProxy(date, new NoOpMethodInterceptor(), COMPARABLE_ONLY);
115 assertEquals(proxy1, proxy1);
116 assertFalse(proxy1.equals(proxy2));
117 assertFalse(proxy2.equals(proxy1));
118 }
119
120 @Test
121 public void testInvokerEquals() throws Exception
122 {
123 final Comparable<?> proxy1 = factory.createInvokerProxy(new InvokerTester(), COMPARABLE_ONLY);
124 final Comparable<?> proxy2 = factory.createInvokerProxy(new InvokerTester(), COMPARABLE_ONLY);
125 assertEquals(proxy1, proxy1);
126 assertFalse(proxy1.equals(proxy2));
127 assertFalse(proxy2.equals(proxy1));
128 }
129
130 @Test
131 public void testDelegatorEquals() throws Exception
132 {
133 final Date date = new Date();
134 final Comparable<?> proxy1 = factory.createDelegatorProxy(new ConstantProvider<Date>(date), COMPARABLE_ONLY);
135 final Comparable<?> proxy2 = factory.createDelegatorProxy(new ConstantProvider<Date>(date), COMPARABLE_ONLY);
136 assertEquals(proxy1, proxy1);
137 assertFalse(proxy1.equals(proxy2));
138 assertFalse(proxy2.equals(proxy1));
139 }
140
141 @Test
142 public void testBooleanInterceptorParameter()
143 {
144 final Echo echo = factory.createInterceptorProxy(new EchoImpl(), new InterceptorTester(), ECHO_ONLY);
145 assertFalse(echo.echoBack(false));
146 assertTrue(echo.echoBack(true));
147 }
148
149 @Test
150 public void testCanProxy()
151 {
152 assertTrue(factory.canProxy(Echo.class));
153 assertFalse(factory.canProxy(EchoImpl.class));
154 }
155
156 @Test
157 public void testChangingArguments()
158 {
159 final Echo proxy = factory.createInterceptorProxy(new EchoImpl(), new ChangeArgumentInterceptor(), ECHO_ONLY);
160 assertEquals("something different", proxy.echoBack("whatever"));
161 }
162
163 @Test
164 public void testCreateDelegatingProxy()
165 {
166 final Echo echo = factory.createDelegatorProxy(createSingletonEcho(), ECHO_ONLY);
167 echo.echo();
168 assertEquals("message", echo.echoBack("message"));
169 assertEquals("ab", echo.echoBack("a", "b"));
170 }
171
172 @Test
173 public void testCreateInterceptorProxy()
174 {
175 final Echo target = factory.createDelegatorProxy(createSingletonEcho(), ECHO_ONLY);
176 final Echo proxy = factory.createInterceptorProxy(target, new SuffixInterceptor(" suffix"), ECHO_ONLY);
177 proxy.echo();
178 assertEquals("message suffix", proxy.echoBack("message"));
179 }
180
181 @Test
182 public void testDelegatingProxyClassCaching() throws Exception
183 {
184 final Echo proxy1 = factory.createDelegatorProxy(new ConstantProvider<Echo>(new EchoImpl()), Echo.class);
185 final Echo proxy2 = factory.createDelegatorProxy(new ConstantProvider<Echo>(new EchoImpl()), Echo.class);
186 assertNotSame(proxy1, proxy2);
187 assertSame(proxy1.getClass(), proxy2.getClass());
188 }
189
190 @Test
191 public void testDelegatingProxyInterfaceOrder()
192 {
193 final Echo echo = factory.createDelegatorProxy(createSingletonEcho(), Echo.class, DuplicateEcho.class);
194 final List<Class<?>> expected = new LinkedList<Class<?>>(Arrays.<Class<?>> asList(Echo.class,
195 DuplicateEcho.class));
196 final List<Class<?>> actual = new LinkedList<Class<?>>(Arrays.asList(echo.getClass().getInterfaces()));
197 actual.retainAll(expected);
198 assertEquals(expected, actual);
199 }
200
201 @Test
202 public void testDelegatingProxySerializable() throws Exception
203 {
204 final Echo proxy = factory.createDelegatorProxy(new ConstantProvider<Echo>(new EchoImpl()), Echo.class);
205 assertSerializable(proxy);
206 }
207
208 @Test
209 public void testInterceptingProxyClassCaching() throws Exception
210 {
211 final Echo proxy1 = factory.createInterceptorProxy(new EchoImpl(), new NoOpMethodInterceptor(), ECHO_ONLY);
212 final Echo proxy2 = factory.createInterceptorProxy(new EchoImpl(), new NoOpMethodInterceptor(), ECHO_ONLY);
213 assertNotSame(proxy1, proxy2);
214 assertSame(proxy1.getClass(), proxy2.getClass());
215 }
216
217 @Test
218 public void testInterceptingProxySerializable() throws Exception
219 {
220 final Echo proxy = factory.createInterceptorProxy(new EchoImpl(), new NoOpMethodInterceptor(), ECHO_ONLY);
221 assertSerializable(proxy);
222 }
223
224 @Test(expected = IOException.class)
225 public void testInterceptorProxyWithCheckedException() throws Exception
226 {
227 final Echo proxy = factory.createInterceptorProxy(new EchoImpl(), new NoOpMethodInterceptor(), ECHO_ONLY);
228 proxy.ioException();
229 }
230
231 @Test(expected = IllegalArgumentException.class)
232 public void testInterceptorProxyWithUncheckedException() throws Exception
233 {
234 final Echo proxy = factory.createInterceptorProxy(new EchoImpl(), new NoOpMethodInterceptor(), ECHO_ONLY);
235 proxy.illegalArgument();
236 }
237
238 @Test
239 public void testInterfaceHierarchies()
240 {
241 final SortedSet<String> set = factory.createDelegatorProxy(new ConstantProvider<SortedSet<String>>(
242 new TreeSet<String>()), SortedSet.class);
243 set.add("Hello");
244 }
245
246 @Test
247 public void testInvokerProxy() throws Exception
248 {
249 final InvokerTester tester = new InvokerTester();
250 final Echo echo = factory.createInvokerProxy(tester, ECHO_ONLY);
251 echo.echoBack("hello");
252 assertEquals(Echo.class.getMethod("echoBack", String.class), tester.method);
253 assertSame(echo, tester.proxy);
254 assertNotNull(tester.args);
255 assertEquals(1, tester.args.length);
256 assertEquals("hello", tester.args[0]);
257 }
258
259 @Test
260 public void testInvokerProxyClassCaching() throws Exception
261 {
262 final Echo proxy1 = factory.createInvokerProxy(new InvokerTester(), ECHO_ONLY);
263 final Echo proxy2 = factory.createInvokerProxy(new InvokerTester(), ECHO_ONLY);
264 assertNotSame(proxy1, proxy2);
265 assertSame(proxy1.getClass(), proxy2.getClass());
266 }
267
268 @Test
269 public void testInvokerProxySerializable() throws Exception
270 {
271 final Echo proxy = factory.createInvokerProxy(new InvokerTester(), ECHO_ONLY);
272 assertSerializable(proxy);
273 }
274
275 @Test
276 public void testMethodInvocationClassCaching() throws Exception
277 {
278 final InterceptorTester tester = new InterceptorTester();
279 final EchoImpl target = new EchoImpl();
280 final Echo proxy1 = factory.createInterceptorProxy(target, tester, ECHO_ONLY);
281 final Echo proxy2 = factory.createInterceptorProxy(target, tester, Echo.class, DuplicateEcho.class);
282 proxy1.echoBack("hello1");
283 final Class<?> invocationClass1 = tester.invocationClass;
284 proxy2.echoBack("hello2");
285 assertSame(invocationClass1, tester.invocationClass);
286 }
287
288 @Test
289 public void testMethodInvocationDuplicateMethods() throws Exception
290 {
291 final InterceptorTester tester = new InterceptorTester();
292 final EchoImpl target = new EchoImpl();
293 final Echo proxy = factory.createInterceptorProxy(target, tester, Echo.class, DuplicateEcho.class);
294 proxy.echoBack("hello");
295 assertEquals(Echo.class.getMethod("echoBack", String.class), tester.method);
296 }
297
298 @Test
299 public void testMethodInvocationImplementation() throws Exception
300 {
301 final InterceptorTester tester = new InterceptorTester();
302 final EchoImpl target = new EchoImpl();
303 final Echo proxy = factory.createInterceptorProxy(target, tester, ECHO_ONLY);
304 proxy.echo();
305 assertNotNull(tester.arguments);
306 assertEquals(0, tester.arguments.length);
307 assertEquals(Echo.class.getMethod("echo"), tester.method);
308 assertSame(proxy, tester.proxy);
309 proxy.echoBack("Hello");
310 assertNotNull(tester.arguments);
311 assertEquals(1, tester.arguments.length);
312 assertEquals("Hello", tester.arguments[0]);
313 assertEquals(Echo.class.getMethod("echoBack", String.class), tester.method);
314 proxy.echoBack("Hello", "World");
315 assertNotNull(tester.arguments);
316 assertEquals(2, tester.arguments.length);
317 assertEquals("Hello", tester.arguments[0]);
318 assertEquals("World", tester.arguments[1]);
319 assertEquals(Echo.class.getMethod("echoBack", String.class, String.class), tester.method);
320 }
321
322 @Test
323 public void testPrimitiveParameter()
324 {
325 final Echo echo = factory.createDelegatorProxy(createSingletonEcho(), ECHO_ONLY);
326 assertEquals(1, echo.echoBack(1));
327 }
328
329 @Test(expected = IOException.class)
330 public void testProxyWithCheckedException() throws Exception
331 {
332 final Echo proxy = factory.createDelegatorProxy(new ConstantProvider<Echo>(new EchoImpl()), Echo.class);
333 proxy.ioException();
334 }
335
336 @Test(expected = IllegalArgumentException.class)
337 public void testProxyWithUncheckedException() throws Exception
338 {
339 final Echo proxy = factory.createDelegatorProxy(new ConstantProvider<Echo>(new EchoImpl()), Echo.class);
340 proxy.illegalArgument();
341 }
342
343 @Test
344 public void testWithNonAccessibleTargetType()
345 {
346 final Echo proxy = factory.createInterceptorProxy(new PrivateEcho(), new NoOpMethodInterceptor(), ECHO_ONLY);
347 proxy.echo();
348 }
349
350
351
352
353
354 private static class ChangeArgumentInterceptor implements Interceptor
355 {
356 @Override
357 public Object intercept(Invocation methodInvocation) throws Throwable
358 {
359 methodInvocation.getArguments()[0] = "something different";
360 return methodInvocation.proceed();
361 }
362 }
363
364 protected static class InterceptorTester implements Interceptor
365 {
366 private Object[] arguments;
367 private Method method;
368 private Object proxy;
369 private Class<?> invocationClass;
370
371 @Override
372 public Object intercept(Invocation methodInvocation) throws Throwable
373 {
374 arguments = methodInvocation.getArguments();
375 method = methodInvocation.getMethod();
376 proxy = methodInvocation.getProxy();
377 invocationClass = methodInvocation.getClass();
378 return methodInvocation.proceed();
379 }
380 }
381
382 protected static class InvokerTester implements Invoker
383 {
384 private Object method;
385 private Object[] args;
386 private Object proxy;
387
388 @Override
389 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
390 {
391 this.proxy = proxy;
392 this.method = method;
393 this.args = args;
394 return null;
395 }
396 }
397
398 protected static class NoOpMethodInterceptor implements Interceptor, Serializable
399 {
400 @Override
401 public Object intercept(Invocation methodInvocation) throws Throwable
402 {
403 return methodInvocation.proceed();
404 }
405 }
406
407 private static class PrivateEcho extends EchoImpl
408 {
409 }
410 }