001    /*****************************************************************************
002     * Copyright (C) PicoContainer Organization. All rights reserved.            *
003     * ------------------------------------------------------------------------- *
004     * The software in this package is published under the terms of the BSD      *
005     * style license a copy of which has been included with this distribution in *
006     * the LICENSE.txt file.                                                     *
007     *                                                                           *
008     * Original code by                                                          *
009     *****************************************************************************/
010    package org.picocontainer.injectors;
011    
012    import org.junit.Test;
013    import org.picocontainer.DefaultPicoContainer;
014    import org.picocontainer.MutablePicoContainer;
015    import org.picocontainer.PicoBuilder;
016    import org.picocontainer.annotations.Inject;
017    import org.picocontainer.monitors.NullComponentMonitor;
018    
019    import java.lang.annotation.ElementType;
020    import java.lang.annotation.Retention;
021    import java.lang.annotation.RetentionPolicy;
022    import java.lang.annotation.Target;
023    
024    import static org.junit.Assert.assertNotNull;
025    import static org.junit.Assert.assertNull;
026    
027    public class AnnotatedFieldInjectorTestCase {
028    
029        public static class Helicopter {
030            @Inject
031            private PogoStick pogo;
032    
033            public Helicopter() {
034            }
035        }
036    
037        public static class Helicopter2 {
038            private PogoStick pogo;
039    
040            public Helicopter2() {
041            }
042        }
043    
044        public static class PogoStick {
045        }
046    
047        @Test
048        public void testFieldInjection() {
049            MutablePicoContainer pico = new DefaultPicoContainer();
050            pico.addAdapter(new AnnotatedFieldInjector(Helicopter.class, Helicopter.class, null,
051                    new NullComponentMonitor(), Inject.class, false));
052            pico.addComponent(PogoStick.class, new PogoStick());
053            Helicopter chopper = pico.getComponent(Helicopter.class);
054            assertNotNull(chopper);
055            assertNotNull(chopper.pogo);
056        }
057    
058        @Test
059        public void testFieldInjectionWithoutAnnotationDoesNotWork() {
060            MutablePicoContainer pico = new DefaultPicoContainer();
061            pico.addAdapter(new AnnotatedFieldInjector(Helicopter2.class, Helicopter2.class, null,
062                    new NullComponentMonitor(), Inject.class, false));
063            pico.addComponent(PogoStick.class, new PogoStick());
064            Helicopter2 chopper = pico.getComponent(Helicopter2.class);
065            assertNotNull(chopper);
066            assertNull(chopper.pogo);
067        }
068    
069        @Test
070        public void testFieldDeosNotHappenWithoutRightInjectorDoesNotWork() {
071            MutablePicoContainer pico = new DefaultPicoContainer();
072            pico.addAdapter(new SetterInjector(Helicopter.class, Helicopter.class, null,
073                    new NullComponentMonitor(),
074                    "set", "", false, false));
075            pico.addComponent(PogoStick.class, new PogoStick());
076            Helicopter chopper = pico.getComponent(Helicopter.class);
077            assertNotNull(chopper);
078            assertNull(chopper.pogo);
079        }
080    
081        @Retention(RetentionPolicy.RUNTIME)
082        @Target(value = {ElementType.METHOD, ElementType.FIELD})
083        public @interface AlternativeInject {
084        }
085    
086        public static class Helicopter3 {
087            @AlternativeInject
088            private PogoStick pogo;
089    
090            public Helicopter3() {
091            }
092        }
093    
094        @Test
095        public void testFieldInjectionWithAlternativeInjectionAnnotation() {
096            MutablePicoContainer pico = new DefaultPicoContainer();
097            pico.addAdapter(new AnnotatedFieldInjector(Helicopter3.class, Helicopter3.class, null,
098                    new NullComponentMonitor(), AlternativeInject.class, false));
099            pico.addComponent(PogoStick.class, new PogoStick());
100            Helicopter3 chopper = pico.getComponent(Helicopter3.class);
101            assertNotNull(chopper);
102            assertNotNull(chopper.pogo);
103        }
104    
105        public static abstract class A {
106            @Inject
107            protected C c;
108        }
109    
110        public static class B extends A {
111        }
112    
113        public static class C {
114        }
115    
116        @Test
117        public void testThatSuperClassCanHaveAnnotatedFields() {
118            MutablePicoContainer container = new PicoBuilder().withAutomatic().build();
119            container.addComponent(C.class);
120            container.addComponent(B.class);
121    
122            B b = container.getComponent(B.class);
123            assertNotNull(b);
124            assertNotNull(b.c);
125        }
126    
127        public static abstract class A2 {
128            @Inject
129            protected D2 d2;
130        }
131    
132        public static abstract class B2 extends A2 {
133        }
134    
135        public static class C2 extends B2 {
136        }
137    
138        public static class D2 {
139        }
140    
141        @Test
142        public void testThatEvenMoreSuperClassCanHaveAnnotatedFields() {
143            MutablePicoContainer container = new PicoBuilder().withAnnotatedFieldInjection().build();
144            container.addComponent(D2.class);
145            container.addComponent(C2.class);
146    
147            C2 c2 = container.getComponent(C2.class);
148            assertNotNull(c2);
149            assertNotNull(c2.d2);
150        }
151    
152        @Test
153        public void testThatEvenMoreSuperClassCanHaveAnnotatedFieldsViaAdaptingInjection() {
154            MutablePicoContainer container = new PicoBuilder().build();
155            container.addComponent(D2.class);
156            container.addComponent(C2.class);
157    
158            C2 c2 = container.getComponent(C2.class);
159            assertNotNull(c2);
160            assertNotNull(c2.d2);
161        }
162    
163    }