/******************************************************************************* * Copyright 2013 Ivan Shubin http://mindengine.net * * 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. ******************************************************************************/ package net.mindengine.blogix.compiler; import java.io.File; import java.net.URL; import java.net.URLClassLoader; import java.util.Arrays; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Locale; import javax.tools.Diagnostic; import javax.tools.DiagnosticCollector; import javax.tools.JavaCompiler; import javax.tools.JavaCompiler.CompilationTask; import javax.tools.JavaFileObject; import javax.tools.StandardJavaFileManager; import javax.tools.ToolProvider; public class BlogixCompiler { private File classesDir; private File sourceDir; public void loadClassesFromCompiledDirectory() throws Exception { new URLClassLoader(new URL[]{classesDir.toURI().toURL()}); } public void compile() throws CompilationError { JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>(); StandardJavaFileManager fileManager = compiler.getStandardFileManager(diagnostics, Locale.getDefault(), null); List<JavaFileObject> javaObjects = scanRecursivelyForJavaObjects(sourceDir, fileManager); if (javaObjects.size() == 0) { throw new CompilationError("There are no source files to compile in " + sourceDir.getAbsolutePath()); } String[] compileOptions = new String[]{"-d", classesDir.getAbsolutePath()} ; Iterable<String> compilationOptions = Arrays.asList(compileOptions); CompilationTask compilerTask = compiler.getTask(null, fileManager, diagnostics, compilationOptions, null, javaObjects) ; if (!compilerTask.call()) { for (Diagnostic<?> diagnostic : diagnostics.getDiagnostics()) { System.err.format("Error on line %d in %s", diagnostic.getLineNumber(), diagnostic); } throw new CompilationError("Could not compile project"); } } private List<JavaFileObject> scanRecursivelyForJavaObjects(File dir, StandardJavaFileManager fileManager) { List<JavaFileObject> javaObjects = new LinkedList<JavaFileObject>(); File[] files = dir.listFiles(); for (File file : files) { if (file.isDirectory()) { javaObjects.addAll(scanRecursivelyForJavaObjects(file, fileManager)); } else if (file.isFile() && file.getName().toLowerCase().endsWith(".java")) { javaObjects.add(readJavaObject(file, fileManager)); } } return javaObjects; } private JavaFileObject readJavaObject(File file, StandardJavaFileManager fileManager) { Iterable<? extends JavaFileObject> javaFileObjects = fileManager.getJavaFileObjects(file); Iterator<? extends JavaFileObject> it = javaFileObjects.iterator(); if (it.hasNext()) { return it.next(); } throw new RuntimeException("Could not load " + file.getAbsolutePath() + " java file object"); } public File getClassesDir() { return classesDir; } public void setClassesDir(File classesDir) { this.classesDir = classesDir; } public File getSourceDir() { return sourceDir; } public void setSourceDir(File sourceDir) { this.sourceDir = sourceDir; } }