/*
* Copyright 2014 Lukas Krejci
*
* 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 org.revapi.java.compilation;
import java.io.File;
import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.FileVisitor;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import javax.tools.JavaFileManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author Lukas Krejci
* @since 0.1
*/
public final class CompilationValve {
private static final Logger LOG = LoggerFactory.getLogger(CompilationValve.class);
private final Future<Boolean> compilationResult;
private final File dirToCleanup;
private final ProbingEnvironment environment;
private final JavaFileManager fileManager;
/* package private */ CompilationValve(Future<Boolean> results, File dirToCleanup, ProbingEnvironment env,
JavaFileManager fileManager) {
this.compilationResult = results;
this.dirToCleanup = dirToCleanup;
this.environment = env;
this.fileManager = fileManager;
}
ProbingEnvironment getEnvironment() {
return environment;
}
Future<Boolean> getCompilationResult() {
return compilationResult;
}
public void removeCompiledResults() {
if (LOG.isTraceEnabled()) {
LOG.trace("Releasing compilation environment for " + environment.getApi());
}
environment.getCompilationTeardownLatch().countDown();
if (!compilationResult.isDone()) {
try {
compilationResult.get();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
//but clean up below anyway before returning
} catch (ExecutionException e) {
throw new IllegalStateException("Exception thrown while waiting for compilation to end for clean up",
e);
}
}
try {
fileManager.close();
} catch (IOException e) {
throw new IllegalStateException("Failed to close the file manager used by the compiler.", e);
}
try {
Files.walkFileTree(dirToCleanup.toPath(), new FileVisitor<Path>() {
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
Files.delete(file);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
if (dirToCleanup.toPath().equals(file)) {
return FileVisitResult.CONTINUE;
}
throw new IOException("Failed to delete file '" + file + "'.", exc);
}
@Override
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
Files.delete(dir);
return FileVisitResult.CONTINUE;
}
});
} catch (IOException e) {
throw new IllegalStateException("Failed to remove compiled results", e);
}
}
}