001: /**
002: * Copyright (C) 2006 Google Inc.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */package com.google.inject;
016:
017: import com.google.inject.ConstructionProxy;
018: import static com.google.inject.matcher.Matchers.*;
019: import com.google.inject.Provider;
020:
021: import junit.framework.TestCase;
022:
023: import org.aopalliance.intercept.MethodInterceptor;
024: import org.aopalliance.intercept.MethodInvocation;
025:
026: import java.lang.reflect.InvocationTargetException;
027: import java.lang.annotation.Retention;
028: import java.lang.annotation.RetentionPolicy;
029:
030: /**
031: * @author crazybob@google.com (Bob Lee)
032: */
033: public class ProxyFactoryTest extends TestCase {
034:
035: public void testSimpleCase() throws NoSuchMethodException,
036: InvocationTargetException {
037: SimpleInterceptor interceptor = new SimpleInterceptor();
038:
039: ProxyFactoryBuilder builder = new ProxyFactoryBuilder();
040: builder.intercept(any(), any(), interceptor);
041: ProxyFactory factory = builder.create();
042:
043: Provider<Simple> creator = factory.getFactory(Simple.class);
044:
045: Simple simple = creator.get();
046: simple.invoke();
047: assertTrue(simple.invoked);
048: assertTrue(interceptor.invoked);
049: }
050:
051: static class Simple {
052: boolean invoked = false;
053:
054: public void invoke() {
055: invoked = true;
056: }
057: }
058:
059: static class SimpleInterceptor implements MethodInterceptor {
060:
061: boolean invoked = false;
062:
063: public Object invoke(MethodInvocation methodInvocation)
064: throws Throwable {
065: invoked = true;
066: return methodInvocation.proceed();
067: }
068: }
069:
070: public void testInterceptOneMethod() throws NoSuchMethodException,
071: InvocationTargetException {
072: SimpleInterceptor interceptor = new SimpleInterceptor();
073:
074: ProxyFactoryBuilder builder = new ProxyFactoryBuilder();
075:
076: builder.intercept(only(Bar.class),
077: annotatedWith(Intercept.class), interceptor);
078: ProxyFactory factory = builder.create();
079:
080: ConstructionProxy<Foo> fooFactory = factory.get(Foo.class
081: .getDeclaredConstructor());
082: ConstructionProxy<Bar> barFactory = factory.get(Bar.class
083: .getDeclaredConstructor());
084:
085: Foo foo = fooFactory.newInstance();
086: Bar bar = barFactory.newInstance();
087:
088: foo.foo();
089: assertTrue(foo.fooCalled);
090: assertFalse(interceptor.invoked);
091:
092: bar.bar();
093: assertTrue(bar.barCalled);
094: assertFalse(interceptor.invoked);
095:
096: bar.intercepted();
097: assertTrue(bar.interceptedCalled);
098: assertTrue(interceptor.invoked);
099: }
100:
101: static class Foo {
102: boolean fooCalled;
103:
104: @Intercept
105: void foo() {
106: fooCalled = true;
107: }
108: }
109:
110: static class Bar {
111:
112: boolean barCalled;
113:
114: void bar() {
115: barCalled = true;
116: }
117:
118: boolean interceptedCalled;
119:
120: @Intercept
121: void intercepted() {
122: interceptedCalled = true;
123: }
124: }
125:
126: @Retention(RetentionPolicy.RUNTIME)
127: @interface Intercept {
128: }
129:
130: public void testWithConstructorArguments()
131: throws InvocationTargetException, NoSuchMethodException {
132: SimpleInterceptor interceptor = new SimpleInterceptor();
133:
134: ProxyFactoryBuilder builder = new ProxyFactoryBuilder();
135: builder.intercept(any(), any(), interceptor);
136: ProxyFactory factory = builder.create();
137:
138: ConstructionProxy<A> constructor = factory.get(A.class
139: .getDeclaredConstructor(int.class));
140:
141: A a = constructor.newInstance(5);
142: a.a();
143: assertEquals(5, a.i);
144: }
145:
146: public void testNotProxied() throws NoSuchMethodException,
147: InvocationTargetException {
148: SimpleInterceptor interceptor = new SimpleInterceptor();
149:
150: ProxyFactoryBuilder builder = new ProxyFactoryBuilder();
151: builder.intercept(not(any()), not(any()), interceptor);
152: ProxyFactory factory = builder.create();
153:
154: ConstructionProxy<A> constructor = factory.get(A.class
155: .getDeclaredConstructor(int.class));
156:
157: A a = constructor.newInstance(5);
158: assertEquals(A.class, a.getClass());
159: }
160:
161: static class A {
162: final int i;
163:
164: public A(int i) {
165: this .i = i;
166: }
167:
168: public void a() {
169: }
170: }
171:
172: public void testMultipleInterceptors()
173: throws NoSuchMethodException, InvocationTargetException {
174: DoubleInterceptor doubleInterceptor = new DoubleInterceptor();
175: CountingInterceptor countingInterceptor = new CountingInterceptor();
176:
177: ProxyFactoryBuilder builder = new ProxyFactoryBuilder();
178: builder.intercept(any(), any(), doubleInterceptor,
179: countingInterceptor);
180: ProxyFactory factory = builder.create();
181:
182: ConstructionProxy<Counter> constructor = factory
183: .get(Counter.class.getDeclaredConstructor());
184:
185: Counter counter = constructor.newInstance();
186: counter.inc();
187: assertEquals(2, counter.count);
188: assertEquals(2, countingInterceptor.count);
189: }
190:
191: static class CountingInterceptor implements MethodInterceptor {
192:
193: int count;
194:
195: public Object invoke(MethodInvocation methodInvocation)
196: throws Throwable {
197: count++;
198: return methodInvocation.proceed();
199: }
200: }
201:
202: static class DoubleInterceptor implements MethodInterceptor {
203:
204: public Object invoke(MethodInvocation methodInvocation)
205: throws Throwable {
206: methodInvocation.proceed();
207: return methodInvocation.proceed();
208: }
209: }
210:
211: static class Counter {
212: int count;
213:
214: void inc() {
215: count++;
216: }
217: }
218: }
|