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 }