# HG changeset patch # User Jaroslav Tulach # Date 1379262288 -7200 # Node ID 1d0e583ac981396bf43f0f6e695c49b9a6659b96 # Parent 8d29792a09c6452846176b48e4dbc7ac2aa3dbc1 Use the new netbeans.inspect property to connect to the IDE diff -r 8d29792a09c6 -r 1d0e583ac981 launcher/fx/src/main/java/org/apidesign/bck2brwsr/launcher/fximpl/BrowserToolbar.java --- a/launcher/fx/src/main/java/org/apidesign/bck2brwsr/launcher/fximpl/BrowserToolbar.java Thu Sep 12 14:15:47 2013 +0200 +++ b/launcher/fx/src/main/java/org/apidesign/bck2brwsr/launcher/fximpl/BrowserToolbar.java Sun Sep 15 18:24:48 2013 +0200 @@ -45,7 +45,7 @@ private final ToggleGroup resizeGroup = new ToggleGroup(); private final ComboBox comboZoom = new ComboBox(); - BrowserToolbar(WebView webView, Pane container, boolean useFirebug, final WebDebug webDebug) { + BrowserToolbar(WebView webView, Pane container, boolean useFirebug) { this.webView = webView; this.container = container; @@ -104,19 +104,6 @@ }); getItems().add(firebug); } - - if (webDebug != null) { - final ToggleButton btnSelMode = new ToggleButton(null, new ImageView( - new Image(BrowserToolbar.class.getResourceAsStream("selectionMode.png")))); - btnSelMode.setTooltip(new Tooltip("Toggle selection mode")); - btnSelMode.selectedProperty().addListener(new InvalidationListener() { - @Override - public void invalidated(Observable o) { - toggleSelectionMode(webDebug, btnSelMode.isSelected()); - } - }); - getItems().add(btnSelMode); - } } private String zoom( String zoomFactor ) { @@ -181,11 +168,6 @@ webView.autosize(); } - private void toggleSelectionMode(WebDebug dbg, boolean selMode) { - // "inspect" - dbg.call("{\"message\":\"selection_mode\",\"selectionMode\":" + selMode + "}"); - } - final void toggleFireBug(boolean enable) { WebEngine eng = webView.getEngine(); Object installed = eng.executeScript("window.Firebug"); diff -r 8d29792a09c6 -r 1d0e583ac981 launcher/fx/src/main/java/org/apidesign/bck2brwsr/launcher/fximpl/FXBrwsr.java --- a/launcher/fx/src/main/java/org/apidesign/bck2brwsr/launcher/fximpl/FXBrwsr.java Thu Sep 12 14:15:47 2013 +0200 +++ b/launcher/fx/src/main/java/org/apidesign/bck2brwsr/launcher/fximpl/FXBrwsr.java Sun Sep 15 18:24:48 2013 +0200 @@ -55,8 +55,9 @@ @Override public void start(Stage primaryStage) throws Exception { WebView view = new WebView(); - final String nbUserDir = this.getParameters().getNamed().get("userdir"); // NOI18N - WebController wc = new WebController(view, nbUserDir, getParameters().getUnnamed()); + WebController wc = new WebController(view, getParameters().getUnnamed()); + + FXInspect.initialize(view.getEngine()); final VBox vbox = new VBox(); vbox.setAlignment( Pos.CENTER ); @@ -73,7 +74,7 @@ final boolean showToolbar = "true".equals(this.getParameters().getNamed().get("toolbar")); // NOI18N final boolean useFirebug = "true".equals(this.getParameters().getNamed().get("firebug")); // NOI18N if (showToolbar) { - final ToolBar toolbar = new BrowserToolbar(view, vbox, useFirebug, wc.dbg); + final ToolBar toolbar = new BrowserToolbar(view, vbox, useFirebug); root.setTop( toolbar ); } root.setCenter(hbox); @@ -90,12 +91,9 @@ */ private static class WebController { private final JVMBridge bridge; - private final WebDebug dbg; - private final String ud; - public WebController(WebView view, String ud, List params) { + public WebController(WebView view, List params) { this.bridge = new JVMBridge(view.getEngine()); - this.ud = ud; LOG.log(Level.INFO, "Initializing WebView with {0}", params); final WebEngine eng = view.getEngine(); try { @@ -138,15 +136,6 @@ dialogStage.showAndWait(); } }); - WebDebug wd = null; - try { - if (ud != null) { - wd = WebDebug.create(eng.impl_getDebugger(), ud); - } - } catch (Exception ex) { - LOG.log(Level.WARNING, null, ex); - } - this.dbg = wd; } boolean initBck2Brwsr(WebEngine webEngine) { diff -r 8d29792a09c6 -r 1d0e583ac981 launcher/fx/src/main/java/org/apidesign/bck2brwsr/launcher/fximpl/FXInspect.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/launcher/fx/src/main/java/org/apidesign/bck2brwsr/launcher/fximpl/FXInspect.java Sun Sep 15 18:24:48 2013 +0200 @@ -0,0 +1,112 @@ +/** + * Back 2 Browser Bytecode Translator + * Copyright (C) 2012 Jaroslav Tulach + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. Look for COPYING file in the top folder. + * If not, see http://opensource.org/licenses/GPL-2.0. + */ +package org.apidesign.bck2brwsr.launcher.fximpl; + +import com.sun.javafx.scene.web.Debugger; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.net.InetAddress; +import java.net.Socket; +import java.nio.charset.StandardCharsets; +import java.util.logging.Level; +import java.util.logging.Logger; +import javafx.application.Platform; +import javafx.scene.web.WebEngine; +import javafx.util.Callback; +import org.openide.util.Exceptions; + +/** + * + * @author Jaroslav Tulach + */ +final class FXInspect implements Runnable { + private static final Logger LOG = Logger.getLogger(FXInspect.class.getName()); + + + private final WebEngine engine; + private final ObjectInputStream input; + + private FXInspect(WebEngine engine, int port) throws IOException { + this.engine = engine; + + Socket socket = new Socket(InetAddress.getByName(null), port); + ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream()); + this.input = new ObjectInputStream(socket.getInputStream()); + initializeDebugger(output); + } + + static boolean initialize(WebEngine engine) { + final int inspectPort = Integer.getInteger("netbeans.inspect.port", -1); // NOI18N + if (inspectPort != -1) { + try { + FXInspect inspector = new FXInspect(engine, inspectPort); + Thread t = new Thread(inspector, "FX<->NetBeans Inspector"); + t.start(); + return true; + } catch (IOException ex) { + LOG.log(Level.INFO, "Cannot connect to NetBeans IDE to port " + inspectPort, ex); // NOI18N + } + } + return false; + } + + private void initializeDebugger(final ObjectOutputStream output) { + Platform.runLater(new Runnable() { + @Override + public void run() { + Debugger debugger = engine.impl_getDebugger(); + debugger.setEnabled(true); + debugger.setMessageCallback(new Callback() { + @Override + public Void call(String message) { + try { + byte[] bytes = message.getBytes(StandardCharsets.UTF_8); + output.writeInt(bytes.length); + output.write(bytes); + output.flush(); + } catch (IOException ioex) { + ioex.printStackTrace(); + } + return null; + } + }); + } + }); + } + + @Override + public void run() { + try { + while (true) { + int length = input.readInt(); + byte[] bytes = new byte[length]; + input.readFully(bytes); + final String message = new String(bytes, StandardCharsets.UTF_8); + Platform.runLater(new Runnable() { + @Override + public void run() { + engine.impl_getDebugger().sendMessage(message); + } + }); + } + } catch (IOException ioex) { + ioex.printStackTrace(); + } + } +} diff -r 8d29792a09c6 -r 1d0e583ac981 launcher/fx/src/main/java/org/apidesign/bck2brwsr/launcher/fximpl/WebDebug.java --- a/launcher/fx/src/main/java/org/apidesign/bck2brwsr/launcher/fximpl/WebDebug.java Thu Sep 12 14:15:47 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,189 +0,0 @@ -/** - * Back 2 Browser Bytecode Translator - * Copyright (C) 2012 Jaroslav Tulach - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. Look for COPYING file in the top folder. - * If not, see http://opensource.org/licenses/GPL-2.0. - */ -package org.apidesign.bck2brwsr.launcher.fximpl; - -import com.sun.javafx.scene.web.Debugger; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.InterruptedIOException; -import java.io.OutputStream; -import java.io.UnsupportedEncodingException; -import java.lang.reflect.Method; -import java.util.concurrent.ArrayBlockingQueue; -import java.util.concurrent.Executors; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicReference; -import java.util.logging.Level; -import java.util.logging.Logger; -import javafx.application.Platform; -import javafx.util.Callback; - -/** Simulates WebKit protocol over WebSockets. - * - * @author Jaroslav Tulach - */ -abstract class WebDebug extends OutputStream -implements Callback, Runnable { - private static final Logger LOG = Logger.getLogger(WebDebug.class.getName()); - - private final Debugger debug; - private final StringBuilder cmd = new StringBuilder(); - private final ToDbgInputStream toDbg; - private final String ud; - - WebDebug(Debugger debug, String ud) throws Exception { - this.debug = debug; - this.ud = ud; - toDbg = new ToDbgInputStream(); - debug.setEnabled(true); - debug.setMessageCallback(this); - } - - static WebDebug create(Debugger debug, String ud) throws Exception { - WebDebug web = new WebDebug(debug, ud) {}; - - Executors.newFixedThreadPool(1).execute(web); - - return web; - } - - @Override - public void run() { - try { - String p = System.getProperty("startpage.file"); - File f; - if (p != null && (f = new File(p)).exists()) { - String[] args = {"--livehtml", f.getAbsolutePath()}; - File dir = f.getParentFile(); - cliHandler(args, toDbg, this, System.err, dir); - } - } catch (Exception ex) { - LOG.log(Level.SEVERE, null, ex); - } - } - - @Override - public void close() { - try { - toDbg.close(); - } catch (IOException ex) { - LOG.log(Level.SEVERE, null, ex); - } - } - - @Override - public Void call(String p) { - assert p.indexOf('\n') == -1 : "No new line: " + p; - LOG.log(Level.INFO, "toDbgr: {0}", p); - toDbg.pushMsg(p); - return null; - } - - @Override - public void write(int b) throws IOException { - if (b == '\n') { - final String msg = cmd.toString(); - Platform.runLater(new Runnable() { - @Override - public void run() { - LOG.log(Level.INFO, "toView: {0}", msg); - debug.sendMessage(msg); - } - }); - cmd.setLength(0); - } else { - if (cmd.length() > 100000) { - LOG.log(Level.WARNING, "Too big:\n{0}", cmd); - } - cmd.append((char)b); - } - } - - private void cliHandler( - String[] args, InputStream is, OutputStream os, OutputStream err, File dir - ) { - try { - Class main = Class.forName("org.netbeans.MainImpl"); - Method m = main.getDeclaredMethod("execute", String[].class, InputStream.class, - OutputStream.class, OutputStream.class, AtomicReference.class - ); - m.setAccessible(true); - System.setProperty("netbeans.user", ud); - int ret = (Integer)m.invoke(null, args, is, os, err, null); - LOG.log(Level.INFO, "Return value: {0}", ret); - } catch (Exception ex) { - LOG.log(Level.SEVERE, null, ex); - } finally { - LOG.info("Communication is over"); - } - - } - - private class ToDbgInputStream extends InputStream { - private byte[] current; - private int currentPos; - private final ArrayBlockingQueue pending = new ArrayBlockingQueue(64); - - public ToDbgInputStream() { - } - - @Override - public int read() throws IOException { - return read(null, 0, 1); - } - - @Override - public int read(byte[] arr, int offset, int len) throws IOException { - if (current == null || current.length <= currentPos) { - for (;;) { - WebDebug.this.flush(); - try { - current = pending.poll(5, TimeUnit.MILLISECONDS); - if (current == null) { - return 0; - } - break; - } catch (InterruptedException ex) { - throw (InterruptedIOException)new InterruptedIOException().initCause(ex); - } - } - LOG.info("Will return: " + new String(current)); - currentPos = 0; - } - int cnt = 0; - while (len-- > 0 && currentPos < current.length) { - final byte nextByte = current[currentPos++]; - if (arr == null) { - return nextByte; - } - arr[offset + cnt++] = nextByte; - } - LOG.log(Level.INFO, "read returns: {0}", new String(arr, offset, cnt)); - return cnt; - } - - private void pushMsg(String p) { - try { - pending.offer((p + '\n').getBytes("UTF-8")); - } catch (UnsupportedEncodingException ex) { - throw new IllegalStateException(ex); - } - } - } -}