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 018 package org.apache.commons.configuration; 019 020 import static org.junit.Assert.assertEquals; 021 import static org.junit.Assert.assertFalse; 022 import static org.junit.Assert.assertNotNull; 023 import static org.junit.Assert.assertNotSame; 024 import static org.junit.Assert.assertNull; 025 import static org.junit.Assert.assertSame; 026 import static org.junit.Assert.assertTrue; 027 import static org.junit.Assert.fail; 028 029 import java.io.File; 030 import java.io.FileWriter; 031 import java.io.IOException; 032 import java.io.PrintWriter; 033 import java.util.ArrayList; 034 import java.util.Collection; 035 import java.util.Iterator; 036 import java.util.List; 037 import java.util.NoSuchElementException; 038 039 import org.apache.commons.configuration.event.ConfigurationEvent; 040 import org.apache.commons.configuration.event.ConfigurationListener; 041 import org.apache.commons.configuration.reloading.FileAlwaysReloadingStrategy; 042 import org.easymock.EasyMock; 043 import org.junit.Before; 044 import org.junit.Test; 045 046 /** 047 * Test loading multiple configurations. 048 * 049 * @version $Id: TestCompositeConfiguration.java 1233058 2012-01-18 20:49:12Z oheger $ 050 */ 051 public class TestCompositeConfiguration 052 { 053 /** Constant for a test property to be checked.*/ 054 private static final String TEST_PROPERTY = "test.source.property"; 055 056 protected PropertiesConfiguration conf1; 057 protected PropertiesConfiguration conf2; 058 protected XMLConfiguration xmlConf; 059 protected CompositeConfiguration cc; 060 061 /** 062 * The File that we test with 063 */ 064 private String testProperties = ConfigurationAssert.getTestFile("test.properties").getAbsolutePath(); 065 private String testProperties2 = ConfigurationAssert.getTestFile("test2.properties").getAbsolutePath(); 066 private String testPropertiesXML = ConfigurationAssert.getTestFile("test.xml").getAbsolutePath(); 067 068 @Before 069 public void setUp() throws Exception 070 { 071 cc = new CompositeConfiguration(); 072 conf1 = new PropertiesConfiguration(testProperties); 073 conf2 = new PropertiesConfiguration(testProperties2); 074 xmlConf = new XMLConfiguration(new File(testPropertiesXML)); 075 076 cc.setThrowExceptionOnMissing(true); 077 } 078 079 @Test 080 public void testThrowExceptionOnMissing() 081 { 082 assertTrue("Throw Exception Property is not set!", cc.isThrowExceptionOnMissing()); 083 } 084 085 @Test 086 public void testAddRemoveConfigurations() throws Exception 087 { 088 cc.addConfiguration(conf1); 089 assertEquals("Number of configurations", 2, cc.getNumberOfConfigurations()); 090 cc.addConfiguration(conf1); 091 assertEquals("Number of configurations", 2, cc.getNumberOfConfigurations()); 092 cc.addConfiguration(conf2); 093 assertEquals("Number of configurations", 3, cc.getNumberOfConfigurations()); 094 cc.removeConfiguration(conf1); 095 assertEquals("Number of configurations", 2, cc.getNumberOfConfigurations()); 096 cc.clear(); 097 assertEquals("Number of configurations", 1, cc.getNumberOfConfigurations()); 098 } 099 100 @Test 101 public void testGetPropertyWIncludes() throws Exception 102 { 103 cc.addConfiguration(conf1); 104 cc.addConfiguration(conf2); 105 List<Object> l = cc.getList("packages"); 106 assertTrue(l.contains("packagea")); 107 } 108 109 @Test 110 public void testGetProperty() throws Exception 111 { 112 cc.addConfiguration(conf1); 113 cc.addConfiguration(conf2); 114 assertEquals("Make sure we get the property from conf1 first", "test.properties", cc.getString("propertyInOrder")); 115 cc.clear(); 116 117 cc.addConfiguration(conf2); 118 cc.addConfiguration(conf1); 119 assertEquals("Make sure we get the property from conf2 first", "test2.properties", cc.getString("propertyInOrder")); 120 } 121 122 @Test 123 public void testCantRemoveMemoryConfig() throws Exception 124 { 125 cc.clear(); 126 assertEquals(1, cc.getNumberOfConfigurations()); 127 128 Configuration internal = cc.getConfiguration(0); 129 cc.removeConfiguration(internal); 130 131 assertEquals(1, cc.getNumberOfConfigurations()); 132 } 133 134 @Test 135 public void testGetPropertyMissing() throws Exception 136 { 137 cc.addConfiguration(conf1); 138 cc.addConfiguration(conf2); 139 try 140 { 141 assertNull(cc.getString("bogus.property")); 142 fail("Should have thrown a NoSuchElementException"); 143 } 144 catch (NoSuchElementException nsee) 145 { 146 assertTrue(nsee.getMessage().indexOf("bogus.property") > -1); 147 } 148 149 assertTrue("Should be false", !cc.getBoolean("test.missing.boolean", false)); 150 assertTrue("Should be true", cc.getBoolean("test.missing.boolean.true", true)); 151 } 152 153 /** 154 * Tests {@code List} parsing. 155 */ 156 @Test 157 public void testMultipleTypesOfConfigs() throws Exception 158 { 159 cc.addConfiguration(conf1); 160 cc.addConfiguration(xmlConf); 161 assertEquals("Make sure we get the property from conf1 first", 1, cc.getInt("test.short")); 162 cc.clear(); 163 164 cc.addConfiguration(xmlConf); 165 cc.addConfiguration(conf1); 166 assertEquals("Make sure we get the property from xml", 8, cc.getInt("test.short")); 167 } 168 169 @Test 170 public void testPropertyExistsInOnlyOneConfig() throws Exception 171 { 172 cc.addConfiguration(conf1); 173 cc.addConfiguration(xmlConf); 174 assertEquals("value", cc.getString("element")); 175 } 176 177 /** 178 * Tests getting a default when the key doesn't exist 179 */ 180 @Test 181 public void testDefaultValueWhenKeyMissing() throws Exception 182 { 183 cc.addConfiguration(conf1); 184 cc.addConfiguration(xmlConf); 185 assertEquals("default", cc.getString("bogus", "default")); 186 assertTrue(1.4 == cc.getDouble("bogus", 1.4)); 187 assertTrue(1.4 == cc.getDouble("bogus", 1.4)); 188 } 189 190 @Test 191 public void testGettingConfiguration() throws Exception 192 { 193 cc.addConfiguration(conf1); 194 cc.addConfiguration(xmlConf); 195 assertEquals(PropertiesConfiguration.class, cc.getConfiguration(0).getClass()); 196 assertEquals(XMLConfiguration.class, cc.getConfiguration(1).getClass()); 197 } 198 199 /** 200 * Tests setting values. These are set in memory mode only! 201 */ 202 @Test 203 public void testClearingProperty() throws Exception 204 { 205 cc.addConfiguration(conf1); 206 cc.addConfiguration(xmlConf); 207 cc.clearProperty("test.short"); 208 assertTrue("Make sure test.short is gone!", !cc.containsKey("test.short")); 209 } 210 211 /** 212 * Tests adding values. Make sure they _DON'T_ override any other properties but add to the 213 * existing properties and keep sequence 214 */ 215 @Test 216 public void testAddingProperty() throws Exception 217 { 218 cc.addConfiguration(conf1); 219 cc.addConfiguration(xmlConf); 220 221 String[] values = cc.getStringArray("test.short"); 222 223 assertEquals("Number of values before add is wrong!", 1, values.length); 224 assertEquals("First Value before add is wrong", "1", values[0]); 225 226 cc.addProperty("test.short", "88"); 227 228 values = cc.getStringArray("test.short"); 229 230 assertEquals("Number of values is wrong!", 2, values.length); 231 assertEquals("First Value is wrong", "1", values[0]); 232 assertEquals("Third Value is wrong", "88", values[1]); 233 } 234 235 /** 236 * Tests setting values. These are set in memory mode only! 237 */ 238 @Test 239 public void testSettingMissingProperty() throws Exception 240 { 241 cc.addConfiguration(conf1); 242 cc.addConfiguration(xmlConf); 243 cc.setProperty("my.new.property", "supernew"); 244 assertEquals("supernew", cc.getString("my.new.property")); 245 } 246 247 /** 248 * Tests retrieving subsets of configurations 249 */ 250 @Test 251 public void testGettingSubset() throws Exception 252 { 253 cc.addConfiguration(conf1); 254 cc.addConfiguration(xmlConf); 255 256 Configuration subset = cc.subset("test"); 257 assertNotNull(subset); 258 assertFalse("Shouldn't be empty", subset.isEmpty()); 259 assertEquals("Make sure the initial loaded configs subset overrides any later add configs subset", "1", subset.getString("short")); 260 261 cc.setProperty("test.short", "43"); 262 subset = cc.subset("test"); 263 assertEquals("Make sure the initial loaded configs subset overrides any later add configs subset", "43", subset.getString("short")); 264 } 265 266 /** 267 * Tests subsets and still can resolve elements 268 */ 269 @Test 270 public void testSubsetCanResolve() throws Exception 271 { 272 cc = new CompositeConfiguration(); 273 final BaseConfiguration config = new BaseConfiguration(); 274 config.addProperty("subset.tempfile", "${java.io.tmpdir}/file.tmp"); 275 cc.addConfiguration(config); 276 cc.addConfiguration(ConfigurationConverter.getConfiguration(System.getProperties())); 277 278 Configuration subset = cc.subset("subset"); 279 assertEquals(System.getProperty("java.io.tmpdir") + "/file.tmp", subset.getString("tempfile")); 280 } 281 282 /** 283 * Tests {@code List} parsing. 284 */ 285 @Test 286 public void testList() throws Exception 287 { 288 cc.addConfiguration(conf1); 289 cc.addConfiguration(xmlConf); 290 291 List<Object> packages = cc.getList("packages"); 292 // we should get 3 packages here 293 assertEquals(3, packages.size()); 294 295 List<Object> defaultList = new ArrayList<Object>(); 296 defaultList.add("1"); 297 defaultList.add("2"); 298 299 packages = cc.getList("packages.which.dont.exist", defaultList); 300 // we should get 2 packages here 301 assertEquals(2, packages.size()); 302 303 } 304 305 /** 306 * Tests {@code String} array parsing. 307 */ 308 @Test 309 public void testStringArray() throws Exception 310 { 311 cc.addConfiguration(conf1); 312 cc.addConfiguration(xmlConf); 313 314 String[] packages = cc.getStringArray("packages"); 315 // we should get 3 packages here 316 assertEquals(3, packages.length); 317 318 packages = cc.getStringArray("packages.which.dont.exist"); 319 // we should get 0 packages here 320 assertEquals(0, packages.length); 321 } 322 323 @Test 324 public void testGetList() 325 { 326 Configuration conf1 = new BaseConfiguration(); 327 conf1.addProperty("array", "value1"); 328 conf1.addProperty("array", "value2"); 329 330 Configuration conf2 = new BaseConfiguration(); 331 conf2.addProperty("array", "value3"); 332 conf2.addProperty("array", "value4"); 333 334 cc.addConfiguration(conf1); 335 cc.addConfiguration(conf2); 336 337 // check the composite 'array' property 338 List<Object> list = cc.getList("array"); 339 assertNotNull("null list", list); 340 assertEquals("list size", 2, list.size()); 341 assertTrue("'value1' not found in the list", list.contains("value1")); 342 assertTrue("'value2' not found in the list", list.contains("value2")); 343 344 // add an element to the list in the composite configuration 345 cc.addProperty("array", "value5"); 346 347 // test the new list 348 list = cc.getList("array"); 349 assertNotNull("null list", list); 350 assertEquals("list size", 3, list.size()); 351 assertTrue("'value1' not found in the list", list.contains("value1")); 352 assertTrue("'value2' not found in the list", list.contains("value2")); 353 assertTrue("'value5' not found in the list", list.contains("value5")); 354 } 355 356 /** 357 * Tests {@code getKeys} preserves the order 358 */ 359 @Test 360 public void testGetKeysPreservesOrder() throws Exception 361 { 362 cc.addConfiguration(conf1); 363 List<String> orderedList = new ArrayList<String>(); 364 for (Iterator<String> keys = conf1.getKeys(); keys.hasNext();) 365 { 366 orderedList.add(keys.next()); 367 } 368 List<String> iteratedList = new ArrayList<String>(); 369 for (Iterator<String> keys = cc.getKeys(); keys.hasNext();) 370 { 371 iteratedList.add(keys.next()); 372 } 373 assertEquals(orderedList.size(), iteratedList.size()); 374 for (int i = 0; i < orderedList.size(); i++) 375 { 376 assertEquals(orderedList.get(i), iteratedList.get(i)); 377 } 378 } 379 380 /** 381 * Tests {@code getKeys(String key)} preserves the order 382 */ 383 @Test 384 public void testGetKeys2PreservesOrder() throws Exception 385 { 386 cc.addConfiguration(conf1); 387 List<String> orderedList = new ArrayList<String>(); 388 for (Iterator<String> keys = conf1.getKeys("test"); keys.hasNext();) 389 { 390 orderedList.add(keys.next()); 391 } 392 List<String> iteratedList = new ArrayList<String>(); 393 for (Iterator<String> keys = cc.getKeys("test"); keys.hasNext();) 394 { 395 iteratedList.add(keys.next()); 396 } 397 assertEquals(orderedList.size(), iteratedList.size()); 398 for (int i = 0; i < orderedList.size(); i++) 399 { 400 assertEquals(orderedList.get(i), iteratedList.get(i)); 401 } 402 } 403 404 @Test 405 public void testGetStringWithDefaults() 406 { 407 BaseConfiguration defaults = new BaseConfiguration(); 408 defaults.addProperty("default", "default string"); 409 410 CompositeConfiguration c = new CompositeConfiguration(defaults); 411 c.setThrowExceptionOnMissing(cc.isThrowExceptionOnMissing()); 412 c.addProperty("string", "test string"); 413 414 assertEquals("test string", c.getString("string")); 415 try 416 { 417 c.getString("XXX"); 418 fail("Should throw NoSuchElementException exception"); 419 } 420 catch (NoSuchElementException e) 421 { 422 //ok 423 } 424 catch (Exception e) 425 { 426 fail("Should throw NoSuchElementException exception, not " + e); 427 } 428 429 //test defaults 430 assertEquals("test string", c.getString("string", "some default value")); 431 assertEquals("default string", c.getString("default")); 432 assertEquals("default string", c.getString("default", "some default value")); 433 assertEquals("some default value", c.getString("XXX", "some default value")); 434 } 435 436 @Test 437 public void testCheckingInMemoryConfiguration() throws Exception 438 { 439 String TEST_KEY = "testKey"; 440 Configuration defaults = new PropertiesConfiguration(); 441 defaults.setProperty(TEST_KEY, "testValue"); 442 Configuration testConfiguration = new CompositeConfiguration(defaults); 443 assertTrue(testConfiguration.containsKey(TEST_KEY)); 444 assertFalse(testConfiguration.isEmpty()); 445 boolean foundTestKey = false; 446 Iterator<String> i = testConfiguration.getKeys(); 447 //assertTrue(i instanceof IteratorChain); 448 //IteratorChain ic = (IteratorChain)i; 449 //assertEquals(2,i.size()); 450 for (; i.hasNext();) 451 { 452 String key = i.next(); 453 if (key.equals(TEST_KEY)) 454 { 455 foundTestKey = true; 456 } 457 } 458 assertTrue(foundTestKey); 459 testConfiguration.clearProperty(TEST_KEY); 460 assertFalse(testConfiguration.containsKey(TEST_KEY)); 461 } 462 463 @Test 464 public void testStringArrayInterpolation() 465 { 466 CompositeConfiguration config = new CompositeConfiguration(); 467 config.addProperty("base", "foo"); 468 config.addProperty("list", "${base}.bar1"); 469 config.addProperty("list", "${base}.bar2"); 470 config.addProperty("list", "${base}.bar3"); 471 472 String[] array = config.getStringArray("list"); 473 assertEquals("size", 3, array.length); 474 assertEquals("1st element", "foo.bar1", array[0]); 475 assertEquals("2nd element", "foo.bar2", array[1]); 476 assertEquals("3rd element", "foo.bar3", array[2]); 477 } 478 479 /** 480 * Tests whether global interpolation works with lists. 481 */ 482 @Test 483 public void testListInterpolation() 484 { 485 PropertiesConfiguration c1 = new PropertiesConfiguration(); 486 c1.addProperty("c1.value", "test1"); 487 c1.addProperty("c1.value", "${c2.value}"); 488 cc.addConfiguration(c1); 489 PropertiesConfiguration c2 = new PropertiesConfiguration(); 490 c2.addProperty("c2.value", "test2"); 491 cc.addConfiguration(c2); 492 List<Object> lst = cc.getList("c1.value"); 493 assertEquals("Wrong list size", 2, lst.size()); 494 assertEquals("Wrong first element", "test1", lst.get(0)); 495 assertEquals("Wrong second element", "test2", lst.get(1)); 496 } 497 498 /** 499 * Tests interpolation in combination with reloading. 500 */ 501 @Test 502 public void testInterpolationWithReload() throws IOException, 503 ConfigurationException 504 { 505 File testFile = new File("target/testConfig.properties"); 506 final String propFirst = "first.name"; 507 final String propFull = "full.name"; 508 509 try 510 { 511 writeTestConfig(testFile, propFirst, "John"); 512 PropertiesConfiguration c1 = new PropertiesConfiguration(testFile); 513 c1.setReloadingStrategy(new FileAlwaysReloadingStrategy()); 514 PropertiesConfiguration c2 = new PropertiesConfiguration(); 515 c2.addProperty(propFull, "${" + propFirst + "} Doe"); 516 CompositeConfiguration cc = new CompositeConfiguration(); 517 cc.addConfiguration(c1); 518 cc.addConfiguration(c2); 519 assertEquals("Wrong name", "John Doe", cc.getString(propFull)); 520 521 writeTestConfig(testFile, propFirst, "Jane"); 522 assertEquals("First name not changed", "Jane", c1 523 .getString(propFirst)); 524 assertEquals("First name not changed in composite", "Jane", cc 525 .getString(propFirst)); 526 assertEquals("Full name not changed", "Jane Doe", cc 527 .getString(propFull)); 528 } 529 finally 530 { 531 if (testFile.exists()) 532 { 533 testFile.delete(); 534 } 535 } 536 } 537 538 /** 539 * Writes a test properties file containing a single property definition. 540 * 541 * @param f the file to write 542 * @param prop the property name 543 * @param value the property value 544 * @throws IOException if an error occurs 545 */ 546 private void writeTestConfig(File f, String prop, String value) 547 throws IOException 548 { 549 PrintWriter out = new PrintWriter(new FileWriter(f)); 550 out.print(prop); 551 out.print("="); 552 out.println(value); 553 out.close(); 554 } 555 556 @Test 557 public void testInstanciateWithCollection() 558 { 559 Collection<Configuration> configs = new ArrayList<Configuration>(); 560 configs.add(xmlConf); 561 configs.add(conf1); 562 configs.add(conf2); 563 564 CompositeConfiguration config = new CompositeConfiguration(configs); 565 assertEquals("Number of configurations", 4, config.getNumberOfConfigurations()); 566 assertTrue("The in memory configuration is not empty", config.getInMemoryConfiguration().isEmpty()); 567 } 568 569 @Test 570 public void testClone() 571 { 572 CompositeConfiguration cc2 = (CompositeConfiguration) cc.clone(); 573 assertEquals("Wrong number of contained configurations", cc 574 .getNumberOfConfigurations(), cc2.getNumberOfConfigurations()); 575 576 StrictConfigurationComparator comp = new StrictConfigurationComparator(); 577 for (int i = 0; i < cc.getNumberOfConfigurations(); i++) 578 { 579 assertEquals("Wrong configuration class at " + i, cc 580 .getConfiguration(i).getClass(), cc2.getConfiguration(i) 581 .getClass()); 582 assertNotSame("Configuration was not cloned", cc 583 .getConfiguration(i), cc2.getConfiguration(i)); 584 assertTrue("Configurations at " + i + " not equal", comp.compare(cc 585 .getConfiguration(i), cc2.getConfiguration(i))); 586 } 587 588 assertTrue("Configurations are not equal", comp.compare(cc, cc2)); 589 } 590 591 /** 592 * Tests cloning if one of the contained configurations does not support 593 * this operation. This should cause an exception. 594 */ 595 @Test(expected = ConfigurationRuntimeException.class) 596 public void testCloneNotSupported() 597 { 598 cc.addConfiguration(new NonCloneableConfiguration()); 599 cc.clone(); 600 } 601 602 /** 603 * Ensures that event listeners are not cloned. 604 */ 605 @Test 606 public void testCloneEventListener() 607 { 608 cc.addConfigurationListener(new TestEventListenerImpl()); 609 CompositeConfiguration cc2 = (CompositeConfiguration) cc.clone(); 610 assertTrue("Listeners have been cloned", cc2 611 .getConfigurationListeners().isEmpty()); 612 } 613 614 /** 615 * Tests whether add property events are triggered. 616 */ 617 @Test 618 public void testEventAddProperty() 619 { 620 TestEventListenerImpl l = new TestEventListenerImpl(); 621 cc.addConfigurationListener(l); 622 cc.addProperty("test", "value"); 623 assertEquals("No add events received", 2, l.eventCount); 624 } 625 626 /** 627 * Tests whether set property events are triggered. 628 */ 629 @Test 630 public void testEventSetProperty() 631 { 632 TestEventListenerImpl l = new TestEventListenerImpl(); 633 cc.addConfigurationListener(l); 634 cc.setProperty("test", "value"); 635 assertEquals("No set events received", 2, l.eventCount); 636 } 637 638 /** 639 * Tests whether clear property events are triggered. 640 */ 641 @Test 642 public void testEventClearProperty() 643 { 644 cc.addConfiguration(conf1); 645 assertTrue("Wrong value for property", cc 646 .getBoolean("configuration.loaded")); 647 TestEventListenerImpl l = new TestEventListenerImpl(); 648 cc.addConfigurationListener(l); 649 cc.clearProperty("configuration.loaded"); 650 assertFalse("Key still present", cc.containsKey("configuration.loaded")); 651 assertEquals("No clear events received", 2, l.eventCount); 652 } 653 654 /** 655 * Tests changing the list delimiter character. 656 */ 657 @Test 658 public void testSetListDelimiter() 659 { 660 cc.setListDelimiter('/'); 661 checkSetListDelimiter(); 662 } 663 664 /** 665 * Tests whether the correct list delimiter is set after a clear operation. 666 */ 667 @Test 668 public void testSetListDelimiterAfterClear() 669 { 670 cc.setListDelimiter('/'); 671 cc.clear(); 672 checkSetListDelimiter(); 673 } 674 675 /** 676 * Helper method for testing whether the list delimiter is correctly 677 * handled. 678 */ 679 private void checkSetListDelimiter() 680 { 681 cc.addProperty("test.list", "a/b/c"); 682 cc.addProperty("test.property", "a,b,c"); 683 assertEquals("Wrong number of list elements", 3, cc 684 .getList("test.list").size()); 685 assertEquals("Wrong value of property", "a,b,c", cc 686 .getString("test.property")); 687 } 688 689 /** 690 * Tests whether list splitting can be disabled. 691 */ 692 @Test 693 public void testSetDelimiterParsingDisabled() 694 { 695 cc.setDelimiterParsingDisabled(true); 696 checkSetListDelimiterParsingDisabled(); 697 } 698 699 /** 700 * Tests whether the list parsing flag is correctly handled after a clear() 701 * operation. 702 */ 703 @Test 704 public void testSetDelimiterParsingDisabledAfterClear() 705 { 706 cc.setDelimiterParsingDisabled(true); 707 cc.clear(); 708 checkSetListDelimiterParsingDisabled(); 709 } 710 711 /** 712 * Helper method for checking whether the list parsing flag is correctly 713 * handled. 714 */ 715 private void checkSetListDelimiterParsingDisabled() 716 { 717 cc.addProperty("test.property", "a,b,c"); 718 assertEquals("Wrong value of property", "a,b,c", cc 719 .getString("test.property")); 720 } 721 722 /** 723 * Prepares a test of the getSource() method. 724 */ 725 private void setUpSourceTest() 726 { 727 cc.addConfiguration(conf1); 728 cc.addConfiguration(conf2); 729 } 730 731 /** 732 * Tests the getSource() method if the property is defined in a single child 733 * configuration. 734 */ 735 @Test 736 public void testGetSourceSingle() 737 { 738 setUpSourceTest(); 739 conf1.addProperty(TEST_PROPERTY, Boolean.TRUE); 740 assertSame("Wrong source configuration", conf1, cc 741 .getSource(TEST_PROPERTY)); 742 } 743 744 /** 745 * Tests the getSource() method for an unknown property key. 746 */ 747 @Test 748 public void testGetSourceUnknown() 749 { 750 setUpSourceTest(); 751 assertNull("Wrong source for unknown key", cc.getSource(TEST_PROPERTY)); 752 } 753 754 /** 755 * Tests the getSource() method for a property contained in the in memory 756 * configuration. 757 */ 758 @Test 759 public void testGetSourceInMemory() 760 { 761 setUpSourceTest(); 762 cc.addProperty(TEST_PROPERTY, Boolean.TRUE); 763 assertSame("Source not found in in-memory config", cc 764 .getInMemoryConfiguration(), cc.getSource(TEST_PROPERTY)); 765 } 766 767 /** 768 * Tests the getSource() method if the property is defined by multiple child 769 * configurations. In this case an exception should be thrown. 770 */ 771 @Test(expected = IllegalArgumentException.class) 772 public void testGetSourceMultiple() 773 { 774 setUpSourceTest(); 775 conf1.addProperty(TEST_PROPERTY, Boolean.TRUE); 776 cc.addProperty(TEST_PROPERTY, "a value"); 777 cc.getSource(TEST_PROPERTY); 778 } 779 780 /** 781 * Tests the getSource() method for a null key. This should cause an 782 * exception. 783 */ 784 @Test(expected = IllegalArgumentException.class) 785 public void testGetSourceNull() 786 { 787 cc.getSource(null); 788 } 789 790 /** 791 * Prepares a test for interpolation with multiple configurations and 792 * similar properties. 793 */ 794 private void prepareInterpolationTest() 795 { 796 PropertiesConfiguration p = new PropertiesConfiguration(); 797 p.addProperty("foo", "initial"); 798 p.addProperty("bar", "${foo}"); 799 p.addProperty("prefix.foo", "override"); 800 801 cc.addConfiguration(p.subset("prefix")); 802 cc.addConfiguration(p); 803 assertEquals("Wrong value on direct access", "override", cc 804 .getString("bar")); 805 } 806 807 /** 808 * Tests querying a list when a tricky interpolation is involved. This is 809 * related to CONFIGURATION-339. 810 */ 811 @Test 812 public void testGetListWithInterpolation() 813 { 814 prepareInterpolationTest(); 815 List<Object> lst = cc.getList("bar"); 816 assertEquals("Wrong number of values", 1, lst.size()); 817 assertEquals("Wrong value in list", "override", lst.get(0)); 818 } 819 820 /** 821 * Tests querying a string array when a tricky interpolation is involved. 822 */ 823 @Test 824 public void testGetStringArrayWithInterpolation() 825 { 826 prepareInterpolationTest(); 827 String[] values = cc.getStringArray("bar"); 828 assertEquals("Wrong number of values", 1, values.length); 829 assertEquals("Wrong value in array", "override", values[0]); 830 } 831 832 /** 833 * Tests whether interpolation works if multiple configurations are 834 * involved. This test is related to CONFIGURATION-441. 835 */ 836 @Test 837 public void testInterpolationInMultipleConfigs() 838 { 839 Configuration c1 = new PropertiesConfiguration(); 840 c1.addProperty("property.one", "one"); 841 c1.addProperty("property.two", "two"); 842 Configuration c2 = new PropertiesConfiguration(); 843 c2.addProperty("property.one.ref", "${property.one}"); 844 cc.addConfiguration(c1); 845 cc.addConfiguration(c2); 846 assertEquals("Wrong interpolated value", "one", 847 cc.getString("property.one.ref")); 848 } 849 850 /** 851 * Tests the behavior of setListDelimiter() if the in-memory configuration 852 * is not derived from BaseConfiguration. This test is related to 853 * CONFIGURATION-476. 854 */ 855 @Test 856 public void testSetListDelimiterInMemoryConfigNonBaseConfig() 857 { 858 Configuration inMemoryConfig = EasyMock.createMock(Configuration.class); 859 EasyMock.replay(inMemoryConfig); 860 cc = new CompositeConfiguration(inMemoryConfig); 861 cc.setListDelimiter(';'); 862 } 863 864 /** 865 * Tests the behavior of setDelimiterParsingDisabled() if the in-memory 866 * configuration is not derived from BaseConfiguration. This test is related 867 * to CONFIGURATION-476. 868 */ 869 @Test 870 public void testSetDelimiterParsingDisabledInMemoryConfigNonBaseConfig() 871 { 872 Configuration inMemoryConfig = EasyMock.createMock(Configuration.class); 873 EasyMock.replay(inMemoryConfig); 874 cc = new CompositeConfiguration(inMemoryConfig); 875 cc.setDelimiterParsingDisabled(true); 876 } 877 878 /** 879 * Tests whether a configuration can act as both regular child configuration 880 * and in-memory configuration. This test is related to CONFIGURATION-471. 881 */ 882 @Test 883 public void testUseChildConfigAsInMemoryConfig() 884 { 885 conf1.setProperty(TEST_PROPERTY, "conf1"); 886 conf2.setProperty(TEST_PROPERTY, "conf2"); 887 cc.addConfiguration(conf1, true); 888 cc.addConfiguration(conf2); 889 assertEquals("Wrong number of configurations", 2, 890 cc.getNumberOfConfigurations()); 891 assertEquals("Wrong property", "conf1", cc.getString(TEST_PROPERTY)); 892 cc.addProperty("newProperty", "newValue"); 893 assertEquals("Not added to in-memory config", "newValue", 894 conf1.getString("newProperty")); 895 } 896 897 /** 898 * Tests whether the in-memory configuration can be replaced by a new child 899 * configuration. 900 */ 901 @Test 902 public void testReplaceInMemoryConfig() 903 { 904 conf1.setProperty(TEST_PROPERTY, "conf1"); 905 conf2.setProperty(TEST_PROPERTY, "conf2"); 906 cc.addConfiguration(conf1, true); 907 cc.addProperty("newProperty1", "newValue1"); 908 cc.addConfiguration(conf2, true); 909 cc.addProperty("newProperty2", "newValue2"); 910 assertEquals("Wrong property", "conf1", cc.getString(TEST_PROPERTY)); 911 assertEquals("Not added to in-memory config", "newValue1", 912 conf1.getString("newProperty1")); 913 assertEquals("In-memory config not changed", "newValue2", 914 conf2.getString("newProperty2")); 915 } 916 917 /** 918 * A test configuration event listener that counts the number of received 919 * events. Used for testing the event facilities. 920 */ 921 static class TestEventListenerImpl implements ConfigurationListener 922 { 923 /** The number of received events.*/ 924 int eventCount; 925 926 public void configurationChanged(ConfigurationEvent event) 927 { 928 eventCount++; 929 } 930 } 931 }