/*
* Copyright 1990-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version
* 2 only, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License version 2 for more details (a copy is
* included at /legal/license.txt).
*
* You should have received a copy of the GNU General Public License
* version 2 along with this work; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
* Clara, CA 95054 or visit www.sun.com if you need additional
* information or have any questions.
*/
package com.sun.ams.ui;
final class TestBaseScreenStack {
static final long SMALL_TIMEOUT = 100;
static final long REASONABLE_TIMEOUT = 10000;
static private void testThrown(Runnable action, Class exClass)
throws Exception {
try {
action.run();
} catch (Exception e) {
if (exClass.isInstance(e)) {
return;
}
throw e;
}
}
static private void test(boolean value) {
if (!value) {
throw new RuntimeException();
}
}
static private void testAfterDestroy() throws Exception {
final Screen s = new Screen();
final ScreenStack ss = new ScreenStack();
test(!ss.destroyed);
ss.destroy();
test(ss.destroyed);
// all methods should report IllegalStateException
testThrown(
new Runnable () { public void run() { ss.show(s); }},
Class.forName("java.lang.IllegalStateException"));
test(s.stack == null);
testThrown(
new Runnable () {
public void run() { ss.showAndWait(s, false, 0); }},
Class.forName("java.lang.IllegalStateException"));
test(s.stack == null);
testThrown(
new Runnable () { public void run() { ss.removeScreen(s); }},
Class.forName("java.lang.IllegalStateException"));
test(s.stack == null);
testThrown(
new Runnable () { public void run() { ss.destroy(); }},
Class.forName("java.lang.IllegalStateException"));
}
static private void testShow() throws Exception {
final Screen s = new Screen();
final Screen s2 = new Screen();
final ScreenStack ss = new ScreenStack();
final ScreenStack ss2 = new ScreenStack();
testThrown(
new Runnable () { public void run() { ss.show(null); }},
Class.forName("java.lang.NullPointerException"));
ss.show(s);
test(ss.curScreen == s && s.stack == ss);
testThrown(
new Runnable () { public void run() { ss2.show(s); }},
Class.forName("java.lang.IllegalArgumentException"));
ss.show(s);
test(ss.curScreen == s && s.stack == ss);
ss.show(s2);
test(ss.curScreen == s2 && s.stack == ss && s2.stack == ss);
ss.show(s);
test(ss.curScreen == s && s.stack == ss);
}
static private void testShowAndWait() throws Exception {
final Screen s = new Screen();
final Screen s2 = new Screen();
final ScreenStack ss = new ScreenStack();
final ScreenStack ss2 = new ScreenStack();
testThrown(
new Runnable () {
public void run() { ss.showAndWait(null, false, 0); }},
Class.forName("java.lang.NullPointerException"));
ss.show(s);
test(ss.curScreen == s && s.stack == ss);
testThrown(
new Runnable () {
public void run() { ss2.showAndWait(s, false, 0); }},
Class.forName("java.lang.IllegalArgumentException"));
ss.curScreen = null;
new Thread() {
public void run() {
ss.showAndWait(s, true, Long.MAX_VALUE);
test(s.stack == null);
synchronized(s) {
s.notifyAll();
}
}
}.start();
// wait for showAndWait to block
synchronized(ss) {
while(ss.curScreen != s) {
ss.wait(REASONABLE_TIMEOUT);
}
}
// this should not have any effect as "ss" has only a
// single screen that can't be removed
test(!ss.removeScreen(s));
test(ss.curScreen == s && s.stack == ss);
// this should remove "s" from the "ss" stack
ss.show(s2);
test(ss.curScreen == s2 && s2.stack == ss);
synchronized(s) {
while(s.stack != null) {
s.wait(REASONABLE_TIMEOUT);
}
}
new Thread() {
public void run() {
// this should block for some millis and then remove "s"
// from the "ss" on showAndWait exit
test(s.stack == null);
ss.showAndWait(s, true, SMALL_TIMEOUT);
test(s.stack == null);
synchronized(s) {
s.notifyAll();
}
}
}.start();
synchronized(ss) {
while(s.stack != ss) {
ss.wait(REASONABLE_TIMEOUT);
}
}
synchronized(s) {
while(s.stack != null) {
s.wait(REASONABLE_TIMEOUT);
}
}
test(ss.curScreen == s2 && s2.stack == ss);
new Thread() {
public void run() {
// this should block for some millis bit will not remove "s"
// from the "ss" on showAndWait exit
ss.showAndWait(s, false, SMALL_TIMEOUT);
test(ss.curScreen == s && s.stack == ss);
}
}.start();
}
static private void testRemoveScreen() throws Exception {
final Screen s = new Screen();
final Screen s2 = new Screen();
final ScreenStack ss = new ScreenStack();
final ScreenStack ss2 = new ScreenStack();
ss.show(s);
testThrown(
new Runnable () {
public void run() { ss.removeScreen(null); }},
Class.forName("java.lang.NullPointerException"));
testThrown(
new Runnable () {
public void run() { ss.removeScreen(s2); }},
Class.forName("java.lang.IllegalArgumentException"));
testThrown(
new Runnable () {
public void run() { ss2.removeScreen(s); }},
Class.forName("java.lang.IllegalArgumentException"));
test(!ss.removeScreen(s));
test(s.stack == ss);
ss.show(s2);
test(ss.removeScreen(s));
test(s.stack == null && ss.curScreen == s2 && s2.stack == ss);
testThrown(
new Runnable () {
public void run() { ss.removeScreen(s); }},
Class.forName("java.lang.IllegalArgumentException"));
ss.show(s);
ss.show(s2);
test(ss.removeScreen(s2));
test(s2.stack == null && ss.curScreen == s && s.stack == ss);
test(!ss.removeScreen(s));
test(ss.curScreen == s && s.stack == ss);
}
static private void testDestroy() throws Exception {
final Screen s = new Screen();
final Screen s2 = new Screen();
final ScreenStack ss = new ScreenStack();
final ScreenStack ss2 = new ScreenStack();
ss.show(s);
ss.show(s2);
ss.destroy();
ss2.show(s);
ss2.show(s2);
new Thread() {
public void run() {
ss2.showAndWait(s, false, Long.MAX_VALUE);
test(s.stack == null);
test(ss2.destroyed);
}
}.start();
// wait for showAndWait to block
synchronized(ss2) {
while(ss2.curScreen != s) {
ss2.wait(REASONABLE_TIMEOUT);
}
}
ss2.destroy();
}
public static void main(String args[]) throws Exception {
testAfterDestroy();
testShow();
testShowAndWait();
testRemoveScreen();
testDestroy();
}
}
final class Screen {
BaseScreenStack stack;
}
final class ScreenStack extends BaseScreenStack {
boolean destroyed;
Screen curScreen;
protected void showScreen(Screen screen) {
if (screen == null) {
throw new RuntimeException();
}
if (destroyed) {
throw new RuntimeException();
}
curScreen = screen;
notifyAll();
}
protected void destroyImpl() {
if (destroyed) {
throw new RuntimeException();
}
destroyed = true;
}
}