KickJava   Java API By Example, From Geeks To Geeks.

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


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 junit.framework.*;
23 import junit.textui.TestRunner;
24 import java.util.*;
25 import org.openide.cookies.EditCookie;
26 import org.openide.cookies.OpenCookie;
27 import org.openide.cookies.SaveCookie;
28 import org.openide.nodes.*;
29
30 import org.netbeans.junit.*;
31 import javax.swing.event.ChangeListener JavaDoc;
32
33 import org.openide.nodes.CookieSet.Factory;
34
35 /** Checks whether modified behaviour of cookie set is the same as
36  * behaviour of the old one.
37  *
38  * @author Jaroslav Tulach
39  */

40 public class CookieSetCompatibilityTest extends NbTestCase implements java.lang.reflect.InvocationHandler JavaDoc {
41     private ArrayList interfaces = new ArrayList ();
42     private ArrayList classes = new ArrayList ();
43     private ArrayList instances = new ArrayList ();
44     
45     public CookieSetCompatibilityTest(String JavaDoc name) {
46         super(name);
47     }
48
49     
50     public void testRandomCheck () throws Exception JavaDoc {
51         long seed = System.currentTimeMillis();
52         try {
53             compare (createOperator (new CookieSet ()), new OldCookieSetFromFebruary2005 (), seed);
54         } catch (AssertionFailedError ex) {
55             AssertionFailedError n = new AssertionFailedError ("Seed: " + seed + "\n" + ex.getMessage ());
56             n.initCause(ex);
57             throw n;
58         } catch (Exception JavaDoc ex) {
59             IllegalStateException JavaDoc n = new IllegalStateException JavaDoc ("Seed: " + seed + "\n" + ex.getMessage ());
60             n.initCause(ex);
61             throw n;
62         }
63     }
64     
65     private void compare (Operator o1, Operator o2, long seed) throws Exception JavaDoc {
66         java.util.Random JavaDoc r = new java.util.Random JavaDoc (seed);
67         
68         interfaces.add (org.openide.cookies.SaveCookie.class);
69         interfaces.add (java.io.Serializable JavaDoc.class);
70         interfaces.add (Runnable JavaDoc.class);
71         interfaces.add (Node.Cookie.class);
72
73         class L implements javax.swing.event.ChangeListener JavaDoc, CookieSet.Factory {
74             public int cnt;
75             
76             public void stateChanged (javax.swing.event.ChangeEvent JavaDoc ev) {
77                 cnt++;
78             }
79
80             
81             private HashMap/*Class,Object*/ createdCookies = new HashMap ();
82             public Node.Cookie createCookie (Class JavaDoc c) {
83                 Object JavaDoc o = createdCookies.get (c);
84                 if (o != null) {
85                     return (Node.Cookie)o;
86                 }
87                 
88                 try {
89                     Node.Cookie cookie = (Node.Cookie)c.getConstructors()[0].newInstance(new Object JavaDoc[] { CookieSetCompatibilityTest.this });
90                     createdCookies.put (c, cookie);
91                     return cookie;
92                 } catch (Exception JavaDoc ex) {
93                     throw (AssertionFailedError)new AssertionFailedError (ex.getMessage()).initCause(ex);
94                 }
95                 
96             }
97         }
98         
99         L listener1 = new L ();
100         L listener2 = new L ();
101         
102         o1.addChangeListener(listener1);
103         o2.addChangeListener(listener2);
104         
105         for (int bigLoop = 0; bigLoop < 1000; bigLoop++) {
106             int operation = r.nextInt(10);
107             switch (operation) {
108                 case 0: { // generate new class
109
ArrayList superclasses = new ArrayList ();
110                     int number = r.nextInt (interfaces.size () + 1);
111                     for (int i = 0; i < number; i++) {
112                         int index = r.nextInt (interfaces.size ());
113                         Class JavaDoc c = (Class JavaDoc)interfaces.get (index);
114                         if (!superclasses.contains (c)) {
115                             superclasses.add (c);
116                         }
117                     }
118                     Class JavaDoc c = java.lang.reflect.Proxy.getProxyClass(getClass ().getClassLoader(), (Class JavaDoc[])superclasses.toArray(new Class JavaDoc[0]));
119                     classes.add (c);
120                     break;
121                 }
122                 case 1: { // generate new instance
123
Object JavaDoc o;
124                     Class JavaDoc c = randomClass (false, true, r);
125                     if (c != null) {
126                         o = c.getConstructors()[0].newInstance(new Object JavaDoc[] { this });
127                     } else {
128                         o = new Integer JavaDoc (r.nextInt());
129                     }
130                     instances.add (o);
131                     break;
132                 }
133                 case 2: { // just add
134
if (instances.size () > 0) {
135                         int index = r.nextInt (instances.size ());
136                         Object JavaDoc o = instances.get (index);
137                         if (o instanceof Node.Cookie) {
138                             o1.add ((Node.Cookie)o);
139                             o2.add ((Node.Cookie)o);
140                         }
141                     }
142                     break;
143                 }
144                 case 3: { // just remove
145
if (instances.size () > 0) {
146                         int index = r.nextInt (instances.size ());
147                         Object JavaDoc o = instances.get (index);
148                         if (o instanceof Node.Cookie) {
149                             o1.remove ((Node.Cookie)o);
150                             o2.remove ((Node.Cookie)o);
151                         }
152                     }
153                     break;
154                 }
155                 case 4: { // check the get
156
Class JavaDoc query = randomClass (true, true, r);
157                     Object JavaDoc r1 = o1.getCookie(query);
158                     Object JavaDoc r2 = o2.getCookie(query);
159                     assertSame ("After querying " + query, r1, r2);
160                     break;
161                 }
162                 case 5: { // single class factory
163
Class JavaDoc c = randomClass (false, true, r);
164                     if (c != null) {
165                         CookieSet.Factory f = r.nextBoolean() ? listener1 : listener2;
166
167                         o1.add (c, f);
168                         o2.add (c, f);
169                     }
170                     break;
171                 }
172                 case 6: { // single class factory
173
Class JavaDoc c = randomClass (false, true, r);
174                     if (c != null) {
175                         CookieSet.Factory f = r.nextBoolean() ? listener1 : listener2;
176
177                         o1.remove (c, f);
178                         o2.remove (c, f);
179                     }
180                     break;
181                 }
182                 case 7: { // array class factory
183
Class JavaDoc[] arr = randomClasses (false, true, r);
184                     CookieSet.Factory f = r.nextBoolean() ? listener1 : listener2;
185
186                     o1.add (arr, f);
187                     o2.add (arr, f);
188                     break;
189                 }
190                 case 8: { // single class factory
191
Class JavaDoc[] arr = randomClasses (false, true, r);
192                     CookieSet.Factory f = r.nextBoolean() ? listener1 : listener2;
193
194                     o1.remove (arr, f);
195                     o2.remove (arr, f);
196                     break;
197                 }
198             }
199             
200             assertEquals ("Listener counts are the same", listener1.cnt, listener2.cnt);
201         }
202         
203     }
204     
205     private Class JavaDoc[] randomClasses (boolean fromInterfaces, boolean fromClasses, Random r) {
206         ArrayList arr = new ArrayList ();
207         int cnt = r.nextInt((fromInterfaces ? interfaces.size () : 0) + (fromClasses ? classes.size () : 0) + 1);
208         while (cnt-- > 0) {
209             Class JavaDoc c = randomClass (fromInterfaces, fromClasses, r);
210             if (c != null && !arr.contains (c)) {
211                 arr.add (c);
212             }
213         }
214         return (Class JavaDoc[])arr.toArray (new Class JavaDoc[0]);
215     }
216     
217     private Class JavaDoc randomClass (boolean fromInterfaces, boolean fromClasses, Random r) {
218         if (fromInterfaces && fromClasses) {
219             if (r.nextBoolean()) {
220                 return randomClass (interfaces, r);
221             } else {
222                 return randomClass (classes, r);
223             }
224         }
225         
226         if (fromInterfaces) {
227             return randomClass (interfaces, r);
228         }
229         
230         if (fromClasses) {
231             return randomClass (classes, r);
232         }
233         
234         return null;
235     }
236     
237     private Class JavaDoc randomClass (List l, Random r) {
238         if (l.size () == 0) return null;
239         
240         int index = r.nextInt (l.size ());
241         return (Class JavaDoc)l.get (index);
242     }
243
244     
245     public interface Operator {
246         public void add (Node.Cookie cookie);
247         public void add(Class JavaDoc cookieClass, Factory factory);
248         public void add(Class JavaDoc[] cookieClass, Factory factory);
249
250         public void remove (Node.Cookie cookie);
251         public void remove(Class JavaDoc cookieClass, Factory factory);
252         public void remove(Class JavaDoc[] cookieClass, Factory factory);
253         
254         public Node.Cookie getCookie (Class JavaDoc clazz);
255         public void addChangeListener (ChangeListener JavaDoc l);
256         public void removeChangeListener (ChangeListener JavaDoc l);
257         
258     }
259     
260     private Operator createOperator (final CookieSet set) {
261         class O implements Operator {
262             public void add (Node.Cookie cookie) {
263                 set.add (cookie);
264             }
265             public void add(Class JavaDoc cookieClass, Factory factory) {
266                 set.add (cookieClass, factory);
267             }
268             public void add(Class JavaDoc[] cookieClass, Factory factory) {
269                 set.add (cookieClass, factory);
270             }
271
272             public void remove (Node.Cookie cookie) {
273                 set.remove (cookie);
274             }
275             public void remove(Class JavaDoc cookieClass, Factory factory) {
276                 set.remove (cookieClass, factory);
277             }
278             public void remove(Class JavaDoc[] cookieClass, Factory factory) {
279                 set.remove (cookieClass, factory);
280             }
281
282             public Node.Cookie getCookie (Class JavaDoc clazz) {
283                 return set.getCookie (clazz);
284             }
285             public void addChangeListener (ChangeListener JavaDoc l) {
286                 set.addChangeListener (l);
287             }
288             public void removeChangeListener (ChangeListener JavaDoc l) {
289                 set.removeChangeListener (l);
290             }
291         }
292         return new O ();
293     }
294
295     public Object JavaDoc invoke(Object JavaDoc proxy, java.lang.reflect.Method JavaDoc method, Object JavaDoc[] args) throws Throwable JavaDoc {
296         if (method.getDeclaringClass() == Object JavaDoc.class) {
297             // ok we have to implement these
298
if ("equals".equals (method.getName())) {
299                 return Boolean.valueOf (proxy == args[0]);
300             }
301             if ("hashCode".equals (method.getName ())) {
302                 return new Integer JavaDoc (System.identityHashCode(proxy));
303             }
304             if ("toString".equals (method.getName ())) {
305                 return proxy.getClass () + "@" + System.identityHashCode(proxy);
306             }
307             
308         }
309         
310         throw new org.openide.util.NotImplementedException ("Method: " + method);
311     }
312     
313
314     /** This is a copy of the implementation of CookieSet from Feb 2005, rev. 1.16 */
315     static final class OldCookieSetFromFebruary2005 extends Object JavaDoc implements Operator {
316         /** variable to allow effecient communication with NodeLookup */
317         private static java.lang.ThreadLocal JavaDoc QUERY_MODE = new java.lang.ThreadLocal JavaDoc ();
318
319         /** list of cookies (Class, Node.Cookie) */
320         private HashMap map = new HashMap (31);
321
322         /** set of listeners */
323         private javax.swing.event.EventListenerList JavaDoc listeners = new javax.swing.event.EventListenerList JavaDoc ();
324
325         /** Default constructor. */
326         public OldCookieSetFromFebruary2005 () {}
327
328         /** Add a new cookie to the set. If a cookie of the same
329         * <em>actual</em> (not representation!) class is already there,
330         * it is replaced.
331         * <p>Cookies inserted earlier are given preference during lookup,
332         * in case a supplied representation class matches more than one cookie
333         * in the set.
334         *
335         * @param cookie cookie to add
336         */

337         public void add (Node.Cookie cookie) {
338             synchronized (this) {
339                 registerCookie (cookie.getClass (), cookie);
340             }
341
342             fireChangeEvent ();
343         }
344
345         /** Remove a cookie from the set.
346         * @param cookie the cookie to remove
347         */

348         public void remove (Node.Cookie cookie) {
349             synchronized (this) {
350                 unregisterCookie (cookie.getClass (), cookie);
351             }
352
353             fireChangeEvent ();
354         }
355
356         /** Get a cookie.
357         *
358         * @param clazz the representation class
359         * @return a cookie assignable to the representation class, or <code>null</code> if there is none
360         */

361         public Node.Cookie getCookie (Class JavaDoc clazz) {
362             Node.Cookie ret = null;
363             synchronized (this) {
364                 R r = findR (clazz);
365                 if (r == null) {
366                     return null;
367                 }
368                 ret = r.cookie ();
369             }
370             if (ret instanceof CookieEntry) {
371                 if (clazz == QUERY_MODE.get ()) {
372                     // we expected to be asked for this class
373
// set cookie entry as a result
374
QUERY_MODE.set (ret);
375                     ret = null;
376                 } else {
377                     // unwrap the cookie
378
ret = ((CookieEntry) ret).getCookie(true);
379                 }
380             }
381
382             return ret;
383         }
384
385         /** Add a listener to changes in the cookie set.
386         * @param l the listener to add
387         */

388         public void addChangeListener (ChangeListener JavaDoc l) {
389             listeners.add (ChangeListener JavaDoc.class, l);
390         }
391
392         /** Remove a listener to changes in the cookie set.
393         * @param l the listener to remove
394         */

395         public void removeChangeListener (ChangeListener JavaDoc l) {
396             listeners.remove (ChangeListener JavaDoc.class, l);
397         }
398
399         /** Node lookup starts its non-important query.
400          */

401         static Object JavaDoc entryQueryMode (Class JavaDoc c) {
402             Object JavaDoc prev = QUERY_MODE.get ();
403             QUERY_MODE.set (c);
404             return prev;
405         }
406
407         /** Exits query mode.
408          */

409         static org.openide.util.lookup.AbstractLookup.Pair exitQueryMode (Object JavaDoc prev) {
410             Object JavaDoc cookie = QUERY_MODE.get ();
411             QUERY_MODE.set (prev);
412             if (cookie instanceof CookieEntry) {
413                 return new CookieEntryPair ((CookieEntry)cookie);
414             } else {
415                 return null;
416             }
417         }
418
419         /** Fires change event
420         */

421         private void fireChangeEvent () {
422             Object JavaDoc[] arr = listeners.getListenerList();
423             if (arr.length > 0) {
424                 javax.swing.event.ChangeEvent JavaDoc ev = null;
425                 // Process the listeners last to first, notifying
426
// those that are interested in this event
427
for (int i = arr.length-2; i>=0; i-=2) {
428                     if (arr[i] == ChangeListener JavaDoc.class) {
429                         if (ev == null) {
430                             ev = new javax.swing.event.ChangeEvent JavaDoc (this);
431                         }
432
433                         ((ChangeListener JavaDoc)arr[i + 1]).stateChanged (ev);
434                     }
435                 }
436             }
437         }
438
439         /** Attaches cookie to given class and all its superclasses and
440         * superinterfaces.
441         *
442         * @param c class or null
443         * @param cookie cookie to attach
444         */

445         private void registerCookie (Class JavaDoc c, Node.Cookie cookie) {
446             if ((c == null) || !Node.Cookie.class.isAssignableFrom(c)) return;
447
448             R r = findR (c);
449             if (r == null) {
450                 r = new R ();
451                 map.put (c, r);
452             }
453
454             r.add (cookie);
455
456             registerCookie (c.getSuperclass (), cookie);
457
458             Class JavaDoc[] inter = c.getInterfaces ();
459             for (int i = 0; i < inter.length; i++) {
460                 registerCookie (inter[i], cookie);
461             }
462         }
463
464         /** Removes cookie from the class and all its superclasses and
465         * superinterfaces.
466         *
467         * @param c class or null
468         * @param cookie cookie to attach
469         */

470         private void unregisterCookie (Class JavaDoc c, Node.Cookie cookie) {
471             if (
472                 c == null || !Node.Cookie.class.isAssignableFrom(c)
473             ) return;
474
475             // if different cookie is attached to class c stop removing
476
R r = findR (c);
477             if (r != null) {
478                 // remove the cookie
479
r.remove (cookie);
480             }
481
482             unregisterCookie (c.getSuperclass (), cookie);
483
484             Class JavaDoc[] inter = c.getInterfaces ();
485             for (int i = 0; i < inter.length; i++) {
486                 unregisterCookie (inter[i], cookie);
487             }
488         }
489
490         /** Registers a Factory for given cookie class */
491         public void add(Class JavaDoc cookieClass, Factory factory) {
492             if (factory == null) {
493                 throw new IllegalArgumentException JavaDoc();
494             }
495
496             synchronized (this) {
497                 registerCookie (cookieClass, new CookieEntry(factory, cookieClass));
498             }
499
500             fireChangeEvent ();
501         }
502
503         /** Registers a Factory for given cookie classes */
504         public void add(Class JavaDoc[] cookieClass, Factory factory) {
505             if (factory == null) {
506                 throw new IllegalArgumentException JavaDoc();
507             }
508
509             synchronized (this) {
510                 for (int i = 0; i < cookieClass.length; i++) {
511                     registerCookie (cookieClass[i], new CookieEntry(factory, cookieClass[i]));
512                 }
513             }
514
515             fireChangeEvent ();
516         }
517
518         /**
519          * Unregisters a Factory for given cookie class
520          * @since 2.6
521          */

522         public void remove(Class JavaDoc cookieClass, Factory factory) {
523             if (factory == null) {
524                 throw new IllegalArgumentException JavaDoc();
525             }
526
527             synchronized (this) {
528                 R r = findR(cookieClass);
529                 if (r != null) {
530                     Node.Cookie c = r.cookie();
531                     if (c instanceof CookieEntry) {
532                         CookieEntry ce = (CookieEntry)c;
533                         if (ce.factory == factory) {
534                             unregisterCookie (cookieClass, c);
535                         }
536                     }
537                 }
538             }
539
540             fireChangeEvent ();
541         }
542
543         /**
544          * Unregisters a Factory for given cookie classes
545          * @since 2.6
546          */

547         public void remove(Class JavaDoc[] cookieClass, Factory factory) {
548             if (factory == null) {
549                 throw new IllegalArgumentException JavaDoc();
550             }
551
552             synchronized (this) {
553                 for (int i = 0; i < cookieClass.length; i++) {
554                     R r = findR(cookieClass[i]);
555                     if (r != null) {
556                         Node.Cookie c = r.cookie();
557                         if (c instanceof CookieEntry) {
558                             CookieEntry ce = (CookieEntry)c;
559                             if (ce.factory == factory) {
560                                 unregisterCookie (cookieClass[i], c);
561                             }
562                         }
563                     }
564                 }
565             }
566
567             fireChangeEvent ();
568         }
569
570         /** Finds a result in a map.
571          */

572         private R findR (Class JavaDoc c) {
573             return (R)map.get (c);
574         }
575
576         /** Finds base class for a cookie.
577          * @param c cookie
578          * @return base class
579          */

580         private static Class JavaDoc baseForCookie (Node.Cookie c) {
581             if (c instanceof CookieEntry) {
582                 return ((CookieEntry)c).klass;
583             }
584             return c.getClass ();
585         }
586
587
588         /** Entry for one Cookie */
589         private static class CookieEntry implements Node.Cookie {
590             /** Factory for the cookie */
591             final Factory factory;
592             /** Class of the cookie */
593             private final Class JavaDoc klass;
594             /** A Referenec to the cookie */
595             private java.lang.ref.Reference JavaDoc cookie;
596
597             /** Constructs new FactoryEntry */
598             public CookieEntry(Factory factory, Class JavaDoc klass) {
599                 this.factory = factory;
600                 this.klass = klass;
601             }
602
603             /** Getter for the cookie.
604              * Synchronized because we don't want to run factory.createCookie
605              * symultaneously from two threads.
606              */

607             public synchronized Node.Cookie getCookie(boolean create) {
608                 Node.Cookie ret;
609                 if (create) {
610                     if ((cookie == null) || ((ret = (Node.Cookie) cookie.get()) == null)) {
611                         ret = factory.createCookie(klass);
612                         if (ret == null) return null;
613                         cookie = new java.lang.ref.WeakReference JavaDoc(ret);
614                     }
615                 } else {
616                     ret = (Node.Cookie) (cookie == null ? null : cookie.get ());
617                 }
618
619                 return ret;
620             }
621         } // end of CookieEntry
622

623         /** Pair that represents an entry.
624          */

625         private static final class CookieEntryPair extends org.openide.util.lookup.AbstractLookup.Pair {
626             private CookieEntry entry;
627
628             public CookieEntryPair (CookieEntry e) {
629                 this.entry = e;
630             }
631
632             protected boolean creatorOf(Object JavaDoc obj) {
633                 return obj == entry.getCookie (false);
634             }
635
636             public String JavaDoc getDisplayName() {
637                 return getId ();
638             }
639
640             public String JavaDoc getId() {
641                 return entry.klass.getName ();
642             }
643
644             public Object JavaDoc getInstance() {
645                 return entry.getCookie (true);
646             }
647
648             public Class JavaDoc getType() {
649                 return entry.klass;
650             }
651
652             protected boolean instanceOf(Class JavaDoc c) {
653                 return c.isAssignableFrom(entry.klass);
654             }
655
656             public int hashCode () {
657                 return entry.hashCode () + 5;
658             }
659
660             public boolean equals (Object JavaDoc obj) {
661                 if (obj instanceof CookieEntryPair) {
662                     return ((CookieEntryPair)obj).entry == entry;
663                 }
664                 return false;
665             }
666         } // end of CookieEntryPair
667

668         /** Implementation of the result.
669          */

670         private static final class R extends Object JavaDoc {
671             /** list of registered cookies */
672             public List cookies;
673             /** base class of the first cookie registered here */
674             public Class JavaDoc base;
675
676             R() {}
677
678             /** Adds a cookie.
679              * @return true if adding should continue on superclasses should continue
680              */

681             public void add (Node.Cookie cookie) {
682                 if (cookies == null) {
683                     cookies = new ArrayList (1);
684                     cookies.add (cookie);
685                     base = baseForCookie (cookie);
686                     return;
687                 }
688
689                 Class JavaDoc newBase = baseForCookie (cookie);
690                 if (base == null || newBase.isAssignableFrom (base)) {
691                     cookies.set (0, cookie);
692                     base = newBase;
693                 } else {
694                     cookies.add (cookie);
695                 }
696             }
697
698             /** Removes a cookie.
699              * @return true if empty
700              */

701             public boolean remove (Node.Cookie cookie) {
702                 if (cookies == null) {
703                     return true;
704                 }
705
706                 if (cookies.remove (cookie) && cookies.size () == 0) {
707                     base = null;
708                     cookies = null;
709                     return true;
710                 }
711
712                 base = baseForCookie ((Node.Cookie)cookies.get (0));
713
714                 return false;
715             }
716
717             /** @return the cookie for this result or null
718              */

719             public Node.Cookie cookie () {
720                 return cookies == null || cookies.isEmpty () ? null : (Node.Cookie)cookies.get (0);
721             }
722         }
723     } // end of OldCookieSetFromFebruary2005
724

725 }
726
Popular Tags