Using cummulative factory with the hope to prevent enormous increase in overloaded 'generate' methods closure
authorJaroslav Tulach <jaroslav.tulach@apidesign.org>
Fri, 22 Mar 2013 14:46:10 +0100
branchclosure
changeset 8742bcbe348dbec
parent 873 95c6ffa9d8e7
child 880 32eb44c74e1e
Using cummulative factory with the hope to prevent enormous increase in overloaded 'generate' methods
rt/mojo/src/main/java/org/apidesign/bck2brwsr/mojo/Java2JavaScript.java
rt/vm/src/main/java/org/apidesign/vm4brwsr/Bck2Brwsr.java
rt/vm/src/main/java/org/apidesign/vm4brwsr/LdrRsrcs.java
rt/vm/src/main/java/org/apidesign/vm4brwsr/StringArray.java
     1.1 --- a/rt/mojo/src/main/java/org/apidesign/bck2brwsr/mojo/Java2JavaScript.java	Fri Mar 22 10:52:51 2013 +0100
     1.2 +++ b/rt/mojo/src/main/java/org/apidesign/bck2brwsr/mojo/Java2JavaScript.java	Fri Mar 22 14:46:10 2013 +0100
     1.3 @@ -88,7 +88,11 @@
     1.4          try {
     1.5              URLClassLoader url = buildClassLoader(classes, prj.getDependencyArtifacts());
     1.6              FileWriter w = new FileWriter(javascript);
     1.7 -            Bck2Brwsr.generate(w, obfuscation, url, arr.toArray(new String[0]));
     1.8 +            Bck2Brwsr.newCompiler().
     1.9 +                obfuscation(obfuscation).
    1.10 +                resources(url).
    1.11 +                addRootClasses(arr.toArray(new String[0])).
    1.12 +                generate(w);
    1.13              w.close();
    1.14          } catch (IOException ex) {
    1.15              throw new MojoExecutionException("Can't compile", ex);
     2.1 --- a/rt/vm/src/main/java/org/apidesign/vm4brwsr/Bck2Brwsr.java	Fri Mar 22 10:52:51 2013 +0100
     2.2 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/Bck2Brwsr.java	Fri Mar 22 14:46:10 2013 +0100
     2.3 @@ -54,10 +54,17 @@
     2.4   * @author Jaroslav Tulach <jtulach@netbeans.org>
     2.5   */
     2.6  public final class Bck2Brwsr {
     2.7 -    private Bck2Brwsr() {
     2.8 +    private final ObfuscationLevel level;
     2.9 +    private final StringArray classes;
    2.10 +    private final Resources res;
    2.11 +
    2.12 +    private Bck2Brwsr(ObfuscationLevel level, StringArray classes, Resources resources) {
    2.13 +        this.level = level;
    2.14 +        this.classes = classes;
    2.15 +        this.res = resources;
    2.16      }
    2.17 -
    2.18 -    /** Generates virtual machine from bytes served by a <code>resources</code>
    2.19 +    
    2.20 +    /** Helper method to generate virtual machine from bytes served by a <code>resources</code>
    2.21       * provider.
    2.22       *
    2.23       * @param out the output to write the generated JavaScript to
    2.24 @@ -66,10 +73,10 @@
    2.25       * @throws IOException I/O exception can be thrown when something goes wrong
    2.26       */
    2.27      public static void generate(Appendable out, Resources resources, String... classes) throws IOException {
    2.28 -        generate(out, ObfuscationLevel.NONE, resources, classes);
    2.29 +        newCompiler().resources(resources).addRootClasses(classes).generate(out);
    2.30      }
    2.31  
    2.32 -    /** Generates virtual machine from bytes served by a class loader.
    2.33 +    /** Helper method to generate virtual machine from bytes served by a class loader.
    2.34       *
    2.35       * @param out the output to write the generated JavaScript to
    2.36       * @param loader class loader to load needed classes from
    2.37 @@ -77,27 +84,87 @@
    2.38       * @throws IOException I/O exception can be thrown when something goes wrong
    2.39       */
    2.40      public static void generate(Appendable out, ClassLoader loader, String... classes) throws IOException {
    2.41 -        generate(out, ObfuscationLevel.NONE, loader, classes);
    2.42 +        newCompiler().resources(loader).addRootClasses(classes).generate(out);
    2.43 +    }
    2.44 +    
    2.45 +    /** Creates new instance of Bck2Brwsr compiler which is ready to generate
    2.46 +     * empty Bck2Brwsr virtual machine. The instance can be further
    2.47 +     * configured by calling chain of methods. For example: 
    2.48 +     * <pre>
    2.49 +     * {@link #createCompiler()}.{@link #resources(org.apidesign.vm4brwsr.Bck2Brwsr.Resources) resources(loader)}.{@link #addRootClasses(java.lang.String[]) addRootClasses("your/Clazz")}.{@link #generate(java.lang.Appendable) generate(out)};
    2.50 +     * </pre>
    2.51 +     * 
    2.52 +     * @return new instance of the Bck2Brwsr compiler
    2.53 +     * @since 0.5
    2.54 +     */
    2.55 +    public static Bck2Brwsr newCompiler() {
    2.56 +        StringArray arr = StringArray.asList(VM.class.getName().replace('.', '/'));
    2.57 +        return new Bck2Brwsr(ObfuscationLevel.NONE, arr, null);
    2.58      }
    2.59  
    2.60 -    /** Generates virtual machine from bytes served by a <code>resources</code>
    2.61 -     * provider.
    2.62 +    /** Creates new instance of the Bck2Brwsr compiler which inherits
    2.63 +     * all values from <code>this</code> instance and adds additional classes 
    2.64 +     * to the list of those that should be compiled by the {@link #generate(java.lang.Appendable)} 
    2.65 +     * method.
    2.66 +     * 
    2.67 +     * @param classes the classes to add to the compilation
    2.68 +     * @return new instance of the compiler
    2.69 +     */
    2.70 +    public Bck2Brwsr addRootClasses(String... classes) {
    2.71 +        if (classes.length == 0) {
    2.72 +            return this;
    2.73 +        } else {
    2.74 +            return new Bck2Brwsr(level, this.classes.addAndNew(classes), res);
    2.75 +        }
    2.76 +    }
    2.77 +    
    2.78 +    /** Changes the obfuscation level for the compiler by creating new instance
    2.79 +     * which inherits all values from <code>this</code> and adjust the level
    2.80 +     * of obfuscation.
    2.81 +     * 
    2.82 +     * @param level the new level of obfuscation
    2.83 +     * @return new instance of the compiler with changed level of obfuscation
    2.84 +     * @since 0.5
    2.85 +     */
    2.86 +    public Bck2Brwsr obfuscation(ObfuscationLevel level) {
    2.87 +        return new Bck2Brwsr(level, classes, res);
    2.88 +    }
    2.89 +    
    2.90 +    /** A way to change the provider of additional resources (classes) for the 
    2.91 +     * compiler. 
    2.92 +     * 
    2.93 +     * @param res the implementation of resources provider
    2.94 +     * @return new instance of the compiler with all values remaining the same, just 
    2.95 +     *   with different resources provider
    2.96 +     * @since 0.5
    2.97 +     */
    2.98 +    public Bck2Brwsr resources(Resources res) {
    2.99 +        return new Bck2Brwsr(level, classes, res);
   2.100 +    }
   2.101 +
   2.102 +    /** A way to change the provider of additional resources (classes) for the 
   2.103 +     * compiler by specifying classloader to use for loading them.
   2.104 +     * 
   2.105 +     * @param loader class loader to load the resources from
   2.106 +     * @return new instance of the compiler with all values being the same, just 
   2.107 +     *   different resources provider
   2.108 +     * @since 0.5
   2.109 +     */
   2.110 +    public Bck2Brwsr resources(final ClassLoader loader) {
   2.111 +        return resources(new LdrRsrcs(loader));
   2.112 +    }
   2.113 +    
   2.114 +    /** Generates virtual machine based on previous configuration of the 
   2.115 +     * compiler.
   2.116       * 
   2.117       * @param out the output to write the generated JavaScript to
   2.118 -     * @param obfuscationLevel the obfuscation level for the generated
   2.119 -     *                         JavaScript
   2.120 -     * @param resources provider of class files to use
   2.121 -     * @param classes additional classes to include in the generated script
   2.122 -     * @throws IOException I/O exception can be thrown when something goes wrong
   2.123       * @since 0.5
   2.124       */
   2.125 -    public static void generate(Appendable out, ObfuscationLevel obfuscationLevel, Resources resources, String... classes) throws IOException {
   2.126 -        StringArray arr = StringArray.asList(classes);
   2.127 -        arr.add(VM.class.getName().replace('.', '/'));
   2.128 -
   2.129 -        if (obfuscationLevel != ObfuscationLevel.NONE) {
   2.130 +    public void generate(Appendable out) throws IOException {
   2.131 +        Resources r = res != null ? res : new LdrRsrcs(Bck2Brwsr.class.getClassLoader());
   2.132 +        if (level != ObfuscationLevel.NONE) {
   2.133              try {
   2.134 -                ClosureWrapper.produceTo(out, obfuscationLevel, resources, arr);
   2.135 +                ClosureWrapper.produceTo(out, level, r, classes);
   2.136                  return;
   2.137              } catch (IOException ex) {
   2.138                  throw ex;
   2.139 @@ -107,35 +174,7 @@
   2.140              }
   2.141          }
   2.142  
   2.143 -        VM.compile(resources, out, arr);
   2.144 -    }
   2.145 -    
   2.146 -    /** Generates virtual machine from bytes served by a class loader.
   2.147 -     * 
   2.148 -     * @param out the output to write the generated JavaScript to
   2.149 -     * @param obfuscationLevel the obfuscation level for the generated
   2.150 -     *                         JavaScript
   2.151 -     * @param loader class loader to load needed classes from
   2.152 -     * @param classes additional classes to include in the generated script
   2.153 -     * @throws IOException I/O exception can be thrown when something goes wrong
   2.154 -     * @since 0.5
   2.155 -     */
   2.156 -    public static void generate(Appendable out, ObfuscationLevel obfuscationLevel, final ClassLoader loader, String... classes) throws IOException {
   2.157 -        class R implements Resources {
   2.158 -            @Override
   2.159 -            public InputStream get(String name) throws IOException {
   2.160 -                Enumeration<URL> en = loader.getResources(name);
   2.161 -                URL u = null;
   2.162 -                while (en.hasMoreElements()) {
   2.163 -                    u = en.nextElement();
   2.164 -                }
   2.165 -                if (u == null) {
   2.166 -                    throw new IOException("Can't find " + name);
   2.167 -                }
   2.168 -                return u.openStream();
   2.169 -            }
   2.170 -        }
   2.171 -        generate(out, obfuscationLevel, new R(), classes);
   2.172 +        VM.compile(r, out, classes);
   2.173      }
   2.174      
   2.175      /** Provider of resources (classes and other files). The 
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/LdrRsrcs.java	Fri Mar 22 14:46:10 2013 +0100
     3.3 @@ -0,0 +1,48 @@
     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.vm4brwsr;
    3.22 +
    3.23 +import java.io.IOException;
    3.24 +import java.io.InputStream;
    3.25 +import java.net.URL;
    3.26 +import java.util.Enumeration;
    3.27 +
    3.28 +/** Implementation of Resources that delegates to some class loader.
    3.29 + *
    3.30 + * @author Jaroslav Tulach <jtulach@netbeans.org>
    3.31 + */
    3.32 +final class LdrRsrcs implements Bck2Brwsr.Resources {
    3.33 +    private final ClassLoader loader;
    3.34 +
    3.35 +    LdrRsrcs(ClassLoader loader) {
    3.36 +        this.loader = loader;
    3.37 +    }
    3.38 +
    3.39 +    @Override
    3.40 +    public InputStream get(String name) throws IOException {
    3.41 +        Enumeration<URL> en = loader.getResources(name);
    3.42 +        URL u = null;
    3.43 +        while (en.hasMoreElements()) {
    3.44 +            u = en.nextElement();
    3.45 +        }
    3.46 +        if (u == null) {
    3.47 +            throw new IOException("Can't find " + name);
    3.48 +        }
    3.49 +        return u.openStream();
    3.50 +    }
    3.51 +}
     4.1 --- a/rt/vm/src/main/java/org/apidesign/vm4brwsr/StringArray.java	Fri Mar 22 10:52:51 2013 +0100
     4.2 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/StringArray.java	Fri Mar 22 14:46:10 2013 +0100
     4.3 @@ -43,6 +43,25 @@
     4.4          }
     4.5          arr[arr.length - 1] = s;
     4.6      }
     4.7 +
     4.8 +    StringArray addAndNew(String... values) {
     4.9 +        int j;
    4.10 +        String[] tmp;
    4.11 +        if (arr == null) {
    4.12 +            tmp = new String[values.length];
    4.13 +            j = 0;
    4.14 +        } else {
    4.15 +            tmp = new String[arr.length + values.length];
    4.16 +            for (int i = 0; i < arr.length; i++) {
    4.17 +                tmp[i] = arr[i];
    4.18 +            }
    4.19 +            j = arr.length;
    4.20 +        }
    4.21 +        for (int i = 0; i < values.length;) {
    4.22 +            tmp[j++] = values[i++];
    4.23 +        }
    4.24 +        return new StringArray(tmp);
    4.25 +    }
    4.26      
    4.27      public String[] toArray() {
    4.28          return arr == null ? new String[0] : arr;
    4.29 @@ -93,5 +112,4 @@
    4.30          }
    4.31          return -1;
    4.32      }
    4.33 -    
    4.34  }