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

com.ethlo.qjc.java.JavaCompiler Maven / Gradle / Ivy

There is a newer version: 1.1.1
Show newest version
package com.ethlo.qjc.java;/*-
 * #%L
 * jc
 * %%
 * Copyright (C) 2018 - 2019 Morten Haraldsen (ethlo)
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */

import java.io.File;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import javax.tools.Diagnostic;
import javax.tools.DiagnosticCollector;
import javax.tools.JavaFileManager;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.ethlo.qjc.CompilationException;
import com.ethlo.qjc.Compiler;
import com.ethlo.qjc.CompilerUtil;
import com.ethlo.qjc.StringUtils;

public class JavaCompiler implements Compiler
{
    private static final String JAVA_EXTENSION = "java";

    private static final Logger logger = LoggerFactory.getLogger(JavaCompiler.class);

    private final ClassLoader classLoader;

    public JavaCompiler(ClassLoader classLoader)
    {
        this.classLoader = classLoader;
    }

    private static List buildCompilerOptions(final Collection sourcePath, final Path classesDirectory)
    {
        final Map compilerOpts = new LinkedHashMap<>();

        compilerOpts.put("d", classesDirectory.toAbsolutePath().toString());

        compilerOpts.put("sourcepath", StringUtils.collectionToDelimitedString(sourcePath, File.separator));

        final List opts = new ArrayList<>(compilerOpts.size() * 2);
        for (Map.Entry compilerOption : compilerOpts.entrySet())
        {
            opts.add("-" + compilerOption.getKey());
            String value = compilerOption.getValue();
            if (!StringUtils.isEmpty(value))
            {
                opts.add(value);
            }
        }
        return opts;
    }

    @Override
    public void compile(final Set sourcePaths, Path classesDirectory)
    {
        final javax.tools.JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
        if (compiler == null)
        {
            throw new IllegalStateException("You need to run build with JDK or have tools.jar on the classpath");
        }

        try (final StandardJavaFileManager standardFileManager = compiler.getStandardFileManager(null, Locale.getDefault(), StandardCharsets.UTF_8))
        {
            final JavaFileManager fileManager = new CustomClassloaderJavaFileManager(classLoader, standardFileManager);
            final List sourceFiles = CompilerUtil.findSourceFiles(JAVA_EXTENSION, sourcePaths.toArray(new Path[0])).stream().map(Path::toFile).collect(Collectors.toList());
            if (sourceFiles.isEmpty())
            {
                logger.debug("No Java files found in {}", StringUtils.collectionToCommaDelimitedString(sourcePaths));
                return;
            }
            logger.info("Found {} java files", sourceFiles.size());

            logger.debug("Compiling: {}", StringUtils.collectionToCommaDelimitedString(sourceFiles));

            final Iterable compilationUnits = standardFileManager.getJavaFileObjectsFromFiles(sourceFiles);

            List compilerOptions = buildCompilerOptions(sourcePaths, classesDirectory);
            logger.debug("Compiler options: {}", StringUtils.collectionToCommaDelimitedString(compilerOptions));

            final DiagnosticCollector diagnostics = new DiagnosticCollector<>();
            final javax.tools.JavaCompiler.CompilationTask task = compiler.getTask(null, fileManager, diagnostics, compilerOptions, null, compilationUnits);
            final Boolean retVal = task.call();
            final StringBuilder s = new StringBuilder();
            for (Diagnostic diagnostic : diagnostics.getDiagnostics())
            {
                s.append("\n").append(diagnostic);
            }

            if (!retVal)
            {
                throw new CompilationException(s.toString());
            }
        }
        catch (IOException e)
        {
            throw new UncheckedIOException(e);
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy