Hidding the launchers behind common fasade
authorJaroslav Tulach <jaroslav.tulach@apidesign.org>
Tue, 25 Dec 2012 15:08:39 +0100
changeset 38257fc3a0563c9
parent 381 70d15cf323ba
child 383 88ed1f51eb22
Hidding the launchers behind common fasade
launcher/src/main/java/org/apidesign/bck2brwsr/launcher/Bck2BrwsrLauncher.java
launcher/src/main/java/org/apidesign/bck2brwsr/launcher/JSLauncher.java
launcher/src/main/java/org/apidesign/bck2brwsr/launcher/Launcher.java
mojo/src/main/java/org/apidesign/bck2brwsr/mojo/BrswrMojo.java
vmtest/src/main/java/org/apidesign/bck2brwsr/vmtest/impl/Bck2BrwsrCase.java
vmtest/src/main/java/org/apidesign/bck2brwsr/vmtest/impl/Launchers.java
     1.1 --- a/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/Bck2BrwsrLauncher.java	Tue Dec 25 14:07:02 2012 +0100
     1.2 +++ b/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/Bck2BrwsrLauncher.java	Tue Dec 25 15:08:39 2012 +0100
     1.3 @@ -17,6 +17,7 @@
     1.4   */
     1.5  package org.apidesign.bck2brwsr.launcher;
     1.6  
     1.7 +import java.io.Closeable;
     1.8  import java.io.File;
     1.9  import java.io.IOException;
    1.10  import java.io.InputStream;
    1.11 @@ -52,18 +53,23 @@
    1.12   * Supports execution in native browser as well as Java's internal 
    1.13   * execution engine.
    1.14   */
    1.15 -public class Bck2BrwsrLauncher {
    1.16 +final class Bck2BrwsrLauncher extends Launcher implements Closeable {
    1.17      private static final Logger LOG = Logger.getLogger(Bck2BrwsrLauncher.class.getName());
    1.18      private static final MethodInvocation END = new MethodInvocation(null, null);
    1.19      private Set<ClassLoader> loaders = new LinkedHashSet<>();
    1.20      private BlockingQueue<MethodInvocation> methods = new LinkedBlockingQueue<>();
    1.21      private long timeOut;
    1.22      private final Res resources = new Res();
    1.23 +    private final String cmd;
    1.24      private Object[] brwsr;
    1.25      private HttpServer server;
    1.26      private CountDownLatch wait;
    1.27 +
    1.28 +    public Bck2BrwsrLauncher(String cmd) {
    1.29 +        this.cmd = cmd;
    1.30 +    }
    1.31      
    1.32 -    
    1.33 +    @Override
    1.34      public MethodInvocation addMethod(Class<?> clazz, String method) throws IOException {
    1.35          loaders.add(clazz.getClassLoader());
    1.36          MethodInvocation c = new MethodInvocation(clazz.getName(), method);
    1.37 @@ -83,23 +89,21 @@
    1.38      public void addClassLoader(ClassLoader url) {
    1.39          this.loaders.add(url);
    1.40      }
    1.41 -    
    1.42 -    public static void main( String[] args ) throws Exception {
    1.43 -        Bck2BrwsrLauncher l = new Bck2BrwsrLauncher();
    1.44 -        l.addClassLoader(Bck2BrwsrLauncher.class.getClassLoader());
    1.45 -        l.showURL("org/apidesign/bck2brwsr/launcher/console.xhtml");
    1.46 -        System.in.read();
    1.47 -    }
    1.48  
    1.49 -    public void showURL(String startpage) throws URISyntaxException, InterruptedException, IOException {
    1.50 +    public void showURL(String startpage) throws IOException {
    1.51          if (!startpage.startsWith("/")) {
    1.52              startpage = "/" + startpage;
    1.53          }
    1.54          HttpServer s = initServer();
    1.55          s.getServerConfiguration().addHttpHandler(new Page(resources, null), "/");
    1.56 -        launchServerAndBrwsr(s, startpage);
    1.57 +        try {
    1.58 +            launchServerAndBrwsr(s, startpage);
    1.59 +        } catch (URISyntaxException | InterruptedException ex) {
    1.60 +            throw new IOException(ex);
    1.61 +        }
    1.62      }
    1.63  
    1.64 +    @Override
    1.65      public void initialize() throws IOException {
    1.66          try {
    1.67              executeInBrowser();
    1.68 @@ -178,12 +182,17 @@
    1.69          this.brwsr = launchServerAndBrwsr(server, "/execute");
    1.70      }
    1.71      
    1.72 -    public void shutdown() throws InterruptedException, IOException {
    1.73 +    @Override
    1.74 +    public void shutdown() throws IOException {
    1.75          methods.offer(END);
    1.76          for (;;) {
    1.77              int prev = methods.size();
    1.78 -            if (wait.await(timeOut, TimeUnit.MILLISECONDS)) {
    1.79 -                break;
    1.80 +            try {
    1.81 +                if (wait.await(timeOut, TimeUnit.MILLISECONDS)) {
    1.82 +                    break;
    1.83 +                }
    1.84 +            } catch (InterruptedException ex) {
    1.85 +                throw new IOException(ex);
    1.86              }
    1.87              if (prev == methods.size()) {
    1.88                  LOG.log(
    1.89 @@ -244,11 +253,12 @@
    1.90  //            return new Object[] { process, dir };
    1.91          }
    1.92          {
    1.93 -            String[] cmd = { 
    1.94 -                "xdg-open", uri.toString()
    1.95 +            String cmdName = cmd == null ? "xdg-open" : cmd;
    1.96 +            String[] cmdArr = { 
    1.97 +                cmdName, uri.toString()
    1.98              };
    1.99 -            LOG.log(Level.INFO, "Launching {0}", Arrays.toString(cmd));
   1.100 -            final Process process = Runtime.getRuntime().exec(cmd);
   1.101 +            LOG.log(Level.INFO, "Launching {0}", Arrays.toString(cmdArr));
   1.102 +            final Process process = Runtime.getRuntime().exec(cmdArr);
   1.103              return new Object[] { process, null };
   1.104          }
   1.105      }
   1.106 @@ -264,7 +274,7 @@
   1.107          }
   1.108      }
   1.109      
   1.110 -    private void stopServerAndBrwsr(HttpServer server, Object[] brwsr) throws IOException, InterruptedException {
   1.111 +    private void stopServerAndBrwsr(HttpServer server, Object[] brwsr) throws IOException {
   1.112          Process process = (Process)brwsr[0];
   1.113          
   1.114          server.stop();
   1.115 @@ -273,7 +283,12 @@
   1.116          drain("StdOut", stdout);
   1.117          drain("StdErr", stderr);
   1.118          process.destroy();
   1.119 -        int res = process.waitFor();
   1.120 +        int res;
   1.121 +        try {
   1.122 +            res = process.waitFor();
   1.123 +        } catch (InterruptedException ex) {
   1.124 +            throw new IOException(ex);
   1.125 +        }
   1.126          LOG.log(Level.INFO, "Exit code: {0}", res);
   1.127  
   1.128          deleteTree((File)brwsr[1]);
   1.129 @@ -305,6 +320,11 @@
   1.130          file.delete();
   1.131      }
   1.132  
   1.133 +    @Override
   1.134 +    public void close() throws IOException {
   1.135 +        shutdown();
   1.136 +    }
   1.137 +
   1.138      private class Res implements Bck2Brwsr.Resources {
   1.139          @Override
   1.140          public InputStream get(String resource) throws IOException {
     2.1 --- a/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/JSLauncher.java	Tue Dec 25 14:07:02 2012 +0100
     2.2 +++ b/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/JSLauncher.java	Tue Dec 25 15:08:39 2012 +0100
     2.3 @@ -33,7 +33,7 @@
     2.4  /**
     2.5   * Tests execution in Java's internal scripting engine.
     2.6   */
     2.7 -public final class JSLauncher {
     2.8 +final class JSLauncher extends Launcher {
     2.9      private static final Logger LOG = Logger.getLogger(JSLauncher.class.getName());
    2.10      private Set<ClassLoader> loaders = new LinkedHashSet<>();
    2.11      private final Res resources = new Res();
    2.12 @@ -41,6 +41,7 @@
    2.13      private Object console;
    2.14      
    2.15      
    2.16 +    @Override
    2.17      public MethodInvocation addMethod(Class<?> clazz, String method) {
    2.18          loaders.add(clazz.getClassLoader());
    2.19          MethodInvocation mi = new MethodInvocation(clazz.getName(), method);
    2.20 @@ -59,6 +60,7 @@
    2.21          this.loaders.add(url);
    2.22      }
    2.23  
    2.24 +    @Override
    2.25      public void initialize() throws IOException {
    2.26          try {
    2.27              initRhino();
    2.28 @@ -94,6 +96,10 @@
    2.29          Object vm = code.invokeFunction("initVM");
    2.30          console = code.invokeMethod(vm, "loadClass", Console.class.getName());
    2.31      }
    2.32 +
    2.33 +    @Override
    2.34 +    public void shutdown() throws IOException {
    2.35 +    }
    2.36      
    2.37      private class Res implements Bck2Brwsr.Resources {
    2.38          @Override
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/Launcher.java	Tue Dec 25 15:08:39 2012 +0100
     3.3 @@ -0,0 +1,63 @@
     3.4 +/**
     3.5 + * Back 2 Browser Bytecode Translator
     3.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
     3.7 + *
     3.8 + * This program is free software: you can redistribute it and/or modify
     3.9 + * it under the terms of the GNU General Public License as published by
    3.10 + * the Free Software Foundation, version 2 of the License.
    3.11 + *
    3.12 + * This program is distributed in the hope that it will be useful,
    3.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    3.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    3.15 + * GNU General Public License for more details.
    3.16 + *
    3.17 + * You should have received a copy of the GNU General Public License
    3.18 + * along with this program. Look for COPYING file in the top folder.
    3.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
    3.20 + */
    3.21 +package org.apidesign.bck2brwsr.launcher;
    3.22 +
    3.23 +import java.io.Closeable;
    3.24 +import java.io.IOException;
    3.25 +import java.net.URLClassLoader;
    3.26 +import org.apidesign.vm4brwsr.Bck2Brwsr;
    3.27 +
    3.28 +/** An abstraction for executing tests in a Bck2Brwsr virtual machine.
    3.29 + * Either in JavaScript engine, or in external browser.
    3.30 + *
    3.31 + * @author Jaroslav Tulach <jtulach@netbeans.org>
    3.32 + */
    3.33 +public abstract class Launcher {
    3.34 +
    3.35 +    Launcher() {
    3.36 +    }
    3.37 +    
    3.38 +    abstract MethodInvocation addMethod(Class<?> clazz, String method) throws IOException; 
    3.39 +
    3.40 +    public abstract void initialize() throws IOException;
    3.41 +    public abstract void shutdown() throws IOException;
    3.42 +    public MethodInvocation invokeMethod(Class<?> clazz, String method) throws IOException {
    3.43 +        return addMethod(clazz, method);
    3.44 +    }
    3.45 +    
    3.46 +    
    3.47 +
    3.48 +    public static Launcher createJavaScript() {
    3.49 +        final JSLauncher l = new JSLauncher();
    3.50 +        l.addClassLoader(Bck2Brwsr.class.getClassLoader());
    3.51 +        return l;
    3.52 +    }
    3.53 +    
    3.54 +    public static Launcher createBrowser(String cmd) {
    3.55 +        final Bck2BrwsrLauncher l = new Bck2BrwsrLauncher(cmd);
    3.56 +        l.addClassLoader(Bck2Brwsr.class.getClassLoader());
    3.57 +        l.setTimeout(180000);
    3.58 +        return l;
    3.59 +    }
    3.60 +    public static Closeable showURL(URLClassLoader classes, String startpage) throws IOException {
    3.61 +        Bck2BrwsrLauncher l = new Bck2BrwsrLauncher(null);
    3.62 +        l.addClassLoader(classes);
    3.63 +        l.showURL(startpage);
    3.64 +        return l;
    3.65 +    }
    3.66 +}
     4.1 --- a/mojo/src/main/java/org/apidesign/bck2brwsr/mojo/BrswrMojo.java	Tue Dec 25 14:07:02 2012 +0100
     4.2 +++ b/mojo/src/main/java/org/apidesign/bck2brwsr/mojo/BrswrMojo.java	Tue Dec 25 15:08:39 2012 +0100
     4.3 @@ -17,26 +17,24 @@
     4.4   */
     4.5  package org.apidesign.bck2brwsr.mojo;
     4.6  
     4.7 +import java.io.Closeable;
     4.8  import org.apache.maven.plugin.AbstractMojo;
     4.9  
    4.10  import java.io.File;
    4.11  import java.io.IOException;
    4.12  import java.net.MalformedURLException;
    4.13 -import java.net.URISyntaxException;
    4.14  import java.net.URL;
    4.15  import java.net.URLClassLoader;
    4.16  import java.util.ArrayList;
    4.17  import java.util.Collection;
    4.18  import java.util.List;
    4.19 -import java.util.logging.Level;
    4.20 -import java.util.logging.Logger;
    4.21  import org.apache.maven.artifact.Artifact;
    4.22  import org.apache.maven.plugin.MojoExecutionException;
    4.23  import org.apache.maven.plugins.annotations.LifecyclePhase;
    4.24  import org.apache.maven.plugins.annotations.Mojo;
    4.25  import org.apache.maven.plugins.annotations.Parameter;
    4.26  import org.apache.maven.project.MavenProject;
    4.27 -import org.apidesign.bck2brwsr.launcher.Bck2BrwsrLauncher;
    4.28 +import org.apidesign.bck2brwsr.launcher.Launcher;
    4.29  
    4.30  /** Executes given HTML page in a browser. */
    4.31  @Mojo(name="brwsr", defaultPhase=LifecyclePhase.DEPLOY)
    4.32 @@ -63,15 +61,14 @@
    4.33          try {
    4.34              URLClassLoader url = buildClassLoader(classes, prj.getDependencyArtifacts());
    4.35              
    4.36 -            Bck2BrwsrLauncher httpServer = new Bck2BrwsrLauncher();
    4.37 -            httpServer.addClassLoader(url);
    4.38 +            Closeable httpServer;
    4.39              try {
    4.40 -                httpServer.showURL(startpage);
    4.41 +                httpServer = Launcher.showURL(url, startpage);
    4.42              } catch (Exception ex) {
    4.43                  throw new MojoExecutionException("Can't open " + startpage, ex);
    4.44              }
    4.45 -            
    4.46              System.in.read();
    4.47 +            httpServer.close();
    4.48          } catch (IOException ex) {
    4.49              throw new MojoExecutionException("Can't show the browser", ex);
    4.50          }
     5.1 --- a/vmtest/src/main/java/org/apidesign/bck2brwsr/vmtest/impl/Bck2BrwsrCase.java	Tue Dec 25 14:07:02 2012 +0100
     5.2 +++ b/vmtest/src/main/java/org/apidesign/bck2brwsr/vmtest/impl/Bck2BrwsrCase.java	Tue Dec 25 15:08:39 2012 +0100
     5.3 @@ -48,10 +48,10 @@
     5.4      @Test(groups = "run")
     5.5      public void executeCode() throws Throwable {
     5.6          if (type == 1) {
     5.7 -            MethodInvocation c = l.addMethod(m.getDeclaringClass(), m.getName(), false);
     5.8 +            MethodInvocation c = l.invokeMethod(m.getDeclaringClass(), m.getName(), false);
     5.9              value = c.toString();
    5.10          } else if (type == 2) {
    5.11 -            MethodInvocation c = l.addMethod(m.getDeclaringClass(), m.getName(), true);
    5.12 +            MethodInvocation c = l.invokeMethod(m.getDeclaringClass(), m.getName(), true);
    5.13              value = c.toString();
    5.14          } else {
    5.15              value = m.invoke(m.getDeclaringClass().newInstance());
     6.1 --- a/vmtest/src/main/java/org/apidesign/bck2brwsr/vmtest/impl/Launchers.java	Tue Dec 25 14:07:02 2012 +0100
     6.2 +++ b/vmtest/src/main/java/org/apidesign/bck2brwsr/vmtest/impl/Launchers.java	Tue Dec 25 15:08:39 2012 +0100
     6.3 @@ -18,10 +18,8 @@
     6.4  package org.apidesign.bck2brwsr.vmtest.impl;
     6.5  
     6.6  import java.io.IOException;
     6.7 -import org.apidesign.bck2brwsr.launcher.Bck2BrwsrLauncher;
     6.8 -import org.apidesign.bck2brwsr.launcher.JSLauncher;
     6.9 +import org.apidesign.bck2brwsr.launcher.Launcher;
    6.10  import org.apidesign.bck2brwsr.launcher.MethodInvocation;
    6.11 -import org.apidesign.vm4brwsr.Bck2Brwsr;
    6.12  import org.testng.annotations.AfterGroups;
    6.13  import org.testng.annotations.BeforeGroups;
    6.14  
    6.15 @@ -32,34 +30,32 @@
    6.16  public final class Launchers {
    6.17      public static final Launchers INSTANCE = new Launchers();
    6.18      
    6.19 -    private JSLauncher jsl;
    6.20 -    private Bck2BrwsrLauncher brwsr;
    6.21 +    private Launcher jsl;
    6.22 +    private Launcher brwsr;
    6.23      
    6.24      private Launchers() {
    6.25      }
    6.26  
    6.27      @BeforeGroups("run")
    6.28      public void initializeLauncher() throws IOException {
    6.29 -        jsl = new JSLauncher();
    6.30 -        jsl.addClassLoader(Bck2Brwsr.class.getClassLoader());
    6.31 +        jsl = Launcher.createJavaScript();
    6.32          jsl.initialize();
    6.33 -        Bck2BrwsrLauncher l = new Bck2BrwsrLauncher();
    6.34 -        l.addClassLoader(Bck2Brwsr.class.getClassLoader());
    6.35 +        Launcher l = Launcher.createBrowser("xdg-open");
    6.36          l.initialize();
    6.37 -        l.setTimeout(180000);
    6.38          brwsr = l;
    6.39      }
    6.40  
    6.41      @AfterGroups("run")
    6.42      public void shutDownLauncher() throws IOException, InterruptedException {
    6.43 +        jsl.shutdown();
    6.44          brwsr.shutdown();
    6.45      }
    6.46  
    6.47 -    public MethodInvocation addMethod(Class<?> clazz, String name, boolean inBrwsr) throws IOException {
    6.48 +    public MethodInvocation invokeMethod(Class<?> clazz, String name, boolean inBrwsr) throws IOException {
    6.49          if (!inBrwsr) {
    6.50 -            return jsl.addMethod(clazz, name);
    6.51 +            return jsl.invokeMethod(clazz, name);
    6.52          } else {
    6.53 -            return brwsr.addMethod(clazz, name);
    6.54 +            return brwsr.invokeMethod(clazz, name);
    6.55          }
    6.56      }
    6.57  }