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 case SWT: 59 instantiateOnSWTQueue(cl, args); 60 break; 61 case REMOTE: 62 launchOnRemoteStage(cl, args); 63 break; 64 default: 65 throw new IllegalStateException("Unknown launch mode: " + mode); 66 67 } 68 } 69 70 public enum Mode { 71 72 DEFAULT, SWING, SWT, REMOTE 73 }; 74 private Mode mode = Mode.DEFAULT; 75 private long testDelay = Long.getLong("test.javafx.testdelay", 1000); 76 private long testDelayRemote = Long.getLong("test.javafx.testdelayremote", 4000); 77 78 public long getTestDelay() { 79 return mode == Mode.REMOTE ? testDelayRemote : testDelay; 80 } 81 82 public Mode getMode() { 83 return mode; 84 } 85 86 private AppLauncher() { 87 if (Boolean.getBoolean("javafx.swinginteroperability")) { 88 mode = Mode.SWING; 89 } 90 if (Boolean.getBoolean("javafx.swtinteroperability")) { 91 mode = Mode.SWT; 92 } 93 } 94 private final static AppLauncher INSTANCE = new AppLauncher(); 95 96 public static AppLauncher getInstance() { 97 return INSTANCE; 98 } 99 100 private static void instantiateOnSwingQueue(final Class<? extends Interoperability> cl, String[] args) { 101 try { 102 SwingAWTUtils.instantiateOnSwingQueue(cl); 103 } catch (Exception ex) { 104 ex.printStackTrace(); 105 } 106 } 107 108 private static void instantiateOnSWTQueue(final Class<? extends Interoperability> cl, String[] args) { 109 try { 110 Interoperability obj = cl.newInstance(); 111 obj.startSWT(); 112 } catch (Exception ex) { 113 ex.printStackTrace(); 114 } 115 } 116 117 private void launchOnRemoteStage(final Class<? extends Application> cl, final String[] args) { 118 Platform.runLater(new Runnable() { 119 120 public void run() { 121 try { 122 Application obj = (Application) cl.newInstance(); 123 ParametersImpl.registerParameters(obj, new ParametersImpl(args)); 124 obj.start(remoteStage); 125 } catch (Exception ex) { 126 ex.printStackTrace(); 127 } 128 } 129 }); 130 } 131 132 private static void defaultLaunch(final Class<? extends Application> cl, final String[] args) { 133 final boolean waitToolkit = args != null ? java.util.Arrays.asList(args).contains(WAIT_TOOLKIT_START_ONLY) : false; 134 135 new Thread(new Runnable() { 136 137 public void run() { 138 Application.launch(cl, args); 139 } 140 }, "FXSQE app launch thread").start(); 141 142 new Waiter(new Timeout("FXSQE launch start waiter", TestUtil.isEmbedded() ? 600000 : 10000)).ensureState(new State<Boolean>() { 143 144 public Boolean reached() { 145 // try { 146 // Thread.sleep(100); // otherwise mac doesn't start 147 // } catch (InterruptedException ex) { 148 // } 149 if (waitToolkit) { 150 try { 151 final Toolkit toolkit = com.sun.javafx.tk.Toolkit.getToolkit(); 152 } catch (Throwable ex) { 153 return null; 154 } 155 return Boolean.TRUE; 156 } else { 157 Iterator<Window> it = Stage.impl_getWindows(); 158 while (it.hasNext()) { 159 160 if (it.next().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 }