001 package org.picocontainer.adapters; 002 003 import static org.picocontainer.BindKey.bindKey; 004 005 import java.lang.annotation.ElementType; 006 import java.lang.annotation.Retention; 007 import java.lang.annotation.RetentionPolicy; 008 import java.lang.annotation.Target; 009 010 import org.junit.Assert; 011 import org.junit.Test; 012 import static org.junit.Assert.assertNotNull; 013 import static org.junit.Assert.assertEquals; 014 import org.picocontainer.DefaultPicoContainer; 015 import org.picocontainer.MutablePicoContainer; 016 import org.picocontainer.annotations.Bind; 017 import org.picocontainer.annotations.Inject; 018 import org.picocontainer.injectors.AbstractInjector; 019 import org.picocontainer.injectors.AnnotatedFieldInjection; 020 import org.picocontainer.injectors.ConstructorInjection; 021 import org.picocontainer.injectors.MethodInjection; 022 import org.picocontainer.injectors.SetterInjection; 023 024 /** @author Paul Hammant */ 025 public class TypedBindingAnnotationTestCase { 026 027 @Test public void testFieldInjectionWithBindings() { 028 MutablePicoContainer mpc = new DefaultPicoContainer(new AnnotatedFieldInjection()); 029 030 addFiveComponents(mpc); 031 FruitBasket fb = mpc.getComponent(FruitBasket.class); 032 assertFourMemberApplesAreRight(fb); 033 assertGettingOfAppleOneWorks(mpc); 034 } 035 036 private void assertGettingOfAppleOneWorks(MutablePicoContainer mpc) { 037 try { 038 mpc.getComponent(Apple.class); 039 Assert.fail("should have barfed"); 040 } catch (AbstractInjector.AmbiguousComponentResolutionException e) { 041 // expected 042 } 043 assertNotNull(mpc.getComponent(Apple.class, Bramley.class)); 044 } 045 046 @Test public void testBindingAnnotationsWithConstructorInjection() { 047 MutablePicoContainer mpc = new DefaultPicoContainer(new ConstructorInjection()); 048 049 addFiveComponents(mpc, FruitBasketViaConstructor.class); 050 FruitBasket fb = mpc.getComponent(FruitBasketViaConstructor.class); 051 assertFourMemberApplesAreRight(fb); 052 assertGettingOfAppleOneWorks(mpc); 053 } 054 055 private void assertFourMemberApplesAreRight(FruitBasket fb) { 056 assertNotNull(fb); 057 assertEquals(fb.bramley.getX(), 1); 058 assertEquals(fb.cox.getX(), 2); 059 assertEquals(fb.granny.getX(), 3); 060 assertEquals(fb.braeburn.getX(), 4); 061 } 062 063 @Test public void testBindingAnnotationsWithMethodInjection() { 064 MutablePicoContainer mpc = new DefaultPicoContainer(new MethodInjection("foo")); 065 addFiveComponents(mpc); 066 FruitBasket fb = mpc.getComponent(FruitBasket.class); 067 assertFourMemberApplesAreRight(fb); 068 assertGettingOfAppleOneWorks(mpc); 069 070 } 071 072 @Test public void testBindingAnnotationsWithSetterInjection() { 073 MutablePicoContainer mpc = new DefaultPicoContainer(new SetterInjection()); 074 addFiveComponents(mpc); 075 FruitBasket fb = mpc.getComponent(FruitBasket.class); 076 assertFourMemberApplesAreRight(fb); 077 assertGettingOfAppleOneWorks(mpc); 078 079 } 080 081 private void addFiveComponents(MutablePicoContainer mpc) { 082 addFiveComponents(mpc, FruitBasket.class); 083 } 084 085 private void addFiveComponents(MutablePicoContainer mpc, Class clazz) { 086 mpc.addComponent(clazz); 087 mpc.addComponent(bindKey(Apple.class, Bramley.class), AppleImpl1.class); 088 mpc.addComponent(bindKey(Apple.class, Cox.class), AppleImpl2.class); 089 mpc.addComponent(bindKey(Apple.class, Granny.class), AppleImpl3.class); 090 mpc.addComponent(bindKey(Apple.class, Braeburn.class), AppleImpl4.class); 091 } 092 093 public interface Apple { 094 int getX(); 095 } 096 public static class AppleImpl1 implements Apple { 097 public int getX() { 098 return 1; 099 } 100 } 101 public static class AppleImpl2 implements Apple { 102 public int getX() { 103 return 2; 104 } 105 } 106 public static class AppleImpl3 implements Apple { 107 public int getX() { 108 return 3; 109 } 110 } 111 public static class AppleImpl4 implements Apple { 112 public int getX() { 113 return 4; 114 } 115 } 116 117 @Retention(RetentionPolicy.RUNTIME) 118 @Target({ElementType.FIELD, ElementType.PARAMETER}) 119 @Bind 120 public static @interface Bramley {} 121 122 @Retention(RetentionPolicy.RUNTIME) 123 @Target({ElementType.FIELD, ElementType.PARAMETER}) 124 @Bind 125 public static @interface Cox {} 126 127 @Retention(RetentionPolicy.RUNTIME) 128 @Target({ElementType.FIELD, ElementType.PARAMETER}) 129 @Bind 130 public static @interface Granny {} 131 132 @Retention(RetentionPolicy.RUNTIME) 133 @Target({ElementType.FIELD, ElementType.PARAMETER}) 134 @Bind 135 public static @interface Braeburn {} 136 137 public static class FruitBasketViaConstructor extends FruitBasket { 138 // used in testBindingAnnotationsWithConstructorInjection() 139 public FruitBasketViaConstructor(@Bramley Apple bramley, @Cox Apple cox, @Granny Apple granny, @Braeburn Apple braeburn) { 140 foo(bramley, cox, granny, braeburn); 141 } 142 143 } 144 public static class FruitBasket { 145 @Inject 146 private @Bramley Apple bramley; 147 @Inject 148 private @Cox Apple cox; 149 @Inject 150 private @Granny Apple granny; 151 @Inject 152 private @Braeburn Apple braeburn; 153 154 public FruitBasket() { 155 } 156 157 158 // used in testBindingAnnotationsWithMethodInjection() 159 public void foo(@Bramley Apple bramley, @Cox Apple cox, @Granny Apple granny, @Braeburn Apple braeburn) { 160 this.bramley = bramley; 161 this.cox = cox; 162 this.granny = granny; 163 this.braeburn = braeburn; 164 } 165 166 public void setOne(@Bramley Apple bramley) { 167 this.bramley = bramley; 168 } 169 170 public void setTwo(@Cox Apple cox) { 171 this.cox = cox; 172 } 173 174 public void setThree(@Granny Apple granny) { 175 this.granny = granny; 176 } 177 178 public void setFour(@Braeburn Apple braeburn) { 179 this.braeburn = braeburn; 180 } 181 } 182 183 184 }