2 * To change this template, choose Tools | Templates
3 * and open the template in the editor.
5 package org.apidesign.bck2brwsr.dew;
7 import java.io.ByteArrayInputStream;
8 import java.io.ByteArrayOutputStream;
9 import java.io.IOException;
10 import java.io.InputStream;
11 import java.io.OutputStream;
13 import java.net.URISyntaxException;
14 import java.nio.charset.Charset;
15 import java.util.ArrayList;
16 import java.util.Arrays;
17 import java.util.Collections;
18 import java.util.HashMap;
19 import java.util.Iterator;
20 import java.util.List;
21 import java.util.Locale;
24 import java.util.logging.Level;
25 import java.util.logging.Logger;
26 import java.util.regex.Matcher;
27 import java.util.regex.Pattern;
28 import javax.tools.Diagnostic;
29 import javax.tools.DiagnosticListener;
30 import javax.tools.FileObject;
31 import javax.tools.ForwardingJavaFileManager;
32 import javax.tools.JavaCompiler;
33 import javax.tools.JavaCompiler.CompilationTask;
34 import javax.tools.JavaFileManager;
35 import javax.tools.JavaFileObject;
36 import javax.tools.JavaFileObject.Kind;
37 import javax.tools.SimpleJavaFileObject;
38 import javax.tools.StandardJavaFileManager;
39 import javax.tools.StandardLocation;
40 import javax.tools.ToolProvider;
44 * @author Jaroslav Tulach <jtulach@netbeans.org>
46 final class Compile implements JavaFileManager, DiagnosticListener<JavaFileObject> {
47 private final JFO jfo;
48 private final String pkg;
49 private StandardJavaFileManager delegate;
50 private List<Diagnostic<? extends JavaFileObject>> errors = new ArrayList<>();
52 public Compile(String pkg, JFO jfo) {
58 public static Map<String,byte[]> compile(String html, String java) throws IOException {
59 JavaCompiler jc = javax.tools.ToolProvider.getSystemJavaCompiler();
60 String pkg = findPkg(java);
61 String cls = findCls(java);
63 JFO jfo = new JFO(java, pkg.replace('.', '/') + '/' + cls + ".java");
64 final Compile cmp = new Compile(pkg, jfo);
65 cmp.delegate = jc.getStandardFileManager(cmp, Locale.ENGLISH, Charset.forName("UTF-8"));
67 Set<String> toCmp = Collections.singleton(pkg + '.' + cls);
68 Set<JFO> unit = Collections.singleton(jfo);
69 CompilationTask task = jc.getTask(null, cmp, cmp, null, null, unit);
70 if (task.call() != true) {
71 throw new IOException("Compilation failed: " + cmp.errors);
73 return Collections.emptyMap();
76 public static Map<String, byte[]> compile(final String html, final String code) throws IOException {
77 final String pkg = findPkg(code);
78 // String cls = findCls(code);
80 DiagnosticListener<JavaFileObject> devNull = new DiagnosticListener<JavaFileObject>() {
81 public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
82 System.err.println("diagnostic=" + diagnostic);
85 StandardJavaFileManager sjfm = ToolProvider.getSystemJavaCompiler().getStandardFileManager(devNull, null, null);
87 // sjfm.setLocation(StandardLocation.PLATFORM_CLASS_PATH, toFiles(boot));
88 // sjfm.setLocation(StandardLocation.CLASS_PATH, toFiles(compile));
90 final Map<String, ByteArrayOutputStream> class2BAOS = new HashMap<String, ByteArrayOutputStream>();
92 JavaFileObject file = new SimpleJavaFileObject(URI.create("mem://mem"), Kind.SOURCE) {
94 public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
98 final JavaFileObject htmlFile = new SimpleJavaFileObject(URI.create("mem://mem2"), Kind.OTHER) {
100 public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
105 public InputStream openInputStream() throws IOException {
106 return new ByteArrayInputStream(html.getBytes());
112 scratch = new URI("mem://mem3");
113 } catch (URISyntaxException ex) {
114 throw new IOException(ex);
117 JavaFileManager jfm = new ForwardingJavaFileManager<JavaFileManager>(sjfm) {
119 public JavaFileObject getJavaFileForOutput(Location location, String className, Kind kind, FileObject sibling) throws IOException {
120 if (kind == Kind.CLASS) {
121 final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
123 class2BAOS.put(className.replace('.', '/') + ".class", buffer);
124 return new SimpleJavaFileObject(sibling.toUri(), kind) {
126 public OutputStream openOutputStream() throws IOException {
132 if (kind == Kind.SOURCE) {
133 return new SimpleJavaFileObject(scratch/*sibling.toUri()*/, kind) {
134 private final ByteArrayOutputStream data = new ByteArrayOutputStream();
136 public OutputStream openOutputStream() throws IOException {
141 public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
143 return new String(data.toByteArray());
148 throw new IllegalStateException();
151 // public Iterable<JavaFileObject> list(Location location, String packageName, Set<Kind> kinds, boolean recurse) throws IOException {
152 // if (location == StandardLocation.PLATFORM_CLASS_PATH) {
153 // return super.list(location, packageName, kinds, recurse);
155 // if (location == StandardLocation.CLASS_PATH) {
156 // return super.list(location, packageName, kinds, recurse);
158 // if (location == StandardLocation.SOURCE_PATH) {
159 // System.out.println("src path for " + packageName + " kinds: " + kinds);
160 // if (packageName.equals(pkg) && kinds.contains(Kind.OTHER)) {
161 // return Collections.<JavaFileObject>singleton(htmlFile);
163 // return Collections.emptyList();
165 // throw new UnsupportedOperationException("Loc: " + location + " pkg: " + packageName + " kinds: " + kinds + " rec: " + recurse);
169 public FileObject getFileForInput(Location location, String packageName, String relativeName) throws IOException {
170 if (location == StandardLocation.SOURCE_PATH) {
171 // System.out.println("src path for " + packageName + " kinds: " + kinds);
172 if (packageName.equals(pkg)) {
182 ToolProvider.getSystemJavaCompiler().getTask(null, jfm, devNull, /*XXX:*/Arrays.asList("-source", "1.7", "-target", "1.7"), null, Arrays.asList(file)).call();
184 Map<String, byte[]> result = new HashMap<String, byte[]>();
186 for (Map.Entry<String, ByteArrayOutputStream> e : class2BAOS.entrySet()) {
187 result.put(e.getKey(), e.getValue().toByteArray());
194 public ClassLoader getClassLoader(Location location) {
195 return null;//Compile.class.getClassLoader();
199 public Iterable<JavaFileObject> list(Location location, String packageName, Set<Kind> kinds, boolean recurse) throws IOException {
200 if (location == StandardLocation.PLATFORM_CLASS_PATH) {
201 return delegate.list(location, packageName, kinds, recurse);
203 if (location == StandardLocation.CLASS_PATH) {
204 return delegate.list(location, packageName, kinds, recurse);
206 if (location == StandardLocation.SOURCE_PATH) {
207 if (packageName.equals(pkg)) {
208 return Collections.<JavaFileObject>singleton(jfo);
210 return Collections.emptyList();
212 throw new UnsupportedOperationException("Loc: " + location + " pkg: " + packageName + " kinds: " + kinds + " rec: " + recurse);
216 public String inferBinaryName(Location location, JavaFileObject file) {
218 return pkg + "." + file.getName();
220 return delegate.inferBinaryName(location, file);
224 public boolean isSameFile(FileObject a, FileObject b) {
225 throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
229 public boolean handleOption(String current, Iterator<String> remaining) {
230 throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
234 public boolean hasLocation(Location location) {
239 public JavaFileObject getJavaFileForInput(Location location, String className, Kind kind) throws IOException {
240 throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
244 public JavaFileObject getJavaFileForOutput(Location location, String className, Kind kind, FileObject sibling) throws IOException {
245 throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
249 public FileObject getFileForInput(Location location, String packageName, String relativeName) throws IOException {
250 throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
254 public FileObject getFileForOutput(Location location, String packageName, String relativeName, FileObject sibling) throws IOException {
255 throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
259 public void flush() throws IOException {
263 public void close() throws IOException {
264 throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
268 public int isSupportedOption(String option) {
269 throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
273 public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
274 errors.add(diagnostic);
276 private static String findPkg(String java) throws IOException {
277 Pattern p = Pattern.compile("package\\p{javaWhitespace}*([\\p{Alnum}\\.]+)\\p{javaWhitespace}*;", Pattern.MULTILINE);
278 Matcher m = p.matcher(java);
280 throw new IOException("Can't find package declaration in the java file");
282 String pkg = m.group(1);
285 private static String findCls(String java) throws IOException {
286 Pattern p = Pattern.compile("class\\p{javaWhitespace}*([\\p{Alnum}\\.]+)\\p{javaWhitespace}", Pattern.MULTILINE);
287 Matcher m = p.matcher(java);
289 throw new IOException("Can't find package declaration in the java file");
291 String cls = m.group(1);