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