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