001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 package org.apache.commons.configuration; 018 019 import static org.junit.Assert.assertEquals; 020 import static org.junit.Assert.fail; 021 022 import java.awt.event.KeyEvent; 023 import java.util.List; 024 025 import org.apache.commons.configuration.interpol.ConfigurationInterpolator; 026 import org.apache.commons.lang.text.StrLookup; 027 028 /** 029 * A helper class that defines a bunch of tests related to variable 030 * interpolation. It can be used for running these tests on different 031 * configuration implementations. 032 * 033 * @author <a 034 * href="http://commons.apache.org/configuration/team-list.html">Commons 035 * Configuration team</a> 036 * @version $Id: InterpolationTestHelper.java 1222452 2011-12-22 21:06:17Z oheger $ 037 */ 038 public class InterpolationTestHelper 039 { 040 /** 041 * Tests basic interpolation facilities of the specified configuration. 042 * 043 * @param config the configuration to test 044 */ 045 public static void testInterpolation(Configuration config) 046 { 047 config.setProperty("applicationRoot", "/home/applicationRoot"); 048 config.setProperty("db", "${applicationRoot}/db/hypersonic"); 049 String unInterpolatedValue = "${applicationRoot2}/db/hypersonic"; 050 config.setProperty("dbFailedInterpolate", unInterpolatedValue); 051 String dbProp = "/home/applicationRoot/db/hypersonic"; 052 053 assertEquals("Checking interpolated variable", dbProp, config 054 .getString("db")); 055 assertEquals("lookup fails, leave variable as is", config 056 .getString("dbFailedInterpolate"), unInterpolatedValue); 057 058 config.setProperty("arrayInt", "${applicationRoot}/1"); 059 String[] arrayInt = config.getStringArray("arrayInt"); 060 assertEquals("check first entry was interpolated", 061 "/home/applicationRoot/1", arrayInt[0]); 062 063 config.addProperty("path", "/temp,C:\\Temp,/usr/local/tmp"); 064 config.setProperty("path.current", "${path}"); 065 assertEquals("Interpolation with multi-valued property", 066 "/temp", config.getString("path.current")); 067 } 068 069 /** 070 * Tests an interpolation over multiple levels (i.e. the replacement of a 071 * variable is another variable and so on). 072 * 073 * @param config the configuration to test 074 */ 075 public static void testMultipleInterpolation(Configuration config) 076 { 077 config.setProperty("test.base-level", "/base-level"); 078 config 079 .setProperty("test.first-level", 080 "${test.base-level}/first-level"); 081 config.setProperty("test.second-level", 082 "${test.first-level}/second-level"); 083 config.setProperty("test.third-level", 084 "${test.second-level}/third-level"); 085 086 String expectedValue = "/base-level/first-level/second-level/third-level"; 087 088 assertEquals(config.getString("test.third-level"), 089 expectedValue); 090 } 091 092 /** 093 * Tests an invalid interpolation that results in an infinite loop. This 094 * loop should be detected and an exception should be thrown. 095 * 096 * @param config the configuration to test 097 */ 098 public static void testInterpolationLoop(Configuration config) 099 { 100 config.setProperty("test.a", "${test.b}"); 101 config.setProperty("test.b", "${test.a}"); 102 103 try 104 { 105 config.getString("test.a"); 106 fail("IllegalStateException should have been thrown for looped property references"); 107 } 108 catch (IllegalStateException e) 109 { 110 // ok 111 } 112 113 } 114 115 /** 116 * Tests interpolation when a subset configuration is involved. 117 * 118 * @param config the configuration to test 119 */ 120 public static void testInterpolationSubset(Configuration config) 121 { 122 config.addProperty("test.a", new Integer(42)); 123 config.addProperty("test.b", "${test.a}"); 124 assertEquals("Wrong interpolated value", 42, config 125 .getInt("test.b")); 126 Configuration subset = config.subset("test"); 127 assertEquals("Wrong string property", "42", subset 128 .getString("b")); 129 assertEquals("Wrong int property", 42, subset.getInt("b")); 130 } 131 132 /** 133 * Tests interpolation when the referred property is not found. 134 * 135 * @param config the configuration to test 136 */ 137 public static void testInterpolationUnknownProperty(Configuration config) 138 { 139 config.addProperty("test.interpol", "${unknown.property}"); 140 assertEquals("Wrong interpolated unknown property", 141 "${unknown.property}", config.getString("test.interpol")); 142 } 143 144 /** 145 * Tests interpolation of system properties. 146 * 147 * @param config the configuration to test 148 */ 149 public static void testInterpolationSystemProperties(Configuration config) 150 { 151 String[] sysProperties = 152 { "java.version", "java.vendor", "os.name", "java.class.path" }; 153 for (int i = 0; i < sysProperties.length; i++) 154 { 155 config.addProperty("prop" + i, "${sys:" + sysProperties[i] + "}"); 156 } 157 158 for (int i = 0; i < sysProperties.length; i++) 159 { 160 assertEquals("Wrong value for system property " 161 + sysProperties[i], System.getProperty(sysProperties[i]), 162 config.getString("prop" + i)); 163 } 164 } 165 166 /** 167 * Tests interpolation of constant values. 168 * 169 * @param config the configuration to test 170 */ 171 public static void testInterpolationConstants(Configuration config) 172 { 173 config.addProperty("key.code", 174 "${const:java.awt.event.KeyEvent.VK_CANCEL}"); 175 assertEquals("Wrong value of constant variable", 176 KeyEvent.VK_CANCEL, config.getInt("key.code")); 177 assertEquals("Wrong value when fetching constant from cache", 178 KeyEvent.VK_CANCEL, config.getInt("key.code")); 179 } 180 181 /** 182 * Tests whether a variable can be escaped, so that it won't be 183 * interpolated. 184 * 185 * @param config the configuration to test 186 */ 187 public static void testInterpolationEscaped(Configuration config) 188 { 189 config.addProperty("var", "x"); 190 config.addProperty("escVar", "Use the variable $${${var}}."); 191 assertEquals("Wrong escaped variable", "Use the variable ${x}.", 192 config.getString("escVar")); 193 } 194 195 /** 196 * Tests accessing and manipulating the interpolator object. 197 * 198 * @param config the configuration to test 199 */ 200 public static void testGetInterpolator(AbstractConfiguration config) 201 { 202 config.addProperty("var", "${echo:testVar}"); 203 ConfigurationInterpolator interpol = config.getInterpolator(); 204 interpol.registerLookup("echo", new StrLookup() 205 { 206 @Override 207 public String lookup(String varName) 208 { 209 return "Value of variable " + varName; 210 } 211 }); 212 assertEquals("Wrong value of echo variable", 213 "Value of variable testVar", config.getString("var")); 214 } 215 216 /** 217 * Tests obtaining a configuration with all variables replaced by their 218 * actual values. 219 * 220 * @param config the configuration to test 221 * @return the interpolated configuration 222 */ 223 public static Configuration testInterpolatedConfiguration( 224 AbstractConfiguration config) 225 { 226 config.setProperty("applicationRoot", "/home/applicationRoot"); 227 config.setProperty("db", "${applicationRoot}/db/hypersonic"); 228 config.setProperty("inttest.interpol", "${unknown.property}"); 229 config.setProperty("intkey.code", 230 "${const:java.awt.event.KeyEvent.VK_CANCEL}"); 231 config.setProperty("inttest.sysprop", "${sys:java.version}"); 232 config.setProperty("inttest.numvalue", "3\\,1415"); 233 config.setProperty("inttest.value", "${inttest.numvalue}"); 234 config.setProperty("inttest.list", "${db}"); 235 config.addProperty("inttest.list", "${inttest.value}"); 236 237 Configuration c = config.interpolatedConfiguration(); 238 assertEquals("Property not replaced", 239 "/home/applicationRoot/db/hypersonic", c.getProperty("db")); 240 assertEquals("Const variable not replaced", KeyEvent.VK_CANCEL, 241 c.getInt("intkey.code")); 242 assertEquals("Sys property not replaced", System 243 .getProperty("java.version"), c.getProperty("inttest.sysprop")); 244 assertEquals("Delimiter value not replaced", "3,1415", c 245 .getProperty("inttest.value")); 246 List<?> lst = (List<?>) c.getProperty("inttest.list"); 247 assertEquals("Wrong number of list elements", 2, lst.size()); 248 assertEquals("List element 0 not replaced", 249 "/home/applicationRoot/db/hypersonic", lst.get(0)); 250 assertEquals("List element 1 not replaced", "3,1415", lst 251 .get(1)); 252 assertEquals("Unresolvable variable not found", 253 "${unknown.property}", c.getProperty("inttest.interpol")); 254 255 return c; 256 } 257 }