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