/* * Copyright (C) 2006 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.google.inject.internal; import static com.google.inject.matcher.Matchers.annotatedWith; import static com.google.inject.matcher.Matchers.any; import static com.google.inject.matcher.Matchers.not; import static com.google.inject.matcher.Matchers.only; import com.google.common.collect.Lists; import com.google.inject.Inject; import com.google.inject.spi.InjectionPoint; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.reflect.InvocationTargetException; import java.util.List; import junit.framework.TestCase; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; /** @author crazybob@google.com (Bob Lee) */ public class ProxyFactoryTest extends TestCase { List<MethodAspect> aspects = Lists.newArrayList(); public void testSimpleCase() throws NoSuchMethodException, InvocationTargetException, ErrorsException { SimpleInterceptor interceptor = new SimpleInterceptor(); InjectionPoint injectionPoint = InjectionPoint.forConstructorOf(Simple.class); aspects.add(new MethodAspect(any(), any(), interceptor)); ProxyFactory<Simple> factory = new ProxyFactory<Simple>(injectionPoint, aspects); ConstructionProxy<Simple> constructionProxy = factory.create(); Simple simple = constructionProxy.newInstance(); simple.invoke(); assertTrue(simple.invoked); assertTrue(interceptor.invoked); } static class Simple { boolean invoked = false; public void invoke() { invoked = true; } } static class SimpleInterceptor implements MethodInterceptor { boolean invoked = false; @Override public Object invoke(MethodInvocation methodInvocation) throws Throwable { invoked = true; return methodInvocation.proceed(); } } public void testInterceptOneMethod() throws NoSuchMethodException, InvocationTargetException, ErrorsException { SimpleInterceptor interceptor = new SimpleInterceptor(); aspects.add(new MethodAspect(only(Bar.class), annotatedWith(Intercept.class), interceptor)); ConstructionProxy<Foo> fooFactory = new ProxyFactory<Foo>(InjectionPoint.forConstructorOf(Foo.class), aspects).create(); ConstructionProxy<Bar> barFactory = new ProxyFactory<Bar>(InjectionPoint.forConstructorOf(Bar.class), aspects).create(); Foo foo = fooFactory.newInstance(); Bar bar = barFactory.newInstance(); foo.foo(); assertTrue(foo.fooCalled); assertFalse(interceptor.invoked); bar.bar(); assertTrue(bar.barCalled); assertFalse(interceptor.invoked); bar.intercepted(); assertTrue(bar.interceptedCalled); assertTrue(interceptor.invoked); } static class Foo { boolean fooCalled; @Intercept void foo() { fooCalled = true; } } static class Bar { boolean barCalled; void bar() { barCalled = true; } boolean interceptedCalled; @Intercept void intercepted() { interceptedCalled = true; } } @Retention(RetentionPolicy.RUNTIME) @interface Intercept {} public void testWithConstructorArguments() throws InvocationTargetException, NoSuchMethodException, ErrorsException { SimpleInterceptor interceptor = new SimpleInterceptor(); aspects.add(new MethodAspect(any(), any(), interceptor)); ProxyFactory<A> factory = new ProxyFactory<A>(InjectionPoint.forConstructorOf(A.class), aspects); ConstructionProxy<A> constructor = factory.create(); A a = constructor.newInstance(5); a.a(); assertEquals(5, a.i); } public void testNotProxied() throws NoSuchMethodException, InvocationTargetException, ErrorsException { SimpleInterceptor interceptor = new SimpleInterceptor(); aspects.add(new MethodAspect(not(any()), not(any()), interceptor)); ProxyFactory<A> factory = new ProxyFactory<A>(InjectionPoint.forConstructorOf(A.class), aspects); ConstructionProxy<A> constructor = factory.create(); A a = constructor.newInstance(5); assertEquals(A.class, a.getClass()); } static class A { final int i; @Inject public A(int i) { this.i = i; } public void a() {} } public void testMultipleInterceptors() throws NoSuchMethodException, InvocationTargetException, ErrorsException { DoubleInterceptor doubleInterceptor = new DoubleInterceptor(); CountingInterceptor countingInterceptor = new CountingInterceptor(); aspects.add(new MethodAspect(any(), any(), doubleInterceptor, countingInterceptor)); ProxyFactory<Counter> factory = new ProxyFactory<Counter>(InjectionPoint.forConstructorOf(Counter.class), aspects); ConstructionProxy<Counter> constructor = factory.create(); Counter counter = constructor.newInstance(); counter.inc(); assertEquals(2, counter.count); assertEquals(2, countingInterceptor.count); } static class CountingInterceptor implements MethodInterceptor { int count; @Override public Object invoke(MethodInvocation methodInvocation) throws Throwable { count++; return methodInvocation.proceed(); } } static class DoubleInterceptor implements MethodInterceptor { @Override public Object invoke(MethodInvocation methodInvocation) throws Throwable { methodInvocation.proceed(); return methodInvocation.proceed(); } } static class Counter { int count; void inc() { count++; } } }