1 /* 2 * Copyright (c) 2009, 2012, 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 */ 24 25 package test.javaclient.shared; 26 27 import com.sun.javafx.application.ParametersImpl; 28 import com.sun.javafx.tk.Toolkit; 29 import java.util.Iterator; 30 import javafx.stage.Stage; 31 import javafx.application.Application; 32 import javafx.application.Platform; 33 import javafx.stage.Window; 34 import org.jemmy.env.Timeout; 35 import org.jemmy.timing.State; 36 import org.jemmy.timing.Waiter; 37 38 /** 39 * Launcher class which is aware of different run modes we need for our tests 40 * 41 * @author Sergey Grinev 42 */ 43 public class AppLauncher { 44 45 /** 46 * For tests, which will not wait for stage appearing, and need only toolkit start. 47 */ 48 public static final String WAIT_TOOLKIT_START_ONLY = "WAIT_TOOLKIT_START_ONLY"; 49 50 public void launch(final Class cl, String[] args) { 51 switch (mode) { 52 case DEFAULT: 53 defaultLaunch(cl, args); 54 break; 55 case SWING: 56 instantiateOnSwingQueue(cl, args); 57 break; 58 // https://bugs.openjdk.java.net/browse/JDK-8131888 59 case SWT: 60 instantiateOnSWTQueue(cl, args); 61 break; 62 case REMOTE: 63 launchOnRemoteStage(cl, args); 64 break; 65 default: 66 throw new IllegalStateException("Unknown launch mode: " + mode); 67 68 } 69 } 70 71 public enum Mode { 72 73 DEFAULT, SWING, SWT, REMOTE 74 }; 75 private Mode mode = Mode.DEFAULT; 76 private long testDelay = Long.getLong("test.javafx.testdelay", 1000); 77 private long testDelayRemote = Long.getLong("test.javafx.testdelayremote", 4000); 78 79 public long getTestDelay() { 80 return mode == Mode.REMOTE ? testDelayRemote : testDelay; 81 } 82 83 public Mode getMode() { 84 return mode; 85 } 86 87 private AppLauncher() { 88 if (Boolean.getBoolean("javafx.swinginteroperability")) { 89 mode = Mode.SWING; 90 } 91 if (Boolean.getBoolean("javafx.swtinteroperability")) { 92 mode = Mode.SWT; 93 } 94 } 95 private final static AppLauncher INSTANCE = new AppLauncher(); 96 97 public static AppLauncher getInstance() { 98 return INSTANCE; 99 } 100 101 private static void instantiateOnSwingQueue(final Class<? extends Interoperability> cl, String[] args) { 102 try { 103 SwingAWTUtils.instantiateOnSwingQueue(cl); 104 } catch (Exception ex) { 105 ex.printStackTrace(); 106 } 107 } 108 109 // https://bugs.openjdk.java.net/browse/JDK-8131888 110 private static void instantiateOnSWTQueue(final Class<? extends Interoperability> cl, String[] args) { 111 try { 112 Interoperability obj = cl.newInstance(); 113 obj.startSWT(); 114 } catch (Exception ex) { 115 ex.printStackTrace(); 116 } 117 } 118 119 private void launchOnRemoteStage(final Class<? extends Application> cl, final String[] args) { 120 Platform.runLater(new Runnable() { 121 122 public void run() { 123 try { 124 Application obj = (Application) cl.newInstance(); 125 ParametersImpl.registerParameters(obj, new ParametersImpl(args)); 126 obj.start(remoteStage); 127 } catch (Exception ex) { 128 ex.printStackTrace(); 129 } 130 } 131 }); 132 } 133 134 private static void defaultLaunch(final Class<? extends Application> cl, final String[] args) { 135 final boolean waitToolkit = args != null ? java.util.Arrays.asList(args).contains(WAIT_TOOLKIT_START_ONLY) : false; 136 137 new Thread(new Runnable() { 138 139 public void run() { 140 Application.launch(cl, args); 141 } 142 }, "FXSQE app launch thread").start(); 143 144 new Waiter(new Timeout("FXSQE launch start waiter", TestUtil.isEmbedded() ? 600000 : 10000)).ensureState(new State<Boolean>() { 145 146 public Boolean reached() { 147 // try { 148 // Thread.sleep(100); // otherwise mac doesn't start 149 // } catch (InterruptedException ex) { 150 // } 151 if (waitToolkit) { 152 try { 153 final Toolkit toolkit = com.sun.javafx.tk.Toolkit.getToolkit(); 154 } catch (Throwable ex) { 155 return null; 156 } 157 return Boolean.TRUE; 158 } else { 159 for (Window w : Stage.getWindows()) { 160 if (w.isShowing()) { 161 return Boolean.TRUE; 162 } 163 } 164 } 165 166 // following wait method was changed due to problem on Mac+JDK7: 167 // we can't use AWT (and consequently Jemmy based on ATW Robot) before FX scene is shown 168 // otherwise FX hangs. 169 // Root.ROOT.lookup(new ByWindowType(Stage.class)).lookup(Scene.class).wrap(0).getControl(); 170 return null; 171 } 172 }); 173 // more JDK7+Mac tricks 174 // System.setProperty("java.awt.headless","false"); 175 // java.awt.GraphicsEnvironment.isHeadless(); 176 } 177 178 /** 179 * Setup stage to be used by launcher. E.g. stage provided by plugin 180 * launcher 181 * 182 * @param remoteStage 183 */ 184 public void setRemoteStage(Stage remoteStage) { 185 if (remoteStage == null) { 186 throw new IllegalArgumentException("Stage can't null"); 187 } 188 if (this.remoteStage != null) { 189 throw new IllegalStateException("Current implementation allows only one remote stage per VM"); 190 } 191 mode = Mode.REMOTE; 192 this.remoteStage = remoteStage; 193 } 194 private Stage remoteStage = null; 195 }