1 /* Licensed to the Apache Software Foundation (ASF) under one or more 2 * contributor license agreements. See the NOTICE file distributed with 3 * this work for additional information regarding copyright ownership. 4 * The ASF licenses this file to You under the Apache License, Version 2.0 5 * (the "License"); you may not use this file except in compliance with 6 * the License. You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package libcore.java.util.prefs; 18 19 import java.io.File; 20 import java.io.IOException; 21 import java.io.OutputStream; 22 import java.util.Arrays; 23 import java.util.prefs.BackingStoreException; 24 import java.util.prefs.NodeChangeEvent; 25 import java.util.prefs.NodeChangeListener; 26 import java.util.prefs.PreferenceChangeEvent; 27 import java.util.prefs.PreferenceChangeListener; 28 import java.util.prefs.Preferences; 29 import java.util.prefs.PreferencesFactory; 30 import junit.framework.TestCase; 31 32 import libcore.testing.io.TestIoUtils; 33 34 public final class OldPreferencesTest extends TestCase { 35 36 private static final boolean ENCOURAGE_RACES = false; 37 38 private static final String longKey; 39 private static final String longValue; 40 41 static { 42 StringBuilder key = new StringBuilder(Preferences.MAX_KEY_LENGTH); 43 for (int i = 0; i < Preferences.MAX_KEY_LENGTH; i++) { 44 key.append('a'); 45 } 46 longKey = key.toString(); 47 48 StringBuilder value = new StringBuilder(Preferences.MAX_VALUE_LENGTH); 49 for (int i = 0; i < Preferences.MAX_VALUE_LENGTH; i++) { 50 value.append('a'); 51 } 52 longValue = value.toString(); 53 } 54 55 private PreferencesFactory defaultFactory; 56 57 @Override setUp()58 protected void setUp() throws Exception { 59 super.setUp(); 60 final File tmpDir = TestIoUtils.createTemporaryDirectory("OldPreferenceTest"); 61 defaultFactory = Preferences.setPreferencesFactory( 62 new PreferencesTest.TestPreferencesFactory(tmpDir.getAbsolutePath())); 63 64 Preferences pref = Preferences.userNodeForPackage(Preferences.class); 65 for (String child : pref.childrenNames()) { 66 pref.node(child).removeNode(); 67 } 68 pref.clear(); 69 } 70 71 @Override tearDown()72 protected void tearDown() throws Exception { 73 Preferences.setPreferencesFactory(defaultFactory); 74 } 75 testAbstractMethods()76 public void testAbstractMethods() throws IOException, BackingStoreException { 77 Preferences p = new MockPreferences(); 78 p.absolutePath(); 79 p.childrenNames(); 80 p.clear(); 81 p.exportNode(null); 82 p.exportSubtree(null); 83 p.flush(); 84 p.get(null, null); 85 p.getBoolean(null, false); 86 p.getByteArray(null, null); 87 p.getFloat(null, 0.1f); 88 p.getDouble(null, 0.1); 89 p.getInt(null, 1); 90 p.getLong(null, 1l); 91 p.isUserNode(); 92 p.keys(); 93 p.name(); 94 p.node(null); 95 p.nodeExists(null); 96 p.parent(); 97 p.put(null, null); 98 p.putBoolean(null, false); 99 p.putByteArray(null, null); 100 p.putDouble(null, 1); 101 p.putFloat(null, 1f); 102 p.putInt(null, 1); 103 p.putLong(null, 1l); 104 p.remove(null); 105 p.removeNode(); 106 p.addNodeChangeListener(null); 107 p.addPreferenceChangeListener(null); 108 p.removeNodeChangeListener(null); 109 p.removePreferenceChangeListener(null); 110 p.sync(); 111 p.toString(); 112 } 113 testConstructor()114 public void testConstructor() { 115 MockPreferences mp = new MockPreferences(); 116 assertEquals(mp.getClass(), MockPreferences.class); 117 } 118 testToString()119 public void testToString() { 120 Preferences p1 = Preferences.userNodeForPackage(Preferences.class); 121 assertNotNull(p1.toString()); 122 123 Preferences p2 = Preferences.systemRoot(); 124 assertNotNull(p2.toString()); 125 126 Preferences p3 = Preferences.userRoot(); 127 assertNotNull(p3.toString()); 128 } 129 testAbsolutePath()130 public void testAbsolutePath() { 131 Preferences p = Preferences.userNodeForPackage(Preferences.class); 132 assertEquals("/java/util/prefs", p.absolutePath()); 133 134 } 135 testChildrenNames()136 public void testChildrenNames() throws BackingStoreException { 137 Preferences pref = Preferences.userNodeForPackage(Preferences.class); 138 139 Preferences child1 = pref.node("child1"); 140 141 pref.node("child2"); 142 pref.node("child3"); 143 child1.node("subchild1"); 144 145 assertSame(pref, child1.parent()); 146 assertEquals(3, pref.childrenNames().length); 147 assertEquals("child1", pref.childrenNames()[0]); 148 assertEquals(1, child1.childrenNames().length); 149 assertEquals("subchild1", child1.childrenNames()[0]); 150 } 151 testClear()152 public void testClear() throws BackingStoreException { 153 Preferences pref = Preferences.userNodeForPackage(Preferences.class); 154 pref.put("testClearKey", "testClearValue"); 155 pref.put("testClearKey1", "testClearValue1"); 156 assertEquals("testClearValue", pref.get("testClearKey", null)); 157 assertEquals("testClearValue1", pref.get("testClearKey1", null)); 158 pref.clear(); 159 assertNull(pref.get("testClearKey", null)); 160 assertNull(pref.get("testClearKey1", null)); 161 } 162 testGet()163 public void testGet() throws BackingStoreException { 164 Preferences root = Preferences.userNodeForPackage(Preferences.class); 165 Preferences pref = root.node("mock"); 166 assertNull(pref.get("", null)); 167 assertEquals("default", pref.get("key", "default")); 168 assertNull(pref.get("key", null)); 169 pref.put("testGetkey", "value"); 170 assertNull(pref.get("testGetKey", null)); 171 assertEquals("value", pref.get("testGetkey", null)); 172 173 try { 174 pref.get(null, "abc"); 175 fail(); 176 } catch (NullPointerException expected) { 177 } 178 pref.get("", "abc"); 179 pref.get("key", null); 180 pref.get("key", ""); 181 pref.putFloat("floatKey", 1.0f); 182 assertEquals("1.0", pref.get("floatKey", null)); 183 184 pref.removeNode(); 185 try { 186 pref.get("key", "abc"); 187 fail(); 188 } catch (IllegalStateException expected) { 189 } 190 try { 191 pref.get(null, "abc"); 192 fail(); 193 } catch (NullPointerException expected) { 194 } 195 } 196 testGetBoolean()197 public void testGetBoolean() { 198 Preferences pref = Preferences.userNodeForPackage(Preferences.class); 199 try { 200 pref.getBoolean(null, false); 201 fail(); 202 } catch (NullPointerException expected) { 203 } 204 205 pref.put("testGetBooleanKey", "false"); 206 pref.put("testGetBooleanKey2", "value"); 207 assertFalse(pref.getBoolean("testGetBooleanKey", true)); 208 assertTrue(pref.getBoolean("testGetBooleanKey2", true)); 209 } 210 testGetByteArray()211 public void testGetByteArray() { 212 Preferences pref = Preferences.userNodeForPackage(Preferences.class); 213 try { 214 pref.getByteArray(null, new byte[0]); 215 fail(); 216 } catch (NullPointerException expected) { 217 } 218 byte[] b64Array = new byte[] { 0x59, 0x57, 0x4a, 0x6a };// BASE64 219 220 pref.put("testGetByteArrayKey", "abc="); 221 pref.put("testGetByteArrayKey2", new String(b64Array)); 222 pref.put("invalidKey", "<>?"); 223 assertTrue(Arrays.equals(new byte[] { 105, -73 }, pref.getByteArray( 224 "testGetByteArrayKey", new byte[0]))); 225 assertTrue(Arrays.equals(new byte[] { 'a', 'b', 'c' }, pref 226 .getByteArray("testGetByteArrayKey2", new byte[0]))); 227 assertTrue(Arrays.equals(new byte[0], pref.getByteArray("invalidKey", 228 new byte[0]))); 229 230 pref.putByteArray("testGetByteArrayKey3", b64Array); 231 pref.putByteArray("testGetByteArrayKey4", "abc".getBytes()); 232 assertTrue(Arrays.equals(b64Array, pref.getByteArray( 233 "testGetByteArrayKey3", new byte[0]))); 234 assertTrue(Arrays.equals("abc".getBytes(), pref.getByteArray( 235 "testGetByteArrayKey4", new byte[0]))); 236 } 237 testGetDouble()238 public void testGetDouble() { 239 Preferences pref = Preferences.userNodeForPackage(Preferences.class); 240 try { 241 pref.getDouble(null, 0); 242 fail(); 243 } catch (NullPointerException expected) { 244 } 245 246 pref.put("testGetDoubleKey", "1"); 247 pref.put("testGetDoubleKey2", "value"); 248 pref.putDouble("testGetDoubleKey3", 1); 249 pref.putInt("testGetDoubleKey4", 1); 250 assertEquals(1.0, pref.getDouble("testGetDoubleKey", 0.0), 0); 251 assertEquals(0.0, pref.getDouble("testGetDoubleKey2", 0.0), 0); 252 assertEquals(1.0, pref.getDouble("testGetDoubleKey3", 0.0), 0); 253 assertEquals(1.0, pref.getDouble("testGetDoubleKey4", 0.0), 0); 254 } 255 testGetFloat()256 public void testGetFloat() { 257 Preferences pref = Preferences.userNodeForPackage(Preferences.class); 258 try { 259 pref.getFloat(null, 0f); 260 fail(); 261 } catch (NullPointerException expected) { 262 } 263 pref.put("testGetFloatKey", "1"); 264 pref.put("testGetFloatKey2", "value"); 265 assertEquals(1f, pref.getFloat("testGetFloatKey", 0f), 0); 266 assertEquals(0f, pref.getFloat("testGetFloatKey2", 0f), 0); 267 } 268 testGetInt()269 public void testGetInt() { 270 Preferences pref = Preferences.userNodeForPackage(Preferences.class); 271 try { 272 pref.getInt(null, 0); 273 fail(); 274 } catch (NullPointerException expected) { 275 } 276 277 pref.put("testGetIntKey", "1"); 278 pref.put("testGetIntKey2", "value"); 279 assertEquals(1, pref.getInt("testGetIntKey", 0)); 280 assertEquals(0, pref.getInt("testGetIntKey2", 0)); 281 } 282 testGetLong()283 public void testGetLong() { 284 Preferences pref = Preferences.userNodeForPackage(Preferences.class); 285 try { 286 pref.getLong(null, 0); 287 fail(); 288 } catch (NullPointerException expected) { 289 } 290 291 pref.put("testGetLongKey", "1"); 292 pref.put("testGetLongKey2", "value"); 293 assertEquals(1, pref.getInt("testGetLongKey", 0)); 294 assertEquals(0, pref.getInt("testGetLongKey2", 0)); 295 } 296 testIsUserNode()297 public void testIsUserNode() { 298 Preferences pref1 = Preferences.userNodeForPackage(Preferences.class); 299 assertTrue(pref1.isUserNode()); 300 301 Preferences pref2 = Preferences.systemNodeForPackage(Preferences.class); 302 assertFalse(pref2.isUserNode()); 303 } 304 testKeys()305 public void testKeys() throws BackingStoreException { 306 Preferences pref = Preferences.userNodeForPackage(Preferences.class); 307 pref.clear(); 308 309 pref.put("key0", "value"); 310 pref.put("key1", "value1"); 311 pref.put("key2", "value2"); 312 pref.put("key3", "value3"); 313 314 String[] keys = pref.keys(); 315 assertEquals(4, keys.length); 316 for (String key : keys) { 317 assertEquals(0, key.indexOf("key")); 318 assertEquals(4, key.length()); 319 } 320 } 321 testName()322 public void testName() { 323 Preferences pref = Preferences.userNodeForPackage(Preferences.class); 324 Preferences child = pref.node("mock"); 325 assertEquals("mock", child.name()); 326 } 327 testNode()328 public void testNode() throws BackingStoreException { 329 StringBuilder name = new StringBuilder(Preferences.MAX_NAME_LENGTH); 330 for (int i = 0; i < Preferences.MAX_NAME_LENGTH; i++) { 331 name.append('a'); 332 } 333 String longName = name.toString(); 334 335 Preferences root = Preferences.userRoot(); 336 Preferences parent = Preferences.userNodeForPackage(Preferences.class); 337 Preferences pref = parent.node("mock"); 338 339 try { 340 pref.node(null); 341 fail(); 342 } catch (NullPointerException expected) { 343 } 344 try { 345 pref.node("/java/util/prefs/"); 346 fail(); 347 } catch (IllegalArgumentException expected) { 348 } 349 try { 350 pref.node("/java//util/prefs"); 351 fail(); 352 } catch (IllegalArgumentException expected) { 353 } 354 try { 355 pref.node(longName + "a"); 356 fail(); 357 } catch (IllegalArgumentException expected) { 358 } 359 assertNotNull(pref.node(longName)); 360 361 assertSame(root, pref.node("/")); 362 363 Preferences prefs = pref.node("/java/util/prefs"); 364 assertSame(prefs, parent); 365 366 assertSame(pref, pref.node("")); 367 } 368 testNodeExists()369 public void testNodeExists() throws BackingStoreException { 370 371 Preferences parent = Preferences.userNodeForPackage(Preferences.class); 372 Preferences pref = parent.node("mock"); 373 374 try { 375 pref.nodeExists(null); 376 fail(); 377 } catch (NullPointerException expected) { 378 } 379 try { 380 pref.nodeExists("/java/util/prefs/"); 381 fail(); 382 } catch (IllegalArgumentException expected) { 383 } 384 try { 385 pref.nodeExists("/java//util/prefs"); 386 fail(); 387 } catch (IllegalArgumentException expected) { 388 } 389 390 assertTrue(pref.nodeExists("/")); 391 392 assertTrue(pref.nodeExists("/java/util/prefs")); 393 394 assertTrue(pref.nodeExists("")); 395 396 assertFalse(pref.nodeExists("child")); 397 Preferences grandchild = pref.node("child/grandchild"); 398 assertTrue(pref.nodeExists("child")); 399 assertTrue(pref.nodeExists("child/grandchild")); 400 grandchild.removeNode(); 401 assertTrue(pref.nodeExists("child")); 402 assertFalse(pref.nodeExists("child/grandchild")); 403 assertFalse(grandchild.nodeExists("")); 404 405 assertFalse(pref.nodeExists("child2/grandchild")); 406 pref.node("child2/grandchild"); 407 assertTrue(pref.nodeExists("child2/grandchild")); 408 } 409 testParent()410 public void testParent() { 411 Preferences parent = Preferences.userNodeForPackage(Preferences.class); 412 Preferences pref = parent.node("mock"); 413 414 assertSame(parent, pref.parent()); 415 } 416 testPut()417 public void testPut() throws BackingStoreException { 418 Preferences pref = Preferences.userNodeForPackage(Preferences.class); 419 pref.put("", "emptyvalue"); 420 assertEquals("emptyvalue", pref.get("", null)); 421 pref.put("testPutkey", "value1"); 422 assertEquals("value1", pref.get("testPutkey", null)); 423 pref.put("testPutkey", "value2"); 424 assertEquals("value2", pref.get("testPutkey", null)); 425 426 pref.put("", "emptyvalue"); 427 assertEquals("emptyvalue", pref.get("", null)); 428 429 try { 430 pref.put(null, "value"); 431 fail(); 432 } catch (NullPointerException expected) { 433 } 434 try { 435 pref.put("key", null); 436 fail(); 437 } catch (NullPointerException expected) { 438 } 439 pref.put(longKey, longValue); 440 try { 441 pref.put(longKey + 1, longValue); 442 fail(); 443 } catch (IllegalArgumentException expected) { 444 } 445 try { 446 pref.put(longKey, longValue + 1); 447 fail(); 448 } catch (IllegalArgumentException expected) { 449 } 450 451 pref.removeNode(); 452 try { 453 pref.put(longKey, longValue + 1); 454 fail(); 455 } catch (IllegalArgumentException expected) { 456 } 457 458 try { 459 pref.put(longKey, longValue); 460 fail(); 461 } catch (IllegalStateException expected) { 462 } 463 } 464 testPutBoolean()465 public void testPutBoolean() { 466 Preferences pref = Preferences.userNodeForPackage(Preferences.class); 467 try { 468 pref.putBoolean(null, false); 469 fail(); 470 } catch (NullPointerException expected) { 471 } 472 pref.putBoolean(longKey, false); 473 try { 474 pref.putBoolean(longKey + "a", false); 475 fail(); 476 } catch (IllegalArgumentException expected) { 477 } 478 pref.putBoolean("testPutBooleanKey", false); 479 assertEquals("false", pref.get("testPutBooleanKey", null)); 480 assertFalse(pref.getBoolean("testPutBooleanKey", true)); 481 } 482 testPutDouble()483 public void testPutDouble() { 484 Preferences pref = Preferences.userNodeForPackage(Preferences.class); 485 try { 486 pref.putDouble(null, 3); 487 fail(); 488 } catch (NullPointerException expected) { 489 } 490 pref.putDouble(longKey, 3); 491 try { 492 pref.putDouble(longKey + "a", 3); 493 fail(); 494 } catch (IllegalArgumentException expected) { 495 } 496 pref.putDouble("testPutDoubleKey", 3); 497 assertEquals("3.0", pref.get("testPutDoubleKey", null)); 498 assertEquals(3, pref.getDouble("testPutDoubleKey", 0), 0); 499 } 500 testPutFloat()501 public void testPutFloat() { 502 Preferences pref = Preferences.userNodeForPackage(Preferences.class); 503 try { 504 pref.putFloat(null, 3f); 505 fail(); 506 } catch (NullPointerException expected) { 507 } 508 pref.putFloat(longKey, 3f); 509 try { 510 pref.putFloat(longKey + "a", 3f); 511 fail(); 512 } catch (IllegalArgumentException expected) { 513 } 514 pref.putFloat("testPutFloatKey", 3f); 515 assertEquals("3.0", pref.get("testPutFloatKey", null)); 516 assertEquals(3f, pref.getFloat("testPutFloatKey", 0), 0); 517 } 518 testPutInt()519 public void testPutInt() { 520 Preferences pref = Preferences.userNodeForPackage(Preferences.class); 521 try { 522 pref.putInt(null, 3); 523 fail(); 524 } catch (NullPointerException expected) { 525 } 526 pref.putInt(longKey, 3); 527 try { 528 pref.putInt(longKey + "a", 3); 529 fail(); 530 } catch (IllegalArgumentException expected) { 531 } 532 pref.putInt("testPutIntKey", 3); 533 assertEquals("3", pref.get("testPutIntKey", null)); 534 assertEquals(3, pref.getInt("testPutIntKey", 0)); 535 } 536 testPutLong()537 public void testPutLong() { 538 Preferences pref = Preferences.userNodeForPackage(Preferences.class); 539 try { 540 pref.putLong(null, 3L); 541 fail(); 542 } catch (NullPointerException expected) { 543 } 544 pref.putLong(longKey, 3L); 545 try { 546 pref.putLong(longKey + "a", 3L); 547 fail(); 548 } catch (IllegalArgumentException expected) { 549 } 550 pref.putLong("testPutLongKey", 3L); 551 assertEquals("3", pref.get("testPutLongKey", null)); 552 assertEquals(3L, pref.getLong("testPutLongKey", 0)); 553 } 554 testPutByteArray()555 public void testPutByteArray() { 556 Preferences pref = Preferences.userNodeForPackage(Preferences.class); 557 try { 558 pref.putByteArray(null, new byte[0]); 559 fail(); 560 } catch (NullPointerException expected) { 561 } 562 try { 563 pref.putByteArray("testPutByteArrayKey4", null); 564 fail(); 565 } catch (NullPointerException expected) { 566 } 567 568 pref.putByteArray(longKey, new byte[0]); 569 try { 570 pref.putByteArray(longKey + "a", new byte[0]); 571 fail(); 572 } catch (IllegalArgumentException expected) { 573 } 574 byte[] longArray = new byte[(int) (Preferences.MAX_VALUE_LENGTH * 0.74)]; 575 byte[] longerArray = new byte[(int) (Preferences.MAX_VALUE_LENGTH * 0.75) + 1]; 576 pref.putByteArray(longKey, longArray); 577 try { 578 pref.putByteArray(longKey, longerArray); 579 fail(); 580 } catch (IllegalArgumentException expected) { 581 } 582 583 pref.putByteArray("testPutByteArrayKey", new byte[0]); 584 assertEquals("", pref.get("testPutByteArrayKey", null)); 585 assertTrue(Arrays.equals(new byte[0], pref.getByteArray( 586 "testPutByteArrayKey", null))); 587 588 pref.putByteArray("testPutByteArrayKey3", new byte[] { 'a', 'b', 'c' }); 589 assertEquals("YWJj", pref.get("testPutByteArrayKey3", null)); 590 assertTrue(Arrays.equals(new byte[] { 'a', 'b', 'c' }, pref 591 .getByteArray("testPutByteArrayKey3", null))); 592 } 593 testRemove()594 public void testRemove() throws BackingStoreException { 595 Preferences pref = Preferences.userNodeForPackage(Preferences.class); 596 pref.remove("key"); 597 598 pref.put("key", "value"); 599 assertEquals("value", pref.get("key", null)); 600 pref.remove("key"); 601 assertNull(pref.get("key", null)); 602 603 pref.remove("key"); 604 605 try { 606 pref.remove(null); 607 fail(); 608 } catch (NullPointerException expected) { 609 } 610 611 pref.removeNode(); 612 try { 613 pref.remove("key"); 614 fail(); 615 } catch (IllegalStateException expected) { 616 } 617 } 618 testRemoveNode()619 public void testRemoveNode() throws BackingStoreException { 620 Preferences pref = Preferences.userNodeForPackage(Preferences.class); 621 Preferences child = pref.node("child"); 622 Preferences child1 = pref.node("child1"); 623 Preferences grandchild = child.node("grandchild"); 624 625 pref.removeNode(); 626 627 assertFalse(child.nodeExists("")); 628 assertFalse(child1.nodeExists("")); 629 assertFalse(grandchild.nodeExists("")); 630 assertFalse(pref.nodeExists("")); 631 } 632 testAddNodeChangeListener()633 public void testAddNodeChangeListener() throws BackingStoreException { 634 Preferences pref = Preferences.userNodeForPackage(Preferences.class); 635 try { 636 pref.addNodeChangeListener(null); 637 fail(); 638 } catch (NullPointerException expected) { 639 } 640 641 Preferences child1 = null; 642 643 MockNodeChangeListener nl = null; 644 // To get existed node doesn't create the change event 645 try { 646 nl = new MockNodeChangeListener(); 647 pref.addNodeChangeListener(nl); 648 child1 = pref.node("mock1"); 649 nl.waitForEvent(1); 650 assertEquals(1, nl.getAdded()); 651 nl.reset(); 652 pref.node("mock1"); 653 // There shouldn't be an event, but wait in case one arrives... 654 try { Thread.sleep(1000); } catch (InterruptedException ignored) {} 655 assertEquals(0, nl.getAdded()); 656 nl.reset(); 657 } finally { 658 pref.removeNodeChangeListener(nl); 659 child1.removeNode(); 660 } 661 // same listener can be added twice, and must be removed twice 662 try { 663 nl = new MockNodeChangeListener(); 664 pref.addNodeChangeListener(nl); 665 pref.addNodeChangeListener(nl); 666 child1 = pref.node("mock2"); 667 nl.waitForEvent(2); 668 assertEquals(2, nl.getAdded()); 669 nl.reset(); 670 } finally { 671 pref.removeNodeChangeListener(nl); 672 pref.removeNodeChangeListener(nl); 673 child1.removeNode(); 674 } 675 // test remove event 676 try { 677 nl = new MockNodeChangeListener(); 678 pref.addNodeChangeListener(nl); 679 child1 = pref.node("mock3"); 680 child1.removeNode(); 681 nl.waitForEvent(2); 682 assertEquals(1, nl.getRemoved()); 683 nl.reset(); 684 } finally { 685 pref.removeNodeChangeListener(nl); 686 } 687 // test remove event with two listeners 688 try { 689 nl = new MockNodeChangeListener(); 690 pref.addNodeChangeListener(nl); 691 pref.addNodeChangeListener(nl); 692 child1 = pref.node("mock6"); 693 child1.removeNode(); 694 nl.waitForEvent(4); 695 assertEquals(2, nl.getRemoved()); 696 nl.reset(); 697 } finally { 698 pref.removeNodeChangeListener(nl); 699 pref.removeNodeChangeListener(nl); 700 } 701 // test add/remove indirect children, or remove several children at the 702 // same time 703 Preferences child3; 704 try { 705 nl = new MockNodeChangeListener(); 706 child1 = pref.node("mock4"); 707 child1.addNodeChangeListener(nl); 708 pref.node("mock4/mock5"); 709 nl.waitForEvent(1); 710 assertEquals(1, nl.getAdded()); 711 nl.reset(); 712 child3 = pref.node("mock4/mock5/mock6"); 713 // There shouldn't be an event, but wait in case one arrives... 714 try { Thread.sleep(1000); } catch (InterruptedException ignored) {} 715 assertEquals(0, nl.getAdded()); 716 nl.reset(); 717 718 child3.removeNode(); 719 // There shouldn't be an event, but wait in case one arrives... 720 try { Thread.sleep(1000); } catch (InterruptedException ignored) {} 721 assertEquals(0, nl.getRemoved()); 722 nl.reset(); 723 724 pref.node("mock4/mock7"); 725 nl.waitForEvent(1); 726 assertEquals(1, nl.getAdded()); 727 nl.reset(); 728 729 child1.removeNode(); 730 nl.waitForEvent(2); 731 assertEquals(2, nl.getRemoved()); 732 nl.reset(); 733 } finally { 734 try { 735 child1.removeNode(); 736 } catch (Exception ignored) { 737 } 738 } 739 } 740 testAddPreferenceChangeListener()741 public void testAddPreferenceChangeListener() throws Exception { 742 Preferences pref = Preferences.userNodeForPackage(Preferences.class); 743 MockPreferenceChangeListener pl = null; 744 745 try { 746 pref.addPreferenceChangeListener(null); 747 fail(); 748 } catch (NullPointerException expected) { 749 } 750 751 // To get existed node doesn't create the change event 752 try { 753 pl = new MockPreferenceChangeListener(); 754 pref.addPreferenceChangeListener(pl); 755 pref.putInt("mock1", 123); 756 pl.waitForEvent(1); 757 assertEquals(1, pl.getChanged()); 758 pref.putLong("long_key", Long.MAX_VALUE); 759 pl.waitForEvent(2); 760 assertEquals(2, pl.getChanged()); 761 pl.reset(); 762 try { 763 pref.clear(); 764 pl.waitForEvent(2); 765 assertEquals(2, pl.getChanged()); 766 } catch(BackingStoreException bse) { 767 pl.reset(); 768 fail("BackingStoreException is thrown"); 769 } 770 pl.reset(); 771 } finally { 772 pref.removePreferenceChangeListener(pl); 773 //child1.removeNode(); 774 } 775 776 // same listener can be added twice, and must be removed twice 777 try { 778 pl = new MockPreferenceChangeListener(); 779 pref.addPreferenceChangeListener(pl); 780 pref.addPreferenceChangeListener(pl); 781 pref.putFloat("float_key", Float.MIN_VALUE); 782 pl.waitForEvent(2); 783 assertEquals(2, pl.getChanged()); 784 pl.reset(); 785 } finally { 786 pref.removePreferenceChangeListener(pl); 787 pref.removePreferenceChangeListener(pl); 788 789 } 790 // test remove event 791 try { 792 pl = new MockPreferenceChangeListener(); 793 pref.addPreferenceChangeListener(pl); 794 pref.putDouble("double_key", Double.MAX_VALUE); 795 pl.waitForEvent(1); 796 assertEquals(1, pl.getChanged()); 797 try { 798 pref.clear(); 799 pl.waitForEvent(3); 800 assertEquals(3, pl.getChanged()); 801 } catch(BackingStoreException bse) { 802 fail("BackingStoreException is thrown"); 803 } 804 pl.reset(); 805 } finally { 806 pref.removePreferenceChangeListener(pl); 807 } 808 // test remove event with two listeners 809 try { 810 pl = new MockPreferenceChangeListener(); 811 pref.addPreferenceChangeListener(pl); 812 pref.addPreferenceChangeListener(pl); 813 pref.putByteArray("byte_array_key", new byte [] {1 ,2 , 3}); 814 try { 815 pref.clear(); 816 pl.waitForEvent(4); 817 assertEquals(4, pl.getChanged()); 818 } catch(BackingStoreException bse) { 819 fail("BackingStoreException is thrown"); 820 } 821 pl.reset(); 822 } finally { 823 pref.removePreferenceChangeListener(pl); 824 pref.removePreferenceChangeListener(pl); 825 } 826 827 } 828 testRemoveNodeChangeListener()829 public void testRemoveNodeChangeListener() { 830 Preferences pref = Preferences.userNodeForPackage(Preferences.class); 831 try { 832 pref.removeNodeChangeListener(null); 833 fail(); 834 } catch (IllegalArgumentException expected) { 835 } 836 MockNodeChangeListener l1 = new MockNodeChangeListener(); 837 MockNodeChangeListener l2 = new MockNodeChangeListener(); 838 pref.addNodeChangeListener(l1); 839 pref.addNodeChangeListener(l1); 840 841 pref.removeNodeChangeListener(l1); 842 pref.removeNodeChangeListener(l1); 843 try { 844 pref.removeNodeChangeListener(l1); 845 fail(); 846 } catch (IllegalArgumentException expected) { 847 } 848 try { 849 pref.removeNodeChangeListener(l2); 850 fail(); 851 } catch (IllegalArgumentException expected) { 852 } 853 } 854 testRemovePreferenceChangeListener()855 public void testRemovePreferenceChangeListener() { 856 Preferences pref = Preferences.userNodeForPackage(Preferences.class); 857 try { 858 pref.removePreferenceChangeListener(null); 859 fail(); 860 } catch (IllegalArgumentException expected) { 861 } 862 MockPreferenceChangeListener l1 = new MockPreferenceChangeListener(); 863 MockPreferenceChangeListener l2 = new MockPreferenceChangeListener(); 864 pref.addPreferenceChangeListener(l1); 865 pref.addPreferenceChangeListener(l1); 866 try { 867 pref.removePreferenceChangeListener(l2); 868 fail(); 869 } catch (IllegalArgumentException expected) { 870 } 871 pref.removePreferenceChangeListener(l1); 872 pref.removePreferenceChangeListener(l1); 873 try { 874 pref.removePreferenceChangeListener(l1); 875 fail(); 876 } catch (IllegalArgumentException expected) { 877 } 878 879 } 880 881 static class MockNodeChangeListener implements NodeChangeListener { 882 private int added = 0; 883 private int removed = 0; 884 private int eventCount = 0; 885 waitForEvent(int count)886 public void waitForEvent(int count) { 887 synchronized (this) { 888 while (eventCount < count) { 889 try { 890 wait(); 891 } catch (InterruptedException ignored) { 892 } 893 } 894 } 895 } 896 childAdded(NodeChangeEvent e)897 public void childAdded(NodeChangeEvent e) { 898 if (ENCOURAGE_RACES) try { Thread.sleep(1000); } catch (InterruptedException ignored) { } 899 synchronized (this) { 900 ++eventCount; 901 ++added; 902 notifyAll(); 903 } 904 } 905 childRemoved(NodeChangeEvent e)906 public void childRemoved(NodeChangeEvent e) { 907 if (ENCOURAGE_RACES) try { Thread.sleep(1000); } catch (InterruptedException ignored) { } 908 synchronized (this) { 909 ++eventCount; 910 ++removed; 911 notifyAll(); 912 } 913 } 914 getAdded()915 public synchronized int getAdded() { 916 return added; 917 } 918 getRemoved()919 public synchronized int getRemoved() { 920 return removed; 921 } 922 reset()923 public synchronized void reset() { 924 eventCount = 0; 925 added = 0; 926 removed = 0; 927 } 928 } 929 930 private static class MockPreferenceChangeListener implements PreferenceChangeListener { 931 private int changed = 0; 932 private int eventCount = 0; 933 waitForEvent(int count)934 public void waitForEvent(int count) { 935 synchronized (this) { 936 while (eventCount < count) { 937 try { 938 wait(); 939 } catch (InterruptedException ignored) { 940 } 941 } 942 } 943 } 944 preferenceChange(PreferenceChangeEvent pce)945 public void preferenceChange(PreferenceChangeEvent pce) { 946 if (ENCOURAGE_RACES) try { Thread.sleep(1000); } catch (InterruptedException ignored) { } 947 synchronized (this) { 948 ++eventCount; 949 ++changed; 950 notifyAll(); 951 } 952 } 953 getChanged()954 public synchronized int getChanged() { 955 return changed; 956 } 957 reset()958 public synchronized void reset() { 959 eventCount = 0; 960 changed = 0; 961 } 962 } 963 964 @SuppressWarnings("unused") 965 static class MockPreferences extends Preferences { 966 967 @Override absolutePath()968 public String absolutePath() { 969 return null; 970 } 971 972 @Override childrenNames()973 public String[] childrenNames() throws BackingStoreException { 974 return null; 975 } 976 977 @Override clear()978 public void clear() throws BackingStoreException { 979 } 980 981 @Override exportNode(OutputStream ostream)982 public void exportNode(OutputStream ostream) throws IOException, BackingStoreException { 983 } 984 985 @Override exportSubtree(OutputStream ostream)986 public void exportSubtree(OutputStream ostream) throws IOException, BackingStoreException { 987 } 988 989 @Override flush()990 public void flush() throws BackingStoreException { 991 } 992 993 @Override get(String key, String deflt)994 public String get(String key, String deflt) { 995 return null; 996 } 997 998 @Override getBoolean(String key, boolean deflt)999 public boolean getBoolean(String key, boolean deflt) { 1000 return false; 1001 } 1002 1003 @Override getByteArray(String key, byte[] deflt)1004 public byte[] getByteArray(String key, byte[] deflt) { 1005 return null; 1006 } 1007 1008 @Override getDouble(String key, double deflt)1009 public double getDouble(String key, double deflt) { 1010 return 0; 1011 } 1012 1013 @Override getFloat(String key, float deflt)1014 public float getFloat(String key, float deflt) { 1015 return 0; 1016 } 1017 1018 @Override getInt(String key, int deflt)1019 public int getInt(String key, int deflt) { 1020 return 0; 1021 } 1022 1023 @Override getLong(String key, long deflt)1024 public long getLong(String key, long deflt) { 1025 return 0; 1026 } 1027 1028 @Override isUserNode()1029 public boolean isUserNode() { 1030 return false; 1031 } 1032 1033 @Override keys()1034 public String[] keys() throws BackingStoreException { 1035 return null; 1036 } 1037 1038 @Override name()1039 public String name() { 1040 return null; 1041 } 1042 1043 @Override node(String name)1044 public Preferences node(String name) { 1045 return null; 1046 } 1047 1048 @Override nodeExists(String name)1049 public boolean nodeExists(String name) throws BackingStoreException { 1050 return false; 1051 } 1052 1053 @Override parent()1054 public Preferences parent() { 1055 return null; 1056 } 1057 1058 @Override put(String key, String value)1059 public void put(String key, String value) { 1060 } 1061 1062 @Override putBoolean(String key, boolean value)1063 public void putBoolean(String key, boolean value) { 1064 } 1065 1066 @Override putByteArray(String key, byte[] value)1067 public void putByteArray(String key, byte[] value) { 1068 } 1069 1070 @Override putDouble(String key, double value)1071 public void putDouble(String key, double value) { 1072 } 1073 1074 @Override putFloat(String key, float value)1075 public void putFloat(String key, float value) { 1076 } 1077 1078 @Override putInt(String key, int value)1079 public void putInt(String key, int value) { 1080 } 1081 1082 @Override putLong(String key, long value)1083 public void putLong(String key, long value) { 1084 } 1085 1086 @Override remove(String key)1087 public void remove(String key) { 1088 } 1089 1090 @Override removeNode()1091 public void removeNode() throws BackingStoreException { 1092 } 1093 1094 @Override addNodeChangeListener(NodeChangeListener ncl)1095 public void addNodeChangeListener(NodeChangeListener ncl) { 1096 } 1097 1098 @Override addPreferenceChangeListener(PreferenceChangeListener pcl)1099 public void addPreferenceChangeListener(PreferenceChangeListener pcl) { 1100 } 1101 1102 @Override removeNodeChangeListener(NodeChangeListener ncl)1103 public void removeNodeChangeListener(NodeChangeListener ncl) { 1104 } 1105 1106 @Override removePreferenceChangeListener(PreferenceChangeListener pcl)1107 public void removePreferenceChangeListener(PreferenceChangeListener pcl) { 1108 } 1109 1110 @Override sync()1111 public void sync() throws BackingStoreException { 1112 } 1113 1114 @Override toString()1115 public String toString() { 1116 return null; 1117 } 1118 } 1119 } 1120