| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.apache.commons.configuration2.beanutils; |
| |
| import static org.junit.Assert.assertEquals; |
| import static org.junit.Assert.assertNotNull; |
| import static org.junit.Assert.assertNull; |
| import static org.junit.Assert.assertSame; |
| import static org.junit.Assert.assertTrue; |
| import static org.junit.Assert.fail; |
| |
| import java.lang.reflect.Constructor; |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.Collections; |
| import java.util.HashMap; |
| import java.util.Map; |
| |
| import org.apache.commons.configuration2.PropertiesConfiguration; |
| import org.apache.commons.configuration2.convert.ConversionHandler; |
| import org.apache.commons.configuration2.convert.DefaultConversionHandler; |
| import org.apache.commons.configuration2.ex.ConfigurationRuntimeException; |
| import org.easymock.EasyMock; |
| import org.junit.Before; |
| import org.junit.Test; |
| |
| /** |
| * Test class for DefaultBeanFactory. |
| * |
| * @since 1.3 |
| */ |
| public class TestDefaultBeanFactory |
| { |
| /** Constant for the test value of the string property. */ |
| private static final String TEST_STRING = "testString"; |
| |
| /** Constant for the test value of the numeric property. */ |
| private static final int TEST_INT = 42; |
| |
| /** The object to be tested. */ |
| private DefaultBeanFactory factory; |
| |
| @Before |
| public void setUp() throws Exception |
| { |
| factory = new DefaultBeanFactory(); |
| } |
| |
| /** |
| * Creates a bean creation context for a create operation. |
| * |
| * @param cls the bean class |
| * @param decl the bean declaration |
| * @return the new creation context |
| */ |
| private static BeanCreationContext createBcc(final Class<?> cls, |
| final BeanDeclaration decl) |
| { |
| return new BeanCreationContext() |
| { |
| private final BeanHelper beanHelper = new BeanHelper(); |
| |
| @Override |
| public void initBean(final Object bean, final BeanDeclaration data) |
| { |
| beanHelper.initBean(bean, data); |
| } |
| |
| @Override |
| public Object getParameter() |
| { |
| return null; |
| } |
| |
| @Override |
| public BeanDeclaration getBeanDeclaration() |
| { |
| return decl; |
| } |
| |
| @Override |
| public Class<?> getBeanClass() |
| { |
| return cls; |
| } |
| |
| @Override |
| public Object createBean(final BeanDeclaration data) |
| { |
| return beanHelper.createBean(data); |
| } |
| }; |
| } |
| |
| /** |
| * Tests obtaining the default class. This should be null. |
| */ |
| @Test |
| public void testGetDefaultBeanClass() |
| { |
| assertNull("Default class is not null", factory.getDefaultBeanClass()); |
| } |
| |
| /** |
| * Tests whether a correct default conversion handler is set. |
| */ |
| @Test |
| public void testDefaultConversionHandler() |
| { |
| assertSame("Wrong default conversion handler", |
| DefaultConversionHandler.INSTANCE, |
| factory.getConversionHandler()); |
| } |
| |
| /** |
| * Tests whether a custom conversion handler can be passed to the |
| * constructor. |
| */ |
| @Test |
| public void testInitWithConversionHandler() |
| { |
| final ConversionHandler handler = |
| EasyMock.createMock(ConversionHandler.class); |
| EasyMock.replay(handler); |
| factory = new DefaultBeanFactory(handler); |
| assertSame("Wrong conversion handler", handler, |
| factory.getConversionHandler()); |
| } |
| |
| /** |
| * Tests creating a bean. |
| */ |
| @Test |
| public void testCreateBean() throws Exception |
| { |
| final BeanDeclarationTestImpl decl = new BeanDeclarationTestImpl(); |
| final Map<String, Object> props = new HashMap<>(); |
| props.put("throwExceptionOnMissing", Boolean.TRUE); |
| decl.setBeanProperties(props); |
| final Object bean = factory.createBean(createBcc(PropertiesConfiguration.class, decl)); |
| assertNotNull("New bean is null", bean); |
| assertEquals("Bean is of wrong class", PropertiesConfiguration.class, |
| bean.getClass()); |
| final PropertiesConfiguration config = (PropertiesConfiguration) bean; |
| assertTrue("Bean was not initialized", config |
| .isThrowExceptionOnMissing()); |
| } |
| |
| /** |
| * Tests whether a bean can be created by calling its constructor. |
| */ |
| @Test |
| public void testCreateBeanConstructor() throws Exception |
| { |
| final BeanDeclarationTestImpl decl = new BeanDeclarationTestImpl(); |
| final Collection<ConstructorArg> args = new ArrayList<>(); |
| args.add(ConstructorArg.forValue("test")); |
| args.add(ConstructorArg.forValue("42")); |
| decl.setConstructorArgs(args); |
| final BeanCreationTestCtorBean bean = |
| (BeanCreationTestCtorBean) factory.createBean(createBcc( |
| BeanCreationTestCtorBean.class, decl)); |
| assertEquals("Wrong string property", "test", bean.getStringValue()); |
| assertEquals("Wrong int property", 42, bean.getIntValue()); |
| } |
| |
| /** |
| * Tests whether nested bean declarations in constructor arguments are taken |
| * into account. |
| */ |
| @Test |
| public void testCreateBeanConstructorNestedBean() throws Exception |
| { |
| final BeanDeclarationTestImpl declNested = new BeanDeclarationTestImpl(); |
| final Collection<ConstructorArg> args = new ArrayList<>(); |
| args.add(ConstructorArg.forValue("test", String.class.getName())); |
| declNested.setConstructorArgs(args); |
| declNested.setBeanClassName(BeanCreationTestCtorBean.class.getName()); |
| final BeanDeclarationTestImpl decl = new BeanDeclarationTestImpl(); |
| decl.setConstructorArgs(Collections.singleton(ConstructorArg |
| .forBeanDeclaration(declNested, |
| BeanCreationTestBean.class.getName()))); |
| final BeanCreationTestCtorBean bean = |
| (BeanCreationTestCtorBean) factory.createBean(createBcc( |
| BeanCreationTestCtorBean.class, decl)); |
| assertNotNull("Buddy bean was not set", bean.getBuddy()); |
| assertEquals("Wrong property of buddy bean", "test", bean.getBuddy() |
| .getStringValue()); |
| } |
| |
| /** |
| * Tests whether the standard constructor can be found. |
| */ |
| @Test |
| public void testFindMatchingConstructorNoArgs() |
| { |
| final BeanDeclarationTestImpl decl = new BeanDeclarationTestImpl(); |
| final Constructor<BeanCreationTestBean> ctor = |
| DefaultBeanFactory.findMatchingConstructor(BeanCreationTestBean.class, decl); |
| assertEquals("Not the standard constructor", 0, |
| ctor.getParameterTypes().length); |
| } |
| |
| /** |
| * Tests whether a matching constructor is found if the number of arguments |
| * is unique. |
| */ |
| @Test |
| public void testFindMatchingConstructorArgCount() |
| { |
| final BeanDeclarationTestImpl decl = new BeanDeclarationTestImpl(); |
| final Collection<ConstructorArg> args = new ArrayList<>(); |
| args.add(ConstructorArg.forValue(TEST_STRING)); |
| args.add(ConstructorArg.forValue(String.valueOf(TEST_INT))); |
| decl.setConstructorArgs(args); |
| final Constructor<BeanCreationTestCtorBean> ctor = |
| DefaultBeanFactory.findMatchingConstructor(BeanCreationTestCtorBean.class, decl); |
| final Class<?>[] paramTypes = ctor.getParameterTypes(); |
| assertEquals("Wrong number of parameters", 2, paramTypes.length); |
| assertEquals("Wrong parameter type 1", String.class, paramTypes[0]); |
| assertEquals("Wrong parameter type 2", Integer.TYPE, paramTypes[1]); |
| } |
| |
| /** |
| * Tests whether ambiguous constructor arguments are detected. |
| */ |
| @Test(expected = ConfigurationRuntimeException.class) |
| public void testFindMatchingConstructorAmbiguous() |
| { |
| final BeanDeclarationTestImpl decl = new BeanDeclarationTestImpl(); |
| final Collection<ConstructorArg> args = new ArrayList<>(); |
| args.add(ConstructorArg.forValue(TEST_STRING)); |
| decl.setConstructorArgs(args); |
| DefaultBeanFactory.findMatchingConstructor(BeanCreationTestCtorBean.class, decl); |
| } |
| |
| /** |
| * Tests whether explicit type declarations are used to resolve ambiguous |
| * parameter types. |
| */ |
| @Test |
| public void testFindMatchingConstructorExplicitType() |
| { |
| final BeanDeclarationTestImpl decl = new BeanDeclarationTestImpl(); |
| final Collection<ConstructorArg> args = new ArrayList<>(); |
| args.add(ConstructorArg.forBeanDeclaration(setUpBeanDeclaration(), |
| BeanCreationTestBean.class.getName())); |
| decl.setConstructorArgs(args); |
| final Constructor<BeanCreationTestCtorBean> ctor = |
| DefaultBeanFactory.findMatchingConstructor(BeanCreationTestCtorBean.class, decl); |
| final Class<?>[] paramTypes = ctor.getParameterTypes(); |
| assertEquals("Wrong number of parameters", 1, paramTypes.length); |
| assertEquals("Wrong parameter type", BeanCreationTestBean.class, paramTypes[0]); |
| } |
| |
| /** |
| * Returns an initialized bean declaration. |
| * |
| * @return the bean declaration |
| */ |
| private static BeanDeclarationTestImpl setUpBeanDeclaration() |
| { |
| final BeanDeclarationTestImpl data = new BeanDeclarationTestImpl(); |
| final Map<String, Object> properties = new HashMap<>(); |
| properties.put("stringValue", TEST_STRING); |
| properties.put("intValue", String.valueOf(TEST_INT)); |
| data.setBeanProperties(properties); |
| final BeanDeclarationTestImpl buddyData = new BeanDeclarationTestImpl(); |
| final Map<String, Object> properties2 = new HashMap<>(); |
| properties2.put("stringValue", "Another test string"); |
| properties2.put("intValue", Integer.valueOf(100)); |
| buddyData.setBeanProperties(properties2); |
| buddyData.setBeanClassName(BeanCreationTestBean.class.getName()); |
| |
| final Map<String, Object> nested = new HashMap<>(); |
| nested.put("buddy", buddyData); |
| data.setNestedBeanDeclarations(nested); |
| return data; |
| } |
| |
| /** |
| * Tests the case that no matching constructor is found. |
| */ |
| @Test |
| public void testFindMatchingConstructorNoMatch() |
| { |
| final BeanDeclarationTestImpl decl = new BeanDeclarationTestImpl(); |
| final Collection<ConstructorArg> args = new ArrayList<>(); |
| args.add(ConstructorArg.forValue(TEST_STRING, getClass().getName())); |
| decl.setConstructorArgs(args); |
| try |
| { |
| DefaultBeanFactory.findMatchingConstructor(BeanCreationTestCtorBean.class, decl); |
| fail("No exception thrown!"); |
| } |
| catch (final ConfigurationRuntimeException crex) |
| { |
| final String msg = crex.getMessage(); |
| assertTrue("Bean class not found:" + msg, |
| msg.indexOf(BeanCreationTestCtorBean.class.getName()) > 0); |
| assertTrue("Parameter value not found: " + msg, |
| msg.indexOf(TEST_STRING) > 0); |
| assertTrue("Parameter type not found: " + msg, |
| msg.indexOf("(" + getClass().getName() + ')') > 0); |
| } |
| } |
| } |