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 }