View Javadoc

1   package org.apache.commons.configuration;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one or more
5    * contributor license agreements.  See the NOTICE file distributed with
6    * this work for additional information regarding copyright ownership.
7    * The ASF licenses this file to You under the Apache License, Version 2.0
8    * (the "License"); you may not use this file except in compliance with
9    * the License.  You may obtain a copy of the License at
10   *
11   *     http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the License is distributed on an "AS IS" BASIS,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the License for the specific language governing permissions and
17   * limitations under the License.
18   */
19  
20  import static org.junit.Assert.assertEquals;
21  import static org.junit.Assert.assertFalse;
22  import static org.junit.Assert.assertTrue;
23  
24  import java.io.File;
25  import java.util.Collection;
26  import java.util.Iterator;
27  
28  import org.junit.Before;
29  import org.junit.Rule;
30  import org.junit.Test;
31  import org.junit.rules.TemporaryFolder;
32  
33  /**
34   * Test class for XMLConfiguration. In addition to TestXMLConfiguration this
35   * class especially tests the hierarchical nature of this class and structured
36   * data access.
37   *
38   * @author Emmanuel Bourg
39   * @author Mark Woodman
40   * @version $Id: TestHierarchicalXMLConfiguration.java 1224764 2011-12-26 17:14:49Z oheger $
41   */
42  public class TestHierarchicalXMLConfiguration
43  {
44      /** Test resources directory. */
45      private static final String TEST_DIR = "conf";
46  
47      /** Test file #1 **/
48      private static final String TEST_FILENAME = "testHierarchicalXMLConfiguration.xml";
49  
50      /** Test file #2 **/
51      private static final String TEST_FILENAME2 = "testHierarchicalXMLConfiguration2.xml";
52  
53      /** Test file path #1 **/
54      private static final String TEST_FILE = ConfigurationAssert.getTestFile(TEST_FILENAME).getAbsolutePath();
55  
56      /** Test file path #2 **/
57      private static final String TEST_FILE2 = ConfigurationAssert.getTestFile(TEST_FILENAME2).getAbsolutePath();
58  
59      /** Test file path #3.*/
60      private static final String TEST_FILE3 = ConfigurationAssert.getTestFile("test.xml").getAbsolutePath();
61  
62      /** File name for saving.*/
63      private static final String TEST_SAVENAME = "testhierarchicalsave.xml";
64  
65      /** Helper object for creating temporary files. */
66      @Rule
67      public TemporaryFolder folder = new TemporaryFolder();
68  
69      /** Instance config used for tests. */
70      private XMLConfiguration config;
71  
72      /** Fixture setup. */
73      @Before
74      public void setUp() throws Exception
75      {
76          config = new XMLConfiguration();
77      }
78  
79      private void configTest(XMLConfiguration config)
80      {
81          assertEquals(1, config.getMaxIndex("tables.table"));
82          assertEquals("system", config.getProperty("tables.table(0)[@tableType]"));
83          assertEquals("application", config.getProperty("tables.table(1)[@tableType]"));
84  
85          assertEquals("users", config.getProperty("tables.table(0).name"));
86          assertEquals("documents", config.getProperty("tables.table(1).name"));
87  
88          Object prop = config.getProperty("tables.table.fields.field.name");
89          assertTrue(prop instanceof Collection);
90          assertEquals(10, ((Collection<?>) prop).size());
91  
92          prop = config.getProperty("tables.table(0).fields.field.type");
93          assertTrue(prop instanceof Collection);
94          assertEquals(5, ((Collection<?>) prop).size());
95  
96          prop = config.getProperty("tables.table(1).fields.field.type");
97          assertTrue(prop instanceof Collection);
98          assertEquals(5, ((Collection<?>) prop).size());
99      }
100 
101     @Test
102     public void testGetProperty() throws Exception
103     {
104         config.setFileName(TEST_FILE);
105         config.load();
106 
107         configTest(config);
108     }
109 
110     @Test
111     public void testLoadURL() throws Exception
112     {
113         config.load(new File(TEST_FILE).getAbsoluteFile().toURI().toURL());
114         configTest(config);
115     }
116 
117     @Test
118     public void testLoadBasePath1() throws Exception
119     {
120         config.setBasePath(TEST_DIR);
121         config.setFileName(TEST_FILENAME);
122         config.load();
123         configTest(config);
124     }
125 
126     @Test
127     public void testLoadBasePath2() throws Exception
128     {
129         config.setBasePath(new File(TEST_FILE).getAbsoluteFile().toURI().toURL().toString());
130         config.setFileName(TEST_FILENAME);
131         config.load();
132         configTest(config);
133     }
134 
135     /**
136      * Ensure various node types are correctly processed in config.
137      * @throws Exception
138      */
139     @Test
140     public void testXmlNodeTypes() throws Exception
141     {
142         // Number of keys expected from test configuration file
143         final int KEY_COUNT = 5;
144 
145         // Load the configuration file
146         config.load(new File(TEST_FILE2).getAbsoluteFile().toURI().toURL());
147 
148         // Validate comment in element ignored
149         assertEquals("Comment in element must not change element value.", "Case1Text", config
150                 .getString("case1"));
151 
152         // Validate sibling comment ignored
153         assertEquals("Comment as sibling must not change element value.", "Case2Text", config
154                 .getString("case2.child"));
155 
156         // Validate comment ignored, CDATA processed
157         assertEquals("Comment and use of CDATA must not change element value.", "Case3Text", config
158                 .getString("case3"));
159 
160         // Validate comment and processing instruction ignored
161         assertEquals("Comment and use of PI must not change element value.", "Case4Text", config
162                 .getString("case4"));
163 
164         // Validate comment ignored in parent attribute
165         assertEquals("Comment must not change attribute node value.", "Case5Text", config
166                 .getString("case5[@attr]"));
167 
168         // Validate non-text nodes haven't snuck in as keys
169         Iterator<String> iter = config.getKeys();
170         int count = 0;
171         while (iter.hasNext())
172         {
173             iter.next();
174             count++;
175         }
176         assertEquals("Config must contain only " + KEY_COUNT + " keys.", KEY_COUNT, count);
177     }
178 
179     @Test
180     public void testSave() throws Exception
181     {
182         config.setFileName(TEST_FILE3);
183         config.load();
184         File saveFile = folder.newFile(TEST_SAVENAME);
185         config.save(saveFile);
186 
187         config = new XMLConfiguration();
188         config.load(saveFile.toURI().toURL());
189         assertEquals("value", config.getProperty("element"));
190         assertEquals("I'm complex!", config.getProperty("element2.subelement.subsubelement"));
191         assertEquals(8, config.getInt("test.short"));
192         assertEquals("one", config.getString("list(0).item(0)[@name]"));
193         assertEquals("two", config.getString("list(0).item(1)"));
194         assertEquals("six", config.getString("list(1).sublist.item(1)"));
195     }
196 
197     /**
198      * Tests to save a newly created configuration.
199      */
200     @Test
201     public void testSaveNew() throws Exception
202     {
203         config.addProperty("connection.url", "jdbc://mydb:1234");
204         config.addProperty("connection.user", "scott");
205         config.addProperty("connection.passwd", "tiger");
206         config.addProperty("connection[@type]", "system");
207         config.addProperty("tables.table.name", "tests");
208         config.addProperty("tables.table(0).fields.field.name", "test_id");
209         config.addProperty("tables.table(0).fields.field(-1).name", "test_name");
210         config.addProperty("tables.table(-1).name", "results");
211         config.addProperty("tables.table(1).fields.field.name", "res_id");
212         config.addProperty("tables.table(1).fields.field(0).type", "int");
213         config.addProperty("tables.table(1).fields.field(-1).name", "value");
214         config.addProperty("tables.table(1).fields.field(1).type", "string");
215         config.addProperty("tables.table(1).fields.field(1)[@null]", "true");
216 
217         File saveFile = folder.newFile(TEST_SAVENAME);
218         config.setFile(saveFile);
219         config.setRootElementName("myconfig");
220         config.save();
221 
222         config = new XMLConfiguration();
223         config.load(saveFile);
224         assertEquals(1, config.getMaxIndex("tables.table.name"));
225         assertEquals("tests", config.getString("tables.table(0).name"));
226         assertEquals("test_name", config.getString("tables.table(0).fields.field(1).name"));
227         assertEquals("int", config.getString("tables.table(1).fields.field(0).type"));
228         assertTrue(config.getBoolean("tables.table(1).fields.field(1)[@null]"));
229         assertEquals("tiger", config.getString("connection.passwd"));
230         assertEquals("system", config.getProperty("connection[@type]"));
231         assertEquals("myconfig", config.getRootElementName());
232     }
233 
234     /**
235      * Tests to save a modified configuration.
236      */
237     @Test
238     public void testSaveModified() throws Exception
239     {
240         config.setFile(new File(TEST_FILE3));
241         config.load();
242 
243         assertTrue(config.getString("mean").startsWith("This is\n A long story..."));
244         assertTrue(config.getString("mean").indexOf("And even longer") > 0);
245         config.clearProperty("test.entity[@name]");
246         config.setProperty("element", "new value");
247         config.setProperty("test(0)", "A <new> value");
248         config.addProperty("test(1).int", new Integer(9));
249         config.addProperty("list(1).sublist.item", "seven");
250         config.setProperty("clear", "yes");
251         config.setProperty("mean", "now it's simple");
252         config.addProperty("[@topattr]", "available");
253         config.addProperty("[@topattr]", "successfull");
254 
255         File saveFile = folder.newFile(TEST_SAVENAME);
256         config.save(saveFile);
257         config = new XMLConfiguration();
258         config.load(saveFile.getAbsolutePath());
259         assertFalse(config.containsKey("test.entity[@name]"));
260         assertEquals("1<2", config.getProperty("test.entity"));
261         assertEquals("new value", config.getString("element"));
262         assertEquals("A <new> value", config.getProperty("test(0)"));
263         assertEquals((short) 8, config.getShort("test(1).short"));
264         assertEquals(9, config.getInt("test(1).int"));
265         assertEquals("six", config.getProperty("list(1).sublist.item(1)"));
266         assertEquals("seven", config.getProperty("list(1).sublist.item(2)"));
267         assertEquals("yes", config.getProperty("clear"));
268         assertEquals("now it's simple", config.getString("mean"));
269         assertEquals("available", config.getString("[@topattr](0)"));
270         assertEquals("successfull", config.getString("[@topattr](1)"));
271     }
272 
273     /**
274      * Tests manipulation of the root element's name.
275      */
276     @Test
277     public void testRootElement() throws Exception
278     {
279         assertEquals("configuration", config.getRootElementName());
280         config.setRootElementName("newRootName");
281         assertEquals("newRootName", config.getRootElementName());
282     }
283 
284     /**
285      * Tests that it is not allowed to change the root element name when the
286      * configuration was loaded from a file.
287      */
288     @Test(expected = UnsupportedOperationException.class)
289     public void testSetRootElementNameWhenLoadedFromFile() throws Exception
290     {
291         config.setFile(new File(TEST_FILE3));
292         config.load();
293         assertEquals("testconfig", config.getRootElementName());
294         config.setRootElementName("anotherRootElement");
295     }
296 }