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; 018 019 import static org.junit.Assert.assertEquals; 020 import static org.junit.Assert.assertFalse; 021 import static org.junit.Assert.assertNotNull; 022 import static org.junit.Assert.assertNull; 023 import static org.junit.Assert.assertSame; 024 import static org.junit.Assert.assertTrue; 025 import static org.junit.Assert.fail; 026 027 import java.io.File; 028 import java.io.FileReader; 029 import java.io.FileWriter; 030 import java.io.IOException; 031 import java.io.Reader; 032 import java.io.Writer; 033 import java.net.URL; 034 import java.util.Collection; 035 import java.util.Iterator; 036 import java.util.List; 037 import java.util.Set; 038 039 import org.apache.commons.configuration.beanutils.BeanHelper; 040 import org.apache.commons.configuration.reloading.FileChangedReloadingStrategy; 041 import org.apache.commons.configuration.tree.DefaultConfigurationNode; 042 import org.apache.commons.configuration.tree.xpath.XPathExpressionEngine; 043 import org.junit.After; 044 import org.junit.Before; 045 import org.junit.Test; 046 047 /** 048 * Test class for VFSConfigurationBuilder. 049 * 050 * @author <a 051 * href="http://commons.apache.org/configuration/team-list.html">Commons 052 * Configuration team</a> 053 * @version $Id: TestVFSConfigurationBuilder.java 1308148 2012-04-01 16:27:41Z rgoers $ 054 */ 055 public class TestVFSConfigurationBuilder 056 { 057 /** Test configuration definition file. */ 058 private static final File TEST_FILE = ConfigurationAssert 059 .getTestFile("testDigesterConfiguration.xml"); 060 061 private static final File ADDITIONAL_FILE = ConfigurationAssert 062 .getTestFile("testDigesterConfiguration2.xml"); 063 064 private static final File OPTIONAL_FILE = ConfigurationAssert 065 .getTestFile("testDigesterOptionalConfiguration.xml"); 066 067 private static final File OPTIONALEX_FILE = ConfigurationAssert 068 .getTestFile("testDigesterOptionalConfigurationEx.xml"); 069 070 private static final File MULTI_FILE = ConfigurationAssert 071 .getTestFile("testDigesterConfiguration3.xml"); 072 073 private static final File INIT_FILE = ConfigurationAssert 074 .getTestFile("testComplexInitialization.xml"); 075 076 private static final File CLASS_FILE = ConfigurationAssert 077 .getTestFile("testExtendedClass.xml"); 078 079 private static final File PROVIDER_FILE = ConfigurationAssert 080 .getTestFile("testConfigurationProvider.xml"); 081 082 private static final File EXTENDED_PROVIDER_FILE = ConfigurationAssert 083 .getTestFile("testExtendedXMLConfigurationProvider.xml"); 084 085 private static final File GLOBAL_LOOKUP_FILE = ConfigurationAssert 086 .getTestFile("testGlobalLookup.xml"); 087 088 private static final File SYSTEM_PROPS_FILE = ConfigurationAssert 089 .getTestFile("testSystemProperties.xml"); 090 091 private static final File VALIDATION_FILE = ConfigurationAssert 092 .getTestFile("testValidation.xml"); 093 094 private static final File VALIDATION2_FILE = ConfigurationAssert 095 .getTestFile("testValidation2.xml"); 096 097 private static final File MULTI_TENENT_FILE = ConfigurationAssert 098 .getTestFile("testMultiTenentConfigurationBuilder.xml"); 099 100 private static final File FILESYSTEM_FILE = ConfigurationAssert 101 .getTestFile("testFileSystem.xml"); 102 103 private static final File FILERELOAD_FILE = ConfigurationAssert 104 .getTestFile("testFileReloadConfigurationBuilder.xml"); 105 106 private static final File MULTI_RELOAD_FILE1 = ConfigurationAssert 107 .getTestFile("testVFSMultiTenentConfigurationBuilder1.xml"); 108 109 private static final File MULTI_RELOAD_FILE2 = ConfigurationAssert 110 .getTestFile("testVFSMultiTenentConfigurationBuilder2.xml"); 111 112 /** Constant for the name of an optional configuration.*/ 113 private static final String OPTIONAL_NAME = "optionalConfig"; 114 115 /** Stores the object to be tested. */ 116 DefaultConfigurationBuilder factory; 117 118 @Before 119 public void setUp() throws Exception 120 { 121 System 122 .setProperty("java.naming.factory.initial", 123 "org.apache.commons.configuration.MockInitialContextFactory"); 124 System.setProperty("test_file_xml", "test.xml"); 125 System.setProperty("test_file_combine", "testcombine1.xml"); 126 System.setProperty("basePath", "file://" + System.getProperty("user.dir") + "/target/test-classes"); 127 FileSystem.setDefaultFileSystem(new VFSFileSystem()); 128 factory = new DefaultConfigurationBuilder(); 129 factory.clearErrorListeners(); // avoid exception messages 130 } 131 132 @After 133 public void tearDown() throws Exception 134 { 135 FileSystem.resetDefaultFileSystem(); 136 } 137 138 /** 139 * Tests the isReservedNode() method of ConfigurationDeclaration. 140 */ 141 @Test 142 public void testConfigurationDeclarationIsReserved() 143 { 144 DefaultConfigurationBuilder.ConfigurationDeclaration decl = new DefaultConfigurationBuilder.ConfigurationDeclaration( 145 factory, factory); 146 DefaultConfigurationNode parent = new DefaultConfigurationNode(); 147 DefaultConfigurationNode nd = new DefaultConfigurationNode("at"); 148 parent.addAttribute(nd); 149 assertTrue("Attribute at not recognized", decl.isReservedNode(nd)); 150 nd = new DefaultConfigurationNode("optional"); 151 parent.addAttribute(nd); 152 assertTrue("Attribute optional not recognized", decl.isReservedNode(nd)); 153 nd = new DefaultConfigurationNode("config-class"); 154 parent.addAttribute(nd); 155 assertTrue("Inherited attribute not recognized", decl 156 .isReservedNode(nd)); 157 nd = new DefaultConfigurationNode("different"); 158 parent.addAttribute(nd); 159 assertFalse("Wrong reserved attribute", decl.isReservedNode(nd)); 160 nd = new DefaultConfigurationNode("at"); 161 parent.addChild(nd); 162 assertFalse("Node type not evaluated", decl.isReservedNode(nd)); 163 } 164 165 /** 166 * Tests if the at attribute is correctly detected as reserved attribute. 167 */ 168 @Test 169 public void testConfigurationDeclarationIsReservedAt() 170 { 171 checkOldReservedAttribute("at"); 172 } 173 174 /** 175 * Tests if the optional attribute is correctly detected as reserved 176 * attribute. 177 */ 178 @Test 179 public void testConfigurationDeclarationIsReservedOptional() 180 { 181 checkOldReservedAttribute("optional"); 182 } 183 184 /** 185 * Tests if special reserved attributes are recognized by the 186 * isReservedNode() method. For compatibility reasons the attributes "at" 187 * and "optional" are also treated as reserved attributes, but only if there 188 * are no corresponding attributes with the "config-" prefix. 189 * 190 * @param name the attribute name 191 */ 192 private void checkOldReservedAttribute(String name) 193 { 194 DefaultConfigurationBuilder.ConfigurationDeclaration decl = new DefaultConfigurationBuilder.ConfigurationDeclaration( 195 factory, factory); 196 DefaultConfigurationNode parent = new DefaultConfigurationNode(); 197 DefaultConfigurationNode nd = new DefaultConfigurationNode("config-" 198 + name); 199 parent.addAttribute(nd); 200 assertTrue("config-" + name + " attribute not recognized", decl 201 .isReservedNode(nd)); 202 DefaultConfigurationNode nd2 = new DefaultConfigurationNode(name); 203 parent.addAttribute(nd2); 204 assertFalse(name + " is reserved though config- exists", decl 205 .isReservedNode(nd2)); 206 assertTrue("config- attribute not recognized when " + name + " exists", 207 decl.isReservedNode(nd)); 208 } 209 210 /** 211 * Tests access to certain reserved attributes of a 212 * ConfigurationDeclaration. 213 */ 214 @Test 215 public void testConfigurationDeclarationGetAttributes() 216 { 217 factory.addProperty("xml.fileName", "test.xml"); 218 DefaultConfigurationBuilder.ConfigurationDeclaration decl = new DefaultConfigurationBuilder.ConfigurationDeclaration( 219 factory, factory.configurationAt("xml")); 220 assertNull("Found an at attribute", decl.getAt()); 221 assertFalse("Found an optional attribute", decl.isOptional()); 222 factory.addProperty("xml[@config-at]", "test1"); 223 assertEquals("Wrong value of at attribute", "test1", decl.getAt()); 224 factory.addProperty("xml[@at]", "test2"); 225 assertEquals("Wrong value of config-at attribute", "test1", decl.getAt()); 226 factory.clearProperty("xml[@config-at]"); 227 assertEquals("Old at attribute not detected", "test2", decl.getAt()); 228 factory.addProperty("xml[@config-optional]", "true"); 229 assertTrue("Wrong value of optional attribute", decl.isOptional()); 230 factory.addProperty("xml[@optional]", "false"); 231 assertTrue("Wrong value of config-optional attribute", decl.isOptional()); 232 factory.clearProperty("xml[@config-optional]"); 233 factory.setProperty("xml[@optional]", Boolean.TRUE); 234 assertTrue("Old optional attribute not detected", decl.isOptional()); 235 } 236 237 /** 238 * Tests whether an invalid value of an optional attribute is detected. 239 */ 240 @Test(expected = ConfigurationRuntimeException.class) 241 public void testConfigurationDeclarationOptionalAttributeInvalid() 242 { 243 factory.addProperty("xml.fileName", "test.xml"); 244 DefaultConfigurationBuilder.ConfigurationDeclaration decl = new DefaultConfigurationBuilder.ConfigurationDeclaration( 245 factory, factory.configurationAt("xml")); 246 factory.setProperty("xml[@optional]", "invalid value"); 247 decl.isOptional(); 248 } 249 250 /** 251 * Tests adding a new configuration provider. 252 */ 253 @Test 254 public void testAddConfigurationProvider() 255 { 256 DefaultConfigurationBuilder.ConfigurationProvider provider = new DefaultConfigurationBuilder.ConfigurationProvider(); 257 assertNull("Provider already registered", factory 258 .providerForTag("test")); 259 factory.addConfigurationProvider("test", provider); 260 assertSame("Provider not registered", provider, factory 261 .providerForTag("test")); 262 } 263 264 /** 265 * Tries to register a null configuration provider. This should cause an 266 * exception. 267 */ 268 @Test(expected = IllegalArgumentException.class) 269 public void testAddConfigurationProviderNull() 270 { 271 factory.addConfigurationProvider("test", null); 272 } 273 274 /** 275 * Tries to register a configuration provider for a null tag. This should 276 * cause an exception to be thrown. 277 */ 278 @Test(expected = IllegalArgumentException.class) 279 public void testAddConfigurationProviderNullTag() 280 { 281 factory.addConfigurationProvider(null, 282 new DefaultConfigurationBuilder.ConfigurationProvider()); 283 } 284 285 /** 286 * Tests removing configuration providers. 287 */ 288 @Test 289 public void testRemoveConfigurationProvider() 290 { 291 assertNull("Removing unknown provider", factory 292 .removeConfigurationProvider("test")); 293 assertNull("Removing provider for null tag", factory 294 .removeConfigurationProvider(null)); 295 DefaultConfigurationBuilder.ConfigurationProvider provider = new DefaultConfigurationBuilder.ConfigurationProvider(); 296 factory.addConfigurationProvider("test", provider); 297 assertSame("Failed to remove provider", provider, factory 298 .removeConfigurationProvider("test")); 299 assertNull("Provider still registered", factory.providerForTag("test")); 300 } 301 302 /** 303 * Tests creating a configuration object from a configuration declaration. 304 */ 305 @Test 306 public void testConfigurationBeanFactoryCreateBean() 307 { 308 factory.addConfigurationProvider("test", 309 new DefaultConfigurationBuilder.ConfigurationProvider( 310 PropertiesConfiguration.class)); 311 factory.addProperty("test[@throwExceptionOnMissing]", "true"); 312 DefaultConfigurationBuilder.ConfigurationDeclaration decl = new DefaultConfigurationBuilder.ConfigurationDeclaration( 313 factory, factory.configurationAt("test")); 314 PropertiesConfiguration conf = (PropertiesConfiguration) BeanHelper 315 .createBean(decl); 316 assertTrue("Property was not initialized", conf 317 .isThrowExceptionOnMissing()); 318 } 319 320 /** 321 * Tests creating a configuration object from an unknown tag. This should 322 * cause an exception. 323 */ 324 @Test(expected = ConfigurationRuntimeException.class) 325 public void testConfigurationBeanFactoryCreateUnknownTag() 326 { 327 factory.addProperty("test[@throwExceptionOnMissing]", "true"); 328 DefaultConfigurationBuilder.ConfigurationDeclaration decl = new DefaultConfigurationBuilder.ConfigurationDeclaration( 329 factory, factory.configurationAt("test")); 330 BeanHelper.createBean(decl); 331 } 332 333 /** 334 * Tests loading a simple configuration definition file. 335 */ 336 @Test 337 public void testLoadConfiguration() throws ConfigurationException 338 { 339 factory.setFile(TEST_FILE); 340 checkConfiguration(); 341 } 342 343 /** 344 * Tests the file constructor. 345 */ 346 @Test 347 public void testLoadConfigurationFromFile() throws ConfigurationException 348 { 349 factory = new DefaultConfigurationBuilder(TEST_FILE); 350 checkConfiguration(); 351 } 352 353 /** 354 * Tests the file name constructor. 355 */ 356 @Test 357 public void testLoadConfigurationFromFileName() 358 throws ConfigurationException 359 { 360 factory = new DefaultConfigurationBuilder(TEST_FILE.getAbsolutePath()); 361 checkConfiguration(); 362 } 363 364 /** 365 * Tests the URL constructor. 366 */ 367 @Test 368 public void testLoadConfigurationFromURL() throws Exception 369 { 370 factory = new DefaultConfigurationBuilder(TEST_FILE.toURI().toURL()); 371 checkConfiguration(); 372 } 373 374 /** 375 * Tests if the configuration was correctly created by the factory. 376 */ 377 private void checkConfiguration() throws ConfigurationException 378 { 379 CombinedConfiguration compositeConfiguration = (CombinedConfiguration) factory 380 .getConfiguration(); 381 382 assertEquals("Number of configurations", 3, compositeConfiguration 383 .getNumberOfConfigurations()); 384 assertEquals(PropertiesConfiguration.class, compositeConfiguration 385 .getConfiguration(0).getClass()); 386 assertEquals(XMLPropertiesConfiguration.class, compositeConfiguration 387 .getConfiguration(1).getClass()); 388 assertEquals(XMLConfiguration.class, compositeConfiguration 389 .getConfiguration(2).getClass()); 390 391 // check the first configuration 392 PropertiesConfiguration pc = (PropertiesConfiguration) compositeConfiguration 393 .getConfiguration(0); 394 assertNotNull("Make sure we have a fileName: " + pc.getFileName(), pc 395 .getFileName()); 396 397 // check some properties 398 checkProperties(compositeConfiguration); 399 } 400 401 /** 402 * Checks if the passed in configuration contains the expected properties. 403 * 404 * @param compositeConfiguration the configuration to check 405 */ 406 private void checkProperties(Configuration compositeConfiguration) 407 { 408 assertTrue("Make sure we have loaded our key", compositeConfiguration 409 .getBoolean("test.boolean")); 410 assertEquals("I'm complex!", compositeConfiguration 411 .getProperty("element2.subelement.subsubelement")); 412 assertEquals("property in the XMLPropertiesConfiguration", "value1", 413 compositeConfiguration.getProperty("key1")); 414 } 415 416 /** 417 * Tests loading a configuration definition file with an additional section. 418 */ 419 @Test 420 public void testLoadAdditional() throws ConfigurationException 421 { 422 factory.setFile(ADDITIONAL_FILE); 423 CombinedConfiguration compositeConfiguration = (CombinedConfiguration) factory 424 .getConfiguration(); 425 assertEquals("Verify how many configs", 2, compositeConfiguration 426 .getNumberOfConfigurations()); 427 428 // Test if union was constructed correctly 429 Object prop = compositeConfiguration.getProperty("tables.table.name"); 430 assertTrue(prop instanceof Collection); 431 assertEquals(3, ((Collection<?>) prop).size()); 432 assertEquals("users", compositeConfiguration 433 .getProperty("tables.table(0).name")); 434 assertEquals("documents", compositeConfiguration 435 .getProperty("tables.table(1).name")); 436 assertEquals("tasks", compositeConfiguration 437 .getProperty("tables.table(2).name")); 438 439 prop = compositeConfiguration 440 .getProperty("tables.table.fields.field.name"); 441 assertTrue(prop instanceof Collection); 442 assertEquals(17, ((Collection<?>) prop).size()); 443 444 assertEquals("smtp.mydomain.org", compositeConfiguration 445 .getString("mail.host.smtp")); 446 assertEquals("pop3.mydomain.org", compositeConfiguration 447 .getString("mail.host.pop")); 448 449 // This was overridden 450 assertEquals("masterOfPost", compositeConfiguration 451 .getString("mail.account.user")); 452 assertEquals("topsecret", compositeConfiguration 453 .getString("mail.account.psswd")); 454 455 // This was overridden, too, but not in additional section 456 assertEquals("enhanced factory", compositeConfiguration 457 .getString("test.configuration")); 458 } 459 460 /** 461 * Tests whether a default log error listener is registered at the builder 462 * instance. 463 */ 464 @Test 465 public void testLogErrorListener() 466 { 467 assertEquals("No default error listener registered", 1, 468 new DefaultConfigurationBuilder().getErrorListeners().size()); 469 } 470 471 /** 472 * Tests loading a definition file that contains optional configurations. 473 */ 474 @Test 475 public void testLoadOptional() throws Exception 476 { 477 factory.setURL(OPTIONAL_FILE.toURI().toURL()); 478 Configuration config = factory.getConfiguration(); 479 assertTrue(config.getBoolean("test.boolean")); 480 assertEquals("value", config.getProperty("element")); 481 } 482 483 /** 484 * Tests whether loading a failing optional configuration causes an error 485 * event. 486 */ 487 @Test 488 public void testLoadOptionalErrorEvent() throws Exception 489 { 490 factory.clearErrorListeners(); 491 ConfigurationErrorListenerImpl listener = new ConfigurationErrorListenerImpl(); 492 factory.addErrorListener(listener); 493 prepareOptionalTest("configuration", false); 494 listener.verify(DefaultConfigurationBuilder.EVENT_ERR_LOAD_OPTIONAL, 495 OPTIONAL_NAME, null); 496 } 497 498 /** 499 * Tests loading a definition file with optional and non optional 500 * configuration sources. One non optional does not exist, so this should 501 * cause an exception. 502 */ 503 @Test(expected = ConfigurationException.class) 504 public void testLoadOptionalWithException() throws ConfigurationException 505 { 506 factory.setFile(OPTIONALEX_FILE); 507 factory.getConfiguration(); 508 } 509 510 /** 511 * Tries to load a configuration file with an optional, non file-based 512 * configuration. The optional attribute should work for other configuration 513 * classes, too. 514 */ 515 @Test 516 public void testLoadOptionalNonFileBased() throws ConfigurationException 517 { 518 CombinedConfiguration config = prepareOptionalTest("configuration", false); 519 assertTrue("Configuration not empty", config.isEmpty()); 520 assertEquals("Wrong number of configurations", 0, config 521 .getNumberOfConfigurations()); 522 } 523 524 /** 525 * Tests an optional, non existing configuration with the forceCreate 526 * attribute. This configuration should be added to the resulting 527 * configuration. 528 */ 529 @Test 530 public void testLoadOptionalForceCreate() throws ConfigurationException 531 { 532 factory.setBasePath(TEST_FILE.getParent()); 533 CombinedConfiguration config = prepareOptionalTest("xml", true); 534 assertEquals("Wrong number of configurations", 1, config 535 .getNumberOfConfigurations()); 536 FileConfiguration fc = (FileConfiguration) config 537 .getConfiguration(OPTIONAL_NAME); 538 assertNotNull("Optional config not found", fc); 539 assertEquals("File name was not set", "nonExisting.xml", fc 540 .getFileName()); 541 assertNotNull("Base path was not set", fc.getBasePath()); 542 } 543 544 /** 545 * Tests loading an embedded optional configuration builder with the force 546 * create attribute. 547 */ 548 @Test 549 public void testLoadOptionalBuilderForceCreate() 550 throws ConfigurationException 551 { 552 CombinedConfiguration config = prepareOptionalTest("configuration", 553 true); 554 assertEquals("Wrong number of configurations", 1, config 555 .getNumberOfConfigurations()); 556 assertTrue( 557 "Wrong optional configuration type", 558 config.getConfiguration(OPTIONAL_NAME) instanceof CombinedConfiguration); 559 } 560 561 /** 562 * Tests loading an optional configuration with the force create attribute 563 * set. The provider will always throw an exception. In this case the 564 * configuration will not be added to the resulting combined configuration. 565 */ 566 @Test 567 public void testLoadOptionalForceCreateWithException() 568 throws ConfigurationException 569 { 570 factory.addConfigurationProvider("test", 571 new DefaultConfigurationBuilder.ConfigurationBuilderProvider() 572 { 573 // Throw an exception here, too 574 @Override 575 public AbstractConfiguration getEmptyConfiguration( 576 DefaultConfigurationBuilder.ConfigurationDeclaration decl) throws Exception 577 { 578 throw new Exception("Unable to create configuration!"); 579 } 580 }); 581 CombinedConfiguration config = prepareOptionalTest("test", true); 582 assertEquals("Optional configuration could be created", 0, config 583 .getNumberOfConfigurations()); 584 } 585 586 /** 587 * Prepares a test for loading a configuration definition file with an 588 * optional configuration declaration. 589 * 590 * @param tag the tag name with the optional configuration 591 * @param force the forceCreate attribute 592 * @return the combined configuration obtained from the builder 593 * @throws org.apache.commons.configuration.ConfigurationException if an error occurs 594 */ 595 private CombinedConfiguration prepareOptionalTest(String tag, boolean force) 596 throws ConfigurationException 597 { 598 String prefix = "override." + tag; 599 factory.addProperty(prefix + "[@fileName]", "nonExisting.xml"); 600 factory.addProperty(prefix + "[@config-optional]", Boolean.TRUE); 601 factory.addProperty(prefix + "[@config-name]", OPTIONAL_NAME); 602 if (force) 603 { 604 factory.addProperty(prefix + "[@config-forceCreate]", Boolean.TRUE); 605 } 606 return factory.getConfiguration(false); 607 } 608 609 /** 610 * Tests loading a definition file with multiple different sources. 611 */ 612 @Test 613 public void testLoadDifferentSources() throws ConfigurationException 614 { 615 factory.setFile(MULTI_FILE); 616 Configuration config = factory.getConfiguration(); 617 assertFalse(config.isEmpty()); 618 assertTrue(config instanceof CombinedConfiguration); 619 CombinedConfiguration cc = (CombinedConfiguration) config; 620 assertEquals("Wrong number of configurations", 1, cc 621 .getNumberOfConfigurations()); 622 623 assertNotNull(config 624 .getProperty("tables.table(0).fields.field(2).name")); 625 assertNotNull(config.getProperty("element2.subelement.subsubelement")); 626 assertEquals("value", config.getProperty("element3")); 627 assertEquals("foo", config.getProperty("element3[@name]")); 628 assertNotNull(config.getProperty("mail.account.user")); 629 630 // test JNDIConfiguration 631 assertNotNull(config.getProperty("test.onlyinjndi")); 632 assertTrue(config.getBoolean("test.onlyinjndi")); 633 634 Configuration subset = config.subset("test"); 635 assertNotNull(subset.getProperty("onlyinjndi")); 636 assertTrue(subset.getBoolean("onlyinjndi")); 637 638 // test SystemConfiguration 639 assertNotNull(config.getProperty("java.version")); 640 assertEquals(System.getProperty("java.version"), config 641 .getString("java.version")); 642 } 643 644 /** 645 * Tests if the base path is correctly evaluated. 646 */ 647 @Test 648 public void testSetConfigurationBasePath() throws ConfigurationException 649 { 650 factory.addProperty("properties[@fileName]", "test.properties"); 651 File deepDir = new File(ConfigurationAssert.TEST_DIR, "config/deep"); 652 factory.setConfigurationBasePath(deepDir.getAbsolutePath()); 653 654 Configuration config = factory.getConfiguration(false); 655 assertEquals("Wrong property value", "somevalue", config 656 .getString("somekey")); 657 } 658 659 /** 660 * Tests reading a configuration definition file that contains complex 661 * initialization of properties of the declared configuration sources. 662 */ 663 @Test 664 public void testComplexInitialization() throws ConfigurationException 665 { 666 factory.setFile(INIT_FILE); 667 CombinedConfiguration cc = (CombinedConfiguration) factory 668 .getConfiguration(); 669 670 assertEquals("System property not found", "test.xml", 671 cc.getString("test_file_xml")); 672 PropertiesConfiguration c1 = (PropertiesConfiguration) cc 673 .getConfiguration(1); 674 assertTrue( 675 "Reloading strategy was not set", 676 c1.getReloadingStrategy() instanceof FileChangedReloadingStrategy); 677 assertEquals("Refresh delay was not set", 10000, 678 ((FileChangedReloadingStrategy) c1.getReloadingStrategy()) 679 .getRefreshDelay()); 680 681 Configuration xmlConf = cc.getConfiguration("xml"); 682 assertEquals("Property not found", "I'm complex!", xmlConf 683 .getString("element2/subelement/subsubelement")); 684 assertEquals("List index not found", "two", xmlConf 685 .getString("list[0]/item[1]")); 686 assertEquals("Property in combiner file not found", "yellow", cc 687 .getString("/gui/selcolor")); 688 689 assertTrue("Delimiter flag was not set", cc 690 .isDelimiterParsingDisabled()); 691 assertTrue("Expression engine was not set", 692 cc.getExpressionEngine() instanceof XPathExpressionEngine); 693 } 694 695 /** 696 * Tests if the returned combined configuration has the expected structure. 697 */ 698 @Test 699 public void testCombinedConfiguration() throws ConfigurationException 700 { 701 factory.setFile(INIT_FILE); 702 CombinedConfiguration cc = (CombinedConfiguration) factory 703 .getConfiguration(); 704 assertNotNull("Properties configuration not found", cc 705 .getConfiguration("properties")); 706 assertNotNull("XML configuration not found", cc.getConfiguration("xml")); 707 assertEquals("Wrong number of contained configs", 4, cc 708 .getNumberOfConfigurations()); 709 710 CombinedConfiguration cc2 = (CombinedConfiguration) cc 711 .getConfiguration(DefaultConfigurationBuilder.ADDITIONAL_NAME); 712 assertNotNull("No additional configuration found", cc2); 713 Set<String> names = cc2.getConfigurationNames(); 714 assertEquals("Wrong number of contained additional configs", 2, names 715 .size()); 716 assertTrue("Config 1 not contained", names.contains("combiner1")); 717 assertTrue("Config 2 not contained", names.contains("combiner2")); 718 } 719 720 /** 721 * Tests the structure of the returned combined configuration if there is no 722 * additional section. 723 */ 724 @Test 725 public void testCombinedConfigurationNoAdditional() 726 throws ConfigurationException 727 { 728 factory.setFile(TEST_FILE); 729 CombinedConfiguration cc = factory.getConfiguration(true); 730 assertNull("Additional configuration was found", cc 731 .getConfiguration(DefaultConfigurationBuilder.ADDITIONAL_NAME)); 732 } 733 734 /** 735 * Tests whether the list node definition was correctly processed. 736 */ 737 @Test 738 public void testCombinedConfigurationListNodes() 739 throws ConfigurationException 740 { 741 factory.setFile(INIT_FILE); 742 CombinedConfiguration cc = factory.getConfiguration(true); 743 Set<String> listNodes = cc.getNodeCombiner().getListNodes(); 744 assertEquals("Wrong number of list nodes", 2, listNodes.size()); 745 assertTrue("table node not a list node", listNodes.contains("table")); 746 assertTrue("list node not a list node", listNodes.contains("list")); 747 748 CombinedConfiguration cca = (CombinedConfiguration) cc 749 .getConfiguration(DefaultConfigurationBuilder.ADDITIONAL_NAME); 750 listNodes = cca.getNodeCombiner().getListNodes(); 751 assertTrue("Found list nodes for additional combiner", listNodes 752 .isEmpty()); 753 } 754 755 /** 756 * Tests whether a configuration builder can itself be declared in a 757 * configuration definition file. 758 */ 759 @Test 760 public void testConfigurationBuilderProvider() 761 throws ConfigurationException 762 { 763 factory.addProperty("override.configuration[@fileName]", TEST_FILE 764 .getAbsolutePath()); 765 CombinedConfiguration cc = factory.getConfiguration(false); 766 assertEquals("Wrong number of configurations", 1, cc 767 .getNumberOfConfigurations()); 768 checkProperties(cc); 769 } 770 771 /** 772 * Tests whether XML settings can be inherited. 773 */ 774 @Test 775 public void testLoadXMLWithSettings() throws Exception 776 { 777 File confDir = new File("conf"); 778 File targetDir = new File("target"); 779 File testXMLValidationSource = new File(confDir, 780 "testValidateInvalid.xml"); 781 File testSavedXML = new File(targetDir, "testSave.xml"); 782 File testSavedFactory = new File(targetDir, "testSaveFactory.xml"); 783 URL dtdFile = getClass().getResource("/properties.dtd"); 784 final String publicId = "http://commons.apache.org/test.dtd"; 785 786 XMLConfiguration config = new XMLConfiguration("testDtd.xml"); 787 config.setPublicID(publicId); 788 config.save(testSavedXML); 789 factory.addProperty("xml[@fileName]", testSavedXML.getAbsolutePath()); 790 factory.addProperty("xml(0)[@validating]", "true"); 791 factory.addProperty("xml(-1)[@fileName]", testXMLValidationSource 792 .getAbsolutePath()); 793 factory.addProperty("xml(1)[@config-optional]", "true"); 794 factory.addProperty("xml(1)[@validating]", "true"); 795 factory.save(testSavedFactory); 796 797 factory = new DefaultConfigurationBuilder(); 798 factory.setFile(testSavedFactory); 799 factory.registerEntityId(publicId, dtdFile); 800 factory.clearErrorListeners(); 801 Configuration c = factory.getConfiguration(); 802 assertEquals("Wrong property value", "value1", c.getString("entry(0)")); 803 assertFalse("Invalid XML source was loaded", c 804 .containsKey("table.name")); 805 806 testSavedXML.delete(); 807 testSavedFactory.delete(); 808 } 809 810 /** 811 * Tests loading a configuration definition file that defines a custom 812 * result class. 813 */ 814 @Test 815 public void testExtendedClass() throws ConfigurationException 816 { 817 factory.setFile(CLASS_FILE); 818 CombinedConfiguration cc = factory.getConfiguration(true); 819 String prop = (String)cc.getProperty("test"); 820 assertEquals("Expected 'Extended', actual '" + prop + "'", "Extended", prop); 821 assertTrue("Wrong result class: " + cc.getClass(), 822 cc instanceof TestDefaultConfigurationBuilder.ExtendedCombinedConfiguration); 823 } 824 825 /** 826 * Tests loading a configuration definition file that defines new providers. 827 */ 828 @Test 829 public void testConfigurationProvider() throws ConfigurationException 830 { 831 factory.setFile(PROVIDER_FILE); 832 factory.getConfiguration(true); 833 DefaultConfigurationBuilder.ConfigurationProvider provider = factory 834 .providerForTag("test"); 835 assertNotNull("Provider 'test' not registered", provider); 836 } 837 838 /** 839 * Tests loading a configuration definition file that defines new providers. 840 */ 841 @Test 842 public void testExtendedXMLConfigurationProvider() throws ConfigurationException 843 { 844 factory.setFile(EXTENDED_PROVIDER_FILE); 845 CombinedConfiguration cc = factory.getConfiguration(true); 846 DefaultConfigurationBuilder.ConfigurationProvider provider = factory 847 .providerForTag("test"); 848 assertNotNull("Provider 'test' not registered", provider); 849 Configuration config = cc.getConfiguration("xml"); 850 assertNotNull("Test configuration not present", config); 851 assertTrue("Configuration is not ExtendedXMLConfiguration, is " + 852 config.getClass().getName(), 853 config instanceof TestDefaultConfigurationBuilder.ExtendedXMLConfiguration); 854 } 855 856 @Test 857 public void testGlobalLookup() throws Exception 858 { 859 factory.setFile(GLOBAL_LOOKUP_FILE); 860 CombinedConfiguration cc = factory.getConfiguration(true); 861 String value = cc.getInterpolator().lookup("test:test_key"); 862 assertNotNull("The test key was not located", value); 863 assertEquals("Incorrect value retrieved","test.value",value); 864 } 865 866 @Test 867 public void testSystemProperties() throws Exception 868 { 869 factory.setFile(SYSTEM_PROPS_FILE); 870 factory.getConfiguration(true); 871 String value = System.getProperty("key1"); 872 assertNotNull("The test key was not located", value); 873 assertEquals("Incorrect value retrieved","value1",value); 874 } 875 876 @Test 877 public void testValidation() throws Exception 878 { 879 factory.setFile(VALIDATION_FILE); 880 CombinedConfiguration cc = factory.getConfiguration(true); 881 String value = cc.getString("key1"); 882 assertNotNull("The test key was not located", value); 883 assertEquals("Incorrect value retrieved","value1",value); 884 } 885 886 @Test 887 public void testValidation2() throws Exception 888 { 889 factory.setFile(VALIDATION2_FILE); 890 CombinedConfiguration cc = factory.getConfiguration(true); 891 String value = cc.getString("key1"); 892 assertNotNull("The test key was not located", value); 893 assertEquals("Incorrect value retrieved","value1",value); 894 } 895 896 @Test 897 public void testMultiTenentConfiguration() throws Exception 898 { 899 factory.setFile(MULTI_TENENT_FILE); 900 System.getProperties().remove("Id"); 901 902 CombinedConfiguration config = factory.getConfiguration(true); 903 assertTrue("Incorrect configuration", config instanceof DynamicCombinedConfiguration); 904 905 verify(null, config, 50); 906 verify("1001", config, 15); 907 verify("1002", config, 25); 908 verify("1003", config, 35); 909 verify("1004", config, 50); 910 verify("1005", config, 50); 911 } 912 913 @Test 914 public void testMultiTenentConfiguration2() throws Exception 915 { 916 factory.setFile(MULTI_TENENT_FILE); 917 System.setProperty("Id", "1004"); 918 919 CombinedConfiguration config = factory.getConfiguration(true); 920 assertTrue("Incorrect configuration", config instanceof DynamicCombinedConfiguration); 921 922 verify("1001", config, 15); 923 verify("1002", config, 25); 924 verify("1003", config, 35); 925 verify("1004", config, 50); 926 verify("1005", config, 50); 927 } 928 929 @Test 930 public void testMultiTenentConfiguration3() throws Exception 931 { 932 factory.setFile(MULTI_TENENT_FILE); 933 System.setProperty("Id", "1005"); 934 935 CombinedConfiguration config = factory.getConfiguration(true); 936 assertTrue("Incorrect configuration", config instanceof DynamicCombinedConfiguration); 937 938 verify("1001", config, 15); 939 verify("1002", config, 25); 940 verify("1003", config, 35); 941 verify("1004", config, 50); 942 verify("1005", config, 50); 943 } 944 945 @Test 946 public void testSetFileSystem() throws Exception 947 { 948 factory.setFile(PROVIDER_FILE); 949 FileSystem fs = new VFSFileSystem(); 950 factory.setFileSystem(fs); 951 FileSystem.resetDefaultFileSystem(); 952 System.getProperties().remove("Id"); 953 954 CombinedConfiguration config = factory.getConfiguration(true); 955 List<AbstractConfiguration> list = config.getConfigurations(); 956 assertTrue("Incorrect number of configurations - " + list.size(), list.size() == 4); 957 Iterator<AbstractConfiguration> iter = list.iterator(); 958 while (iter.hasNext()) 959 { 960 Configuration conf = iter.next(); 961 if (conf instanceof FileSystemBased) 962 { 963 assertTrue("Incorrect file system for Configuration " + conf, 964 ((FileSystemBased)conf).getFileSystem() == fs); 965 } 966 else if (conf instanceof CombinedConfiguration) 967 { 968 Iterator<AbstractConfiguration> it = ((CombinedConfiguration)conf).getConfigurations().iterator(); 969 while (it.hasNext()) 970 { 971 conf = it.next(); 972 if (conf instanceof FileSystemBased) 973 { 974 assertTrue("Incorrect file system for Configuration " + conf, 975 ((FileSystemBased)conf).getFileSystem() == fs); 976 } 977 } 978 } 979 } 980 } 981 982 @Test 983 public void testConfiguredFileSystem() throws Exception 984 { 985 factory.setFile(FILESYSTEM_FILE); 986 FileSystem.resetDefaultFileSystem(); 987 System.getProperties().remove("Id"); 988 989 CombinedConfiguration config = factory.getConfiguration(true); 990 FileSystem fs = factory.getFileSystem(); 991 assertNotNull("No File System",fs); 992 assertTrue("Incorrect File System", fs instanceof VFSFileSystem); 993 List<AbstractConfiguration> list = config.getConfigurations(); 994 assertTrue("Incorrect number of configurations - " + list.size(), list.size() == 4); 995 Iterator<AbstractConfiguration> iter = list.iterator(); 996 while (iter.hasNext()) 997 { 998 Configuration conf = iter.next(); 999 if (conf instanceof FileSystemBased) 1000 { 1001 assertTrue("Incorrect file system for Configuration " + conf, 1002 ((FileSystemBased)conf).getFileSystem() == fs); 1003 } 1004 else if (conf instanceof CombinedConfiguration) 1005 { 1006 Iterator<AbstractConfiguration> it = ((CombinedConfiguration)conf).getConfigurations().iterator(); 1007 while (it.hasNext()) 1008 { 1009 conf = it.next(); 1010 if (conf instanceof FileSystemBased) 1011 { 1012 assertTrue("Incorrect file system for Configuration " + conf, 1013 ((FileSystemBased)conf).getFileSystem() == fs); 1014 } 1015 } 1016 } 1017 } 1018 } 1019 1020 @Test 1021 public void testFileReload1() throws Exception 1022 { 1023 // create a new configuration 1024 File input = new File("target/test-classes/testMultiConfiguration_1001.xml"); 1025 File output = new File("target/test-classes/testwrite/testMultiConfiguration_1001.xml"); 1026 output.delete(); 1027 output.getParentFile().mkdir(); 1028 copyFile(input, output); 1029 // Sleep to make sure the file timestamp is not in the same second as "now". 1030 Thread.sleep(1100); 1031 1032 factory.setFile(FILERELOAD_FILE); 1033 FileSystem.resetDefaultFileSystem(); 1034 System.getProperties().remove("Id"); 1035 1036 CombinedConfiguration config = factory.getConfiguration(true); 1037 assertNotNull(config); 1038 verify("1001", config, 15); 1039 Thread.sleep(1100); 1040 XMLConfiguration x = new XMLConfiguration(output); 1041 x.setProperty("rowsPerPage", "50"); 1042 x.save(); 1043 verify("1001", config, 50); 1044 output.delete(); 1045 } 1046 1047 @Test 1048 public void testFileReload2() throws Exception 1049 { 1050 // create a new configuration 1051 File input = new File("target/test-classes/testMultiConfiguration_1002.xml"); 1052 File output = new File("target/test-classes/testwrite/testMultiConfiguration_1002.xml"); 1053 output.delete(); 1054 1055 factory.setFile(FILERELOAD_FILE); 1056 FileSystem.resetDefaultFileSystem(); 1057 System.getProperties().remove("Id"); 1058 1059 CombinedConfiguration config = factory.getConfiguration(true); 1060 assertNotNull(config); 1061 1062 verify("1002", config, 50); 1063 // Sleep to make sure the file timestamp is not in the same second as "now". 1064 Thread.sleep(1100); 1065 output.getParentFile().mkdir(); 1066 copyFile(input, output); 1067 verify("1002", config, 25); 1068 output.delete(); 1069 } 1070 1071 @Test 1072 public void testFileReload3() throws Exception 1073 { 1074 // create a new configuration 1075 File input = new File("target/test-classes/testMultiConfiguration_1001.xml"); 1076 File output = new File("target/test-classes/testwrite/testMultiConfiguration_1001.xml"); 1077 output.delete(); 1078 output.getParentFile().mkdir(); 1079 1080 factory.setFile(FILERELOAD_FILE); 1081 FileSystem.resetDefaultFileSystem(); 1082 System.getProperties().remove("Id"); 1083 1084 CombinedConfiguration config = factory.getConfiguration(true); 1085 assertNotNull(config); 1086 verify("1001", config, 50); 1087 copyFile(input, output); 1088 // Sleep to make sure the file timestamp is not in the same second as "now". 1089 Thread.sleep(1100); 1090 verify("1001", config, 15); 1091 XMLConfiguration x = new XMLConfiguration(output); 1092 x.setProperty("rowsPerPage", "25"); 1093 x.save(); 1094 // Sleep to make sure the file timestamp is not in the same second as "now". 1095 Thread.sleep(1100); 1096 verify("1001", config, 25); 1097 output.delete(); 1098 } 1099 1100 @Test 1101 public void testReloadDefault() throws Exception 1102 { 1103 // create a new configuration 1104 String defaultName = "target/test-classes/testMultiConfiguration_default.xml"; 1105 File input = new File(defaultName); 1106 1107 System.getProperties().remove("Id"); 1108 factory.setFile(MULTI_RELOAD_FILE1); 1109 CombinedConfiguration config = factory.getConfiguration(true); 1110 assertNotNull(config); 1111 verify("3001", config, 15); 1112 verify("3002", config, 25); 1113 System.setProperty("Id", "3002"); 1114 config.addProperty("/ TestProp", "Test"); 1115 assertTrue("Property not added", "Test".equals(config.getString("TestProp"))); 1116 System.getProperties().remove("Id"); 1117 //Sleep so refreshDelay elapses 1118 Thread.sleep(600); 1119 long time = System.currentTimeMillis(); 1120 long original = input.lastModified(); 1121 input.setLastModified(time); 1122 File defaultFile = new File(defaultName); 1123 long newTime = defaultFile.lastModified(); 1124 assertTrue("time mismatch", original != newTime); 1125 Thread.sleep(600); 1126 verify("3001", config, 15); 1127 verify("3002", config, 25); 1128 System.setProperty("Id", "3002"); 1129 String test = config.getString("TestProp"); 1130 assertNull("Property was not cleared by reload", test); 1131 } 1132 1133 @Test 1134 public void testFileReloadSchemaValidationError() throws Exception 1135 { 1136 System.getProperties().remove("Id"); 1137 factory.setFile(MULTI_RELOAD_FILE2); 1138 CombinedConfiguration config = factory.getConfiguration(true); 1139 1140 // create a new configuration 1141 File input = new File("target/test-classes/testMultiConfiguration_3001.xml"); 1142 File output = new File("target/test-classes/testwrite/testMultiConfiguration_3001.xml"); 1143 output.delete(); 1144 output.getParentFile().mkdir(); 1145 copyFile(input, output); 1146 1147 assertNotNull(config); 1148 verify("3001", config, 15); 1149 Thread.sleep(1100); 1150 XMLConfiguration x = new XMLConfiguration(); 1151 x.setFile(output); 1152 x.setAttributeSplittingDisabled(true); 1153 x.setDelimiterParsingDisabled(true); 1154 x.load(); 1155 x.setProperty("rowsPerPage", "test"); 1156 //Insure orginal timestamp and new timestamp aren't the same second. 1157 Thread.sleep(1100); 1158 x.save(); 1159 System.setProperty("Id", "3001"); 1160 try 1161 { 1162 config.getInt("rowsPerPage"); 1163 fail("No exception was thrown"); 1164 } 1165 catch (Exception ex) 1166 { 1167 1168 } 1169 1170 output.delete(); 1171 } 1172 1173 private void copyFile(File input, File output) throws IOException 1174 { 1175 Reader reader = new FileReader(input); 1176 Writer writer = new FileWriter(output); 1177 char[] buffer = new char[4096]; 1178 int n = 0; 1179 while (-1 != (n = reader.read(buffer))) 1180 { 1181 writer.write(buffer, 0, n); 1182 } 1183 reader.close(); 1184 writer.close(); 1185 } 1186 1187 private void verify(String key, CombinedConfiguration config, int rows) 1188 { 1189 if (key == null) 1190 { 1191 System.getProperties().remove("Id"); 1192 } 1193 else 1194 { 1195 System.setProperty("Id", key); 1196 } 1197 int actual = config.getInt("rowsPerPage"); 1198 assertTrue("expected: " + rows + " actual: " + actual, actual == rows); 1199 } 1200 }