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 * Original code by *
009 *****************************************************************************/
010 package org.picocontainer.behaviors;
011
012 import java.io.File;
013 import java.net.MalformedURLException;
014 import java.net.URL;
015 import java.text.SimpleDateFormat;
016 import java.util.Date;
017 import java.util.HashMap;
018 import java.util.Map;
019 import java.util.Properties;
020
021 import javax.swing.JLabel;
022
023 import org.picocontainer.ComponentAdapter;
024 import org.picocontainer.Parameter;
025 import org.picocontainer.PicoCompositionException;
026 import org.picocontainer.Characteristics;
027 import org.picocontainer.lifecycle.NullLifecycleStrategy;
028 import org.picocontainer.monitors.NullComponentMonitor;
029 import org.picocontainer.behaviors.PropertyApplyingBehavior;
030 import org.picocontainer.behaviors.PropertyApplyingBehaviorFactory;
031 import org.picocontainer.injectors.AdaptiveInjectionFactory;
032 import org.picocontainer.behaviors.AbstractBehavior;
033 import org.picocontainer.ComponentFactory;
034 import org.picocontainer.tck.AbstractComponentFactoryTestCase;
035 import org.picocontainer.testmodel.SimpleTouchable;
036 import org.picocontainer.testmodel.Touchable;
037
038 /**
039 * @author Aslak Hellesøy
040 * @author Mirko Novakovic
041 * @version $Revision: 3677 $
042 */
043 public class PropertyApplyingBehaviorFactoryTestCase extends AbstractComponentFactoryTestCase {
044
045 public static class Foo {
046 public String message;
047
048 public void setMessage(String message) {
049 this.message = message;
050 }
051 }
052
053 public static class Failing {
054 public void setMessage(String message) {
055 throw new ArrayIndexOutOfBoundsException();
056 }
057 }
058
059 /**
060 * Class that contains all types of Java primitives, to test if they are
061 * set correctly.
062 *
063 * @author Mirko Novakovic
064 */
065 public static class Primitives {
066 public byte byte_;
067 public short short_;
068 public int int_;
069 public long long_;
070 public float float_;
071 public double double_;
072 public boolean boolean_;
073 public char char_;
074 public File file_;
075 public URL url_;
076 public Class class_;
077 public String string_;
078
079 public void setClass_(Class class_) {
080 this.class_ = class_;
081 }
082
083 public void setString_(String string_) {
084 this.string_ = string_;
085 }
086
087 public void setBoolean_(boolean boolean_) {
088 this.boolean_ = boolean_;
089 }
090
091 public void setByte_(byte byte_) {
092 this.byte_ = byte_;
093 }
094
095 public void setChar_(char char_) {
096 this.char_ = char_;
097 }
098
099 public void setDouble_(double double_) {
100 this.double_ = double_;
101 }
102
103 public void setFloat_(float float_) {
104 this.float_ = float_;
105 }
106
107 public void setInt_(int int_) {
108 this.int_ = int_;
109 }
110
111 public void setLong_(long long_) {
112 this.long_ = long_;
113 }
114
115 public void setShort_(short short_) {
116 this.short_ = short_;
117 }
118
119 public void setFile_(File file_) {
120 this.file_ = file_;
121 }
122
123 public void setUrl_(URL url_) {
124 this.url_ = url_;
125 }
126 }
127
128 public static class A {
129 private B b;
130
131 public void setB(B b) {
132 this.b = b;
133 }
134 }
135
136 public static class B {
137 }
138
139 public void testSetProperties() {
140 ComponentAdapter adapter = createAdapterCallingSetMessage(Foo.class);
141 Foo foo = (Foo)adapter.getComponentInstance(null);
142 assertNotNull(foo);
143 assertEquals("hello", foo.message);
144 }
145
146 public void testFailingSetter() {
147 ComponentAdapter adapter = createAdapterCallingSetMessage(Failing.class);
148 try {
149 adapter.getComponentInstance(null);
150 fail();
151 } catch (PicoCompositionException e) {
152 }
153 }
154
155 protected ComponentFactory createComponentFactory() {
156 return new PropertyApplyingBehaviorFactory().forThis(new AdaptiveInjectionFactory());
157 }
158
159 public void testPropertiesSetAfterAdapterCreationShouldBeTakenIntoAccount() {
160 PropertyApplyingBehaviorFactory factory = (PropertyApplyingBehaviorFactory)createComponentFactory();
161
162 PropertyApplyingBehavior adapter =
163 (PropertyApplyingBehavior)factory.createComponentAdapter(new NullComponentMonitor(),
164 new NullLifecycleStrategy(),
165 new Properties(Characteristics
166 .CDI),
167 "foo",
168 Foo.class,
169 (Parameter[])null);
170
171 Map properties = new HashMap();
172 properties.put("message", "hello");
173 adapter.setProperties(properties);
174
175 Foo foo = (Foo)adapter.getComponentInstance(null);
176
177 assertEquals("hello", foo.message);
178 }
179
180
181 public void testDelegateIsAccessible() {
182 AbstractBehavior componentAdapter =
183 (AbstractBehavior)createComponentFactory().createComponentAdapter(new NullComponentMonitor(),
184 new NullLifecycleStrategy(),
185 new Properties(Characteristics
186 .CDI),
187 Touchable.class,
188 SimpleTouchable.class,
189 (Parameter[])null);
190
191 assertNotNull(componentAdapter.getDelegate());
192 }
193
194 private ComponentAdapter createAdapterCallingSetMessage(Class impl) {
195 PropertyApplyingBehaviorFactory factory = (PropertyApplyingBehaviorFactory)createComponentFactory();
196
197 Map properties = new HashMap();
198 properties.put("message", "hello");
199
200 PropertyApplyingBehavior adapter =
201 (PropertyApplyingBehavior)factory.createComponentAdapter(new NullComponentMonitor(),
202 new NullLifecycleStrategy(),
203 new Properties(Characteristics
204 .CDI),
205 impl,
206 impl,
207 (Parameter[])null);
208 adapter.setProperties(properties);
209 return adapter;
210 }
211
212 public void testAllJavaPrimitiveAttributesShouldBeSetByTheAdapter() throws MalformedURLException {
213 PropertyApplyingBehaviorFactory factory = (PropertyApplyingBehaviorFactory)createComponentFactory();
214 Map properties = new HashMap();
215 properties.put("byte_", "1");
216 properties.put("short_", "2");
217 properties.put("int_", "3");
218 properties.put("long_", "4");
219 properties.put("float_", "5.0");
220 properties.put("double_", "6.0");
221 properties.put("char_", "a");
222 properties.put("boolean_", "true");
223 properties.put("file_", "/foo/bar");
224 properties.put("url_", "http://www.picocontainer.org/");
225 properties.put("string_", "g string");
226 properties.put("class_", "javax.swing.JLabel");
227 PropertyApplyingBehavior adapter =
228 (PropertyApplyingBehavior)factory.createComponentAdapter(new NullComponentMonitor(),
229 new NullLifecycleStrategy(),
230 new Properties(Characteristics
231 .CDI),
232 Primitives.class,
233 Primitives.class,
234 (Parameter[])null);
235 adapter.setProperties(properties);
236 Primitives primitives = (Primitives)adapter.getComponentInstance(null);
237
238 assertNotNull(primitives);
239 assertEquals(1, primitives.byte_);
240 assertEquals(2, primitives.short_);
241 assertEquals(3, primitives.int_);
242 assertEquals(4, primitives.long_);
243 assertEquals(5.0, primitives.float_, 0.1);
244 assertEquals(6.0, primitives.double_, 0.1);
245 assertEquals('a', primitives.char_);
246 assertEquals(true, primitives.boolean_);
247 assertEquals(new File("/foo/bar"), primitives.file_);
248 assertEquals(new URL("http://www.picocontainer.org/"), primitives.url_);
249 assertEquals("g string", primitives.string_);
250 assertEquals(JLabel.class, primitives.class_);
251 }
252
253 public void testSetDependenComponentWillBeSetByTheAdapter() {
254 picoContainer.addComponent("b", B.class);
255 PropertyApplyingBehaviorFactory factory = (PropertyApplyingBehaviorFactory)createComponentFactory();
256 Map properties = new HashMap();
257
258 // the second b is the key of the B implementation
259 properties.put("b", "b");
260 PropertyApplyingBehavior adapter =
261 (PropertyApplyingBehavior)factory.createComponentAdapter(new NullComponentMonitor(),
262 new NullLifecycleStrategy(),
263 new Properties(Characteristics
264 .CDI),
265 A.class,
266 A.class,
267 (Parameter[])null);
268 adapter.setProperties(properties);
269 picoContainer.addAdapter(adapter);
270 A a = picoContainer.getComponent(A.class);
271
272 assertNotNull(a);
273 assertNotNull(a.b);
274 }
275
276 public void testSetBeanPropertiesWithValueObjects() {
277 PropertyApplyingBehaviorFactory factory = (PropertyApplyingBehaviorFactory)createComponentFactory();
278
279 Map properties = new HashMap();
280 properties.put("lenient", Boolean.FALSE);
281 properties.put("2DigitYearStart", new Date(0));
282
283 PropertyApplyingBehavior adapter =
284 (PropertyApplyingBehavior)factory.createComponentAdapter(new NullComponentMonitor(),
285 new NullLifecycleStrategy(),
286 new Properties(Characteristics
287 .CDI),
288 SimpleDateFormat.class,
289 SimpleDateFormat.class,
290 (Parameter[])null);
291 adapter.setProperties(properties);
292 picoContainer.addAdapter(adapter);
293
294
295 SimpleDateFormat dateFormat = picoContainer.getComponent(SimpleDateFormat.class);
296 assertNotNull(dateFormat);
297 assertEquals(false, dateFormat.isLenient());
298 assertEquals(new Date(0), dateFormat.get2DigitYearStart());
299 }
300
301
302 /** todo Is this test duplicated elsewhere? --MR */
303 public void testSetBeanPropertiesWithWrongNumberOfParametersThrowsPicoInitializationException() {
304 Object testBean = new Object() {
305 public void setMultiValues(String val1, String Val2) {
306 throw new IllegalStateException("Setter should never have been called");
307 }
308
309 public void setSomeString(String val1) {
310 throw new IllegalStateException("Setter should never have been called");
311 }
312 };
313
314 PropertyApplyingBehaviorFactory factory = (PropertyApplyingBehaviorFactory)createComponentFactory();
315
316
317 PropertyApplyingBehavior adapter =
318 (PropertyApplyingBehavior)factory.createComponentAdapter(new NullComponentMonitor(),
319 new NullLifecycleStrategy(),
320 new Properties(Characteristics
321 .CDI),
322 "TestBean",
323 testBean.getClass(),
324 (Parameter[])null);
325
326 Map properties = new HashMap();
327 properties.put("multiValues", "abcdefg");
328 adapter.setProperties(properties);
329
330 picoContainer.addAdapter(adapter);
331
332 try {
333 Object testResult = picoContainer.getComponent("TestBean");
334 fail(
335 "Getting a bad test result through PropertyApplyingBehavior should have thrown exception. Instead got:" +
336 testResult);
337 } catch (PicoCompositionException ex) {
338 //A-ok
339 }
340
341 }
342
343
344 public void testSetBeanPropertiesWithInvalidValueTypes() {
345 PropertyApplyingBehaviorFactory factory = (PropertyApplyingBehaviorFactory)createComponentFactory();
346
347
348 Map properties = new HashMap();
349
350 // Set two digit year to a boolean (should throw error)
351 properties.put("2DigitYearStart", Boolean.FALSE);
352 PropertyApplyingBehavior adapter =
353 (PropertyApplyingBehavior)factory.createComponentAdapter(new NullComponentMonitor(),
354 new NullLifecycleStrategy(),
355 new Properties(Characteristics
356 .CDI),
357 SimpleDateFormat.class,
358 SimpleDateFormat.class,
359 (Parameter[])null);
360 adapter.setProperties(properties);
361 picoContainer.addAdapter(adapter);
362
363
364 try {
365 SimpleDateFormat dateFormat = picoContainer.getComponent(SimpleDateFormat.class);
366 fail(
367 "Getting a bad test result through PropertyApplyingBehavior should have thrown exception. Instead got:" +
368 dateFormat);
369 } catch (ClassCastException ex) {
370 //A-ok
371 }
372
373 }
374 }