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 }