1 19 20 package org.openide.nodes; 21 22 import java.io.PrintWriter ; 23 import java.io.StringWriter ; 24 import java.lang.ref.Reference ; 25 import java.lang.ref.WeakReference ; 26 import java.util.ArrayList ; 27 import java.util.Arrays ; 28 import java.util.Collection ; 29 import java.util.Collections ; 30 import java.util.Iterator ; 31 import java.util.LinkedList ; 32 import java.util.List ; 33 import java.util.logging.Level ; 34 import java.util.logging.Logger ; 35 import org.netbeans.junit.Log; 36 import org.netbeans.junit.NbTestCase; 37 import org.netbeans.junit.NbTestSuite; 38 39 public class ChildrenKeysTest extends NbTestCase { 40 private CharSequence err; 41 private Logger LOG; 42 43 public ChildrenKeysTest(java.lang.String testName) { 44 super(testName); 45 } 46 47 protected Node createNode (Children ch) { 48 return new AbstractNode (ch); 49 } 50 51 public static junit.framework.Test suite() { 52 return new ChildrenKeysTest("testGetNodesFromTwoThreads57769"); 53 } 55 56 @Override 57 protected Level logLevel() { 58 return Level.INFO; 59 } 60 61 62 63 protected void setUp () throws Exception { 64 err = Log.enable("", Level.ALL); 65 LOG = Logger.getLogger("test." + getName()); 66 } 67 68 public void testGetNodesFromTwoThreads57769() throws Exception { 69 final Ticker t1 = new Ticker(); 70 final List who = new java.util.Vector (); 71 72 final int[] count = new int[1]; 73 Children children= new Children.Keys() { 74 protected Node[] createNodes(Object key) { 75 StringWriter msg = new StringWriter (); 76 msg.write("Creating: " + count[0] + " for key: " + key + "\n"); 77 new Exception ().printStackTrace(new PrintWriter (msg)); 78 LOG.log(Level.INFO, msg.toString()); 79 count[0]++; 80 AbstractNode n = new AbstractNode(Children.LEAF); 81 n.setName(key.toString()); 82 try {Thread.sleep(2000);}catch(InterruptedException e) {} 83 return n == null ? new Node[]{} : new Node[]{n}; 84 } 85 86 protected void addNotify() { 87 setKeys(Arrays.asList(new Object [] {"1", "2"})); 88 } 89 }; 90 final Node node = new AbstractNode(children); 91 92 Thread t = new Thread ("THREAD") { 94 Node[] keep; 95 public void run() { 96 t1.tick(); 97 keep = node.getChildren().getNodes(true); 98 } 99 }; 100 t.start(); 101 t1.waitOn(); 102 103 Node[] remember = node.getChildren().getNodes(); 105 106 t.join(); 108 109 if (2 != count[0]) { 110 StringWriter w = new StringWriter (); 111 PrintWriter pw = new PrintWriter (w); 112 w.write("Just two nodes created: " + count[0] + " stacks:\n"); 113 Iterator it = who.iterator(); 114 while (it.hasNext()) { 115 Exception e = (Exception )it.next(); 116 e.printStackTrace(pw); 117 } 118 pw.close(); 119 120 fail(w.toString());; 121 } } 123 124 130 public void testGetNodesFromWriteAccess() throws Exception { 131 final String [] keys = { "Nenik", "Tulach" }; 132 Keys o = new Keys (keys); 133 Node orig = new AbstractNode(o); 134 Node filter = new FilterNode(orig); 135 final Children k = filter.getChildren(); 136 137 final Ticker t1 = new Ticker(); 138 final Ticker tick2 = new Ticker(); 139 final boolean[] done = new boolean[2]; 140 141 Thread t = new Thread ("preempted") { 143 public void run() { 144 Children.PR.enterWriteAccess(); 145 try { 146 t1.tick(); tick2.waitOn(); k.getNodes(); 149 } finally { 150 Children.PR.exitWriteAccess(); 151 } 152 done[0] = true; 153 } 154 }; 155 t.start(); 156 t1.waitOn(); 157 158 Thread t2 = new Thread ("other") { 160 public void run() { 161 k.getNodes(); done[1] = true; 163 } 164 }; 165 t2.start(); 166 167 Thread.sleep(2000); tick2.tick(); 170 t.join(2000); 172 t2.join(2000); 173 174 t.stop(); 175 t2.stop(); 176 177 assertTrue ("Preempted thread finished correctly", done[0]); 178 assertTrue ("Other thread finished correctly", done[1]); 179 } 180 181 184 public void testNodesCreatedJustOnce() throws Exception { 185 Counter children = new Counter(1); 186 Node node = new AbstractNode(children); 187 children.keys(Arrays.asList(new Object [] {"Add Children"})); 188 Node[] nodes = node.getChildren().getNodes(true); 189 190 assertEquals("One node returned", 1, nodes.length); 191 assertEquals("One node created", 1, children.count); 192 } 193 194 195 public void testDestroyIsCalledWhenANodeIsRemovedOrig () throws Exception { 196 class K extends Keys { 197 public Node[] arr; 198 199 protected void destroyNodes (Node[] arr) { 200 super.destroyNodes (arr); 201 assertNull ("No destroy before", this.arr); 202 this.arr = arr; 203 } 204 } 205 206 K k = new K (); 207 k.keys (new String [] { "A", "B", "C" }); 208 209 Node[] n = k.getNodes (); 210 assertEquals ("3", 3, n.length); 211 assertNull ("Still no destroy", k.arr); 212 213 k.keys (new String [] { "A" }); 214 assertNotNull ("Some destroyed", k.arr); 215 assertEquals ("2 destroyed", 2, k.arr.length); 216 k.arr = null; 217 n = k.getNodes (); 218 assertEquals ("! left", 1, n.length); 219 220 WeakReference ref = new WeakReference (n[0]); 221 n = null; 222 assertGC ("Node can be gced", ref); 223 224 assertNull ("Garbage collected nodes are not notified", k.arr); 225 } 226 227 public void testDestroyIsCalledWhenANodeIsRemoved () throws Exception { 228 class K extends Keys { 229 public Node[] arr; 230 231 protected void destroyNodes (Node[] arr) { 232 super.destroyNodes (arr); 233 assertNull ("No destroy before", this.arr); 234 this.arr = arr; 235 } 236 } 237 238 K k = new K (); 239 k.keys (new String [] { "A", "B", "C" }); 240 Node node = createNode (k); 241 242 Node[] n = node.getChildren ().getNodes (); 243 assertEquals ("3", 3, n.length); 244 assertNull ("Still no destroy", k.arr); 245 246 k.keys (new String [] { "A" }); 247 assertNotNull ("Some destroyed", k.arr); 248 assertEquals ("2 destroyed", 2, k.arr.length); 249 k.arr = null; 250 n = node.getChildren ().getNodes (); 251 assertEquals ("! left", 1, n.length); 252 253 WeakReference ref = new WeakReference (n[0]); 254 n = null; 255 assertGC ("Node can be gced", ref); 256 257 assertNull ("Garbage collected nodes are not notified", k.arr); 258 } 259 260 public void testDestroyIsCalledWhenEntryIsRefreshed () throws Exception { 261 class K extends Keys { 262 public Node[] arr; 263 public Node[] toReturn; 264 265 protected void destroyNodes (Node[] arr) { 266 super.destroyNodes (arr); 267 assertNull ("No destroy before", this.arr); 268 this.arr = arr; 269 } 270 271 protected Node[] createNodes (Object key) { 272 if (toReturn != null) { 273 return toReturn; 274 } else { 275 return super.createNodes (key); 276 } 277 } 278 } 279 280 K k = new K (); 281 k.keys (new String [] { "A", "B", "C" }); 282 Node node = createNode (k); 283 284 Node[] n = node.getChildren ().getNodes (); 285 assertEquals ("3", 3, n.length); 286 assertNull ("Still no destroy", k.arr); 287 288 k.toReturn = new Node[0]; 289 k.refreshKey ("A"); 290 291 assertNotNull ("Some destroyed", k.arr); 292 assertEquals ("1 destroyed", 1, k.arr.length); 293 k.arr = null; 294 n = node.getChildren ().getNodes (); 295 assertEquals ("B C", 2, n.length); 296 297 WeakReference ref = new WeakReference (n[0]); 298 n = null; 299 assertGC ("Node can be gced", ref); 300 301 assertNull ("Garbage collected nodes are not notified", k.arr); 302 } 303 304 public void testRefreshKeyCanBeCalledFromReadAccess () throws Exception { 305 final String [] keys = { "Hrebejk", "Tulach" }; 306 final Keys k = new Keys (keys); 307 308 Keys.MUTEX.readAccess (new Runnable () { 309 public void run () { 310 k.refreshKey ("Hrebejk"); 311 } 312 }); 313 314 if (err.toString ().indexOf ("readAccess") >= 0) { 315 fail ("Should not contain messages about going from read to write access: " + err); 316 } 317 } 318 319 320 public void testGCKeys () throws Exception { 321 class K extends Children.Keys { 322 int counterAdd = 0; 323 int counterRem = 0; 324 Object key; 325 326 Reference createdNode; 327 328 K(Object keyObject) { 329 key = keyObject; 330 } 331 332 protected void addNotify() { 333 counterAdd++; 334 setKeys(Collections.singleton(key)); 335 } 336 337 protected void removeNotify() { 338 counterRem++; 339 setKeys(Collections.EMPTY_LIST); 340 key = null; 341 } 342 343 protected Node[] createNodes(Object k) { 344 Node n = Node.EMPTY.cloneNode(); 345 assertNull ("Just one created node", createdNode); 346 createdNode = new WeakReference (n); 347 return new Node[] { n }; 348 } 349 } 350 351 Object myKey = new Object (); 352 K temp = new K(myKey); 353 Node node = createNode (temp); 354 355 assertEquals("not touched", 0, temp.counterAdd); 356 assertEquals("not touched", 0, temp.counterRem); 357 358 Node[] arr = node.getChildren ().getNodes(); 359 360 assertEquals("initialized", 1, temp.counterAdd); 361 assertEquals("not touched", 0, temp.counterRem); 362 assertEquals("one item", 1, arr.length); 363 364 WeakReference ref = new WeakReference (arr[0]); 365 arr = null; 366 assertGC("node freed", ref); 367 assertGC("and this one as well", temp.createdNode); 368 369 assertEquals("initialized", 1, temp.counterAdd); 370 assertEquals("removed", 1, temp.counterRem); 371 372 ref = new WeakReference (myKey); 373 myKey = null; 374 assertGC("key freed", ref); 375 376 } 377 378 public void testIndexesAreCorrectWhenInsertingAnObject () { 379 doIndexesAreCorrectWhenInsertingAnObject ("B", 3); 380 } 381 382 public void testIndexesAreCorrectWhenInsertingAnObjectNext () { 383 doIndexesAreCorrectWhenInsertingAnObject ("1", 4); 384 } 385 386 private void doIndexesAreCorrectWhenInsertingAnObject (String add, int index) { 387 Keys k = new Keys (); 388 Node n = createNode (k); 389 390 assertEquals ("Empty", 0, n.getChildren ().getNodesCount ()); 391 Node[] arr = n.getChildren ().getNodes (); 392 393 Listener l = new Listener (); 394 n.addNodeListener(l); 395 396 397 ArrayList list = new ArrayList (); 398 list.add ("A"); 399 list.add ("B"); 400 list.add ("1"); 401 list.add ("2"); 402 list.add ("3"); 403 k.setKeys(list); 404 405 l.assertAddEvent ("Added 5", new int[] { 0, 1, 2, 3, 4 }); 406 Node[] newArr = n.getChildren ().getNodes (); 407 408 list.add (2, "0"); 409 list.add (3, add); 410 k.setKeys (list); 411 412 l.assertAddEvent ("Added 2", new int[] { 2, index }); 413 l.assertNoEvents("And that is all"); 414 } 415 416 public void testAddingALotOfItems () { 417 Keys k = new Keys (); 418 Node n = createNode (k); 419 420 assertEquals ("Empty", 0, n.getChildren ().getNodesCount ()); 421 Node[] arr = n.getChildren ().getNodes (); 422 423 Listener l = new Listener (); 424 n.addNodeListener(l); 425 426 427 ArrayList list = new ArrayList (); 428 list.add ("A"); 429 list.add ("B"); 430 list.add ("1"); 431 list.add ("2"); 432 list.add ("3"); 433 k.setKeys(list); 434 435 l.assertAddEvent ("Added 5", new int[] { 0, 1, 2, 3, 4 }); 436 Node[] newArr = n.getChildren ().getNodes (); 437 438 list.add (2, "0.6"); 439 list.add (2, "0.5"); 440 list.add (2, "0.4"); 441 list.add (2, "0.3"); 442 list.add (2, "0.2"); 443 list.add (2, "0.1"); 444 k.setKeys (list); 445 446 l.assertAddEvent ("Added 6", new int[] { 2, 3, 4, 5, 6, 7 }); 447 l.assertNoEvents("And that is all"); 448 } 449 450 452 public void testGetNodes () throws Exception { 453 String [] arr = { "1", "2", "3", "4" }; 454 Children ch = new Keys (arr); 455 checkNames (createNode (ch), arr); 456 } 457 458 public void testGetNodesOptimalOn0to1 () throws Exception { 459 class K extends Keys { 460 private boolean acceptOposite; 461 462 public K () { 463 super (0, 1); 464 } 465 466 protected Node[] createNodes (Object k) { 467 boolean a = k instanceof String ; 468 if (acceptOposite) { 469 a = !a; 470 } 471 if (a) { 472 return super.createNodes (k); 473 } else { 474 return null; 475 } 476 } 477 } 478 479 480 K k = new K (); 481 Object [] keys = { "Ahoj", new Integer (3), "Kuk", new Integer (2) }; 482 k.setKeys (keys); 483 Node[] arr = k.getNodes (true); 484 assertEquals ("Just two", 2, arr.length); 485 assertEquals ("Ahoj", arr[0].getName ()); 486 assertEquals ("Kuk", arr[1].getName ()); 487 488 try { 489 Children.PR.enterWriteAccess (); 490 k.acceptOposite = true; 491 k.setKeys (new Object [0]); 492 k.setKeys (keys); 493 } finally { 494 Children.PR.exitWriteAccess (); 495 } 496 497 arr = k.getNodes (true); 498 assertEquals ("Just two", 2, arr.length); 499 assertEquals ("3", arr[0].getName ()); 500 assertEquals ("2", arr[1].getName ()); 501 } 502 503 public void testNoReorderEventJustAdd () { 504 Keys k = new Keys (new String [] { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" }); 505 Node n = createNode (k); 506 Listener l = new Listener (); 507 n.addNodeListener (l); 508 Node[] toPreventGC = n.getChildren ().getNodes (); 509 assertEquals (10, toPreventGC.length); 510 511 k.keys (new String [] { "31", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" }); 512 513 l.assertAddEvent ("Adding one index", 1); 514 l.assertNoEvents ("And that is all"); 515 } 516 517 public void testComplexReorderAndAddAndRemoveEvent () { 518 Keys k = new Keys (new String [] { "remove", "1", "0" }); 519 Node n = createNode (k); 520 Listener l = new Listener (); 521 n.addNodeListener (l); 522 Node[] toPreventGC = n.getChildren ().getNodes (); 523 assertEquals (3, toPreventGC.length); 524 525 k.keys (new String [] { "0", "1", "add" }); 526 527 l.assertRemoveEvent ("Removed index 0", 1); 528 l.assertReorderEvent ("0->1 and 1->0", new int[] { 1, 0 }); 529 l.assertAddEvent ("Adding at index 2", 1); 530 l.assertNoEvents ("And that is all"); 531 532 Node[] arr = n.getChildren ().getNodes (); 533 assertEquals (3, arr.length); 534 assertEquals ("0", arr[0].getName ()); 535 assertEquals ("1", arr[1].getName ()); 536 assertEquals ("add", arr[2].getName ()); 537 } 538 539 541 public void testResetOfNodes () throws Exception { 542 String [] arr; 543 Keys ch = new Keys (); 544 arr = new String [] { "1", "2" }; 545 Node node = createNode (ch); 546 547 ch.keys (arr); 548 checkNames (node, arr); 549 550 arr = new String [] { "X", "Y", "Z" }; 551 ch.keys (arr); 552 checkNames (node, arr); 553 554 Collections.reverse (Arrays.asList (arr)); 555 ch.keys (arr); 556 checkNames (node, arr); 557 } 558 559 563 private void checkNames (Node ch, String [] arr) { 564 Node[] nodes = ch.getChildren ().getNodes (); 565 566 if (nodes.length != arr.length) { 567 fail ("Keys: " + arr.length + " Nodes: " + nodes.length); 568 } 569 570 for (int i = 0; i < arr.length; i++) { 571 if (!nodes[i].getName ().equals (arr[i])) { 572 fail (i + "th: name: " + nodes[i].getName () + " key: " + arr[i]); 573 } 574 } 575 } 576 577 public void testGetAndRemove () { 578 Keys k = new Keys (new String [] { "1", "2" }); 579 Node n = createNode (k); 580 Listener l = new Listener (); 581 n.addNodeListener (l); 582 583 Node d1 = n.getChildren ().getNodeAt (0); 584 assertEquals ("Name is 1", "1", d1.getName ()); 585 586 k.keys (new String [] { "2" }); 587 588 l.assertRemoveEvent ("One node removed", 1); 589 assertNull (d1.getParentNode ()); 590 } 591 592 public void testSetBefore () { 593 Keys k = new Keys (new String [] { "Ahoj" }); 594 k.add (new Node[] { Node.EMPTY.cloneNode () }); 595 596 Node node = createNode (k); 597 598 Node[] arr; 599 600 arr = node.getChildren ().getNodes (); 601 assertEquals (2, arr.length); 602 assertEquals ("First is ahoj", "Ahoj", arr[0].getName ()); 603 assertEquals ("2nd equlas to EMPTY", Node.EMPTY, arr[1]); 604 605 k.setBefore (true); 606 607 arr = node.getChildren ().getNodes (); 608 assertEquals (2, arr.length); 609 assertEquals ("2nd is ahoj", "Ahoj", arr[1].getName ()); 610 assertEquals ("First equals to EMPTY", Node.EMPTY, arr[0]); 611 612 k.setBefore (false); 613 614 arr = node.getChildren ().getNodes (); 615 assertEquals (2, arr.length); 616 assertEquals ("First is ahoj", "Ahoj", arr[0].getName ()); 617 assertEquals ("2nd equlas to EMPTY", Node.EMPTY, arr[1]); 618 619 } 620 621 public void testOperationsOnEqualNumberOfMinAndMax () throws Exception { 622 Keys k = new Keys (1, 1); 623 Node n = createNode (k); 624 Listener l = new Listener (); 625 n.addNodeListener (l); 626 627 assertEquals ("No nodes", 0, n.getChildren ().getNodesCount ()); 628 k.keys (new String [] { "Ahoj", "Kuk" }); 629 630 NodeMemberEvent mem = l.assertEvents (1); 631 632 assertEquals ("Two nodes", 2, n.getChildren ().getNodesCount ()); 633 } 634 635 public void testChildrenFireCorrectEvents () throws Exception { 636 ChildrenKeysTest.Keys k = new ChildrenKeysTest.Keys (new String [] { "1", "2", "3" }); 637 Node fn = createNode (k); 638 ChildrenKeysTest.Listener l = new ChildrenKeysTest.Listener (); 639 fn.addNodeListener (l); 640 641 assertEquals ("Three", 3, fn.getChildren ().getNodesCount ()); 642 643 Node n1, n2; 644 n1 = fn.getChildren ().getNodeAt (0); 645 n2 = fn.getChildren ().getNodeAt (2); 646 assertEquals ("Name is 1", "1", n1.getName ()); 647 assertEquals ("Name is 3", "3", n2.getName ()); 648 649 k.keys (new String [] { "1", "3"}); 650 651 NodeMemberEvent ev = l.assertEvents (1); 652 assertEquals ("Removal event type", NodeMemberEvent.class, ev.getClass ()); 653 int[] removed = ev.getDeltaIndices (); 654 assertEquals ("One node gone", 1, removed.length); 655 assertEquals ("Middle one", 1, removed[0]); 656 } 657 658 public void testRemovedNodesWillHaveParentRemoved () throws Exception { 659 Keys k = new Keys (new String [] { "Ahoj", "Kuk" }); 660 Node n = createNode (k); 661 662 Node[] arr = n.getChildren ().getNodes (); 663 assertEquals ("Two", 2, arr.length); 664 assertEquals ("Parent1", n, arr[0].getParentNode ()); 665 assertEquals ("Parent2", n, arr[1].getParentNode ()); 666 667 k.keys (new String [0]); 668 669 Node[] newArr = n.getChildren ().getNodes(); 670 assertEquals ("Zero is current number of children", 0, newArr.length); 671 assertNull ("Old node parent zeroed1", arr[0].getParentNode ()); 672 assertNull ("Old node parent zeroed2", arr[1].getParentNode ()); 673 } 674 675 676 public void testRefreshClearsSizeWithoutLimits () throws Exception { 677 doRefreshClearsSize (0, 0); 678 } 679 680 public void testRefreshClearsSizeOto1 () throws Exception { 681 doRefreshClearsSize (0, 1); 682 } 683 684 private void doRefreshClearsSize (int min, int max) throws Exception { 685 final String [] NULL = { "Null" }; 686 687 Keys k = new Keys (min, max) { 688 protected Node[] createNodes (Object o) { 689 if (o == NULL) { 690 if (NULL[0] == null) { 691 return null; 692 } 693 o = NULL[0]; 694 } 695 return super.createNodes (o); 696 } 697 }; 698 Node n = createNode (k); 699 Listener l = new Listener (); 700 n.addNodeListener (l); 701 702 assertEquals ("No nodes", 0, n.getChildren ().getNodesCount ()); 703 k.setKeys (new Object [] { "Ahoj", NULL }); 704 assertEquals ("Two nodes", 2, n.getChildren ().getNodesCount ()); 705 NULL[0] = null; 706 k.refreshKey (NULL); 707 assertEquals ("Just one node", 1, n.getChildren ().getNodesCount ()); 708 } 709 710 public void testGetNodesFromTwoThreads57769WhenBlockingAtRightPlaces() throws Exception { 711 final Ticker t1 = new Ticker(); 712 final List who = new java.util.Vector (); 713 714 final int[] count = new int[1]; 715 class ChildrenKeys extends Children.Keys { 716 protected Node[] createNodes(Object key) { 717 who.add(new Exception ("Creating: " + count[0] + " for key: " + key)); 718 count[0]++; 719 AbstractNode n = new AbstractNode(Children.LEAF); 720 n.setName(key.toString()); 721 try {Thread.sleep(2000);}catch(InterruptedException e) {} 722 return n == null ? new Node[]{} : new Node[]{n}; 723 } 724 725 protected void addNotify() { 726 setKeys(Arrays.asList(new Object [] {"1", "2"})); 727 } 728 }; 729 730 732 final String TOKEN = new String ("TOKEN to wait on"); 733 final String THREAD_NAME = Thread.currentThread().getName(); 734 735 class Th extends Thread { 736 public Th() { 737 super("THREAD"); 738 } 739 Node node; 740 Node[] keep; 741 Error err; 742 743 public void run() { 744 synchronized (TOKEN) { 745 } 746 747 try { 748 keep = node.getChildren().getNodes(true); 749 } catch (Error err) { 750 this.err = err; 751 } 752 } 753 } 754 755 Th t = new Th(); 756 ChildrenKeys children = new ChildrenKeys(); 757 t.node = new AbstractNode(children); 758 759 Node[] remember; 760 synchronized (TOKEN) { 761 t.start(); 762 763 remember = t.node.getChildren().getNodes(); 766 767 TOKEN.notifyAll(); 768 } 769 770 t.join(); 772 773 if (2 != count[0]) { 774 StringWriter w = new StringWriter (); 775 PrintWriter pw = new PrintWriter (w); 776 w.write("Just two nodes created: " + count[0] + " stacks:\n"); 777 Iterator it = who.iterator(); 778 while (it.hasNext()) { 779 Exception e = (Exception )it.next(); 780 e.printStackTrace(pw); 781 } 782 pw.close(); 783 784 fail(w.toString());; 785 } 786 787 if (t.err != null) { 788 throw t.err; 789 } 790 791 } 793 794 795 797 public static class Keys extends Children.Keys { 798 public Keys () { 799 } 800 801 public Keys (int minKeys, int maxKeys) { 802 super(); 803 } 804 805 807 public Keys (String [] args) { 808 setKeys (args); 809 } 810 811 813 public void keys (String [] args) { 814 super.setKeys (args); 815 } 816 817 819 public void keys (Collection args) { 820 super.setKeys (args); 821 } 822 823 828 protected Node[] createNodes(Object key) { 829 AbstractNode an = new AbstractNode (Children.LEAF); 830 an.setName (key.toString ()); 831 832 return new Node[] { an }; 833 } 834 835 } 836 837 public static class Counter extends Children.Keys { 838 int limit; 839 int count = 0; 840 841 public Counter (int limit) { 842 this.limit = limit; 843 } 844 845 846 848 public void keys (String [] args) { 849 super.setKeys (args); 850 } 851 852 854 public void keys (Collection args) { 855 super.setKeys (args); 856 } 857 858 863 protected Node[] createNodes(Object key) { 864 synchronized(this) { 865 count++; 866 assertTrue("# of created nodes", count <= limit); 867 } 868 AbstractNode an = new AbstractNode (Children.LEAF); 869 an.setName (key.toString ()); 870 871 return new Node[] { an }; 872 } 873 874 } 875 876 static class Listener extends NodeAdapter { 877 private LinkedList events = new LinkedList (); 878 879 880 public void childrenRemoved (NodeMemberEvent ev) { 881 events.add (ev); 882 } 883 884 public void childrenAdded (NodeMemberEvent ev) { 885 events.add (ev); 886 } 887 888 public void childrenReordered (NodeReorderEvent ev) { 889 events.add (ev); 890 } 891 892 public NodeMemberEvent assertEvents (int number) { 893 if (events.size () != number) { 894 fail ("There should be " + number + " event(s) but was :" + events.size () + ":\n" + events); 895 } 896 return (NodeMemberEvent)events.removeFirst (); 897 } 898 899 public void assertAddEvent (String msg, int cnt) { 900 checkOneEvent (msg, cnt, null, true); 901 } 902 public void assertRemoveEvent (String msg, int cnt) { 903 checkOneEvent (msg, cnt, null, false); 904 } 905 public void assertAddEvent (String msg, int[] indexes) { 906 checkOneEvent (msg, indexes.length, indexes, true); 907 } 908 public void assertRemoveEvent (String msg, int[] indexes) { 909 checkOneEvent (msg, indexes.length, indexes, false); 910 } 911 912 public void assertReorderEvent (String msg, int[] perm) { 913 assertFalse (msg + " Cannot be empty", events.isEmpty ()); 914 Object o = events.removeFirst (); 915 assertEquals (msg + " Reoder event", NodeReorderEvent.class, o.getClass ()); 916 NodeReorderEvent m = (NodeReorderEvent)o; 917 918 int[] arr = m.getPermutation (); 919 FAIL: if (arr.length == perm.length) { 920 for (int i = 0; i < arr.length; i++) { 921 if (arr[i] != perm[i]) break FAIL; 922 } 923 return; 924 } 925 926 StringBuffer sb = new StringBuffer (); 927 928 for (int i = 0; i < arr.length; i++) { 929 sb.append ("at [" + i + "]: "); 930 if (arr.length > i) { 931 sb.append (arr[i]); 932 } else { 933 sb.append ("none"); 934 } 935 sb.append (" = "); 936 if (perm.length > i) { 937 sb.append (perm[i]); 938 } else { 939 sb.append ("none"); 940 } 941 } 942 fail (sb.toString ()); 943 } 944 945 private void checkOneEvent (String msg, int cnt, int[] indexes, boolean add) { 946 assertFalse (msg + " Cannot be empty", events.isEmpty ()); 947 Object o = events.removeFirst (); 948 assertEquals (msg + " Remove event", NodeMemberEvent.class, o.getClass ()); 949 NodeMemberEvent m = (NodeMemberEvent)o; 950 if (add) { 951 assertTrue (msg + " is add ", m.isAddEvent ()); 952 } else { 953 assertFalse (msg + " Is remove", m.isAddEvent ()); 954 } 955 assertEquals (msg + " Right count of removed nodes", cnt, m.getDelta ().length); 956 assertEquals (msg + " Right count of removed indicies", cnt, m.getDeltaIndices ().length); 957 958 if (indexes != null) { 959 StringBuffer f = new StringBuffer (); 960 boolean ok = true; 961 for (int i = 0; i < cnt; i++) { 962 f.append ("[" + i + "]: " + indexes[i] + " = " + m.getDeltaIndices ()[i] + "\n"); 963 ok = ok && indexes[i] == m.getDeltaIndices ()[i]; 964 } 965 if (!ok) { 966 fail ("Indicies are not correct:\n" + f); 967 } 968 } 969 } 970 971 public void assertNoEvents (String msg) { 972 assertEquals (msg, 0, events.size ()); 973 } 974 975 } 977 Ticker t1 = new Ticker(); 978 979 private static class Ticker { 980 boolean state; 981 982 public void waitOn() { 983 synchronized(this) { 984 while (!state) { 985 try { 986 wait(); 987 } catch (InterruptedException e) { 988 throw new InternalError (); 989 } 990 } 991 state = false; } 993 } 994 995 public void tick() { 996 synchronized(this) { 997 state = true; 998 notifyAll(); 999 } 1000 } 1001 } 1002 1003 1004} 1005 | Popular Tags |