1 package org.apidesign.bck2brwsr.dew;
3 import java.io.ByteArrayInputStream;
4 import java.io.ByteArrayOutputStream;
5 import java.io.IOException;
6 import java.io.InputStream;
7 import java.io.OutputStream;
9 import java.net.URISyntaxException;
10 import java.util.ArrayList;
11 import java.util.Arrays;
12 import java.util.HashMap;
13 import java.util.List;
15 import java.util.regex.Matcher;
16 import java.util.regex.Pattern;
17 import javax.tools.Diagnostic;
18 import javax.tools.DiagnosticListener;
19 import javax.tools.FileObject;
20 import javax.tools.ForwardingJavaFileManager;
21 import javax.tools.JavaFileManager;
22 import javax.tools.JavaFileObject;
23 import javax.tools.JavaFileObject.Kind;
24 import javax.tools.SimpleJavaFileObject;
25 import javax.tools.StandardJavaFileManager;
26 import javax.tools.StandardLocation;
27 import javax.tools.ToolProvider;
31 * @author Jaroslav Tulach <jtulach@netbeans.org>
33 final class Compile implements DiagnosticListener<JavaFileObject> {
34 private final List<Diagnostic<? extends JavaFileObject>> errors = new ArrayList<>();
35 private final Map<String, byte[]> classes;
36 private final String pkg;
37 private final String cls;
39 private Compile(String html, String code) throws IOException {
40 this.pkg = findPkg(code);
41 this.cls = findCls(code);
42 classes = compile(html, code);
45 /** Performs compilation of given HTML page and associated Java code
47 public static Compile create(String html, String code) throws IOException {
48 return new Compile(html, code);
51 /** Checks for given class among compiled resources */
52 public byte[] get(String res) {
53 return classes.get(res);
56 /** Obtains errors created during compilation.
58 public List<Diagnostic<? extends JavaFileObject>> getErrors() {
59 List<Diagnostic<? extends JavaFileObject>> err = new ArrayList<>();
60 for (Diagnostic<? extends JavaFileObject> diagnostic : errors) {
61 if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
68 private Map<String, byte[]> compile(final String html, final String code) throws IOException {
69 StandardJavaFileManager sjfm = ToolProvider.getSystemJavaCompiler().getStandardFileManager(this, null, null);
71 final Map<String, ByteArrayOutputStream> class2BAOS = new HashMap<>();
73 JavaFileObject file = new SimpleJavaFileObject(URI.create("mem://mem"), Kind.SOURCE) {
75 public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
79 final JavaFileObject htmlFile = new SimpleJavaFileObject(URI.create("mem://mem2"), Kind.OTHER) {
81 public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
86 public InputStream openInputStream() throws IOException {
87 return new ByteArrayInputStream(html.getBytes());
93 scratch = new URI("mem://mem3");
94 } catch (URISyntaxException ex) {
95 throw new IOException(ex);
98 JavaFileManager jfm = new ForwardingJavaFileManager<JavaFileManager>(sjfm) {
100 public JavaFileObject getJavaFileForOutput(Location location, String className, Kind kind, FileObject sibling) throws IOException {
101 if (kind == Kind.CLASS) {
102 final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
104 class2BAOS.put(className.replace('.', '/') + ".class", buffer);
105 return new SimpleJavaFileObject(sibling.toUri(), kind) {
107 public OutputStream openOutputStream() throws IOException {
113 if (kind == Kind.SOURCE) {
114 return new SimpleJavaFileObject(scratch/*sibling.toUri()*/, kind) {
115 private final ByteArrayOutputStream data = new ByteArrayOutputStream();
117 public OutputStream openOutputStream() throws IOException {
122 public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
124 return new String(data.toByteArray());
129 throw new IllegalStateException();
133 public FileObject getFileForInput(Location location, String packageName, String relativeName) throws IOException {
134 if (location == StandardLocation.SOURCE_PATH) {
135 if (packageName.equals(pkg)) {
145 ToolProvider.getSystemJavaCompiler().getTask(null, jfm, this, /*XXX:*/Arrays.asList("-source", "1.7", "-target", "1.7"), null, Arrays.asList(file)).call();
147 Map<String, byte[]> result = new HashMap<>();
149 for (Map.Entry<String, ByteArrayOutputStream> e : class2BAOS.entrySet()) {
150 result.put(e.getKey(), e.getValue().toByteArray());
158 public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
159 errors.add(diagnostic);
161 private static String findPkg(String java) throws IOException {
162 Pattern p = Pattern.compile("package\\p{javaWhitespace}*([\\p{Alnum}\\.]+)\\p{javaWhitespace}*;", Pattern.MULTILINE);
163 Matcher m = p.matcher(java);
165 throw new IOException("Can't find package declaration in the java file");
167 String pkg = m.group(1);
170 private static String findCls(String java) throws IOException {
171 Pattern p = Pattern.compile("class\\p{javaWhitespace}*([\\p{Alnum}\\.]+)\\p{javaWhitespace}", Pattern.MULTILINE);
172 Matcher m = p.matcher(java);
174 throw new IOException("Can't find package declaration in the java file");
176 String cls = m.group(1);