1 package org.apache.commons.configuration;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 import junit.framework.TestCase;
21
22 import java.io.File;
23 import java.util.Collection;
24 import java.util.Iterator;
25
26 /***
27 * Test class for XMLConfiguration. In addition to TestXMLConfiguration this
28 * class especially tests the hierarchical nature of this class and structured
29 * data access.
30 *
31 * @author Emmanuel Bourg
32 * @author Mark Woodman
33 * @author Oliver Heger
34 * @version $Id: TestHierarchicalXMLConfiguration.java 439648 2006-09-02 20:42:10Z oheger $
35 */
36 public class TestHierarchicalXMLConfiguration extends TestCase
37 {
38 /*** Test resources directory. */
39 private static final String TEST_DIR = "conf";
40
41 /*** Test file #1 **/
42 private static final String TEST_FILENAME = "testHierarchicalXMLConfiguration.xml";
43
44 /*** Test file #2 **/
45 private static final String TEST_FILENAME2 = "testHierarchicalXMLConfiguration2.xml";
46
47 /*** Test file path #1 **/
48 private static final String TEST_FILE = TEST_DIR + File.separator + TEST_FILENAME;
49
50 /*** Test file path #2 **/
51 private static final String TEST_FILE2 = TEST_DIR + File.separator + TEST_FILENAME2;
52
53 /*** Test file path #3.*/
54 private static final String TEST_FILE3 = TEST_DIR + File.separator + "test.xml";
55
56 /*** File name for saving.*/
57 private static final String TEST_SAVENAME = "testhierarchicalsave.xml";
58
59 /*** File path for saving.*/
60 private static final String TEST_SAVE = "target" + File.separator + TEST_SAVENAME;
61
62 /*** Instance config used for tests. */
63 private XMLConfiguration config;
64
65 /*** Fixture setup. */
66 protected void setUp() throws Exception
67 {
68 config = new XMLConfiguration();
69 }
70
71 private void configTest(XMLConfiguration config)
72 {
73 assertEquals(1, config.getMaxIndex("tables.table"));
74 assertEquals("system", config.getProperty("tables.table(0)[@tableType]"));
75 assertEquals("application", config.getProperty("tables.table(1)[@tableType]"));
76
77 assertEquals("users", config.getProperty("tables.table(0).name"));
78 assertEquals("documents", config.getProperty("tables.table(1).name"));
79
80 Object prop = config.getProperty("tables.table.fields.field.name");
81 assertTrue(prop instanceof Collection);
82 assertEquals(10, ((Collection) prop).size());
83
84 prop = config.getProperty("tables.table(0).fields.field.type");
85 assertTrue(prop instanceof Collection);
86 assertEquals(5, ((Collection) prop).size());
87
88 prop = config.getProperty("tables.table(1).fields.field.type");
89 assertTrue(prop instanceof Collection);
90 assertEquals(5, ((Collection) prop).size());
91 }
92
93 public void testGetProperty() throws Exception
94 {
95 config.setFileName(TEST_FILE);
96 config.load();
97
98 configTest(config);
99 }
100
101 public void testLoadURL() throws Exception
102 {
103 config.load(new File(TEST_FILE).getAbsoluteFile().toURL());
104 configTest(config);
105 }
106
107 public void testLoadBasePath1() throws Exception
108 {
109 config.setBasePath(TEST_DIR);
110 config.setFileName(TEST_FILENAME);
111 config.load();
112 configTest(config);
113 }
114
115 public void testLoadBasePath2() throws Exception
116 {
117 config.setBasePath(new File(TEST_FILE).getAbsoluteFile().toURL().toString());
118 config.setFileName(TEST_FILENAME);
119 config.load();
120 configTest(config);
121 }
122
123 /***
124 * Ensure various node types are correctly processed in config.
125 * @throws Exception
126 */
127 public void testXmlNodeTypes() throws Exception
128 {
129
130 final int KEY_COUNT = 5;
131
132
133 config.load(new File(TEST_FILE2).getAbsoluteFile().toURL());
134
135
136 assertEquals("Comment in element must not change element value.", "Case1Text", config
137 .getString("case1"));
138
139
140 assertEquals("Comment as sibling must not change element value.", "Case2Text", config
141 .getString("case2.child"));
142
143
144 assertEquals("Comment and use of CDATA must not change element value.", "Case3Text", config
145 .getString("case3"));
146
147
148 assertEquals("Comment and use of PI must not change element value.", "Case4Text", config
149 .getString("case4"));
150
151
152 assertEquals("Comment must not change attribute node value.", "Case5Text", config
153 .getString("case5[@attr]"));
154
155
156 Iterator iter = config.getKeys();
157 int count = 0;
158 while (iter.hasNext())
159 {
160 iter.next();
161 count++;
162 }
163 assertEquals("Config must contain only " + KEY_COUNT + " keys.", KEY_COUNT, count);
164 }
165
166 public void testSave() throws Exception
167 {
168 removeTestSaveFile();
169 try
170 {
171 config.setFileName(TEST_FILE3);
172 config.load();
173 File saveFile = new File(TEST_SAVE);
174 config.save(saveFile);
175
176 config = new XMLConfiguration();
177 config.load(saveFile.toURL());
178 assertEquals("value", config.getProperty("element"));
179 assertEquals("I'm complex!", config.getProperty("element2.subelement.subsubelement"));
180 assertEquals(8, config.getInt("test.short"));
181 assertEquals("one", config.getString("list(0).item(0)[@name]"));
182 assertEquals("two", config.getString("list(0).item(1)"));
183 assertEquals("six", config.getString("list(1).sublist.item(1)"));
184
185 }
186 finally
187 {
188 removeTestSaveFile();
189 }
190 }
191
192 /***
193 * Tests to save a newly created configuration.
194 *
195 */
196 public void testSaveNew() throws Exception
197 {
198 config.addProperty("connection.url", "jdbc://mydb:1234");
199 config.addProperty("connection.user", "scott");
200 config.addProperty("connection.passwd", "tiger");
201 config.addProperty("connection[@type]", "system");
202 config.addProperty("tables.table.name", "tests");
203 config.addProperty("tables.table(0).fields.field.name", "test_id");
204 config.addProperty("tables.table(0).fields.field(-1).name", "test_name");
205 config.addProperty("tables.table(-1).name", "results");
206 config.addProperty("tables.table(1).fields.field.name", "res_id");
207 config.addProperty("tables.table(1).fields.field(0).type", "int");
208 config.addProperty("tables.table(1).fields.field(-1).name", "value");
209 config.addProperty("tables.table(1).fields.field(1).type", "string");
210 config.addProperty("tables.table(1).fields.field(1)[@null]", "true");
211
212 removeTestSaveFile();
213 try
214 {
215 File saveFile = new File(TEST_SAVE);
216 config.setFile(saveFile);
217 config.setRootElementName("myconfig");
218 config.save();
219
220 config = new XMLConfiguration();
221 config.load(saveFile);
222 assertEquals(1, config.getMaxIndex("tables.table.name"));
223 assertEquals("tests", config.getString("tables.table(0).name"));
224 assertEquals("test_name", config.getString("tables.table(0).fields.field(1).name"));
225 assertEquals("int", config.getString("tables.table(1).fields.field(0).type"));
226 assertTrue(config.getBoolean("tables.table(1).fields.field(1)[@null]"));
227 assertEquals("tiger", config.getString("connection.passwd"));
228 assertEquals("system", config.getProperty("connection[@type]"));
229 assertEquals("myconfig", config.getRootElementName());
230 }
231 finally
232 {
233 removeTestSaveFile();
234 }
235 }
236
237 /***
238 * Tests to save a modified configuration.
239 *
240 */
241 public void testSaveModified() throws Exception
242 {
243 config.setFile(new File(TEST_FILE3));
244 config.load();
245
246 assertTrue(config.getString("mean").startsWith("This is\n A long story..."));
247 assertTrue(config.getString("mean").indexOf("And even longer") > 0);
248 config.clearProperty("test.entity[@name]");
249 config.setProperty("element", "new value");
250 config.setProperty("test(0)", "A <new> value");
251 config.addProperty("test(1).int", new Integer(9));
252 config.addProperty("list(1).sublist.item", "seven");
253 config.setProperty("clear", "yes");
254 config.setProperty("mean", "now it's simple");
255 config.addProperty("[@topattr]", "available");
256 config.addProperty("[@topattr]", "successfull");
257
258 removeTestSaveFile();
259 try
260 {
261 config.save(new File(TEST_SAVE));
262 config = new XMLConfiguration();
263 config.load(TEST_SAVE);
264 assertFalse(config.containsKey("test.entity[@name]"));
265 assertEquals("1<2", config.getProperty("test.entity"));
266 assertEquals("new value", config.getString("element"));
267 assertEquals("A <new> value", config.getProperty("test(0)"));
268 assertEquals((short) 8, config.getShort("test(1).short"));
269 assertEquals(9, config.getInt("test(1).int"));
270 assertEquals("six", config.getProperty("list(1).sublist.item(1)"));
271 assertEquals("seven", config.getProperty("list(1).sublist.item(2)"));
272 assertEquals("yes", config.getProperty("clear"));
273 assertEquals("now it's simple", config.getString("mean"));
274 assertEquals("available", config.getString("[@topattr](0)"));
275 assertEquals("successfull", config.getString("[@topattr](1)"));
276 }
277 finally
278 {
279 removeTestSaveFile();
280 }
281 }
282
283 /***
284 * Tests manipulation of the root element's name.
285 *
286 */
287 public void testRootElement() throws Exception
288 {
289 assertEquals("configuration", config.getRootElementName());
290 config.setRootElementName("newRootName");
291 assertEquals("newRootName", config.getRootElementName());
292
293 config.setFile(new File(TEST_FILE3));
294 config.load();
295 assertEquals("testconfig", config.getRootElementName());
296 try
297 {
298 config.setRootElementName("anotherRootElement");
299 fail("Setting root element name when loaded from file!");
300 }
301 catch(UnsupportedOperationException uex)
302 {
303
304 }
305 }
306
307 /***
308 * Helper method that ensures that the test save file has been removed.
309 *
310 */
311 private void removeTestSaveFile()
312 {
313 File saveFile = new File(TEST_SAVE);
314 if (saveFile.exists())
315 {
316 assertTrue(saveFile.delete());
317 }
318 }
319 }