blob: 0e95ce7c085385f285dc1bb37ddd26145b7ccb56 [file] [log] [blame]
crazyboblee62fcdde2007-02-03 02:10:13 +00001/**
2 * Copyright (C) 2006 Google Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
crazyboblee1b82a8f2007-02-02 23:30:42 +000016
crazyboblee10a3b022007-02-10 01:49:38 +000017package com.google.inject;
crazyboblee1b82a8f2007-02-02 23:30:42 +000018
limpbizkit163c48a2008-06-16 02:58:08 +000019import com.google.inject.internal.ErrorsException;
limpbizkit53664a72009-02-21 00:25:27 +000020import com.google.inject.internal.Lists;
limpbizkitdf98fcd2008-06-14 05:02:15 +000021import static com.google.inject.matcher.Matchers.annotatedWith;
22import static com.google.inject.matcher.Matchers.any;
23import static com.google.inject.matcher.Matchers.not;
24import static com.google.inject.matcher.Matchers.only;
limpbizkita6e0e782008-09-03 06:19:56 +000025import com.google.inject.spi.InjectionPoint;
crazyboblee62fcdde2007-02-03 02:10:13 +000026import java.lang.annotation.Retention;
27import java.lang.annotation.RetentionPolicy;
kevinb9n2394ca62007-04-20 14:33:40 +000028import java.lang.reflect.InvocationTargetException;
limpbizkit5fb9d922008-10-14 23:35:56 +000029import java.util.List;
limpbizkitdf98fcd2008-06-14 05:02:15 +000030import junit.framework.TestCase;
31import org.aopalliance.intercept.MethodInterceptor;
32import org.aopalliance.intercept.MethodInvocation;
crazyboblee1b82a8f2007-02-02 23:30:42 +000033
34/**
35 * @author crazybob@google.com (Bob Lee)
36 */
37public class ProxyFactoryTest extends TestCase {
38
limpbizkit5fb9d922008-10-14 23:35:56 +000039 List<MethodAspect> aspects = Lists.newArrayList();
40
crazyboblee1b82a8f2007-02-02 23:30:42 +000041 public void testSimpleCase()
limpbizkit163c48a2008-06-16 02:58:08 +000042 throws NoSuchMethodException, InvocationTargetException, ErrorsException {
crazyboblee1b82a8f2007-02-02 23:30:42 +000043 SimpleInterceptor interceptor = new SimpleInterceptor();
limpbizkit03b81a62009-03-18 05:34:39 +000044 InjectionPoint injectionPoint = InjectionPoint.forConstructorOf(Simple.class);
crazyboblee1b82a8f2007-02-02 23:30:42 +000045
limpbizkit5fb9d922008-10-14 23:35:56 +000046 aspects.add(new MethodAspect(any(), any(), interceptor));
limpbizkit03b81a62009-03-18 05:34:39 +000047 ProxyFactory<Simple> factory = new ProxyFactory<Simple>(injectionPoint, aspects);
crazyboblee1b82a8f2007-02-02 23:30:42 +000048
limpbizkit03b81a62009-03-18 05:34:39 +000049 ConstructionProxy<Simple> constructionProxy = factory.create();
crazyboblee1b82a8f2007-02-02 23:30:42 +000050
limpbizkit9dc32d42008-06-15 11:29:10 +000051 Simple simple = constructionProxy.newInstance();
crazyboblee1b82a8f2007-02-02 23:30:42 +000052 simple.invoke();
53 assertTrue(simple.invoked);
54 assertTrue(interceptor.invoked);
55 }
56
57 static class Simple {
58 boolean invoked = false;
59 public void invoke() {
60 invoked = true;
61 }
62 }
63
64 static class SimpleInterceptor implements MethodInterceptor {
65
66 boolean invoked = false;
67
68 public Object invoke(MethodInvocation methodInvocation) throws Throwable {
69 invoked = true;
70 return methodInvocation.proceed();
71 }
72 }
73
crazyboblee62fcdde2007-02-03 02:10:13 +000074 public void testInterceptOneMethod()
limpbizkit163c48a2008-06-16 02:58:08 +000075 throws NoSuchMethodException, InvocationTargetException, ErrorsException {
crazyboblee62fcdde2007-02-03 02:10:13 +000076 SimpleInterceptor interceptor = new SimpleInterceptor();
crazyboblee1b82a8f2007-02-02 23:30:42 +000077
limpbizkit5fb9d922008-10-14 23:35:56 +000078 aspects.add(new MethodAspect(only(Bar.class), annotatedWith(Intercept.class), interceptor));
crazyboblee62fcdde2007-02-03 02:10:13 +000079
limpbizkit03b81a62009-03-18 05:34:39 +000080 ConstructionProxy<Foo> fooFactory
81 = new ProxyFactory<Foo>(InjectionPoint.forConstructorOf(Foo.class), aspects).create();
82 ConstructionProxy<Bar> barFactory
83 = new ProxyFactory<Bar>(InjectionPoint.forConstructorOf(Bar.class), aspects).create();
crazyboblee62fcdde2007-02-03 02:10:13 +000084
85 Foo foo = fooFactory.newInstance();
86 Bar bar = barFactory.newInstance();
87
88 foo.foo();
89 assertTrue(foo.fooCalled);
90 assertFalse(interceptor.invoked);
91
92 bar.bar();
93 assertTrue(bar.barCalled);
94 assertFalse(interceptor.invoked);
95
96 bar.intercepted();
97 assertTrue(bar.interceptedCalled);
98 assertTrue(interceptor.invoked);
99 }
100
101 static class Foo {
102 boolean fooCalled;
103 @Intercept
104 void foo() {
105 fooCalled = true;
106 }
107 }
108
109 static class Bar {
110
111 boolean barCalled;
112 void bar() {
113 barCalled = true;
114 }
115
116 boolean interceptedCalled;
117
118 @Intercept
119 void intercepted() {
120 interceptedCalled = true;
121 }
122 }
123
124 @Retention(RetentionPolicy.RUNTIME)
125 @interface Intercept {}
126
127 public void testWithConstructorArguments()
limpbizkit163c48a2008-06-16 02:58:08 +0000128 throws InvocationTargetException, NoSuchMethodException, ErrorsException {
crazyboblee62fcdde2007-02-03 02:10:13 +0000129 SimpleInterceptor interceptor = new SimpleInterceptor();
130
limpbizkit5fb9d922008-10-14 23:35:56 +0000131 aspects.add(new MethodAspect(any(), any(), interceptor));
limpbizkit03b81a62009-03-18 05:34:39 +0000132 ProxyFactory<A> factory
133 = new ProxyFactory<A>(InjectionPoint.forConstructorOf(A.class), aspects);
crazyboblee62fcdde2007-02-03 02:10:13 +0000134
limpbizkit03b81a62009-03-18 05:34:39 +0000135 ConstructionProxy<A> constructor = factory.create();
crazyboblee62fcdde2007-02-03 02:10:13 +0000136
137 A a = constructor.newInstance(5);
138 a.a();
139 assertEquals(5, a.i);
140 }
141
142 public void testNotProxied()
limpbizkit163c48a2008-06-16 02:58:08 +0000143 throws NoSuchMethodException, InvocationTargetException, ErrorsException {
crazyboblee62fcdde2007-02-03 02:10:13 +0000144 SimpleInterceptor interceptor = new SimpleInterceptor();
145
limpbizkit5fb9d922008-10-14 23:35:56 +0000146 aspects.add(new MethodAspect(not(any()), not(any()), interceptor));
limpbizkit03b81a62009-03-18 05:34:39 +0000147 ProxyFactory<A> factory
148 = new ProxyFactory<A>(InjectionPoint.forConstructorOf(A.class), aspects);
crazyboblee62fcdde2007-02-03 02:10:13 +0000149
limpbizkit03b81a62009-03-18 05:34:39 +0000150 ConstructionProxy<A> constructor = factory.create();
crazyboblee62fcdde2007-02-03 02:10:13 +0000151
152 A a = constructor.newInstance(5);
153 assertEquals(A.class, a.getClass());
154 }
155
156 static class A {
157 final int i;
limpbizkita6e0e782008-09-03 06:19:56 +0000158 @Inject public A(int i) {
crazyboblee62fcdde2007-02-03 02:10:13 +0000159 this.i = i;
160 }
161 public void a() {}
162 }
163
164 public void testMultipleInterceptors()
limpbizkit163c48a2008-06-16 02:58:08 +0000165 throws NoSuchMethodException, InvocationTargetException, ErrorsException {
crazyboblee62fcdde2007-02-03 02:10:13 +0000166 DoubleInterceptor doubleInterceptor = new DoubleInterceptor();
167 CountingInterceptor countingInterceptor = new CountingInterceptor();
168
limpbizkit5fb9d922008-10-14 23:35:56 +0000169 aspects.add(new MethodAspect(any(), any(), doubleInterceptor, countingInterceptor));
limpbizkit03b81a62009-03-18 05:34:39 +0000170 ProxyFactory<Counter> factory
171 = new ProxyFactory<Counter>(InjectionPoint.forConstructorOf(Counter.class), aspects);
crazyboblee62fcdde2007-02-03 02:10:13 +0000172
limpbizkit03b81a62009-03-18 05:34:39 +0000173 ConstructionProxy<Counter> constructor = factory.create();
crazyboblee62fcdde2007-02-03 02:10:13 +0000174
175 Counter counter = constructor.newInstance();
176 counter.inc();
177 assertEquals(2, counter.count);
178 assertEquals(2, countingInterceptor.count);
179 }
180
181 static class CountingInterceptor implements MethodInterceptor {
182
183 int count;
184
185 public Object invoke(MethodInvocation methodInvocation) throws Throwable {
186 count++;
187 return methodInvocation.proceed();
188 }
189 }
190
191 static class DoubleInterceptor implements MethodInterceptor {
192
193 public Object invoke(MethodInvocation methodInvocation) throws Throwable {
194 methodInvocation.proceed();
195 return methodInvocation.proceed();
196 }
197 }
198
199 static class Counter {
200 int count;
201 void inc() {
202 count++;
203 }
204 }
crazyboblee1b82a8f2007-02-02 23:30:42 +0000205}