1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.configuration2.beanutils;
18
19 import static org.junit.jupiter.api.Assertions.assertEquals;
20 import static org.junit.jupiter.api.Assertions.assertFalse;
21 import static org.junit.jupiter.api.Assertions.assertInstanceOf;
22 import static org.junit.jupiter.api.Assertions.assertNotNull;
23 import static org.junit.jupiter.api.Assertions.assertNull;
24 import static org.junit.jupiter.api.Assertions.assertThrows;
25 import static org.junit.jupiter.api.Assertions.assertTrue;
26
27 import java.util.Collection;
28 import java.util.HashMap;
29 import java.util.Iterator;
30 import java.util.Map;
31
32 import org.apache.commons.configuration2.BaseHierarchicalConfiguration;
33 import org.apache.commons.configuration2.HierarchicalConfiguration;
34 import org.apache.commons.configuration2.ex.ConfigurationRuntimeException;
35 import org.junit.jupiter.api.Test;
36
37
38
39
40 public class TestXMLBeanDeclaration {
41
42
43
44 private static final class XMLBeanDeclarationTestImpl extends XMLBeanDeclaration {
45 public XMLBeanDeclarationTestImpl(final HierarchicalConfiguration<?> config, final NodeData<?> node) {
46 super(config, node);
47 }
48 }
49
50
51 private static final String[] TEST_PROPS = {"firstName", "lastName", "department", "age", "hobby"};
52
53
54 private static final String[] TEST_VALUES = {"John", "Smith", "Engineering", "42", "TV"};
55
56
57 private static final String[] COMPLEX_PROPS = {"address", "car"};
58
59
60 private static final String[] COMPLEX_CLASSES = {"org.apache.commons.configuration.test.AddressTest", "org.apache.commons.configuration.test.CarTest"};
61
62
63 private static final String[][] COMPLEX_ATTRIBUTES = {{"street", "zip", "city", "country"}, {"brand", "color"}};
64
65
66 private static final String[][] COMPLEX_VALUES = {{"Baker Street", "12354", "London", "UK"}, {"Bentley", "silver"}};
67
68
69 private static final String[] CTOR_COMPLEX_ATTRIBUTES = {"secCode", "validTo"};
70
71
72 private static final String[] CTOR_COMPLEX_VALUES = {"20121110181559", "2015-01-31"};
73
74
75 private static final String CTOR_ID = "20121110182006";
76
77
78 private static final String KEY = "myBean";
79
80
81 private static final String VARS = "variables.";
82
83
84
85
86
87
88
89
90 private static void checkProperties(final BeanDeclaration beanDecl, final String[] names, final String[] values) {
91 final Map<String, Object> props = beanDecl.getBeanProperties();
92
93 final Map<String, String> expected = new HashMap<>();
94 for (int i = 0; i < names.length; i++) {
95 expected.put(names[i], values[i]);
96 }
97 assertEquals(expected, props);
98 }
99
100
101
102
103
104
105 private static BaseHierarchicalConfiguration prepareNestedBeanDeclarations() {
106 final BaseHierarchicalConfiguration config = new BaseHierarchicalConfiguration();
107 setupBeanDeclaration(config, KEY, TEST_PROPS, TEST_VALUES);
108 final String keyCtorArg = KEY + ".config-constrarg";
109 setupBeanDeclaration(config, keyCtorArg, CTOR_COMPLEX_ATTRIBUTES, CTOR_COMPLEX_VALUES);
110 config.addProperty(keyCtorArg + "[@config-class]", "TestClass");
111 config.addProperty(keyCtorArg + "(-1)[@config-value]", CTOR_ID);
112 config.addProperty(keyCtorArg + "[@config-type]", "long");
113 for (int i = 0; i < COMPLEX_PROPS.length; i++) {
114 setupBeanDeclaration(config, KEY + '.' + COMPLEX_PROPS[i], COMPLEX_ATTRIBUTES[i], COMPLEX_VALUES[i]);
115 config.addProperty(KEY + '.' + COMPLEX_PROPS[i] + "[@config-class]", COMPLEX_CLASSES[i]);
116 }
117 return config;
118 }
119
120
121
122
123
124
125
126
127
128
129 private static void setupBeanDeclaration(final HierarchicalConfiguration<?> config, final String key, final String[] names, final String[] values) {
130 for (int i = 0; i < names.length; i++) {
131 config.addProperty(key + "[@" + names[i] + "]", values[i]);
132 }
133 }
134
135
136
137
138 @Test
139 public void testGetBeanClassName() {
140 final BaseHierarchicalConfiguration config = new BaseHierarchicalConfiguration();
141 config.addProperty(KEY + "[@config-class]", getClass().getName());
142 final XMLBeanDeclaration decl = new XMLBeanDeclaration(config, KEY);
143 assertEquals(getClass().getName(), decl.getBeanClassName());
144 }
145
146
147
148
149 @Test
150 public void testGetBeanClassNameFromDefault() {
151 final BaseHierarchicalConfiguration config = new BaseHierarchicalConfiguration();
152 config.addProperty(KEY + "[@someProperty]", Boolean.TRUE);
153 final XMLBeanDeclaration decl = new XMLBeanDeclaration(config, KEY, false, getClass().getName());
154 assertEquals(getClass().getName(), decl.getBeanClassName());
155 }
156
157
158
159
160 @Test
161 public void testGetBeanClassNameUndefined() {
162 final XMLBeanDeclaration decl = new XMLBeanDeclaration(new BaseHierarchicalConfiguration());
163 assertNull(decl.getBeanClassName());
164 }
165
166
167
168
169 @Test
170 public void testGetBeanClassNameUndefinedWithEx() {
171 final BaseHierarchicalConfiguration config = new BaseHierarchicalConfiguration();
172 config.setThrowExceptionOnMissing(true);
173 final XMLBeanDeclaration decl = new XMLBeanDeclaration(config);
174 assertNull(decl.getBeanClassName());
175 }
176
177
178
179
180 @Test
181 public void testGetBeanFactoryName() {
182 final BaseHierarchicalConfiguration config = new BaseHierarchicalConfiguration();
183 config.addProperty(KEY + "[@config-factory]", "myFactory");
184 final XMLBeanDeclaration decl = new XMLBeanDeclaration(config, KEY);
185 assertEquals("myFactory", decl.getBeanFactoryName());
186 }
187
188
189
190
191 @Test
192 public void testGetBeanFactoryNameUndefined() {
193 final XMLBeanDeclaration decl = new XMLBeanDeclaration(new BaseHierarchicalConfiguration());
194 assertNull(decl.getBeanFactoryName());
195 }
196
197
198
199
200 @Test
201 public void testGetBeanFactoryNameUndefinedWithEx() {
202 final BaseHierarchicalConfiguration config = new BaseHierarchicalConfiguration();
203 config.setThrowExceptionOnMissing(true);
204 final XMLBeanDeclaration decl = new XMLBeanDeclaration(config);
205 assertNull(decl.getBeanFactoryName());
206 }
207
208
209
210
211 @Test
212 public void testGetBeanFactoryParameter() {
213 final BaseHierarchicalConfiguration config = new BaseHierarchicalConfiguration();
214 config.addProperty(KEY + "[@config-factoryParam]", "myFactoryParameter");
215 final XMLBeanDeclaration decl = new XMLBeanDeclaration(config, KEY);
216 assertEquals("myFactoryParameter", decl.getBeanFactoryParameter());
217 }
218
219
220
221
222 @Test
223 public void testGetBeanFactoryParameterUndefined() {
224 final XMLBeanDeclaration decl = new XMLBeanDeclaration(new BaseHierarchicalConfiguration());
225 assertNull(decl.getBeanFactoryParameter());
226 }
227
228
229
230
231 @Test
232 public void testGetBeanFactoryParameterUndefinedWithEx() {
233 final BaseHierarchicalConfiguration config = new BaseHierarchicalConfiguration();
234 config.setThrowExceptionOnMissing(true);
235 final XMLBeanDeclaration decl = new XMLBeanDeclaration(config);
236 assertNull(decl.getBeanFactoryParameter());
237 }
238
239
240
241
242 @Test
243 public void testGetBeanProperties() {
244 final BaseHierarchicalConfiguration config = new BaseHierarchicalConfiguration();
245 setupBeanDeclaration(config, KEY, TEST_PROPS, TEST_VALUES);
246 final XMLBeanDeclaration decl = new XMLBeanDeclaration(config, KEY);
247 checkProperties(decl, TEST_PROPS, TEST_VALUES);
248 }
249
250
251
252
253 @Test
254 public void testGetBeanPropertiesEmpty() {
255 final XMLBeanDeclaration decl = new XMLBeanDeclaration(new BaseHierarchicalConfiguration());
256 final Map<String, Object> props = decl.getBeanProperties();
257 assertTrue(props == null || props.isEmpty());
258 }
259
260
261
262
263 @Test
264 public void testGetBeanPropertiesWithReservedAttributes() {
265 final BaseHierarchicalConfiguration config = new BaseHierarchicalConfiguration();
266 setupBeanDeclaration(config, KEY, TEST_PROPS, TEST_VALUES);
267 config.addProperty(KEY + "[@config-testattr]", "yes");
268 config.addProperty(KEY + "[@config-anothertest]", "this, too");
269 final XMLBeanDeclaration decl = new XMLBeanDeclaration(config, KEY);
270 checkProperties(decl, TEST_PROPS, TEST_VALUES);
271 }
272
273
274
275
276 @Test
277 public void testGetConstructorArgs() {
278 final BaseHierarchicalConfiguration config = prepareNestedBeanDeclarations();
279 final XMLBeanDeclaration decl = new XMLBeanDeclaration(config, KEY);
280 final Collection<ConstructorArg> args = decl.getConstructorArgs();
281 assertEquals(2, args.size());
282 final Iterator<ConstructorArg> it = args.iterator();
283 final ConstructorArg arg1 = it.next();
284 assertTrue(arg1.isNestedBeanDeclaration());
285 checkProperties(arg1.getBeanDeclaration(), CTOR_COMPLEX_ATTRIBUTES, CTOR_COMPLEX_VALUES);
286 assertNull(arg1.getTypeName());
287 assertEquals("TestClass", arg1.getBeanDeclaration().getBeanClassName());
288 final ConstructorArg arg2 = it.next();
289 assertFalse(arg2.isNestedBeanDeclaration());
290 assertEquals(CTOR_ID, arg2.getValue());
291 assertEquals("long", arg2.getTypeName());
292 }
293
294
295
296
297 @Test
298 public void testGetConstructorArgsNullArg() {
299 final BaseHierarchicalConfiguration config = new BaseHierarchicalConfiguration();
300 setupBeanDeclaration(config, KEY, TEST_PROPS, TEST_VALUES);
301 config.addProperty(KEY + ".config-constrarg", "");
302 final XMLBeanDeclaration decl = new XMLBeanDeclaration(config, KEY);
303 final Collection<ConstructorArg> args = decl.getConstructorArgs();
304 assertEquals(1, args.size());
305 final ConstructorArg arg = args.iterator().next();
306 assertFalse(arg.isNestedBeanDeclaration());
307 assertNull(arg.getValue());
308 }
309
310
311
312
313 @Test
314 public void testGetInterpolatedBeanProperties() {
315 final BaseHierarchicalConfiguration config = new BaseHierarchicalConfiguration();
316 final String[] varValues = new String[TEST_PROPS.length];
317 for (int i = 0; i < TEST_PROPS.length; i++) {
318 varValues[i] = "${" + VARS + TEST_PROPS[i] + "}";
319 config.addProperty(VARS + TEST_PROPS[i], TEST_VALUES[i]);
320 }
321 setupBeanDeclaration(config, KEY, TEST_PROPS, varValues);
322 final XMLBeanDeclaration decl = new XMLBeanDeclaration(config, KEY);
323 checkProperties(decl, TEST_PROPS, TEST_VALUES);
324 }
325
326
327
328
329 @Test
330 public void testGetInterpolatedConstructorArgs() {
331 final BaseHierarchicalConfiguration config = new BaseHierarchicalConfiguration();
332 final String expectedValue = "ctorArg";
333 config.addProperty("value", expectedValue);
334 setupBeanDeclaration(config, KEY, TEST_PROPS, TEST_VALUES);
335 config.addProperty(KEY + ".config-constrarg[@config-value]", "${value}");
336 final XMLBeanDeclaration decl = new XMLBeanDeclaration(config, KEY);
337 final Collection<ConstructorArg> args = decl.getConstructorArgs();
338 final ConstructorArg arg = args.iterator().next();
339 assertEquals(expectedValue, arg.getValue());
340 }
341
342
343
344
345 @Test
346 public void testGetNestedBeanDeclarations() {
347 final BaseHierarchicalConfiguration config = prepareNestedBeanDeclarations();
348 final XMLBeanDeclaration decl = new XMLBeanDeclaration(config, KEY);
349 checkProperties(decl, TEST_PROPS, TEST_VALUES);
350
351 final Map<String, Object> nested = decl.getNestedBeanDeclarations();
352 assertEquals(COMPLEX_PROPS.length, nested.size());
353 for (int i = 0; i < COMPLEX_PROPS.length; i++) {
354 final XMLBeanDeclaration d = (XMLBeanDeclaration) nested.get(COMPLEX_PROPS[i]);
355 assertNotNull(d, "No declaration found for " + COMPLEX_PROPS[i]);
356 checkProperties(d, COMPLEX_ATTRIBUTES[i], COMPLEX_VALUES[i]);
357 assertEquals(COMPLEX_CLASSES[i], d.getBeanClassName());
358 }
359 }
360
361
362
363
364 @Test
365 public void testGetNestedBeanDeclarationsEmpty() {
366 final BaseHierarchicalConfiguration config = new BaseHierarchicalConfiguration();
367 setupBeanDeclaration(config, KEY, TEST_PROPS, TEST_VALUES);
368 final XMLBeanDeclaration decl = new XMLBeanDeclaration(config, KEY);
369 final Map<String, Object> nested = decl.getNestedBeanDeclarations();
370 assertTrue(nested == null || nested.isEmpty());
371 }
372
373
374
375
376 @Test
377 public void testGetNestedBeanDeclarationsFactoryMethod() {
378 final BaseHierarchicalConfiguration config = prepareNestedBeanDeclarations();
379 final XMLBeanDeclaration decl = new XMLBeanDeclaration(config, KEY) {
380 @Override
381 BeanDeclaration createBeanDeclaration(final NodeData<?> node) {
382 return new XMLBeanDeclarationTestImpl(getConfiguration().configurationAt(node.nodeName()), node);
383 }
384 };
385 final Map<String, Object> nested = decl.getNestedBeanDeclarations();
386 for (final String element : COMPLEX_PROPS) {
387 final Object d = nested.get(element);
388 assertInstanceOf(XMLBeanDeclarationTestImpl.class, d, "Wrong class for bean declaration: " + d);
389 }
390 }
391
392
393
394
395
396 @Test
397 public void testGetNestedBeanDeclarationsReservedCharacter() {
398 final BaseHierarchicalConfiguration config = new BaseHierarchicalConfiguration();
399 final String key = KEY + ".address..private";
400 setupBeanDeclaration(config, key, COMPLEX_ATTRIBUTES[0], COMPLEX_VALUES[0]);
401 final XMLBeanDeclaration decl = new XMLBeanDeclaration(config, KEY);
402
403 final Map<String, Object> nested = decl.getNestedBeanDeclarations();
404 assertTrue(nested.containsKey("address.private"));
405 }
406
407
408
409
410
411 @Test
412 public void testInitFromMultiValueKey() {
413 final BaseHierarchicalConfiguration config = new BaseHierarchicalConfiguration();
414 config.addProperty(KEY, "myFirstKey");
415 config.addProperty(KEY, "mySecondKey");
416 assertThrows(ConfigurationRuntimeException.class, () -> new XMLBeanDeclaration(config, KEY));
417 }
418
419
420
421
422 @Test
423 public void testInitFromNullConfiguration() {
424 assertThrows(IllegalArgumentException.class, () -> new XMLBeanDeclaration(null));
425 }
426
427
428
429
430 @Test
431 public void testInitFromNullConfigurationAndKey() {
432 assertThrows(IllegalArgumentException.class, () -> new XMLBeanDeclaration(null, KEY));
433 }
434
435
436
437
438 @Test
439 public void testInitFromUndefinedKey() {
440 final BaseHierarchicalConfiguration config = new BaseHierarchicalConfiguration();
441 setupBeanDeclaration(config, KEY, TEST_PROPS, TEST_VALUES);
442 assertThrows(ConfigurationRuntimeException.class, () -> new XMLBeanDeclaration(config, "undefined_key"));
443 }
444
445
446
447
448
449 @Test
450 public void testInitFromUndefinedKeyOptional() {
451 final BaseHierarchicalConfiguration config = new BaseHierarchicalConfiguration();
452 setupBeanDeclaration(config, KEY, TEST_PROPS, TEST_VALUES);
453 final XMLBeanDeclaration decl = new XMLBeanDeclaration(config, "undefined_key", true);
454 assertNull(decl.getBeanClassName());
455 }
456
457
458
459
460 @Test
461 public void testInterpolateNoInterpolator() {
462 final BaseHierarchicalConfiguration config = new BaseHierarchicalConfiguration();
463 config.addProperty("value", "expectedValue");
464 setupBeanDeclaration(config, KEY, TEST_PROPS, TEST_VALUES);
465 final String value = "${value}";
466 config.addProperty(KEY + ".config-constrarg[@config-value]", value);
467 config.setInterpolator(null);
468 final XMLBeanDeclaration decl = new XMLBeanDeclaration(config, KEY);
469 final Collection<ConstructorArg> args = decl.getConstructorArgs();
470 final ConstructorArg arg = args.iterator().next();
471 assertEquals(value, arg.getValue());
472 }
473
474
475
476
477 @Test
478 public void tetGetBeanClassNameDefaultOverride() {
479 final BaseHierarchicalConfiguration config = new BaseHierarchicalConfiguration();
480 config.addProperty(KEY + "[@config-class]", getClass().getName());
481 final XMLBeanDeclaration decl = new XMLBeanDeclaration(config, KEY, false, "someDefaultClassName");
482 assertEquals(getClass().getName(), decl.getBeanClassName());
483 }
484 }