    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  package org.apache.commons.configuration;
    18
    19  import java.awt.event.KeyEvent;
    20  import java.util.List;
    21
    22  import junit.framework.Assert;
    23
    24  import org.apache.commons.configuration.interpol.ConfigurationInterpolator;
    25  import org.apache.commons.lang.text.StrLookup;
    26
    27  /***
    28   * A helper class that defines a bunch of tests related to variable
    29   * interpolation. It can be used for running these tests on different
    30   * configuration implementations.
    31   *
    32   * @author Oliver Heger
    33   * @version $Id: InterpolationTestHelper.java 589136 2007-10-27 15:38:15Z oheger $
    34   */
    35  public class InterpolationTestHelper
    36  {
    37      /***
    38       * Tests basic interpolation facilities of the specified configuration.
    39       *
    40       * @param config the configuration to test
    41       */
    42      public static void testInterpolation(Configuration config)
    43      {
    44          config.setProperty("applicationRoot", "/home/applicationRoot");
    45          config.setProperty("db", "${applicationRoot}/db/hypersonic");
    46          String unInterpolatedValue = "${applicationRoot2}/db/hypersonic";
    47          config.setProperty("dbFailedInterpolate", unInterpolatedValue);
    48          String dbProp = "/home/applicationRoot/db/hypersonic";
    49
    50          Assert.assertEquals("Checking interpolated variable", dbProp, config
    51                  .getString("db"));
    52          Assert.assertEquals("lookup fails, leave variable as is", config
    53                  .getString("dbFailedInterpolate"), unInterpolatedValue);
    54
    55          config.setProperty("arrayInt", "${applicationRoot}/1");
    56          String[] arrayInt = config.getStringArray("arrayInt");
    57          Assert.assertEquals("check first entry was interpolated",
    58                  "/home/applicationRoot/1", arrayInt[0]);
    59
    60          config.addProperty("path", "/temp,C://Temp,/usr/local/tmp");
    61          config.setProperty("path.current", "${path}");
    62          Assert.assertEquals("Interpolation with multi-valued property",
    63                  "/temp", config.getString("path.current"));
    64      }
    65
    66      /***
    67       * Tests an interpolation over multiple levels (i.e. the replacement of a
    68       * variable is another variable and so on).
    69       *
    70       * @param config the configuration to test
    71       */
    72      public static void testMultipleInterpolation(Configuration config)
    73      {
    74          config.setProperty("test.base-level", "/base-level");
    75          config
    76                  .setProperty("test.first-level",
    77                          "${test.base-level}/first-level");
    78          config.setProperty("test.second-level",
    79                  "${test.first-level}/second-level");
    80          config.setProperty("test.third-level",
    81                  "${test.second-level}/third-level");
    82
    83          String expectedValue = "/base-level/first-level/second-level/third-level";
    84
    85          Assert
    86                  .assertEquals(config.getString("test.third-level"),
    87                          expectedValue);
    88      }
    89
    90      /***
    91       * Tests an invalid interpolation that results in an infinite loop. This
    92       * loop should be detected and an exception should be thrown.
    93       *
    94       * @param config the configuration to test
    95       */
    96      public static void testInterpolationLoop(Configuration config)
    97      {
    98          config.setProperty("test.a", "${test.b}");
    99          config.setProperty("test.b", "${test.a}");
    100
    101         try
    102         {
    103             config.getString("test.a");
    104             Assert
    105                     .fail("IllegalStateException should have been thrown for looped property references");
    106         }
    107         catch (IllegalStateException e)
    108         {
    109             // ok
    110         }
    111
    112     }
    113
    114     /***
    115      * Tests interpolation when a subset configuration is involved.
    116      *
    117      * @param config the configuration to test
    118      */
    119     public static void testInterpolationSubset(Configuration config)
    120     {
    121         config.addProperty("test.a", new Integer(42));
    122         config.addProperty("test.b", "${test.a}");
    123         Assert.assertEquals("Wrong interpolated value", 42, config
    124                 .getInt("test.b"));
    125         Configuration subset = config.subset("test");
    126         Assert.assertEquals("Wrong string property", "42", subset
    127                 .getString("b"));
    128         Assert.assertEquals("Wrong int property", 42, subset.getInt("b"));
    129     }
    130
    131     /***
    132      * Tests interpolation when the referred property is not found.
    133      *
    134      * @param config the configuration to test
    135      */
    136     public static void testInterpolationUnknownProperty(Configuration config)
    137     {
    138         config.addProperty("test.interpol", "${unknown.property}");
    139         Assert.assertEquals("Wrong interpolated unknown property",
    140                 "${unknown.property}", config.getString("test.interpol"));
    141     }
    142
    143     /***
    144      * Tests interpolation of system properties.
    145      *
    146      * @param config the configuration to test
    147      */
    148     public static void testInterpolationSystemProperties(Configuration config)
    149     {
    150         String[] sysProperties =
    151         { "java.version", "java.vendor", "os.name", "java.class.path" };
    152         for (int i = 0; i < sysProperties.length; i++)
    153         {
    154             config.addProperty("prop" + i, "${sys:" + sysProperties[i] + "}");
    155         }
    156
    157         for (int i = 0; i < sysProperties.length; i++)
    158         {
    159             Assert.assertEquals("Wrong value for system property "
    160                     + sysProperties[i], System.getProperty(sysProperties[i]),
    161                     config.getString("prop" + i));
    162         }
    163     }
    164
    165     /***
    166      * Tests interpolation of constant values.
    167      *
    168      * @param config the configuration to test
    169      */
    170     public static void testInterpolationConstants(Configuration config)
    171     {
    172         config.addProperty("key.code",
    173                 "${const:java.awt.event.KeyEvent.VK_CANCEL}");
    174         Assert.assertEquals("Wrong value of constant variable",
    175                 KeyEvent.VK_CANCEL, config.getInt("key.code"));
    176         Assert.assertEquals("Wrong value when fetching constant from cache",
    177                 KeyEvent.VK_CANCEL, config.getInt("key.code"));
    178     }
    179
    180     /***
    181      * Tests whether a variable can be escaped, so that it won't be
    182      * interpolated.
    183      *
    184      * @param config the configuration to test
    185      */
    186     public static void testInterpolationEscaped(Configuration config)
    187     {
    188         config.addProperty("var", "x");
    189         config.addProperty("escVar", "Use the variable $${${var}}.");
    190         Assert.assertEquals("Wrong escaped variable", "Use the variable ${x}.",
    191                 config.getString("escVar"));
    192     }
    193
    194     /***
    195      * Tests accessing and manipulating the interpolator object.
    196      *
    197      * @param config the configuration to test
    198      */
    199     public static void testGetInterpolator(AbstractConfiguration config)
    200     {
    201         config.addProperty("var", "${echo:testVar}");
    202         ConfigurationInterpolator interpol = config.getInterpolator();
    203         interpol.registerLookup("echo", new StrLookup()
    204         {
    205             public String lookup(String varName)
    206             {
    207                 return "Value of variable " + varName;
    208             }
    209         });
    210         Assert.assertEquals("Wrong value of echo variable",
    211                 "Value of variable testVar", config.getString("var"));
    212     }
    213
    214     /***
    215      * Tests obtaining a configuration with all variables replaced by their
    216      * actual values.
    217      *
    218      * @param config the configuration to test
    219      * @return the interpolated configuration
    220      */
    221     public static Configuration testInterpolatedConfiguration(
    222             AbstractConfiguration config)
    223     {
    224         config.setProperty("applicationRoot", "/home/applicationRoot");
    225         config.setProperty("db", "${applicationRoot}/db/hypersonic");
    226         config.setProperty("inttest.interpol", "${unknown.property}");
    227         config.setProperty("intkey.code",
    228                 "${const:java.awt.event.KeyEvent.VK_CANCEL}");
    229         config.setProperty("inttest.sysprop", "${sys:java.version}");
    230         config.setProperty("inttest.numvalue", "3//,1415");
    231         config.setProperty("inttest.value", "${inttest.numvalue}");
    232         config.setProperty("inttest.list", "${db}");
    233         config.addProperty("inttest.list", "${inttest.value}");
    234
    235         Configuration c = config.interpolatedConfiguration();
    236         Assert.assertEquals("Property not replaced",
    237                 "/home/applicationRoot/db/hypersonic", c.getProperty("db"));
    238         Assert.assertEquals("Const variable not replaced", KeyEvent.VK_CANCEL,
    239                 c.getInt("intkey.code"));
    240         Assert.assertEquals("Sys property not replaced", System
    241                 .getProperty("java.version"), c.getProperty("inttest.sysprop"));
    242         Assert.assertEquals("Delimiter value not replaced", "3,1415", c
    243                 .getProperty("inttest.value"));
    244         List lst = (List) c.getProperty("inttest.list");
    245         Assert.assertEquals("Wrong number of list elements", 2, lst.size());
    246         Assert.assertEquals("List element 0 not replaced",
    247                 "/home/applicationRoot/db/hypersonic", lst.get(0));
    248         Assert
    249                 .assertEquals("List element 1 not replaced", "3,1415", lst
    250                         .get(1));
    251         Assert.assertEquals("Unresolvable variable not found",
    252                 "${unknown.property}", c.getProperty("inttest.interpol"));
    253
    254         return c;
    255     }
    256 }