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