View Javadoc
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.configuration2;
19  
20  import static org.junit.jupiter.api.Assertions.assertArrayEquals;
21  import static org.junit.jupiter.api.Assertions.assertEquals;
22  import static org.junit.jupiter.api.Assertions.assertFalse;
23  import static org.junit.jupiter.api.Assertions.assertNotNull;
24  import static org.junit.jupiter.api.Assertions.assertNull;
25  import static org.junit.jupiter.api.Assertions.assertTrue;
26  
27  import java.io.File;
28  import java.util.ArrayList;
29  import java.util.Arrays;
30  import java.util.Iterator;
31  import java.util.List;
32  
33  import org.apache.commons.configuration2.convert.LegacyListDelimiterHandler;
34  import org.apache.commons.configuration2.convert.ListDelimiterHandler;
35  import org.apache.commons.configuration2.io.FileHandler;
36  import org.apache.commons.io.FileUtils;
37  import org.junit.jupiter.api.BeforeEach;
38  import org.junit.jupiter.api.Test;
39  
40  /**
41   * Test loading multiple configurations.
42   */
43  public class TestNullCompositeConfiguration {
44      protected PropertiesConfiguration conf1;
45      protected PropertiesConfiguration conf2;
46      protected XMLConfiguration xmlConf;
47      protected CompositeConfiguration cc;
48  
49      /** The File that we test with */
50      private final String testProperties = ConfigurationAssert.getTestFile("test.properties").getAbsolutePath();
51      private final String testProperties2 = ConfigurationAssert.getTestFile("test2.properties").getAbsolutePath();
52      private final String testPropertiesXML = ConfigurationAssert.getTestFile("test.xml").getAbsolutePath();
53  
54      @BeforeEach
55      public void setUp() throws Exception {
56          cc = new CompositeConfiguration();
57          final ListDelimiterHandler listHandler = new LegacyListDelimiterHandler(',');
58          conf1 = new PropertiesConfiguration();
59          conf1.setListDelimiterHandler(listHandler);
60          final FileHandler handler1 = new FileHandler(conf1);
61          handler1.setFileName(testProperties);
62          handler1.load();
63          conf2 = new PropertiesConfiguration();
64          conf2.setListDelimiterHandler(listHandler);
65          final FileHandler handler2 = new FileHandler(conf2);
66          handler2.setFileName(testProperties2);
67          handler2.load();
68          xmlConf = new XMLConfiguration();
69          final FileHandler handler3 = new FileHandler(xmlConf);
70          handler3.load(new File(testPropertiesXML));
71  
72          cc.setThrowExceptionOnMissing(false);
73      }
74  
75      /**
76       * Tests adding values. Make sure they _DON'T_ override any other properties but add to the existing properties and keep
77       * sequence
78       */
79      @Test
80      public void testAddingProperty() throws Exception {
81          cc.addConfiguration(conf1);
82          cc.addConfiguration(xmlConf);
83  
84          String[] values = cc.getStringArray("test.short");
85  
86          assertArrayEquals(new String[] {"1"}, values);
87  
88          cc.addProperty("test.short", "88");
89  
90          values = cc.getStringArray("test.short");
91  
92          assertArrayEquals(new String[] {"1", "88"}, values);
93      }
94  
95      @Test
96      public void testAddRemoveConfigurations() throws Exception {
97          cc.addConfiguration(conf1);
98          assertEquals(2, cc.getNumberOfConfigurations());
99          cc.addConfiguration(conf1);
100         assertEquals(2, cc.getNumberOfConfigurations());
101         cc.addConfiguration(conf2);
102         assertEquals(3, cc.getNumberOfConfigurations());
103         cc.removeConfiguration(conf1);
104         assertEquals(2, cc.getNumberOfConfigurations());
105         cc.clear();
106         assertEquals(1, cc.getNumberOfConfigurations());
107     }
108 
109     @Test
110     public void testCantRemoveMemoryConfig() throws Exception {
111         cc.clear();
112         assertEquals(1, cc.getNumberOfConfigurations());
113 
114         final Configuration internal = cc.getConfiguration(0);
115         cc.removeConfiguration(internal);
116 
117         assertEquals(1, cc.getNumberOfConfigurations());
118     }
119 
120     @Test
121     public void testCheckingInMemoryConfiguration() throws Exception {
122         final String TEST_KEY = "testKey";
123         final Configuration defaults = new PropertiesConfiguration();
124         defaults.setProperty(TEST_KEY, "testValue");
125         final Configuration testConfiguration = new CompositeConfiguration(defaults);
126         assertTrue(testConfiguration.containsKey(TEST_KEY));
127         assertFalse(testConfiguration.isEmpty());
128         boolean foundTestKey = false;
129         final Iterator<String> i = testConfiguration.getKeys();
130         while (i.hasNext()) {
131             final String key = i.next();
132             if (key.equals(TEST_KEY)) {
133                 foundTestKey = true;
134             }
135         }
136         assertTrue(foundTestKey);
137         testConfiguration.clearProperty(TEST_KEY);
138         assertFalse(testConfiguration.containsKey(TEST_KEY));
139     }
140 
141     /**
142      * Tests setting values. These are set in memory mode only!
143      */
144     @Test
145     public void testClearingProperty() throws Exception {
146         cc.addConfiguration(conf1);
147         cc.addConfiguration(xmlConf);
148         cc.clearProperty("test.short");
149         assertFalse(cc.containsKey("test.short"));
150     }
151 
152     /**
153      * Tests getting a default when the key doesn't exist
154      */
155     @Test
156     public void testDefaultValueWhenKeyMissing() throws Exception {
157         cc.addConfiguration(conf1);
158         cc.addConfiguration(xmlConf);
159         assertEquals("default", cc.getString("bogus", "default"));
160         assertEquals(1.4, cc.getDouble("bogus", 1.4), 0.0);
161         assertEquals(1.4, cc.getDouble("bogus", 1.4), 0.0);
162     }
163 
164     /**
165      * Tests {@code getKeys(String key)} preserves the order
166      */
167     @Test
168     public void testGetKeys2PreservesOrder() throws Exception {
169         cc.addConfiguration(conf1);
170         final List<String> orderedList = new ArrayList<>();
171         for (final Iterator<String> keys = conf1.getKeys("test"); keys.hasNext();) {
172             orderedList.add(keys.next());
173         }
174         final List<String> iteratedList = new ArrayList<>();
175         for (final Iterator<String> keys = cc.getKeys("test"); keys.hasNext();) {
176             iteratedList.add(keys.next());
177         }
178         assertEquals(orderedList, iteratedList);
179     }
180 
181     /**
182      * Tests {@code getKeys()} preserves the order
183      */
184     @Test
185     public void testGetKeysPreservesOrder() throws Exception {
186         cc.addConfiguration(conf1);
187         final List<String> orderedList = new ArrayList<>();
188         for (final Iterator<String> keys = conf1.getKeys(); keys.hasNext();) {
189             orderedList.add(keys.next());
190         }
191         final List<String> iteratedList = new ArrayList<>();
192         for (final Iterator<String> keys = cc.getKeys(); keys.hasNext();) {
193             iteratedList.add(keys.next());
194         }
195         assertEquals(orderedList, iteratedList);
196     }
197 
198     @Test
199     public void testGetList() {
200         final Configuration conf1 = new BaseConfiguration();
201         conf1.addProperty("array", "value1");
202         conf1.addProperty("array", "value2");
203 
204         final Configuration conf2 = new BaseConfiguration();
205         conf2.addProperty("array", "value3");
206         conf2.addProperty("array", "value4");
207 
208         cc.addConfiguration(conf1);
209         cc.addConfiguration(conf2);
210 
211         // check the composite 'array' property
212         List<Object> list = cc.getList("array");
213         assertEquals(Arrays.asList("value1", "value2"), list);
214 
215         // add an element to the list in the composite configuration
216         cc.addProperty("array", "value5");
217 
218         // test the new list
219         list = cc.getList("array");
220         assertEquals(Arrays.asList("value1", "value2", "value5"), list);
221     }
222 
223     @Test
224     public void testGetProperty() throws Exception {
225         cc.addConfiguration(conf1);
226         cc.addConfiguration(conf2);
227         assertEquals("test.properties", cc.getString("propertyInOrder"));
228         cc.clear();
229 
230         cc.addConfiguration(conf2);
231         cc.addConfiguration(conf1);
232         assertEquals("test2.properties", cc.getString("propertyInOrder"));
233     }
234 
235     @Test
236     public void testGetPropertyMissing() throws Exception {
237         cc.addConfiguration(conf1);
238         cc.addConfiguration(conf2);
239 
240         assertNull(cc.getString("bogus.property"));
241 
242         assertFalse(cc.getBoolean("test.missing.boolean", false));
243         assertTrue(cc.getBoolean("test.missing.boolean.true", true));
244     }
245 
246     @Test
247     public void testGetPropertyWIncludes() throws Exception {
248         cc.addConfiguration(conf1);
249         cc.addConfiguration(conf2);
250         final List<Object> l = cc.getList("packages");
251         assertTrue(l.contains("packagea"));
252     }
253 
254     @Test
255     public void testGetStringWithDefaults() {
256         final BaseConfiguration defaults = new BaseConfiguration();
257         defaults.addProperty("default", "default string");
258 
259         final Configuration c = new CompositeConfiguration(defaults);
260 
261         c.addProperty("string", "test string");
262 
263         assertEquals("test string", c.getString("string"));
264 
265         assertNull(c.getString("XXX"));
266 
267         // test defaults
268         assertEquals("test string", c.getString("string", "some default value"));
269         assertEquals("default string", c.getString("default"));
270         assertEquals("default string", c.getString("default", "some default value"));
271         assertEquals("some default value", c.getString("XXX", "some default value"));
272     }
273 
274     @Test
275     public void testGettingConfiguration() throws Exception {
276         cc.addConfiguration(conf1);
277         cc.addConfiguration(xmlConf);
278         assertEquals(PropertiesConfiguration.class, cc.getConfiguration(0).getClass());
279         assertEquals(XMLConfiguration.class, cc.getConfiguration(1).getClass());
280     }
281 
282     /**
283      * Tests retrieving subsets of configurations
284      */
285     @Test
286     public void testGettingSubset() throws Exception {
287         cc.addConfiguration(conf1);
288         cc.addConfiguration(xmlConf);
289 
290         Configuration subset = cc.subset("test");
291         assertNotNull(subset);
292         assertFalse(subset.isEmpty());
293         assertEquals("1", subset.getString("short"));
294 
295         cc.setProperty("test.short", "43");
296         subset = cc.subset("test");
297         assertEquals("43", subset.getString("short"));
298     }
299 
300     @Test
301     public void testGetVector() {
302         final Configuration conf1 = new BaseConfiguration();
303         conf1.addProperty("array", "value1");
304         conf1.addProperty("array", "value2");
305 
306         final Configuration conf2 = new BaseConfiguration();
307         conf2.addProperty("array", "value3");
308         conf2.addProperty("array", "value4");
309 
310         cc.addConfiguration(conf1);
311         cc.addConfiguration(conf2);
312 
313         // add an element to the vector in the composite configuration
314         cc.addProperty("array", "value5");
315 
316         final List<Object> list = cc.getList("array");
317         assertEquals(Arrays.asList("value1", "value2", "value5"), list);
318     }
319 
320     /**
321      * Tests {@code List} parsing.
322      */
323     @Test
324     public void testList() throws Exception {
325         cc.addConfiguration(conf1);
326         cc.addConfiguration(xmlConf);
327 
328         List<Object> packages = cc.getList("packages");
329         // we should get 3 packages here
330         assertEquals(3, packages.size());
331 
332         final List<Object> defaultList = new ArrayList<>();
333         defaultList.add("1");
334         defaultList.add("2");
335 
336         packages = cc.getList("packages.which.dont.exist", defaultList);
337         // we should get 2 packages here
338         assertEquals(2, packages.size());
339     }
340 
341     @Test
342     public void testMultipleTypesOfConfigs() throws Exception {
343         cc.addConfiguration(conf1);
344         cc.addConfiguration(xmlConf);
345         assertEquals(1, cc.getInt("test.short"));
346         cc.clear();
347 
348         cc.addConfiguration(xmlConf);
349         cc.addConfiguration(conf1);
350         assertEquals(8, cc.getInt("test.short"));
351     }
352 
353     @Test
354     public void testPropertyExistsInOnlyOneConfig() throws Exception {
355         cc.addConfiguration(conf1);
356         cc.addConfiguration(xmlConf);
357         assertEquals("value", cc.getString("element"));
358     }
359 
360     /**
361      * Tests setting values. These are set in memory mode only!
362      */
363     @Test
364     public void testSettingMissingProperty() throws Exception {
365         cc.addConfiguration(conf1);
366         cc.addConfiguration(xmlConf);
367         cc.setProperty("my.new.property", "supernew");
368         assertEquals("supernew", cc.getString("my.new.property"));
369     }
370 
371     /**
372      * Tests {@code String} array parsing.
373      */
374     @Test
375     public void testStringArray() throws Exception {
376         cc.addConfiguration(conf1);
377         cc.addConfiguration(xmlConf);
378 
379         String[] packages = cc.getStringArray("packages");
380         // we should get 3 packages here
381         assertEquals(3, packages.length);
382 
383         packages = cc.getStringArray("packages.which.dont.exist");
384         // we should get 0 packages here
385         assertEquals(0, packages.length);
386     }
387 
388     /**
389      * Tests subsets and still can resolve elements
390      */
391     @Test
392     public void testSubsetCanResolve() throws Exception {
393         cc = new CompositeConfiguration();
394         final BaseConfiguration config = new BaseConfiguration();
395         config.addProperty("subset.tempfile", "${java.io.tmpdir}/file.tmp");
396         cc.addConfiguration(config);
397         cc.addConfiguration(ConfigurationConverter.getConfiguration(System.getProperties()));
398 
399         final Configuration subset = cc.subset("subset");
400         assertEquals(FileUtils.getTempDirectoryPath() + "/file.tmp", subset.getString("tempfile"));
401     }
402 
403     @Test
404     public void testThrowExceptionOnMissing() {
405         assertFalse(cc.isThrowExceptionOnMissing());
406     }
407 }