    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.net.URL;
    22  import java.util.ArrayList;
    23  import java.util.Iterator;
    24  import java.util.List;
    25
    26  import junit.framework.TestCase;
    27  import junitx.framework.ListAssert;
    28
    29  import org.apache.commons.configuration.tree.DefaultExpressionEngine;
    30  import org.apache.commons.configuration.tree.ExpressionEngine;
    31
    32  import com.mockobjects.dynamic.Mock;
    33
    34  /***
    35   * Tests the ConfigurationUtils class
    36   *
    37   * @version $Revision: 710159 $, $Date: 2008-11-03 22:07:27 +0100 (Mo, 03 Nov 2008) $
    38   */
    39  public class TestConfigurationUtils extends TestCase
    40  {
    41      protected Configuration config = new BaseConfiguration();
    42
    43      public void testToString()
    44      {
    45          String lineSeparator = System.getProperty("line.separator");
    46
    47          assertEquals("String representation of an empty configuration", "", ConfigurationUtils.toString(config));
    48
    49          config.setProperty("one", "1");
    50          assertEquals("String representation of a configuration", "one=1", ConfigurationUtils.toString(config));
    51
    52          config.setProperty("two", "2");
    53          assertEquals("String representation of a configuration", "one=1" + lineSeparator + "two=2" , ConfigurationUtils.toString(config));
    54
    55          config.clearProperty("one");
    56          assertEquals("String representation of a configuration", "two=2" , ConfigurationUtils.toString(config));
    57
    58          config.setProperty("one","1");
    59          assertEquals("String representation of a configuration", "two=2" + lineSeparator + "one=1" , ConfigurationUtils.toString(config));
    60      }
    61
    62      public void testGetURL() throws Exception
    63      {
    64          assertEquals(
    65              "http://localhost:8080/webapp/config/config.xml",
    66              ConfigurationUtils
    67                  .getURL(
    68                      "http://localhost:8080/webapp/config/baseConfig.xml",
    69                      "config.xml")
    70                  .toString());
    71          assertEquals(
    72              "http://localhost:8080/webapp/config/config.xml",
    73              ConfigurationUtils
    74                  .getURL(
    75                      "http://localhost:8080/webapp/baseConfig.xml",
    76                      "config/config.xml")
    77                  .toString());
    78          URL url = ConfigurationUtils.getURL(null, "config.xml");
    79          assertEquals("file", url.getProtocol());
    80          assertEquals("", url.getHost());
    81
    82          assertEquals(
    83              "http://localhost:8080/webapp/config/config.xml",
    84              ConfigurationUtils
    85                  .getURL(
    86                      "ftp://ftp.server.com/downloads/baseConfig.xml",
    87                      "http://localhost:8080/webapp/config/config.xml")
    88                  .toString());
    89          assertEquals(
    90              "http://localhost:8080/webapp/config/config.xml",
    91              ConfigurationUtils
    92                  .getURL(null, "http://localhost:8080/webapp/config/config.xml")
    93                  .toString());
    94          File absFile = new File("config.xml").getAbsoluteFile();
    95          assertEquals(
    96              absFile.toURL(),
    97              ConfigurationUtils.getURL(
    98                  "http://localhost:8080/webapp/config/baseConfig.xml",
    99                  absFile.getAbsolutePath()));
    100         assertEquals(
    101             absFile.toURL(),
    102             ConfigurationUtils.getURL(null, absFile.getAbsolutePath()));
    103
    104 		assertEquals(absFile.toURL(),
    105 		ConfigurationUtils.getURL(absFile.getParent(), "config.xml"));
    106     }
    107
    108     public void testGetBasePath() throws Exception
    109     {
    110         URL url = new URL("http://xyz.net/foo/bar.xml");
    111         assertEquals("base path of " + url, "http://xyz.net/foo/", ConfigurationUtils.getBasePath(url));
    112
    113         url = new URL("http://xyz.net/foo/");
    114         assertEquals("base path of " + url, "http://xyz.net/foo/", ConfigurationUtils.getBasePath(url));
    115
    116         url = new URL("http://xyz.net/foo");
    117         assertEquals("base path of " + url, "http://xyz.net/", ConfigurationUtils.getBasePath(url));
    118
    119         url = new URL("http://xyz.net/");
    120         assertEquals("base path of " + url, "http://xyz.net/", ConfigurationUtils.getBasePath(url));
    121
    122         url = new URL("http://xyz.net");
    123         assertEquals("base path of " + url, "http://xyz.net", ConfigurationUtils.getBasePath(url));
    124     }
    125
    126     public void testGetFileName() throws Exception
    127     {
    128         assertEquals("file name for a null URL", null, ConfigurationUtils.getFileName(null));
    129
    130         URL url = new URL("http://xyz.net/foo/");
    131         assertEquals("file for a directory URL " + url, null, ConfigurationUtils.getFileName(url));
    132
    133         url = new URL("http://xyz.net/foo/bar.xml");
    134         assertEquals("file name for a valid URL " + url, "bar.xml", ConfigurationUtils.getFileName(url));
    135     }
    136
    137     public void testCopy()
    138     {
    139         // create the source configuration
    140         Configuration conf1 = new BaseConfiguration();
    141         conf1.addProperty("key1", "value1");
    142         conf1.addProperty("key2", "value2");
    143
    144         // create the target configuration
    145         Configuration conf2 = new BaseConfiguration();
    146         conf2.addProperty("key1", "value3");
    147         conf2.addProperty("key2", "value4");
    148
    149         // copy the source configuration into the target configuration
    150         ConfigurationUtils.copy(conf1, conf2);
    151
    152         assertEquals("'key1' property", "value1", conf2.getProperty("key1"));
    153         assertEquals("'key2' property", "value2", conf2.getProperty("key2"));
    154     }
    155
    156     public void testAppend()
    157     {
    158         // create the source configuration
    159         Configuration conf1 = new BaseConfiguration();
    160         conf1.addProperty("key1", "value1");
    161         conf1.addProperty("key2", "value2");
    162
    163         // create the target configuration
    164         Configuration conf2 = new BaseConfiguration();
    165         conf2.addProperty("key1", "value3");
    166         conf2.addProperty("key2", "value4");
    167
    168         // append the source configuration to the target configuration
    169         ConfigurationUtils.append(conf1, conf2);
    170
    171         List expected = new ArrayList();
    172         expected.add("value3");
    173         expected.add("value1");
    174         ListAssert.assertEquals("'key1' property", expected, conf2.getList("key1"));
    175
    176         expected = new ArrayList();
    177         expected.add("value4");
    178         expected.add("value2");
    179         ListAssert.assertEquals("'key2' property", expected, conf2.getList("key2"));
    180     }
    181
    182     public void testGetFile() throws Exception
    183     {
    184         File directory = new File("target");
    185         File reference = new File(directory, "test.txt").getAbsoluteFile();
    186
    187         assertEquals(reference, ConfigurationUtils.getFile(null, reference.getAbsolutePath()));
    188         assertEquals(reference, ConfigurationUtils.getFile(directory.getAbsolutePath(), reference.getAbsolutePath()));
    189         assertEquals(reference, ConfigurationUtils.getFile(directory.getAbsolutePath(), reference.getName()));
    190         assertEquals(reference, ConfigurationUtils.getFile(directory.toURL().toString(), reference.getName()));
    191         assertEquals(reference, ConfigurationUtils.getFile("invalid", reference.toURL().toString()));
    192         assertEquals(reference, ConfigurationUtils.getFile(
    193                 "jar:file:/C:/myjar.jar!/my-config.xml/someprops.properties",
    194                 reference.getAbsolutePath()));
    195     }
    196
    197     public void testLocateWithNullTCCL() throws Exception
    198     {
    199         ClassLoader cl = Thread.currentThread().getContextClassLoader();
    200         try
    201         {
    202             Thread.currentThread().setContextClassLoader(null);
    203             assertNull(ConfigurationUtils.locate("abase", "aname"));
    204             // This assert fails when maven 2 is used, so commented out
    205             //assertNotNull(ConfigurationUtils.locate("test.xml"));
    206         }
    207         finally
    208         {
    209             Thread.currentThread().setContextClassLoader(cl);
    210         }
    211     }
    212
    213     /***
    214      * Tests converting a configuration into a hierarchical one.
    215      */
    216     public void testConvertToHierarchical()
    217     {
    218         Configuration conf = new BaseConfiguration();
    219         for (int i = 0; i < 10; i++)
    220         {
    221             conf.addProperty("test" + i, "value" + i);
    222             conf.addProperty("test.list", "item" + i);
    223         }
    224
    225         HierarchicalConfiguration hc = ConfigurationUtils
    226                 .convertToHierarchical(conf);
    227         for (Iterator it = conf.getKeys(); it.hasNext();)
    228         {
    229             String key = (String) it.next();
    230             assertEquals("Wrong value for key " + key, conf.getProperty(key),
    231                     hc.getProperty(key));
    232         }
    233     }
    234
    235     /***
    236      * Tests converting a configuration into a hierarchical one that is already
    237      * hierarchical.
    238      */
    239     public void testConvertHierarchicalToHierarchical()
    240     {
    241         Configuration conf = new HierarchicalConfiguration();
    242         conf.addProperty("test", "yes");
    243         assertSame("Wrong configuration returned", conf, ConfigurationUtils
    244                 .convertToHierarchical(conf));
    245     }
    246
    247     /***
    248      * Tests converting a null configuration to a hierarchical one. The result
    249      * should be null, too.
    250      */
    251     public void testConvertNullToHierarchical()
    252     {
    253         assertNull("Wrong conversion result for null config",
    254                 ConfigurationUtils.convertToHierarchical(null));
    255     }
    256
    257     /***
    258      * Tests converting a configuration into a hierarchical one if some of its
    259      * properties contain escaped list delimiter characters.
    260      */
    261     public void testConvertToHierarchicalDelimiters()
    262     {
    263         Configuration conf = new BaseConfiguration();
    264         conf.addProperty("test.key", "1//,2//,3");
    265         assertEquals("Wrong property value", "1,2,3", conf
    266                 .getString("test.key"));
    267         HierarchicalConfiguration hc = ConfigurationUtils
    268                 .convertToHierarchical(conf);
    269         assertEquals("Escaped list delimiters not correctly handled", "1,2,3",
    270                 hc.getString("test.key"));
    271     }
    272
    273     /***
    274      * Tests converting a configuration to a hierarchical one using a specific
    275      * expression engine.
    276      */
    277     public void testConvertToHierarchicalEngine()
    278     {
    279         Configuration conf = new BaseConfiguration();
    280         conf.addProperty("test(a)", Boolean.TRUE);
    281         conf.addProperty("test(b)", Boolean.FALSE);
    282         DefaultExpressionEngine engine = new DefaultExpressionEngine();
    283         engine.setIndexStart("[");
    284         engine.setIndexEnd("]");
    285         HierarchicalConfiguration hc = ConfigurationUtils
    286                 .convertToHierarchical(conf, engine);
    287         assertTrue("Wrong value for test(a)", hc.getBoolean("test(a)"));
    288         assertFalse("Wrong value for test(b)", hc.getBoolean("test(b)"));
    289     }
    290
    291     /***
    292      * Tests converting an already hierarchical configuration using an
    293      * expression engine. The new engine should be set.
    294      */
    295     public void testConvertHierarchicalToHierarchicalEngine()
    296     {
    297         HierarchicalConfiguration hc = new HierarchicalConfiguration();
    298         ExpressionEngine engine = new DefaultExpressionEngine();
    299         assertSame("Created new configuration", hc, ConfigurationUtils
    300                 .convertToHierarchical(hc, engine));
    301         assertSame("Engine was not set", engine, hc.getExpressionEngine());
    302     }
    303
    304     /***
    305      * Tests converting an already hierarchical configuration using a null
    306      * expression engine. In this case the expression engine of the
    307      * configuration should not be touched.
    308      */
    309     public void testConvertHierarchicalToHierarchicalNullEngine()
    310     {
    311         HierarchicalConfiguration hc = new HierarchicalConfiguration();
    312         ExpressionEngine engine = new DefaultExpressionEngine();
    313         hc.setExpressionEngine(engine);
    314         assertSame("Created new configuration", hc, ConfigurationUtils
    315                 .convertToHierarchical(hc, null));
    316         assertSame("Expression engine was changed", engine, hc
    317                 .getExpressionEngine());
    318     }
    319
    320     /***
    321      * Tests converting a configuration to a hierarchical one that contains a
    322      * property with multiple values. This test is related to CONFIGURATION-346.
    323      */
    324     public void testConvertToHierarchicalMultiValues()
    325     {
    326         BaseConfiguration config = new BaseConfiguration();
    327         config.addProperty("test", "1,2,3");
    328         HierarchicalConfiguration hc = ConfigurationUtils
    329                 .convertToHierarchical(config);
    330         assertEquals("Wrong value 1", 1, hc.getInt("test(0)"));
    331         assertEquals("Wrong value 2", 2, hc.getInt("test(1)"));
    332         assertEquals("Wrong value 3", 3, hc.getInt("test(2)"));
    333     }
    334
    335     /***
    336      * Tests cloning a configuration that supports this operation.
    337      */
    338     public void testCloneConfiguration()
    339     {
    340         HierarchicalConfiguration conf = new HierarchicalConfiguration();
    341         conf.addProperty("test", "yes");
    342         HierarchicalConfiguration copy = (HierarchicalConfiguration) ConfigurationUtils
    343                 .cloneConfiguration(conf);
    344         assertNotSame("Same object was returned", conf, copy);
    345         assertEquals("Property was not cloned", "yes", copy.getString("test"));
    346     }
    347
    348     /***
    349      * Tests cloning a configuration that does not support this operation. This
    350      * should cause an exception.
    351      */
    352     public void testCloneConfigurationNotSupported()
    353     {
    354         Configuration myNonCloneableConfig = new NonCloneableConfiguration();
    355         try
    356         {
    357             ConfigurationUtils.cloneConfiguration(myNonCloneableConfig);
    358             fail("Could clone non cloneable config!");
    359         }
    360         catch (ConfigurationRuntimeException crex)
    361         {
    362             // ok
    363         }
    364     }
    365
    366     /***
    367      * Tests cloning a <b>null</b> configuration.
    368      */
    369     public void testCloneConfigurationNull()
    370     {
    371         assertNull("Wrong return value", ConfigurationUtils
    372                 .cloneConfiguration(null));
    373     }
    374
    375     /***
    376      * Tests whether runtime exceptions can be enabled.
    377      */
    378     public void testEnableRuntimeExceptions()
    379     {
    380         PropertiesConfiguration config = new PropertiesConfiguration()
    381         {
    382             protected void addPropertyDirect(String key, Object value)
    383             {
    384                 // always simulate an exception
    385                 fireError(EVENT_ADD_PROPERTY, key, value, new RuntimeException(
    386                         "A faked exception!"));
    387             }
    388         };
    389         config.clearErrorListeners();
    390         ConfigurationUtils.enableRuntimeExceptions(config);
    391         try
    392         {
    393             config.addProperty("test", "testValue");
    394             fail("No runtime exception was thrown!");
    395         }
    396         catch (ConfigurationRuntimeException crex)
    397         {
    398             // ok
    399         }
    400     }
    401
    402     /***
    403      * Tries to enable runtime exceptions for a configurtion that does not
    404      * inherit from EventSource. This should cause an exception.
    405      */
    406     public void testEnableRuntimeExceptionsInvalid()
    407     {
    408         try
    409         {
    410             ConfigurationUtils
    411                     .enableRuntimeExceptions((Configuration) new Mock(
    412                             Configuration.class).proxy());
    413             fail("Could enable exceptions for non EventSource configuration!");
    414         }
    415         catch (IllegalArgumentException iex)
    416         {
    417             // ok
    418         }
    419     }
    420
    421     /***
    422      * Tries to enable runtime exceptions for a null configuration. This should
    423      * cause an exception.
    424      */
    425     public void testEnableRuntimeExceptionsNull()
    426     {
    427         try
    428         {
    429             ConfigurationUtils.enableRuntimeExceptions(null);
    430             fail("Could enable exceptions for a null configuration!");
    431         }
    432         catch (IllegalArgumentException iex)
    433         {
    434             //ok
    435         }
    436     }
    437 }