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 System.out.println(""); 042 // expected 043 } 044 assertNotNull(mpc.getComponent(Apple.class, Bramley.class)); 045 } 046 047 @Test public void testBindingAnnotationsWithConstructorInjection() { 048 MutablePicoContainer mpc = new DefaultPicoContainer(new ConstructorInjection()); 049 050 addFiveComponents(mpc, FruitBasketViaConstructor.class); 051 FruitBasket fb = mpc.getComponent(FruitBasketViaConstructor.class); 052 assertFourMemberApplesAreRight(fb); 053 assertGettingOfAppleOneWorks(mpc); 054 } 055 056 private void assertFourMemberApplesAreRight(FruitBasket fb) { 057 assertNotNull(fb); 058 assertEquals(fb.bramley.getX(), 1); 059 assertEquals(fb.cox.getX(), 2); 060 assertEquals(fb.granny.getX(), 3); 061 assertEquals(fb.braeburn.getX(), 4); 062 } 063 064 @Test public void testBindingAnnotationsWithMethodInjection() { 065 MutablePicoContainer mpc = new DefaultPicoContainer(new MethodInjection("foo")); 066 addFiveComponents(mpc); 067 FruitBasket fb = mpc.getComponent(FruitBasket.class); 068 assertFourMemberApplesAreRight(fb); 069 assertGettingOfAppleOneWorks(mpc); 070 071 } 072 073 @Test public void testBindingAnnotationsWithSetterInjection() { 074 MutablePicoContainer mpc = new DefaultPicoContainer(new SetterInjection()); 075 addFiveComponents(mpc); 076 FruitBasket fb = mpc.getComponent(FruitBasket.class); 077 assertFourMemberApplesAreRight(fb); 078 assertGettingOfAppleOneWorks(mpc); 079 080 } 081 082 private void addFiveComponents(MutablePicoContainer mpc) { 083 addFiveComponents(mpc, FruitBasket.class); 084 } 085 086 private void addFiveComponents(MutablePicoContainer mpc, Class clazz) { 087 mpc.addComponent(clazz); 088 mpc.addComponent(bindKey(Apple.class, Bramley.class), AppleImpl1.class); 089 mpc.addComponent(bindKey(Apple.class, Cox.class), AppleImpl2.class); 090 mpc.addComponent(bindKey(Apple.class, Granny.class), AppleImpl3.class); 091 mpc.addComponent(bindKey(Apple.class, Braeburn.class), AppleImpl4.class); 092 } 093 094 public interface Apple { 095 int getX(); 096 } 097 public static class AppleImpl1 implements Apple { 098 public int getX() { 099 return 1; 100 } 101 } 102 public static class AppleImpl2 implements Apple { 103 public int getX() { 104 return 2; 105 } 106 } 107 public static class AppleImpl3 implements Apple { 108 public int getX() { 109 return 3; 110 } 111 } 112 public static class AppleImpl4 implements Apple { 113 public int getX() { 114 return 4; 115 } 116 } 117 118 @Retention(RetentionPolicy.RUNTIME) 119 @Target({ElementType.FIELD, ElementType.PARAMETER}) 120 @Bind 121 public static @interface Bramley {} 122 123 @Retention(RetentionPolicy.RUNTIME) 124 @Target({ElementType.FIELD, ElementType.PARAMETER}) 125 @Bind 126 public static @interface Cox {} 127 128 @Retention(RetentionPolicy.RUNTIME) 129 @Target({ElementType.FIELD, ElementType.PARAMETER}) 130 @Bind 131 public static @interface Granny {} 132 133 @Retention(RetentionPolicy.RUNTIME) 134 @Target({ElementType.FIELD, ElementType.PARAMETER}) 135 @Bind 136 public static @interface Braeburn {} 137 138 public static class FruitBasketViaConstructor extends FruitBasket { 139 // used in testBindingAnnotationsWithConstructorInjection() 140 public FruitBasketViaConstructor(@Bramley Apple bramley, @Cox Apple cox, @Granny Apple granny, @Braeburn Apple braeburn) { 141 foo(bramley, cox, granny, braeburn); 142 } 143 144 } 145 public static class FruitBasket { 146 @Inject 147 private @Bramley Apple bramley; 148 @Inject 149 private @Cox Apple cox; 150 @Inject 151 private @Granny Apple granny; 152 @Inject 153 private @Braeburn Apple braeburn; 154 155 public FruitBasket() { 156 } 157 158 159 // used in testBindingAnnotationsWithMethodInjection() 160 public void foo(@Bramley Apple bramley, @Cox Apple cox, @Granny Apple granny, @Braeburn Apple braeburn) { 161 this.bramley = bramley; 162 this.cox = cox; 163 this.granny = granny; 164 this.braeburn = braeburn; 165 } 166 167 public void setOne(@Bramley Apple bramley) { 168 this.bramley = bramley; 169 } 170 171 public void setTwo(@Cox Apple cox) { 172 this.cox = cox; 173 } 174 175 public void setThree(@Granny Apple granny) { 176 this.granny = granny; 177 } 178 179 public void setFour(@Braeburn Apple braeburn) { 180 this.braeburn = braeburn; 181 } 182 } 183 184 185 }