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    *     https://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.assertInstanceOf;
24  import static org.junit.jupiter.api.Assertions.assertNotNull;
25  import static org.junit.jupiter.api.Assertions.assertNull;
26  import static org.junit.jupiter.api.Assertions.assertThrows;
27  import static org.junit.jupiter.api.Assertions.assertTrue;
28  import static org.mockito.Mockito.mock;
29  import static org.mockito.Mockito.verify;
30  import static org.mockito.Mockito.verifyNoMoreInteractions;
31  
32  import java.awt.Color;
33  import java.math.BigDecimal;
34  import java.math.BigInteger;
35  import java.net.InetAddress;
36  import java.net.URI;
37  import java.net.URL;
38  import java.text.DateFormat;
39  import java.text.ParseException;
40  import java.text.SimpleDateFormat;
41  import java.util.ArrayList;
42  import java.util.Calendar;
43  import java.util.Date;
44  import java.util.Iterator;
45  import java.util.List;
46  import java.util.Locale;
47  import java.util.NoSuchElementException;
48  
49  import jakarta.mail.internet.InternetAddress;
50  
51  import org.apache.commons.configuration2.convert.DefaultConversionHandler;
52  import org.apache.commons.configuration2.convert.DefaultListDelimiterHandler;
53  import org.apache.commons.configuration2.ex.ConversionException;
54  import org.junit.jupiter.api.BeforeEach;
55  import org.junit.jupiter.api.Test;
56  
57  /**
58   */
59  public class TestDataConfiguration {
60  
61      /** Constant for the date pattern used by tests. */
62      private static final String DATE_PATTERN = "yyyy-MM-dd";
63  
64      /**
65       * Returns the expected test date.
66       *
67       * @return the expected test date
68       * @throws ParseException if the date cannot be parsed
69       */
70      private static Date expectedDate() throws ParseException {
71          final DateFormat format = new SimpleDateFormat(DATE_PATTERN);
72          return format.parse("2004-01-01");
73      }
74  
75      /** The test instance. */
76      private DataConfiguration conf;
77  
78      @BeforeEach
79      public void setUp() throws Exception {
80          final BaseConfiguration baseConfig = new BaseConfiguration();
81          baseConfig.setListDelimiterHandler(new DefaultListDelimiterHandler(','));
82          conf = new DataConfiguration(baseConfig);
83          // empty value
84          conf.addProperty("empty", "");
85          // lists of boolean
86          conf.addProperty("boolean.list1", "true");
87          conf.addProperty("boolean.list1", "false");
88          conf.addProperty("boolean.list2", "true, false");
89          conf.addProperty("boolean.list3", Boolean.TRUE);
90          conf.addProperty("boolean.list3", Boolean.FALSE);
91          conf.addPropertyDirect("boolean.list4", new Boolean[] {Boolean.TRUE, Boolean.FALSE});
92          conf.addPropertyDirect("boolean.list5", new boolean[] {true, false});
93          final List<Object> booleans = new ArrayList<>();
94          booleans.add(Boolean.TRUE);
95          booleans.add(Boolean.FALSE);
96          conf.addProperty("boolean.list6", booleans);
97          conf.addProperty("boolean.string", "true");
98          conf.addProperty("boolean.object", Boolean.TRUE);
99          conf.addProperty("boolean.list.interpolated", "${boolean.string},false");
100         // lists of bytes
101         conf.addProperty("byte.list1", "1");
102         conf.addProperty("byte.list1", "2");
103         conf.addProperty("byte.list2", "1, 2");
104         conf.addProperty("byte.list3", Byte.valueOf("1"));
105         conf.addProperty("byte.list3", Byte.valueOf("2"));
106         conf.addPropertyDirect("byte.list4", new Byte[] {Byte.valueOf("1"), Byte.valueOf("2")});
107         conf.addPropertyDirect("byte.list5", new byte[] {1, 2});
108         final List<Object> bytes = new ArrayList<>();
109         bytes.add(Byte.valueOf("1"));
110         bytes.add(Byte.valueOf("2"));
111         conf.addProperty("byte.list6", bytes);
112         conf.addProperty("byte.string", "1");
113         conf.addProperty("byte.object", Byte.valueOf("1"));
114         conf.addProperty("byte.list.interpolated", "${byte.string},2");
115         // lists of shorts
116         conf.addProperty("short.list1", "1");
117         conf.addProperty("short.list1", "2");
118         conf.addProperty("short.list2", "1, 2");
119         conf.addProperty("short.list3", Short.valueOf("1"));
120         conf.addProperty("short.list3", Short.valueOf("2"));
121         conf.addPropertyDirect("short.list4", new Short[] {Short.valueOf("1"), Short.valueOf("2")});
122         conf.addPropertyDirect("short.list5", new short[] {1, 2});
123         final List<Object> shorts = new ArrayList<>();
124         shorts.add(Short.valueOf("1"));
125         shorts.add(Short.valueOf("2"));
126         conf.addProperty("short.list6", shorts);
127         conf.addProperty("short.string", "1");
128         conf.addProperty("short.object", Short.valueOf("1"));
129         conf.addProperty("short.list.interpolated", "${short.string},2");
130         // lists of integers
131         conf.addProperty("integer.list1", "1");
132         conf.addProperty("integer.list1", "2");
133         conf.addProperty("integer.list2", "1, 2");
134         conf.addProperty("integer.list3", Integer.valueOf("1"));
135         conf.addProperty("integer.list3", Integer.valueOf("2"));
136         conf.addPropertyDirect("integer.list4", new Integer[] {Integer.valueOf("1"), Integer.valueOf("2")});
137         conf.addPropertyDirect("integer.list5", new int[] {1, 2});
138         final List<Object> integers = new ArrayList<>();
139         integers.add(Integer.valueOf("1"));
140         integers.add(Integer.valueOf("2"));
141         conf.addProperty("integer.list6", integers);
142         conf.addProperty("integer.string", "1");
143         conf.addProperty("integer.object", Integer.valueOf("1"));
144         conf.addProperty("integer.list.interpolated", "${integer.string},2");
145         // lists of longs
146         conf.addProperty("long.list1", "1");
147         conf.addProperty("long.list1", "2");
148         conf.addProperty("long.list2", "1, 2");
149         conf.addProperty("long.list3", Long.valueOf("1"));
150         conf.addProperty("long.list3", Long.valueOf("2"));
151         conf.addPropertyDirect("long.list4", new Long[] {Long.valueOf("1"), Long.valueOf("2")});
152         conf.addPropertyDirect("long.list5", new long[] {1, 2});
153         final List<Object> longs = new ArrayList<>();
154         longs.add(Long.valueOf("1"));
155         longs.add(Long.valueOf("2"));
156         conf.addProperty("long.list6", longs);
157         conf.addProperty("long.string", "1");
158         conf.addProperty("long.object", Long.valueOf("1"));
159         conf.addProperty("long.list.interpolated", "${long.string},2");
160         // lists of floats
161         conf.addProperty("float.list1", "1");
162         conf.addProperty("float.list1", "2");
163         conf.addProperty("float.list2", "1, 2");
164         conf.addProperty("float.list3", Float.valueOf("1"));
165         conf.addProperty("float.list3", Float.valueOf("2"));
166         conf.addPropertyDirect("float.list4", new Float[] {Float.valueOf("1"), Float.valueOf("2")});
167         conf.addPropertyDirect("float.list5", new float[] {1, 2});
168         final List<Object> floats = new ArrayList<>();
169         floats.add(Float.valueOf("1"));
170         floats.add(Float.valueOf("2"));
171         conf.addProperty("float.list6", floats);
172         conf.addProperty("float.string", "1");
173         conf.addProperty("float.object", Float.valueOf("1"));
174         conf.addProperty("float.list.interpolated", "${float.string},2");
175         // lists of doubles
176         conf.addProperty("double.list1", "1");
177         conf.addProperty("double.list1", "2");
178         conf.addProperty("double.list2", "1, 2");
179         conf.addProperty("double.list3", Double.valueOf("1"));
180         conf.addProperty("double.list3", Double.valueOf("2"));
181         conf.addPropertyDirect("double.list4", new Double[] {Double.valueOf("1"), Double.valueOf("2")});
182         conf.addPropertyDirect("double.list5", new double[] {1, 2});
183         final List<Object> doubles = new ArrayList<>();
184         doubles.add(Double.valueOf("1"));
185         doubles.add(Double.valueOf("2"));
186         conf.addProperty("double.list6", doubles);
187         conf.addProperty("double.string", "1");
188         conf.addProperty("double.object", Double.valueOf("1"));
189         conf.addProperty("double.list.interpolated", "${double.string},2");
190         // lists of big integers
191         conf.addProperty("biginteger.list1", "1");
192         conf.addProperty("biginteger.list1", "2");
193         conf.addProperty("biginteger.list2", "1, 2");
194         conf.addProperty("biginteger.list3", new BigInteger("1"));
195         conf.addProperty("biginteger.list3", new BigInteger("2"));
196         conf.addPropertyDirect("biginteger.list4", new BigInteger[] {new BigInteger("1"), new BigInteger("2")});
197         final List<Object> bigintegers = new ArrayList<>();
198         bigintegers.add(new BigInteger("1"));
199         bigintegers.add(new BigInteger("2"));
200         conf.addProperty("biginteger.list6", bigintegers);
201         conf.addProperty("biginteger.string", "1");
202         conf.addProperty("biginteger.object", new BigInteger("1"));
203         conf.addProperty("biginteger.list.interpolated", "${biginteger.string},2");
204         // lists of big decimals
205         conf.addProperty("bigdecimal.list1", "1");
206         conf.addProperty("bigdecimal.list1", "2");
207         conf.addProperty("bigdecimal.list2", "1, 2");
208         conf.addProperty("bigdecimal.list3", new BigDecimal("1"));
209         conf.addProperty("bigdecimal.list3", new BigDecimal("2"));
210         conf.addPropertyDirect("bigdecimal.list4", new BigDecimal[] {new BigDecimal("1"), new BigDecimal("2")});
211         final List<Object> bigdecimals = new ArrayList<>();
212         bigdecimals.add(new BigDecimal("1"));
213         bigdecimals.add(new BigDecimal("2"));
214         conf.addProperty("bigdecimal.list6", bigdecimals);
215         conf.addProperty("bigdecimal.string", "1");
216         conf.addProperty("bigdecimal.object", new BigDecimal("1"));
217         conf.addProperty("bigdecimal.list.interpolated", "${bigdecimal.string},2");
218         // URIs
219         final String uri1 = "http://jakarta.apache.org";
220         final String uri2 = "http://www.apache.org";
221         conf.addProperty("uri.string", uri1);
222         conf.addProperty("uri.string.interpolated", "${uri.string}");
223         conf.addProperty("uri.object", new URI(uri1));
224         conf.addProperty("uri.list1", uri1);
225         conf.addProperty("uri.list1", uri2);
226         conf.addProperty("uri.list2", uri1 + ", " + uri2);
227         conf.addProperty("uri.list3", new URI(uri1));
228         conf.addProperty("uri.list3", new URI(uri2));
229         conf.addPropertyDirect("uri.list4", new URI[] {new URI(uri1), new URI(uri2)});
230         final List<Object> uris = new ArrayList<>();
231         uris.add(new URI(uri1));
232         uris.add(new URI(uri2));
233         conf.addProperty("uri.list6", uris);
234         conf.addProperty("uri.list.interpolated", "${uri.string}," + uri2);
235         // URLs
236         final String url1 = "http://jakarta.apache.org";
237         final String url2 = "http://www.apache.org";
238         conf.addProperty("url.string", url1);
239         conf.addProperty("url.string.interpolated", "${url.string}");
240         conf.addProperty("url.object", new URL(url1));
241         conf.addProperty("url.list1", url1);
242         conf.addProperty("url.list1", url2);
243         conf.addProperty("url.list2", url1 + ", " + url2);
244         conf.addProperty("url.list3", new URL(url1));
245         conf.addProperty("url.list3", new URL(url2));
246         conf.addPropertyDirect("url.list4", new URL[] {new URL(url1), new URL(url2)});
247         final List<Object> urls = new ArrayList<>();
248         urls.add(new URL(url1));
249         urls.add(new URL(url2));
250         conf.addProperty("url.list6", urls);
251         conf.addProperty("url.list.interpolated", "${url.string}," + url2);
252         // Locales
253         conf.addProperty("locale.string", "fr");
254         conf.addProperty("locale.string.interpolated", "${locale.string}");
255         conf.addProperty("locale.object", Locale.FRENCH);
256         conf.addProperty("locale.list1", "fr");
257         conf.addProperty("locale.list1", "de");
258         conf.addProperty("locale.list2", "fr, de");
259         conf.addProperty("locale.list3", Locale.FRENCH);
260         conf.addProperty("locale.list3", Locale.GERMAN);
261         conf.addPropertyDirect("locale.list4", new Locale[] {Locale.FRENCH, Locale.GERMAN});
262         final List<Object> locales = new ArrayList<>();
263         locales.add(Locale.FRENCH);
264         locales.add(Locale.GERMAN);
265         conf.addProperty("locale.list6", locales);
266         conf.addProperty("locale.list.interpolated", "${locale.string},de");
267         // Colors
268         final String color1 = "FF0000";
269         final String color2 = "0000FF";
270         conf.addProperty("color.string", color1);
271         conf.addProperty("color.string.interpolated", "${color.string}");
272         conf.addProperty("color.object", Color.red);
273         conf.addProperty("color.list1", color1);
274         conf.addProperty("color.list1", color2);
275         conf.addProperty("color.list2", color1 + ", " + color2);
276         conf.addProperty("color.list3", Color.red);
277         conf.addProperty("color.list3", Color.blue);
278         conf.addPropertyDirect("color.list4", new Color[] {Color.red, Color.blue});
279         final List<Object> colors = new ArrayList<>();
280         colors.add(Color.red);
281         colors.add(Color.blue);
282         conf.addProperty("color.list6", colors);
283         conf.addProperty("color.list.interpolated", "${color.string}," + color2);
284         // Dates & Calendars
285         final String pattern = DATE_PATTERN;
286         final DateFormat format = new SimpleDateFormat(pattern);
287         conf.setProperty(DataConfiguration.DATE_FORMAT_KEY, pattern);
288         final Date date1 = format.parse("2004-01-01");
289         final Date date2 = format.parse("2004-12-31");
290         final Calendar calendar1 = Calendar.getInstance();
291         calendar1.setTime(date1);
292         final Calendar calendar2 = Calendar.getInstance();
293         calendar2.setTime(date2);
294         conf.addProperty("date.string", "2004-01-01");
295         conf.addProperty("date.string.interpolated", "${date.string}");
296         conf.addProperty("date.object", date1);
297         conf.addProperty("date.list1", "2004-01-01");
298         conf.addProperty("date.list1", "2004-12-31");
299         conf.addProperty("date.list2", "2004-01-01, 2004-12-31");
300         conf.addProperty("date.list3", date1);
301         conf.addProperty("date.list3", date2);
302         conf.addPropertyDirect("date.list4", new Date[] {date1, date2});
303         conf.addPropertyDirect("date.list5", new Calendar[] {calendar1, calendar2});
304         final List<Object> dates = new ArrayList<>();
305         dates.add(date1);
306         dates.add(date2);
307         conf.addProperty("date.list6", dates);
308         conf.addProperty("date.list.interpolated", "${date.string},2004-12-31");
309         conf.addPropertyDirect("date.list7", new String[] {"2004-01-01", "2004-12-31"});
310         conf.addProperty("calendar.string", "2004-01-01");
311         conf.addProperty("calendar.string.interpolated", "${calendar.string}");
312         conf.addProperty("calendar.object", calendar1);
313         conf.addProperty("calendar.list1", "2004-01-01");
314         conf.addProperty("calendar.list1", "2004-12-31");
315         conf.addProperty("calendar.list2", "2004-01-01, 2004-12-31");
316         conf.addProperty("calendar.list3", calendar1);
317         conf.addProperty("calendar.list3", calendar2);
318         conf.addPropertyDirect("calendar.list4", new Calendar[] {calendar1, calendar2});
319         conf.addPropertyDirect("calendar.list5", new Date[] {date1, date2});
320         final List<Object> calendars = new ArrayList<>();
321         calendars.add(date1);
322         calendars.add(date2);
323         conf.addProperty("calendar.list6", calendars);
324         conf.addProperty("calendar.list.interpolated", "${calendar.string},2004-12-31");
325         conf.addPropertyDirect("calendar.list7", new String[] {"2004-01-01", "2004-12-31"});
326         // host address
327         conf.addProperty("ip.string", "127.0.0.1");
328         conf.addProperty("ip.string.interpolated", "${ip.string}");
329         conf.addProperty("ip.object", InetAddress.getByName("127.0.0.1"));
330         // email address
331         conf.addProperty("email.string", "dev@test.org");
332         conf.addProperty("email.string.interpolated", "${email.string}");
333         conf.addProperty("email.object", new InternetAddress("dev@test.org"));
334     }
335 
336     /**
337      * Tests whether properties can be cleared.
338      */
339     @Test
340     void testClearProperty() {
341         final String key = "test.property";
342         conf.addProperty(key, "someValue");
343         conf.clearProperty(key);
344         assertFalse(conf.containsKey(key));
345     }
346 
347     /**
348      * Tests the implementation of clearPropertyDirect().
349      */
350     @Test
351     void testClearPropertyDirect() {
352         final String key = "test.property";
353         conf.addProperty(key, "someValue");
354         conf.clearPropertyDirect(key);
355         assertFalse(conf.containsKey(key));
356     }
357 
358     /**
359      * Tests clearPropertyDirect() if the wrapped configuration does not extend AbstractConfiguration.
360      */
361     @Test
362     void testClearPropertyDirectNoAbstractConf() {
363         final Configuration wrapped = mock(Configuration.class);
364         final String key = "test.property";
365         conf = new DataConfiguration(wrapped);
366         conf.clearPropertyDirect(key);
367 
368         verify(wrapped).clearProperty(key);
369         verifyNoMoreInteractions(wrapped);
370     }
371 
372     @Test
373     void testContainsKey() {
374         final Configuration baseconf = new BaseConfiguration();
375         final DataConfiguration conf = new DataConfiguration(baseconf);
376 
377         assertFalse(conf.containsKey("foo"));
378 
379         baseconf.setProperty("foo", "bar");
380 
381         assertTrue(conf.containsKey("foo"));
382     }
383 
384     @Test
385     void testContainsValue() {
386         final Configuration config = conf.getConfiguration();
387         assertFalse(config.containsValue(null));
388         assertTrue(config.containsValue(""));
389     }
390 
391     @Test
392     void testConversionException() throws Exception {
393         conf.addProperty("key1", new Object());
394         conf.addProperty("key2", "xxxxxx");
395 
396         assertThrows(ConversionException.class, () -> conf.getBooleanArray("key1"));
397         assertThrows(ConversionException.class, () -> conf.getBooleanArray("key2"));
398 
399         assertThrows(ConversionException.class, () -> conf.getBooleanList("key1"));
400         assertThrows(ConversionException.class, () -> conf.getBooleanList("key2"));
401 
402         assertThrows(ConversionException.class, () -> conf.getByteArray("key1"));
403         assertThrows(ConversionException.class, () -> conf.getByteArray("key2"));
404 
405         assertThrows(ConversionException.class, () -> conf.getByteList("key1"));
406         assertThrows(ConversionException.class, () -> conf.getByteList("key2"));
407 
408         assertThrows(ConversionException.class, () -> conf.getShortArray("key1"));
409         assertThrows(ConversionException.class, () -> conf.getShortArray("key2"));
410 
411         assertThrows(ConversionException.class, () -> conf.getShortList("key1"));
412         assertThrows(ConversionException.class, () -> conf.getShortList("key2"));
413 
414         assertThrows(ConversionException.class, () -> conf.getIntArray("key1"));
415         assertThrows(ConversionException.class, () -> conf.getIntArray("key2"));
416 
417         assertThrows(ConversionException.class, () -> conf.getIntegerList("key1"));
418         assertThrows(ConversionException.class, () -> conf.getIntegerList("key2"));
419 
420         assertThrows(ConversionException.class, () -> conf.getLongArray("key1"));
421         assertThrows(ConversionException.class, () -> conf.getLongArray("key2"));
422 
423         assertThrows(ConversionException.class, () -> conf.getLongList("key1"));
424         assertThrows(ConversionException.class, () -> conf.getLongList("key2"));
425 
426         assertThrows(ConversionException.class, () -> conf.getFloatArray("key1"));
427         assertThrows(ConversionException.class, () -> conf.getFloatArray("key2"));
428 
429         assertThrows(ConversionException.class, () -> conf.getFloatList("key1"));
430         assertThrows(ConversionException.class, () -> conf.getFloatList("key2"));
431 
432         assertThrows(ConversionException.class, () -> conf.getDoubleArray("key1"));
433         assertThrows(ConversionException.class, () -> conf.getDoubleArray("key2"));
434 
435         assertThrows(ConversionException.class, () -> conf.getDoubleList("key1"));
436         assertThrows(ConversionException.class, () -> conf.getDoubleList("key2"));
437 
438         assertThrows(ConversionException.class, () -> conf.getBigIntegerArray("key1"));
439         assertThrows(ConversionException.class, () -> conf.getBigIntegerArray("key2"));
440 
441         assertThrows(ConversionException.class, () -> conf.getBigIntegerList("key1"));
442         assertThrows(ConversionException.class, () -> conf.getBigIntegerList("key2"));
443 
444         assertThrows(ConversionException.class, () -> conf.getBigDecimalArray("key1"));
445         assertThrows(ConversionException.class, () -> conf.getBigDecimalArray("key2"));
446 
447         assertThrows(ConversionException.class, () -> conf.getBigDecimalList("key1"));
448         assertThrows(ConversionException.class, () -> conf.getBigDecimalList("key2"));
449 
450         assertThrows(ConversionException.class, () -> conf.getURLArray("key1"));
451         assertThrows(ConversionException.class, () -> conf.getURLArray("key2"));
452 
453         assertThrows(ConversionException.class, () -> conf.getURLList("key1"));
454         assertThrows(ConversionException.class, () -> conf.getURLList("key2"));
455 
456         assertThrows(ConversionException.class, () -> conf.getLocaleArray("key1"));
457         assertThrows(ConversionException.class, () -> conf.getLocaleArray("key2"));
458 
459         assertThrows(ConversionException.class, () -> conf.getLocaleList("key1"));
460         assertThrows(ConversionException.class, () -> conf.getLocaleList("key2"));
461 
462         assertThrows(ConversionException.class, () -> conf.getColorArray("key1"));
463         assertThrows(ConversionException.class, () -> conf.getColorArray("key2"));
464 
465         assertThrows(ConversionException.class, () -> conf.getColorList("key1"));
466         assertThrows(ConversionException.class, () -> conf.getColorList("key2"));
467 
468         assertThrows(ConversionException.class, () -> conf.getDateArray("key1"));
469         assertThrows(ConversionException.class, () -> conf.getDateArray("key2"));
470 
471         assertThrows(ConversionException.class, () -> conf.getDate("key1", DATE_PATTERN));
472         assertThrows(ConversionException.class, () -> conf.getDate("key2", DATE_PATTERN));
473 
474         assertThrows(ConversionException.class, () -> conf.getDateList("key1"));
475         assertThrows(ConversionException.class, () -> conf.getDateList("key2"));
476 
477         assertThrows(ConversionException.class, () -> conf.getCalendar("key1", DATE_PATTERN));
478         assertThrows(ConversionException.class, () -> conf.getCalendar("key2", DATE_PATTERN));
479 
480         assertThrows(ConversionException.class, () -> conf.getCalendarArray("key1"));
481         assertThrows(ConversionException.class, () -> conf.getCalendarArray("key2"));
482 
483         assertThrows(ConversionException.class, () -> conf.getCalendarList("key1"));
484         assertThrows(ConversionException.class, () -> conf.getCalendarList("key2"));
485 
486         assertThrows(ConversionException.class, () -> conf.get(InetAddress.class, "key1"));
487 
488         assertThrows(ConversionException.class, () -> conf.get(InternetAddress.class, "key1"));
489     }
490 
491     /**
492      * Tests that the cause of a conversion exception is kept.
493      */
494     @Test
495     void testConversionExceptionCause() {
496         final ConversionException cex = assertThrows(ConversionException.class, () -> conf.get(Integer.TYPE, "uri.string"));
497         assertInstanceOf(NumberFormatException.class, cex.getCause());
498     }
499 
500     @Test
501     void testGetArrayInvalidDefaultType() {
502         assertThrows(IllegalArgumentException.class, () -> conf.getArray(Boolean.class, "unknownkey", new URL[] {}));
503     }
504 
505     @Test
506     void testGetBigDecimalArray() {
507         // missing list
508         final BigDecimal[] defaultValue = {new BigDecimal("2"), new BigDecimal("1")};
509         assertArrayEquals(defaultValue, conf.getBigDecimalArray("bigdecimal.list", defaultValue));
510 
511         final BigDecimal[] expected = {new BigDecimal("1"), new BigDecimal("2")};
512 
513         // list of strings
514         assertArrayEquals(expected, conf.getBigDecimalArray("bigdecimal.list1"));
515 
516         // list of strings, comma separated
517         assertArrayEquals(expected, conf.getBigDecimalArray("bigdecimal.list2"));
518 
519         // list of BigDecimal objects
520         assertArrayEquals(expected, conf.getBigDecimalArray("bigdecimal.list3"));
521 
522         // array of BigDecimal objects
523         assertArrayEquals(expected, conf.getBigDecimalArray("bigdecimal.list4"));
524 
525         // list of BigDecimal objects
526         assertArrayEquals(expected, conf.getBigDecimalArray("bigdecimal.list6"));
527 
528         // list of interpolated values
529         assertArrayEquals(expected, conf.getBigDecimalArray("bigdecimal.list.interpolated"));
530 
531         // single BigDecimal values
532         assertArrayEquals(new BigDecimal[] {new BigDecimal("1")}, conf.getBigDecimalArray("bigdecimal.string"));
533         assertArrayEquals(new BigDecimal[] {new BigDecimal("1")}, conf.getBigDecimalArray("bigdecimal.object"));
534 
535         // empty array
536         assertArrayEquals(new BigDecimal[] {}, conf.getBigDecimalArray("empty"));
537     }
538 
539     @Test
540     void testGetBigDecimalList() {
541         // missing list
542         assertNull(conf.getBigDecimalList("bigdecimal.list", null));
543 
544         List<Object> expected = new ArrayList<>();
545         expected.add(new BigDecimal("1"));
546         expected.add(new BigDecimal("2"));
547 
548         // list of strings
549         assertEquals(expected, conf.getBigDecimalList("bigdecimal.list1"));
550 
551         // list of strings, comma separated
552         assertEquals(expected, conf.getBigDecimalList("bigdecimal.list2"));
553 
554         // list of BigDecimal objects
555         assertEquals(expected, conf.getBigDecimalList("bigdecimal.list3"));
556 
557         // array of BigDecimal objects
558         assertEquals(expected, conf.getBigDecimalList("bigdecimal.list4"));
559 
560         // list of BigDecimal objects
561         assertEquals(expected, conf.getBigDecimalList("bigdecimal.list6"));
562 
563         // list of interpolated values
564         assertEquals(expected, conf.getBigDecimalList("bigdecimal.list.interpolated"));
565 
566         // single BigDecimal values
567         expected = new ArrayList<>();
568         expected.add(new BigDecimal("1"));
569         assertEquals(expected, conf.getBigDecimalList("bigdecimal.string"));
570         assertEquals(expected, conf.getBigDecimalList("bigdecimal.object"));
571 
572         // empty list
573         assertEquals(new ArrayList<>(), conf.getBigDecimalList("empty"));
574     }
575 
576     @Test
577     void testGetBigIntegerArray() {
578         // missing list
579         final BigInteger[] defaultValue = {new BigInteger("2"), new BigInteger("1")};
580         assertArrayEquals(defaultValue, conf.getBigIntegerArray("biginteger.list", defaultValue));
581 
582         final BigInteger[] expected = {new BigInteger("1"), new BigInteger("2")};
583 
584         // list of strings
585         assertArrayEquals(expected, conf.getBigIntegerArray("biginteger.list1"));
586 
587         // list of strings, comma separated
588         assertArrayEquals(expected, conf.getBigIntegerArray("biginteger.list2"));
589 
590         // list of BigInteger objects
591         assertArrayEquals(expected, conf.getBigIntegerArray("biginteger.list3"));
592 
593         // array of BigInteger objects
594         assertArrayEquals(expected, conf.getBigIntegerArray("biginteger.list4"));
595 
596         // list of BigInteger objects
597         assertArrayEquals(expected, conf.getBigIntegerArray("biginteger.list6"));
598 
599         // list of interpolated values
600         assertArrayEquals(expected, conf.getBigIntegerArray("biginteger.list.interpolated"));
601 
602         // single BigInteger values
603         assertArrayEquals(new BigInteger[] {new BigInteger("1")}, conf.getBigIntegerArray("biginteger.string"));
604         assertArrayEquals(new BigInteger[] {new BigInteger("1")}, conf.getBigIntegerArray("biginteger.object"));
605 
606         // empty array
607         assertArrayEquals(new BigInteger[] {}, conf.getBigIntegerArray("empty"));
608     }
609 
610     @Test
611     void testGetBigIntegerList() {
612         // missing list
613         final List<BigInteger> bigIntegerList = conf.getBigIntegerList("biginteger.list", null);
614         assertNull(bigIntegerList);
615 
616         List<Object> expected = new ArrayList<>();
617         expected.add(new BigInteger("1"));
618         expected.add(new BigInteger("2"));
619 
620         // list of strings
621         assertEquals(expected, conf.getBigIntegerList("biginteger.list1"));
622 
623         // list of strings, comma separated
624         assertEquals(expected, conf.getBigIntegerList("biginteger.list2"));
625 
626         // list of BigInteger objects
627         assertEquals(expected, conf.getBigIntegerList("biginteger.list3"));
628 
629         // array of BigInteger objects
630         assertEquals(expected, conf.getBigIntegerList("biginteger.list4"));
631 
632         // list of BigInteger objects
633         assertEquals(expected, conf.getBigIntegerList("biginteger.list6"));
634 
635         // list of interpolated values
636         assertEquals(expected, conf.getBigIntegerList("biginteger.list.interpolated"));
637 
638         // single BigInteger values
639         expected = new ArrayList<>();
640         expected.add(new BigInteger("1"));
641         assertEquals(expected, conf.getBigIntegerList("biginteger.string"));
642         assertEquals(expected, conf.getBigIntegerList("biginteger.object"));
643 
644         // empty list
645         assertEquals(new ArrayList<>(), conf.getBigIntegerList("empty"));
646     }
647 
648     @Test
649     void testGetBooleanArray() {
650         // missing list
651         final boolean[] defaultValue = {false, true};
652         assertArrayEquals(defaultValue, conf.getBooleanArray("boolean.list", defaultValue));
653 
654         final boolean[] expected = {true, false};
655 
656         // list of strings
657         assertArrayEquals(expected, conf.getBooleanArray("boolean.list1"));
658 
659         // list of strings, comma separated
660         assertArrayEquals(expected, conf.getBooleanArray("boolean.list2"));
661 
662         // list of Boolean objects
663         assertArrayEquals(expected, conf.getBooleanArray("boolean.list3"));
664 
665         // array of Boolean objects
666         assertArrayEquals(expected, conf.getBooleanArray("boolean.list4"));
667 
668         // array of boolean primitives
669         assertArrayEquals(expected, conf.getBooleanArray("boolean.list5"));
670 
671         // list of Boolean objects
672         assertArrayEquals(expected, conf.getBooleanArray("boolean.list6"));
673 
674         // list of interpolated values
675         assertArrayEquals(expected, conf.getBooleanArray("boolean.list.interpolated"));
676 
677         // single boolean values
678         assertArrayEquals(new boolean[] {true}, conf.getBooleanArray("boolean.string"));
679         assertArrayEquals(new boolean[] {true}, conf.getBooleanArray("boolean.object"));
680 
681         // empty array
682         assertArrayEquals(new boolean[] {}, conf.getBooleanArray("empty"));
683     }
684 
685     @Test
686     void testGetBooleanList() {
687         // missing list
688         assertNull(conf.getBooleanList("boolean.list", null));
689 
690         List<Object> expected = new ArrayList<>();
691         expected.add(Boolean.TRUE);
692         expected.add(Boolean.FALSE);
693 
694         // list of strings
695         assertEquals(expected, conf.getBooleanList("boolean.list1"));
696 
697         // list of strings, comma separated
698         assertEquals(expected, conf.getBooleanList("boolean.list2"));
699 
700         // list of Boolean objects
701         assertEquals(expected, conf.getBooleanList("boolean.list3"));
702 
703         // array of Boolean objects
704         assertEquals(expected, conf.getBooleanList("boolean.list4"));
705 
706         // array of boolean primitives
707         assertEquals(expected, conf.getBooleanList("boolean.list5"));
708 
709         // list of Boolean objects
710         assertEquals(expected, conf.getBooleanList("boolean.list6"));
711 
712         // list of interpolated values
713         assertEquals(expected, conf.getBooleanList("boolean.list.interpolated"));
714 
715         // single boolean values
716         expected = new ArrayList<>();
717         expected.add(Boolean.TRUE);
718         assertEquals(expected, conf.getBooleanList("boolean.string"));
719         assertEquals(expected, conf.getBooleanList("boolean.object"));
720 
721         // empty list
722         assertEquals(new ArrayList<>(), conf.getBooleanList("empty"));
723     }
724 
725     @Test
726     void testGetByteArray() {
727         // missing list
728         final byte[] defaultValue = {1, 2};
729         assertArrayEquals(defaultValue, conf.getByteArray("byte.list", defaultValue));
730 
731         final byte[] expected = {1, 2};
732 
733         // list of strings
734         assertArrayEquals(expected, conf.getByteArray("byte.list1"));
735 
736         // list of strings, comma separated
737         assertArrayEquals(expected, conf.getByteArray("byte.list2"));
738 
739         // list of Byte objects
740         assertArrayEquals(expected, conf.getByteArray("byte.list3"));
741 
742         // array of Byte objects
743         assertArrayEquals(expected, conf.getByteArray("byte.list4"));
744 
745         // array of byte primitives
746         assertArrayEquals(expected, conf.getByteArray("byte.list5"));
747 
748         // list of Byte objects
749         assertArrayEquals(expected, conf.getByteArray("byte.list6"));
750 
751         // list of interpolated values
752         assertArrayEquals(expected, conf.getByteArray("byte.list.interpolated"));
753 
754         // single byte values
755         assertArrayEquals(new byte[] {1}, conf.getByteArray("byte.string"));
756         assertArrayEquals(new byte[] {1}, conf.getByteArray("byte.object"));
757 
758         // empty array
759         assertArrayEquals(new byte[] {}, conf.getByteArray("empty"));
760     }
761 
762     @Test
763     void testGetByteList() {
764         // missing list
765         assertNull(conf.getByteList("byte.list", null));
766 
767         List<Object> expected = new ArrayList<>();
768         expected.add(Byte.valueOf("1"));
769         expected.add(Byte.valueOf("2"));
770 
771         // list of strings
772         assertEquals(expected, conf.getByteList("byte.list1"));
773 
774         // list of strings, comma separated
775         assertEquals(expected, conf.getByteList("byte.list2"));
776 
777         // list of Byte objects
778         assertEquals(expected, conf.getByteList("byte.list3"));
779 
780         // array of Byte objects
781         assertEquals(expected, conf.getByteList("byte.list4"));
782 
783         // array of byte primitives
784         assertEquals(expected, conf.getByteList("byte.list5"));
785 
786         // list of Byte objects
787         assertEquals(expected, conf.getByteList("byte.list6"));
788 
789         // list of interpolated values
790         assertEquals(expected, conf.getByteList("byte.list.interpolated"));
791 
792         // single byte values
793         expected = new ArrayList<>();
794         expected.add(Byte.valueOf("1"));
795         assertEquals(expected, conf.getByteList("byte.string"));
796         assertEquals(expected, conf.getByteList("byte.object"));
797 
798         // empty list
799         assertEquals(new ArrayList<>(), conf.getByteList("empty"));
800     }
801 
802     @Test
803     void testGetCalendar() throws Exception {
804         final DateFormat format = new SimpleDateFormat(DATE_PATTERN);
805 
806         // missing Date
807         final Calendar defaultValue = Calendar.getInstance();
808         defaultValue.setTime(new Date());
809         assertEquals(conf.getCalendar("calendar", defaultValue), defaultValue);
810         assertNull(conf.getCalendar("unknownkey", DATE_PATTERN));
811 
812         conf.setThrowExceptionOnMissing(true);
813 
814         assertThrows(NoSuchElementException.class, () -> conf.getCalendar("unknownkey", DATE_PATTERN));
815 
816         final Calendar expected = Calendar.getInstance();
817         expected.setTime(format.parse("2004-01-01"));
818 
819         // Calendar string
820         assertEquals(expected, conf.getCalendar("calendar.string"));
821         assertEquals(conf.getCalendar("calendar.string", DATE_PATTERN), expected);
822 
823         // Calendar object
824         assertEquals(expected, conf.getCalendar("calendar.object"));
825 
826         // Date object
827         assertEquals(expected, conf.getCalendar("date.object"));
828 
829         // interpolated value
830         assertEquals(expected, conf.getCalendar("calendar.string.interpolated"));
831     }
832 
833     @Test
834     void testGetCalendarArray() throws Exception {
835         final DateFormat format = new SimpleDateFormat(DATE_PATTERN);
836         final Date date1 = format.parse("2004-01-01");
837         final Date date2 = format.parse("2004-12-31");
838         final Calendar calendar1 = Calendar.getInstance();
839         calendar1.setTime(date1);
840         final Calendar calendar2 = Calendar.getInstance();
841         calendar2.setTime(date2);
842 
843         // missing list
844         final Calendar[] defaultValue = {calendar2, calendar1};
845         assertArrayEquals(defaultValue, conf.getCalendarArray("calendar.list", defaultValue));
846 
847         final Calendar[] expected = {calendar1, calendar2};
848 
849         // list of strings
850         assertArrayEquals(expected, conf.getCalendarArray("calendar.list1"));
851 
852         // list of strings, comma separated
853         assertArrayEquals(expected, conf.getCalendarArray("calendar.list2"));
854 
855         // list of Calendar objects
856         assertArrayEquals(expected, conf.getCalendarArray("calendar.list3"));
857 
858         // array of Calendar objects
859         assertArrayEquals(expected, conf.getCalendarArray("calendar.list4"));
860 
861         // list of Date objects
862         assertArrayEquals(expected, conf.getCalendarArray("calendar.list5"));
863 
864         // list of Calendar objects
865         assertArrayEquals(expected, conf.getCalendarArray("calendar.list6"));
866 
867         // list of interpolated values
868         assertArrayEquals(expected, conf.getCalendarArray("calendar.list.interpolated"));
869 
870         // single Calendar values
871         assertArrayEquals(new Calendar[] {calendar1}, conf.getCalendarArray("calendar.string"));
872         assertArrayEquals(new Calendar[] {calendar1}, conf.getCalendarArray("calendar.object"));
873 
874         // empty array
875         assertArrayEquals(new Calendar[] {}, conf.getCalendarArray("empty"));
876     }
877 
878     @Test
879     void testGetCalendarArrayWithFormat() throws Exception {
880         final DateFormat format = new SimpleDateFormat("MM/dd/yyyy");
881         final Date date1 = format.parse("01/01/2004");
882         final Date date2 = format.parse("12/31/2004");
883 
884         final Calendar calendar1 = Calendar.getInstance();
885         calendar1.setTime(date1);
886         final Calendar calendar2 = Calendar.getInstance();
887         calendar2.setTime(date2);
888         final Calendar[] expected = {calendar1, calendar2};
889 
890         conf.addProperty("calendar.format", "01/01/2004");
891         conf.addProperty("calendar.format", "12/31/2004");
892         assertArrayEquals(expected, conf.getCalendarArray("calendar.format", "MM/dd/yyyy"));
893     }
894 
895     @Test
896     void testGetCalendarList() throws Exception {
897         final DateFormat format = new SimpleDateFormat(DATE_PATTERN);
898         final Date date1 = format.parse("2004-01-01");
899         final Date date2 = format.parse("2004-12-31");
900         final Calendar calendar1 = Calendar.getInstance();
901         calendar1.setTime(date1);
902         final Calendar calendar2 = Calendar.getInstance();
903         calendar2.setTime(date2);
904 
905         // missing list
906         final List<Calendar> nullList = null;
907         assertNull(conf.getCalendarList("calendar.list", nullList));
908 
909         List<Object> expected = new ArrayList<>();
910         expected.add(calendar1);
911         expected.add(calendar2);
912 
913         // list of strings
914         assertEquals(expected, conf.getCalendarList("calendar.list1"));
915         assertEquals(conf.getList(Calendar.class, "calendar.list1"), expected);
916 
917         // list of strings, comma separated
918         assertEquals(expected, conf.getCalendarList("calendar.list2"));
919 
920         // list of Calendar objects
921         assertEquals(expected, conf.getCalendarList("calendar.list3"));
922 
923         // array of Calendar objects
924         assertEquals(expected, conf.getCalendarList("calendar.list4"));
925 
926         // list of Date objects
927         assertEquals(expected, conf.getCalendarList("calendar.list5"));
928 
929         // list of Calendar objects
930         assertEquals(expected, conf.getCalendarList("calendar.list6"));
931 
932         // array of strings
933         assertEquals(conf.getList(Calendar.class, "calendar.list7"), expected);
934 
935         // list of interpolated values
936         assertEquals(expected, conf.getCalendarList("calendar.list.interpolated"));
937 
938         // single Calendar values
939         expected = new ArrayList<>();
940         expected.add(calendar1);
941         assertEquals(expected, conf.getCalendarList("date.string"));
942         assertEquals(expected, conf.getCalendarList("date.object"));
943 
944         // empty list
945         assertEquals(new ArrayList<>(), conf.getCalendarList("empty"));
946     }
947 
948     @Test
949     void testGetColor() {
950         // RRGGBB
951         conf.setProperty("color", "FF0000");
952         assertEquals(Color.red, conf.getColor("color"));
953 
954         // #RRGGBB
955         conf.setProperty("color", "#00FF00");
956         assertEquals(Color.green, conf.getColor("color"));
957 
958         // #RRGGBBAA
959         conf.setProperty("color", "#01030507");
960         final Color color = conf.getColor("color");
961         assertNotNull(color);
962         assertEquals(1, color.getRed());
963         assertEquals(3, color.getGreen());
964         assertEquals(5, color.getBlue());
965         assertEquals(7, color.getAlpha());
966 
967         // interpolated value
968         assertEquals(Color.red, conf.getColor("color.string.interpolated"));
969 
970         // default value
971         assertEquals(Color.cyan, conf.getColor("unknownkey", Color.cyan));
972     }
973 
974     @Test
975     void testGetColorArray() throws Exception {
976         // missing list
977         final Color[] defaultValue = {Color.red, Color.blue};
978         assertArrayEquals(defaultValue, conf.getColorArray("color.list", defaultValue));
979 
980         final Color[] expected = {Color.red, Color.blue};
981 
982         // list of strings
983         assertArrayEquals(expected, conf.getColorArray("color.list1"));
984 
985         // list of strings, comma separated
986         assertArrayEquals(expected, conf.getColorArray("color.list2"));
987 
988         // list of Color objects
989         assertArrayEquals(expected, conf.getColorArray("color.list3"));
990 
991         // array of Color objects
992         assertArrayEquals(expected, conf.getColorArray("color.list4"));
993 
994         // list of Color objects
995         assertArrayEquals(expected, conf.getColorArray("color.list6"));
996 
997         // list of interpolated values
998         assertArrayEquals(expected, conf.getColorArray("color.list.interpolated"));
999 
1000         // single Color values
1001         assertArrayEquals(new Color[] {Color.red}, conf.getColorArray("color.string"));
1002         assertArrayEquals(new Color[] {Color.red}, conf.getColorArray("color.object"));
1003 
1004         // empty array
1005         assertArrayEquals(new Color[] {}, conf.getColorArray("empty"));
1006     }
1007 
1008     @Test
1009     void testGetColorList() throws Exception {
1010         // missing list
1011         assertNull(conf.getColorList("color.list", null));
1012 
1013         List<Object> expected = new ArrayList<>();
1014         expected.add(Color.red);
1015         expected.add(Color.blue);
1016 
1017         // list of strings
1018         assertEquals(expected, conf.getColorList("color.list1"));
1019 
1020         // list of strings, comma separated
1021         assertEquals(expected, conf.getColorList("color.list2"));
1022 
1023         // list of Color objects
1024         assertEquals(expected, conf.getColorList("color.list3"));
1025 
1026         // array of Color objects
1027         assertEquals(expected, conf.getColorList("color.list4"));
1028 
1029         // list of Color objects
1030         assertEquals(expected, conf.getColorList("color.list6"));
1031 
1032         // list of interpolated values
1033         assertEquals(expected, conf.getColorList("color.list.interpolated"));
1034 
1035         // single Color values
1036         expected = new ArrayList<>();
1037         expected.add(Color.red);
1038         assertEquals(expected, conf.getColorList("color.string"));
1039         assertEquals(expected, conf.getColorList("color.object"));
1040 
1041         // empty list
1042         assertEquals(new ArrayList<>(), conf.getColorList("empty"));
1043     }
1044 
1045     @Test
1046     void testGetConfiguration() {
1047         final Configuration baseconf = new BaseConfiguration();
1048         final DataConfiguration conf = new DataConfiguration(baseconf);
1049 
1050         assertEquals(baseconf, conf.getConfiguration());
1051     }
1052 
1053     @Test
1054     void testGetDate() throws Exception {
1055         final Date expected = expectedDate();
1056 
1057         // missing Date
1058         final Date defaultValue = new Date();
1059         assertEquals(conf.getDate("date", defaultValue), defaultValue);
1060         assertNull(conf.getDate("unknownkey", DATE_PATTERN));
1061 
1062         conf.setThrowExceptionOnMissing(true);
1063 
1064         assertThrows(NoSuchElementException.class, () -> conf.getDate("unknownkey", DATE_PATTERN));
1065 
1066         // Date string
1067         assertEquals(expected, conf.getDate("date.string"));
1068         assertEquals(conf.getDate("date.string", DATE_PATTERN), expected);
1069 
1070         // Date object
1071         assertEquals(expected, conf.getDate("date.object"));
1072 
1073         // Calendar object
1074         assertEquals(expected, conf.getDate("calendar.object"));
1075 
1076         // interpolated value
1077         assertEquals(expected, conf.getDate("date.string.interpolated"));
1078     }
1079 
1080     @Test
1081     void testGetDateArray() throws Exception {
1082         final DateFormat format = new SimpleDateFormat(DATE_PATTERN);
1083         final Date date1 = format.parse("2004-01-01");
1084         final Date date2 = format.parse("2004-12-31");
1085 
1086         // missing list
1087         final Date[] defaultValue = {date2, date1};
1088         assertArrayEquals(defaultValue, conf.getDateArray("date.list", defaultValue));
1089 
1090         final Date[] expected = {date1, date2};
1091 
1092         // list of strings
1093         assertArrayEquals(expected, conf.getDateArray("date.list1"));
1094 
1095         // list of strings, comma separated
1096         assertArrayEquals(expected, conf.getDateArray("date.list2"));
1097 
1098         // list of Date objects
1099         assertArrayEquals(expected, conf.getDateArray("date.list3"));
1100 
1101         // array of Date objects
1102         assertArrayEquals(expected, conf.getDateArray("date.list4"));
1103 
1104         // list of Calendar objects
1105         assertArrayEquals(expected, conf.getDateArray("date.list5"));
1106 
1107         // list of Date objects
1108         assertArrayEquals(expected, conf.getDateArray("date.list6"));
1109 
1110         // list of interpolated values
1111         assertArrayEquals(expected, conf.getDateArray("date.list.interpolated"));
1112 
1113         // single Date values
1114         assertArrayEquals(new Date[] {date1}, conf.getDateArray("date.string"));
1115         assertArrayEquals(new Date[] {date1}, conf.getDateArray("date.object"));
1116 
1117         // empty array
1118         assertArrayEquals(new Date[] {}, conf.getDateArray("empty"));
1119     }
1120 
1121     @Test
1122     void testGetDateArrayWithFormat() throws Exception {
1123         final DateFormat format = new SimpleDateFormat("MM/dd/yyyy");
1124         final Date date1 = format.parse("01/01/2004");
1125         final Date date2 = format.parse("12/31/2004");
1126         final Date[] expected = {date1, date2};
1127 
1128         conf.addProperty("date.format", "01/01/2004");
1129         conf.addProperty("date.format", "12/31/2004");
1130         assertArrayEquals(expected, conf.getDateArray("date.format", "MM/dd/yyyy"));
1131     }
1132 
1133     @Test
1134     void testGetDateList() throws Exception {
1135         final DateFormat format = new SimpleDateFormat(DATE_PATTERN);
1136         final Date date1 = format.parse("2004-01-01");
1137         final Date date2 = format.parse("2004-12-31");
1138 
1139         // missing list
1140         final List<Date> nullList = null;
1141         assertNull(conf.getDateList("date.list", nullList));
1142 
1143         List<Object> expected = new ArrayList<>();
1144         expected.add(date1);
1145         expected.add(date2);
1146 
1147         // list of strings
1148         assertEquals(expected, conf.getDateList("date.list1"));
1149         assertEquals(conf.getList(Date.class, "date.list1"), expected);
1150 
1151         // list of strings, comma separated
1152         assertEquals(expected, conf.getDateList("date.list2"));
1153 
1154         // list of Date objects
1155         assertEquals(expected, conf.getDateList("date.list3"));
1156 
1157         // array of Date objects
1158         assertEquals(expected, conf.getDateList("date.list4"));
1159 
1160         // list of Calendar objects
1161         assertEquals(expected, conf.getDateList("date.list5"));
1162 
1163         // list of Date objects
1164         assertEquals(expected, conf.getDateList("date.list6"));
1165 
1166         // array of strings
1167         assertEquals(conf.getList(Date.class, "date.list7"), expected);
1168 
1169         // list of interpolated values
1170         assertEquals(expected, conf.getDateList("date.list.interpolated"));
1171 
1172         // single Date values
1173         expected = new ArrayList<>();
1174         expected.add(date1);
1175         assertEquals(expected, conf.getDateList("date.string"));
1176         assertEquals(expected, conf.getDateList("date.object"));
1177 
1178         // empty list
1179         assertEquals(new ArrayList<>(), conf.getDateList("empty"));
1180     }
1181 
1182     /**
1183      * Tests a conversion to a Date if no property is set with the date format, and the format is specified in the
1184      * conversion handler.
1185      */
1186     @Test
1187     void testGetDateNoFormatPropertyConversionHandler() throws Exception {
1188         conf.clearProperty(DataConfiguration.DATE_FORMAT_KEY);
1189         final DefaultConversionHandler handler = new DefaultConversionHandler();
1190         handler.setDateFormat(DATE_PATTERN);
1191         conf.setConversionHandler(handler);
1192         assertEquals(expectedDate(), conf.getDate("date.string"));
1193     }
1194 
1195     /**
1196      * Tests a conversion to a Date if no property is set with the date format, and the format is directly passed in.
1197      */
1198     @Test
1199     void testGetDateNoFormatPropertyDirectlySpecified() throws Exception {
1200         conf.clearProperty(DataConfiguration.DATE_FORMAT_KEY);
1201         assertEquals(expectedDate(), conf.getDate("date.string", DATE_PATTERN));
1202     }
1203 
1204     @Test
1205     void testGetDoubleArray() {
1206         // missing list
1207         final double[] defaultValue = {2, 1};
1208         assertArrayEquals(defaultValue, conf.getDoubleArray("double.list", defaultValue), 0);
1209 
1210         final double[] expected = {1, 2};
1211 
1212         // list of strings
1213         assertArrayEquals(expected, conf.getDoubleArray("double.list1"), 0);
1214 
1215         // list of strings, comma separated
1216         assertArrayEquals(expected, conf.getDoubleArray("double.list2"), 0);
1217 
1218         // list of Double objects
1219         assertArrayEquals(expected, conf.getDoubleArray("double.list3"), 0);
1220 
1221         // array of Double objects
1222         assertArrayEquals(expected, conf.getDoubleArray("double.list4"), 0);
1223 
1224         // array of double primitives
1225         assertArrayEquals(expected, conf.getDoubleArray("double.list5"), 0);
1226 
1227         // list of Double objects
1228         assertArrayEquals(expected, conf.getDoubleArray("double.list6"), 0);
1229 
1230         // list of interpolated values
1231         assertArrayEquals(expected, conf.getDoubleArray("double.list.interpolated"), 0);
1232 
1233         // single double values
1234         assertArrayEquals(new double[] {1}, conf.getDoubleArray("double.string"), 0);
1235         assertArrayEquals(new double[] {1}, conf.getDoubleArray("double.object"), 0);
1236 
1237         // empty array
1238         assertArrayEquals(new double[] {}, conf.getDoubleArray("empty"), 0);
1239     }
1240 
1241     @Test
1242     void testGetDoubleList() {
1243         // missing list
1244         assertNull(conf.getDoubleList("double.list", null));
1245 
1246         List<Object> expected = new ArrayList<>();
1247         expected.add(Double.valueOf("1"));
1248         expected.add(Double.valueOf("2"));
1249 
1250         // list of strings
1251         assertEquals(expected, conf.getDoubleList("double.list1"));
1252 
1253         // list of strings, comma separated
1254         assertEquals(expected, conf.getDoubleList("double.list2"));
1255 
1256         // list of Double objects
1257         assertEquals(expected, conf.getDoubleList("double.list3"));
1258 
1259         // array of Double objects
1260         assertEquals(expected, conf.getDoubleList("double.list4"));
1261 
1262         // array of double primitives
1263         assertEquals(expected, conf.getDoubleList("double.list5"));
1264 
1265         // list of Double objects
1266         assertEquals(expected, conf.getDoubleList("double.list6"));
1267 
1268         // list of interpolated values
1269         assertEquals(expected, conf.getDoubleList("double.list.interpolated"));
1270 
1271         // single double values
1272         expected = new ArrayList<>();
1273         expected.add(Double.valueOf("1"));
1274         assertEquals(expected, conf.getDoubleList("double.string"));
1275         assertEquals(expected, conf.getDoubleList("double.object"));
1276 
1277         // empty list
1278         assertEquals(new ArrayList<>(), conf.getDoubleList("empty"));
1279     }
1280 
1281     @Test
1282     void testGetFloatArray() {
1283         // missing list
1284         final float[] defaultValue = {2, 1};
1285         assertArrayEquals(defaultValue, conf.getFloatArray("float.list", defaultValue), 0);
1286 
1287         final float[] expected = {1, 2};
1288 
1289         // list of strings
1290         assertArrayEquals(expected, conf.getFloatArray("float.list1"), 0);
1291 
1292         // list of strings, comma separated
1293         assertArrayEquals(expected, conf.getFloatArray("float.list2"), 0);
1294 
1295         // list of Float objects
1296         assertArrayEquals(expected, conf.getFloatArray("float.list3"), 0);
1297 
1298         // array of Float objects
1299         assertArrayEquals(expected, conf.getFloatArray("float.list4"), 0);
1300 
1301         // array of float primitives
1302         assertArrayEquals(expected, conf.getFloatArray("float.list5"), 0);
1303 
1304         // list of Float objects
1305         assertArrayEquals(expected, conf.getFloatArray("float.list6"), 0);
1306 
1307         // list of interpolated values
1308         assertArrayEquals(expected, conf.getFloatArray("float.list.interpolated"), 0);
1309 
1310         // single float values
1311         assertArrayEquals(new float[] {1}, conf.getFloatArray("float.string"), 0);
1312         assertArrayEquals(new float[] {1}, conf.getFloatArray("float.object"), 0);
1313 
1314         // empty array
1315         assertArrayEquals(new float[] {}, conf.getFloatArray("empty"), 0);
1316     }
1317 
1318     @Test
1319     void testGetFloatList() {
1320         // missing list
1321         assertNull(conf.getFloatList("float.list", null));
1322 
1323         List<Object> expected = new ArrayList<>();
1324         expected.add(Float.valueOf("1"));
1325         expected.add(Float.valueOf("2"));
1326 
1327         // list of strings
1328         assertEquals(expected, conf.getFloatList("float.list1"));
1329 
1330         // list of strings, comma separated
1331         assertEquals(expected, conf.getFloatList("float.list2"));
1332 
1333         // list of Float objects
1334         assertEquals(expected, conf.getFloatList("float.list3"));
1335 
1336         // array of Float objects
1337         assertEquals(expected, conf.getFloatList("float.list4"));
1338 
1339         // array of float primitives
1340         assertEquals(expected, conf.getFloatList("float.list5"));
1341 
1342         // list of Float objects
1343         assertEquals(expected, conf.getFloatList("float.list6"));
1344 
1345         // list of interpolated values
1346         assertEquals(expected, conf.getFloatList("float.list.interpolated"));
1347 
1348         // single float values
1349         expected = new ArrayList<>();
1350         expected.add(Float.valueOf("1"));
1351         assertEquals(expected, conf.getFloatList("float.string"));
1352         assertEquals(expected, conf.getFloatList("float.object"));
1353 
1354         // empty list
1355         assertEquals(new ArrayList<>(), conf.getFloatList("empty"));
1356     }
1357 
1358     @Test
1359     void testGetInetAddress() throws Exception {
1360         final InetAddress expected = InetAddress.getByName("127.0.0.1");
1361 
1362         // address as string
1363         assertEquals(conf.get(InetAddress.class, "ip.string"), expected);
1364 
1365         // address object
1366         assertEquals(conf.get(InetAddress.class, "ip.object"), expected);
1367 
1368         // interpolated value
1369         assertEquals(conf.get(InetAddress.class, "ip.string.interpolated"), expected);
1370     }
1371 
1372     @Test
1373     void testGetInetAddressInvalidType() {
1374         conf.setProperty("ip.unknownhost", "foo");
1375         assertThrows(ConversionException.class, () -> conf.get(InetAddress.class, "ip.unknownhost"));
1376     }
1377 
1378     @Test
1379     void testGetIntegerArray() {
1380         // missing list
1381         final int[] defaultValue = {2, 1};
1382         assertArrayEquals(conf.getIntArray("integer.list", defaultValue), defaultValue);
1383 
1384         final int[] expected = {1, 2};
1385 
1386         // list of strings
1387         assertArrayEquals(expected, conf.getIntArray("integer.list1"));
1388 
1389         // list of strings, comma separated
1390         assertArrayEquals(expected, conf.getIntArray("integer.list2"));
1391 
1392         // list of Integer objects
1393         assertArrayEquals(expected, conf.getIntArray("integer.list3"));
1394 
1395         // array of Integer objects
1396         assertArrayEquals(expected, conf.getIntArray("integer.list4"));
1397 
1398         // array of int primitives
1399         assertArrayEquals(expected, conf.getIntArray("integer.list5"));
1400 
1401         // list of Integer objects
1402         assertArrayEquals(expected, conf.getIntArray("integer.list6"));
1403 
1404         // list of interpolated values
1405         assertArrayEquals(expected, conf.getIntArray("integer.list.interpolated"));
1406 
1407         // single int values
1408         assertArrayEquals(new int[] {1}, conf.getIntArray("integer.string"));
1409         assertArrayEquals(new int[] {1}, conf.getIntArray("integer.object"));
1410 
1411         // empty array
1412         assertArrayEquals(new int[] {}, conf.getIntArray("empty"));
1413     }
1414 
1415     @Test
1416     void testGetIntegerList() {
1417         // missing list
1418         assertNull(conf.getIntegerList("integer.list", null));
1419 
1420         List<Object> expected = new ArrayList<>();
1421         expected.add(Integer.valueOf("1"));
1422         expected.add(Integer.valueOf("2"));
1423 
1424         // list of strings
1425         assertEquals(expected, conf.getIntegerList("integer.list1"));
1426 
1427         // list of strings, comma separated
1428         assertEquals(expected, conf.getIntegerList("integer.list2"));
1429 
1430         // list of Integer objects
1431         assertEquals(expected, conf.getIntegerList("integer.list3"));
1432 
1433         // array of Integer objects
1434         assertEquals(expected, conf.getIntegerList("integer.list4"));
1435 
1436         // array of int primitives
1437         assertEquals(expected, conf.getIntegerList("integer.list5"));
1438 
1439         // list of Integer objects
1440         assertEquals(expected, conf.getIntegerList("integer.list6"));
1441 
1442         // list of interpolated values
1443         assertEquals(expected, conf.getIntegerList("integer.list.interpolated"));
1444 
1445         // single int values
1446         expected = new ArrayList<>();
1447         expected.add(Integer.valueOf("1"));
1448         assertEquals(expected, conf.getIntegerList("integer.string"));
1449         assertEquals(expected, conf.getIntegerList("integer.object"));
1450 
1451         // empty list
1452         assertEquals(new ArrayList<>(), conf.getIntegerList("empty"));
1453     }
1454 
1455     @Test
1456     void testGetInternetAddress() throws Exception {
1457         final Object expected = new InternetAddress("dev@test.org");
1458 
1459         // address as string
1460         assertEquals(conf.get(expected.getClass(), "email.string"), expected);
1461 
1462         // address object
1463         assertEquals(conf.get(expected.getClass(), "email.object"), expected);
1464 
1465         // interpolated value
1466         assertEquals(conf.get(expected.getClass(), "email.string.interpolated"), expected);
1467 
1468         conf.setProperty("email.invalid", "dev@test@org");
1469         assertThrows(ConversionException.class, () -> conf.get(expected.getClass(), "email.invalid"));
1470     }
1471 
1472     @Test
1473     void testGetInternetAddressInvalidType() throws Exception {
1474         final Object expected = new InternetAddress("dev@test.org");
1475         conf.setProperty("email.invalid", "dev@test@org");
1476         assertThrows(ConversionException.class, () -> conf.get(expected.getClass(), "email.invalid"));
1477     }
1478 
1479     @Test
1480     void testGetInvalidType() {
1481         assertThrows(ConversionException.class, () -> conf.get(Boolean.class, "url.object", null));
1482     }
1483 
1484     @Test
1485     void testGetKeys() {
1486         final Configuration baseconf = new BaseConfiguration();
1487         final DataConfiguration conf = new DataConfiguration(baseconf);
1488 
1489         baseconf.setProperty("foo", "bar");
1490 
1491         final Iterator<String> it = conf.getKeys();
1492         assertTrue(it.hasNext());
1493         assertEquals("foo", it.next());
1494         assertFalse(it.hasNext());
1495     }
1496 
1497     @Test
1498     void testGetLocale() {
1499         // language
1500         conf.setProperty("locale", "fr");
1501         assertEquals(new Locale("fr", ""), conf.getLocale("locale"));
1502 
1503         // language + variant
1504         conf.setProperty("locale", "fr__POSIX");
1505         assertEquals(new Locale("fr", "", "POSIX"), conf.getLocale("locale"));
1506 
1507         // country
1508         conf.setProperty("locale", "_FR");
1509         assertEquals(new Locale("", "FR"), conf.getLocale("locale"));
1510 
1511         // country + variant
1512         conf.setProperty("locale", "_FR_WIN");
1513         assertEquals(new Locale("", "FR", "WIN"), conf.getLocale("locale"));
1514 
1515         // language + country
1516         conf.setProperty("locale", "fr_FR");
1517         assertEquals(new Locale("fr", "FR"), conf.getLocale("locale"));
1518 
1519         // language + country + variant
1520         conf.setProperty("locale", "fr_FR_MAC");
1521         assertEquals(new Locale("fr", "FR", "MAC"), conf.getLocale("locale"));
1522 
1523         // default value
1524         conf.setProperty("locale", "fr");
1525         assertEquals(Locale.FRENCH, conf.getLocale("locale", Locale.GERMAN));
1526         assertEquals(Locale.GERMAN, conf.getLocale("localeNotInConfig", Locale.GERMAN));
1527 
1528         // interpolated value
1529         assertEquals(Locale.FRENCH, conf.getLocale("locale.string.interpolated"));
1530     }
1531 
1532     @Test
1533     void testGetLocaleArray() throws Exception {
1534         // missing list
1535         final Locale[] defaultValue = {Locale.GERMAN, Locale.FRENCH};
1536         assertArrayEquals(conf.getLocaleArray("locale.list", defaultValue), defaultValue);
1537 
1538         final Locale[] expected = {Locale.FRENCH, Locale.GERMAN};
1539 
1540         // list of strings
1541         assertArrayEquals(expected, conf.getLocaleArray("locale.list1"));
1542 
1543         // list of strings, comma separated
1544         assertArrayEquals(expected, conf.getLocaleArray("locale.list2"));
1545 
1546         // list of Locale objects
1547         assertArrayEquals(expected, conf.getLocaleArray("locale.list3"));
1548 
1549         // array of Locale objects
1550         assertArrayEquals(expected, conf.getLocaleArray("locale.list4"));
1551 
1552         // list of Locale objects
1553         assertArrayEquals(expected, conf.getLocaleArray("locale.list6"));
1554 
1555         // list of interpolated values
1556         assertArrayEquals(expected, conf.getLocaleArray("locale.list.interpolated"));
1557 
1558         // single Locale values
1559         assertArrayEquals(new Locale[] {Locale.FRENCH}, conf.getLocaleArray("locale.string"));
1560         assertArrayEquals(new Locale[] {Locale.FRENCH}, conf.getLocaleArray("locale.object"));
1561 
1562         // empty array
1563         assertArrayEquals(new Locale[] {}, conf.getLocaleArray("empty"));
1564     }
1565 
1566     @Test
1567     void testGetLocaleList() throws Exception {
1568         // missing list
1569         assertNull(conf.getLocaleList("locale.list", null));
1570 
1571         List<Object> expected = new ArrayList<>();
1572         expected.add(Locale.FRENCH);
1573         expected.add(Locale.GERMAN);
1574 
1575         // list of strings
1576         assertEquals(expected, conf.getLocaleList("locale.list1"));
1577 
1578         // list of strings, comma separated
1579         assertEquals(expected, conf.getLocaleList("locale.list2"));
1580 
1581         // list of Locale objects
1582         assertEquals(expected, conf.getLocaleList("locale.list3"));
1583 
1584         // array of Locale objects
1585         assertEquals(expected, conf.getLocaleList("locale.list4"));
1586 
1587         // list of Locale objects
1588         assertEquals(expected, conf.getLocaleList("locale.list6"));
1589 
1590         // list of interpolated values
1591         assertEquals(expected, conf.getLocaleList("locale.list.interpolated"));
1592 
1593         // single Locale values
1594         expected = new ArrayList<>();
1595         expected.add(Locale.FRENCH);
1596         assertEquals(expected, conf.getLocaleList("locale.string"));
1597         assertEquals(expected, conf.getLocaleList("locale.object"));
1598 
1599         // empty list
1600         assertEquals(new ArrayList<>(), conf.getLocaleList("empty"));
1601     }
1602 
1603     @Test
1604     void testGetLongArray() {
1605         // missing list
1606         final long[] defaultValue = {2, 1};
1607         assertArrayEquals(conf.getLongArray("long.list", defaultValue), defaultValue);
1608 
1609         final long[] expected = {1, 2};
1610 
1611         // list of strings
1612         assertArrayEquals(expected, conf.getLongArray("long.list1"));
1613 
1614         // list of strings, comma separated
1615         assertArrayEquals(expected, conf.getLongArray("long.list2"));
1616 
1617         // list of Long objects
1618         assertArrayEquals(expected, conf.getLongArray("long.list3"));
1619 
1620         // array of Long objects
1621         assertArrayEquals(expected, conf.getLongArray("long.list4"));
1622 
1623         // array of long primitives
1624         assertArrayEquals(expected, conf.getLongArray("long.list5"));
1625 
1626         // list of Long objects
1627         assertArrayEquals(expected, conf.getLongArray("long.list6"));
1628 
1629         // list of interpolated values
1630         assertArrayEquals(expected, conf.getLongArray("long.list.interpolated"));
1631 
1632         // single long values
1633         assertArrayEquals(new long[] {1}, conf.getLongArray("long.string"));
1634         assertArrayEquals(new long[] {1}, conf.getLongArray("long.object"));
1635 
1636         // empty array
1637         assertArrayEquals(new long[] {}, conf.getLongArray("empty"));
1638     }
1639 
1640     @Test
1641     void testGetLongList() {
1642         // missing list
1643         assertNull(conf.getLongList("long.list", null));
1644 
1645         List<Object> expected = new ArrayList<>();
1646         expected.add(Long.valueOf("1"));
1647         expected.add(Long.valueOf("2"));
1648 
1649         // list of strings
1650         assertEquals(expected, conf.getLongList("long.list1"));
1651 
1652         // list of strings, comma separated
1653         assertEquals(expected, conf.getLongList("long.list2"));
1654 
1655         // list of Long objects
1656         assertEquals(expected, conf.getLongList("long.list3"));
1657 
1658         // array of Long objects
1659         assertEquals(expected, conf.getLongList("long.list4"));
1660 
1661         // array of long primitives
1662         assertEquals(expected, conf.getLongList("long.list5"));
1663 
1664         // list of Long objects
1665         assertEquals(expected, conf.getLongList("long.list6"));
1666 
1667         // list of interpolated values
1668         assertEquals(expected, conf.getLongList("long.list.interpolated"));
1669 
1670         // single long values
1671         expected = new ArrayList<>();
1672         expected.add(Long.valueOf("1"));
1673         assertEquals(expected, conf.getLongList("long.string"));
1674         assertEquals(expected, conf.getLongList("long.object"));
1675 
1676         // empty list
1677         assertEquals(new ArrayList<>(), conf.getLongList("empty"));
1678     }
1679 
1680     @Test
1681     void testGetPrimitiveArrayInvalidType() {
1682         assertThrows(ConversionException.class, () -> conf.getArray(Boolean.TYPE, "calendar.list4"));
1683     }
1684 
1685     /**
1686      * Tests whether a string property can be obtained through get() if no type conversion is required.
1687      */
1688     @Test
1689     void testGetPropertyWithoutConversion() {
1690         final String key = "test.str";
1691         final String value = "someTestValue";
1692         conf.addProperty(key, value);
1693         assertEquals(value, conf.get(String.class, key));
1694     }
1695 
1696     @Test
1697     void testGetShortArray() {
1698         // missing list
1699         final short[] defaultValue = {2, 1};
1700         assertArrayEquals(conf.getShortArray("short.list", defaultValue), defaultValue);
1701 
1702         final short[] expected = {1, 2};
1703 
1704         // list of strings
1705         assertArrayEquals(expected, conf.getShortArray("short.list1"));
1706 
1707         // list of strings, comma separated
1708         assertArrayEquals(expected, conf.getShortArray("short.list2"));
1709 
1710         // list of Byte objects
1711         assertArrayEquals(expected, conf.getShortArray("short.list3"));
1712 
1713         // array of Byte objects
1714         assertArrayEquals(expected, conf.getShortArray("short.list4"));
1715 
1716         // array of byte primitives
1717         assertArrayEquals(expected, conf.getShortArray("short.list5"));
1718 
1719         // list of Byte objects
1720         assertArrayEquals(expected, conf.getShortArray("short.list6"));
1721 
1722         // list of interpolated values
1723         assertArrayEquals(expected, conf.getShortArray("short.list.interpolated"));
1724 
1725         // single byte values
1726         assertArrayEquals(new short[] {1}, conf.getShortArray("short.string"));
1727         assertArrayEquals(new short[] {1}, conf.getShortArray("short.object"));
1728 
1729         // empty array
1730         assertArrayEquals(new short[] {}, conf.getShortArray("empty"));
1731     }
1732 
1733     @Test
1734     void testGetShortList() {
1735         // missing list
1736         assertNull(conf.getShortList("short.list", null));
1737 
1738         List<Object> expected = new ArrayList<>();
1739         expected.add(Short.valueOf("1"));
1740         expected.add(Short.valueOf("2"));
1741 
1742         // list of strings
1743         assertEquals(expected, conf.getShortList("short.list1"));
1744 
1745         // list of strings, comma separated
1746         assertEquals(expected, conf.getShortList("short.list2"));
1747 
1748         // list of Short objects
1749         assertEquals(expected, conf.getShortList("short.list3"));
1750 
1751         // array of Short objects
1752         assertEquals(expected, conf.getShortList("short.list4"));
1753 
1754         // array of short primitives
1755         assertEquals(expected, conf.getShortList("short.list5"));
1756 
1757         // list of Short objects
1758         assertEquals(expected, conf.getShortList("short.list6"));
1759 
1760         // list of interpolated values
1761         assertEquals(expected, conf.getShortList("short.list.interpolated"));
1762 
1763         // single short values
1764         expected = new ArrayList<>();
1765         expected.add(Short.valueOf("1"));
1766         assertEquals(expected, conf.getShortList("short.string"));
1767         assertEquals(expected, conf.getShortList("short.object"));
1768 
1769         // empty list
1770         assertEquals(new ArrayList<>(), conf.getShortList("empty"));
1771     }
1772 
1773     @Test
1774     void testGetUnknown() {
1775         assertNull(conf.get(Object.class, "unknownkey"));
1776     }
1777 
1778     @Test
1779     void testGetUnknownException() {
1780         conf.setThrowExceptionOnMissing(true);
1781         assertThrows(NoSuchElementException.class, () -> conf.get(Object.class, "unknownkey"));
1782     }
1783 
1784     @Test
1785     void testGetURI() throws Exception {
1786         // missing URI
1787         final URI defaultValue = new URI("http://www.google.com");
1788         assertEquals(conf.getURI("url", defaultValue), defaultValue);
1789 
1790         final URI expected = new URI("http://jakarta.apache.org");
1791 
1792         // URI string
1793         assertEquals(expected, conf.getURI("uri.string"));
1794 
1795         // URI object
1796         assertEquals(expected, conf.getURI("uri.object"));
1797 
1798         // interpolated value
1799         assertEquals(expected, conf.getURI("uri.string.interpolated"));
1800     }
1801 
1802     @Test
1803     void testGetURIArray() throws Exception {
1804         // missing list
1805         final URI[] defaultValue = {new URI("http://www.apache.org"), new URI("http://jakarta.apache.org")};
1806         assertArrayEquals(conf.getURIArray("url.list", defaultValue), defaultValue);
1807 
1808         final URI[] expected = {new URI("http://jakarta.apache.org"), new URI("http://www.apache.org")};
1809 
1810         // list of strings
1811         assertArrayEquals(expected, conf.getURIArray("uri.list1"));
1812 
1813         // list of strings, comma separated
1814         assertArrayEquals(expected, conf.getURIArray("uri.list2"));
1815 
1816         // list of URI objects
1817         assertArrayEquals(expected, conf.getURIArray("uri.list3"));
1818 
1819         // array of URI objects
1820         assertArrayEquals(expected, conf.getURIArray("uri.list4"));
1821 
1822         // list of URI objects
1823         assertArrayEquals(expected, conf.getURIArray("uri.list6"));
1824 
1825         // list of interpolated values
1826         assertArrayEquals(expected, conf.getURIArray("uri.list.interpolated"));
1827 
1828         // single URI values
1829         assertArrayEquals(new URI[] {new URI("http://jakarta.apache.org")}, conf.getURIArray("uri.string"));
1830         assertArrayEquals(new URI[] {new URI("http://jakarta.apache.org")}, conf.getURIArray("uri.object"));
1831 
1832         // empty array
1833         assertArrayEquals(new URI[] {}, conf.getURIArray("empty"));
1834     }
1835 
1836     @Test
1837     void testGetURIList() throws Exception {
1838         // missing list
1839         assertNull(conf.getURIList("uri.list", null));
1840 
1841         List<Object> expected = new ArrayList<>();
1842         expected.add(new URI("http://jakarta.apache.org"));
1843         expected.add(new URI("http://www.apache.org"));
1844 
1845         // list of strings
1846         assertEquals(expected, conf.getURIList("uri.list1"));
1847 
1848         // list of strings, comma separated
1849         assertEquals(expected, conf.getURIList("uri.list2"));
1850 
1851         // list of URI objects
1852         assertEquals(expected, conf.getURIList("uri.list3"));
1853 
1854         // array of URI objects
1855         assertEquals(expected, conf.getURIList("uri.list4"));
1856 
1857         // list of URI objects
1858         assertEquals(expected, conf.getURIList("uri.list6"));
1859 
1860         // list of interpolated values
1861         assertEquals(expected, conf.getURIList("uri.list.interpolated"));
1862 
1863         // single URI values
1864         expected = new ArrayList<>();
1865         expected.add(new URI("http://jakarta.apache.org"));
1866         assertEquals(expected, conf.getURIList("uri.string"));
1867         assertEquals(expected, conf.getURIList("uri.object"));
1868 
1869         // empty list
1870         assertEquals(new ArrayList<>(), conf.getURIList("empty"));
1871     }
1872 
1873     @Test
1874     void testGetURL() throws Exception {
1875         // missing URL
1876         final URL defaultValue = new URL("http://www.google.com");
1877         assertEquals(conf.getURL("url", defaultValue), defaultValue);
1878 
1879         final URL expected = new URL("http://jakarta.apache.org");
1880 
1881         // URL string
1882         assertEquals(expected, conf.getURL("url.string"));
1883 
1884         // URL object
1885         assertEquals(expected, conf.getURL("url.object"));
1886 
1887         // interpolated value
1888         assertEquals(expected, conf.getURL("url.string.interpolated"));
1889     }
1890 
1891     @Test
1892     void testGetURLArray() throws Exception {
1893         // missing list
1894         final URL[] defaultValue = {new URL("http://www.apache.org"), new URL("http://jakarta.apache.org")};
1895         assertArrayEquals(conf.getURLArray("url.list", defaultValue), defaultValue);
1896 
1897         final URL[] expected = {new URL("http://jakarta.apache.org"), new URL("http://www.apache.org")};
1898 
1899         // list of strings
1900         assertArrayEquals(expected, conf.getURLArray("url.list1"));
1901 
1902         // list of strings, comma separated
1903         assertArrayEquals(expected, conf.getURLArray("url.list2"));
1904 
1905         // list of URL objects
1906         assertArrayEquals(expected, conf.getURLArray("url.list3"));
1907 
1908         // array of URL objects
1909         assertArrayEquals(expected, conf.getURLArray("url.list4"));
1910 
1911         // list of URL objects
1912         assertArrayEquals(expected, conf.getURLArray("url.list6"));
1913 
1914         // list of interpolated values
1915         assertArrayEquals(expected, conf.getURLArray("url.list.interpolated"));
1916 
1917         // single URL values
1918         assertArrayEquals(new URL[] {new URL("http://jakarta.apache.org")}, conf.getURLArray("url.string"));
1919         assertArrayEquals(new URL[] {new URL("http://jakarta.apache.org")}, conf.getURLArray("url.object"));
1920 
1921         // empty array
1922         assertArrayEquals(new URL[] {}, conf.getURLArray("empty"));
1923     }
1924 
1925     @Test
1926     void testGetURLList() throws Exception {
1927         // missing list
1928         assertNull(conf.getURLList("url.list", null));
1929 
1930         List<Object> expected = new ArrayList<>();
1931         expected.add(new URL("http://jakarta.apache.org"));
1932         expected.add(new URL("http://www.apache.org"));
1933 
1934         // list of strings
1935         assertEquals(expected, conf.getURLList("url.list1"));
1936 
1937         // list of strings, comma separated
1938         assertEquals(expected, conf.getURLList("url.list2"));
1939 
1940         // list of URL objects
1941         assertEquals(expected, conf.getURLList("url.list3"));
1942 
1943         // array of URL objects
1944         assertEquals(expected, conf.getURLList("url.list4"));
1945 
1946         // list of URL objects
1947         assertEquals(expected, conf.getURLList("url.list6"));
1948 
1949         // list of interpolated values
1950         assertEquals(expected, conf.getURLList("url.list.interpolated"));
1951 
1952         // single URL values
1953         expected = new ArrayList<>();
1954         expected.add(new URL("http://jakarta.apache.org"));
1955         assertEquals(expected, conf.getURLList("url.string"));
1956         assertEquals(expected, conf.getURLList("url.object"));
1957 
1958         // empty list
1959         assertEquals(new ArrayList<>(), conf.getURLList("empty"));
1960     }
1961 
1962     @Test
1963     void testIsEmpty() {
1964         final Configuration baseconf = new BaseConfiguration();
1965         final DataConfiguration conf = new DataConfiguration(baseconf);
1966 
1967         assertTrue(conf.isEmpty());
1968         baseconf.setProperty("foo", "bar");
1969         assertFalse(conf.isEmpty());
1970     }
1971 
1972     @Test
1973     void testNullConfiguration() {
1974         assertThrows(NullPointerException.class, () -> new DataConfiguration(null));
1975     }
1976 }