jaroslav@1033: /** jaroslav@1033: * Back 2 Browser Bytecode Translator jaroslav@1033: * Copyright (C) 2012 Jaroslav Tulach jaroslav@1033: * jaroslav@1033: * This program is free software: you can redistribute it and/or modify jaroslav@1033: * it under the terms of the GNU General Public License as published by jaroslav@1033: * the Free Software Foundation, version 2 of the License. jaroslav@1033: * jaroslav@1033: * This program is distributed in the hope that it will be useful, jaroslav@1033: * but WITHOUT ANY WARRANTY; without even the implied warranty of jaroslav@1033: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the jaroslav@1033: * GNU General Public License for more details. jaroslav@1033: * jaroslav@1033: * You should have received a copy of the GNU General Public License jaroslav@1033: * along with this program. Look for COPYING file in the top folder. jaroslav@1033: * If not, see http://opensource.org/licenses/GPL-2.0. jaroslav@1033: */ jaroslav@1033: package org.apidesign.bck2brwsr.launcher; jaroslav@1033: jaroslav@1033: import java.io.Closeable; jaroslav@1033: import java.io.File; jaroslav@1033: import java.io.IOException; jaroslav@1033: import java.lang.reflect.Constructor; jaroslav@1033: jaroslav@1033: /** An abstraction for executing tests in a Bck2Brwsr virtual machine. jaroslav@1033: * Either in {@link Launcher#createJavaScript JavaScript engine}, jaroslav@1033: * or in {@link Launcher#createBrowser external browser}. jaroslav@1033: *

jaroslav@1033: * There also are methods to {@link #showDir(java.io.File, java.lang.String) display pages} jaroslav@1033: * in an external browser served by internal HTTP server. jaroslav@1033: * jaroslav@1033: * @author Jaroslav Tulach jaroslav@1033: */ jaroslav@1033: public abstract class Launcher { jaroslav@1033: jaroslav@1033: Launcher() { jaroslav@1033: } jaroslav@1033: jaroslav@1033: /** Initializes the launcher. This may mean starting a web browser or jaroslav@1033: * initializing execution engine. jaroslav@1033: * @throws IOException if something goes wrong jaroslav@1033: */ jaroslav@1033: public abstract void initialize() throws IOException; jaroslav@1033: jaroslav@1033: /** Shuts down the launcher. jaroslav@1033: * @throws IOException if something goes wrong jaroslav@1033: */ jaroslav@1033: public abstract void shutdown() throws IOException; jaroslav@1033: jaroslav@1033: jaroslav@1033: /** Builds an invocation context. The context can later be customized jaroslav@1033: * and {@link InvocationContext#invoke() invoked}. jaroslav@1033: * jaroslav@1033: * @param clazz the class to execute method from jaroslav@1033: * @param method the method to execute jaroslav@1033: * @return the context pointing to the selected method jaroslav@1033: */ jaroslav@1033: public InvocationContext createInvocation(Class clazz, String method) { jaroslav@1033: return new InvocationContext(this, clazz, method); jaroslav@1033: } jaroslav@1033: jaroslav@1033: jaroslav@1033: /** Creates launcher that uses internal JavaScript engine (Rhino). jaroslav@1033: * @return the launcher jaroslav@1033: */ jaroslav@1033: public static Launcher createJavaScript() { jaroslav@1033: try { jaroslav@1033: Class c = loadClass("org.apidesign.bck2brwsr.launcher.JSLauncher"); jaroslav@1033: return (Launcher) c.newInstance(); jaroslav@1033: } catch (Exception ex) { jaroslav@1033: throw new IllegalStateException("Please include org.apidesign.bck2brwsr:launcher.html dependency!", ex); jaroslav@1033: } jaroslav@1033: } jaroslav@1033: jaroslav@1033: /** Creates launcher that is using external browser. jaroslav@1033: * jaroslav@1033: * @param cmd null to use java.awt.Desktop to show the launcher jaroslav@1033: * or a string to execute in an external process (with a parameter to the URL) jaroslav@1033: * @return launcher executing in external browser. jaroslav@1033: */ jaroslav@1033: public static Launcher createBrowser(String cmd) { jaroslav@1041: String msg = "Trying to create browser '" + cmd + "'"; jaroslav@1033: try { jaroslav@1041: Class c; jaroslav@1043: if ("fxbrwsr".equals(cmd)) { // NOI18N jaroslav@1041: msg = "Please include org.apidesign.bck2brwsr:launcher.fx dependency!"; jaroslav@1041: c = loadClass("org.apidesign.bck2brwsr.launcher.FXBrwsrLauncher"); // NOI18N jaroslav@1041: } else { jaroslav@1041: msg = "Please include org.apidesign.bck2brwsr:launcher.html dependency!"; jaroslav@1041: c = loadClass("org.apidesign.bck2brwsr.launcher.Bck2BrwsrLauncher"); // NOI18N jaroslav@1043: if ("bck2brwsr".equals(cmd)) { // NOI18N jaroslav@1043: // use default executable jaroslav@1043: cmd = null; jaroslav@1043: } jaroslav@1041: } jaroslav@1033: Constructor cnstr = c.getConstructor(String.class); jaroslav@1033: return (Launcher) cnstr.newInstance(cmd); jaroslav@1033: } catch (Exception ex) { jaroslav@1041: throw new IllegalStateException(msg, ex); jaroslav@1033: } jaroslav@1033: } jaroslav@1033: jaroslav@1033: /** Starts an HTTP server which provides access to classes and resources jaroslav@1033: * available in the classes URL and shows a start page jaroslav@1033: * available as {@link ClassLoader#getResource(java.lang.String)} from the jaroslav@1033: * provide classloader. Opens a browser with URL showing the start page. jaroslav@1033: * jaroslav@1033: * @param classes classloader offering access to classes and resources jaroslav@1033: * @param startpage page to show in the browser jaroslav@1033: * @return interface that allows one to stop the server jaroslav@1033: * @throws IOException if something goes wrong jaroslav@1033: */ jaroslav@1033: public static Closeable showURL(ClassLoader classes, String startpage) throws IOException { jaroslav@1043: return showURL(null, classes, startpage); jaroslav@1043: } jaroslav@1043: /** Starts an HTTP server which provides access to classes and resources jaroslav@1043: * available in the classes URL and shows a start page jaroslav@1043: * available as {@link ClassLoader#getResource(java.lang.String)} from the jaroslav@1043: * provide classloader. Opens a browser with URL showing the start page. jaroslav@1043: * jaroslav@1043: * @param brwsr name of browser to use or null jaroslav@1043: * @param classes classloader offering access to classes and resources jaroslav@1043: * @param startpage page to show in the browser jaroslav@1043: * @return interface that allows one to stop the server jaroslav@1043: * @throws IOException if something goes wrong jaroslav@1043: * @since 0.7 jaroslav@1043: */ jaroslav@1043: public static Closeable showURL(String brwsr, ClassLoader classes, String startpage) throws IOException { jaroslav@1043: Launcher l = createBrowser(brwsr); jaroslav@1033: l.addClassLoader(classes); jaroslav@1033: l.showURL(startpage); jaroslav@1033: return (Closeable) l; jaroslav@1033: } jaroslav@1033: /** Starts an HTTP server which provides access to certain directory. jaroslav@1033: * The startpage should be relative location inside the root jaroslav@1033: * directory. Opens a browser with URL showing the start page. jaroslav@1033: * jaroslav@1271: * @param brwsr type of the browser to use jaroslav@1271: * @param directory the root directory on disk jaroslav@1271: * @param classes additional classloader with access to classes or null jaroslav@1271: * @param startpage relative path from the root to the page jaroslav@1271: * @return instance of server that can be closed jaroslav@1271: * @exception IOException if something goes wrong. jaroslav@1271: * @since 0.8 jaroslav@1271: */ jaroslav@1271: public static Closeable showDir(String brwsr, File directory, ClassLoader classes, String startpage) throws IOException { jaroslav@1271: Launcher l = createBrowser(brwsr); jaroslav@1271: if (classes != null) { jaroslav@1271: l.addClassLoader(classes); jaroslav@1271: } jaroslav@1271: l.showDirectory(directory, startpage); jaroslav@1271: return (Closeable) l; jaroslav@1271: } jaroslav@1271: jaroslav@1271: /** Starts an HTTP server which provides access to certain directory. jaroslav@1271: * The startpage should be relative location inside the root jaroslav@1271: * directory. Opens a browser with URL showing the start page. jaroslav@1271: * jaroslav@1033: * @param directory the root directory on disk jaroslav@1033: * @param startpage relative path from the root to the page jaroslav@1271: * @return instance of server that can be closed jaroslav@1033: * @exception IOException if something goes wrong. jaroslav@1033: */ jaroslav@1033: public static Closeable showDir(File directory, String startpage) throws IOException { jaroslav@1271: return showDir(null, directory, null, startpage); jaroslav@1033: } jaroslav@1033: jaroslav@1033: abstract InvocationContext runMethod(InvocationContext c) throws IOException; jaroslav@1033: jaroslav@1033: jaroslav@1033: private static Class loadClass(String cn) throws ClassNotFoundException { jaroslav@1033: return Launcher.class.getClassLoader().loadClass(cn); jaroslav@1033: } jaroslav@1033: jaroslav@1033: void showDirectory(File directory, String startpage) throws IOException { jaroslav@1033: throw new UnsupportedOperationException(); jaroslav@1033: } jaroslav@1033: jaroslav@1033: void showURL(String startpage) throws IOException { jaroslav@1033: throw new UnsupportedOperationException(); jaroslav@1033: } jaroslav@1033: jaroslav@1033: void addClassLoader(ClassLoader classes) { jaroslav@1033: throw new UnsupportedOperationException(); jaroslav@1033: } jaroslav@1033: }