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

generator.apt.SimplifiedAPTRunner Maven / Gradle / Ivy

There is a newer version: 0.4.1
Show newest version
package generator.apt;

import lombok.Value;
import lombok.val;

import java.io.*;
import java.net.URI;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.util.*;
import java.util.function.Consumer;
import javax.annotation.processing.Processor;
import javax.tools.*;
import javax.tools.JavaCompiler.CompilationTask;

import static java.util.Arrays.asList;

public class SimplifiedAPTRunner {

	final DiagnosticCollector diagnostics = new DiagnosticCollector<>();
	final List compilerOptionsForProcOnly = asList( "-proc:only" );

	final JavaCompiler compiler;
	final StandardJavaFileManager fileManager;
	final Config config;

	public SimplifiedAPTRunner(Config config, JavaCompiler compiler ) {
		this.config = config;
		this.compiler = compiler;
		this.fileManager = createFileManager();
	}

	public APTResult run( Processor processor, JavaFileObject... compilationUnits ) {
		final List compilationUnitsAsList = asList( compilationUnits );
		return run( compilationUnitsAsList, Collections.singletonList(processor));
	}

	public APTResult run(Iterable compilationUnits, Iterable processors) {
		final CompilationTask task = compiler.getTask( null, fileManager, diagnostics, compilerOptionsForProcOnly, null, compilationUnits );
		task.setProcessors( processors );
		final boolean success = task.call();
		final List> generatedDiagnostics = diagnostics.getDiagnostics();
		return new APTResult( success, generatedDiagnostics );
	}

	private StandardJavaFileManager createFileManager() {
		try {
			ensureThatConfigDirectoriesExists( config );
			final StandardJavaFileManager fileManager = compiler.getStandardFileManager( diagnostics, null, null );
			if ( config.classPath != null )
				fileManager.setLocation( StandardLocation.CLASS_PATH, config.classPath );
			fileManager.setLocation( StandardLocation.CLASS_OUTPUT, config.classOutputDir );
			fileManager.setLocation( StandardLocation.SOURCE_PATH, config.sourceDir );
			fileManager.setLocation( StandardLocation.SOURCE_OUTPUT, config.outputDir );
			return fileManager;
		} catch ( final IOException e ) {
			throw new IllegalStateException( e );
		}
	}

	static void ensureThatConfigDirectoriesExists( Config config ) {
		ensureThatConfigDirectoryExists( config.sourceDir, false );
		ensureThatConfigDirectoryExists( config.outputDir, true );
		ensureThatConfigDirectoryExists( config.classOutputDir, true );
	}

	static void ensureThatConfigDirectoryExists( List dirs, boolean forceCreate ) {
		for ( final File dir : dirs )
			ensureThatConfigDirectoryExists( dir, forceCreate );
	}

	static void ensureThatConfigDirectoryExists( File dir, boolean forceCreate ) {
		if ( !dir.exists() )
			if ( !forceCreate || !dir.mkdirs() )
				throw new IllegalStateException( "Directory does not exists (or could not be created): " + dir );
	}

	static public class Config {

		public List sourceDir = asList( file( "source" ), file( "src/main/java" ) );
		public List outputDir = asList( file( "target" ), file( "output" ) );
		public List classOutputDir = outputDir;
		public List classPath;

		private static File file( String path ) {
			return new File( path );
		}
	}

	@Value
	static public class APTResult {

		final boolean success;
		final List> diagnostics;

		public void printErrorsIfAny(){
			printErrorsIfAny(System.out::println);
		}

		public void printErrorsIfAny( Consumer> writer ) {
            for (final Diagnostic diagnostic : getDiagnostics())
                writer.accept(diagnostic);
		}

		public void failInCaseOfError() {
            failInCaseOfError(d -> {
				System.out.println(d);
				if (d.getKind().equals(Diagnostic.Kind.ERROR)) {
					throw new IllegalStateException(d.getMessage(Locale.getDefault()));
				}
			});
		}

		public void failInCaseOfError( Consumer> writer ) {
            for (final Diagnostic diagnostic : getDiagnostics())
                writer.accept(diagnostic);
		}
	}

	static public class LocalJavaSource extends SimpleJavaFileObject {

		final File file;

		public LocalJavaSource(File file) {
			super(file.toURI(), Kind.SOURCE);
			this.file = file;
		}

		@Override
		public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
			val bytes = Files.readAllBytes( file.toPath() );
			return new String( bytes, Charset.defaultCharset() );
		}
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy