1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.configuration;
18
19 import java.io.File;
20 import java.io.IOException;
21 import java.util.Collection;
22 import java.util.Set;
23 import java.util.Map;
24 import java.util.HashMap;
25
26 import junit.framework.TestCase;
27
28 import org.apache.commons.configuration.beanutils.BeanHelper;
29 import org.apache.commons.configuration.reloading.FileChangedReloadingStrategy;
30 import org.apache.commons.configuration.tree.DefaultConfigurationNode;
31 import org.apache.commons.configuration.tree.xpath.XPathExpressionEngine;
32 import org.apache.commons.lang.text.StrLookup;
33
34 /***
35 * Test class for DefaultConfigurationBuilder.
36 *
37 * @author Oliver Heger
38 * @version $Id: TestDefaultConfigurationBuilder.java 727834 2008-12-18 22:16:32Z rgoers $
39 */
40 public class TestDefaultConfigurationBuilder extends TestCase
41 {
42 /*** Test configuration definition file. */
43 private static final File TEST_FILE = new File(
44 "conf/testDigesterConfiguration.xml");
45
46 private static final File ADDITIONAL_FILE = new File(
47 "conf/testDigesterConfiguration2.xml");
48
49 private static final File OPTIONAL_FILE = new File(
50 "conf/testDigesterOptionalConfiguration.xml");
51
52 private static final File OPTIONALEX_FILE = new File(
53 "conf/testDigesterOptionalConfigurationEx.xml");
54
55 private static final File MULTI_FILE = new File(
56 "conf/testDigesterConfiguration3.xml");
57
58 private static final File INIT_FILE = new File(
59 "conf/testComplexInitialization.xml");
60
61 private static final File CLASS_FILE = new File(
62 "conf/testExtendedClass.xml");
63
64 private static final File PROVIDER_FILE = new File(
65 "conf/testConfigurationProvider.xml");
66
67 private static final File EXTENDED_PROVIDER_FILE = new File(
68 "conf/testExtendedXMLConfigurationProvider.xml");
69
70 private static final File GLOBAL_LOOKUP_FILE = new File(
71 "conf/testGlobalLookup.xml");
72
73 private static final File SYSTEM_PROPS_FILE = new File(
74 "conf/testSystemProperties.xml");
75
76 /*** Constant for the name of an optional configuration.*/
77 private static final String OPTIONAL_NAME = "optionalConfig";
78
79 /*** Stores the object to be tested. */
80 DefaultConfigurationBuilder factory;
81
82 protected void setUp() throws Exception
83 {
84 super.setUp();
85 System
86 .setProperty("java.naming.factory.initial",
87 "org.apache.commons.configuration.MockInitialContextFactory");
88 System.setProperty("test_file_xml", "test.xml");
89 System.setProperty("test_file_combine", "testcombine1.xml");
90 factory = new DefaultConfigurationBuilder();
91 factory.clearErrorListeners();
92 }
93
94 /***
95 * Tests the isReservedNode() method of ConfigurationDeclaration.
96 */
97 public void testConfigurationDeclarationIsReserved()
98 {
99 DefaultConfigurationBuilder.ConfigurationDeclaration decl = new DefaultConfigurationBuilder.ConfigurationDeclaration(
100 factory, factory);
101 DefaultConfigurationNode parent = new DefaultConfigurationNode();
102 DefaultConfigurationNode nd = new DefaultConfigurationNode("at");
103 parent.addAttribute(nd);
104 assertTrue("Attribute at not recognized", decl.isReservedNode(nd));
105 nd = new DefaultConfigurationNode("optional");
106 parent.addAttribute(nd);
107 assertTrue("Attribute optional not recognized", decl.isReservedNode(nd));
108 nd = new DefaultConfigurationNode("config-class");
109 parent.addAttribute(nd);
110 assertTrue("Inherited attribute not recognized", decl
111 .isReservedNode(nd));
112 nd = new DefaultConfigurationNode("different");
113 parent.addAttribute(nd);
114 assertFalse("Wrong reserved attribute", decl.isReservedNode(nd));
115 nd = new DefaultConfigurationNode("at");
116 parent.addChild(nd);
117 assertFalse("Node type not evaluated", decl.isReservedNode(nd));
118 }
119
120 /***
121 * Tests if the at attribute is correctly detected as reserved attribute.
122 */
123 public void testConfigurationDeclarationIsReservedAt()
124 {
125 checkOldReservedAttribute("at");
126 }
127
128 /***
129 * Tests if the optional attribute is correctly detected as reserved
130 * attribute.
131 */
132 public void testConfigurationDeclarationIsReservedOptional()
133 {
134 checkOldReservedAttribute("optional");
135 }
136
137 /***
138 * Tests if special reserved attributes are recognized by the
139 * isReservedNode() method. For compatibility reasons the attributes "at"
140 * and "optional" are also treated as reserved attributes, but only if there
141 * are no corresponding attributes with the "config-" prefix.
142 *
143 * @param name the attribute name
144 */
145 private void checkOldReservedAttribute(String name)
146 {
147 DefaultConfigurationBuilder.ConfigurationDeclaration decl = new DefaultConfigurationBuilder.ConfigurationDeclaration(
148 factory, factory);
149 DefaultConfigurationNode parent = new DefaultConfigurationNode();
150 DefaultConfigurationNode nd = new DefaultConfigurationNode("config-"
151 + name);
152 parent.addAttribute(nd);
153 assertTrue("config-" + name + " attribute not recognized", decl
154 .isReservedNode(nd));
155 DefaultConfigurationNode nd2 = new DefaultConfigurationNode(name);
156 parent.addAttribute(nd2);
157 assertFalse(name + " is reserved though config- exists", decl
158 .isReservedNode(nd2));
159 assertTrue("config- attribute not recognized when " + name + " exists",
160 decl.isReservedNode(nd));
161 }
162
163 /***
164 * Tests access to certain reserved attributes of a
165 * ConfigurationDeclaration.
166 */
167 public void testConfigurationDeclarationGetAttributes()
168 {
169 factory.addProperty("xml.fileName", "test.xml");
170 DefaultConfigurationBuilder.ConfigurationDeclaration decl = new DefaultConfigurationBuilder.ConfigurationDeclaration(
171 factory, factory.configurationAt("xml"));
172 assertNull("Found an at attribute", decl.getAt());
173 assertFalse("Found an optional attribute", decl.isOptional());
174 factory.addProperty("xml[@config-at]", "test1");
175 assertEquals("Wrong value of at attribute", "test1", decl.getAt());
176 factory.addProperty("xml[@at]", "test2");
177 assertEquals("Wrong value of config-at attribute", "test1", decl.getAt());
178 factory.clearProperty("xml[@config-at]");
179 assertEquals("Old at attribute not detected", "test2", decl.getAt());
180 factory.addProperty("xml[@config-optional]", "true");
181 assertTrue("Wrong value of optional attribute", decl.isOptional());
182 factory.addProperty("xml[@optional]", "false");
183 assertTrue("Wrong value of config-optional attribute", decl.isOptional());
184 factory.clearProperty("xml[@config-optional]");
185 factory.setProperty("xml[@optional]", Boolean.TRUE);
186 assertTrue("Old optional attribute not detected", decl.isOptional());
187 factory.setProperty("xml[@optional]", "invalid value");
188 try
189 {
190 decl.isOptional();
191 fail("Invalid optional attribute was not detected!");
192 }
193 catch (ConfigurationRuntimeException crex)
194 {
195
196 }
197 }
198
199 /***
200 * Tests adding a new configuration provider.
201 */
202 public void testAddConfigurationProvider()
203 {
204 DefaultConfigurationBuilder.ConfigurationProvider provider = new DefaultConfigurationBuilder.ConfigurationProvider();
205 assertNull("Provider already registered", factory
206 .providerForTag("test"));
207 factory.addConfigurationProvider("test", provider);
208 assertSame("Provider not registered", provider, factory
209 .providerForTag("test"));
210 }
211
212 /***
213 * Tries to register a null configuration provider. This should cause an
214 * exception.
215 */
216 public void testAddConfigurationProviderNull()
217 {
218 try
219 {
220 factory.addConfigurationProvider("test", null);
221 fail("Could register null provider");
222 }
223 catch (IllegalArgumentException iex)
224 {
225
226 }
227 }
228
229 /***
230 * Tries to register a configuration provider for a null tag. This should
231 * cause an exception to be thrown.
232 */
233 public void testAddConfigurationProviderNullTag()
234 {
235 try
236 {
237 factory.addConfigurationProvider(null,
238 new DefaultConfigurationBuilder.ConfigurationProvider());
239 fail("Could register provider for null tag!");
240 }
241 catch (IllegalArgumentException iex)
242 {
243
244 }
245 }
246
247 /***
248 * Tests removing configuration providers.
249 */
250 public void testRemoveConfigurationProvider()
251 {
252 assertNull("Removing unknown provider", factory
253 .removeConfigurationProvider("test"));
254 assertNull("Removing provider for null tag", factory
255 .removeConfigurationProvider(null));
256 DefaultConfigurationBuilder.ConfigurationProvider provider = new DefaultConfigurationBuilder.ConfigurationProvider();
257 factory.addConfigurationProvider("test", provider);
258 assertSame("Failed to remove provider", provider, factory
259 .removeConfigurationProvider("test"));
260 assertNull("Provider still registered", factory.providerForTag("test"));
261 }
262
263 /***
264 * Tests creating a configuration object from a configuration declaration.
265 */
266 public void testConfigurationBeanFactoryCreateBean()
267 {
268 factory.addConfigurationProvider("test",
269 new DefaultConfigurationBuilder.ConfigurationProvider(
270 PropertiesConfiguration.class));
271 factory.addProperty("test[@throwExceptionOnMissing]", "true");
272 DefaultConfigurationBuilder.ConfigurationDeclaration decl = new DefaultConfigurationBuilder.ConfigurationDeclaration(
273 factory, factory.configurationAt("test"));
274 PropertiesConfiguration conf = (PropertiesConfiguration) BeanHelper
275 .createBean(decl);
276 assertTrue("Property was not initialized", conf
277 .isThrowExceptionOnMissing());
278 }
279
280 /***
281 * Tests creating a configuration object from an unknown tag. This should
282 * cause an exception.
283 */
284 public void testConfigurationBeanFactoryCreateUnknownTag()
285 {
286 factory.addProperty("test[@throwExceptionOnMissing]", "true");
287 DefaultConfigurationBuilder.ConfigurationDeclaration decl = new DefaultConfigurationBuilder.ConfigurationDeclaration(
288 factory, factory.configurationAt("test"));
289 try
290 {
291 BeanHelper.createBean(decl);
292 fail("Could create configuration from unknown tag!");
293 }
294 catch (ConfigurationRuntimeException crex)
295 {
296
297 }
298 }
299
300 /***
301 * Tests loading a simple configuration definition file.
302 */
303 public void testLoadConfiguration() throws ConfigurationException
304 {
305 factory.setFile(TEST_FILE);
306 checkConfiguration();
307 }
308
309 /***
310 * Tests the file constructor.
311 */
312 public void testLoadConfigurationFromFile() throws ConfigurationException
313 {
314 factory = new DefaultConfigurationBuilder(TEST_FILE);
315 checkConfiguration();
316 }
317
318 /***
319 * Tests the file name constructor.
320 */
321 public void testLoadConfigurationFromFileName()
322 throws ConfigurationException
323 {
324 factory = new DefaultConfigurationBuilder(TEST_FILE.getAbsolutePath());
325 checkConfiguration();
326 }
327
328 /***
329 * Tests the URL constructor.
330 */
331 public void testLoadConfigurationFromURL() throws Exception
332 {
333 factory = new DefaultConfigurationBuilder(TEST_FILE.toURL());
334 checkConfiguration();
335 }
336
337 /***
338 * Tests if the configuration was correctly created by the factory.
339 */
340 private void checkConfiguration() throws ConfigurationException
341 {
342 CombinedConfiguration compositeConfiguration = (CombinedConfiguration) factory
343 .getConfiguration();
344
345 assertEquals("Number of configurations", 3, compositeConfiguration
346 .getNumberOfConfigurations());
347 assertEquals(PropertiesConfiguration.class, compositeConfiguration
348 .getConfiguration(0).getClass());
349 assertEquals(XMLPropertiesConfiguration.class, compositeConfiguration
350 .getConfiguration(1).getClass());
351 assertEquals(XMLConfiguration.class, compositeConfiguration
352 .getConfiguration(2).getClass());
353
354
355 PropertiesConfiguration pc = (PropertiesConfiguration) compositeConfiguration
356 .getConfiguration(0);
357 assertNotNull("Make sure we have a fileName: " + pc.getFileName(), pc
358 .getFileName());
359
360
361 checkProperties(compositeConfiguration);
362 }
363
364 /***
365 * Checks if the passed in configuration contains the expected properties.
366 *
367 * @param compositeConfiguration the configuration to check
368 */
369 private void checkProperties(Configuration compositeConfiguration)
370 {
371 assertTrue("Make sure we have loaded our key", compositeConfiguration
372 .getBoolean("test.boolean"));
373 assertEquals("I'm complex!", compositeConfiguration
374 .getProperty("element2.subelement.subsubelement"));
375 assertEquals("property in the XMLPropertiesConfiguration", "value1",
376 compositeConfiguration.getProperty("key1"));
377 }
378
379 /***
380 * Tests loading a configuration definition file with an additional section.
381 */
382 public void testLoadAdditional() throws ConfigurationException
383 {
384 factory.setFile(ADDITIONAL_FILE);
385 CombinedConfiguration compositeConfiguration = (CombinedConfiguration) factory
386 .getConfiguration();
387 assertEquals("Verify how many configs", 2, compositeConfiguration
388 .getNumberOfConfigurations());
389
390
391 Object prop = compositeConfiguration.getProperty("tables.table.name");
392 assertTrue(prop instanceof Collection);
393 assertEquals(3, ((Collection) prop).size());
394 assertEquals("users", compositeConfiguration
395 .getProperty("tables.table(0).name"));
396 assertEquals("documents", compositeConfiguration
397 .getProperty("tables.table(1).name"));
398 assertEquals("tasks", compositeConfiguration
399 .getProperty("tables.table(2).name"));
400
401 prop = compositeConfiguration
402 .getProperty("tables.table.fields.field.name");
403 assertTrue(prop instanceof Collection);
404 assertEquals(17, ((Collection) prop).size());
405
406 assertEquals("smtp.mydomain.org", compositeConfiguration
407 .getString("mail.host.smtp"));
408 assertEquals("pop3.mydomain.org", compositeConfiguration
409 .getString("mail.host.pop"));
410
411
412 assertEquals("masterOfPost", compositeConfiguration
413 .getString("mail.account.user"));
414 assertEquals("topsecret", compositeConfiguration
415 .getString("mail.account.psswd"));
416
417
418 assertEquals("enhanced factory", compositeConfiguration
419 .getString("test.configuration"));
420 }
421
422 /***
423 * Tests whether a default log error listener is registered at the builder
424 * instance.
425 */
426 public void testLogErrorListener()
427 {
428 assertEquals("No default error listener registered", 1,
429 new DefaultConfigurationBuilder().getErrorListeners().size());
430 }
431
432 /***
433 * Tests loading a definition file that contains optional configurations.
434 */
435 public void testLoadOptional() throws Exception
436 {
437 factory.setURL(OPTIONAL_FILE.toURL());
438 Configuration config = factory.getConfiguration();
439 assertTrue(config.getBoolean("test.boolean"));
440 assertEquals("value", config.getProperty("element"));
441 }
442
443 /***
444 * Tests whether loading a failing optional configuration causes an error
445 * event.
446 */
447 public void testLoadOptionalErrorEvent() throws Exception
448 {
449 factory.clearErrorListeners();
450 ConfigurationErrorListenerImpl listener = new ConfigurationErrorListenerImpl();
451 factory.addErrorListener(listener);
452 prepareOptionalTest("configuration", false);
453 listener.verify(DefaultConfigurationBuilder.EVENT_ERR_LOAD_OPTIONAL,
454 OPTIONAL_NAME, null);
455 }
456
457 /***
458 * Tests loading a definition file with optional and non optional
459 * configuration sources. One non optional does not exist, so this should
460 * cause an exception.
461 */
462 public void testLoadOptionalWithException()
463 {
464 factory.setFile(OPTIONALEX_FILE);
465 try
466 {
467 factory.getConfiguration();
468 fail("Non existing source did not cause an exception!");
469 }
470 catch (ConfigurationException cex)
471 {
472
473 }
474 }
475
476 /***
477 * Tries to load a configuration file with an optional, non file-based
478 * configuration. The optional attribute should work for other configuration
479 * classes, too.
480 */
481 public void testLoadOptionalNonFileBased() throws ConfigurationException
482 {
483 CombinedConfiguration config = prepareOptionalTest("configuration", false);
484 assertTrue("Configuration not empty", config.isEmpty());
485 assertEquals("Wrong number of configurations", 0, config
486 .getNumberOfConfigurations());
487 }
488
489 /***
490 * Tests an optional, non existing configuration with the forceCreate
491 * attribute. This configuration should be added to the resulting
492 * configuration.
493 */
494 public void testLoadOptionalForceCreate() throws ConfigurationException
495 {
496 factory.setBasePath(TEST_FILE.getParent());
497 CombinedConfiguration config = prepareOptionalTest("xml", true);
498 assertEquals("Wrong number of configurations", 1, config
499 .getNumberOfConfigurations());
500 FileConfiguration fc = (FileConfiguration) config
501 .getConfiguration(OPTIONAL_NAME);
502 assertNotNull("Optional config not found", fc);
503 assertEquals("File name was not set", "nonExisting.xml", fc
504 .getFileName());
505 assertNotNull("Base path was not set", fc.getBasePath());
506 }
507
508 /***
509 * Tests loading an embedded optional configuration builder with the force
510 * create attribute.
511 */
512 public void testLoadOptionalBuilderForceCreate()
513 throws ConfigurationException
514 {
515 CombinedConfiguration config = prepareOptionalTest("configuration",
516 true);
517 assertEquals("Wrong number of configurations", 1, config
518 .getNumberOfConfigurations());
519 assertTrue(
520 "Wrong optional configuration type",
521 config.getConfiguration(OPTIONAL_NAME) instanceof CombinedConfiguration);
522 }
523
524 /***
525 * Tests loading an optional configuration with the force create attribute
526 * set. The provider will always throw an exception. In this case the
527 * configuration will not be added to the resulting combined configuration.
528 */
529 public void testLoadOptionalForceCreateWithException()
530 throws ConfigurationException
531 {
532 factory.addConfigurationProvider("test",
533 new DefaultConfigurationBuilder.ConfigurationBuilderProvider()
534 {
535
536 public AbstractConfiguration getEmptyConfiguration(
537 DefaultConfigurationBuilder.ConfigurationDeclaration decl) throws Exception
538 {
539 throw new Exception("Unable to create configuration!");
540 }
541 });
542 CombinedConfiguration config = prepareOptionalTest("test", true);
543 assertEquals("Optional configuration could be created", 0, config
544 .getNumberOfConfigurations());
545 }
546
547 /***
548 * Prepares a test for loading a configuration definition file with an
549 * optional configuration declaration.
550 *
551 * @param tag the tag name with the optional configuration
552 * @param force the forceCreate attribute
553 * @return the combined configuration obtained from the builder
554 * @throws ConfigurationException if an error occurs
555 */
556 private CombinedConfiguration prepareOptionalTest(String tag, boolean force)
557 throws ConfigurationException
558 {
559 String prefix = "override." + tag;
560 factory.addProperty(prefix + "[@fileName]", "nonExisting.xml");
561 factory.addProperty(prefix + "[@config-optional]", Boolean.TRUE);
562 factory.addProperty(prefix + "[@config-name]", OPTIONAL_NAME);
563 if (force)
564 {
565 factory.addProperty(prefix + "[@config-forceCreate]", Boolean.TRUE);
566 }
567 return factory.getConfiguration(false);
568 }
569
570 /***
571 * Tests loading a definition file with multiple different sources.
572 */
573 public void testLoadDifferentSources() throws ConfigurationException
574 {
575 factory.setFile(MULTI_FILE);
576 Configuration config = factory.getConfiguration();
577 assertFalse(config.isEmpty());
578 assertTrue(config instanceof CombinedConfiguration);
579 CombinedConfiguration cc = (CombinedConfiguration) config;
580 assertEquals("Wrong number of configurations", 1, cc
581 .getNumberOfConfigurations());
582
583 assertNotNull(config
584 .getProperty("tables.table(0).fields.field(2).name"));
585 assertNotNull(config.getProperty("element2.subelement.subsubelement"));
586 assertEquals("value", config.getProperty("element3"));
587 assertEquals("foo", config.getProperty("element3[@name]"));
588 assertNotNull(config.getProperty("mail.account.user"));
589
590
591 assertNotNull(config.getProperty("test.onlyinjndi"));
592 assertTrue(config.getBoolean("test.onlyinjndi"));
593
594 Configuration subset = config.subset("test");
595 assertNotNull(subset.getProperty("onlyinjndi"));
596 assertTrue(subset.getBoolean("onlyinjndi"));
597
598
599 assertNotNull(config.getProperty("java.version"));
600 assertEquals(System.getProperty("java.version"), config
601 .getString("java.version"));
602 }
603
604 /***
605 * Tests if the base path is correctly evaluated.
606 */
607 public void testSetConfigurationBasePath() throws ConfigurationException
608 {
609 factory.addProperty("properties[@fileName]", "test.properties");
610 File deepDir = new File("conf/config/deep");
611 factory.setConfigurationBasePath(deepDir.getAbsolutePath());
612
613 Configuration config = factory.getConfiguration(false);
614 assertEquals("Wrong property value", "somevalue", config
615 .getString("somekey"));
616 }
617
618 /***
619 * Tests reading a configuration definition file that contains complex
620 * initialization of properties of the declared configuration sources.
621 */
622 public void testComplexInitialization() throws ConfigurationException
623 {
624 factory.setFile(INIT_FILE);
625 CombinedConfiguration cc = (CombinedConfiguration) factory
626 .getConfiguration();
627
628 assertEquals("System property not found", "test.xml",
629 cc.getString("test_file_xml"));
630 PropertiesConfiguration c1 = (PropertiesConfiguration) cc
631 .getConfiguration(1);
632 assertTrue(
633 "Reloading strategy was not set",
634 c1.getReloadingStrategy() instanceof FileChangedReloadingStrategy);
635 assertEquals("Refresh delay was not set", 10000,
636 ((FileChangedReloadingStrategy) c1.getReloadingStrategy())
637 .getRefreshDelay());
638
639 Configuration xmlConf = cc.getConfiguration("xml");
640 assertEquals("Property not found", "I'm complex!", xmlConf
641 .getString("element2/subelement/subsubelement"));
642 assertEquals("List index not found", "two", xmlConf
643 .getString("list[0]/item[1]"));
644 assertEquals("Property in combiner file not found", "yellow", cc
645 .getString("/gui/selcolor"));
646
647 assertTrue("Delimiter flag was not set", cc
648 .isDelimiterParsingDisabled());
649 assertTrue("Expression engine was not set",
650 cc.getExpressionEngine() instanceof XPathExpressionEngine);
651 }
652
653 /***
654 * Tests if the returned combined configuration has the expected structure.
655 */
656 public void testCombinedConfiguration() throws ConfigurationException
657 {
658 factory.setFile(INIT_FILE);
659 CombinedConfiguration cc = (CombinedConfiguration) factory
660 .getConfiguration();
661 assertNotNull("Properties configuration not found", cc
662 .getConfiguration("properties"));
663 assertNotNull("XML configuration not found", cc.getConfiguration("xml"));
664 assertEquals("Wrong number of contained configs", 4, cc
665 .getNumberOfConfigurations());
666
667 CombinedConfiguration cc2 = (CombinedConfiguration) cc
668 .getConfiguration(DefaultConfigurationBuilder.ADDITIONAL_NAME);
669 assertNotNull("No additional configuration found", cc2);
670 Set names = cc2.getConfigurationNames();
671 assertEquals("Wrong number of contained additional configs", 2, names
672 .size());
673 assertTrue("Config 1 not contained", names.contains("combiner1"));
674 assertTrue("Config 2 not contained", names.contains("combiner2"));
675 }
676
677 /***
678 * Tests the structure of the returned combined configuration if there is no
679 * additional section.
680 */
681 public void testCombinedConfigurationNoAdditional()
682 throws ConfigurationException
683 {
684 factory.setFile(TEST_FILE);
685 CombinedConfiguration cc = factory.getConfiguration(true);
686 assertNull("Additional configuration was found", cc
687 .getConfiguration(DefaultConfigurationBuilder.ADDITIONAL_NAME));
688 }
689
690 /***
691 * Tests whether the list node definition was correctly processed.
692 */
693 public void testCombinedConfigurationListNodes()
694 throws ConfigurationException
695 {
696 factory.setFile(INIT_FILE);
697 CombinedConfiguration cc = factory.getConfiguration(true);
698 Set listNodes = cc.getNodeCombiner().getListNodes();
699 assertEquals("Wrong number of list nodes", 2, listNodes.size());
700 assertTrue("table node not a list node", listNodes.contains("table"));
701 assertTrue("list node not a list node", listNodes.contains("list"));
702
703 CombinedConfiguration cca = (CombinedConfiguration) cc
704 .getConfiguration(DefaultConfigurationBuilder.ADDITIONAL_NAME);
705 listNodes = cca.getNodeCombiner().getListNodes();
706 assertTrue("Found list nodes for additional combiner", listNodes
707 .isEmpty());
708 }
709
710 /***
711 * Tests whether a configuration builder can itself be declared in a
712 * configuration definition file.
713 */
714 public void testConfigurationBuilderProvider()
715 throws ConfigurationException
716 {
717 factory.addProperty("override.configuration[@fileName]", TEST_FILE
718 .getAbsolutePath());
719 CombinedConfiguration cc = factory.getConfiguration(false);
720 assertEquals("Wrong number of configurations", 1, cc
721 .getNumberOfConfigurations());
722 checkProperties(cc);
723 }
724
725 /***
726 * Tests whether XML settings can be inherited.
727 */
728 public void testLoadXMLWithSettings() throws ConfigurationException,
729 IOException
730 {
731 File confDir = new File("conf");
732 File targetDir = new File("target");
733 File testXMLSource = new File(confDir, "testDtd.xml");
734 File testXMLValidationSource = new File(confDir,
735 "testValidateInvalid.xml");
736 File testSavedXML = new File(targetDir, "testSave.xml");
737 File testSavedFactory = new File(targetDir, "testSaveFactory.xml");
738 File dtdFile = new File(confDir, "properties.dtd");
739 final String publicId = "http://commons.apache.org/test.dtd";
740
741 XMLConfiguration config = new XMLConfiguration(testXMLSource);
742 config.setPublicID(publicId);
743 config.save(testSavedXML);
744 factory.addProperty("xml[@fileName]", testSavedXML.getAbsolutePath());
745 factory.addProperty("xml(0)[@validating]", "true");
746 factory.addProperty("xml(-1)[@fileName]", testXMLValidationSource
747 .getAbsolutePath());
748 factory.addProperty("xml(1)[@config-optional]", "true");
749 factory.addProperty("xml(1)[@validating]", "true");
750 factory.save(testSavedFactory);
751
752 factory = new DefaultConfigurationBuilder();
753 factory.setFile(testSavedFactory);
754 factory.registerEntityId(publicId, dtdFile.toURL());
755 factory.clearErrorListeners();
756 Configuration c = factory.getConfiguration();
757 assertEquals("Wrong property value", "value1", c.getString("entry(0)"));
758 assertFalse("Invalid XML source was loaded", c
759 .containsKey("table.name"));
760
761 testSavedXML.delete();
762 testSavedFactory.delete();
763 }
764
765 /***
766 * Tests loading a configuration definition file that defines a custom
767 * result class.
768 */
769 public void testExtendedClass() throws ConfigurationException
770 {
771 factory.setFile(CLASS_FILE);
772 CombinedConfiguration cc = factory.getConfiguration(true);
773 assertEquals("Extended", cc.getProperty("test"));
774 assertTrue("Wrong result class: " + cc.getClass(),
775 cc instanceof ExtendedCombinedConfiguration);
776 }
777
778 /***
779 * Tests loading a configuration definition file that defines new providers.
780 */
781 public void testConfigurationProvider() throws ConfigurationException
782 {
783 factory.setFile(PROVIDER_FILE);
784 factory.getConfiguration(true);
785 DefaultConfigurationBuilder.ConfigurationProvider provider = factory
786 .providerForTag("test");
787 assertNotNull("Provider 'test' not registered", provider);
788 }
789
790 /***
791 * Tests loading a configuration definition file that defines new providers.
792 */
793 public void testExtendedXMLConfigurationProvider() throws ConfigurationException
794 {
795 factory.setFile(EXTENDED_PROVIDER_FILE);
796 CombinedConfiguration cc = factory.getConfiguration(true);
797 DefaultConfigurationBuilder.ConfigurationProvider provider = factory
798 .providerForTag("test");
799 assertNotNull("Provider 'test' not registered", provider);
800 Configuration config = cc.getConfiguration("xml");
801 assertNotNull("Test configuration not present", config);
802 assertTrue("Configuration is not ExtendedXMLConfiguration, is " +
803 config.getClass().getName(), config instanceof ExtendedXMLConfiguration);
804 }
805
806 public void testGlobalLookup() throws Exception
807 {
808 factory.setFile(GLOBAL_LOOKUP_FILE);
809 CombinedConfiguration cc = factory.getConfiguration(true);
810 String value = cc.getInterpolator().lookup("test:test_key");
811 assertNotNull("The test key was not located", value);
812 assertEquals("Incorrect value retrieved","test.value",value);
813 }
814
815 public void testSystemProperties() throws Exception
816 {
817 factory.setFile(SYSTEM_PROPS_FILE);
818 CombinedConfiguration cc = factory.getConfiguration(true);
819 String value = System.getProperty("key1");
820 assertNotNull("The test key was not located", value);
821 assertEquals("Incorrect value retrieved","value1",value);
822 }
823
824
825 /***
826 * A specialized combined configuration implementation used for testing
827 * custom result classes.
828 */
829 public static class ExtendedCombinedConfiguration extends
830 CombinedConfiguration
831 {
832 /***
833 * The serial version UID.
834 */
835 private static final long serialVersionUID = 4678031745085083392L;
836
837 public Object getProperty(String key)
838 {
839 if (key.equals("test"))
840 {
841 return "Extended";
842 }
843 return super.getProperty(key);
844 }
845 }
846
847 public static class ExtendedXMLConfiguration extends XMLConfiguration
848 {
849 public ExtendedXMLConfiguration()
850 {
851 }
852
853 }
854
855 public static class TestLookup extends StrLookup
856 {
857 Map map = new HashMap();
858
859 public TestLookup()
860 {
861 map.put("test_file_xml", "test.xml");
862 map.put("test_file_combine", "testcombine1.xml");
863 map.put("test_key", "test.value");
864 }
865
866 public String lookup(String key)
867 {
868 if (key == null)
869 {
870 return null;
871 }
872 return (String)map.get(key);
873
874 }
875 }
876 }
877