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    }