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