001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.commons.configuration.beanutils;
018:
019: import java.util.HashMap;
020: import java.util.Iterator;
021: import java.util.Map;
022:
023: import org.apache.commons.configuration.ConfigurationRuntimeException;
024:
025: import junit.framework.TestCase;
026:
027: /**
028: * Test class for BeanHelper.
029: *
030: * @since 1.3
031: * @author Oliver Heger
032: * @version $Id: TestBeanHelper.java 439648 2006-09-02 20:42:10Z oheger $
033: */
034: public class TestBeanHelper extends TestCase {
035: /** Constant for the name of the test bean factory. */
036: private static final String TEST_FACTORY = "testFactory";
037:
038: /**
039: * Stores the default bean factory. Because this is a static field in
040: * BeanHelper it is temporarily stored and reset after the tests.
041: */
042: private BeanFactory tempDefaultBeanFactory;
043:
044: protected void setUp() throws Exception {
045: super .setUp();
046: tempDefaultBeanFactory = BeanHelper.getDefaultBeanFactory();
047: }
048:
049: protected void tearDown() throws Exception {
050: // Remove all bean factories that might have been registered
051: for (Iterator it = BeanHelper.registeredFactoryNames()
052: .iterator(); it.hasNext();) {
053: BeanHelper.deregisterBeanFactory((String) it.next());
054: }
055: assertTrue("Remaining registered bean factories", BeanHelper
056: .registeredFactoryNames().isEmpty());
057:
058: // Reset old default bean factory
059: BeanHelper.setDefaultBeanFactory(tempDefaultBeanFactory);
060:
061: super .tearDown();
062: }
063:
064: /**
065: * Tests registering a new bean factory.
066: */
067: public void testRegisterBeanFactory() {
068: assertTrue("List of registered factories is not empty",
069: BeanHelper.registeredFactoryNames().isEmpty());
070: BeanHelper.registerBeanFactory(TEST_FACTORY,
071: new TestBeanFactory());
072: assertEquals("Wrong number of registered factories", 1,
073: BeanHelper.registeredFactoryNames().size());
074: assertTrue("Test factory is not contained", BeanHelper
075: .registeredFactoryNames().contains(TEST_FACTORY));
076: }
077:
078: /**
079: * Tries to register a null factory. This should cause an exception.
080: */
081: public void testRegisterBeanFactoryNull() {
082: try {
083: BeanHelper.registerBeanFactory(TEST_FACTORY, null);
084: fail("Could register null factory!");
085: } catch (IllegalArgumentException iex) {
086: // ok
087: }
088: }
089:
090: /**
091: * Tries to register a bean factory with a null name. This should cause an
092: * exception.
093: */
094: public void testRegisterBeanFactoryNullName() {
095: try {
096: BeanHelper.registerBeanFactory(null, new TestBeanFactory());
097: fail("Could register factory with null name!");
098: } catch (IllegalArgumentException iex) {
099: // ok
100: }
101: }
102:
103: /**
104: * Tests to deregister a bean factory.
105: */
106: public void testDeregisterBeanFactory() {
107: assertNull("deregistering non existing factory", BeanHelper
108: .deregisterBeanFactory(TEST_FACTORY));
109: assertNull("deregistering null factory", BeanHelper
110: .deregisterBeanFactory(null));
111: BeanFactory factory = new TestBeanFactory();
112: BeanHelper.registerBeanFactory(TEST_FACTORY, factory);
113: assertSame("Could not deregister factory", factory, BeanHelper
114: .deregisterBeanFactory(TEST_FACTORY));
115: assertTrue("List of factories is not empty", BeanHelper
116: .registeredFactoryNames().isEmpty());
117: }
118:
119: /**
120: * Tests whether the default bean factory is correctly initialized.
121: */
122: public void testGetDefaultBeanFactory() {
123: assertSame("Incorrect default bean factory",
124: DefaultBeanFactory.INSTANCE, tempDefaultBeanFactory);
125: }
126:
127: /**
128: * Tests setting the default bean factory to null. This should caus an
129: * exception.
130: */
131: public void testSetDefaultBeanFactoryNull() {
132: try {
133: BeanHelper.setDefaultBeanFactory(null);
134: fail("Could set default bean factory to null!");
135: } catch (IllegalArgumentException iex) {
136: // ok
137: }
138: }
139:
140: /**
141: * Tests initializing a bean.
142: */
143: public void testInitBean() {
144: BeanHelper.setDefaultBeanFactory(new TestBeanFactory());
145: TestBeanDeclaration data = setUpBeanDeclaration();
146: TestBean bean = new TestBean();
147: BeanHelper.initBean(bean, data);
148: checkBean(bean);
149: }
150:
151: /**
152: * Tests initializing a bean when the bean declaration does not contain any
153: * data.
154: */
155: public void testInitBeanWithNoData() {
156: TestBeanDeclaration data = new TestBeanDeclaration();
157: TestBean bean = new TestBean();
158: BeanHelper.initBean(bean, data);
159: assertNull("Wrong string property", bean.getStringValue());
160: assertEquals("Wrong int property", 0, bean.getIntValue());
161: assertNull("Buddy was set", bean.getBuddy());
162: }
163:
164: /**
165: * Tries to initialize a bean with a bean declaration that contains an
166: * invalid property value. This should cause an exception.
167: */
168: public void testInitBeanWithInvalidProperty() {
169: TestBeanDeclaration data = setUpBeanDeclaration();
170: data.getBeanProperties().put("nonExistingProperty",
171: Boolean.TRUE);
172: try {
173: BeanHelper.initBean(new TestBean(), data);
174: fail("Could initialize non existing property!");
175: } catch (ConfigurationRuntimeException cex) {
176: // ok
177: }
178: }
179:
180: /**
181: * Tests creating a bean. All necessary information is stored in the bean
182: * declaration.
183: */
184: public void testCreateBean() {
185: TestBeanFactory factory = new TestBeanFactory();
186: BeanHelper.registerBeanFactory(TEST_FACTORY, factory);
187: TestBeanDeclaration data = setUpBeanDeclaration();
188: data.setBeanFactoryName(TEST_FACTORY);
189: data.setBeanClassName(TestBean.class.getName());
190: checkBean((TestBean) BeanHelper.createBean(data, null));
191: assertNull("A parameter was passed", factory.parameter);
192: }
193:
194: /**
195: * Tests creating a bean when no bean declaration is provided. This should
196: * cause an exception.
197: */
198: public void testCreateBeanWithNullDeclaration() {
199: try {
200: BeanHelper.createBean(null);
201: fail("Could create bean with null declaration!");
202: } catch (IllegalArgumentException iex) {
203: // ok
204: }
205: }
206:
207: /**
208: * Tests creating a bean. The bean's class is specified as the default class
209: * argument.
210: */
211: public void testCreateBeanWithDefaultClass() {
212: BeanHelper.registerBeanFactory(TEST_FACTORY,
213: new TestBeanFactory());
214: TestBeanDeclaration data = setUpBeanDeclaration();
215: data.setBeanFactoryName(TEST_FACTORY);
216: checkBean((TestBean) BeanHelper
217: .createBean(data, TestBean.class));
218: }
219:
220: /**
221: * Tests creating a bean when the bean's class is specified as the default
222: * class of the bean factory.
223: */
224: public void testCreateBeanWithFactoryDefaultClass() {
225: TestBeanFactory factory = new TestBeanFactory();
226: factory.supportsDefaultClass = true;
227: BeanHelper.registerBeanFactory(TEST_FACTORY, factory);
228: TestBeanDeclaration data = setUpBeanDeclaration();
229: data.setBeanFactoryName(TEST_FACTORY);
230: checkBean((TestBean) BeanHelper.createBean(data, null));
231: }
232:
233: /**
234: * Tries to create a bean when no class is provided. This should cause an
235: * exception.
236: */
237: public void testCreateBeanWithNoClass() {
238: BeanHelper.registerBeanFactory(TEST_FACTORY,
239: new TestBeanFactory());
240: TestBeanDeclaration data = setUpBeanDeclaration();
241: data.setBeanFactoryName(TEST_FACTORY);
242: try {
243: BeanHelper.createBean(data, null);
244: fail("Could create bean without class!");
245: } catch (ConfigurationRuntimeException cex) {
246: // ok
247: }
248: }
249:
250: /**
251: * Tries to create a bean with a non existing class. This should cause an
252: * exception.
253: */
254: public void testCreateBeanWithInvalidClass() {
255: BeanHelper.registerBeanFactory(TEST_FACTORY,
256: new TestBeanFactory());
257: TestBeanDeclaration data = setUpBeanDeclaration();
258: data.setBeanFactoryName(TEST_FACTORY);
259: data.setBeanClassName("non.existing.ClassName");
260: try {
261: BeanHelper.createBean(data, null);
262: fail("Could create bean of an unexisting class!");
263: } catch (ConfigurationRuntimeException cex) {
264: // ok
265: }
266: }
267:
268: /**
269: * Tests creating a bean using the default bean factory.
270: */
271: public void testCreateBeanWithDefaultFactory() {
272: BeanHelper.setDefaultBeanFactory(new TestBeanFactory());
273: TestBeanDeclaration data = setUpBeanDeclaration();
274: data.setBeanClassName(TestBean.class.getName());
275: checkBean((TestBean) BeanHelper.createBean(data, null));
276: }
277:
278: /**
279: * Tests creating a bean using a non registered factory.
280: */
281: public void testCreateBeanWithUnknownFactory() {
282: TestBeanDeclaration data = setUpBeanDeclaration();
283: data.setBeanFactoryName(TEST_FACTORY);
284: data.setBeanClassName(TestBean.class.getName());
285: try {
286: BeanHelper.createBean(data, null);
287: fail("Could create bean with non registered factory!");
288: } catch (ConfigurationRuntimeException cex) {
289: // ok
290: }
291: }
292:
293: /**
294: * Tests creating a bean when the factory throws an exception.
295: */
296: public void testCreateBeanWithException() {
297: BeanHelper.registerBeanFactory(TEST_FACTORY,
298: new TestBeanFactory());
299: TestBeanDeclaration data = setUpBeanDeclaration();
300: data.setBeanFactoryName(TEST_FACTORY);
301: data.setBeanClassName(getClass().getName());
302: try {
303: BeanHelper.createBean(data, null);
304: fail("Could create bean of wrong class!");
305: } catch (ConfigurationRuntimeException cex) {
306: // ok
307: }
308: }
309:
310: /**
311: * Tests if a parameter is correctly passed to the bean factory.
312: */
313: public void testCreateBeanWithParameter() {
314: Object param = new Integer(42);
315: TestBeanFactory factory = new TestBeanFactory();
316: BeanHelper.registerBeanFactory(TEST_FACTORY, factory);
317: TestBeanDeclaration data = setUpBeanDeclaration();
318: data.setBeanFactoryName(TEST_FACTORY);
319: data.setBeanClassName(TestBean.class.getName());
320: checkBean((TestBean) BeanHelper.createBean(data, null, param));
321: assertSame("Wrong parameter", param, factory.parameter);
322: }
323:
324: /**
325: * Returns an initialized bean declaration.
326: *
327: * @return the bean declaration
328: */
329: private TestBeanDeclaration setUpBeanDeclaration() {
330: TestBeanDeclaration data = new TestBeanDeclaration();
331: Map properties = new HashMap();
332: properties.put("stringValue", "testString");
333: properties.put("intValue", "42");
334: data.setBeanProperties(properties);
335: TestBeanDeclaration buddyData = new TestBeanDeclaration();
336: Map properties2 = new HashMap();
337: properties2.put("stringValue", "Another test string");
338: properties2.put("intValue", new Integer(100));
339: buddyData.setBeanProperties(properties2);
340: buddyData.setBeanClassName(TestBean.class.getName());
341: if (BeanHelper.getDefaultBeanFactory() == null) {
342: buddyData.setBeanFactoryName(TEST_FACTORY);
343: }
344: Map nested = new HashMap();
345: nested.put("buddy", buddyData);
346: data.setNestedBeanDeclarations(nested);
347: return data;
348: }
349:
350: /**
351: * Tests if the bean was correctly initialized from the data of the test
352: * bean declaration.
353: *
354: * @param bean the bean to be checked
355: */
356: private void checkBean(TestBean bean) {
357: assertEquals("Wrong string property", "testString", bean
358: .getStringValue());
359: assertEquals("Wrong int property", 42, bean.getIntValue());
360: TestBean buddy = bean.getBuddy();
361: assertNotNull("Buddy was not set", buddy);
362: assertEquals("Wrong string property in buddy",
363: "Another test string", buddy.getStringValue());
364: assertEquals("Wrong int property in buddy", 100, buddy
365: .getIntValue());
366: }
367:
368: /**
369: * A simple bean class used for testing creation operations.
370: */
371: public static class TestBean {
372: private String stringValue;
373:
374: private int intValue;
375:
376: private TestBean buddy;
377:
378: public TestBean getBuddy() {
379: return buddy;
380: }
381:
382: public void setBuddy(TestBean buddy) {
383: this .buddy = buddy;
384: }
385:
386: public int getIntValue() {
387: return intValue;
388: }
389:
390: public void setIntValue(int intValue) {
391: this .intValue = intValue;
392: }
393:
394: public String getStringValue() {
395: return stringValue;
396: }
397:
398: public void setStringValue(String stringValue) {
399: this .stringValue = stringValue;
400: }
401: }
402:
403: /**
404: * An implementation of the BeanFactory interface used for testing. This
405: * implementation is really simple: If the TestBean class is provided, a new
406: * instance will be created. Otherwise an exception is thrown.
407: */
408: static class TestBeanFactory implements BeanFactory {
409: Object parameter;
410:
411: boolean supportsDefaultClass;
412:
413: public Object createBean(Class beanClass, BeanDeclaration data,
414: Object param) throws Exception {
415: parameter = param;
416: if (TestBean.class.equals(beanClass)) {
417: TestBean bean = new TestBean();
418: BeanHelper.initBean(bean, data);
419: return bean;
420: } else {
421: throw new IllegalArgumentException(
422: "Unsupported class: " + beanClass);
423: }
424: }
425:
426: /**
427: * Returns the default class, but only if the supportsDefaultClass flag
428: * is set.
429: */
430: public Class getDefaultBeanClass() {
431: return supportsDefaultClass ? TestBean.class : null;
432: }
433: }
434:
435: /**
436: * A test implementation of the BeanDeclaration interface. This
437: * implementation allows to set the values directly, which should be
438: * returned by the methods required by the BeanDeclaration interface.
439: */
440: static class TestBeanDeclaration implements BeanDeclaration {
441: private String beanClassName;
442:
443: private String beanFactoryName;
444:
445: private Object beanFactoryParameter;
446:
447: private Map beanProperties;
448:
449: private Map nestedBeanDeclarations;
450:
451: public String getBeanClassName() {
452: return beanClassName;
453: }
454:
455: public void setBeanClassName(String beanClassName) {
456: this .beanClassName = beanClassName;
457: }
458:
459: public String getBeanFactoryName() {
460: return beanFactoryName;
461: }
462:
463: public void setBeanFactoryName(String beanFactoryName) {
464: this .beanFactoryName = beanFactoryName;
465: }
466:
467: public Object getBeanFactoryParameter() {
468: return beanFactoryParameter;
469: }
470:
471: public void setBeanFactoryParameter(Object beanFactoryParameter) {
472: this .beanFactoryParameter = beanFactoryParameter;
473: }
474:
475: public Map getBeanProperties() {
476: return beanProperties;
477: }
478:
479: public void setBeanProperties(Map beanProperties) {
480: this .beanProperties = beanProperties;
481: }
482:
483: public Map getNestedBeanDeclarations() {
484: return nestedBeanDeclarations;
485: }
486:
487: public void setNestedBeanDeclarations(Map nestedBeanDeclarations) {
488: this.nestedBeanDeclarations = nestedBeanDeclarations;
489: }
490: }
491: }
|