001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 018 package org.apache.commons.configuration.plist; 019 020 import static org.junit.Assert.assertEquals; 021 import static org.junit.Assert.assertFalse; 022 import static org.junit.Assert.assertNotNull; 023 import static org.junit.Assert.assertTrue; 024 025 import java.io.File; 026 import java.util.Calendar; 027 import java.util.Iterator; 028 import java.util.List; 029 import java.util.TimeZone; 030 031 import junitx.framework.ArrayAssert; 032 import junitx.framework.ListAssert; 033 import junitx.framework.ObjectAssert; 034 035 import org.apache.commons.configuration.Configuration; 036 import org.apache.commons.configuration.ConfigurationAssert; 037 import org.apache.commons.configuration.ConfigurationComparator; 038 import org.apache.commons.configuration.ConfigurationException; 039 import org.apache.commons.configuration.FileConfiguration; 040 import org.apache.commons.configuration.HierarchicalConfiguration; 041 import org.apache.commons.configuration.StrictConfigurationComparator; 042 import org.junit.Before; 043 import org.junit.Test; 044 045 /** 046 * @author Emmanuel Bourg 047 * @version $Id: TestXMLPropertyListConfiguration.java 1367253 2012-07-30 19:59:36Z oheger $ 048 */ 049 public class TestXMLPropertyListConfiguration 050 { 051 private FileConfiguration config; 052 053 @Before 054 public void setUp() throws Exception 055 { 056 config = new XMLPropertyListConfiguration(); 057 config.setFile(ConfigurationAssert.getTestFile("test.plist.xml")); 058 config.load(); 059 } 060 061 @Test 062 public void testString() throws Exception 063 { 064 assertEquals("'string' property", "value1", config.getString("string")); 065 } 066 067 @Test 068 public void testInteger() throws Exception 069 { 070 assertEquals("'integer' property", 12345678900L, config.getLong("integer")); 071 } 072 073 @Test 074 public void testReal() throws Exception 075 { 076 assertEquals("'real' property", -12.345, config.getDouble("real"), 0); 077 } 078 079 @Test 080 public void testBoolean() throws Exception 081 { 082 assertEquals("'boolean1' property", true, config.getBoolean("boolean1")); 083 assertEquals("'boolean2' property", false, config.getBoolean("boolean2")); 084 } 085 086 @Test 087 public void testDictionary() 088 { 089 assertEquals("1st element", "value1", config.getProperty("dictionary.key1")); 090 assertEquals("2nd element", "value2", config.getProperty("dictionary.key2")); 091 assertEquals("3rd element", "value3", config.getProperty("dictionary.key3")); 092 } 093 094 @Test 095 public void testDate() throws Exception 096 { 097 Calendar calendar = Calendar.getInstance(); 098 calendar.clear(); 099 calendar.setTimeZone(TimeZone.getTimeZone("UTC")); 100 calendar.set(2005, Calendar.JANUARY, 1, 12, 0, 0); 101 102 assertEquals("'date' property", calendar.getTime(), config.getProperty("date")); 103 104 calendar.setTimeZone(TimeZone.getTimeZone("CET")); 105 calendar.set(2002, Calendar.MARCH, 22, 11, 30, 0); 106 107 assertEquals("'date-gnustep' property", calendar.getTime(), config.getProperty("date-gnustep")); 108 } 109 110 @Test 111 public void testSubset() 112 { 113 Configuration subset = config.subset("dictionary"); 114 Iterator<String> keys = subset.getKeys(); 115 116 String key = keys.next(); 117 assertEquals("1st key", "key1", key); 118 assertEquals("1st value", "value1", subset.getString(key)); 119 120 key = keys.next(); 121 assertEquals("2nd key", "key2", key); 122 assertEquals("2nd value", "value2", subset.getString(key)); 123 124 key = keys.next(); 125 assertEquals("3rd key", "key3", key); 126 assertEquals("3rd value", "value3", subset.getString(key)); 127 128 assertFalse("more than 3 properties founds", keys.hasNext()); 129 } 130 131 @Test 132 public void testArray() 133 { 134 Object array = config.getProperty("array"); 135 136 assertNotNull("array not found", array); 137 ObjectAssert.assertInstanceOf("the array element is not parsed as a List", List.class, array); 138 List<?> list = config.getList("array"); 139 140 assertFalse("empty array", list.isEmpty()); 141 assertEquals("size", 3, list.size()); 142 assertEquals("1st element", "value1", list.get(0)); 143 assertEquals("2nd element", "value2", list.get(1)); 144 assertEquals("3rd element", "value3", list.get(2)); 145 } 146 147 @Test 148 public void testNestedArray() 149 { 150 String key = "nested-array"; 151 152 Object array = config.getProperty(key); 153 154 // root array 155 assertNotNull("array not found", array); 156 ObjectAssert.assertInstanceOf("the array element is not parsed as a List", List.class, array); 157 List<?> list = config.getList(key); 158 159 assertFalse("empty array", list.isEmpty()); 160 assertEquals("size", 2, list.size()); 161 162 // 1st array 163 ObjectAssert.assertInstanceOf("the array element is not parsed as a List", List.class, list.get(0)); 164 List<?> list1 = (List<?>) list.get(0); 165 assertFalse("nested array 1 is empty", list1.isEmpty()); 166 assertEquals("size", 2, list1.size()); 167 assertEquals("1st element", "a", list1.get(0)); 168 assertEquals("2nd element", "b", list1.get(1)); 169 170 // 2nd array 171 ObjectAssert.assertInstanceOf("the array element is not parsed as a List", List.class, list.get(1)); 172 List<?> list2 = (List<?>) list.get(1); 173 assertFalse("nested array 2 is empty", list2.isEmpty()); 174 assertEquals("size", 2, list2.size()); 175 assertEquals("1st element", "c", list2.get(0)); 176 assertEquals("2nd element", "d", list2.get(1)); 177 } 178 179 @Test 180 public void testDictionaryArray() 181 { 182 String key = "dictionary-array"; 183 184 Object array = config.getProperty(key); 185 186 // root array 187 assertNotNull("array not found", array); 188 ObjectAssert.assertInstanceOf("the array element is not parsed as a List", List.class, array); 189 List<?> list = config.getList(key); 190 191 assertFalse("empty array", list.isEmpty()); 192 assertEquals("size", 2, list.size()); 193 194 // 1st dictionary 195 ObjectAssert.assertInstanceOf("the dict element is not parsed as a Configuration", Configuration.class, list.get(0)); 196 Configuration conf1 = (Configuration) list.get(0); 197 assertFalse("configuration 1 is empty", conf1.isEmpty()); 198 assertEquals("configuration element", "bar", conf1.getProperty("foo")); 199 200 // 2nd dictionary 201 ObjectAssert.assertInstanceOf("the dict element is not parsed as a Configuration", Configuration.class, list.get(1)); 202 Configuration conf2 = (Configuration) list.get(1); 203 assertFalse("configuration 2 is empty", conf2.isEmpty()); 204 assertEquals("configuration element", "value", conf2.getProperty("key")); 205 } 206 207 @Test 208 public void testNested() 209 { 210 assertEquals("nested property", "value", config.getString("nested.node1.node2.node3")); 211 } 212 213 @Test 214 public void testSave() throws Exception 215 { 216 File savedFile = new File("target/testsave.plist.xml"); 217 218 // remove the file previously saved if necessary 219 if (savedFile.exists()) 220 { 221 assertTrue(savedFile.delete()); 222 } 223 224 // add an array of strings to the configuration 225 /* 226 config.addProperty("string", "value1"); 227 List list = new ArrayList(); 228 for (int i = 1; i < 5; i++) 229 { 230 list.add("value" + i); 231 } 232 config.addProperty("newarray", list);*/ 233 // todo : investigate why the array structure of 'newarray' is lost in the saved file 234 235 // add a map of strings 236 /* 237 Map map = new HashMap(); 238 map.put("foo", "bar"); 239 map.put("int", new Integer(123)); 240 config.addProperty("newmap", map); 241 */ 242 // todo : a Map added to a HierarchicalConfiguration should be decomposed as list of nodes 243 244 // save the configuration 245 String filename = savedFile.getAbsolutePath(); 246 config.save(filename); 247 248 assertTrue("The saved file doesn't exist", savedFile.exists()); 249 250 // read the configuration and compare the properties 251 Configuration checkConfig = new XMLPropertyListConfiguration(new File(filename)); 252 253 Iterator<String> it = config.getKeys(); 254 while (it.hasNext()) 255 { 256 String key = it.next(); 257 assertTrue("The saved configuration doesn't contain the key '" + key + "'", checkConfig.containsKey(key)); 258 259 Object value = checkConfig.getProperty(key); 260 if (value instanceof byte[]) 261 { 262 byte[] array = (byte[]) value; 263 ArrayAssert.assertEquals("Value of the '" + key + "' property", (byte[]) config.getProperty(key), array); 264 } 265 else if (value instanceof List) 266 { 267 List<?> list1 = (List<?>) config.getProperty(key); 268 List<?> list2 = (List<?>) value; 269 270 assertEquals("The size of the list for the key '" + key + "' doesn't match", list1.size(), list2.size()); 271 272 for (int i = 0; i < list2.size(); i++) 273 { 274 Object value1 = list1.get(i); 275 Object value2 = list2.get(i); 276 277 if (value1 instanceof Configuration) 278 { 279 ConfigurationComparator comparator = new StrictConfigurationComparator(); 280 assertTrue("The dictionnary at index " + i + " for the key '" + key + "' doesn't match", comparator.compare((Configuration) value1, (Configuration) value2)); 281 } 282 else 283 { 284 assertEquals("Element at index " + i + " for the key '" + key + "'", value1, value2); 285 } 286 } 287 288 ListAssert.assertEquals("Value of the '" + key + "' property", (List<?>) config.getProperty(key), list1); 289 } 290 else 291 { 292 assertEquals("Value of the '" + key + "' property", config.getProperty(key), checkConfig.getProperty(key)); 293 } 294 295 } 296 } 297 298 @Test 299 public void testSaveEmptyDictionary() throws Exception 300 { 301 File savedFile = new File("target/testsave.plist.xml"); 302 303 // remove the file previously saved if necessary 304 if (savedFile.exists()) 305 { 306 assertTrue(savedFile.delete()); 307 } 308 309 // save the configuration 310 String filename = savedFile.getAbsolutePath(); 311 config.save(filename); 312 313 assertTrue("The saved file doesn't exist", savedFile.exists()); 314 315 // read the configuration and compare the properties 316 Configuration checkConfig = new XMLPropertyListConfiguration(new File(filename)); 317 318 assertEquals(null, config.getProperty("empty-dictionary")); 319 assertEquals(null, checkConfig.getProperty("empty-dictionary")); 320 } 321 322 /** 323 * Ensure that setProperty doesn't alter an array of byte 324 * since it's a first class type in plist file 325 */ 326 @Test 327 public void testSetDataProperty() throws Exception 328 { 329 byte[] expected = new byte[]{1, 2, 3, 4}; 330 XMLPropertyListConfiguration config = new XMLPropertyListConfiguration(); 331 config.setProperty("foo", expected); 332 config.save("target/testdata.plist.xml"); 333 334 XMLPropertyListConfiguration config2 = new XMLPropertyListConfiguration("target/testdata.plist.xml"); 335 Object array = config2.getProperty("foo"); 336 337 assertNotNull("data not found", array); 338 assertEquals("property type", byte[].class, array.getClass()); 339 ArrayAssert.assertEquals(expected, (byte[]) array); 340 } 341 342 /** 343 * Ensure that addProperty doesn't alter an array of byte 344 */ 345 @Test 346 public void testAddDataProperty() throws Exception 347 { 348 byte[] expected = new byte[]{1, 2, 3, 4}; 349 XMLPropertyListConfiguration config = new XMLPropertyListConfiguration(); 350 config.addProperty("foo", expected); 351 config.save("target/testdata.plist.xml"); 352 353 XMLPropertyListConfiguration config2 = new XMLPropertyListConfiguration("target/testdata.plist.xml"); 354 Object array = config2.getProperty("foo"); 355 356 assertNotNull("data not found", array); 357 assertEquals("property type", byte[].class, array.getClass()); 358 ArrayAssert.assertEquals(expected, (byte[]) array); 359 } 360 361 @Test 362 public void testInitCopy() 363 { 364 XMLPropertyListConfiguration copy = new XMLPropertyListConfiguration((HierarchicalConfiguration) config); 365 StrictConfigurationComparator comp = new StrictConfigurationComparator(); 366 assertTrue("Configurations are not equal", comp.compare(config, copy)); 367 } 368 369 /** 370 * Tests whether a configuration can be loaded that does not start with a 371 * {@code dict} element. This test case is related to 372 * CONFIGURATION-405. 373 */ 374 @Test 375 public void testLoadNoDict() throws ConfigurationException 376 { 377 XMLPropertyListConfiguration plist = new XMLPropertyListConfiguration(); 378 plist.setFile(ConfigurationAssert.getTestFile("test2.plist.xml")); 379 plist.load(); 380 assertFalse("Configuration is empty", plist.isEmpty()); 381 } 382 383 /** 384 * Tests whether a configuration that does not start with a 385 * {@code dict} element can be loaded from a constructor. This test 386 * case is related to CONFIGURATION-405. 387 */ 388 @Test 389 public void testLoadNoDictConstr() throws ConfigurationException 390 { 391 XMLPropertyListConfiguration plist = new XMLPropertyListConfiguration( 392 ConfigurationAssert.getTestFile("test2.plist.xml")); 393 assertFalse("Configuration is empty", plist.isEmpty()); 394 } 395 396 /** 397 * Tests a configuration file which contains an invalid date property value. 398 * This test is related to CONFIGURATION-501. 399 */ 400 @Test 401 public void testSetDatePropertyInvalid() throws ConfigurationException 402 { 403 config.clear(); 404 config.setFile(ConfigurationAssert.getTestFile("test_invalid_date.plist.xml")); 405 config.load(); 406 assertEquals("'string' property", "value1", config.getString("string")); 407 assertFalse("Date property was loaded", config.containsKey("date")); 408 } 409 }