launcher/src/main/java/org/apidesign/bck2brwsr/dew/Compile.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Tue, 15 Jan 2013 22:48:17 +0100
branchdew
changeset 462 aa69b1387624
child 463 3641fd0663d3
permissions -rw-r--r--
Trying to compile Java source via the javax.tools.ToolProvider.getSystemJavaCompiler
     1 /*
     2  * To change this template, choose Tools | Templates
     3  * and open the template in the editor.
     4  */
     5 package org.apidesign.bck2brwsr.dew;
     6 
     7 import java.io.IOException;
     8 import java.nio.charset.Charset;
     9 import java.util.ArrayList;
    10 import java.util.Collections;
    11 import java.util.Iterator;
    12 import java.util.List;
    13 import java.util.Locale;
    14 import java.util.Map;
    15 import java.util.Set;
    16 import java.util.regex.Matcher;
    17 import java.util.regex.Pattern;
    18 import javax.tools.Diagnostic;
    19 import javax.tools.DiagnosticListener;
    20 import javax.tools.FileObject;
    21 import javax.tools.JavaCompiler;
    22 import javax.tools.JavaCompiler.CompilationTask;
    23 import javax.tools.JavaFileManager;
    24 import javax.tools.JavaFileObject;
    25 import javax.tools.JavaFileObject.Kind;
    26 import javax.tools.StandardJavaFileManager;
    27 import javax.tools.StandardLocation;
    28 
    29 /**
    30  *
    31  * @author Jaroslav Tulach <jtulach@netbeans.org>
    32  */
    33 final class Compile implements JavaFileManager, DiagnosticListener<JavaFileObject> {
    34     private final JFO jfo;
    35     private final String pkg;
    36     private StandardJavaFileManager delegate;
    37     private List<Diagnostic<? extends JavaFileObject>> errors = new ArrayList<>();
    38 
    39     public Compile(String pkg, JFO jfo) {
    40         this.pkg = pkg;
    41         this.jfo = jfo;
    42     }
    43     
    44     public static Map<String,byte[]> compile(String html, String java) throws IOException {
    45         JavaCompiler jc = javax.tools.ToolProvider.getSystemJavaCompiler();
    46         String pkg = findPkg(java);
    47         String cls = findCls(java);
    48         
    49         JFO jfo = new JFO(java, pkg.replace('.', '/') + '/' + cls + ".java");
    50         final Compile cmp = new Compile(pkg, jfo);
    51         cmp.delegate = jc.getStandardFileManager(cmp, Locale.ENGLISH, Charset.forName("UTF-8"));
    52         
    53         Set<String> toCmp = Collections.singleton(pkg + '.' + cls);
    54         Set<JFO> unit = Collections.singleton(jfo);
    55         CompilationTask task = jc.getTask(null, cmp, cmp, null, null, unit);
    56         if (task.call() != true) {
    57             throw new IOException("Compilation failed: " + cmp.errors);
    58         }
    59         return Collections.emptyMap();
    60     }
    61 
    62     @Override
    63     public ClassLoader getClassLoader(Location location) {
    64         return null;//Compile.class.getClassLoader();
    65     }
    66 
    67     @Override
    68     public Iterable<JavaFileObject> list(Location location, String packageName, Set<Kind> kinds, boolean recurse) throws IOException {
    69         if (location == StandardLocation.PLATFORM_CLASS_PATH) {
    70             return delegate.list(location, packageName, kinds, recurse);
    71         }
    72         if (location == StandardLocation.CLASS_PATH) {
    73             return delegate.list(location, packageName, kinds, recurse);
    74         }
    75         if (location == StandardLocation.SOURCE_PATH) {
    76             if (packageName.equals(pkg)) {
    77                 return Collections.<JavaFileObject>singleton(jfo);
    78             }
    79             return Collections.emptyList();
    80         }
    81         throw new UnsupportedOperationException("Loc: " + location + " pkg: " + packageName + " kinds: " + kinds + " rec: " + recurse);
    82     }
    83 
    84     @Override
    85     public String inferBinaryName(Location location, JavaFileObject file) {
    86         if (file == jfo) {
    87             return pkg + "." + file.getName();
    88         }
    89         return delegate.inferBinaryName(location, file);
    90     }
    91 
    92     @Override
    93     public boolean isSameFile(FileObject a, FileObject b) {
    94         throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    95     }
    96 
    97     @Override
    98     public boolean handleOption(String current, Iterator<String> remaining) {
    99         throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
   100     }
   101 
   102     @Override
   103     public boolean hasLocation(Location location) {
   104         return true;
   105     }
   106 
   107     @Override
   108     public JavaFileObject getJavaFileForInput(Location location, String className, Kind kind) throws IOException {
   109         throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
   110     }
   111 
   112     @Override
   113     public JavaFileObject getJavaFileForOutput(Location location, String className, Kind kind, FileObject sibling) throws IOException {
   114         throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
   115     }
   116 
   117     @Override
   118     public FileObject getFileForInput(Location location, String packageName, String relativeName) throws IOException {
   119         throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
   120     }
   121 
   122     @Override
   123     public FileObject getFileForOutput(Location location, String packageName, String relativeName, FileObject sibling) throws IOException {
   124         throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
   125     }
   126 
   127     @Override
   128     public void flush() throws IOException {
   129     }
   130 
   131     @Override
   132     public void close() throws IOException {
   133         throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
   134     }
   135 
   136     @Override
   137     public int isSupportedOption(String option) {
   138         throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
   139     }
   140 
   141     @Override
   142     public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
   143         errors.add(diagnostic);
   144     }
   145     private static String findPkg(String java) throws IOException {
   146         Pattern p = Pattern.compile("package\\p{javaWhitespace}*([\\p{Alnum}\\.]+)\\p{javaWhitespace}*;", Pattern.MULTILINE);
   147         Matcher m = p.matcher(java);
   148         if (!m.find()) {
   149             throw new IOException("Can't find package declaration in the java file");
   150         }
   151         String pkg = m.group(1);
   152         return pkg;
   153     }
   154     private static String findCls(String java) throws IOException {
   155         Pattern p = Pattern.compile("class\\p{javaWhitespace}*([\\p{Alnum}\\.]+)\\p{javaWhitespace}", Pattern.MULTILINE);
   156         Matcher m = p.matcher(java);
   157         if (!m.find()) {
   158             throw new IOException("Can't find package declaration in the java file");
   159         }
   160         String cls = m.group(1);
   161         return cls;
   162     }
   163 }