KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > openide > util > SharedClassObjectTest


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.util;
21
22 import java.beans.PropertyChangeEvent JavaDoc;
23 import java.beans.PropertyChangeListener JavaDoc;
24 import java.io.ByteArrayInputStream JavaDoc;
25 import java.io.ByteArrayOutputStream JavaDoc;
26 import java.io.ObjectInputStream JavaDoc;
27 import java.io.ObjectOutputStream JavaDoc;
28 import java.io.PrintStream JavaDoc;
29 import java.lang.ref.Reference JavaDoc;
30 import java.lang.ref.WeakReference JavaDoc;
31 import java.lang.reflect.Field JavaDoc;
32 import java.lang.reflect.Method JavaDoc;
33 import java.net.URL JavaDoc;
34 import java.net.URLClassLoader JavaDoc;
35 import junit.textui.TestRunner;
36 import org.netbeans.junit.NbTestCase;
37 import org.openide.util.SharedClassObject;
38
39 /** Test SharedClassObject singletons: esp. initialization semantics.
40  * @author Jesse Glick
41  */

42 public class SharedClassObjectTest extends NbTestCase {
43     
44     public SharedClassObjectTest(String JavaDoc name) {
45         super(name);
46     }
47     
48     public void testSimpleSCO() throws Exception JavaDoc {
49         Class JavaDoc c = makeClazz("SimpleSCO");
50         assertTrue(c != SimpleSCO.class);
51         assertNull("No instance created yet", SharedClassObject.findObject(c, false));
52         SharedClassObject o = SharedClassObject.findObject(c, true);
53         assertNotNull(o);
54         assertEquals("org.openide.util.SharedClassObjectTest$SimpleSCO", o.getClass().getName());
55         assertEquals(c, o.getClass());
56         assertEquals("has not been initialized", 0, o.getClass().getField("initcount").getInt(o));
57         assertNull(o.getProperty("foo"));
58         assertEquals("has been initialized", 1, o.getClass().getField("initcount").getInt(o));
59         assertNull(o.getProperty("bar"));
60         assertEquals("has been initialized just once", 1, o.getClass().getField("initcount").getInt(null));
61         Class JavaDoc c2 = makeClazz("SimpleSCO");
62         assertTrue("Call to makeClazz created a fresh class", c != c2);
63         SharedClassObject o2 = SharedClassObject.findObject(c2, true);
64         o2.getProperty("baz");
65         assertEquals(1, o2.getClass().getField("initcount").getInt(null));
66     }
67     
68     public void testClearSharedData() throws Exception JavaDoc {
69         Class JavaDoc c = makeClazz("DontClearSharedDataSCO");
70         SharedClassObject o = SharedClassObject.findObject(c, true);
71         o.putProperty("inited", Boolean.TRUE);
72         assertEquals("DCSD has been initialized", Boolean.TRUE, o.getProperty("inited"));
73         Reference JavaDoc r = new WeakReference JavaDoc(o);
74         o = null;
75         assertGC("collected SCO instance", r);
76         assertNull("findObject(Class,false) gives nothing after running GC + finalization #1", SharedClassObject.findObject(c));
77         o = SharedClassObject.findObject(c, true);
78         assertEquals("has still been initialized", Boolean.TRUE, o.getProperty("inited"));
79         c = makeClazz("ClearSharedDataSCO");
80         o = SharedClassObject.findObject(c, true);
81         o.putProperty("inited", Boolean.TRUE);
82         assertEquals("CSD has been initialized", Boolean.TRUE, o.getProperty("inited"));
83         r = new WeakReference JavaDoc(o);
84         o = null;
85         assertGC("collected SCO instance", r);
86         assertNull("findObject(Class,false) gives nothing after running GC + finalization #2", SharedClassObject.findObject(c));
87         o = SharedClassObject.findObject(c, true);
88         assertEquals("is no longer initialized", null, o.getProperty("inited"));
89         o.putProperty("inited", Boolean.TRUE);
90         assertEquals("has now been initialized again", Boolean.TRUE, o.getProperty("inited"));
91     }
92     
93     public void testIllegalState() throws Exception JavaDoc {
94         Class JavaDoc c = makeClazz("InitErrorSCO");
95         SharedClassObject o = SharedClassObject.findObject(c, true);
96         assertNotNull(o);
97         try {
98             o.getProperty("foo");
99             fail("should not be able to do anything with it");
100         } catch (IllegalStateException JavaDoc ise) {
101             // Good.
102
}
103         try {
104             o.getProperty("bar");
105             fail("should still not be able to do anything with it");
106         } catch (IllegalStateException JavaDoc ise) {
107             // Good.
108
}
109     }
110     
111     public void testPropertyChanges() throws Exception JavaDoc {
112         Class JavaDoc c = makeClazz("PropFirerSCO");
113         Method JavaDoc putprop = c.getMethod("putprop", new Class JavaDoc[] {Object JavaDoc.class, Boolean.TYPE});
114         Method JavaDoc getprop = c.getMethod("getprop", new Class JavaDoc[] {});
115         Field JavaDoc count = c.getField("addCount");
116         SharedClassObject o = SharedClassObject.findObject(c, true);
117         assertNull(getprop.invoke(o, null));
118         assertEquals(0, count.getInt(o));
119         class Listener implements PropertyChangeListener JavaDoc {
120             public int count = 0;
121             public void propertyChange(PropertyChangeEvent JavaDoc ev) {
122                 if ("key".equals(ev.getPropertyName())) {
123                     count++;
124                 }
125             }
126         }
127         Listener JavaDoc l = new Listener JavaDoc();
128         o.addPropertyChangeListener(l);
129         assertEquals(1, count.getInt(o));
130         Listener JavaDoc l2 = new Listener JavaDoc();
131         o.addPropertyChangeListener(l2);
132         assertEquals(1, count.getInt(o));
133         o.removePropertyChangeListener(l2);
134         assertEquals(1, count.getInt(o));
135         putprop.invoke(o, new Object JavaDoc[] {"something", Boolean.FALSE});
136         assertEquals(0, l.count);
137         assertEquals("something", getprop.invoke(o, null));
138         putprop.invoke(o, new Object JavaDoc[] {"somethingelse", Boolean.TRUE});
139         assertEquals(1, l.count);
140         assertEquals("somethingelse", getprop.invoke(o, null));
141         // Check that setting the same val does not fire an additional change (cf. #37769):
142
putprop.invoke(o, new Object JavaDoc[] {"somethingelse", Boolean.TRUE});
143         assertEquals(1, l.count);
144         assertEquals("somethingelse", getprop.invoke(o, null));
145         // Check equals() as well as ==:
146
putprop.invoke(o, new Object JavaDoc[] {new String JavaDoc("somethingelse"), Boolean.TRUE});
147         assertEquals(1, l.count);
148         assertEquals("somethingelse", getprop.invoke(o, null));
149         o.removePropertyChangeListener(l);
150         assertEquals(0, count.getInt(o));
151         o.addPropertyChangeListener(l);
152         assertEquals(1, count.getInt(o));
153         o.removePropertyChangeListener(l);
154         assertEquals(0, count.getInt(o));
155     }
156     
157     public void testRecursiveInit() throws Exception JavaDoc {
158         Class JavaDoc c = makeClazz("RecursiveInitSCO");
159         SharedClassObject o = SharedClassObject.findObject(c, true);
160         assertEquals(0, c.getField("count").getInt(null));
161         o.getProperty("foo");
162         assertEquals(1, c.getField("count").getInt(null));
163         assertEquals(o, c.getField("INSTANCE").get(null));
164     }
165     
166     public void testAbilityToReadResolveToAnyObject () throws Exception JavaDoc {
167         SharedClassObject o = SharedClassObject.findObject (SharedClassObjectWithReadResolve.class, true);
168         ByteArrayOutputStream JavaDoc os = new ByteArrayOutputStream JavaDoc ();
169         ObjectOutputStream JavaDoc oos = new ObjectOutputStream JavaDoc (os);
170         oos.writeObject (o);
171         oos.close ();
172         
173         ObjectInputStream JavaDoc ois = new ObjectInputStream JavaDoc (new ByteArrayInputStream JavaDoc (os.toByteArray()));
174         Object JavaDoc result = ois.readObject ();
175         ois.close ();
176         
177         
178         assertEquals ("Result should be the string", String JavaDoc.class, result.getClass());
179         
180     }
181     
182     /** Create a fresh Class object from one of this test's inner classes.
183      * Produces a new classloader so the class is always fresh.
184      */

185     private Class JavaDoc makeClazz(String JavaDoc name) throws Exception JavaDoc {
186         return Class.forName("org.openide.util.SharedClassObjectTest$" + name, false, new MaskingURLClassLoader());
187     }
188     private static final class MaskingURLClassLoader extends URLClassLoader JavaDoc {
189         public MaskingURLClassLoader() {
190             super(new URL JavaDoc[] {SharedClassObjectTest.class.getProtectionDomain().getCodeSource().getLocation()},
191                   SharedClassObject.class.getClassLoader());
192         }
193         protected Class JavaDoc loadClass(String JavaDoc name, boolean resolve) throws ClassNotFoundException JavaDoc {
194             if (name.startsWith("org.openide.util.SharedClassObjectTest")) {
195                 // Do not proxy to parent!
196
Class JavaDoc c = findLoadedClass(name);
197                 if (c != null) return c;
198                 c = findClass(name);
199                 if (resolve) resolveClass(c);
200                 return c;
201             } else {
202                 return super.loadClass(name, resolve);
203             }
204         }
205     }
206     
207     public static class SimpleSCO extends SharedClassObject {
208         public static int initcount = 0;
209         private static String JavaDoc firstinit = null;
210         protected void initialize() {
211             super.initialize();
212             initcount++;
213             if (initcount > 1) {
214                 System.err.println("Multiple initializations of SimpleSCO: see http://www.netbeans.org/issues/show_bug.cgi?id=14700");
215                 System.err.print(firstinit);
216                 new Throwable JavaDoc("Init #" + initcount + " here").printStackTrace();
217             } else {
218                 ByteArrayOutputStream JavaDoc baos = new ByteArrayOutputStream JavaDoc();
219                 new Throwable JavaDoc("Init #1 here").printStackTrace(new PrintStream JavaDoc(baos));
220                 firstinit = baos.toString();
221                 // don't print anything unless there is a problem later
222
}
223         }
224         // Protect against random workings of GC:
225
protected boolean clearSharedData() {
226             return false;
227         }
228     }
229     
230     public static class ClearSharedDataSCO extends SharedClassObject {
231         protected boolean clearSharedData() {
232             return true;
233         }
234     }
235     
236     public static class DontClearSharedDataSCO extends SharedClassObject {
237         protected boolean clearSharedData() {
238             return false;
239         }
240     }
241     
242     // SCO.DataEntry.tryToInitialize in absence of EM will try to print
243
// stack trace of unexpected exceptions, so just suppress it
244
private static final class QuietException extends NullPointerException JavaDoc {
245         public void printStackTrace() {
246             // do nothing
247
}
248     }
249     
250     public static class InitErrorSCO extends SharedClassObject {
251         protected void initialize() {
252             throw new QuietException();
253         }
254     }
255     
256     public static class PropFirerSCO extends SharedClassObject {
257         public int addCount = 0;
258         protected void addNotify() {
259             super.addNotify();
260             addCount++;
261         }
262         protected void removeNotify() {
263             addCount--;
264             super.removeNotify();
265         }
266         public void putprop(Object JavaDoc val, boolean notify) {
267             putProperty("key", val, notify);
268         }
269         public Object JavaDoc getprop() {
270             return getProperty("key");
271         }
272     }
273     
274     public static class RecursiveInitSCO extends SharedClassObject {
275         public static final RecursiveInitSCO INSTANCE = (RecursiveInitSCO)SharedClassObject.findObject(RecursiveInitSCO.class, true);
276         public static int count = 0;
277         protected void initialize() {
278             super.initialize();
279             count++;
280         }
281     }
282
283     public static final class SharedClassObjectWithReadResolve extends SharedClassObject {
284         public Object JavaDoc readResolve () throws java.io.ObjectStreamException JavaDoc {
285             return "Ahoj";
286         }
287     }
288 }
289
Popular Tags