Changeset 371:f31d11b0d46d in livinglogic.java.ul4

Show
Ignore:
Timestamp:
02/15/11 14:50:41 (8 years ago)
Author:
Walter Doerwald <walter@…>
Branch:
default
Message:

Add native Java compilation to InterpretedTemplate?.

InterpretedTemplate?.compileToJava() converts the template to Java source code,
compiles this source code and loads and instantiates the resulting JSPTemplate
subclass.

Files:
3 modified

Legend:

Unmodified
Added
Removed
  • docs/versiondoc.txt

    r369 r371  
    88* Updated commons-lang.jar to version 2.6 (StringEscapeUtils.escapeJava() 
    99  was escaping '/' in version 2.4) 
     10* InterpretedTemplate now has a new method compileToJava() that can be used to 
     11  compile the template into native Java code. (This generated Java source 
     12  code for the template and compiles this with the help of the Java compiler). 
    1013 
    1114 
  • library/src/com/livinglogic/ul4/InterpretedTemplate.java

    r368 r371  
    55import java.io.Reader; 
    66import java.io.Writer; 
     7import java.io.File; 
    78import java.io.StringWriter; 
    89import java.io.StringReader; 
     10import java.io.PrintWriter; 
     11import java.io.FileOutputStream; 
    912import java.util.LinkedList; 
    1013import java.util.List; 
     
    19091912    } 
    19101913 
     1914    public JSPTemplate compileToJava() throws java.io.IOException, java.io.FileNotFoundException 
     1915    { 
     1916        File file = File.createTempFile("jav", ".java", new File(System.getProperty("user.dir"))); 
     1917        file.deleteOnExit(); // Set the file to delete on exit 
     1918        // Get the file name and extract a class name from it 
     1919        String filename = file.getName(); 
     1920        String classname = filename.substring(0, filename.length()-5); 
     1921 
     1922        PrintWriter out = new PrintWriter(new FileOutputStream(file)); 
     1923        out.println("/* Created on " + new Date() + " */"); 
     1924        out.println(); 
     1925        out.println("public class " + classname + " extends com.livinglogic.ul4.JSPTemplate"); 
     1926        out.println("{"); 
     1927        // Get rid of "Note: Some input files use unchecked or unsafe operations." warnings from the Java compiler 
     1928        // Using the compiler option -Xlint:-unchecked doesn't seem to work 
     1929        out.println("\t@SuppressWarnings(\"unchecked\")"); 
     1930        out.println("\tpublic void render(java.io.Writer out, java.util.Map<String, Object> variables) throws java.io.IOException"); 
     1931        out.println("\t{"); 
     1932        out.println(javaSource()); 
     1933        out.println("\t}"); 
     1934        out.println("}"); 
     1935        // Flush and close the stream 
     1936        out.flush(); 
     1937        out.close(); 
     1938 
     1939        // This requires $JAVA_HOME/lib/tools.jar in the CLASSPATH 
     1940        com.sun.tools.javac.Main javac = new com.sun.tools.javac.Main(); 
     1941 
     1942        String[] args = new String[] { 
     1943            "-d", System.getProperty("user.dir"), 
     1944            filename 
     1945        }; 
     1946 
     1947        int status = javac.compile(args); 
     1948 
     1949        switch (status) 
     1950        { 
     1951            case 0:  // OK 
     1952                // Make the class file temporary as well 
     1953                new File(file.getParent(), classname + ".class").deleteOnExit(); 
     1954 
     1955                // Create an instance and return it 
     1956                try 
     1957                { 
     1958                    Class clazz = Class.forName(classname); 
     1959                    return (JSPTemplate)clazz.newInstance(); 
     1960                } 
     1961                catch (ClassNotFoundException ex) 
     1962                { 
     1963                    // Can't happen 
     1964                    return null; 
     1965                } 
     1966                catch (InstantiationException ex) 
     1967                { 
     1968                    // Can't happen 
     1969                    return null; 
     1970                } 
     1971                catch (IllegalAccessException ex) 
     1972                { 
     1973                    // Can't happen 
     1974                    return null; 
     1975                } 
     1976            case 1: 
     1977                throw new RuntimeException("Compile status: ERROR"); 
     1978            case 2: 
     1979                throw new RuntimeException("Compile status: CMDERR"); 
     1980            case 3: 
     1981                throw new RuntimeException("Compile status: SYSERR"); 
     1982            case 4: 
     1983                throw new RuntimeException("Compile status: ABNORMAL"); 
     1984            default: 
     1985                throw new RuntimeException("Compile status: Unknown exit status"); 
     1986        } 
     1987    } 
     1988 
    19111989    public String toString() 
    19121990    { 
  • library/src/com/livinglogic/ul4/Main.java

    r347 r371  
    99public class Main 
    1010{ 
    11     public static void main(String[] args) 
     11    private static String pretty(long duration) 
    1212    { 
    13         InterpretedTemplate tmpl = Compiler.compile("<?print 'a<=><=>b<=>c'.rsplit('<=>', 10)?>"); 
     13        return (duration/1000) + "micros"; 
     14    } 
     15 
     16    public static void main(String[] args) throws java.io.IOException 
     17    { 
     18        InterpretedTemplate tmpl = Compiler.compile("<?code langs = ['Python', 'Java', 'C']?><ul><?for l in langs?><li><?printx l?></li><?end for?></ul>"); 
     19        System.out.println("Testing template:"); 
     20        System.out.println(tmpl.source); 
     21        System.out.println(); 
     22 
     23        System.out.println("Byte code for template:"); 
    1424        System.out.println(tmpl); 
     25        // Not required System.out.println(); 
    1526 
    1627        Map vars = new HashMap<String, Object>(); 
    1728        vars.put("t", tmpl); 
    18         long start = System.nanoTime(); 
    19         String output = tmpl.renders(vars); 
    20         System.out.println("rendered " + ((System.nanoTime()-start)/1000) + "us"); 
    21         System.out.println("output " + output); 
    22         System.out.println(new JavaSource4Template(tmpl)); 
     29 
     30        System.out.println("Interpreted run:"); 
     31        long interpretedstart = System.nanoTime(); 
     32        String interpretedoutput = tmpl.renders(vars); 
     33        long interpretedend = System.nanoTime(); 
     34        long interpretedrendertime = interpretedend - interpretedstart; 
     35        System.out.println("rendered in " + pretty(interpretedrendertime)); 
     36        System.out.println("output " + interpretedoutput); 
     37        System.out.println(); 
     38 
     39        System.out.println("Compiled run:"); 
     40        long compiledcompilestart = System.nanoTime(); 
     41        JSPTemplate compiledTmpl = tmpl.compileToJava(); 
     42        long compiledcompileend = System.nanoTime(); 
     43        long compiledcompiletime = compiledcompileend - compiledcompilestart; 
     44        long compiledrenderstart = System.nanoTime(); 
     45        String compiledoutput = compiledTmpl.renders(vars); 
     46        long compiledrenderend = System.nanoTime(); 
     47        long compiledrendertime = compiledrenderend - compiledrenderstart; 
     48        System.out.println("compiled in " + pretty(compiledcompiletime)); 
     49        System.out.println("rendered in " + pretty(compiledrendertime)); 
     50        System.out.println("output " + compiledoutput); 
     51        System.out.println(); 
     52 
     53        if (compiledoutput.equals(interpretedoutput)) 
     54            System.out.println("identical output"); 
     55        else 
     56            System.out.println("outputs not identical!"); 
     57 
     58        if (interpretedrendertime > compiledrendertime) 
     59        { 
     60            double breakeven = (compiledcompiletime) / (interpretedrendertime - compiledrendertime); 
     61            System.out.println("Break even: " + breakeven); 
     62        } 
     63        else 
     64            System.out.println("No break even"); 
    2365    } 
    2466}