vm/src/main/java/org/apidesign/vm4brwsr/Bck2Brwsr.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Tue, 11 Dec 2012 09:36:44 +0100
branchlazyvm
changeset 298 885acca2fa0b
child 405 e41809be6106
child 424 aef4fd91e99c
permissions -rw-r--r--
Creating Bck2Brwsr entrypoint to for those who wish to generate their JavaScript based Java VM
     1 /**
     2  * Back 2 Browser Bytecode Translator
     3  * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
     4  *
     5  * This program is free software: you can redistribute it and/or modify
     6  * it under the terms of the GNU General Public License as published by
     7  * the Free Software Foundation, version 2 of the License.
     8  *
     9  * This program is distributed in the hope that it will be useful,
    10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    12  * GNU General Public License for more details.
    13  *
    14  * You should have received a copy of the GNU General Public License
    15  * along with this program. Look for COPYING file in the top folder.
    16  * If not, see http://opensource.org/licenses/GPL-2.0.
    17  */
    18 package org.apidesign.vm4brwsr;
    19 
    20 import java.io.IOException;
    21 import java.io.InputStream;
    22 import java.net.URL;
    23 import java.util.Enumeration;
    24 
    25 /** Build your own virtual machine! Use methods in this class to generate
    26  * a skeleton JVM in JavaScript that contains pre-compiled classes of your
    27  * choice. The generated script defines one JavaScript method that can
    28  * be used to bootstrap and load the virtual machine: <pre>
    29  * var vm = bck2brwsr();
    30  * var main = vm.loadClass('org.your.pkg.Main');
    31  * main.main__V_3Ljava_lang_String_2(null);
    32  * </pre>
    33  * In case one wants to initialize the virtual machine with ability to
    34  * load classes lazily when needed, one can provide a loader function to
    35  * when creating the virtual machine: <pre>
    36  * var vm = bck2brwsr(function(resource) { 
    37  *   return null; // byte[] for the resource
    38  * });
    39  * </pre>
    40  * In this scenario, when a request for a unknown class is made, the loader
    41  * function is asked for its byte code and the system dynamically transforms
    42  * it to JavaScript.
    43  *
    44  * @author Jaroslav Tulach <jtulach@netbeans.org>
    45  */
    46 public final class Bck2Brwsr {
    47     private Bck2Brwsr() {
    48     }
    49     
    50     /** Generates virtual machine from bytes served by a <code>resources</code>
    51      * provider.
    52      * 
    53      * @param out the output to write the generated JavaScript to
    54      * @param resources provider of class files to use
    55      * @param classes additional classes to include in the generated script
    56      * @throws IOException I/O exception can be thrown when something goes wrong
    57      */
    58     public static void generate(Appendable out, Resources resources, String... classes) throws IOException {
    59         StringArray arr = StringArray.asList(classes);
    60         arr.add(VM.class.getName().replace('.', '/'));
    61         VM.compile(resources, out, arr);
    62     }
    63     
    64     /** Generates virtual machine from bytes served by a class loader.
    65      * 
    66      * @param out the output to write the generated JavaScript to
    67      * @param loader class loader to load needed classes from
    68      * @param classes additional classes to include in the generated script
    69      * @throws IOException I/O exception can be thrown when something goes wrong
    70      */
    71     public static void generate(Appendable out, final ClassLoader loader, String... classes) throws IOException {
    72         class R implements Resources {
    73             @Override
    74             public InputStream get(String name) throws IOException {
    75                 Enumeration<URL> en = loader.getResources(name);
    76                 URL u = null;
    77                 while (en.hasMoreElements()) {
    78                     u = en.nextElement();
    79                 }
    80                 if (u == null) {
    81                     throw new IOException("Can't find " + name);
    82                 }
    83                 return u.openStream();
    84             }
    85         }
    86         generate(out, new R(), classes);
    87     }
    88     
    89     /** Provider of resources (classes and other files). The 
    90      * {@link #generate(java.lang.Appendable, org.apidesign.vm4brwsr.Bck2Brwsr.Resources, java.lang.String[]) 
    91      * generator method} will call back here for all classes needed during
    92      * translation to JavaScript.
    93      */
    94     public interface Resources {
    95         /** Loads given resource (class or other file like image). The 
    96          * resource name to load bytes for the {@link String} class
    97          * would be <code>"java/lang/String.class"</code>.
    98          * 
    99          * @param resource path to resource to load
   100          * @return the input stream for the resource 
   101          * @throws IOException can be thrown if the loading fails on some error
   102          *   or the file cannot be found
   103          */
   104         public InputStream get(String resource) throws IOException;
   105     }
   106 }