org.apache.geode.test.compiler.JavaCompiler.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.geode.test.compiler.JavaCompiler.java

Source

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
 * agreements. See the NOTICE file distributed with this work for additional information regarding
 * copyright ownership. The ASF licenses this file to You 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.
 */
package org.apache.geode.test.compiler;

import static java.util.stream.Collectors.toList;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;

import javax.tools.ToolProvider;

import com.google.common.base.Charsets;
import com.google.common.io.Files;
import org.apache.commons.io.FileUtils;

public class JavaCompiler {
    private File tempDir;
    private String classpath;

    public JavaCompiler() {
        this.tempDir = Files.createTempDir();
        tempDir.deleteOnExit();
        this.classpath = System.getProperty("java.class.path");
    }

    public void addToClasspath(File jarFile) {
        classpath += File.pathSeparator + jarFile.getAbsolutePath();
    }

    public List<CompiledSourceCode> compile(File... sourceFiles) throws IOException {
        String[] sourceFileContents = Arrays.stream(sourceFiles).map(this::readFileToString).toArray(String[]::new);

        return compile(sourceFileContents);
    }

    public List<CompiledSourceCode> compile(String... sourceFileContents) throws IOException {
        UncompiledSourceCode[] uncompiledSourceCodes = Arrays.stream(sourceFileContents)
                .map(UncompiledSourceCode::fromSourceCode).toArray(UncompiledSourceCode[]::new);

        return compile(uncompiledSourceCodes);
    }

    public List<CompiledSourceCode> compile(UncompiledSourceCode... uncompiledSources) throws IOException {
        File temporarySourcesDirectory = createSubdirectory(tempDir, "sources");
        File temporaryClassesDirectory = createSubdirectory(tempDir, "classes");

        List<String> options = Stream.of("-d", temporaryClassesDirectory.getAbsolutePath(), "-classpath", classpath)
                .collect(toList());

        try {
            for (UncompiledSourceCode sourceCode : uncompiledSources) {
                File sourceFile = new File(temporarySourcesDirectory, sourceCode.simpleClassName + ".java");
                FileUtils.writeStringToFile(sourceFile, sourceCode.sourceCode, Charsets.UTF_8);
                options.add(sourceFile.getAbsolutePath());
            }

            int exitCode = ToolProvider.getSystemJavaCompiler().run(System.in, System.out, System.err,
                    options.toArray(new String[] {}));

            if (exitCode != 0) {
                throw new RuntimeException("Unable to compile the given source code. See System.err for details.");
            }

            List<CompiledSourceCode> compiledSourceCodes = new ArrayList<>();
            addCompiledClasses(compiledSourceCodes, "", temporaryClassesDirectory);
            return compiledSourceCodes;
        } finally {
            FileUtils.deleteDirectory(temporaryClassesDirectory);
        }
    }

    private static void addCompiledClasses(List<CompiledSourceCode> ret, String pkgName, File dir)
            throws IOException {
        for (File file : dir.listFiles()) {
            String filename = file.getName();

            if (file.isDirectory()) {
                String qname = pkgName + filename + ".";
                addCompiledClasses(ret, qname, file);
            } else if (filename.endsWith(".class")) {
                String qname = pkgName + filename.substring(0, filename.length() - 6);
                ret.add(new CompiledSourceCode(qname, FileUtils.readFileToByteArray(file)));
            } else {
                System.err.println("Unexpected file : " + file.getAbsolutePath());
            }
        }
    }

    private File createSubdirectory(File parent, String directoryName) {
        File subdirectory = parent.toPath().resolve(directoryName).toFile();
        if (!subdirectory.exists()) {
            subdirectory.mkdirs();
        }

        if (!subdirectory.exists() || !subdirectory.isDirectory()) {
            throw new IllegalArgumentException("Invalid directory" + subdirectory.getAbsolutePath());
        }

        return subdirectory;
    }

    private String readFileToString(File file) {
        try {
            return FileUtils.readFileToString(file, Charsets.UTF_8);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}