2 * Back 2 Browser Bytecode Translator
3 * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, version 2 of the License.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. Look for COPYING file in the top folder.
16 * If not, see http://opensource.org/licenses/GPL-2.0.
18 package org.apidesign.bck2brwsr.dew;
20 import java.io.ByteArrayInputStream;
21 import java.io.ByteArrayOutputStream;
22 import java.io.IOException;
23 import java.io.InputStream;
24 import java.io.OutputStream;
26 import java.net.URISyntaxException;
27 import java.util.ArrayList;
28 import java.util.Arrays;
29 import java.util.HashMap;
30 import java.util.List;
32 import javax.tools.Diagnostic;
33 import javax.tools.DiagnosticListener;
34 import javax.tools.FileObject;
35 import javax.tools.ForwardingJavaFileManager;
36 import javax.tools.JavaFileManager;
37 import javax.tools.JavaFileObject;
38 import javax.tools.JavaFileObject.Kind;
39 import javax.tools.SimpleJavaFileObject;
40 import javax.tools.StandardJavaFileManager;
41 import javax.tools.StandardLocation;
42 import javax.tools.ToolProvider;
46 * @author Jaroslav Tulach <jtulach@netbeans.org>
48 final class Compile implements DiagnosticListener<JavaFileObject> {
49 private final List<Diagnostic<? extends JavaFileObject>> errors = new ArrayList<>();
50 private final Map<String, byte[]> classes;
51 private final String pkg;
52 private final String cls;
53 private final String html;
55 private Compile(String html, String code) throws IOException {
56 this.pkg = find("package", ';', code);
57 this.cls = find("class", ' ', code);
59 classes = compile(html, code);
62 /** Performs compilation of given HTML page and associated Java code
64 public static Compile create(String html, String code) throws IOException {
65 return new Compile(html, code);
68 /** Checks for given class among compiled resources */
69 public byte[] get(String res) {
70 return classes.get(res);
73 /** Obtains errors created during compilation.
75 public List<Diagnostic<? extends JavaFileObject>> getErrors() {
76 List<Diagnostic<? extends JavaFileObject>> err = new ArrayList<>();
77 for (Diagnostic<? extends JavaFileObject> diagnostic : errors) {
78 if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
85 private Map<String, byte[]> compile(final String html, final String code) throws IOException {
86 final ClassLoaderFileManager clfm = new ClassLoaderFileManager();
87 final JavaFileObject file = clfm.createMemoryFileObject(
88 ClassLoaderFileManager.convertFQNToResource(pkg.isEmpty() ? cls : pkg + "." + cls) + Kind.SOURCE.extension,
91 final JavaFileObject htmlFile = clfm.createMemoryFileObject(
92 ClassLoaderFileManager.convertFQNToResource(pkg),
96 JavaFileManager jfm = new ForwardingJavaFileManager<JavaFileManager>(clfm) {
98 public FileObject getFileForInput(Location location, String packageName, String relativeName) throws IOException {
99 if (location == StandardLocation.SOURCE_PATH) {
100 if (packageName.equals(pkg)) {
108 final Boolean res = ToolProvider.getSystemJavaCompiler().getTask(null, jfm, this, /*XXX:*/Arrays.asList("-source", "1.7", "-target", "1.7"), null, Arrays.asList(file)).call();
109 Map<String, byte[]> result = new HashMap<>();
110 for (MemoryFileObject generated : clfm.getGeneratedFiles(Kind.CLASS)) {
111 result.put(generated.getName().substring(1), generated.getContent());
118 public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
119 errors.add(diagnostic);
121 private static String find(String pref, char term, String java) throws IOException {
122 int pkg = java.indexOf(pref);
124 pkg += pref.length();
125 while (Character.isWhitespace(java.charAt(pkg))) {
128 int semicolon = java.indexOf(term, pkg);
129 if (semicolon != -1) {
130 String pkgName = java.substring(pkg, semicolon).trim();
134 throw new IOException("Can't find " + pref + " declaration in the java file");
138 String fqn = "'" + pkg + '.' + cls + "'";
139 return html.replace("'${fqn}'", fqn);