001 package org.picocontainer.defaults; 002 003 import junit.framework.TestCase; 004 import org.picocontainer.MutablePicoContainer; 005 import org.picocontainer.PicoContainer; 006 import org.picocontainer.PicoInitializationException; 007 import org.picocontainer.PicoIntrospectionException; 008 009 import java.util.HashMap; 010 import java.util.Map; 011 012 /** 013 * This class can be used to test out various things asked on the mailing list. 014 * Or to answer questions. 015 * 016 * @author Aslak Hellesøy 017 * @version $Revision: 1595 $ 018 */ 019 public class UserQuestionTestCase extends TestCase { 020 021 // From Scott Farquahsr 022 public static class CheeseComponentAdapter extends AbstractComponentAdapter { 023 private Map bla; 024 025 public CheeseComponentAdapter(Object componentKey, Class componentImplementation, Map cheeseMap) throws AssignabilityRegistrationException, NotConcreteRegistrationException { 026 super(componentKey, componentImplementation); 027 this.bla = cheeseMap; 028 } 029 030 public Object getComponentInstance(PicoContainer pico) throws PicoInitializationException, PicoIntrospectionException { 031 return bla.get("cheese"); 032 } 033 034 public void verify(PicoContainer pico) throws UnsatisfiableDependenciesException { 035 } 036 } 037 038 public static interface Cheese { 039 String getName(); 040 } 041 042 public static class Gouda implements Cheese { 043 public String getName() { 044 return "Gouda"; 045 } 046 } 047 048 public static class Roquefort implements Cheese { 049 public String getName() { 050 return "Roquefort"; 051 } 052 } 053 054 public static class Omelette { 055 private final Cheese cheese; 056 057 public Omelette(Cheese cheese) { 058 this.cheese = cheese; 059 } 060 061 public Cheese getCheese() { 062 return cheese; 063 } 064 } 065 066 public void testOmeletteCanHaveDifferentCheeseWithAFunnyComponentAdapter() { 067 Map cheeseMap = new HashMap(); 068 069 MutablePicoContainer pico = new DefaultPicoContainer(new ConstructorInjectionComponentAdapterFactory()); 070 pico.registerComponentImplementation(Omelette.class); 071 pico.registerComponent(new CheeseComponentAdapter("scott", Gouda.class, cheeseMap)); 072 073 Cheese gouda = new Gouda(); 074 cheeseMap.put("cheese", gouda); 075 Omelette goudaOmelette = (Omelette) pico.getComponentInstance(Omelette.class); 076 assertSame(gouda, goudaOmelette.getCheese()); 077 078 Cheese roquefort = new Roquefort(); 079 cheeseMap.put("cheese", roquefort); 080 Omelette roquefortOmelette = (Omelette) pico.getComponentInstance(Omelette.class); 081 assertSame(roquefort, roquefortOmelette.getCheese()); 082 } 083 084 public static interface InterfaceX { 085 String getIt(); 086 } 087 088 public static class Enabled implements InterfaceX { 089 public String getIt() { 090 return "Enabled"; 091 } 092 } 093 094 public static class Disabled implements InterfaceX { 095 public String getIt() { 096 return "Disabled"; 097 } 098 } 099 100 public static class Something implements InterfaceX { 101 private final Disabled disabled; 102 private final Enabled enabled; 103 private final Map map; 104 105 public Something(Disabled disabled, Enabled enabled, Map map) { 106 this.disabled = disabled; 107 this.enabled = enabled; 108 this.map = map; 109 } 110 111 public String getIt() { 112 if (map.get("enabled") == null) { 113 return disabled.getIt(); 114 } else { 115 return enabled.getIt(); 116 } 117 } 118 } 119 120 public static class NeedsInterfaceX { 121 private final InterfaceX interfaceX; 122 123 public NeedsInterfaceX(InterfaceX interfaceX) { 124 this.interfaceX = interfaceX; 125 } 126 127 public String getIt() { 128 return interfaceX.getIt(); 129 } 130 } 131 132 public void testMoreWeirdness() { 133 MutablePicoContainer pico = new DefaultPicoContainer(); 134 Map map = new HashMap(); 135 pico.registerComponentInstance(map); 136 // See class level javadoc in DefaultPicoContainer - about precedence. 137 pico.registerComponentImplementation(InterfaceX.class, Something.class); 138 pico.registerComponentImplementation(Disabled.class); 139 pico.registerComponentImplementation(Enabled.class); 140 pico.registerComponentImplementation(NeedsInterfaceX.class); 141 142 NeedsInterfaceX needsInterfaceX = (NeedsInterfaceX) pico.getComponentInstance(NeedsInterfaceX.class); 143 assertEquals("Disabled", needsInterfaceX.getIt()); 144 map.put("enabled", "blah"); 145 assertEquals("Enabled", needsInterfaceX.getIt()); 146 } 147 148 // From John Tal 23/03/2004 149 public static interface ABC { 150 } 151 152 public static interface DEF { 153 } 154 155 public static class ABCImpl implements ABC { 156 public ABCImpl(DEF def) { 157 } 158 } 159 160 public static class DEFImpl implements DEF { 161 public DEFImpl() { 162 } 163 } 164 165 public void testJohnTalOne() { 166 MutablePicoContainer picoContainer = new DefaultPicoContainer(); 167 168 picoContainer.registerComponentImplementation("ABC", ABCImpl.class); 169 picoContainer.registerComponentImplementation("DEF", DEFImpl.class); 170 171 assertEquals(ABCImpl.class, picoContainer.getComponentInstance("ABC").getClass()); 172 } 173 174 public static interface Foo { 175 } 176 177 public static interface Bar { 178 } 179 180 public static class FooBar implements Foo, Bar { 181 } 182 183 public static class NeedsFoo { 184 private final Foo foo; 185 186 public NeedsFoo(Foo foo) { 187 this.foo = foo; 188 } 189 190 public Foo getFoo() { 191 return foo; 192 } 193 } 194 195 public static class NeedsBar { 196 private final Bar bar; 197 198 public NeedsBar(Bar bar) { 199 this.bar = bar; 200 } 201 202 public Bar getBar() { 203 return bar; 204 } 205 } 206 207 public void testShouldBeAbleShareSameReferenceForDifferentTypes() { 208 MutablePicoContainer pico = new DefaultPicoContainer(); 209 pico.registerComponentImplementation(FooBar.class); 210 pico.registerComponentImplementation(NeedsFoo.class); 211 pico.registerComponentImplementation(NeedsBar.class); 212 NeedsFoo needsFoo = (NeedsFoo) pico.getComponentInstance(NeedsFoo.class); 213 NeedsBar needsBar = (NeedsBar) pico.getComponentInstance(NeedsBar.class); 214 assertSame(needsFoo.getFoo(), needsBar.getBar()); 215 } 216 217 public void testSeveralDifferentInstancesCanBeCreatedWithOnePreconfiguredContainer() { 218 // create a container that doesn't cache instances 219 MutablePicoContainer container = new DefaultPicoContainer(new ConstructorInjectionComponentAdapterFactory()); 220 container.registerComponentImplementation(NeedsBar.class); 221 222 Bar barOne = new FooBar(); 223 container.registerComponentInstance(Bar.class, barOne); 224 NeedsBar needsBarOne = (NeedsBar) container.getComponentInstance(NeedsBar.class); 225 assertSame(barOne, needsBarOne.getBar()); 226 227 // reuse the same container - just flip out the existing foo. 228 Bar barTwo = new FooBar(); 229 container.unregisterComponent(Bar.class); 230 container.registerComponentInstance(Bar.class, barTwo); 231 NeedsBar needsBarTwo = (NeedsBar) container.getComponentInstance(NeedsBar.class); 232 assertSame(barTwo, needsBarTwo.getBar()); 233 234 assertNotSame(needsBarOne, needsBarTwo); 235 } 236 }