    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.net.URL;
    21  import java.util.Properties;
    22  import java.io.File;
    23  import java.io.FileInputStream;
    24  import java.io.FileOutputStream;
    25  import java.io.FileWriter;
    26  import java.io.IOException;
    27  import java.io.PrintWriter;
    28
    29  import org.apache.commons.configuration.reloading.FileChangedReloadingStrategy;
    30
    31  import junit.framework.TestCase;
    32
    33  /***
    34   * @author Emmanuel Bourg
    35   * @version $Revision: 439648 $, $Date: 2006-09-02 22:42:10 +0200 (Sa, 02 Sep 2006) $
    36   */
    37  public class TestFileConfiguration extends TestCase
    38  {
    39      private static final File TARGET_DIR = new File("target");
    40
    41      private static final String RESOURCE_NAME = "config/deep/deeptest.properties";
    42
    43      public void testSetURL() throws Exception
    44      {
    45          // http URL
    46          FileConfiguration config = new PropertiesConfiguration();
    47          config.setURL(new URL("http://jakarta.apache.org/commons/configuration/index.html"));
    48
    49          assertEquals("base path", "http://jakarta.apache.org/commons/configuration/", config
    50                  .getBasePath());
    51          assertEquals("file name", "index.html", config.getFileName());
    52
    53          // file URL
    54          config.setURL(new URL("file:/temp/test.properties"));
    55          assertEquals("base path", "file:/temp/", config.getBasePath());
    56          assertEquals("file name", "test.properties", config.getFileName());
    57      }
    58
    59      public void testSetURLWithParams() throws Exception
    60      {
    61          FileConfiguration config = new PropertiesConfiguration();
    62          URL url = new URL(
    63                  "http://issues.apache.org/bugzilla/show_bug.cgi?id=37886");
    64          config.setURL(url);
    65          assertEquals("Base path incorrect",
    66                  "http://issues.apache.org/bugzilla/", config.getBasePath());
    67          assertEquals("File name incorrect", "show_bug.cgi", config
    68                  .getFileName());
    69          assertEquals("URL was not correctly stored", url, config.getURL());
    70      }
    71
    72      public void testLocations() throws Exception
    73      {
    74          PropertiesConfiguration config = new PropertiesConfiguration();
    75
    76          File directory = new File("conf");
    77          File file = new File(directory, "test.properties");
    78          config.setFile(file);
    79          assertEquals(directory.getAbsolutePath(), config.getBasePath());
    80          assertEquals("test.properties", config.getFileName());
    81          assertEquals(file.getAbsolutePath(), config.getPath());
    82
    83          config.setPath("conf" + File.separator + "test.properties");
    84          assertEquals("test.properties", config.getFileName());
    85          assertEquals(directory.getAbsolutePath(), config.getBasePath());
    86          assertEquals(file.getAbsolutePath(), config.getPath());
    87          assertEquals(file.toURL(), config.getURL());
    88
    89          config.setBasePath(null);
    90          config.setFileName("test.properties");
    91          assertNull(config.getBasePath());
    92          assertEquals("test.properties", config.getFileName());
    93      }
    94
    95      public void testCreateFile1() throws Exception
    96      {
    97          File file = new File("target/test-resources/foo/bar/test.properties");
    98          if (file.exists())
    99          {
    100             file.delete();
    101             file.getParentFile().delete();
    102         }
    103
    104         assertFalse("The file should not exist", file.exists());
    105
    106         FileConfiguration config = new PropertiesConfiguration(file);
    107         config.save();
    108
    109         assertTrue("The file doesn't exist", file.exists());
    110     }
    111
    112     public void testCreateFile2() throws Exception
    113     {
    114         File file = new File("target/test-resources/foo/bar/test.properties");
    115         if (file.exists())
    116         {
    117             file.delete();
    118             file.getParentFile().delete();
    119         }
    120
    121         assertFalse("The file should not exist", file.exists());
    122
    123         FileConfiguration config = new PropertiesConfiguration();
    124         config.setFile(file);
    125         config.save();
    126
    127         assertTrue("The file doesn't exist", file.exists());
    128     }
    129
    130     public void testCreateFile3() throws Exception
    131     {
    132         File file = new File("target/test-resources/foo/bar/test.properties");
    133         if (file.exists())
    134         {
    135             file.delete();
    136             file.getParentFile().delete();
    137         }
    138
    139         assertFalse("The file should not exist", file.exists());
    140
    141         FileConfiguration config = new PropertiesConfiguration();
    142         config.save(file);
    143
    144         assertTrue("The file doesn't exist", file.exists());
    145     }
    146
    147     /***
    148      * Tests collaboration with ConfigurationFactory: Is the base path set on
    149      * loading is valid in file based configurations?
    150      *
    151      * @throws Exception if an error occurs
    152      */
    153     public void testWithConfigurationFactory() throws Exception
    154     {
    155         File dir = new File("conf");
    156         File file = new File(dir, "testFileConfiguration.properties");
    157
    158         if (file.exists())
    159         {
    160             assertTrue("File cannot be deleted", file.delete());
    161         }
    162
    163         try
    164         {
    165             ConfigurationFactory factory = new ConfigurationFactory();
    166             factory.setConfigurationURL(new File(dir, "testDigesterConfiguration2.xml").toURL());
    167             CompositeConfiguration cc = (CompositeConfiguration) factory.getConfiguration();
    168             PropertiesConfiguration config = null;
    169             for (int i = 0; config == null; i++)
    170             {
    171                 if (cc.getConfiguration(i) instanceof PropertiesConfiguration)
    172                 {
    173                     config = (PropertiesConfiguration) cc.getConfiguration(i);
    174                 }
    175             }
    176
    177             config.setProperty("test", "yes");
    178             config.save(file.getName());
    179             assertTrue(file.exists());
    180             config = new PropertiesConfiguration();
    181             config.setFile(file);
    182             config.load();
    183
    184             assertEquals("yes", config.getProperty("test"));
    185             assertEquals("masterOfPost", config.getProperty("mail.account.user"));
    186         }
    187         finally
    188         {
    189             if (file.exists())
    190             {
    191                 assertTrue("File could not be deleted", file.delete());
    192             }
    193         }
    194     }
    195
    196     /***
    197      * Tests if invalid URLs cause an exception.
    198      */
    199     public void testSaveInvalidURL() throws Exception
    200     {
    201         FileConfiguration config = new PropertiesConfiguration();
    202         try
    203         {
    204             config.save(new URL("http://jakarta.apache.org"));
    205             fail("Should throw a ConfigurationException!");
    206         }
    207         catch (ConfigurationException cex)
    208         {
    209             //fine
    210         }
    211
    212         try
    213         {
    214             config.save("http://www.apache.org");
    215             fail("Should throw a ConfigurationException!");
    216         }
    217         catch (ConfigurationException cex)
    218         {
    219             //fine
    220         }
    221     }
    222
    223     /***
    224      * Tests if the URL used by the load() method is also used by save().
    225      */
    226     public void testFileOverwrite() throws Exception
    227     {
    228         FileOutputStream out = null;
    229         FileInputStream in = null;
    230         File tempFile = null;
    231         try
    232         {
    233             String path = System.getProperties().getProperty("user.home");
    234             File homeDir = new File(path);
    235             tempFile = File.createTempFile("CONF", null, homeDir);
    236             String fileName = tempFile.getName();
    237             Properties props = new Properties();
    238             props.setProperty("1", "one");
    239             out = new FileOutputStream(tempFile);
    240             props.store(out, "TestFileOverwrite");
    241             out.close();
    242             out = null;
    243             FileConfiguration config = new PropertiesConfiguration(fileName);
    244             config.load();
    245             String value = config.getString("1");
    246             assertTrue("one".equals(value));
    247             config.setProperty("1", "two");
    248             config.save();
    249             props = new Properties();
    250             in = new FileInputStream(tempFile);
    251             props.load(in);
    252             String value2 = props.getProperty("1");
    253             assertTrue("two".equals(value2));
    254         }
    255         finally
    256         {
    257             if (out != null)
    258             {
    259                 try
    260                 {
    261                     out.close();
    262                 }
    263                 catch (IOException ioex)
    264                 {
    265                     ioex.printStackTrace();
    266                 }
    267             }
    268             if (in != null)
    269             {
    270                 try
    271                 {
    272                     in.close();
    273                 }
    274                 catch (IOException ioex)
    275                 {
    276                     ioex.printStackTrace();
    277                 }
    278             }
    279             if (tempFile.exists())
    280             {
    281                 assertTrue(tempFile.delete());
    282             }
    283         }
    284     }
    285
    286     /***
    287      * Tests setting a file changed reloading strategy together with the auto
    288      * save feature.
    289      */
    290     public void testReloadingWithAutoSave() throws Exception
    291     {
    292         File configFile = new File(TARGET_DIR, "test.properties");
    293         PrintWriter out = null;
    294
    295         try
    296         {
    297             out = new PrintWriter(new FileWriter(configFile));
    298             out.println("a = one");
    299             out.close();
    300             out = null;
    301
    302             PropertiesConfiguration config = new PropertiesConfiguration(
    303                     configFile);
    304             config.setReloadingStrategy(new FileChangedReloadingStrategy());
    305             config.setAutoSave(true);
    306
    307             assertEquals("one", config.getProperty("a"));
    308             config.setProperty("b", "two");
    309             assertEquals("one", config.getProperty("a"));
    310         }
    311         finally
    312         {
    313             if (out != null)
    314             {
    315                 out.close();
    316             }
    317             if (configFile.exists())
    318             {
    319                 assertTrue(configFile.delete());
    320             }
    321         }
    322     }
    323
    324     /***
    325      * Tests loading and saving a configuration file with a complicated path
    326      * name including spaces. (related to issue 35210)
    327      */
    328     public void testPathWithSpaces() throws Exception
    329     {
    330         File path = new File(TARGET_DIR, "path with spaces");
    331         File confFile = new File(path, "config-test.properties");
    332         PrintWriter out = null;
    333
    334         try
    335         {
    336             if (!path.exists())
    337             {
    338                 assertTrue(path.mkdir());
    339             }
    340             out = new PrintWriter(new FileWriter(confFile));
    341             out.println("saved = false");
    342             out.close();
    343             out = null;
    344
    345             URL url = new URL(TARGET_DIR.toURL()
    346                     + "path%20with%20spaces/config-test.properties");
    347             PropertiesConfiguration config = new PropertiesConfiguration(url);
    348             config.load();
    349             assertFalse(config.getBoolean("saved"));
    350
    351             config.setProperty("saved", Boolean.TRUE);
    352             config.save();
    353             config = new PropertiesConfiguration();
    354             config.setFile(confFile);
    355             config.load();
    356             assertTrue(config.getBoolean("saved"));
    357         }
    358         finally
    359         {
    360             if (out != null)
    361             {
    362                 out.close();
    363             }
    364             if (confFile.exists())
    365             {
    366                 assertTrue(confFile.delete());
    367             }
    368             if (path.exists())
    369             {
    370                 assertTrue(path.delete());
    371             }
    372         }
    373     }
    374
    375     /***
    376      * Tests the getFile() method.
    377      */
    378     public void testGetFile() throws ConfigurationException
    379     {
    380         FileConfiguration config = new PropertiesConfiguration();
    381         assertNull(config.getFile());
    382         File file = new File("conf/test.properties").getAbsoluteFile();
    383         config.setFile(file);
    384         assertEquals(file, config.getFile());
    385         config.load();
    386         assertEquals(file, config.getFile());
    387     }
    388
    389     /***
    390      * Tests to invoke save() without explicitely setting a file name. This
    391      * will cause an exception.
    392      */
    393     public void testSaveWithoutFileName() throws Exception
    394     {
    395         FileConfiguration config = new PropertiesConfiguration();
    396         File file = new File("conf/test.properties");
    397         config.load(file);
    398         try
    399         {
    400             config.save();
    401             fail("Could save config without setting a file name!");
    402         }
    403         catch(ConfigurationException cex)
    404         {
    405             //ok
    406         }
    407
    408         config = new PropertiesConfiguration();
    409         config.load("conf/test.properties");
    410         try
    411         {
    412             config.save();
    413             fail("Could save config without setting a file name!");
    414         }
    415         catch(ConfigurationException cex)
    416         {
    417             //ok
    418         }
    419
    420         config = new PropertiesConfiguration();
    421         config.load(file.toURL());
    422         try
    423         {
    424             config.save();
    425             fail("Could save config without setting a file name!");
    426         }
    427         catch(ConfigurationException cex)
    428         {
    429             //ok
    430         }
    431     }
    432
    433     /***
    434      * Checks that loading a directory instead of a file throws an exception.
    435      */
    436     public void testLoadDirectory()
    437     {
    438         PropertiesConfiguration config = new PropertiesConfiguration();
    439
    440         try
    441         {
    442             config.load("target");
    443             fail("Could load config from a directory!");
    444         }
    445         catch (ConfigurationException e)
    446         {
    447             // ok
    448         }
    449
    450         try
    451         {
    452             config.load(new File("target"));
    453             fail("Could load config from a directory!");
    454         }
    455         catch (ConfigurationException e)
    456         {
    457             // ok
    458         }
    459
    460         try
    461         {
    462             new PropertiesConfiguration("target");
    463             fail("Could load config from a directory!");
    464         }
    465         catch (ConfigurationException e)
    466         {
    467             // ok
    468         }
    469
    470         try
    471         {
    472             new PropertiesConfiguration(new File("target"));
    473             fail("Could load config from a directory!");
    474         }
    475         catch (ConfigurationException e)
    476         {
    477             // ok
    478         }
    479     }
    480
    481     /***
    482      * Tests whether the constructor behaves the same as setFileName() when the
    483      * configuration source is in the classpath.
    484      */
    485     public void testInitFromClassPath() throws ConfigurationException
    486     {
    487         PropertiesConfiguration config1 = new PropertiesConfiguration();
    488         config1.setFileName(RESOURCE_NAME);
    489         config1.load();
    490         PropertiesConfiguration config2 = new PropertiesConfiguration(
    491                 RESOURCE_NAME);
    492         compare(config1, config2);
    493     }
    494
    495     /***
    496      * Tests the loading of configuration file in a Combined configuration
    497      * when the configuration source is in the classpath.
    498      */
    499     public void testLoadFromClassPath() throws ConfigurationException
    500     {
    501         DefaultConfigurationBuilder cf =
    502             new DefaultConfigurationBuilder("conf/config/deep/testFileFromClasspath.xml");
    503         CombinedConfiguration config = cf.getConfiguration(true);
    504         Configuration config1 = config.getConfiguration("propConf");
    505         Configuration config2 = config.getConfiguration("propConfDeep");
    506         compare(config1, config2);
    507     }
    508
    509     /***
    510      * Tests cloning a file based configuration.
    511      */
    512     public void testClone() throws ConfigurationException
    513     {
    514         PropertiesConfiguration config = new PropertiesConfiguration(
    515                 RESOURCE_NAME);
    516         PropertiesConfiguration copy = (PropertiesConfiguration) config.clone();
    517         compare(config, copy);
    518         assertNull("URL was not reset", copy.getURL());
    519         assertNull("Base path was not reset", copy.getBasePath());
    520         assertNull("File name was not reset", copy.getFileName());
    521         assertNotSame("Reloading strategy was not reset", config
    522                 .getReloadingStrategy(), copy.getReloadingStrategy());
    523     }
    524
    525     /***
    526      * Helper method for comparing the content of two configuration objects.
    527      *
    528      * @param config1 the first configuration
    529      * @param config2 the second configuration
    530      */
    531     private void compare(Configuration config1, Configuration config2)
    532     {
    533         StrictConfigurationComparator cc = new StrictConfigurationComparator();
    534         assertTrue("Configurations are different", cc.compare(config1, config2));
    535     }
    536 }