KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > openide > nodes > ChildrenKeysTest


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.openide.nodes;
21
22 import java.io.PrintWriter JavaDoc;
23 import java.io.StringWriter JavaDoc;
24 import java.lang.ref.Reference JavaDoc;
25 import java.lang.ref.WeakReference JavaDoc;
26 import java.util.ArrayList JavaDoc;
27 import java.util.Arrays JavaDoc;
28 import java.util.Collection JavaDoc;
29 import java.util.Collections JavaDoc;
30 import java.util.Iterator JavaDoc;
31 import java.util.LinkedList JavaDoc;
32 import java.util.List JavaDoc;
33 import java.util.logging.Level JavaDoc;
34 import java.util.logging.Logger JavaDoc;
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 JavaDoc err;
41     private Logger JavaDoc LOG;
42     
43     public ChildrenKeysTest(java.lang.String JavaDoc 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         //return new NbTestSuite(ChildrenKeysTest.class);
54
}
55     
56     @Override JavaDoc
57     protected Level JavaDoc logLevel() {
58         return Level.INFO;
59     }
60
61     
62
63     protected void setUp () throws Exception JavaDoc {
64         err = Log.enable("", Level.ALL);
65         LOG = Logger.getLogger("test." + getName());
66     }
67
68     public void testGetNodesFromTwoThreads57769() throws Exception JavaDoc {
69         final Ticker t1 = new Ticker();
70         final List JavaDoc who = new java.util.Vector JavaDoc();
71         
72         final int[] count = new int[1];
73         Children children= new Children.Keys() {
74             protected Node[] createNodes(Object JavaDoc key) {
75                 StringWriter JavaDoc msg = new StringWriter JavaDoc();
76                 msg.write("Creating: " + count[0] + " for key: " + key + "\n");
77                 new Exception JavaDoc().printStackTrace(new PrintWriter JavaDoc(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 JavaDoc e) {}
83                 return n == null ? new Node[]{} : new Node[]{n};
84             }
85
86             protected void addNotify() {
87                 setKeys(Arrays.asList(new Object JavaDoc[] {"1", "2"}));
88             }
89         };
90         final Node node = new AbstractNode(children);
91         
92         // Get optimal nodes from other thread
93
Thread JavaDoc t = new Thread JavaDoc("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         // and also from main thread
104
Node[] remember = node.getChildren().getNodes();
105         
106         // wait for other thread
107
t.join();
108         
109         if (2 != count[0]) {
110             StringWriter JavaDoc w = new StringWriter JavaDoc();
111             PrintWriter JavaDoc pw = new PrintWriter JavaDoc(w);
112             w.write("Just two nodes created: " + count[0] + " stacks:\n");
113             Iterator JavaDoc it = who.iterator();
114             while (it.hasNext()) {
115                 Exception JavaDoc e = (Exception JavaDoc)it.next();
116                 e.printStackTrace(pw);
117             }
118             pw.close();
119             
120             fail(w.toString());;
121         }//fail("Ok");
122
}
123
124     /**
125      * See #78519
126      * T1 has write access and gets preempted just before call to
127      * getNodes() by another thread callig getNodes.
128      * Other thread
129      */

130     public void testGetNodesFromWriteAccess() throws Exception JavaDoc {
131         final String JavaDoc[] 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         // Try to get nodes from writeAccess
142
Thread JavaDoc t = new Thread JavaDoc("preempted") {
143             public void run() {
144                 Children.PR.enterWriteAccess();
145                 try {
146                     t1.tick(); // I do have the write access ...
147
tick2.waitOn(); // ... so wait till I'm preempted
148
k.getNodes();
149                 } finally {
150                     Children.PR.exitWriteAccess();
151                 }
152                 done[0] = true;
153             }
154         };
155         t.start();
156         t1.waitOn();
157         
158         // and also from another thread
159
Thread JavaDoc t2 = new Thread JavaDoc("other") {
160             public void run() {
161                 k.getNodes(); // will block in getNodes
162
done[1] = true;
163             }
164         };
165         t2.start();
166         
167         Thread.sleep(2000); // give T2 some time ...
168
tick2.tick(); // and unfuse T
169

170         // wait for other thread
171
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     /**
182      * See issue #76614
183      */

184     public void testNodesCreatedJustOnce() throws Exception JavaDoc {
185         Counter children = new Counter(1);
186         Node node = new AbstractNode(children);
187         children.keys(Arrays.asList(new Object JavaDoc[] {"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 JavaDoc {
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 JavaDoc[] { "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 JavaDoc[] { "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 JavaDoc ref = new WeakReference JavaDoc (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 JavaDoc {
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 JavaDoc[] { "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 JavaDoc[] { "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 JavaDoc ref = new WeakReference JavaDoc (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 JavaDoc {
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 JavaDoc 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 JavaDoc[] { "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 JavaDoc ref = new WeakReference JavaDoc (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 JavaDoc {
305         final String JavaDoc[] keys = { "Hrebejk", "Tulach" };
306         final Keys k = new Keys (keys);
307         
308         Keys.MUTEX.readAccess (new Runnable JavaDoc () {
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 JavaDoc {
321         class K extends Children.Keys {
322             int counterAdd = 0;
323             int counterRem = 0;
324             Object JavaDoc key;
325             
326             Reference JavaDoc createdNode;
327             
328             K(Object JavaDoc 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 JavaDoc k) {
344                 Node n = Node.EMPTY.cloneNode();
345                 assertNull ("Just one created node", createdNode);
346                 createdNode = new WeakReference JavaDoc (n);
347                 return new Node[] { n };
348             }
349         }
350         
351         Object JavaDoc myKey = new Object JavaDoc();
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 JavaDoc ref = new WeakReference JavaDoc(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 JavaDoc(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 JavaDoc 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 JavaDoc list = new ArrayList JavaDoc ();
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 JavaDoc list = new ArrayList JavaDoc ();
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     /** Check whether a nodes appears when keys are set.
451     */

452     public void testGetNodes () throws Exception JavaDoc {
453         String JavaDoc[] arr = { "1", "2", "3", "4" };
454         Children ch = new Keys (arr);
455         checkNames (createNode (ch), arr);
456     }
457     
458     public void testGetNodesOptimalOn0to1 () throws Exception JavaDoc {
459         class K extends Keys {
460             private boolean acceptOposite;
461             
462             public K () {
463                 super (0, 1);
464             }
465             
466             protected Node[] createNodes (Object JavaDoc k) {
467                 boolean a = k instanceof String JavaDoc;
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 JavaDoc[] keys = { "Ahoj", new Integer JavaDoc (3), "Kuk", new Integer JavaDoc (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 JavaDoc[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 JavaDoc[] { "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 JavaDoc[] { "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 JavaDoc[] { "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 JavaDoc[] { "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     /** Check refresh of nodes.
540      */

541     public void testResetOfNodes () throws Exception JavaDoc {
542         String JavaDoc[] arr;
543         Keys ch = new Keys ();
544         arr = new String JavaDoc[] { "1", "2" };
545         Node node = createNode (ch);
546         
547         ch.keys (arr);
548         checkNames (node, arr);
549         
550         arr = new String JavaDoc[] { "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     /** Tests whether nodes in children have the correct names on correct places
560      * @param ch children
561      * @param arr names
562      */

563     private void checkNames (Node ch, String JavaDoc[] 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 JavaDoc[] { "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 JavaDoc[] { "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 JavaDoc[] { "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 JavaDoc {
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 JavaDoc[] { "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 JavaDoc {
636         ChildrenKeysTest.Keys k = new ChildrenKeysTest.Keys (new String JavaDoc[] { "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 JavaDoc[] { "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 JavaDoc {
659         Keys k = new Keys (new String JavaDoc[] { "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 JavaDoc[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 JavaDoc {
677         doRefreshClearsSize (0, 0);
678     }
679     
680     public void testRefreshClearsSizeOto1 () throws Exception JavaDoc {
681         doRefreshClearsSize (0, 1);
682     }
683     
684     private void doRefreshClearsSize (int min, int max) throws Exception JavaDoc {
685         final String JavaDoc[] NULL = { "Null" };
686         
687         Keys k = new Keys (min, max) {
688             protected Node[] createNodes (Object JavaDoc 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 JavaDoc[] { "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 JavaDoc {
711         final Ticker t1 = new Ticker();
712         final List JavaDoc who = new java.util.Vector JavaDoc();
713         
714         final int[] count = new int[1];
715         class ChildrenKeys extends Children.Keys {
716             protected Node[] createNodes(Object JavaDoc key) {
717                 who.add(new Exception JavaDoc("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 JavaDoc e) {}
722                 return n == null ? new Node[]{} : new Node[]{n};
723             }
724
725             protected void addNotify() {
726                 setKeys(Arrays.asList(new Object JavaDoc[] {"1", "2"}));
727             }
728         };
729         
730         // Get optimal nodes from other thread
731

732         final String JavaDoc TOKEN = new String JavaDoc("TOKEN to wait on");
733         final String JavaDoc THREAD_NAME = Thread.currentThread().getName();
734         
735         class Th extends Thread JavaDoc {
736             public Th() {
737                 super("THREAD");
738             }
739             Node node;
740             Node[] keep;
741             Error JavaDoc err;
742             
743             public void run() {
744                 synchronized (TOKEN) {
745                 }
746      
747                 try {
748                     keep = node.getChildren().getNodes(true);
749                 } catch (Error JavaDoc 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             // this call will result in "point X".notifyAll() when the
764
// main thread reaches "setEntries"
765
remember = t.node.getChildren().getNodes();
766             
767             TOKEN.notifyAll();
768         }
769         
770         // wait for other thread
771
t.join();
772         
773         if (2 != count[0]) {
774             StringWriter JavaDoc w = new StringWriter JavaDoc();
775             PrintWriter JavaDoc pw = new PrintWriter JavaDoc(w);
776             w.write("Just two nodes created: " + count[0] + " stacks:\n");
777             Iterator JavaDoc it = who.iterator();
778             while (it.hasNext()) {
779                 Exception JavaDoc e = (Exception JavaDoc)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         //fail("Ok");
792
}
793
794     
795     /** Sample keys.
796     */

797     public static class Keys extends Children.Keys {
798         public Keys () {
799         }
800         
801         public Keys (int minKeys, int maxKeys) {
802             super(/*XXX what was this for? minKeys, maxKeys*/);
803         }
804         
805         /** Constructor.
806          */

807         public Keys (String JavaDoc[] args) {
808             setKeys (args);
809         }
810         
811         /** Changes the keys.
812          */

813         public void keys (String JavaDoc[] args) {
814             super.setKeys (args);
815         }
816
817         /** Changes the keys.
818          */

819         public void keys (Collection JavaDoc args) {
820             super.setKeys (args);
821         }
822         
823         /** Create nodes for a given key.
824          * @param key the key
825          * @return child nodes for this key or null if there should be no
826          * nodes for this key
827          */

828         protected Node[] createNodes(Object JavaDoc 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         /** Changes the keys.
847          */

848         public void keys (String JavaDoc[] args) {
849             super.setKeys (args);
850         }
851
852         /** Changes the keys.
853          */

854         public void keys (Collection JavaDoc args) {
855             super.setKeys (args);
856         }
857         
858         /** Create nodes for a given key.
859          * @param key the key
860          * @return child nodes for this key or null if there should be no
861          * nodes for this key
862          */

863         protected Node[] createNodes(Object JavaDoc 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 JavaDoc events = new LinkedList JavaDoc ();
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 JavaDoc msg, int cnt) {
900             checkOneEvent (msg, cnt, null, true);
901         }
902         public void assertRemoveEvent (String JavaDoc msg, int cnt) {
903             checkOneEvent (msg, cnt, null, false);
904         }
905         public void assertAddEvent (String JavaDoc msg, int[] indexes) {
906             checkOneEvent (msg, indexes.length, indexes, true);
907         }
908         public void assertRemoveEvent (String JavaDoc msg, int[] indexes) {
909             checkOneEvent (msg, indexes.length, indexes, false);
910         }
911         
912         public void assertReorderEvent (String JavaDoc msg, int[] perm) {
913             assertFalse (msg + " Cannot be empty", events.isEmpty ());
914             Object JavaDoc 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 JavaDoc sb = new StringBuffer JavaDoc ();
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 JavaDoc msg, int cnt, int[] indexes, boolean add) {
946             assertFalse (msg + " Cannot be empty", events.isEmpty ());
947             Object JavaDoc 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 JavaDoc f = new StringBuffer JavaDoc ();
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 JavaDoc msg) {
972             assertEquals (msg, 0, events.size ());
973         }
974         
975     } // end of Listener
976

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 JavaDoc e) {
988                         throw new InternalError JavaDoc();
989                     }
990                 }
991                 state = false; // reusable
992
}
993         }
994         
995         public void tick() {
996             synchronized(this) {
997                 state = true;
998                 notifyAll();
999             }
1000        }
1001    }
1002
1003    
1004}
1005
Popular Tags