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