launcher/src/main/java/org/apidesign/bck2brwsr/launcher/Bck2BrwsrLauncher.java
branchlauncher
changeset 357 dc375a56fd15
parent 356 e078953818d2
child 360 86f3ea771e24
     1.1 --- a/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/Bck2BrwsrLauncher.java	Thu Dec 20 11:03:34 2012 +0100
     1.2 +++ b/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/Bck2BrwsrLauncher.java	Thu Dec 20 16:17:31 2012 +0100
     1.3 @@ -33,8 +33,6 @@
     1.4  import java.util.Set;
     1.5  import java.util.concurrent.CountDownLatch;
     1.6  import java.util.concurrent.TimeUnit;
     1.7 -import java.util.logging.Level;
     1.8 -import java.util.logging.Logger;
     1.9  import javax.script.Invocable;
    1.10  import javax.script.ScriptEngine;
    1.11  import javax.script.ScriptEngineManager;
    1.12 @@ -50,13 +48,17 @@
    1.13  import org.glassfish.grizzly.http.server.ServerConfiguration;
    1.14  
    1.15  /**
    1.16 - * Lightweight server to launch Bck2Brwsr applications in real browser.
    1.17 + * Lightweight server to launch Bck2Brwsr applications and tests.
    1.18 + * Supports execution in native browser as well as Java's internal 
    1.19 + * execution engine.
    1.20   */
    1.21  public class Bck2BrwsrLauncher {
    1.22      private Set<ClassLoader> loaders = new LinkedHashSet<>();
    1.23      private List<MethodInvocation> methods = new ArrayList<>();
    1.24      private long timeOut;
    1.25      private String sen;
    1.26 +    private String showURL;
    1.27 +    private final Res resources = new Res();
    1.28      
    1.29      
    1.30      public MethodInvocation addMethod(Class<?> clazz, String method) {
    1.31 @@ -73,20 +75,24 @@
    1.32      public void setScriptEngineName(String sen) {
    1.33          this.sen = sen;
    1.34      }
    1.35 +
    1.36 +    public void setStartPage(String startpage) {
    1.37 +        if (!startpage.startsWith("/")) {
    1.38 +            startpage = "/" + startpage;
    1.39 +        }
    1.40 +        this.showURL = startpage;
    1.41 +    }
    1.42 +
    1.43 +    public void addClassLoader(ClassLoader url) {
    1.44 +        this.loaders.add(url);
    1.45 +    }
    1.46      
    1.47      public static void main( String[] args ) throws Exception {
    1.48          Bck2BrwsrLauncher l = new Bck2BrwsrLauncher();
    1.49 -        
    1.50 -        final MethodInvocation[] cases = { 
    1.51 -            l.addMethod(Console.class, "welcome"),
    1.52 -            l.addMethod(Console.class, "multiply"),
    1.53 -        };
    1.54 -        
    1.55 +        l.setStartPage("org/apidesign/bck2brwsr/launcher/console.xhtml");
    1.56 +        l.addClassLoader(Bck2BrwsrLauncher.class.getClassLoader());
    1.57          l.execute();
    1.58 -        
    1.59 -        for (MethodInvocation c : cases) {
    1.60 -            System.err.println(c.className + "." + c.methodName + " = " + c.result);
    1.61 -        }
    1.62 +        System.in.read();
    1.63      }
    1.64  
    1.65  
    1.66 @@ -94,6 +100,10 @@
    1.67          try {
    1.68              if (sen != null) {
    1.69                  executeRhino();
    1.70 +            } else if (showURL != null) {
    1.71 +                HttpServer server = initServer();
    1.72 +                server.getServerConfiguration().addHttpHandler(new Page(resources, null), "/");
    1.73 +                launchServerAndBrwsr(server, showURL);
    1.74              } else {
    1.75                  executeInBrowser();
    1.76              }
    1.77 @@ -142,21 +152,29 @@
    1.78          }
    1.79      }
    1.80      
    1.81 -    private void executeInBrowser() throws InterruptedException, URISyntaxException, IOException {
    1.82 -        final CountDownLatch wait = new CountDownLatch(1);
    1.83 -        final MethodInvocation[] cases = this.methods.toArray(new MethodInvocation[0]);
    1.84 -        
    1.85 +    private HttpServer initServer() {
    1.86          HttpServer server = HttpServer.createSimpleServer(".", new PortRange(8080, 65535));
    1.87 -        
    1.88 -        Res resources = new Res();
    1.89 -        
    1.90 +
    1.91          final ServerConfiguration conf = server.getServerConfiguration();
    1.92 -        conf.addHttpHandler(new Page("console.xhtml", 
    1.93 +        conf.addHttpHandler(new Page(resources, 
    1.94 +            "org/apidesign/bck2brwsr/launcher/console.xhtml",
    1.95              "org.apidesign.bck2brwsr.launcher.Console", "welcome", "false"
    1.96          ), "/console");
    1.97          conf.addHttpHandler(new VM(resources), "/bck2brwsr.js");
    1.98          conf.addHttpHandler(new VMInit(), "/vm.js");
    1.99          conf.addHttpHandler(new Classes(resources), "/classes/");
   1.100 +        return server;
   1.101 +    }
   1.102 +    
   1.103 +    private void executeInBrowser() throws InterruptedException, URISyntaxException, IOException {
   1.104 +        final CountDownLatch wait = new CountDownLatch(1);
   1.105 +        final MethodInvocation[] cases = this.methods.toArray(new MethodInvocation[0]);
   1.106 +        
   1.107 +        HttpServer server = initServer();
   1.108 +        ServerConfiguration conf = server.getServerConfiguration();
   1.109 +        conf.addHttpHandler(new Page(resources, 
   1.110 +            "org/apidesign/bck2brwsr/launcher/harness.xhtml"
   1.111 +        ), "/execute");
   1.112          conf.addHttpHandler(new HttpHandler() {
   1.113              int cnt;
   1.114              @Override
   1.115 @@ -183,21 +201,8 @@
   1.116                  cnt++;
   1.117              }
   1.118          }, "/data");
   1.119 -        conf.addHttpHandler(new Page("harness.xhtml"), "/");
   1.120 -        
   1.121 -        server.start();
   1.122 -        NetworkListener listener = server.getListeners().iterator().next();
   1.123 -        int port = listener.getPort();
   1.124 -        
   1.125 -        URI uri = new URI("http://localhost:" + port + "/execute");
   1.126 -        try {
   1.127 -            Desktop.getDesktop().browse(uri);
   1.128 -        } catch (UnsupportedOperationException ex) {
   1.129 -            String[] cmd = { 
   1.130 -                "xdg-open", uri.toString()
   1.131 -            };
   1.132 -            Runtime.getRuntime().exec(cmd).waitFor();
   1.133 -        }
   1.134 +
   1.135 +        launchServerAndBrwsr(server, "/execute");
   1.136          
   1.137          wait.await(timeOut, TimeUnit.MILLISECONDS);
   1.138          server.stop();
   1.139 @@ -223,6 +228,23 @@
   1.140          }
   1.141      }
   1.142  
   1.143 +    private void launchServerAndBrwsr(HttpServer server, final String page) throws IOException, URISyntaxException, InterruptedException {
   1.144 +        server.start();
   1.145 +        NetworkListener listener = server.getListeners().iterator().next();
   1.146 +        int port = listener.getPort();
   1.147 +        
   1.148 +        URI uri = new URI("http://localhost:" + port + page);
   1.149 +        try {
   1.150 +            Desktop.getDesktop().browse(uri);
   1.151 +        } catch (UnsupportedOperationException ex) {
   1.152 +            String[] cmd = { 
   1.153 +                "xdg-open", uri.toString()
   1.154 +            };
   1.155 +            Runtime.getRuntime().exec(cmd).waitFor();
   1.156 +        }
   1.157 +        System.err.println("Showing " + uri);
   1.158 +    }
   1.159 +
   1.160      private class Res implements Bck2Brwsr.Resources {
   1.161          @Override
   1.162          public InputStream get(String resource) throws IOException {
   1.163 @@ -243,18 +265,34 @@
   1.164      private static class Page extends HttpHandler {
   1.165          private final String resource;
   1.166          private final String[] args;
   1.167 +        private final Res res;
   1.168          
   1.169 -        public Page(String resource, String... args) {
   1.170 +        public Page(Res res, String resource, String... args) {
   1.171 +            this.res = res;
   1.172              this.resource = resource;
   1.173              this.args = args;
   1.174          }
   1.175  
   1.176          @Override
   1.177          public void service(Request request, Response response) throws Exception {
   1.178 -            response.setContentType("text/html");
   1.179 +            String r = resource;
   1.180 +            if (r == null) {
   1.181 +                r = request.getHttpHandlerPath();
   1.182 +                if (r.startsWith("/")) {
   1.183 +                    r = r.substring(1);
   1.184 +                }
   1.185 +            }
   1.186 +            if (r.endsWith(".html") || r.endsWith(".xhtml")) {
   1.187 +                response.setContentType("text/html");
   1.188 +            }
   1.189              OutputStream os = response.getOutputStream();
   1.190 -            InputStream is = Bck2BrwsrLauncher.class.getResourceAsStream(resource);
   1.191 -            copyStream(is, os, request.getRequestURL().toString(), args);
   1.192 +            try (InputStream is = res.get(r)) {
   1.193 +                copyStream(is, os, request.getRequestURL().toString(), args);
   1.194 +            } catch (IOException ex) {
   1.195 +                response.setDetailMessage(ex.getLocalizedMessage());
   1.196 +                response.setError();
   1.197 +                response.setStatus(404);
   1.198 +            }
   1.199          }
   1.200      }
   1.201  
   1.202 @@ -283,7 +321,7 @@
   1.203              response.getWriter().append(
   1.204                  "function ldCls(res) {\n"
   1.205                  + "  var request = new XMLHttpRequest();\n"
   1.206 -                + "  request.open('GET', 'classes/' + res, false);\n"
   1.207 +                + "  request.open('GET', '/classes/' + res, false);\n"
   1.208                  + "  request.send();\n"
   1.209                  + "  var arr = eval('(' + request.responseText + ')');\n"
   1.210                  + "  return arr;\n"