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
9
* http://www.apache.org/licenses/LICENSE-2.0
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.
17
package org.apache.commons.configuration;
19
import java.util.ArrayList;
20
import java.util.Arrays;
21
import java.util.Collection;
22
import java.util.HashMap;
23
import java.util.Iterator;
24
import java.util.List;
27
import junit.framework.TestCase;
29
import org.apache.commons.collections.CollectionUtils;
30
import org.apache.commons.configuration.event.ConfigurationEvent;
31
import org.apache.commons.configuration.event.ConfigurationListener;
34
* A test class for some of the basic functionality implemented by
35
* AbstractConfiguration.
37
* @version $Id: TestAbstractConfigurationBasicFeatures.java 1072120 2011-02-18 20:06:08Z oheger $
39
public class TestAbstractConfigurationBasicFeatures extends TestCase
41
/** Constant for the prefix of test keys.*/
42
private static final String KEY_PREFIX = "key";
44
/** Constant for the number of properties in tests for copy operations.*/
45
private static final int PROP_COUNT = 12;
48
* Tests the clear() implementation of AbstractConfiguration if the iterator
49
* returned by getKeys() does not support the remove() operation.
51
public void testClearIteratorNoRemove()
53
AbstractConfiguration config = new TestConfigurationImpl(
54
new BaseConfiguration())
56
// return an iterator that does not support remove operations
57
public Iterator getKeys()
59
Collection keyCol = new ArrayList();
60
CollectionUtils.addAll(keyCol, getUnderlyingConfiguration()
62
Object[] keys = keyCol.toArray();
63
return Arrays.asList(keys).iterator();
66
for (int i = 0; i < 20; i++)
68
config.addProperty("key" + i, "value" + i);
71
assertTrue("Configuration not empty", config.isEmpty());
75
* Tests escaping the variable marker, so that no interpolation will be
78
public void testInterpolateEscape()
80
AbstractConfiguration config = new TestConfigurationImpl(
81
new PropertiesConfiguration());
85
"$${DB2UNIVERSAL_JDBC_DRIVER_PATH}/db2jcc.jar\\,$${DB2UNIVERSAL_JDBC_DRIVER_PATH}/db2jcc_license_cu.jar");
87
"Wrong interpolated value",
88
"${DB2UNIVERSAL_JDBC_DRIVER_PATH}/db2jcc.jar,${DB2UNIVERSAL_JDBC_DRIVER_PATH}/db2jcc_license_cu.jar",
89
config.getString("mypath"));
93
* Tests adding list properties. The single elements of the list should be
96
public void testAddPropertyList()
98
checkAddListProperty(new TestConfigurationImpl(
99
new PropertiesConfiguration()));
103
* Tests adding list properties when delimiter parsing is disabled.
105
public void testAddPropertyListNoDelimiterParsing()
107
AbstractConfiguration config = new TestConfigurationImpl(
108
new PropertiesConfiguration());
109
config.setDelimiterParsingDisabled(true);
110
checkAddListProperty(config);
114
* Helper method for adding properties with multiple values.
116
* @param config the configuration to be used for testing
118
private void checkAddListProperty(AbstractConfiguration config)
120
config.addProperty("test", "value1");
121
Object[] lstValues1 = new Object[]
122
{ "value2", "value3" };
123
Object[] lstValues2 = new Object[]
124
{ "value4", "value5", "value6" };
125
config.addProperty("test", lstValues1);
126
config.addProperty("test", Arrays.asList(lstValues2));
127
List lst = config.getList("test");
128
assertEquals("Wrong number of list elements", 6, lst.size());
129
for (int i = 0; i < lst.size(); i++)
131
assertEquals("Wrong list element at " + i, "value" + (i + 1), lst
137
* Tests the copy() method.
139
public void testCopy()
141
AbstractConfiguration config = setUpDestConfig();
142
Configuration srcConfig = setUpSourceConfig();
143
config.copy(srcConfig);
144
for (int i = 0; i < PROP_COUNT; i++)
146
String key = KEY_PREFIX + i;
147
if (srcConfig.containsKey(key))
149
assertEquals("Value not replaced: " + key, srcConfig
150
.getProperty(key), config.getProperty(key));
154
assertEquals("Value modified: " + key, "value" + i, config
161
* Tests the copy() method when properties with multiple values and escaped
162
* list delimiters are involved.
164
public void testCopyWithLists()
166
Configuration srcConfig = setUpSourceConfig();
167
AbstractConfiguration config = setUpDestConfig();
168
config.copy(srcConfig);
169
checkListProperties(config);
173
* Tests the events generated by a copy() operation.
175
public void testCopyEvents()
177
AbstractConfiguration config = setUpDestConfig();
178
Configuration srcConfig = setUpSourceConfig();
179
CollectingConfigurationListener l = new CollectingConfigurationListener();
180
config.addConfigurationListener(l);
181
config.copy(srcConfig);
182
checkCopyEvents(l, srcConfig, AbstractConfiguration.EVENT_SET_PROPERTY);
186
* Tests copying a null configuration. This should be a noop.
188
public void testCopyNull()
190
AbstractConfiguration config = setUpDestConfig();
192
ConfigurationAssert.assertEquals(setUpDestConfig(), config);
196
* Tests the append() method.
198
public void testAppend()
200
AbstractConfiguration config = setUpDestConfig();
201
Configuration srcConfig = setUpSourceConfig();
202
config.append(srcConfig);
203
for (int i = 0; i < PROP_COUNT; i++)
205
String key = KEY_PREFIX + i;
206
if (srcConfig.containsKey(key))
208
List values = config.getList(key);
209
assertEquals("Value not added: " + key, 2, values.size());
210
assertEquals("Wrong value 1 for " + key, "value" + i, values
212
assertEquals("Wrong value 2 for " + key, "src" + i, values
217
assertEquals("Value modified: " + key, "value" + i, config
224
* Tests the append() method when properties with multiple values and
225
* escaped list delimiters are involved.
227
public void testAppendWithLists()
229
AbstractConfiguration config = setUpDestConfig();
230
config.append(setUpSourceConfig());
231
checkListProperties(config);
235
* Tests the events generated by an append() operation.
237
public void testAppendEvents()
239
AbstractConfiguration config = setUpDestConfig();
240
Configuration srcConfig = setUpSourceConfig();
241
CollectingConfigurationListener l = new CollectingConfigurationListener();
242
config.addConfigurationListener(l);
243
config.append(srcConfig);
244
checkCopyEvents(l, srcConfig, AbstractConfiguration.EVENT_ADD_PROPERTY);
248
* Tests appending a null configuration. This should be a noop.
250
public void testAppendNull()
252
AbstractConfiguration config = setUpDestConfig();
254
ConfigurationAssert.assertEquals(setUpDestConfig(), config);
258
* Tests whether environment variables can be interpolated.
260
public void testInterpolateEnvironmentVariables()
262
AbstractConfiguration config = new TestConfigurationImpl(
263
new PropertiesConfiguration());
264
EnvironmentConfiguration envConfig = new EnvironmentConfiguration();
265
Map env = new HashMap();
266
for (Iterator it = envConfig.getKeys(); it.hasNext();)
268
String key = (String) it.next();
269
String propKey = "envtest." + key;
270
env.put(propKey, envConfig.getProperty(key));
271
config.addProperty(propKey, "${env:" + key + "}");
273
assertFalse("No environment properties", env.isEmpty());
274
for (Iterator it = env.entrySet().iterator(); it.hasNext();)
276
Map.Entry e = (Map.Entry) it.next();
277
assertEquals("Wrong value for " + e.getKey(), e.getValue(), config
278
.getString((String) e.getKey()));
283
* Tests getList() for single non-string values.
285
public void testGetListNonString()
287
checkGetListScalar(new Integer(42));
288
checkGetListScalar(new Long(42));
289
checkGetListScalar(new Short((short) 42));
290
checkGetListScalar(new Byte((byte) 42));
291
checkGetListScalar(new Float(42));
292
checkGetListScalar(new Double(42));
293
checkGetListScalar(Boolean.TRUE);
297
* Tests getStringArray() for single son-string values.
299
public void testGetStringArrayNonString()
301
checkGetStringArrayScalar(new Integer(42));
302
checkGetStringArrayScalar(new Long(42));
303
checkGetStringArrayScalar(new Short((short) 42));
304
checkGetStringArrayScalar(new Byte((byte) 42));
305
checkGetStringArrayScalar(new Float(42));
306
checkGetStringArrayScalar(new Double(42));
307
checkGetStringArrayScalar(Boolean.TRUE);
311
* Helper method for checking getList() if the property value is a scalar.
312
* @param value the value of the property
314
private void checkGetListScalar(Object value)
316
BaseConfiguration config = new BaseConfiguration();
317
config.addProperty(KEY_PREFIX, value);
318
List lst = config.getList(KEY_PREFIX);
319
assertEquals("Wrong number of values", 1, lst.size());
320
assertEquals("Wrong value", value.toString(), lst.get(0));
324
* Helper method for checking getStringArray() if the property value is a
327
* @param value the value of the property
329
private void checkGetStringArrayScalar(Object value)
331
BaseConfiguration config = new BaseConfiguration();
332
config.addProperty(KEY_PREFIX, value);
333
String[] array = config.getStringArray(KEY_PREFIX);
334
assertEquals("Weong number of elements", 1, array.length);
335
assertEquals("Wrong value", value.toString(), array[0]);
339
* Tests whether interpolation works in variable names.
341
public void testNestedVariableInterpolation()
343
BaseConfiguration config = new BaseConfiguration();
344
config.getSubstitutor().setEnableSubstitutionInVariables(true);
345
config.addProperty("java.version", "1.4");
346
config.addProperty("jre-1.4", "C:\\java\\1.4");
347
config.addProperty("jre.path", "${jre-${java.version}}");
348
assertEquals("Wrong path", "C:\\java\\1.4",
349
config.getString("jre.path"));
353
* Creates the source configuration for testing the copy() and append()
354
* methods. This configuration contains keys with an odd index and values
355
* starting with the prefix "src". There are also some list properties.
357
* @return the source configuration for copy operations
359
private Configuration setUpSourceConfig()
361
BaseConfiguration config = new BaseConfiguration();
362
for (int i = 1; i < PROP_COUNT; i += 2)
364
config.addProperty(KEY_PREFIX + i, "src" + i);
366
config.addProperty("list1", "1,2,3");
367
config.addProperty("list2", "3\\,1415,9\\,81");
372
* Creates the destination configuration for testing the copy() and append()
373
* methods. This configuration contains keys with a running index and
374
* corresponding values starting with the prefix "value".
376
* @return the destination configuration for copy operations
378
private AbstractConfiguration setUpDestConfig()
380
AbstractConfiguration config = new TestConfigurationImpl(
381
new PropertiesConfiguration());
382
for (int i = 0; i < PROP_COUNT; i++)
384
config.addProperty(KEY_PREFIX + i, "value" + i);
390
* Tests the values of list properties after a copy operation.
392
* @param config the configuration to test
394
private void checkListProperties(Configuration config)
396
List values = config.getList("list1");
397
assertEquals("Wrong number of elements in list 1", 3, values.size());
398
values = config.getList("list2");
399
assertEquals("Wrong number of elements in list 2", 2, values.size());
400
assertEquals("Wrong value 1", "3,1415", values.get(0));
401
assertEquals("Wrong value 2", "9,81", values.get(1));
405
* Tests whether the correct events are received for a copy operation.
407
* @param l the event listener
408
* @param src the configuration that was copied
409
* @param eventType the expected event type
411
private void checkCopyEvents(CollectingConfigurationListener l,
412
Configuration src, int eventType)
414
Map events = new HashMap();
415
for (Iterator it = l.events.iterator(); it.hasNext();)
417
ConfigurationEvent e = (ConfigurationEvent) it.next();
418
assertEquals("Wrong event type", eventType, e.getType());
419
assertTrue("Unknown property: " + e.getPropertyName(), src
420
.containsKey(e.getPropertyName()));
421
assertEquals("Wrong property value for " + e.getPropertyName(), e
422
.getPropertyValue(), src.getProperty(e.getPropertyName()));
423
if (!e.isBeforeUpdate())
425
assertTrue("After event without before event", events
426
.containsKey(e.getPropertyName()));
430
events.put(e.getPropertyName(), e);
434
for (Iterator it = src.getKeys(); it.hasNext();)
436
String key = (String) it.next();
437
assertTrue("No event received for key " + key, events
443
* A test configuration implementation. This implementation inherits
444
* directly from AbstractConfiguration. For implementing the required
445
* functionality another implementation of AbstractConfiguration is used;
446
* all methods that need to be implemented delegate to this wrapped
449
static class TestConfigurationImpl extends AbstractConfiguration
451
/** Stores the underlying configuration. */
452
private AbstractConfiguration config;
454
public AbstractConfiguration getUnderlyingConfiguration()
459
public TestConfigurationImpl(AbstractConfiguration wrappedConfig)
461
config = wrappedConfig;
464
protected void addPropertyDirect(String key, Object value)
466
config.addPropertyDirect(key, value);
469
public boolean containsKey(String key)
471
return config.containsKey(key);
474
public Iterator getKeys()
476
return config.getKeys();
479
public Object getProperty(String key)
481
return config.getProperty(key);
484
public boolean isEmpty()
486
return config.isEmpty();
489
protected void clearPropertyDirect(String key)
491
config.clearPropertyDirect(key);
496
* An event listener implementation that simply collects all received
497
* configuration events.
499
static class CollectingConfigurationListener implements
500
ConfigurationListener
502
List events = new ArrayList();
504
public void configurationChanged(ConfigurationEvent event)