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