001 package org.apache.commons.configuration; 002 003 /* 004 * Licensed to the Apache Software Foundation (ASF) under one or more 005 * contributor license agreements. See the NOTICE file distributed with 006 * this work for additional information regarding copyright ownership. 007 * The ASF licenses this file to You under the Apache License, Version 2.0 008 * (the "License"); you may not use this file except in compliance with 009 * the License. You may obtain a copy of the License at 010 * 011 * http://www.apache.org/licenses/LICENSE-2.0 012 * 013 * Unless required by applicable law or agreed to in writing, software 014 * distributed under the License is distributed on an "AS IS" BASIS, 015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 016 * See the License for the specific language governing permissions and 017 * limitations under the License. 018 */ 019 020 import static org.junit.Assert.assertEquals; 021 import static org.junit.Assert.assertFalse; 022 import static org.junit.Assert.assertTrue; 023 024 import java.io.File; 025 import java.util.Collection; 026 import java.util.Iterator; 027 028 import org.junit.Before; 029 import org.junit.Rule; 030 import org.junit.Test; 031 import org.junit.rules.TemporaryFolder; 032 033 /** 034 * Test class for XMLConfiguration. In addition to TestXMLConfiguration this 035 * class especially tests the hierarchical nature of this class and structured 036 * data access. 037 * 038 * @author Emmanuel Bourg 039 * @author Mark Woodman 040 * @version $Id: TestHierarchicalXMLConfiguration.java 1224764 2011-12-26 17:14:49Z oheger $ 041 */ 042 public class TestHierarchicalXMLConfiguration 043 { 044 /** Test resources directory. */ 045 private static final String TEST_DIR = "conf"; 046 047 /** Test file #1 **/ 048 private static final String TEST_FILENAME = "testHierarchicalXMLConfiguration.xml"; 049 050 /** Test file #2 **/ 051 private static final String TEST_FILENAME2 = "testHierarchicalXMLConfiguration2.xml"; 052 053 /** Test file path #1 **/ 054 private static final String TEST_FILE = ConfigurationAssert.getTestFile(TEST_FILENAME).getAbsolutePath(); 055 056 /** Test file path #2 **/ 057 private static final String TEST_FILE2 = ConfigurationAssert.getTestFile(TEST_FILENAME2).getAbsolutePath(); 058 059 /** Test file path #3.*/ 060 private static final String TEST_FILE3 = ConfigurationAssert.getTestFile("test.xml").getAbsolutePath(); 061 062 /** File name for saving.*/ 063 private static final String TEST_SAVENAME = "testhierarchicalsave.xml"; 064 065 /** Helper object for creating temporary files. */ 066 @Rule 067 public TemporaryFolder folder = new TemporaryFolder(); 068 069 /** Instance config used for tests. */ 070 private XMLConfiguration config; 071 072 /** Fixture setup. */ 073 @Before 074 public void setUp() throws Exception 075 { 076 config = new XMLConfiguration(); 077 } 078 079 private void configTest(XMLConfiguration config) 080 { 081 assertEquals(1, config.getMaxIndex("tables.table")); 082 assertEquals("system", config.getProperty("tables.table(0)[@tableType]")); 083 assertEquals("application", config.getProperty("tables.table(1)[@tableType]")); 084 085 assertEquals("users", config.getProperty("tables.table(0).name")); 086 assertEquals("documents", config.getProperty("tables.table(1).name")); 087 088 Object prop = config.getProperty("tables.table.fields.field.name"); 089 assertTrue(prop instanceof Collection); 090 assertEquals(10, ((Collection<?>) prop).size()); 091 092 prop = config.getProperty("tables.table(0).fields.field.type"); 093 assertTrue(prop instanceof Collection); 094 assertEquals(5, ((Collection<?>) prop).size()); 095 096 prop = config.getProperty("tables.table(1).fields.field.type"); 097 assertTrue(prop instanceof Collection); 098 assertEquals(5, ((Collection<?>) prop).size()); 099 } 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 }