|
What this is
Other links
The source code
/*
* Sun Public License Notice
*
* The contents of this file are subject to the Sun Public License
* Version 1.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://www.sun.com/
*
* The Original Code is NetBeans. The Initial Developer of the Original
* Code is Sun Microsystems, Inc. Portions Copyright 1997-2003 Sun
* Microsystems, Inc. All Rights Reserved.
*/
package org.openide.util;
import junit.framework.*;
import junit.textui.TestRunner;
import java.net.*;
import java.io.*;
import java.lang.reflect.*;
import java.beans.*;
import org.netbeans.junit.*;
/** Test SharedClassObject singletons: esp. initialization semantics.
* @author Jesse Glick
*/
public class SharedClassObjectTest extends NbTestCase {
public SharedClassObjectTest(String name) {
super(name);
}
public static void main(String[] args) {
TestRunner.run(new NbTestSuite(SharedClassObjectTest.class));
}
/*
protected void setUp() throws Exception {
}
protected void tearDown() throws Exception {
}
*/
public void testSimpleSCO() throws Exception {
Class c = makeClazz("SimpleSCO");
assertTrue(c != SimpleSCO.class);
assertNull("No instance created yet", SharedClassObject.findObject(c, false));
SharedClassObject o = SharedClassObject.findObject(c, true);
assertNotNull(o);
assertEquals("org.openide.util.SharedClassObjectTest$SimpleSCO", o.getClass().getName());
assertEquals(c, o.getClass());
assertEquals("has not been initialized", 0, o.getClass().getField("initcount").getInt(o));
assertNull(o.getProperty("foo"));
assertEquals("has been initialized", 1, o.getClass().getField("initcount").getInt(o));
assertNull(o.getProperty("bar"));
assertEquals("has been initialized just once", 1, o.getClass().getField("initcount").getInt(null));
Class c2 = makeClazz("SimpleSCO");
assertTrue("Call to makeClazz created a fresh class", c != c2);
SharedClassObject o2 = SharedClassObject.findObject(c2, true);
o2.getProperty("baz");
assertEquals(1, o2.getClass().getField("initcount").getInt(null));
}
public void testClearSharedData() throws Exception {
Class c = makeClazz("DontClearSharedDataSCO");
SharedClassObject o = SharedClassObject.findObject(c, true);
o.putProperty("inited", Boolean.TRUE);
assertEquals("DCSD has been initialized", Boolean.TRUE, o.getProperty("inited"));
o = null;
System.gc();
System.runFinalization();
// XXX should use assertGC here, it is more reliable and helpful...
assertNull("findObject(Class,false) gives nothing after running GC + finalization #1", SharedClassObject.findObject(c));
o = SharedClassObject.findObject(c, true);
assertEquals("has still been initialized", Boolean.TRUE, o.getProperty("inited"));
c = makeClazz("ClearSharedDataSCO");
o = SharedClassObject.findObject(c, true);
o.putProperty("inited", Boolean.TRUE);
assertEquals("CSD has been initialized", Boolean.TRUE, o.getProperty("inited"));
o = null;
System.gc();
System.runFinalization();
assertNull("findObject(Class,false) gives nothing after running GC + finalization #2", SharedClassObject.findObject(c));
o = SharedClassObject.findObject(c, true);
assertEquals("is no longer initialized", null, o.getProperty("inited"));
o.putProperty("inited", Boolean.TRUE);
assertEquals("has now been initialized again", Boolean.TRUE, o.getProperty("inited"));
}
public void testIllegalState() throws Exception {
Class c = makeClazz("InitErrorSCO");
SharedClassObject o = SharedClassObject.findObject(c, true);
assertNotNull(o);
try {
o.getProperty("foo");
fail("should not be able to do anything with it");
} catch (IllegalStateException ise) {
// Good.
}
try {
o.getProperty("bar");
fail("should still not be able to do anything with it");
} catch (IllegalStateException ise) {
// Good.
}
}
public void testPropertyChanges() throws Exception {
Class c = makeClazz("PropFirerSCO");
Method putprop = c.getMethod("putprop", new Class[] {Object.class, Boolean.TYPE});
Method getprop = c.getMethod("getprop", new Class[] {});
Field count = c.getField("addCount");
SharedClassObject o = SharedClassObject.findObject(c, true);
assertNull(getprop.invoke(o, null));
assertEquals(0, count.getInt(o));
class Listener implements PropertyChangeListener {
public int count = 0;
public void propertyChange(PropertyChangeEvent ev) {
if ("key".equals(ev.getPropertyName())) {
count++;
}
}
}
Listener l = new Listener();
o.addPropertyChangeListener(l);
assertEquals(1, count.getInt(o));
Listener l2 = new Listener();
o.addPropertyChangeListener(l2);
assertEquals(1, count.getInt(o));
o.removePropertyChangeListener(l2);
assertEquals(1, count.getInt(o));
putprop.invoke(o, new Object[] {"something", Boolean.FALSE});
assertEquals(0, l.count);
assertEquals("something", getprop.invoke(o, null));
putprop.invoke(o, new Object[] {"somethingelse", Boolean.TRUE});
assertEquals(1, l.count);
assertEquals("somethingelse", getprop.invoke(o, null));
// Check that setting the same val does not fire an additional change (cf. #37769):
putprop.invoke(o, new Object[] {"somethingelse", Boolean.TRUE});
assertEquals(1, l.count);
assertEquals("somethingelse", getprop.invoke(o, null));
// Check equals() as well as ==:
putprop.invoke(o, new Object[] {new String("somethingelse"), Boolean.TRUE});
assertEquals(1, l.count);
assertEquals("somethingelse", getprop.invoke(o, null));
o.removePropertyChangeListener(l);
assertEquals(0, count.getInt(o));
o.addPropertyChangeListener(l);
assertEquals(1, count.getInt(o));
o.removePropertyChangeListener(l);
assertEquals(0, count.getInt(o));
}
public void testRecursiveInit() throws Exception {
Class c = makeClazz("RecursiveInitSCO");
SharedClassObject o = SharedClassObject.findObject(c, true);
assertEquals(0, c.getField("count").getInt(null));
o.getProperty("foo");
assertEquals(1, c.getField("count").getInt(null));
assertEquals(o, c.getField("INSTANCE").get(null));
}
public void testAbilityToReadResolveToAnyObject () throws Exception {
SharedClassObject o = SharedClassObject.findObject (SharedClassObjectWithReadResolve.class, true);
ByteArrayOutputStream os = new ByteArrayOutputStream ();
ObjectOutputStream oos = new ObjectOutputStream (os);
oos.writeObject (o);
oos.close ();
ObjectInputStream ois = new ObjectInputStream (new ByteArrayInputStream (os.toByteArray()));
Object result = ois.readObject ();
ois.close ();
assertEquals ("Result should be the string", String.class, result.getClass());
}
/** Create a fresh Class object from one of this test's inner classes.
* Produces a new classloader so the class is always fresh.
*/
private Class makeClazz(String name) throws Exception {
return Class.forName("org.openide.util.SharedClassObjectTest$" + name, false, new MaskingURLClassLoader());
}
private static final class MaskingURLClassLoader extends URLClassLoader {
public MaskingURLClassLoader() {
super(new URL[] {SharedClassObjectTest.class.getProtectionDomain().getCodeSource().getLocation()},
SharedClassObject.class.getClassLoader());
}
protected Class loadClass(String name, boolean resolve) throws ClassNotFoundException {
if (name.startsWith("org.openide.util.SharedClassObjectTest")) {
// Do not proxy to parent!
Class c = findLoadedClass(name);
if (c != null) return c;
c = findClass(name);
if (resolve) resolveClass(c);
return c;
} else {
return super.loadClass(name, resolve);
}
}
}
public static class SimpleSCO extends SharedClassObject {
public static int initcount = 0;
private static String firstinit = null;
protected void initialize() {
super.initialize();
initcount++;
if (initcount > 1) {
System.err.println("Multiple initializations of SimpleSCO: see http://www.netbeans.org/issues/show_bug.cgi?id=14700");
System.err.print(firstinit);
new Throwable("Init #" + initcount + " here").printStackTrace();
} else {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
new Throwable("Init #1 here").printStackTrace(new PrintStream(baos));
firstinit = baos.toString();
// don't print anything unless there is a problem later
}
}
// Protect against random workings of GC:
protected boolean clearSharedData() {
return false;
}
}
public static class ClearSharedDataSCO extends SharedClassObject {
protected boolean clearSharedData() {
return true;
}
}
public static class DontClearSharedDataSCO extends SharedClassObject {
protected boolean clearSharedData() {
return false;
}
}
// SCO.DataEntry.tryToInitialize in absence of EM will try to print
// stack trace of unexpected exceptions, so just suppress it
private static final class QuietException extends NullPointerException {
public void printStackTrace() {
// do nothing
}
}
public static class InitErrorSCO extends SharedClassObject {
protected void initialize() {
throw new QuietException();
}
}
public static class PropFirerSCO extends SharedClassObject {
public int addCount = 0;
protected void addNotify() {
super.addNotify();
addCount++;
}
protected void removeNotify() {
addCount--;
super.removeNotify();
}
public void putprop(Object val, boolean notify) {
putProperty("key", val, notify);
}
public Object getprop() {
return getProperty("key");
}
}
public static class RecursiveInitSCO extends SharedClassObject {
public static final RecursiveInitSCO INSTANCE = (RecursiveInitSCO)SharedClassObject.findObject(RecursiveInitSCO.class, true);
public static int count = 0;
protected void initialize() {
super.initialize();
count++;
}
}
public static final class SharedClassObjectWithReadResolve extends SharedClassObject {
public Object readResolve () throws java.io.ObjectStreamException {
return "Ahoj";
}
}
}
|
| ... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2024 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.