    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    }