blob: c516d6606d37155d959499b631c24bfc08ed6a46 [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
limpbizkit5ae41eb2009-06-06 17:51:27 +000017package com.google.inject.internal;
crazyboblee1b82a8f2007-02-02 23:30:42 +000018
limpbizkit5ae41eb2009-06-06 17:51:27 +000019import com.google.inject.Inject;
limpbizkitdf98fcd2008-06-14 05:02:15 +000020import static com.google.inject.matcher.Matchers.annotatedWith;
21import static com.google.inject.matcher.Matchers.any;
22import static com.google.inject.matcher.Matchers.not;
23import static com.google.inject.matcher.Matchers.only;
limpbizkita6e0e782008-09-03 06:19:56 +000024import com.google.inject.spi.InjectionPoint;
crazyboblee62fcdde2007-02-03 02:10:13 +000025import java.lang.annotation.Retention;
26import java.lang.annotation.RetentionPolicy;
kevinb9n2394ca62007-04-20 14:33:40 +000027import java.lang.reflect.InvocationTargetException;
limpbizkit5fb9d922008-10-14 23:35:56 +000028import java.util.List;
limpbizkitdf98fcd2008-06-14 05:02:15 +000029import junit.framework.TestCase;
30import org.aopalliance.intercept.MethodInterceptor;
31import org.aopalliance.intercept.MethodInvocation;
crazyboblee1b82a8f2007-02-02 23:30:42 +000032
33/**
34 * @author crazybob@google.com (Bob Lee)
35 */
36public class ProxyFactoryTest extends TestCase {
37
limpbizkit5fb9d922008-10-14 23:35:56 +000038 List<MethodAspect> aspects = Lists.newArrayList();
39
crazyboblee1b82a8f2007-02-02 23:30:42 +000040 public void testSimpleCase()
limpbizkit163c48a2008-06-16 02:58:08 +000041 throws NoSuchMethodException, InvocationTargetException, ErrorsException {
crazyboblee1b82a8f2007-02-02 23:30:42 +000042 SimpleInterceptor interceptor = new SimpleInterceptor();
limpbizkit03b81a62009-03-18 05:34:39 +000043 InjectionPoint injectionPoint = InjectionPoint.forConstructorOf(Simple.class);
crazyboblee1b82a8f2007-02-02 23:30:42 +000044
limpbizkit5fb9d922008-10-14 23:35:56 +000045 aspects.add(new MethodAspect(any(), any(), interceptor));
limpbizkit03b81a62009-03-18 05:34:39 +000046 ProxyFactory<Simple> factory = new ProxyFactory<Simple>(injectionPoint, aspects);
crazyboblee1b82a8f2007-02-02 23:30:42 +000047
limpbizkit03b81a62009-03-18 05:34:39 +000048 ConstructionProxy<Simple> constructionProxy = factory.create();
crazyboblee1b82a8f2007-02-02 23:30:42 +000049
limpbizkit9dc32d42008-06-15 11:29:10 +000050 Simple simple = constructionProxy.newInstance();
crazyboblee1b82a8f2007-02-02 23:30:42 +000051 simple.invoke();
52 assertTrue(simple.invoked);
53 assertTrue(interceptor.invoked);
54 }
55
56 static class Simple {
57 boolean invoked = false;
58 public void invoke() {
59 invoked = true;
60 }
61 }
62
63 static class SimpleInterceptor implements MethodInterceptor {
64
65 boolean invoked = false;
66
67 public Object invoke(MethodInvocation methodInvocation) throws Throwable {
68 invoked = true;
69 return methodInvocation.proceed();
70 }
71 }
72
crazyboblee62fcdde2007-02-03 02:10:13 +000073 public void testInterceptOneMethod()
limpbizkit163c48a2008-06-16 02:58:08 +000074 throws NoSuchMethodException, InvocationTargetException, ErrorsException {
crazyboblee62fcdde2007-02-03 02:10:13 +000075 SimpleInterceptor interceptor = new SimpleInterceptor();
crazyboblee1b82a8f2007-02-02 23:30:42 +000076
limpbizkit5fb9d922008-10-14 23:35:56 +000077 aspects.add(new MethodAspect(only(Bar.class), annotatedWith(Intercept.class), interceptor));
crazyboblee62fcdde2007-02-03 02:10:13 +000078
limpbizkit03b81a62009-03-18 05:34:39 +000079 ConstructionProxy<Foo> fooFactory
80 = new ProxyFactory<Foo>(InjectionPoint.forConstructorOf(Foo.class), aspects).create();
81 ConstructionProxy<Bar> barFactory
82 = new ProxyFactory<Bar>(InjectionPoint.forConstructorOf(Bar.class), aspects).create();
crazyboblee62fcdde2007-02-03 02:10:13 +000083
84 Foo foo = fooFactory.newInstance();
85 Bar bar = barFactory.newInstance();
86
87 foo.foo();
88 assertTrue(foo.fooCalled);
89 assertFalse(interceptor.invoked);
90
91 bar.bar();
92 assertTrue(bar.barCalled);
93 assertFalse(interceptor.invoked);
94
95 bar.intercepted();
96 assertTrue(bar.interceptedCalled);
97 assertTrue(interceptor.invoked);
98 }
99
100 static class Foo {
101 boolean fooCalled;
102 @Intercept
103 void foo() {
104 fooCalled = true;
105 }
106 }
107
108 static class Bar {
109
110 boolean barCalled;
111 void bar() {
112 barCalled = true;
113 }
114
115 boolean interceptedCalled;
116
117 @Intercept
118 void intercepted() {
119 interceptedCalled = true;
120 }
121 }
122
123 @Retention(RetentionPolicy.RUNTIME)
124 @interface Intercept {}
125
126 public void testWithConstructorArguments()
limpbizkit163c48a2008-06-16 02:58:08 +0000127 throws InvocationTargetException, NoSuchMethodException, ErrorsException {
crazyboblee62fcdde2007-02-03 02:10:13 +0000128 SimpleInterceptor interceptor = new SimpleInterceptor();
129
limpbizkit5fb9d922008-10-14 23:35:56 +0000130 aspects.add(new MethodAspect(any(), any(), interceptor));
limpbizkit03b81a62009-03-18 05:34:39 +0000131 ProxyFactory<A> factory
132 = new ProxyFactory<A>(InjectionPoint.forConstructorOf(A.class), aspects);
crazyboblee62fcdde2007-02-03 02:10:13 +0000133
limpbizkit03b81a62009-03-18 05:34:39 +0000134 ConstructionProxy<A> constructor = factory.create();
crazyboblee62fcdde2007-02-03 02:10:13 +0000135
136 A a = constructor.newInstance(5);
137 a.a();
138 assertEquals(5, a.i);
139 }
140
141 public void testNotProxied()
limpbizkit163c48a2008-06-16 02:58:08 +0000142 throws NoSuchMethodException, InvocationTargetException, ErrorsException {
crazyboblee62fcdde2007-02-03 02:10:13 +0000143 SimpleInterceptor interceptor = new SimpleInterceptor();
144
limpbizkit5fb9d922008-10-14 23:35:56 +0000145 aspects.add(new MethodAspect(not(any()), not(any()), interceptor));
limpbizkit03b81a62009-03-18 05:34:39 +0000146 ProxyFactory<A> factory
147 = new ProxyFactory<A>(InjectionPoint.forConstructorOf(A.class), aspects);
crazyboblee62fcdde2007-02-03 02:10:13 +0000148
limpbizkit03b81a62009-03-18 05:34:39 +0000149 ConstructionProxy<A> constructor = factory.create();
crazyboblee62fcdde2007-02-03 02:10:13 +0000150
151 A a = constructor.newInstance(5);
152 assertEquals(A.class, a.getClass());
153 }
154
155 static class A {
156 final int i;
limpbizkita6e0e782008-09-03 06:19:56 +0000157 @Inject public A(int i) {
crazyboblee62fcdde2007-02-03 02:10:13 +0000158 this.i = i;
159 }
160 public void a() {}
161 }
162
163 public void testMultipleInterceptors()
limpbizkit163c48a2008-06-16 02:58:08 +0000164 throws NoSuchMethodException, InvocationTargetException, ErrorsException {
crazyboblee62fcdde2007-02-03 02:10:13 +0000165 DoubleInterceptor doubleInterceptor = new DoubleInterceptor();
166 CountingInterceptor countingInterceptor = new CountingInterceptor();
167
limpbizkit5fb9d922008-10-14 23:35:56 +0000168 aspects.add(new MethodAspect(any(), any(), doubleInterceptor, countingInterceptor));
limpbizkit03b81a62009-03-18 05:34:39 +0000169 ProxyFactory<Counter> factory
170 = new ProxyFactory<Counter>(InjectionPoint.forConstructorOf(Counter.class), aspects);
crazyboblee62fcdde2007-02-03 02:10:13 +0000171
limpbizkit03b81a62009-03-18 05:34:39 +0000172 ConstructionProxy<Counter> constructor = factory.create();
crazyboblee62fcdde2007-02-03 02:10:13 +0000173
174 Counter counter = constructor.newInstance();
175 counter.inc();
176 assertEquals(2, counter.count);
177 assertEquals(2, countingInterceptor.count);
178 }
179
180 static class CountingInterceptor implements MethodInterceptor {
181
182 int count;
183
184 public Object invoke(MethodInvocation methodInvocation) throws Throwable {
185 count++;
186 return methodInvocation.proceed();
187 }
188 }
189
190 static class DoubleInterceptor implements MethodInterceptor {
191
192 public Object invoke(MethodInvocation methodInvocation) throws Throwable {
193 methodInvocation.proceed();
194 return methodInvocation.proceed();
195 }
196 }
197
198 static class Counter {
199 int count;
200 void inc() {
201 count++;
202 }
203 }
crazyboblee1b82a8f2007-02-02 23:30:42 +0000204}