First updates to run with forthcoming version 0.5 - WebSockets in FX launcher and etc.
authorJaroslav Tulach <jaroslav.tulach@apidesign.org>
Mon, 26 Aug 2013 08:56:37 +0200
changeset 1249cdaeea7becf2
parent 1248 a3eb8b0dfb81
child 1250 28949f8ce196
First updates to run with forthcoming version 0.5 - WebSockets in FX launcher and etc.
ko/bck2brwsr/src/main/java/org/apidesign/bck2brwsr/ko2brwsr/BrwsrCtxImpl.java
ko/fx/pom.xml
ko/fx/src/test/java/org/apidesign/bck2brwsr/kofx/KnockoutFXTest.java
launcher/fx/pom.xml
launcher/fx/src/main/java/org/apidesign/bck2brwsr/launcher/BaseHTTPLauncher.java
launcher/fx/src/main/java/org/apidesign/bck2brwsr/launcher/fximpl/Console.java
pom.xml
     1.1 --- a/ko/bck2brwsr/src/main/java/org/apidesign/bck2brwsr/ko2brwsr/BrwsrCtxImpl.java	Fri Jul 12 16:06:38 2013 +0200
     1.2 +++ b/ko/bck2brwsr/src/main/java/org/apidesign/bck2brwsr/ko2brwsr/BrwsrCtxImpl.java	Mon Aug 26 08:56:37 2013 +0200
     1.3 @@ -21,8 +21,6 @@
     1.4  import java.io.IOException;
     1.5  import java.io.InputStream;
     1.6  import java.io.InputStreamReader;
     1.7 -import net.java.html.BrwsrCtx;
     1.8 -import org.apidesign.html.context.spi.Contexts;
     1.9  import org.apidesign.html.json.spi.FunctionBinding;
    1.10  import org.apidesign.html.json.spi.JSONCall;
    1.11  import org.apidesign.html.json.spi.PropertyBinding;
    1.12 @@ -123,4 +121,9 @@
    1.13          }
    1.14          return ConvertTypes.parse(sb.toString());
    1.15      }
    1.16 +
    1.17 +    @Override
    1.18 +    public void runSafe(Runnable r) {
    1.19 +        r.run();
    1.20 +    }
    1.21  }
     2.1 --- a/ko/fx/pom.xml	Fri Jul 12 16:06:38 2013 +0200
     2.2 +++ b/ko/fx/pom.xml	Mon Aug 26 08:56:37 2013 +0200
     2.3 @@ -86,5 +86,35 @@
     2.4        <scope>test</scope>
     2.5        <type>jar</type>
     2.6      </dependency>
     2.7 +    <dependency>
     2.8 +      <groupId>org.apidesign.html</groupId>
     2.9 +      <artifactId>ko-ws-tyrus</artifactId>
    2.10 +      <version>${net.java.html.version}</version>
    2.11 +      <scope>test</scope>
    2.12 +    </dependency>
    2.13    </dependencies>
    2.14 +  <profiles>
    2.15 +      <profile>
    2.16 +          <id>jdk8</id>
    2.17 +          <activation>
    2.18 +              <file>
    2.19 +                  <exists>${java.home}/lib/ext/jfxrt.jar</exists>
    2.20 +              </file>
    2.21 +          </activation>
    2.22 +          <properties>
    2.23 +            <jfxrt.jar>${java.home}/lib/ext/jfxrt.jar</jfxrt.jar>
    2.24 +          </properties>
    2.25 +      </profile>
    2.26 +      <profile>
    2.27 +          <id>jdk7</id>
    2.28 +          <activation>
    2.29 +              <file>
    2.30 +                  <exists>${java.home}/lib/jfxrt.jar</exists>
    2.31 +              </file>
    2.32 +          </activation>
    2.33 +          <properties>
    2.34 +            <jfxrt.jar>${java.home}/lib/jfxrt.jar</jfxrt.jar>
    2.35 +          </properties>
    2.36 +      </profile>
    2.37 +  </profiles>
    2.38  </project>
     3.1 --- a/ko/fx/src/test/java/org/apidesign/bck2brwsr/kofx/KnockoutFXTest.java	Fri Jul 12 16:06:38 2013 +0200
     3.2 +++ b/ko/fx/src/test/java/org/apidesign/bck2brwsr/kofx/KnockoutFXTest.java	Mon Aug 26 08:56:37 2013 +0200
     3.3 @@ -31,9 +31,11 @@
     3.4  import org.apidesign.html.context.spi.Contexts;
     3.5  import org.apidesign.html.json.spi.Technology;
     3.6  import org.apidesign.html.json.spi.Transfer;
     3.7 +import org.apidesign.html.json.spi.WSTransfer;
     3.8  import org.apidesign.html.json.tck.KOTest;
     3.9  import org.apidesign.html.json.tck.KnockoutTCK;
    3.10  import org.apidesign.html.kofx.FXContext;
    3.11 +import org.apidesign.html.wstyrus.TyrusContext;
    3.12  import org.json.JSONException;
    3.13  import org.json.JSONObject;
    3.14  import org.openide.util.lookup.ServiceProvider;
    3.15 @@ -58,10 +60,19 @@
    3.16      @Override
    3.17      public BrwsrCtx createContext() {
    3.18          FXContext fx = new FXContext();
    3.19 -        return Contexts.newBuilder().
    3.20 +        TyrusContext tc = new TyrusContext();
    3.21 +        Contexts.Builder b = Contexts.newBuilder().
    3.22              register(Technology.class, fx, 10).
    3.23 -            register(Transfer.class, fx, 10).
    3.24 -            build();
    3.25 +            register(Transfer.class, fx, 10);
    3.26 +        try {
    3.27 +            Class.forName("java.util.function.Function");
    3.28 +            // prefer WebView's WebSockets on JDK8
    3.29 +            b.register(WSTransfer.class, fx, 10);
    3.30 +        } catch (ClassNotFoundException ex) {
    3.31 +            // ok, JDK7 needs tyrus
    3.32 +            b.register(WSTransfer.class, tc, 20);
    3.33 +        }
    3.34 +        return b.build();
    3.35      }
    3.36  
    3.37      @Override
     4.1 --- a/launcher/fx/pom.xml	Fri Jul 12 16:06:38 2013 +0200
     4.2 +++ b/launcher/fx/pom.xml	Mon Aug 26 08:56:37 2013 +0200
     4.3 @@ -78,7 +78,23 @@
     4.4      <dependency>
     4.5        <groupId>org.apidesign.html</groupId>
     4.6        <artifactId>net.java.html.boot</artifactId>
     4.7 -      <version>0.4-SNAPSHOT</version>
     4.8 +      <version>${net.java.html.version}</version>
     4.9 +    </dependency>
    4.10 +    <dependency>
    4.11 +        <groupId>org.glassfish.grizzly</groupId>
    4.12 +        <artifactId>grizzly-websockets-server</artifactId>
    4.13 +        <version>${grizzly.version}</version>
    4.14 +        <type>jar</type>
    4.15 +    </dependency>
    4.16 +    <dependency>
    4.17 +        <groupId>org.glassfish.grizzly</groupId>
    4.18 +        <artifactId>grizzly-http-servlet</artifactId>
    4.19 +        <version>${grizzly.version}</version>
    4.20 +    </dependency>    
    4.21 +    <dependency>
    4.22 +        <groupId>javax.servlet</groupId>
    4.23 +        <artifactId>javax.servlet-api</artifactId>
    4.24 +        <version>3.1.0</version>
    4.25      </dependency>
    4.26    </dependencies>
    4.27  </project>
     5.1 --- a/launcher/fx/src/main/java/org/apidesign/bck2brwsr/launcher/BaseHTTPLauncher.java	Fri Jul 12 16:06:38 2013 +0200
     5.2 +++ b/launcher/fx/src/main/java/org/apidesign/bck2brwsr/launcher/BaseHTTPLauncher.java	Mon Aug 26 08:56:37 2013 +0200
     5.3 @@ -18,6 +18,7 @@
     5.4  package org.apidesign.bck2brwsr.launcher;
     5.5  
     5.6  import java.io.ByteArrayInputStream;
     5.7 +import java.io.ByteArrayOutputStream;
     5.8  import java.io.Closeable;
     5.9  import java.io.File;
    5.10  import java.io.IOException;
    5.11 @@ -53,6 +54,11 @@
    5.12  import org.glassfish.grizzly.http.server.ServerConfiguration;
    5.13  import org.glassfish.grizzly.http.util.HttpStatus;
    5.14  import org.glassfish.grizzly.threadpool.ThreadPoolConfig;
    5.15 +import org.glassfish.grizzly.websockets.WebSocket;
    5.16 +import org.glassfish.grizzly.websockets.WebSocketAddOn;
    5.17 +import org.glassfish.grizzly.websockets.WebSocketApplication;
    5.18 +import org.glassfish.grizzly.websockets.WebSocketEngine;
    5.19 +import org.openide.util.Exceptions;
    5.20  
    5.21  /**
    5.22   * Lightweight server to launch Bck2Brwsr applications and tests.
    5.23 @@ -151,7 +157,11 @@
    5.24      
    5.25      private HttpServer initServer(String path, boolean addClasses) throws IOException {
    5.26          HttpServer s = HttpServer.createSimpleServer(path, new PortRange(8080, 65535));
    5.27 -
    5.28 +        final WebSocketAddOn addon = new WebSocketAddOn();
    5.29 +        for (NetworkListener listener : s.getListeners()) {
    5.30 +            listener.registerAddOn(addon);
    5.31 +        }
    5.32 +        
    5.33          ThreadPoolConfig fewThreads = ThreadPoolConfig.defaultConfig().copy().
    5.34              setPoolName("Fx/Bck2 Brwsr").
    5.35              setCorePoolSize(1).
    5.36 @@ -202,6 +212,7 @@
    5.37                  }
    5.38                  
    5.39                  if ("/dynamic".equals(request.getRequestURI())) {
    5.40 +                    boolean webSocket = false;
    5.41                      String mimeType = request.getParameter("mimeType");
    5.42                      List<String> params = new ArrayList<String>();
    5.43                      for (int i = 0; ; i++) {
    5.44 @@ -210,11 +221,20 @@
    5.45                              break;
    5.46                          }
    5.47                          params.add(p);
    5.48 -                    }
    5.49 +                        if ("protocol:ws".equals(p)) {
    5.50 +                            webSocket = true;
    5.51 +                            continue;
    5.52 +                        }                    }
    5.53                      final String cnt = request.getParameter("content");
    5.54                      String mangle = cnt.replace("%20", " ").replace("%0A", "\n");
    5.55                      ByteArrayInputStream is = new ByteArrayInputStream(mangle.getBytes("UTF-8"));
    5.56 -                    URI url = registerResource(new Resource(is, mimeType, "/dynamic/res" + ++resourcesCount, params.toArray(new String[params.size()])));
    5.57 +                    URI url;
    5.58 +                    final Resource res = new Resource(is, mimeType, "/dynamic/res" + ++resourcesCount, params.toArray(new String[params.size()]));
    5.59 +                    if (webSocket) {
    5.60 +                        url = registerWebSocket(res);
    5.61 +                    } else {
    5.62 +                        url = registerResource(res);
    5.63 +                    }
    5.64                      response.getWriter().write(url.toString());
    5.65                      response.getWriter().write("\n");
    5.66                      return;
    5.67 @@ -256,13 +276,18 @@
    5.68                      }
    5.69                  }
    5.70              }
    5.71 +            
    5.72 +            private URI registerWebSocket(Resource r) {
    5.73 +                WebSocketEngine.getEngine().register("", r.httpPath, new WS(r));
    5.74 +                return pageURL("ws", server, r.httpPath);
    5.75 +            }
    5.76  
    5.77              private URI registerResource(Resource r) {
    5.78                  if (!ic.resources.contains(r)) {
    5.79                      ic.resources.add(r);
    5.80                      conf.addHttpHandler(this, r.httpPath);
    5.81                  }
    5.82 -                return pageURL(server, r.httpPath);
    5.83 +                return pageURL("http", server, r.httpPath);
    5.84              }
    5.85          }
    5.86          
    5.87 @@ -411,7 +436,7 @@
    5.88  
    5.89      private Object[] launchServerAndBrwsr(HttpServer server, final String page) throws IOException, URISyntaxException, InterruptedException {
    5.90          server.start();
    5.91 -        URI uri = pageURL(server, page);
    5.92 +        URI uri = pageURL("http", server, page);
    5.93          return showBrwsr(uri);
    5.94      }
    5.95      private static String toUTF8(String value) throws UnsupportedEncodingException {
    5.96 @@ -523,11 +548,11 @@
    5.97      abstract void generateBck2BrwsrJS(StringBuilder sb, Res loader) throws IOException;
    5.98      abstract String harnessResource();
    5.99  
   5.100 -    private static URI pageURL(HttpServer server, final String page) {
   5.101 +    private static URI pageURL(String protocol, HttpServer server, final String page) {
   5.102          NetworkListener listener = server.getListeners().iterator().next();
   5.103          int port = listener.getPort();
   5.104          try {
   5.105 -            return new URI("http://localhost:" + port + page);
   5.106 +            return new URI(protocol + "://localhost:" + port + page);
   5.107          } catch (URISyntaxException ex) {
   5.108              throw new IllegalStateException(ex);
   5.109          }
   5.110 @@ -675,4 +700,25 @@
   5.111              }
   5.112          }
   5.113      }
   5.114 -}
   5.115 +    private static class WS extends WebSocketApplication {
   5.116 +
   5.117 +        private final Resource r;
   5.118 +
   5.119 +        private WS(Resource r) {
   5.120 +            this.r = r;
   5.121 +        }
   5.122 +
   5.123 +        @Override
   5.124 +        public void onMessage(WebSocket socket, String text) {
   5.125 +            try {
   5.126 +                r.httpContent.reset();
   5.127 +                ByteArrayOutputStream out = new ByteArrayOutputStream();
   5.128 +                copyStream(r.httpContent, out, null, text);
   5.129 +                String s = new String(out.toByteArray(), "UTF-8");
   5.130 +                socket.send(s);
   5.131 +            } catch (IOException ex) {
   5.132 +                Exceptions.printStackTrace(ex);
   5.133 +            }
   5.134 +        }
   5.135 +
   5.136 +    }}
     6.1 --- a/launcher/fx/src/main/java/org/apidesign/bck2brwsr/launcher/fximpl/Console.java	Fri Jul 12 16:06:38 2013 +0200
     6.2 +++ b/launcher/fx/src/main/java/org/apidesign/bck2brwsr/launcher/fximpl/Console.java	Mon Aug 26 08:56:37 2013 +0200
     6.3 @@ -146,6 +146,7 @@
     6.4          
     6.5          @Override
     6.6          public void run() {
     6.7 +            Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
     6.8              try {
     6.9                  if (c == null) {
    6.10                      String data = arr[0];
     7.1 --- a/pom.xml	Fri Jul 12 16:06:38 2013 +0200
     7.2 +++ b/pom.xml	Mon Aug 26 08:56:37 2013 +0200
     7.3 @@ -15,7 +15,7 @@
     7.4        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
     7.5        <netbeans.version>RELEASE73</netbeans.version>
     7.6        <license>COPYING</license>
     7.7 -      <net.java.html.version>0.4-SNAPSHOT</net.java.html.version>
     7.8 +      <net.java.html.version>0.5-SNAPSHOT</net.java.html.version>
     7.9    </properties>
    7.10    <modules>
    7.11      <module>dew</module>