1 /*
   2  * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 package com.sun.glass.ui.monocle;
  26 
  27 import javafx.application.Platform;
  28 
  29 import java.util.concurrent.Semaphore;
  30 
  31 public abstract class TestRunnable implements Runnable {
  32 
  33     private Throwable t;
  34     private final Semaphore done = new Semaphore(1);
  35 
  36     public abstract void test() throws Exception;
  37 
  38     public final void run() {
  39         t = null;
  40         try {
  41             test();
  42         } catch (Throwable x) {
  43             t = x;
  44         }
  45         done.release();
  46     }
  47 
  48     public final void invokeAndWait() throws Exception {
  49         if (Platform.isFxApplicationThread()) {
  50             test();
  51         } else {
  52             done.acquire();
  53             Platform.runLater(this);
  54             done.acquire();
  55             done.release();
  56             rethrow(t);
  57         }
  58     }
  59 
  60     private void rethrow(Throwable t) throws Exception {
  61         if (t != null) {
  62             try {
  63                 throw t;
  64             } catch (RuntimeException re) {
  65                 throw re;
  66             } catch (Error e) {
  67                 throw e;
  68             } catch (Throwable x) {
  69                 throw (RuntimeException) new RuntimeException().initCause(x);
  70             }
  71         }
  72     }
  73 
  74     public final void invokeAndWaitUntilSuccess(long timeout) throws Exception {
  75         long startTime = System.currentTimeMillis();
  76         long endTime = startTime + timeout;
  77         boolean passed = false;
  78         do {
  79             try {
  80                 invokeAndWait();
  81                 passed = true;
  82             } catch (Throwable pendingThrowable) {
  83                 Thread.sleep(100);
  84             }
  85         } while (System.currentTimeMillis() < endTime && !passed);
  86         rethrow(t);
  87     }
  88 
  89     public static void invokeAndWaitUntilSuccess(Testable t, long timeout) throws Exception {
  90         new TestRunnable() {
  91             public void test() throws Exception {
  92                 t.test();
  93             }
  94         }.invokeAndWaitUntilSuccess(timeout);
  95     }
  96 
  97     public static void invokeAndWait(Testable t) throws Exception {
  98         new TestRunnable() {
  99             public void test() throws Exception {
 100                 t.test();
 101             }
 102         }.invokeAndWait();
 103     }
 104 
 105     public static interface Testable {
 106         public void test() throws Exception;
 107     }
 108 
 109 }