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