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 *****************************************************************************/
009 package org.picocontainer.injectors;
010
011 import org.junit.Test;
012 import static org.junit.Assert.assertNotNull;
013 import static org.junit.Assert.assertEquals;
014 import org.picocontainer.MutablePicoContainer;
015 import org.picocontainer.DefaultPicoContainer;
016 import org.picocontainer.PicoContainer;
017 import org.picocontainer.PicoCompositionException;
018 import org.picocontainer.annotations.Inject;
019
020 import java.lang.reflect.Type;
021 import java.util.Map;
022
023 public class FactoryInjectorTestCase {
024
025 public static interface Swede {
026 }
027
028 public static class Turnip2 {
029 Swede swede;
030 private final String foo;
031 public Turnip2(String foo, Swede swede) {
032 this.foo = foo;
033 assertNotNull(swede);
034 this.swede = swede;
035 }
036 public Swede getSwede() {
037 return swede;
038 }
039
040 public String getFoo() {
041 return foo;
042 }
043 }
044
045 public static class Turnip {
046 @Inject
047 Swede swede;
048 private final String foo;
049
050 public Turnip(String foo) {
051 this.foo = foo;
052 }
053
054 public Swede getSwede() {
055 return swede;
056 }
057
058 public String getFoo() {
059 return foo;
060 }
061 }
062
063 @Test
064 public void testThatComponentCanHaveAProvidedDependency() {
065 MutablePicoContainer container = new DefaultPicoContainer(new MultiInjection());
066 container.addComponent(String.class, "foo");
067 container.addComponent(Turnip.class);
068 container.addAdapter(new SwedeFactoryInjector());
069 Turnip t = container.getComponent(Turnip.class);
070 assertNotNull(t);
071 assertEquals("Swede for " + Turnip.class.getName(), t.getSwede().toString());
072 assertEquals("foo", t.getFoo());
073
074 }
075
076 @Test
077 public void testThatComponentCanHaveAProvidedDependencyWithInlinedFactoryInjector() {
078 MutablePicoContainer container = new DefaultPicoContainer(new MultiInjection());
079 container.addComponent(String.class, "foo");
080 container.addComponent(Turnip.class);
081 container.addAdapter(new FactoryInjector<Swede>() {
082 public Swede getComponentInstance(PicoContainer container, final Type into) {
083 return new Swede() {
084 public String toString() {
085 return "Swede for " + ((Class) into).getName();
086 }
087 };
088 }
089 });
090 Turnip t = container.getComponent(Turnip.class);
091 assertNotNull(t);
092 assertEquals("Swede for " + Turnip.class.getName(), t.getSwede().toString());
093 assertEquals("foo", t.getFoo());
094
095 }
096
097 @Test
098 public void testThatComponentCanHaveAProvidedDependencyWithInlinedFactoryInjector2() {
099 MutablePicoContainer container = new DefaultPicoContainer(new MultiInjection());
100 container.addComponent(String.class, "foo");
101 container.addComponent(Turnip.class);
102 container.addAdapter(new FactoryInjector(Swede.class) {
103 public Swede getComponentInstance(PicoContainer container, final Type into) {
104 return new Swede() {
105 public String toString() {
106 return "Swede for " + ((Class) into).getName();
107 }
108 };
109 }
110 });
111 Turnip t = container.getComponent(Turnip.class);
112 assertNotNull(t);
113 assertEquals("Swede for " + Turnip.class.getName(), t.getSwede().toString());
114 assertEquals("foo", t.getFoo());
115
116 }
117
118 @Test
119 public void testThatComponentCanHaveAProvidedDependencyWithInlinedFactoryInjector3() {
120 MutablePicoContainer container = new DefaultPicoContainer(new MultiInjection());
121 container.addComponent(String.class, "foo");
122 container.addComponent(Turnip.class);
123 container.addAdapter(new FactoryInjector(Swede.class) {
124 public Swede getComponentInstance(PicoContainer container, final Type into) {
125 return new Swede() {
126 public String toString() {
127 return "Swede for " + ((Class) into).getName();
128 }
129 };
130 }
131 });
132 Turnip t = container.getComponent(Turnip.class);
133 assertNotNull(t);
134 assertEquals("Swede for " + Turnip.class.getName(), t.getSwede().toString());
135 assertEquals("foo", t.getFoo());
136
137 }
138
139
140 @Test
141 public void testThatComponentCanHaveAProvidedDependencyViaConstructor() {
142 MutablePicoContainer container = new DefaultPicoContainer();
143 container.addComponent(String.class, "foo");
144 container.addComponent(Turnip2.class);
145 container.addAdapter(new SwedeFactoryInjector());
146 Turnip2 t = container.getComponent(Turnip2.class);
147 assertNotNull(t);
148 assertEquals("Swede for " + Turnip2.class.getName(), t.getSwede().toString());
149 assertEquals("foo", t.getFoo());
150
151 }
152
153 @Test
154 public void testThatComponentCanHaveAProvidedDependencyViaConstructorADifferentWay() {
155 MutablePicoContainer container = new DefaultPicoContainer();
156 container.addComponent(String.class, "foo");
157 container.addComponent(Turnip2.class);
158 container.addAdapter(new Swede2FactoryInjector()); // this injector defines Swede2 as key in its ctor
159 Turnip2 t = container.getComponent(Turnip2.class);
160 assertNotNull(t);
161 assertEquals("Swede for " + Turnip2.class.getName(), t.getSwede().toString());
162 assertEquals("foo", t.getFoo());
163
164 }
165
166 private static class SwedeFactoryInjector extends FactoryInjector<Swede> {
167 public Swede getComponentInstance(PicoContainer container, final Type into) throws PicoCompositionException {
168 // Mauro: you can do anything in here by way of startegy for injecting a specific logger :-)
169 return new Swede() {
170 public String toString() {
171 return "Swede for " + ((Class) into).getName();
172 }
173 };
174 }
175 }
176
177 private static class Swede2FactoryInjector extends FactoryInjector {
178 private Swede2FactoryInjector() {
179 super(Swede.class);
180 }
181
182 public Swede getComponentInstance(PicoContainer container, final Type into) throws PicoCompositionException {
183 // Mauro: you can do anything in here by way of startegy for injecting a specific logger :-)
184 return new Swede() {
185 public String toString() {
186 return "Swede for " + ((Class) into).getName();
187 }
188 };
189 }
190 }
191
192 private abstract class Footle<T> {
193 private class ServiceConnectionInjector extends FactoryInjector<T> {
194 public T getComponentInstance(PicoContainer container, Type into) {
195 System.out.println("**** injector called for " + into);
196 return null;
197 }
198 }
199
200 private void addAdapter(MutablePicoContainer mpc) {
201 mpc.addAdapter(new ServiceConnectionInjector());
202 }
203 }
204
205 public static interface Tree {
206 String leafColor();
207 }
208 public static class OakTree implements Tree {
209 private String leafColor;
210
211 public OakTree(String leafColor) {
212 this.leafColor = leafColor;
213 }
214
215 public String leafColor() {
216 return leafColor;
217 }
218 }
219
220 @Test public void ensureSophistcatedFactorInjectorCaseIsPossible() {
221
222 DefaultPicoContainer pico = new DefaultPicoContainer();
223 pico.addConfig("leafColor", "green");
224 pico.addComponent(Tree.class, OakTree.class);
225
226 Footle<Map> ft = new Footle<Map>(){};
227
228 ft.addAdapter(pico);
229
230 Tree tree = pico.getComponent(Tree.class);
231 }
232
233 }