All Downloads are FREE. Search and download functionalities are using the official Maven repository.

pluginloader.load.PluginCompiler Maven / Gradle / Ivy

The newest version!
package pluginloader.load;

import javax.lang.model.SourceVersion;
import javax.tools.*;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URI;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;

public class PluginCompiler {
    public static class CompilationFailedException extends Exception{
        private final String code;

        public CompilationFailedException(String message, String code) {
            super(message);
            this.code = code;
        }

        public String getCode() {
            return code;
        }
    }

    private static class JavaStringObject extends SimpleJavaFileObject{
        private final String code;

        public JavaStringObject(String pluginName, String code) {
            super(URI.create(String.format(
                    "string:///%s%s",
                    pluginName.replace('.','/'),
                    Kind.SOURCE.extension
            )), Kind.SOURCE);
            this.code = code;
        }

        @Override
        public CharSequence getCharContent(boolean ignoreEncodingErrors) {
            return code;
        }
    }

    private static class JavaByteObject extends SimpleJavaFileObject{
        private final ByteArrayOutputStream outputStream;

        public JavaByteObject(String name) {
            super(URI.create(String.format("bytes:///%s%s", name, name.replaceAll("\\.", "/"))), Kind.CLASS);
            this.outputStream = new ByteArrayOutputStream();
        }

        @Override
        public OutputStream openOutputStream() throws IOException {
            return outputStream;
        }

        public byte[] getBytes() {
            return outputStream.toByteArray();
        }
    }

    public static byte[] compile(String pluginName, String sourceCode) throws CompilationFailedException {
        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
        DiagnosticCollector diagnostics = new DiagnosticCollector<>();
        JavaByteObject javaByteObject = new JavaByteObject(pluginName);
        PluginFileManager pluginFileManager = new PluginFileManager(compiler.getStandardFileManager(diagnostics, null, null), javaByteObject);
        //"-source", Integer.toString(SourceVersion.latest().ordinal())
        List options = Collections.emptyList();
        JavaCompiler.CompilationTask compilationTask = compiler.getTask(
                null, pluginFileManager, diagnostics,
                options, null, () -> {
                    JavaFileObject javaFileObject = new JavaStringObject(pluginName, sourceCode);
                    return Collections.singletonList(javaFileObject).iterator();
                });
        boolean compilationSuccessful = compilationTask.call();
        if (!compilationSuccessful){
            String message = diagnostics.getDiagnostics().stream().map(new Function, String>() {
                @Override
                public String apply(Diagnostic diagnostic) {
                    return diagnostic.toString();
                }
            }).collect(Collectors.joining());
            throw new CompilationFailedException(String.format("Failed to compile class '%s':\n%s", pluginName, message), sourceCode);
        }
        return javaByteObject.getBytes();
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy