1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.configuration.beanutils;
18
19 import java.util.Map;
20
21 import org.apache.commons.configuration.HierarchicalConfiguration;
22 import org.apache.commons.configuration.SubnodeConfiguration;
23 import org.apache.commons.configuration.tree.ConfigurationNode;
24
25 import junit.framework.TestCase;
26
27 /***
28 * Test class for XMLBeanDeclaration.
29 *
30 * @since 1.3
31 * @author Oliver Heger
32 * @version $Id: TestXMLBeanDeclaration.java 670739 2008-06-23 20:36:37Z oheger $
33 */
34 public class TestXMLBeanDeclaration extends TestCase
35 {
36 /*** An array with some test properties. */
37 static final String[] TEST_PROPS =
38 { "firstName", "lastName", "department", "age", "hobby"};
39
40 /*** An array with the values for the test properties. */
41 static final String[] TEST_VALUES =
42 { "John", "Smith", "Engineering", "42", "TV"};
43
44 /*** An array with the names of nested (complex) properties. */
45 static final String[] COMPLEX_PROPS =
46 { "address", "car"};
47
48 /*** An array with the names of the classes of the complex properties. */
49 static final String[] COMPLEX_CLASSES =
50 { "org.apache.commons.configuration.test.AddressTest",
51 "org.apache.commons.configuration.test.CarTest"};
52
53 /*** An array with the property names of the complex properties. */
54 static final String[][] COMPLEX_ATTRIBUTES =
55 {
56 { "street", "zip", "city", "country"},
57 { "brand", "color"}};
58
59 /*** An array with the values of the complex properties. */
60 static final String[][] COMPLEX_VALUES =
61 {
62 { "Baker Street", "12354", "London", "UK"},
63 { "Bentley", "silver"}};
64
65 /*** Constant for the key with the bean declaration. */
66 static final String KEY = "myBean";
67
68 /*** Constant for the section with the variables.*/
69 static final String VARS = "variables.";
70
71 /*** Stores the object to be tested. */
72 XMLBeanDeclaration decl;
73
74 /***
75 * Tests creating a declaration from a null node. This should cause an
76 * exception.
77 */
78 public void testInitFromNullNode()
79 {
80 try
81 {
82 decl = new XMLBeanDeclaration(new HierarchicalConfiguration().configurationAt(null),
83 (ConfigurationNode) null);
84 fail("Could init declaration with null node!");
85 }
86 catch (IllegalArgumentException iex)
87 {
88
89 }
90 }
91
92 /***
93 * Tests creating a declaration from a null configuration. This should cause
94 * an exception.
95 */
96 public void testInitFromNullConfiguration()
97 {
98 try
99 {
100 decl = new XMLBeanDeclaration((HierarchicalConfiguration) null);
101 fail("Could init declaration with null configuration!");
102 }
103 catch (IllegalArgumentException iex)
104 {
105
106 }
107 }
108
109 /***
110 * Tests creating a declaration from a null configuration with a key. This
111 * should cause an exception.
112 */
113 public void testInitFromNullConfigurationAndKey()
114 {
115 try
116 {
117 decl = new XMLBeanDeclaration(null, KEY);
118 fail("Could init declaration with null configuration and key!");
119 }
120 catch (IllegalArgumentException iex)
121 {
122
123 }
124 }
125
126 /***
127 * Tests creating a declaration from a null configuration with a node. This
128 * should cause an exception.
129 */
130 public void testInitFromNullConfigurationAndNode()
131 {
132 try
133 {
134 decl = new XMLBeanDeclaration(null, new HierarchicalConfiguration()
135 .getRoot());
136 fail("Could init declaration with null configuration and node!");
137 }
138 catch (IllegalArgumentException iex)
139 {
140
141 }
142 }
143
144 /***
145 * Tests fetching the bean's class name.
146 */
147 public void testGetBeanClassName()
148 {
149 HierarchicalConfiguration config = new HierarchicalConfiguration();
150 config.addProperty(KEY + "[@config-class]", getClass().getName());
151 decl = new XMLBeanDeclaration(config, KEY);
152 assertEquals("Wrong class name", getClass().getName(), decl
153 .getBeanClassName());
154 }
155
156 /***
157 * Tests fetching the bean's class name if it is undefined.
158 */
159 public void testGetBeanClassNameUndefined()
160 {
161 decl = new XMLBeanDeclaration(new HierarchicalConfiguration());
162 assertNull(decl.getBeanClassName());
163 }
164
165 /***
166 * Tests fetching the name of the bean factory.
167 */
168 public void testGetBeanFactoryName()
169 {
170 HierarchicalConfiguration config = new HierarchicalConfiguration();
171 config.addProperty(KEY + "[@config-factory]", "myFactory");
172 decl = new XMLBeanDeclaration(config, KEY);
173 assertEquals("Wrong factory name", "myFactory", decl
174 .getBeanFactoryName());
175 }
176
177 /***
178 * Tests fetching the name of the bean factory if it is undefined.
179 */
180 public void testGetBeanFactoryNameUndefined()
181 {
182 decl = new XMLBeanDeclaration(new HierarchicalConfiguration());
183 assertNull(decl.getBeanFactoryName());
184 }
185
186 /***
187 * Tests fetching the paramter for the bean factory.
188 */
189 public void testGetBeanFactoryParameter()
190 {
191 HierarchicalConfiguration config = new HierarchicalConfiguration();
192 config
193 .addProperty(KEY + "[@config-factoryParam]",
194 "myFactoryParameter");
195 decl = new XMLBeanDeclaration(config, KEY);
196 assertEquals("Wrong factory parameter", "myFactoryParameter", decl
197 .getBeanFactoryParameter());
198 }
199
200 /***
201 * Tests fetching the paramter for the bean factory if it is undefined.
202 */
203 public void testGetBeanFactoryParameterUndefined()
204 {
205 decl = new XMLBeanDeclaration(new HierarchicalConfiguration());
206 assertNull(decl.getBeanFactoryParameter());
207 }
208
209 /***
210 * Tests if the bean's properties are correctly extracted from the
211 * configuration object.
212 */
213 public void testGetBeanProperties()
214 {
215 HierarchicalConfiguration config = new HierarchicalConfiguration();
216 setupBeanDeclaration(config, KEY, TEST_PROPS, TEST_VALUES);
217 decl = new XMLBeanDeclaration(config, KEY);
218 checkProperties(decl, TEST_PROPS, TEST_VALUES);
219 }
220
221 /***
222 * Tests obtaining the bean's properties when reserved attributes are
223 * involved. These should be ignored.
224 */
225 public void testGetBeanPropertiesWithReservedAttributes()
226 {
227 HierarchicalConfiguration config = new HierarchicalConfiguration();
228 setupBeanDeclaration(config, KEY, TEST_PROPS, TEST_VALUES);
229 config.addProperty(KEY + "[@config-testattr]", "yes");
230 config.addProperty(KEY + "[@config-anothertest]", "this, too");
231 decl = new XMLBeanDeclaration(config, KEY);
232 checkProperties(decl, TEST_PROPS, TEST_VALUES);
233 }
234
235 /***
236 * Tests fetching properties if none are defined.
237 */
238 public void testGetBeanPropertiesEmpty()
239 {
240 decl = new XMLBeanDeclaration(new HierarchicalConfiguration());
241 Map props = decl.getBeanProperties();
242 assertTrue("Properties found", props == null || props.isEmpty());
243 }
244
245 /***
246 * Creates a configuration with data for testing nested bean declarations.
247 * @return the initialized test configuration
248 */
249 private HierarchicalConfiguration prepareNestedBeanDeclarations()
250 {
251 HierarchicalConfiguration config = new HierarchicalConfiguration();
252 setupBeanDeclaration(config, KEY, TEST_PROPS, TEST_VALUES);
253 for (int i = 0; i < COMPLEX_PROPS.length; i++)
254 {
255 setupBeanDeclaration(config, KEY + '.' + COMPLEX_PROPS[i],
256 COMPLEX_ATTRIBUTES[i], COMPLEX_VALUES[i]);
257 config.addProperty(
258 KEY + '.' + COMPLEX_PROPS[i] + "[@config-class]",
259 COMPLEX_CLASSES[i]);
260 }
261 return config;
262 }
263
264 /***
265 * Tests fetching nested bean declarations.
266 */
267 public void testGetNestedBeanDeclarations()
268 {
269 HierarchicalConfiguration config = prepareNestedBeanDeclarations();
270 decl = new XMLBeanDeclaration(config, KEY);
271 checkProperties(decl, TEST_PROPS, TEST_VALUES);
272
273 Map nested = decl.getNestedBeanDeclarations();
274 assertEquals("Wrong number of nested declarations",
275 COMPLEX_PROPS.length, nested.size());
276 for (int i = 0; i < COMPLEX_PROPS.length; i++)
277 {
278 XMLBeanDeclaration d = (XMLBeanDeclaration) nested
279 .get(COMPLEX_PROPS[i]);
280 assertNotNull("No declaration found for " + COMPLEX_PROPS[i], d);
281 checkProperties(d, COMPLEX_ATTRIBUTES[i], COMPLEX_VALUES[i]);
282 assertEquals("Wrong bean class", COMPLEX_CLASSES[i], d
283 .getBeanClassName());
284 }
285 }
286
287 /***
288 * Tests whether the factory method for creating nested bean declarations
289 * gets called.
290 */
291 public void testGetNestedBeanDeclarationsFactoryMethod()
292 {
293 HierarchicalConfiguration config = prepareNestedBeanDeclarations();
294 decl = new XMLBeanDeclaration(config, KEY)
295 {
296 protected BeanDeclaration createBeanDeclaration(
297 ConfigurationNode node)
298 {
299 return new XMLBeanDeclarationTestImpl(getConfiguration()
300 .configurationAt(node.getName()), node);
301 }
302 };
303 Map nested = decl.getNestedBeanDeclarations();
304 for (int i = 0; i < COMPLEX_PROPS.length; i++)
305 {
306 Object d = nested.get(COMPLEX_PROPS[i]);
307 assertTrue("Wrong class for bean declaration: " + d,
308 d instanceof XMLBeanDeclarationTestImpl);
309 }
310 }
311
312 /***
313 * Tests fetching nested bean declarations if none are defined.
314 */
315 public void testGetNestedBeanDeclarationsEmpty()
316 {
317 HierarchicalConfiguration config = new HierarchicalConfiguration();
318 setupBeanDeclaration(config, KEY, TEST_PROPS, TEST_VALUES);
319 decl = new XMLBeanDeclaration(config, KEY);
320 Map nested = decl.getNestedBeanDeclarations();
321 assertTrue("Found nested declarations", nested == null
322 || nested.isEmpty());
323 }
324
325 /***
326 * Tests whether interpolation of bean properties works.
327 */
328 public void testGetInterpolatedBeanProperties()
329 {
330 HierarchicalConfiguration config = new HierarchicalConfiguration();
331 String[] varValues = new String[TEST_PROPS.length];
332 for(int i = 0; i < TEST_PROPS.length; i++)
333 {
334 varValues[i] = "${" + VARS + TEST_PROPS[i] + "}";
335 config.addProperty(VARS + TEST_PROPS[i], TEST_VALUES[i]);
336 }
337 setupBeanDeclaration(config, KEY, TEST_PROPS, varValues);
338 decl = new XMLBeanDeclaration(config, KEY);
339 checkProperties(decl, TEST_PROPS, TEST_VALUES);
340 }
341
342 /***
343 * Tests constructing a bean declaration from an undefined key. This should
344 * cause an exception.
345 */
346 public void testInitFromUndefinedKey()
347 {
348 HierarchicalConfiguration config = new HierarchicalConfiguration();
349 setupBeanDeclaration(config, KEY, TEST_PROPS, TEST_VALUES);
350 try
351 {
352 decl = new XMLBeanDeclaration(config, "undefined_key");
353 fail("Could create declaration from an undefined key!");
354 }
355 catch (IllegalArgumentException iex)
356 {
357
358 }
359 }
360
361 /***
362 * Tests constructing a bean declaration from a key, which is undefined when
363 * the optional flag is set. In this case an empty declaration should be
364 * created, which can be used for creating beans as long as a default class
365 * is provided.
366 */
367 public void testInitFromUndefinedKeyOptional()
368 {
369 HierarchicalConfiguration config = new HierarchicalConfiguration();
370 setupBeanDeclaration(config, KEY, TEST_PROPS, TEST_VALUES);
371 decl = new XMLBeanDeclaration(config, "undefined_key", true);
372 assertNull("Found a bean class", decl.getBeanClassName());
373 }
374
375 /***
376 * Tests constructing a bean declaration from a key with multiple values.
377 * This should cause an exception because keys must be unique.
378 */
379 public void testInitFromMultiValueKey()
380 {
381 HierarchicalConfiguration config = new HierarchicalConfiguration();
382 config.addProperty(KEY, "myFirstKey");
383 config.addProperty(KEY, "mySecondKey");
384 try
385 {
386 decl = new XMLBeanDeclaration(config, KEY);
387 fail("Could create declaration from multi-valued property!");
388 }
389 catch (IllegalArgumentException iex)
390 {
391
392 }
393 }
394
395 /***
396 * Initializes a configuration object with a bean declaration. Under the
397 * specified key the given properties will be added.
398 *
399 * @param config the configuration to initialize
400 * @param key the key of the bean declaration
401 * @param names an array with the names of the properties
402 * @param values an array with the corresponding values
403 */
404 private void setupBeanDeclaration(HierarchicalConfiguration config,
405 String key, String[] names, String[] values)
406 {
407 for (int i = 0; i < names.length; i++)
408 {
409 config.addProperty(key + "[@" + names[i] + "]", values[i]);
410 }
411 }
412
413 /***
414 * Checks the properties returned by a bean declaration.
415 *
416 * @param beanDecl the bean declaration
417 * @param names an array with the expected property names
418 * @param values an array with the expected property values
419 */
420 private void checkProperties(BeanDeclaration beanDecl, String[] names,
421 String[] values)
422 {
423 Map props = beanDecl.getBeanProperties();
424 assertEquals("Wrong number of properties", names.length, props.size());
425 for (int i = 0; i < names.length; i++)
426 {
427 assertTrue("Property " + names[i] + " not contained", props
428 .containsKey(names[i]));
429 assertEquals("Wrong value for property " + names[i], values[i],
430 props.get(names[i]));
431 }
432 }
433
434 /***
435 * A helper class used for testing the createBeanDeclaration() factory
436 * method.
437 */
438 private static class XMLBeanDeclarationTestImpl extends XMLBeanDeclaration
439 {
440 public XMLBeanDeclarationTestImpl(SubnodeConfiguration config,
441 ConfigurationNode node)
442 {
443 super(config, node);
444 }
445 }
446 }