1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.configuration.beanutils;
18
19 import java.util.HashMap;
20 import java.util.Iterator;
21 import java.util.Map;
22
23 import org.apache.commons.configuration.ConfigurationRuntimeException;
24
25 import junit.framework.TestCase;
26
27 /***
28 * Test class for BeanHelper.
29 *
30 * @since 1.3
31 * @author Oliver Heger
32 * @version $Id: TestBeanHelper.java 570462 2007-08-28 15:56:49Z oheger $
33 */
34 public class TestBeanHelper extends TestCase
35 {
36 /*** Constant for the name of the test bean factory. */
37 private static final String TEST_FACTORY = "testFactory";
38
39 /***
40 * Stores the default bean factory. Because this is a static field in
41 * BeanHelper it is temporarily stored and reset after the tests.
42 */
43 private BeanFactory tempDefaultBeanFactory;
44
45 protected void setUp() throws Exception
46 {
47 super.setUp();
48 tempDefaultBeanFactory = BeanHelper.getDefaultBeanFactory();
49 deregisterFactories();
50 }
51
52 protected void tearDown() throws Exception
53 {
54 deregisterFactories();
55
56
57 BeanHelper.setDefaultBeanFactory(tempDefaultBeanFactory);
58
59 super.tearDown();
60 }
61
62 /***
63 * Removes all bean factories that might have been registered during a test.
64 */
65 private void deregisterFactories()
66 {
67 for (Iterator it = BeanHelper.registeredFactoryNames().iterator(); it
68 .hasNext();)
69 {
70 BeanHelper.deregisterBeanFactory((String) it.next());
71 }
72 assertTrue("Remaining registered bean factories", BeanHelper
73 .registeredFactoryNames().isEmpty());
74 }
75
76 /***
77 * Tests registering a new bean factory.
78 */
79 public void testRegisterBeanFactory()
80 {
81 assertTrue("List of registered factories is not empty", BeanHelper
82 .registeredFactoryNames().isEmpty());
83 BeanHelper.registerBeanFactory(TEST_FACTORY, new TestBeanFactory());
84 assertEquals("Wrong number of registered factories", 1, BeanHelper
85 .registeredFactoryNames().size());
86 assertTrue("Test factory is not contained", BeanHelper
87 .registeredFactoryNames().contains(TEST_FACTORY));
88 }
89
90 /***
91 * Tries to register a null factory. This should cause an exception.
92 */
93 public void testRegisterBeanFactoryNull()
94 {
95 try
96 {
97 BeanHelper.registerBeanFactory(TEST_FACTORY, null);
98 fail("Could register null factory!");
99 }
100 catch (IllegalArgumentException iex)
101 {
102
103 }
104 }
105
106 /***
107 * Tries to register a bean factory with a null name. This should cause an
108 * exception.
109 */
110 public void testRegisterBeanFactoryNullName()
111 {
112 try
113 {
114 BeanHelper.registerBeanFactory(null, new TestBeanFactory());
115 fail("Could register factory with null name!");
116 }
117 catch (IllegalArgumentException iex)
118 {
119
120 }
121 }
122
123 /***
124 * Tests to deregister a bean factory.
125 */
126 public void testDeregisterBeanFactory()
127 {
128 assertNull("deregistering non existing factory", BeanHelper
129 .deregisterBeanFactory(TEST_FACTORY));
130 assertNull("deregistering null factory", BeanHelper
131 .deregisterBeanFactory(null));
132 BeanFactory factory = new TestBeanFactory();
133 BeanHelper.registerBeanFactory(TEST_FACTORY, factory);
134 assertSame("Could not deregister factory", factory, BeanHelper
135 .deregisterBeanFactory(TEST_FACTORY));
136 assertTrue("List of factories is not empty", BeanHelper
137 .registeredFactoryNames().isEmpty());
138 }
139
140 /***
141 * Tests whether the default bean factory is correctly initialized.
142 */
143 public void testGetDefaultBeanFactory()
144 {
145 assertSame("Incorrect default bean factory",
146 DefaultBeanFactory.INSTANCE, tempDefaultBeanFactory);
147 }
148
149 /***
150 * Tests setting the default bean factory to null. This should caus an
151 * exception.
152 */
153 public void testSetDefaultBeanFactoryNull()
154 {
155 try
156 {
157 BeanHelper.setDefaultBeanFactory(null);
158 fail("Could set default bean factory to null!");
159 }
160 catch (IllegalArgumentException iex)
161 {
162
163 }
164 }
165
166 /***
167 * Tests initializing a bean.
168 */
169 public void testInitBean()
170 {
171 BeanHelper.setDefaultBeanFactory(new TestBeanFactory());
172 TestBeanDeclaration data = setUpBeanDeclaration();
173 TestBean bean = new TestBean();
174 BeanHelper.initBean(bean, data);
175 checkBean(bean);
176 }
177
178 /***
179 * Tests initializing a bean when the bean declaration does not contain any
180 * data.
181 */
182 public void testInitBeanWithNoData()
183 {
184 TestBeanDeclaration data = new TestBeanDeclaration();
185 TestBean bean = new TestBean();
186 BeanHelper.initBean(bean, data);
187 assertNull("Wrong string property", bean.getStringValue());
188 assertEquals("Wrong int property", 0, bean.getIntValue());
189 assertNull("Buddy was set", bean.getBuddy());
190 }
191
192 /***
193 * Tries to initialize a bean with a bean declaration that contains an
194 * invalid property value. This should cause an exception.
195 */
196 public void testInitBeanWithInvalidProperty()
197 {
198 TestBeanDeclaration data = setUpBeanDeclaration();
199 data.getBeanProperties().put("nonExistingProperty", Boolean.TRUE);
200 try
201 {
202 BeanHelper.initBean(new TestBean(), data);
203 fail("Could initialize non existing property!");
204 }
205 catch (ConfigurationRuntimeException cex)
206 {
207
208 }
209 }
210
211 /***
212 * Tests creating a bean. All necessary information is stored in the bean
213 * declaration.
214 */
215 public void testCreateBean()
216 {
217 TestBeanFactory factory = new TestBeanFactory();
218 BeanHelper.registerBeanFactory(TEST_FACTORY, factory);
219 TestBeanDeclaration data = setUpBeanDeclaration();
220 data.setBeanFactoryName(TEST_FACTORY);
221 data.setBeanClassName(TestBean.class.getName());
222 checkBean((TestBean) BeanHelper.createBean(data, null));
223 assertNull("A parameter was passed", factory.parameter);
224 }
225
226 /***
227 * Tests creating a bean when no bean declaration is provided. This should
228 * cause an exception.
229 */
230 public void testCreateBeanWithNullDeclaration()
231 {
232 try
233 {
234 BeanHelper.createBean(null);
235 fail("Could create bean with null declaration!");
236 }
237 catch (IllegalArgumentException iex)
238 {
239
240 }
241 }
242
243 /***
244 * Tests creating a bean. The bean's class is specified as the default class
245 * argument.
246 */
247 public void testCreateBeanWithDefaultClass()
248 {
249 BeanHelper.registerBeanFactory(TEST_FACTORY, new TestBeanFactory());
250 TestBeanDeclaration data = setUpBeanDeclaration();
251 data.setBeanFactoryName(TEST_FACTORY);
252 checkBean((TestBean) BeanHelper.createBean(data, TestBean.class));
253 }
254
255 /***
256 * Tests creating a bean when the bean's class is specified as the default
257 * class of the bean factory.
258 */
259 public void testCreateBeanWithFactoryDefaultClass()
260 {
261 TestBeanFactory factory = new TestBeanFactory();
262 factory.supportsDefaultClass = true;
263 BeanHelper.registerBeanFactory(TEST_FACTORY, factory);
264 TestBeanDeclaration data = setUpBeanDeclaration();
265 data.setBeanFactoryName(TEST_FACTORY);
266 checkBean((TestBean) BeanHelper.createBean(data, null));
267 }
268
269 /***
270 * Tries to create a bean when no class is provided. This should cause an
271 * exception.
272 */
273 public void testCreateBeanWithNoClass()
274 {
275 BeanHelper.registerBeanFactory(TEST_FACTORY, new TestBeanFactory());
276 TestBeanDeclaration data = setUpBeanDeclaration();
277 data.setBeanFactoryName(TEST_FACTORY);
278 try
279 {
280 BeanHelper.createBean(data, null);
281 fail("Could create bean without class!");
282 }
283 catch (ConfigurationRuntimeException cex)
284 {
285
286 }
287 }
288
289 /***
290 * Tries to create a bean with a non existing class. This should cause an
291 * exception.
292 */
293 public void testCreateBeanWithInvalidClass()
294 {
295 BeanHelper.registerBeanFactory(TEST_FACTORY, new TestBeanFactory());
296 TestBeanDeclaration data = setUpBeanDeclaration();
297 data.setBeanFactoryName(TEST_FACTORY);
298 data.setBeanClassName("non.existing.ClassName");
299 try
300 {
301 BeanHelper.createBean(data, null);
302 fail("Could create bean of an unexisting class!");
303 }
304 catch (ConfigurationRuntimeException cex)
305 {
306
307 }
308 }
309
310 /***
311 * Tests creating a bean using the default bean factory.
312 */
313 public void testCreateBeanWithDefaultFactory()
314 {
315 BeanHelper.setDefaultBeanFactory(new TestBeanFactory());
316 TestBeanDeclaration data = setUpBeanDeclaration();
317 data.setBeanClassName(TestBean.class.getName());
318 checkBean((TestBean) BeanHelper.createBean(data, null));
319 }
320
321 /***
322 * Tests creating a bean using a non registered factory.
323 */
324 public void testCreateBeanWithUnknownFactory()
325 {
326 TestBeanDeclaration data = setUpBeanDeclaration();
327 data.setBeanFactoryName(TEST_FACTORY);
328 data.setBeanClassName(TestBean.class.getName());
329 try
330 {
331 BeanHelper.createBean(data, null);
332 fail("Could create bean with non registered factory!");
333 }
334 catch (ConfigurationRuntimeException cex)
335 {
336
337 }
338 }
339
340 /***
341 * Tests creating a bean when the factory throws an exception.
342 */
343 public void testCreateBeanWithException()
344 {
345 BeanHelper.registerBeanFactory(TEST_FACTORY, new TestBeanFactory());
346 TestBeanDeclaration data = setUpBeanDeclaration();
347 data.setBeanFactoryName(TEST_FACTORY);
348 data.setBeanClassName(getClass().getName());
349 try
350 {
351 BeanHelper.createBean(data, null);
352 fail("Could create bean of wrong class!");
353 }
354 catch (ConfigurationRuntimeException cex)
355 {
356
357 }
358 }
359
360 /***
361 * Tests if a parameter is correctly passed to the bean factory.
362 */
363 public void testCreateBeanWithParameter()
364 {
365 Object param = new Integer(42);
366 TestBeanFactory factory = new TestBeanFactory();
367 BeanHelper.registerBeanFactory(TEST_FACTORY, factory);
368 TestBeanDeclaration data = setUpBeanDeclaration();
369 data.setBeanFactoryName(TEST_FACTORY);
370 data.setBeanClassName(TestBean.class.getName());
371 checkBean((TestBean) BeanHelper.createBean(data, null, param));
372 assertSame("Wrong parameter", param, factory.parameter);
373 }
374
375 /***
376 * Returns an initialized bean declaration.
377 *
378 * @return the bean declaration
379 */
380 private TestBeanDeclaration setUpBeanDeclaration()
381 {
382 TestBeanDeclaration data = new TestBeanDeclaration();
383 Map properties = new HashMap();
384 properties.put("stringValue", "testString");
385 properties.put("intValue", "42");
386 data.setBeanProperties(properties);
387 TestBeanDeclaration buddyData = new TestBeanDeclaration();
388 Map properties2 = new HashMap();
389 properties2.put("stringValue", "Another test string");
390 properties2.put("intValue", new Integer(100));
391 buddyData.setBeanProperties(properties2);
392 buddyData.setBeanClassName(TestBean.class.getName());
393 if (BeanHelper.getDefaultBeanFactory() == null)
394 {
395 buddyData.setBeanFactoryName(TEST_FACTORY);
396 }
397 Map nested = new HashMap();
398 nested.put("buddy", buddyData);
399 data.setNestedBeanDeclarations(nested);
400 return data;
401 }
402
403 /***
404 * Tests if the bean was correctly initialized from the data of the test
405 * bean declaration.
406 *
407 * @param bean the bean to be checked
408 */
409 private void checkBean(TestBean bean)
410 {
411 assertEquals("Wrong string property", "testString", bean
412 .getStringValue());
413 assertEquals("Wrong int property", 42, bean.getIntValue());
414 TestBean buddy = bean.getBuddy();
415 assertNotNull("Buddy was not set", buddy);
416 assertEquals("Wrong string property in buddy", "Another test string",
417 buddy.getStringValue());
418 assertEquals("Wrong int property in buddy", 100, buddy.getIntValue());
419 }
420
421 /***
422 * A simple bean class used for testing creation operations.
423 */
424 public static class TestBean
425 {
426 private String stringValue;
427
428 private int intValue;
429
430 private TestBean buddy;
431
432 public TestBean getBuddy()
433 {
434 return buddy;
435 }
436
437 public void setBuddy(TestBean buddy)
438 {
439 this.buddy = buddy;
440 }
441
442 public int getIntValue()
443 {
444 return intValue;
445 }
446
447 public void setIntValue(int intValue)
448 {
449 this.intValue = intValue;
450 }
451
452 public String getStringValue()
453 {
454 return stringValue;
455 }
456
457 public void setStringValue(String stringValue)
458 {
459 this.stringValue = stringValue;
460 }
461 }
462
463 /***
464 * An implementation of the BeanFactory interface used for testing. This
465 * implementation is really simple: If the TestBean class is provided, a new
466 * instance will be created. Otherwise an exception is thrown.
467 */
468 static class TestBeanFactory implements BeanFactory
469 {
470 Object parameter;
471
472 boolean supportsDefaultClass;
473
474 public Object createBean(Class beanClass, BeanDeclaration data, Object param)
475 throws Exception
476 {
477 parameter = param;
478 if (TestBean.class.equals(beanClass))
479 {
480 TestBean bean = new TestBean();
481 BeanHelper.initBean(bean, data);
482 return bean;
483 }
484 else
485 {
486 throw new IllegalArgumentException("Unsupported class: "
487 + beanClass);
488 }
489 }
490
491 /***
492 * Returns the default class, but only if the supportsDefaultClass flag
493 * is set.
494 */
495 public Class getDefaultBeanClass()
496 {
497 return supportsDefaultClass ? TestBean.class : null;
498 }
499 }
500
501 /***
502 * A test implementation of the BeanDeclaration interface. This
503 * implementation allows to set the values directly, which should be
504 * returned by the methods required by the BeanDeclaration interface.
505 */
506 static class TestBeanDeclaration implements BeanDeclaration
507 {
508 private String beanClassName;
509
510 private String beanFactoryName;
511
512 private Object beanFactoryParameter;
513
514 private Map beanProperties;
515
516 private Map nestedBeanDeclarations;
517
518 public String getBeanClassName()
519 {
520 return beanClassName;
521 }
522
523 public void setBeanClassName(String beanClassName)
524 {
525 this.beanClassName = beanClassName;
526 }
527
528 public String getBeanFactoryName()
529 {
530 return beanFactoryName;
531 }
532
533 public void setBeanFactoryName(String beanFactoryName)
534 {
535 this.beanFactoryName = beanFactoryName;
536 }
537
538 public Object getBeanFactoryParameter()
539 {
540 return beanFactoryParameter;
541 }
542
543 public void setBeanFactoryParameter(Object beanFactoryParameter)
544 {
545 this.beanFactoryParameter = beanFactoryParameter;
546 }
547
548 public Map getBeanProperties()
549 {
550 return beanProperties;
551 }
552
553 public void setBeanProperties(Map beanProperties)
554 {
555 this.beanProperties = beanProperties;
556 }
557
558 public Map getNestedBeanDeclarations()
559 {
560 return nestedBeanDeclarations;
561 }
562
563 public void setNestedBeanDeclarations(Map nestedBeanDeclarations)
564 {
565 this.nestedBeanDeclarations = nestedBeanDeclarations;
566 }
567 }
568 }