    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one or more
    3    * contributor license agreements.  See the NOTICE file distributed with
    4    * this work for additional information regarding copyright ownership.
    5    * The ASF licenses this file to You under the Apache License, Version 2.0
    6    * (the "License"); you may not use this file except in compliance with
    7    * the License.  You may obtain a copy of the License at
    8    *
    9    *     http://www.apache.org/licenses/LICENSE-2.0
    10   *
    11   * Unless required by applicable law or agreed to in writing, software
    12   * distributed under the License is distributed on an "AS IS" BASIS,
    13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14   * See the License for the specific language governing permissions and
    15   * limitations under the License.
    16   */
    17
    18  package org.apache.commons.configuration;
    19
    20  import java.io.File;
    21  import java.io.FileWriter;
    22  import java.util.Collection;
    23  import java.util.List;
    24
    25  import junit.framework.TestCase;
    26
    27  import org.xml.sax.SAXException;
    28
    29  /***
    30   * Test the ConfigurationFactory.
    31   *
    32   * @version $Id: TestConfigurationFactory.java 570916 2007-08-29 20:05:46Z oheger $
    33   */
    34  public class TestConfigurationFactory extends TestCase
    35  {
    36      /*** The Files that we test with */
    37      private File digesterRules = new File("conf/digesterRules.xml");
    38      private File testDigesterFile =
    39              new File("conf/testDigesterConfiguration.xml");
    40      private File testDigesterFileReverseOrder =
    41              new File("conf/testDigesterConfigurationReverseOrder.xml");
    42      private File testDigesterFileNamespaceAware =
    43              new File("conf/testDigesterConfigurationNamespaceAware.xml");
    44      private File testDigesterFileBasePath =
    45              new File("conf/testDigesterConfigurationBasePath.xml");
    46      private File testDigesterFileEnhanced =
    47              new File("conf/testDigesterConfiguration2.xml");
    48      private File testDigesterFileComplete =
    49              new File("conf/testDigesterConfiguration3.xml");
    50      private File testDigesterFileOptional =
    51              new File("conf/testDigesterOptionalConfiguration.xml");
    52      private File testDigesterFileOptionalEx =
    53              new File("conf/testDigesterOptionalConfigurationEx.xml");
    54      private File testDigesterFileSysProps =
    55              new File("conf/testDigesterConfigurationSysProps.xml");
    56      private File testDigesterFileInitProps =
    57              new File("conf/testDigesterConfigurationWithProps.xml");
    58
    59      private File testDigesterBadXML = new File("conf/testDigesterBadXML.xml");
    60
    61      private String testBasePath = new File("conf").getAbsolutePath();
    62
    63      private File testProperties = new File("conf/test.properties");
    64      private File testAbsConfig = new File("target/testAbsConfig.xml");
    65
    66      private Configuration configuration;
    67      private CompositeConfiguration compositeConfiguration;
    68      private ConfigurationFactory factory;
    69
    70      public void setUp() throws Exception
    71      {
    72          System.setProperty("java.naming.factory.initial", "org.apache.commons.configuration.MockInitialContextFactory");
    73          factory = new ConfigurationFactory();
    74      }
    75
    76      public void testJNDI() throws Exception
    77      {
    78          JNDIConfiguration jndiConfiguration = new JNDIConfiguration();
    79          Object o = jndiConfiguration.getProperty("test.boolean");
    80          assertNotNull(o);
    81          assertEquals("true", o.toString());
    82      }
    83
    84      public void testLoadingConfiguration() throws Exception
    85      {
    86          factory.setConfigurationFileName(testDigesterFile.toString());
    87
    88          compositeConfiguration = (CompositeConfiguration) factory.getConfiguration();
    89
    90          assertEquals("Number of configurations", 4, compositeConfiguration.getNumberOfConfigurations());
    91          assertEquals(PropertiesConfiguration.class, compositeConfiguration.getConfiguration(0).getClass());
    92          assertEquals(XMLPropertiesConfiguration.class, compositeConfiguration.getConfiguration(1).getClass());
    93          assertEquals(XMLConfiguration.class, compositeConfiguration.getConfiguration(2).getClass());
    94
    95          // check the first configuration
    96          PropertiesConfiguration pc = (PropertiesConfiguration) compositeConfiguration.getConfiguration(0);
    97          assertNotNull("Make sure we have a fileName: " + pc.getFileName(), pc.getFileName());
    98
    99          // check some properties
    100         assertTrue("Make sure we have loaded our key", compositeConfiguration.getBoolean("test.boolean"));
    101         assertEquals("I'm complex!", compositeConfiguration.getProperty("element2.subelement.subsubelement"));
    102         assertEquals("property in the XMLPropertiesConfiguration", "value1", compositeConfiguration.getProperty("key1"));
    103     }
    104
    105     public void testLoadingConfigurationWithRulesXML() throws Exception
    106     {
    107         factory.setConfigurationFileName(testDigesterFile.toString());
    108         factory.setDigesterRules(digesterRules.toURL());
    109
    110         compositeConfiguration = (CompositeConfiguration) factory.getConfiguration();
    111
    112         assertEquals("Number of configurations", 4, compositeConfiguration.getNumberOfConfigurations());
    113         assertEquals(PropertiesConfiguration.class, compositeConfiguration.getConfiguration(0).getClass());
    114         //assertEquals(XMLPropertiesConfiguration.class, compositeConfiguration.getConfiguration(1).getClass()); // doesn't work
    115         assertEquals(XMLConfiguration.class, compositeConfiguration.getConfiguration(2).getClass());
    116
    117         // check the first configuration
    118         PropertiesConfiguration pc = (PropertiesConfiguration) compositeConfiguration.getConfiguration(0);
    119         assertNotNull("Make sure we have a fileName: " + pc.getFileName(), pc.getFileName());
    120
    121         // check some properties
    122         assertTrue("Make sure we have loaded our key", pc.getBoolean("test.boolean"));
    123         assertTrue("Make sure we have loaded our key", compositeConfiguration.getBoolean("test.boolean"));
    124
    125         assertEquals("I'm complex!", compositeConfiguration.getProperty("element2.subelement.subsubelement"));
    126     }
    127
    128     public void testLoadingConfigurationReverseOrder() throws Exception
    129     {
    130         factory.setConfigurationFileName(testDigesterFileReverseOrder.toString());
    131
    132         configuration = factory.getConfiguration();
    133
    134         assertEquals("8", configuration.getProperty("test.short"));
    135
    136         factory.setConfigurationFileName(testDigesterFile.toString());
    137
    138         configuration = factory.getConfiguration();
    139         assertEquals("1", configuration.getProperty("test.short"));
    140     }
    141
    142     public void testLoadingConfigurationNamespaceAware() throws Exception
    143     {
    144         factory.setConfigurationFileName(testDigesterFileNamespaceAware.toString());
    145         //factory.setDigesterRules(digesterRules.toURL());
    146         factory.setDigesterRuleNamespaceURI("namespace-one");
    147
    148         checkCompositeConfiguration();
    149     }
    150
    151     public void testLoadingConfigurationBasePath() throws Exception
    152     {
    153         factory.setConfigurationFileName(testDigesterFileBasePath.toString());
    154
    155         factory.setBasePath(testBasePath);
    156
    157         //factory.setDigesterRules(digesterRules.toURL());
    158         //factory.setDigesterRuleNamespaceURI("namespace-one");
    159
    160         checkCompositeConfiguration();
    161     }
    162
    163     public void testLoadingAdditional() throws Exception
    164     {
    165         factory.setConfigurationFileName(testDigesterFileEnhanced.toString());
    166         factory.setBasePath(null);
    167         checkUnionConfig();
    168     }
    169
    170     public void testLoadingURL() throws Exception
    171     {
    172         factory.setConfigurationURL(testDigesterFileEnhanced.toURL());
    173         checkUnionConfig();
    174
    175         factory = new ConfigurationFactory();
    176         File nonExistingFile = new File("conf/nonexisting.xml");
    177         factory.setConfigurationURL(nonExistingFile.toURL());
    178         try
    179         {
    180             factory.getConfiguration();
    181             fail("Could load non existing file!");
    182         }
    183         catch(ConfigurationException cex)
    184         {
    185             //ok
    186         }
    187     }
    188
    189     public void testThrowingConfigurationInitializationException() throws Exception
    190     {
    191         factory.setConfigurationFileName(testDigesterBadXML.toString());
    192         try
    193         {
    194             factory.getConfiguration();
    195             fail("Should have throw an Exception");
    196         }
    197         catch (ConfigurationException cle)
    198         {
    199             assertTrue("Unexpected cause: " + cle.getCause(),
    200                     cle.getCause() instanceof SAXException);
    201         }
    202     }
    203
    204     // Tests if properties from all sources can be loaded
    205     public void testAllConfiguration() throws Exception
    206     {
    207         factory.setConfigurationURL(testDigesterFileComplete.toURL());
    208         Configuration config = factory.getConfiguration();
    209         assertFalse(config.isEmpty());
    210         assertTrue(config instanceof CompositeConfiguration);
    211         CompositeConfiguration cc = (CompositeConfiguration) config;
    212         assertTrue(cc.getNumberOfConfigurations() > 1);
    213         // Currently fails, should be 4?  Only 2?
    214         //assertEquals(4, cc.getNumberOfConfigurations());
    215
    216         assertNotNull(config.getProperty("tables.table(0).fields.field(2).name"));
    217         assertNotNull(config.getProperty("element2.subelement.subsubelement"));
    218         assertEquals("value", config.getProperty("element3"));
    219         assertEquals("foo", config.getProperty("element3[@name]"));
    220         assertNotNull(config.getProperty("mail.account.user"));
    221
    222         // test JNDIConfiguration
    223         assertNotNull(config.getProperty("test.onlyinjndi"));
    224         assertTrue(config.getBoolean("test.onlyinjndi"));
    225
    226         Configuration subset = config.subset("test");
    227         assertNotNull(subset.getProperty("onlyinjndi"));
    228         assertTrue(subset.getBoolean("onlyinjndi"));
    229
    230         // test SystemConfiguration
    231         assertNotNull(config.getProperty("java.version"));
    232         assertEquals(System.getProperty("java.version"), config.getString("java.version"));
    233     }
    234
    235     // Checks if optional configurations work
    236     public void testOptionalConfigurations() throws Exception
    237     {
    238         factory.setConfigurationURL(testDigesterFileOptional.toURL());
    239         Configuration config = factory.getConfiguration();
    240         assertTrue(config.getBoolean("test.boolean"));
    241         assertEquals("value", config.getProperty("element"));
    242
    243         factory.setConfigurationURL(testDigesterFileOptionalEx.toURL());
    244         try
    245         {
    246             config = factory.getConfiguration();
    247             fail("Unexisting properties loaded!");
    248         }
    249         catch(ConfigurationException cex)
    250         {
    251             // fine
    252         }
    253     }
    254
    255     // Checks if a file with an absolute path can be loaded
    256     public void testLoadAbsolutePath() throws Exception
    257     {
    258         try
    259         {
    260             FileWriter out = null;
    261             try
    262             {
    263                 out = new FileWriter(testAbsConfig);
    264                 out.write("<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>");
    265                 out.write("<configuration>");
    266                 out.write("<properties fileName=\"");
    267                 out.write(testProperties.getAbsolutePath());
    268                 out.write("\"/>");
    269                 out.write("</configuration>");
    270             }
    271             finally
    272             {
    273                 if (out != null)
    274                 {
    275                     out.close();
    276                 }
    277             }
    278
    279             factory.setConfigurationFileName(testAbsConfig.toString());
    280             Configuration config = factory.getConfiguration();
    281             assertTrue(config.getBoolean("configuration.loaded"));
    282         }
    283         finally
    284         {
    285             if (testAbsConfig.exists())
    286             {
    287                 testAbsConfig.delete();
    288             }
    289         }
    290     }
    291
    292     public void testBasePath() throws Exception
    293     {
    294         assertEquals(".", factory.getBasePath());
    295         factory.setConfigurationFileName(testDigesterFile.getAbsolutePath());
    296         // if no specific base path has been set, the base is determined
    297         // from the file name
    298         assertEquals(testDigesterFile.getParentFile().getAbsolutePath(),
    299                 factory.getBasePath());
    300
    301         String homeDir = System.getProperty("user.home");
    302         factory = new ConfigurationFactory();
    303         factory.setBasePath(homeDir);
    304         factory.setConfigurationFileName(testDigesterFile.getAbsolutePath());
    305         // if a base path was set, the file name does not play a role
    306         assertEquals(homeDir, factory.getBasePath());
    307
    308         factory = new ConfigurationFactory(testDigesterFile.getAbsolutePath());
    309         assertEquals(testDigesterFile.getParentFile().getAbsolutePath(),
    310                 factory.getBasePath());
    311         factory.setBasePath(homeDir);
    312         assertEquals(homeDir, factory.getBasePath());
    313
    314         factory = new ConfigurationFactory();
    315         factory.setConfigurationURL(testDigesterFile.toURL());
    316         assertEquals(testDigesterFile.toURL().toString(), factory.getBasePath());
    317     }
    318
    319     // Tests if system properties can be resolved in the configuration
    320     // definition
    321     public void testLoadingWithSystemProperties() throws ConfigurationException
    322     {
    323         System.setProperty("config.file", "test.properties");
    324         factory.setConfigurationFileName(testDigesterFileSysProps
    325                 .getAbsolutePath());
    326         Configuration config = factory.getConfiguration();
    327         assertTrue("Configuration not loaded", config
    328                 .getBoolean("configuration.loaded"));
    329     }
    330
    331     // Tests if the properties of a configuration object are correctly set
    332     // before it is loaded.
    333     public void testLoadInitProperties() throws ConfigurationException
    334     {
    335         factory.setConfigurationFileName(testDigesterFileInitProps
    336                 .getAbsolutePath());
    337         Configuration config = factory.getConfiguration();
    338         PropertiesConfiguration c = (PropertiesConfiguration) ((CompositeConfiguration) config)
    339                 .getConfiguration(0);
    340         assertEquals("List delimiter was not set", ';', c.getListDelimiter());
    341         List l = c.getList("test.mixed.array");
    342         assertEquals("Wrong number of list elements", 2, l.size());
    343         assertEquals("List delimiter was not applied", "b, c, d", l.get(1));
    344     }
    345
    346     private void checkUnionConfig() throws Exception
    347     {
    348         compositeConfiguration = (CompositeConfiguration) factory.getConfiguration();
    349         assertEquals("Verify how many configs", 3, compositeConfiguration.getNumberOfConfigurations());
    350
    351         // Test if union was constructed correctly
    352         Object prop = compositeConfiguration.getProperty("tables.table.name");
    353         assertTrue(prop instanceof Collection);
    354         assertEquals(3, ((Collection) prop).size());
    355         assertEquals("users", compositeConfiguration.getProperty("tables.table(0).name"));
    356         assertEquals("documents", compositeConfiguration.getProperty("tables.table(1).name"));
    357         assertEquals("tasks", compositeConfiguration.getProperty("tables.table(2).name"));
    358
    359         prop = compositeConfiguration.getProperty("tables.table.fields.field.name");
    360         assertTrue(prop instanceof Collection);
    361         assertEquals(17, ((Collection) prop).size());
    362
    363         assertEquals("smtp.mydomain.org", compositeConfiguration.getString("mail.host.smtp"));
    364         assertEquals("pop3.mydomain.org", compositeConfiguration.getString("mail.host.pop"));
    365
    366         // This was overriden
    367         assertEquals("masterOfPost", compositeConfiguration.getString("mail.account.user"));
    368         assertEquals("topsecret", compositeConfiguration.getString("mail.account.psswd"));
    369
    370         // This was overriden, too, but not in additional section
    371         assertEquals("enhanced factory", compositeConfiguration.getString("test.configuration"));
    372     }
    373
    374     private void checkCompositeConfiguration() throws Exception
    375     {
    376         compositeConfiguration = (CompositeConfiguration) factory.getConfiguration();
    377
    378         assertEquals("Verify how many configs", 2, compositeConfiguration.getNumberOfConfigurations());
    379         assertEquals(PropertiesConfiguration.class, compositeConfiguration.getConfiguration(0).getClass());
    380
    381         PropertiesConfiguration pc = (PropertiesConfiguration) compositeConfiguration.getConfiguration(0);
    382         assertNotNull("Make sure we have a fileName:" + pc.getFileName(), pc.getFileName());
    383         assertTrue("Make sure we have loaded our key", pc.getBoolean("test.boolean"));
    384         assertTrue("Make sure we have loaded our key", compositeConfiguration.getBoolean("test.boolean"));
    385
    386         Object property = compositeConfiguration.getProperty("element2.subelement.subsubelement");
    387         assertNull("Should have returned a null", property);
    388     }
    389 }