| /* |
| * 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); |
| } |
| } |
| } |