jaroslav@1041: /** jaroslav@1041: * Back 2 Browser Bytecode Translator jaroslav@1041: * Copyright (C) 2012 Jaroslav Tulach jaroslav@1041: * jaroslav@1041: * This program is free software: you can redistribute it and/or modify jaroslav@1041: * it under the terms of the GNU General Public License as published by jaroslav@1041: * the Free Software Foundation, version 2 of the License. jaroslav@1041: * jaroslav@1041: * This program is distributed in the hope that it will be useful, jaroslav@1041: * but WITHOUT ANY WARRANTY; without even the implied warranty of jaroslav@1041: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the jaroslav@1041: * GNU General Public License for more details. jaroslav@1041: * jaroslav@1041: * You should have received a copy of the GNU General Public License jaroslav@1041: * along with this program. Look for COPYING file in the top folder. jaroslav@1041: * If not, see http://opensource.org/licenses/GPL-2.0. jaroslav@1041: */ jaroslav@1041: package org.apidesign.bck2brwsr.launcher; jaroslav@1041: jaroslav@1273: import java.io.File; jaroslav@1041: import org.apidesign.bck2brwsr.launcher.fximpl.FXBrwsr; jaroslav@1041: import java.io.IOException; jaroslav@1053: import java.io.InputStream; jaroslav@1041: import java.lang.reflect.Method; jaroslav@1273: import java.net.JarURLConnection; jaroslav@1041: import java.net.URI; jaroslav@1273: import java.net.URISyntaxException; jaroslav@1041: import java.net.URL; jaroslav@1041: import java.net.URLClassLoader; jaroslav@1167: import java.util.ArrayList; jaroslav@1053: import java.util.Enumeration; jaroslav@1095: import java.util.List; jaroslav@1041: jaroslav@1041: import java.util.concurrent.Executors; jaroslav@1053: import java.util.jar.Manifest; jaroslav@1041: import java.util.logging.Level; jaroslav@1041: import java.util.logging.Logger; jaroslav@1041: import javafx.application.Platform; jaroslav@1041: import org.apidesign.bck2brwsr.launcher.fximpl.JVMBridge; jaroslav@1273: import org.openide.util.Exceptions; jaroslav@1041: jaroslav@1041: /** jaroslav@1041: * jaroslav@1041: * @author Jaroslav Tulach jaroslav@1041: */ jaroslav@1041: final class FXBrwsrLauncher extends BaseHTTPLauncher { jaroslav@1041: private static final Logger LOG = Logger.getLogger(FXBrwsrLauncher.class.getName()); jaroslav@1041: static { jaroslav@1041: try { jaroslav@1041: Method m = URLClassLoader.class.getDeclaredMethod("addURL", URL.class); jaroslav@1041: m.setAccessible(true); jaroslav@1041: URL l = new URL("file://" + System.getProperty("java.home") + "/lib/jfxrt.jar"); jaroslav@1041: LOG.log(Level.INFO, "url : {0}", l); jaroslav@1041: m.invoke(ClassLoader.getSystemClassLoader(), l); jaroslav@1041: } catch (Exception ex) { jaroslav@1041: throw new LinkageError("Can't add jfxrt.jar on the classpath", ex); jaroslav@1041: } jaroslav@1041: } jaroslav@1053: jaroslav@1041: public FXBrwsrLauncher(String ignore) { jaroslav@1041: super(null); jaroslav@1041: } jaroslav@1041: jaroslav@1041: @Override jaroslav@1041: protected Object[] showBrwsr(final URI url) throws IOException { jaroslav@1041: try { jaroslav@1041: LOG.log(Level.INFO, "showBrwsr for {0}", url); jaroslav@1041: JVMBridge.registerClassLoaders(loaders()); jaroslav@1041: LOG.info("About to launch WebView"); jaroslav@1041: Executors.newSingleThreadExecutor().submit(new Runnable() { jaroslav@1041: @Override jaroslav@1041: public void run() { jaroslav@1041: LOG.log(Level.INFO, "In FX thread. Launching!"); jaroslav@1041: try { jaroslav@1167: List params = new ArrayList(); jaroslav@1167: params.add(url.toString()); jaroslav@1166: if (isDebugged()) { jaroslav@1167: params.add("--toolbar=true"); jaroslav@1167: params.add("--firebug=true"); jaroslav@1169: String ud = System.getProperty("netbeans.user"); jaroslav@1169: if (ud != null) { jaroslav@1169: params.add("--userdir=" + ud); jaroslav@1169: } jaroslav@1166: } jaroslav@1167: FXBrwsr.launch(FXBrwsr.class, params.toArray(new String[params.size()])); jaroslav@1041: LOG.log(Level.INFO, "Launcher is back. Closing"); jaroslav@1041: close(); jaroslav@1096: System.exit(0); jaroslav@1041: } catch (Throwable ex) { jaroslav@1041: LOG.log(Level.WARNING, "Error launching Web View", ex); jaroslav@1041: } jaroslav@1041: } jaroslav@1041: }); jaroslav@1041: } catch (Throwable ex) { jaroslav@1041: LOG.log(Level.WARNING, "Can't open WebView", ex); jaroslav@1041: } jaroslav@1041: return null; jaroslav@1041: } jaroslav@1041: jaroslav@1041: @Override jaroslav@1088: void generateBck2BrwsrJS(StringBuilder sb, Res loader) throws IOException { jaroslav@1041: sb.append("(function() {\n" jaroslav@1041: + " var impl = this.bck2brwsr;\n" jaroslav@1095: + " this.bck2brwsr = function() { return impl; };\n"); jaroslav@1095: sb.append("})(window);\n"); jaroslav@1041: JVMBridge.onBck2BrwsrLoad(); jaroslav@1041: } jaroslav@1095: jaroslav@1041: @Override jaroslav@1041: public void close() throws IOException { jaroslav@1041: super.close(); jaroslav@1041: Platform.exit(); jaroslav@1041: } jaroslav@1053: jaroslav@1088: String harnessResource() { jaroslav@1088: return "org/apidesign/bck2brwsr/launcher/fximpl/harness.xhtml"; jaroslav@1088: } jaroslav@1088: jaroslav@1053: public static void main(String... args) throws IOException { jaroslav@1053: String startPage = null; jaroslav@1053: jaroslav@1053: final ClassLoader cl = FXBrwsrLauncher.class.getClassLoader(); jaroslav@1273: URL[] manifestURL = { null }; jaroslav@1273: startPage = findStartPage(cl, startPage, manifestURL); jaroslav@1053: if (startPage == null) { jaroslav@1053: throw new NullPointerException("Can't find StartPage tag in manifests!"); jaroslav@1053: } jaroslav@1053: jaroslav@1273: File dir = new File("."); jaroslav@1273: if (manifestURL[0].getProtocol().equals("jar")) { jaroslav@1273: try { jaroslav@1273: dir = new File( jaroslav@1273: ((JarURLConnection)manifestURL[0].openConnection()).getJarFileURL().toURI() jaroslav@1273: ).getParentFile(); jaroslav@1273: } catch (URISyntaxException ex) { jaroslav@1273: LOG.log(Level.WARNING, "Can't find root directory", ex); jaroslav@1273: } jaroslav@1273: } jaroslav@1273: jaroslav@1273: Launcher.showDir("fxbrwsr", dir, cl, startPage); jaroslav@1053: } jaroslav@1041: jaroslav@1273: private static String findStartPage( jaroslav@1273: final ClassLoader cl, String startPage, URL[] startURL jaroslav@1273: ) throws IOException { jaroslav@1053: Enumeration en = cl.getResources("META-INF/MANIFEST.MF"); jaroslav@1053: while (en.hasMoreElements()) { jaroslav@1053: URL url = en.nextElement(); jaroslav@1053: Manifest mf; jaroslav@1165: InputStream is = null; jaroslav@1165: try { jaroslav@1165: is = url.openStream(); jaroslav@1053: mf = new Manifest(is); jaroslav@1165: } finally { jaroslav@1165: if (is != null) is.close(); jaroslav@1053: } jaroslav@1053: String sp = mf.getMainAttributes().getValue("StartPage"); jaroslav@1053: if (sp != null) { jaroslav@1053: startPage = sp; jaroslav@1273: if (startURL != null) { jaroslav@1273: startURL[0] = url; jaroslav@1273: } jaroslav@1053: break; jaroslav@1053: } jaroslav@1053: } jaroslav@1053: return startPage; jaroslav@1053: } jaroslav@1095: jaroslav@1095: private static boolean isDebugged() { jaroslav@1095: try { jaroslav@1095: return isDebuggedImpl(); jaroslav@1095: } catch (LinkageError e) { jaroslav@1095: return false; jaroslav@1095: } jaroslav@1095: } jaroslav@1095: jaroslav@1095: private static boolean isDebuggedImpl() { jaroslav@1095: java.lang.management.RuntimeMXBean runtime; jaroslav@1095: runtime = java.lang.management.ManagementFactory.getRuntimeMXBean(); jaroslav@1095: List args = runtime.getInputArguments(); jaroslav@1095: if (args.contains("-Xdebug")) { // NOI18N jaroslav@1095: return true; jaroslav@1095: } jaroslav@1095: return false; jaroslav@1095: } jaroslav@1041: }