| /* |
| * 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.configuration; |
| |
| import java.io.File; |
| import java.io.IOException; |
| import java.io.StringWriter; |
| import java.util.Collection; |
| import java.util.HashMap; |
| import java.util.Map; |
| import java.util.Set; |
| import java.util.List; |
| import java.util.Iterator; |
| |
| import junit.framework.TestCase; |
| |
| import org.apache.commons.configuration.beanutils.BeanHelper; |
| import org.apache.commons.configuration.reloading.FileChangedReloadingStrategy; |
| import org.apache.commons.configuration.tree.DefaultConfigurationNode; |
| import org.apache.commons.configuration.tree.ConfigurationNode; |
| import org.apache.commons.configuration.tree.xpath.XPathExpressionEngine; |
| import org.apache.commons.lang.text.StrLookup; |
| import org.apache.commons.logging.LogFactory; |
| import org.apache.commons.logging.Log; |
| import org.apache.commons.logging.impl.Log4JLogger; |
| import org.apache.log4j.WriterAppender; |
| import org.apache.log4j.Logger; |
| import org.apache.log4j.Level; |
| import org.apache.log4j.SimpleLayout; |
| |
| /** |
| * Test class for DefaultConfigurationBuilder. |
| * |
| * @author Oliver Heger |
| * @version $Id$ |
| */ |
| public class TestDefaultConfigurationBuilder extends TestCase |
| { |
| /** Test configuration definition file. */ |
| private static final File TEST_FILE = new File( |
| "conf/testDigesterConfiguration.xml"); |
| |
| private static final File ADDITIONAL_FILE = new File( |
| "conf/testDigesterConfiguration2.xml"); |
| |
| private static final File OPTIONAL_FILE = new File( |
| "conf/testDigesterOptionalConfiguration.xml"); |
| |
| private static final File OPTIONALEX_FILE = new File( |
| "conf/testDigesterOptionalConfigurationEx.xml"); |
| |
| private static final File MULTI_FILE = new File( |
| "conf/testDigesterConfiguration3.xml"); |
| |
| private static final File INIT_FILE = new File( |
| "conf/testComplexInitialization.xml"); |
| |
| private static final File CLASS_FILE = new File( |
| "conf/testExtendedClass.xml"); |
| |
| private static final File PROVIDER_FILE = new File( |
| "conf/testConfigurationProvider.xml"); |
| |
| private static final File EXTENDED_PROVIDER_FILE = new File( |
| "conf/testExtendedXMLConfigurationProvider.xml"); |
| |
| private static final File GLOBAL_LOOKUP_FILE = new File( |
| "conf/testGlobalLookup.xml"); |
| |
| private static final File SYSTEM_PROPS_FILE = new File( |
| "conf/testSystemProperties.xml"); |
| |
| private static final File VALIDATION_FILE = new File( |
| "conf/testValidation.xml"); |
| |
| private static final File VALIDATION3_FILE = new File( |
| "conf/testValidation3.xml"); |
| |
| private static final File MULTI_TENENT_FILE = new File( |
| "conf/testMultiTenentConfigurationBuilder.xml"); |
| |
| private static final File EXPRESSION_FILE = new File( |
| "conf/testExpression.xml"); |
| |
| /** Constant for the name of an optional configuration.*/ |
| private static final String OPTIONAL_NAME = "optionalConfig"; |
| |
| /** Stores the object to be tested. */ |
| DefaultConfigurationBuilder factory; |
| |
| protected void setUp() throws Exception |
| { |
| super.setUp(); |
| System |
| .setProperty("java.naming.factory.initial", |
| "org.apache.commons.configuration.MockInitialContextFactory"); |
| System.setProperty("test_file_xml", "test.xml"); |
| System.setProperty("test_file_combine", "testcombine1.xml"); |
| factory = new DefaultConfigurationBuilder(); |
| factory.clearErrorListeners(); // avoid exception messages |
| } |
| |
| /** |
| * Tests the isReservedNode() method of ConfigurationDeclaration. |
| */ |
| public void testConfigurationDeclarationIsReserved() |
| { |
| DefaultConfigurationBuilder.ConfigurationDeclaration decl = new DefaultConfigurationBuilder.ConfigurationDeclaration( |
| factory, factory); |
| DefaultConfigurationNode parent = new DefaultConfigurationNode(); |
| DefaultConfigurationNode nd = new DefaultConfigurationNode("at"); |
| parent.addAttribute(nd); |
| assertTrue("Attribute at not recognized", decl.isReservedNode(nd)); |
| nd = new DefaultConfigurationNode("optional"); |
| parent.addAttribute(nd); |
| assertTrue("Attribute optional not recognized", decl.isReservedNode(nd)); |
| nd = new DefaultConfigurationNode("config-class"); |
| parent.addAttribute(nd); |
| assertTrue("Inherited attribute not recognized", decl |
| .isReservedNode(nd)); |
| nd = new DefaultConfigurationNode("different"); |
| parent.addAttribute(nd); |
| assertFalse("Wrong reserved attribute", decl.isReservedNode(nd)); |
| nd = new DefaultConfigurationNode("at"); |
| parent.addChild(nd); |
| assertFalse("Node type not evaluated", decl.isReservedNode(nd)); |
| } |
| |
| /** |
| * Tests if the at attribute is correctly detected as reserved attribute. |
| */ |
| public void testConfigurationDeclarationIsReservedAt() |
| { |
| checkOldReservedAttribute("at"); |
| } |
| |
| /** |
| * Tests if the optional attribute is correctly detected as reserved |
| * attribute. |
| */ |
| public void testConfigurationDeclarationIsReservedOptional() |
| { |
| checkOldReservedAttribute("optional"); |
| } |
| |
| /** |
| * Tests if special reserved attributes are recognized by the |
| * isReservedNode() method. For compatibility reasons the attributes "at" |
| * and "optional" are also treated as reserved attributes, but only if there |
| * are no corresponding attributes with the "config-" prefix. |
| * |
| * @param name the attribute name |
| */ |
| private void checkOldReservedAttribute(String name) |
| { |
| DefaultConfigurationBuilder.ConfigurationDeclaration decl = new DefaultConfigurationBuilder.ConfigurationDeclaration( |
| factory, factory); |
| DefaultConfigurationNode parent = new DefaultConfigurationNode(); |
| DefaultConfigurationNode nd = new DefaultConfigurationNode("config-" |
| + name); |
| parent.addAttribute(nd); |
| assertTrue("config-" + name + " attribute not recognized", decl |
| .isReservedNode(nd)); |
| DefaultConfigurationNode nd2 = new DefaultConfigurationNode(name); |
| parent.addAttribute(nd2); |
| assertFalse(name + " is reserved though config- exists", decl |
| .isReservedNode(nd2)); |
| assertTrue("config- attribute not recognized when " + name + " exists", |
| decl.isReservedNode(nd)); |
| } |
| |
| /** |
| * Tests access to certain reserved attributes of a |
| * ConfigurationDeclaration. |
| */ |
| public void testConfigurationDeclarationGetAttributes() |
| { |
| factory.addProperty("xml.fileName", "test.xml"); |
| DefaultConfigurationBuilder.ConfigurationDeclaration decl = new DefaultConfigurationBuilder.ConfigurationDeclaration( |
| factory, factory.configurationAt("xml")); |
| assertNull("Found an at attribute", decl.getAt()); |
| assertFalse("Found an optional attribute", decl.isOptional()); |
| factory.addProperty("xml[@config-at]", "test1"); |
| assertEquals("Wrong value of at attribute", "test1", decl.getAt()); |
| factory.addProperty("xml[@at]", "test2"); |
| assertEquals("Wrong value of config-at attribute", "test1", decl.getAt()); |
| factory.clearProperty("xml[@config-at]"); |
| assertEquals("Old at attribute not detected", "test2", decl.getAt()); |
| factory.addProperty("xml[@config-optional]", "true"); |
| assertTrue("Wrong value of optional attribute", decl.isOptional()); |
| factory.addProperty("xml[@optional]", "false"); |
| assertTrue("Wrong value of config-optional attribute", decl.isOptional()); |
| factory.clearProperty("xml[@config-optional]"); |
| factory.setProperty("xml[@optional]", Boolean.TRUE); |
| assertTrue("Old optional attribute not detected", decl.isOptional()); |
| factory.setProperty("xml[@optional]", "invalid value"); |
| try |
| { |
| decl.isOptional(); |
| fail("Invalid optional attribute was not detected!"); |
| } |
| catch (ConfigurationRuntimeException crex) |
| { |
| // ok |
| } |
| } |
| |
| /** |
| * Tests adding a new configuration provider. |
| */ |
| public void testAddConfigurationProvider() |
| { |
| DefaultConfigurationBuilder.ConfigurationProvider provider = new DefaultConfigurationBuilder.ConfigurationProvider(); |
| assertNull("Provider already registered", factory |
| .providerForTag("test")); |
| factory.addConfigurationProvider("test", provider); |
| assertSame("Provider not registered", provider, factory |
| .providerForTag("test")); |
| } |
| |
| /** |
| * Tries to register a null configuration provider. This should cause an |
| * exception. |
| */ |
| public void testAddConfigurationProviderNull() |
| { |
| try |
| { |
| factory.addConfigurationProvider("test", null); |
| fail("Could register null provider"); |
| } |
| catch (IllegalArgumentException iex) |
| { |
| // ok |
| } |
| } |
| |
| /** |
| * Tries to register a configuration provider for a null tag. This should |
| * cause an exception to be thrown. |
| */ |
| public void testAddConfigurationProviderNullTag() |
| { |
| try |
| { |
| factory.addConfigurationProvider(null, |
| new DefaultConfigurationBuilder.ConfigurationProvider()); |
| fail("Could register provider for null tag!"); |
| } |
| catch (IllegalArgumentException iex) |
| { |
| // ok |
| } |
| } |
| |
| /** |
| * Tests removing configuration providers. |
| */ |
| public void testRemoveConfigurationProvider() |
| { |
| assertNull("Removing unknown provider", factory |
| .removeConfigurationProvider("test")); |
| assertNull("Removing provider for null tag", factory |
| .removeConfigurationProvider(null)); |
| DefaultConfigurationBuilder.ConfigurationProvider provider = new DefaultConfigurationBuilder.ConfigurationProvider(); |
| factory.addConfigurationProvider("test", provider); |
| assertSame("Failed to remove provider", provider, factory |
| .removeConfigurationProvider("test")); |
| assertNull("Provider still registered", factory.providerForTag("test")); |
| } |
| |
| /** |
| * Tests creating a configuration object from a configuration declaration. |
| */ |
| public void testConfigurationBeanFactoryCreateBean() |
| { |
| factory.addConfigurationProvider("test", |
| new DefaultConfigurationBuilder.ConfigurationProvider( |
| PropertiesConfiguration.class)); |
| factory.addProperty("test[@throwExceptionOnMissing]", "true"); |
| DefaultConfigurationBuilder.ConfigurationDeclaration decl = new DefaultConfigurationBuilder.ConfigurationDeclaration( |
| factory, factory.configurationAt("test")); |
| PropertiesConfiguration conf = (PropertiesConfiguration) BeanHelper |
| .createBean(decl); |
| assertTrue("Property was not initialized", conf |
| .isThrowExceptionOnMissing()); |
| } |
| |
| /** |
| * Tests creating a configuration object from an unknown tag. This should |
| * cause an exception. |
| */ |
| public void testConfigurationBeanFactoryCreateUnknownTag() |
| { |
| factory.addProperty("test[@throwExceptionOnMissing]", "true"); |
| DefaultConfigurationBuilder.ConfigurationDeclaration decl = new DefaultConfigurationBuilder.ConfigurationDeclaration( |
| factory, factory.configurationAt("test")); |
| try |
| { |
| BeanHelper.createBean(decl); |
| fail("Could create configuration from unknown tag!"); |
| } |
| catch (ConfigurationRuntimeException crex) |
| { |
| // ok |
| } |
| } |
| |
| /** |
| * Tests loading a simple configuration definition file. |
| */ |
| public void testLoadConfiguration() throws ConfigurationException |
| { |
| factory.setFile(TEST_FILE); |
| checkConfiguration(); |
| } |
| |
| /** |
| * Tests the file constructor. |
| */ |
| public void testLoadConfigurationFromFile() throws ConfigurationException |
| { |
| factory = new DefaultConfigurationBuilder(TEST_FILE); |
| checkConfiguration(); |
| } |
| |
| /** |
| * Tests the file name constructor. |
| */ |
| public void testLoadConfigurationFromFileName() |
| throws ConfigurationException |
| { |
| factory = new DefaultConfigurationBuilder(TEST_FILE.getAbsolutePath()); |
| checkConfiguration(); |
| } |
| |
| /** |
| * Tests the URL constructor. |
| */ |
| public void testLoadConfigurationFromURL() throws Exception |
| { |
| factory = new DefaultConfigurationBuilder(TEST_FILE.toURL()); |
| checkConfiguration(); |
| } |
| |
| /** |
| * Tests if the configuration was correctly created by the factory. |
| */ |
| private void checkConfiguration() throws ConfigurationException |
| { |
| CombinedConfiguration compositeConfiguration = (CombinedConfiguration) factory |
| .getConfiguration(); |
| |
| assertEquals("Number of configurations", 3, compositeConfiguration |
| .getNumberOfConfigurations()); |
| assertEquals(PropertiesConfiguration.class, compositeConfiguration |
| .getConfiguration(0).getClass()); |
| assertEquals(XMLPropertiesConfiguration.class, compositeConfiguration |
| .getConfiguration(1).getClass()); |
| assertEquals(XMLConfiguration.class, compositeConfiguration |
| .getConfiguration(2).getClass()); |
| |
| // check the first configuration |
| PropertiesConfiguration pc = (PropertiesConfiguration) compositeConfiguration |
| .getConfiguration(0); |
| assertNotNull("Make sure we have a fileName: " + pc.getFileName(), pc |
| .getFileName()); |
| |
| // check some properties |
| checkProperties(compositeConfiguration); |
| } |
| |
| /** |
| * Checks if the passed in configuration contains the expected properties. |
| * |
| * @param compositeConfiguration the configuration to check |
| */ |
| private void checkProperties(Configuration compositeConfiguration) |
| { |
| assertTrue("Make sure we have loaded our key", compositeConfiguration |
| .getBoolean("test.boolean")); |
| assertEquals("I'm complex!", compositeConfiguration |
| .getProperty("element2.subelement.subsubelement")); |
| assertEquals("property in the XMLPropertiesConfiguration", "value1", |
| compositeConfiguration.getProperty("key1")); |
| } |
| |
| /** |
| * Tests loading a configuration definition file with an additional section. |
| */ |
| public void testLoadAdditional() throws ConfigurationException |
| { |
| factory.setFile(ADDITIONAL_FILE); |
| CombinedConfiguration compositeConfiguration = (CombinedConfiguration) factory |
| .getConfiguration(); |
| assertEquals("Verify how many configs", 2, compositeConfiguration |
| .getNumberOfConfigurations()); |
| |
| // Test if union was constructed correctly |
| Object prop = compositeConfiguration.getProperty("tables.table.name"); |
| assertTrue(prop instanceof Collection); |
| assertEquals(3, ((Collection) prop).size()); |
| assertEquals("users", compositeConfiguration |
| .getProperty("tables.table(0).name")); |
| assertEquals("documents", compositeConfiguration |
| .getProperty("tables.table(1).name")); |
| assertEquals("tasks", compositeConfiguration |
| .getProperty("tables.table(2).name")); |
| |
| prop = compositeConfiguration |
| .getProperty("tables.table.fields.field.name"); |
| assertTrue(prop instanceof Collection); |
| assertEquals(17, ((Collection) prop).size()); |
| |
| assertEquals("smtp.mydomain.org", compositeConfiguration |
| .getString("mail.host.smtp")); |
| assertEquals("pop3.mydomain.org", compositeConfiguration |
| .getString("mail.host.pop")); |
| |
| // This was overriden |
| assertEquals("masterOfPost", compositeConfiguration |
| .getString("mail.account.user")); |
| assertEquals("topsecret", compositeConfiguration |
| .getString("mail.account.psswd")); |
| |
| // This was overriden, too, but not in additional section |
| assertEquals("enhanced factory", compositeConfiguration |
| .getString("test.configuration")); |
| } |
| |
| /** |
| * Tests whether a default log error listener is registered at the builder |
| * instance. |
| */ |
| public void testLogErrorListener() |
| { |
| assertEquals("No default error listener registered", 1, |
| new DefaultConfigurationBuilder().getErrorListeners().size()); |
| } |
| |
| /** |
| * Tests loading a definition file that contains optional configurations. |
| */ |
| public void testLoadOptional() throws Exception |
| { |
| factory.setURL(OPTIONAL_FILE.toURL()); |
| Configuration config = factory.getConfiguration(); |
| assertTrue(config.getBoolean("test.boolean")); |
| assertEquals("value", config.getProperty("element")); |
| } |
| |
| /** |
| * Tests whether loading a failing optional configuration causes an error |
| * event. |
| */ |
| public void testLoadOptionalErrorEvent() throws Exception |
| { |
| factory.clearErrorListeners(); |
| ConfigurationErrorListenerImpl listener = new ConfigurationErrorListenerImpl(); |
| factory.addErrorListener(listener); |
| prepareOptionalTest("configuration", false); |
| listener.verify(DefaultConfigurationBuilder.EVENT_ERR_LOAD_OPTIONAL, |
| OPTIONAL_NAME, null); |
| } |
| |
| /** |
| * Tests loading a definition file with optional and non optional |
| * configuration sources. One non optional does not exist, so this should |
| * cause an exception. |
| */ |
| public void testLoadOptionalWithException() |
| { |
| factory.setFile(OPTIONALEX_FILE); |
| try |
| { |
| factory.getConfiguration(); |
| fail("Non existing source did not cause an exception!"); |
| } |
| catch (ConfigurationException cex) |
| { |
| // ok |
| } |
| } |
| |
| /** |
| * Tries to load a configuration file with an optional, non file-based |
| * configuration. The optional attribute should work for other configuration |
| * classes, too. |
| */ |
| public void testLoadOptionalNonFileBased() throws ConfigurationException |
| { |
| CombinedConfiguration config = prepareOptionalTest("configuration", false); |
| assertTrue("Configuration not empty", config.isEmpty()); |
| assertEquals("Wrong number of configurations", 0, config |
| .getNumberOfConfigurations()); |
| } |
| |
| /** |
| * Tests an optional, non existing configuration with the forceCreate |
| * attribute. This configuration should be added to the resulting |
| * configuration. |
| */ |
| public void testLoadOptionalForceCreate() throws ConfigurationException |
| { |
| factory.setBasePath(TEST_FILE.getParent()); |
| CombinedConfiguration config = prepareOptionalTest("xml", true); |
| assertEquals("Wrong number of configurations", 1, config |
| .getNumberOfConfigurations()); |
| FileConfiguration fc = (FileConfiguration) config |
| .getConfiguration(OPTIONAL_NAME); |
| assertNotNull("Optional config not found", fc); |
| assertEquals("File name was not set", "nonExisting.xml", fc |
| .getFileName()); |
| assertNotNull("Base path was not set", fc.getBasePath()); |
| } |
| |
| /** |
| * Tests loading an embedded optional configuration builder with the force |
| * create attribute. |
| */ |
| public void testLoadOptionalBuilderForceCreate() |
| throws ConfigurationException |
| { |
| CombinedConfiguration config = prepareOptionalTest("configuration", |
| true); |
| assertEquals("Wrong number of configurations", 1, config |
| .getNumberOfConfigurations()); |
| assertTrue( |
| "Wrong optional configuration type", |
| config.getConfiguration(OPTIONAL_NAME) instanceof CombinedConfiguration); |
| } |
| |
| /** |
| * Tests loading an optional configuration with the force create attribute |
| * set. The provider will always throw an exception. In this case the |
| * configuration will not be added to the resulting combined configuration. |
| */ |
| public void testLoadOptionalForceCreateWithException() |
| throws ConfigurationException |
| { |
| factory.addConfigurationProvider("test", |
| new DefaultConfigurationBuilder.ConfigurationBuilderProvider() |
| { |
| // Throw an exception here, too |
| public AbstractConfiguration getEmptyConfiguration( |
| DefaultConfigurationBuilder.ConfigurationDeclaration decl) throws Exception |
| { |
| throw new Exception("Unable to create configuration!"); |
| } |
| }); |
| CombinedConfiguration config = prepareOptionalTest("test", true); |
| assertEquals("Optional configuration could be created", 0, config |
| .getNumberOfConfigurations()); |
| } |
| |
| /** |
| * Prepares a test for loading a configuration definition file with an |
| * optional configuration declaration. |
| * |
| * @param tag the tag name with the optional configuration |
| * @param force the forceCreate attribute |
| * @return the combined configuration obtained from the builder |
| * @throws ConfigurationException if an error occurs |
| */ |
| private CombinedConfiguration prepareOptionalTest(String tag, boolean force) |
| throws ConfigurationException |
| { |
| String prefix = "override." + tag; |
| factory.addProperty(prefix + "[@fileName]", "nonExisting.xml"); |
| factory.addProperty(prefix + "[@config-optional]", Boolean.TRUE); |
| factory.addProperty(prefix + "[@config-name]", OPTIONAL_NAME); |
| if (force) |
| { |
| factory.addProperty(prefix + "[@config-forceCreate]", Boolean.TRUE); |
| } |
| return factory.getConfiguration(false); |
| } |
| |
| /** |
| * Tests loading a definition file with multiple different sources. |
| */ |
| public void testLoadDifferentSources() throws ConfigurationException |
| { |
| factory.setFile(MULTI_FILE); |
| Configuration config = factory.getConfiguration(); |
| assertFalse(config.isEmpty()); |
| assertTrue(config instanceof CombinedConfiguration); |
| CombinedConfiguration cc = (CombinedConfiguration) config; |
| assertEquals("Wrong number of configurations", 1, cc |
| .getNumberOfConfigurations()); |
| |
| assertNotNull(config |
| .getProperty("tables.table(0).fields.field(2).name")); |
| assertNotNull(config.getProperty("element2.subelement.subsubelement")); |
| assertEquals("value", config.getProperty("element3")); |
| assertEquals("foo", config.getProperty("element3[@name]")); |
| assertNotNull(config.getProperty("mail.account.user")); |
| |
| // test JNDIConfiguration |
| assertNotNull(config.getProperty("test.onlyinjndi")); |
| assertTrue(config.getBoolean("test.onlyinjndi")); |
| |
| Configuration subset = config.subset("test"); |
| assertNotNull(subset.getProperty("onlyinjndi")); |
| assertTrue(subset.getBoolean("onlyinjndi")); |
| |
| // test SystemConfiguration |
| assertNotNull(config.getProperty("java.version")); |
| assertEquals(System.getProperty("java.version"), config |
| .getString("java.version")); |
| } |
| |
| /** |
| * Tests if the base path is correctly evaluated. |
| */ |
| public void testSetConfigurationBasePath() throws ConfigurationException |
| { |
| factory.addProperty("properties[@fileName]", "test.properties"); |
| File deepDir = new File("conf/config/deep"); |
| factory.setConfigurationBasePath(deepDir.getAbsolutePath()); |
| |
| Configuration config = factory.getConfiguration(false); |
| assertEquals("Wrong property value", "somevalue", config |
| .getString("somekey")); |
| } |
| |
| /** |
| * Tests reading a configuration definition file that contains complex |
| * initialization of properties of the declared configuration sources. |
| */ |
| public void testComplexInitialization() throws ConfigurationException |
| { |
| factory.setFile(INIT_FILE); |
| CombinedConfiguration cc = (CombinedConfiguration) factory |
| .getConfiguration(); |
| |
| assertEquals("System property not found", "test.xml", |
| cc.getString("test_file_xml")); |
| PropertiesConfiguration c1 = (PropertiesConfiguration) cc |
| .getConfiguration(1); |
| assertTrue( |
| "Reloading strategy was not set", |
| c1.getReloadingStrategy() instanceof FileChangedReloadingStrategy); |
| assertEquals("Refresh delay was not set", 10000, |
| ((FileChangedReloadingStrategy) c1.getReloadingStrategy()) |
| .getRefreshDelay()); |
| |
| Configuration xmlConf = cc.getConfiguration("xml"); |
| assertEquals("Property not found", "I'm complex!", xmlConf |
| .getString("element2/subelement/subsubelement")); |
| assertEquals("List index not found", "two", xmlConf |
| .getString("list[0]/item[1]")); |
| assertEquals("Property in combiner file not found", "yellow", cc |
| .getString("/gui/selcolor")); |
| |
| assertTrue("Delimiter flag was not set", cc |
| .isDelimiterParsingDisabled()); |
| assertTrue("Expression engine was not set", |
| cc.getExpressionEngine() instanceof XPathExpressionEngine); |
| } |
| |
| /** |
| * Tests if the returned combined configuration has the expected structure. |
| */ |
| public void testCombinedConfiguration() throws ConfigurationException |
| { |
| factory.setFile(INIT_FILE); |
| CombinedConfiguration cc = (CombinedConfiguration) factory |
| .getConfiguration(); |
| assertNotNull("Properties configuration not found", cc |
| .getConfiguration("properties")); |
| assertNotNull("XML configuration not found", cc.getConfiguration("xml")); |
| assertEquals("Wrong number of contained configs", 4, cc |
| .getNumberOfConfigurations()); |
| |
| CombinedConfiguration cc2 = (CombinedConfiguration) cc |
| .getConfiguration(DefaultConfigurationBuilder.ADDITIONAL_NAME); |
| assertNotNull("No additional configuration found", cc2); |
| Set names = cc2.getConfigurationNames(); |
| assertEquals("Wrong number of contained additional configs", 2, names |
| .size()); |
| assertTrue("Config 1 not contained", names.contains("combiner1")); |
| assertTrue("Config 2 not contained", names.contains("combiner2")); |
| } |
| |
| /** |
| * Tests the structure of the returned combined configuration if there is no |
| * additional section. |
| */ |
| public void testCombinedConfigurationNoAdditional() |
| throws ConfigurationException |
| { |
| factory.setFile(TEST_FILE); |
| CombinedConfiguration cc = factory.getConfiguration(true); |
| assertNull("Additional configuration was found", cc |
| .getConfiguration(DefaultConfigurationBuilder.ADDITIONAL_NAME)); |
| } |
| |
| /** |
| * Tests whether the list node definition was correctly processed. |
| */ |
| public void testCombinedConfigurationListNodes() |
| throws ConfigurationException |
| { |
| factory.setFile(INIT_FILE); |
| CombinedConfiguration cc = factory.getConfiguration(true); |
| Set listNodes = cc.getNodeCombiner().getListNodes(); |
| assertEquals("Wrong number of list nodes", 2, listNodes.size()); |
| assertTrue("table node not a list node", listNodes.contains("table")); |
| assertTrue("list node not a list node", listNodes.contains("list")); |
| |
| CombinedConfiguration cca = (CombinedConfiguration) cc |
| .getConfiguration(DefaultConfigurationBuilder.ADDITIONAL_NAME); |
| listNodes = cca.getNodeCombiner().getListNodes(); |
| assertTrue("Found list nodes for additional combiner", listNodes |
| .isEmpty()); |
| } |
| |
| /** |
| * Tests whether a configuration builder can itself be declared in a |
| * configuration definition file. |
| */ |
| public void testConfigurationBuilderProvider() |
| throws ConfigurationException |
| { |
| factory.addProperty("override.configuration[@fileName]", TEST_FILE |
| .getAbsolutePath()); |
| CombinedConfiguration cc = factory.getConfiguration(false); |
| assertEquals("Wrong number of configurations", 1, cc |
| .getNumberOfConfigurations()); |
| checkProperties(cc); |
| } |
| |
| /** |
| * Tests whether XML settings can be inherited. |
| */ |
| public void testLoadXMLWithSettings() throws ConfigurationException, |
| IOException |
| { |
| File confDir = new File("conf"); |
| File targetDir = new File("target"); |
| File testXMLSource = new File(confDir, "testDtd.xml"); |
| File testXMLValidationSource = new File(confDir, |
| "testValidateInvalid.xml"); |
| File testSavedXML = new File(targetDir, "testSave.xml"); |
| File testSavedFactory = new File(targetDir, "testSaveFactory.xml"); |
| File dtdFile = new File(confDir, "properties.dtd"); |
| final String publicId = "http://commons.apache.org/test.dtd"; |
| |
| XMLConfiguration config = new XMLConfiguration(testXMLSource); |
| config.setPublicID(publicId); |
| config.save(testSavedXML); |
| factory.addProperty("xml[@fileName]", testSavedXML.getAbsolutePath()); |
| factory.addProperty("xml(0)[@validating]", "true"); |
| factory.addProperty("xml(-1)[@fileName]", testXMLValidationSource |
| .getAbsolutePath()); |
| factory.addProperty("xml(1)[@config-optional]", "true"); |
| factory.addProperty("xml(1)[@validating]", "true"); |
| factory.save(testSavedFactory); |
| |
| factory = new DefaultConfigurationBuilder(); |
| factory.setFile(testSavedFactory); |
| factory.registerEntityId(publicId, dtdFile.toURL()); |
| factory.clearErrorListeners(); |
| Configuration c = factory.getConfiguration(); |
| assertEquals("Wrong property value", "value1", c.getString("entry(0)")); |
| assertFalse("Invalid XML source was loaded", c |
| .containsKey("table.name")); |
| |
| testSavedXML.delete(); |
| testSavedFactory.delete(); |
| } |
| |
| /** |
| * Tests loading a configuration definition file that defines a custom |
| * result class. |
| */ |
| public void testExtendedClass() throws ConfigurationException |
| { |
| factory.setFile(CLASS_FILE); |
| CombinedConfiguration cc = factory.getConfiguration(true); |
| assertEquals("Extended", cc.getProperty("test")); |
| assertTrue("Wrong result class: " + cc.getClass(), |
| cc instanceof ExtendedCombinedConfiguration); |
| } |
| |
| /** |
| * Tests loading a configuration definition file that defines new providers. |
| */ |
| public void testConfigurationProvider() throws ConfigurationException |
| { |
| factory.setFile(PROVIDER_FILE); |
| factory.getConfiguration(true); |
| DefaultConfigurationBuilder.ConfigurationProvider provider = factory |
| .providerForTag("test"); |
| assertNotNull("Provider 'test' not registered", provider); |
| } |
| |
| /** |
| * Tests loading a configuration definition file that defines new providers. |
| */ |
| public void testExtendedXMLConfigurationProvider() throws ConfigurationException |
| { |
| factory.setFile(EXTENDED_PROVIDER_FILE); |
| CombinedConfiguration cc = factory.getConfiguration(true); |
| DefaultConfigurationBuilder.ConfigurationProvider provider = factory |
| .providerForTag("test"); |
| assertNotNull("Provider 'test' not registered", provider); |
| Configuration config = cc.getConfiguration("xml"); |
| assertNotNull("Test configuration not present", config); |
| assertTrue("Configuration is not ExtendedXMLConfiguration, is " + |
| config.getClass().getName(), config instanceof ExtendedXMLConfiguration); |
| } |
| |
| public void testGlobalLookup() throws Exception |
| { |
| factory.setFile(GLOBAL_LOOKUP_FILE); |
| CombinedConfiguration cc = factory.getConfiguration(true); |
| String value = cc.getInterpolator().lookup("test:test_key"); |
| assertNotNull("The test key was not located", value); |
| assertEquals("Incorrect value retrieved","test.value",value); |
| } |
| |
| public void testSystemProperties() throws Exception |
| { |
| factory.setFile(SYSTEM_PROPS_FILE); |
| factory.getConfiguration(true); |
| String value = System.getProperty("key1"); |
| assertNotNull("The test key was not located", value); |
| assertEquals("Incorrect value retrieved","value1",value); |
| } |
| |
| |
| public void testValidation() throws Exception |
| { |
| factory.setFile(VALIDATION_FILE); |
| factory.getConfiguration(true); |
| String value = System.getProperty("key1"); |
| assertNotNull("The test key was not located", value); |
| assertEquals("Incorrect value retrieved","value1",value); |
| } |
| |
| |
| public void testValidation3() throws Exception |
| { |
| System.getProperties().remove("Id"); |
| factory.setFile(VALIDATION3_FILE); |
| CombinedConfiguration config = factory.getConfiguration(true); |
| String value = config.getString("Employee/Name"); |
| assertNotNull("The test key was not located", value); |
| assertEquals("Incorrect value retrieved","John Doe",value); |
| System.setProperty("Id", "1001"); |
| value = config.getString("Employee/Name"); |
| assertNotNull("The test key was not located", value); |
| assertEquals("Incorrect value retrieved","Jane Doe",value); |
| } |
| |
| public void testMultiTenentConfiguration() throws Exception |
| { |
| factory.setFile(MULTI_TENENT_FILE); |
| System.getProperties().remove("Id"); |
| |
| CombinedConfiguration config = factory.getConfiguration(true); |
| assertTrue("Incorrect configuration", config instanceof DynamicCombinedConfiguration); |
| |
| verify("1001", config, 15); |
| verify("1002", config, 25); |
| verify("1003", config, 35); |
| verify("1004", config, 50); |
| verify("1005", config, 50); |
| } |
| |
| public void testMultiTenentConfiguration2() throws Exception |
| { |
| factory.setFile(MULTI_TENENT_FILE); |
| System.setProperty("Id", "1004"); |
| |
| CombinedConfiguration config = factory.getConfiguration(true); |
| assertTrue("Incorrect configuration", config instanceof DynamicCombinedConfiguration); |
| |
| verify("1001", config, 15); |
| verify("1002", config, 25); |
| verify("1003", config, 35); |
| verify("1004", config, 50); |
| verify("1005", config, 50); |
| } |
| |
| public void testMultiTenentConfiguration3() throws Exception |
| { |
| factory.setFile(MULTI_TENENT_FILE); |
| StringWriter writer = new StringWriter(); |
| WriterAppender app = new WriterAppender(new SimpleLayout(), writer); |
| Log log = LogFactory.getLog("TestLogger"); |
| Logger logger = ((Log4JLogger)log).getLogger(); |
| logger.addAppender(app); |
| logger.setLevel(Level.DEBUG); |
| logger.setAdditivity(false); |
| |
| System.setProperty("Id", "1005"); |
| |
| CombinedConfiguration config = factory.getConfiguration(true); |
| assertTrue("Incorrect configuration", config instanceof DynamicCombinedConfiguration); |
| |
| verify("1001", config, 15); |
| String xml = writer.getBuffer().toString(); |
| assertNotNull("No XML returned", xml); |
| assertTrue("Incorect configuration data", xml.indexOf("<rowsPerPage>15</rowsPerPage>") >= 0); |
| logger.removeAppender(app); |
| logger.setLevel(Level.OFF); |
| verify("1002", config, 25); |
| verify("1003", config, 35); |
| verify("1004", config, 50); |
| verify("1005", config, 50); |
| } |
| |
| public void testMultiTenantConfigurationAt() throws Exception |
| { |
| factory.setFile(MULTI_TENENT_FILE); |
| System.setProperty("Id", "1001"); |
| CombinedConfiguration config = factory.getConfiguration(true); |
| HierarchicalConfiguration sub1 = config.configurationAt("Channels/Channel[@id='1']"); |
| assertEquals("My Channel", sub1.getString("Name")); |
| assertEquals("test 1 data", sub1.getString("ChannelData")); |
| HierarchicalConfiguration sub2 = config.configurationAt("Channels/Channel[@id='2']"); |
| assertEquals("Channel 2", sub2.getString("Name")); |
| assertEquals("more test 2 data", sub2.getString("MoreChannelData")); |
| } |
| |
| public void testMerge() throws Exception |
| { |
| factory.setFile(MULTI_TENENT_FILE); |
| System.setProperty("Id", "1004"); |
| Map map = new HashMap(); |
| map.put("default", "${colors.header4}"); |
| map.put("background", "#40404040"); |
| map.put("text", "#000000"); |
| map.put("header", "#444444"); |
| |
| CombinedConfiguration config = factory.getConfiguration(true); |
| assertTrue("Incorrect configuration", config instanceof DynamicCombinedConfiguration); |
| |
| List list = config.configurationsAt("colors/*"); |
| Iterator iter = list.iterator(); |
| while (iter.hasNext()) |
| { |
| SubnodeConfiguration sub = (SubnodeConfiguration)iter.next(); |
| ConfigurationNode node = sub.getRootNode(); |
| String value = (node.getValue() == null) ? "null" : node.getValue().toString(); |
| if (map.containsKey(node.getName())) |
| { |
| assertEquals(map.get(node.getName()), value); |
| } |
| } |
| |
| } |
| |
| public void testDelimiterParsingDisabled() throws Exception |
| { |
| factory.setFile(MULTI_TENENT_FILE); |
| System.setProperty("Id", "1004"); |
| |
| CombinedConfiguration config = factory.getConfiguration(true); |
| assertTrue("Incorrect configuration", config instanceof DynamicCombinedConfiguration); |
| |
| assertEquals("a,b,c", config.getString("split/list3/@values")); |
| assertEquals(0, config.getMaxIndex("split/list3/@values")); |
| assertEquals("a\\,b\\,c", config.getString("split/list4/@values")); |
| assertEquals("a,b,c", config.getString("split/list1")); |
| assertEquals(0, config.getMaxIndex("split/list1")); |
| assertEquals("a\\,b\\,c", config.getString("split/list2")); |
| } |
| |
| public void testExpression() throws Exception |
| { |
| factory.setFile(EXPRESSION_FILE); |
| factory.setAttributeSplittingDisabled(true); |
| System.getProperties().remove("Id"); |
| org.slf4j.MDC.clear(); |
| |
| CombinedConfiguration config = factory.getConfiguration(true); |
| assertTrue("Incorrect configuration", config instanceof DynamicCombinedConfiguration); |
| |
| verify("1001", config, 15); |
| } |
| |
| private void verify(String key, CombinedConfiguration config, int rows) |
| { |
| System.setProperty("Id", key); |
| org.slf4j.MDC.put("Id", key); |
| int actual = config.getInt("rowsPerPage"); |
| assertTrue("expected: " + rows + " actual: " + actual, actual == rows); |
| } |
| |
| |
| /** |
| * A specialized combined configuration implementation used for testing |
| * custom result classes. |
| */ |
| public static class ExtendedCombinedConfiguration extends |
| CombinedConfiguration |
| { |
| /** |
| * The serial version UID. |
| */ |
| private static final long serialVersionUID = 4678031745085083392L; |
| |
| public Object getProperty(String key) |
| { |
| if (key.equals("test")) |
| { |
| return "Extended"; |
| } |
| return super.getProperty(key); |
| } |
| } |
| |
| public static class ExtendedXMLConfiguration extends XMLConfiguration |
| { |
| public ExtendedXMLConfiguration() |
| { |
| } |
| |
| } |
| |
| public static class TestLookup extends StrLookup |
| { |
| Map map = new HashMap(); |
| |
| public TestLookup() |
| { |
| map.put("test_file_xml", "test.xml"); |
| map.put("test_file_combine", "testcombine1.xml"); |
| map.put("test_key", "test.value"); |
| } |
| |
| public String lookup(String key) |
| { |
| if (key == null) |
| { |
| return null; |
| } |
| return (String)map.get(key); |
| |
| } |
| } |
| } |
| |