package io.takari.maven.plugins.compile.jdt;
import static io.takari.maven.testing.TestResources.create;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import javax.annotation.processing.FilerException;
import javax.lang.model.element.TypeElement;
import javax.tools.FileObject;
import javax.tools.StandardLocation;
import org.eclipse.jdt.internal.compiler.Compiler;
import org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies;
import org.eclipse.jdt.internal.compiler.ICompilerRequestor;
import org.eclipse.jdt.internal.compiler.IErrorHandlingPolicy;
import org.eclipse.jdt.internal.compiler.IProblemFactory;
import org.eclipse.jdt.internal.compiler.apt.util.EclipseFileManager;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
import org.eclipse.jdt.internal.core.builder.ProblemFactory;
import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import com.google.common.base.Charsets;
import com.google.common.io.CharStreams;
import io.takari.maven.plugins.compile.AbstractCompileMojo.Proc;
import io.takari.maven.plugins.compile.CompilerBuildContext;
import io.takari.maven.plugins.compile.jdt.classpath.Classpath;
import io.takari.maven.plugins.compile.jdt.classpath.ClasspathEntry;
import io.takari.maven.plugins.compile.jdt.classpath.ClasspathJar;
import io.takari.maven.plugins.compile.jdt.classpath.JavaInstallation;
import io.takari.maven.plugins.compile.jdt.classpath.MutableClasspathEntry;
public class FilerImplTest {
@Rule
public TemporaryFolder temp = new TemporaryFolder();
@Test
public void testGetResource_unsupportedLocation() throws Exception {
EclipseFileManager fileManager = new EclipseFileManager(null, Charsets.UTF_8);
FilerImpl filer = new FilerImpl(null /* context */, fileManager, null /* compiler */, null /* env */, Proc.procEX);
try {
filer.getResource(StandardLocation.SOURCE_PATH, "", "test");
Assert.fail();
} catch (IllegalArgumentException expected) {
// TODO check exception message
}
}
@Test
public void testGetResource_location_classpath() throws Exception {
EclipseFileManager fileManager = new EclipseFileManager(null, Charsets.UTF_8);
List<File> classpath = new ArrayList<>();
classpath.add(new File("src/test/projects/compile-jdt-proc/getresource-location-classpath/classes"));
classpath.add(new File("src/test/projects/compile-jdt-proc/getresource-location-classpath/dependency.zip"));
fileManager.setLocation(StandardLocation.CLASS_PATH, classpath);
FilerImpl filer = new FilerImpl(null /* context */, fileManager, null /* compiler */, null /* env */, Proc.procEX);
Assert.assertEquals("dir resource", toString(filer.getResource(StandardLocation.CLASS_PATH, "", "dirresource.txt")));
// Assert.assertEquals("jar resource", toString(filer.getResource(StandardLocation.CLASS_PATH, "", "jarresource.txt")));
Assert.assertEquals("pkg jar resource", toString(filer.getResource(StandardLocation.CLASS_PATH, "pkg", "jarresource.txt")));
}
private static String toString(FileObject file) throws IOException {
try (InputStream is = file.openInputStream()) {
return CharStreams.toString(new InputStreamReader(is, Charsets.UTF_8));
}
}
@Test
public void testRecreateSourceFile() throws Exception {
EclipseFileManager fileManager = new EclipseFileManager(null, Charsets.UTF_8);
File outputDir = temp.newFolder();
fileManager.setLocation(StandardLocation.SOURCE_OUTPUT, Collections.singleton(outputDir));
FilerImpl filer = new FilerImpl(null /* context */, fileManager, null /* compiler */, null /* env */, Proc.procEX);
filer.createSourceFile("test.Source");
try {
filer.createSourceFile("test.Source");
Assert.fail();
} catch (FilerException expected) {
// From Filer javadoc:
// @throws FilerException if the same pathname has already been
// created, the same type has already been created, or the name is
// not valid for a type
}
}
@Test
public void testRecreateResource() throws Exception {
EclipseFileManager fileManager = new EclipseFileManager(null, Charsets.UTF_8);
File outputDir = temp.newFolder();
fileManager.setLocation(StandardLocation.SOURCE_OUTPUT, Collections.singleton(outputDir));
FilerImpl filer = new FilerImpl(null /* context */, fileManager, null /* compiler */, null /* env */, Proc.procEX);
filer.createResource(StandardLocation.SOURCE_OUTPUT, "test", "resource.txt");
try {
filer.createResource(StandardLocation.SOURCE_OUTPUT, "test", "resource.txt");
Assert.fail();
} catch (FilerException expected) {
// From Filer javadoc:
// @throws FilerException if the same pathname has already been
// created
}
try {
create(outputDir, "test/resource.txt");
filer.getResource(StandardLocation.SOURCE_OUTPUT, "test", "resource.txt");
Assert.fail();
} catch (FilerException expected) {
// From Filer javadoc:
// @throws FilerException if the same pathname has already been
// opened for writing
}
}
@Test
public void testBinaryOriginatingElements() throws Exception {
// the point of this test is to assert Filer#createSourceFile does not puke when originatingElements are not sources
// originating source elements are used to cleanup generated outputs when corresponding sources change
// originating binary elements are not currently fully supported and are not tracked during incremental build
Classpath namingEnvironment = createClasspath();
IErrorHandlingPolicy errorHandlingPolicy = DefaultErrorHandlingPolicies.exitAfterAllProblems();
IProblemFactory problemFactory = ProblemFactory.getProblemFactory(Locale.getDefault());
CompilerOptions compilerOptions = new CompilerOptions();
ICompilerRequestor requestor = null;
Compiler compiler = new Compiler(namingEnvironment, errorHandlingPolicy, compilerOptions, requestor, problemFactory);
EclipseFileManager fileManager = new EclipseFileManager(null, Charsets.UTF_8);
File outputDir = temp.newFolder();
fileManager.setLocation(StandardLocation.SOURCE_OUTPUT, Collections.singleton(outputDir));
CompilerBuildContext context = null;
Map<String, String> processorOptions = null;
CompilerJdt incrementalCompiler = null;
ProcessingEnvImpl env = new ProcessingEnvImpl(context, fileManager, processorOptions, compiler, incrementalCompiler, Proc.procEX);
TypeElement typeElement = env.getElementUtils().getTypeElement("java.lang.Object");
FilerImpl filer = new FilerImpl(null /* context */, fileManager, null /* compiler */, null /* env */, Proc.procEX);
filer.createSourceFile("test.Source", typeElement);
}
@Test
public void testResourceDoesNotExist() throws Exception {
EclipseFileManager fileManager = new EclipseFileManager(null, Charsets.UTF_8);
File outputDir = temp.newFolder();
fileManager.setLocation(StandardLocation.SOURCE_OUTPUT, Collections.singleton(outputDir));
FilerImpl filer = new FilerImpl(null /* context */, fileManager, null /* compiler */, null /* env */, Proc.procEX);
try {
filer.getResource(StandardLocation.SOURCE_OUTPUT, "", "does-not-exist");
Assert.fail();
} catch (IOException expected) {
// from Filer javadoc: @throws IOException if the file cannot be opened
}
}
private Classpath createClasspath() throws IOException {
final List<ClasspathEntry> entries = new ArrayList<ClasspathEntry>();
final List<MutableClasspathEntry> mutableentries = new ArrayList<MutableClasspathEntry>();
for (File file : JavaInstallation.getDefault().getClasspath()) {
if (file.isFile()) {
try {
entries.add(ClasspathJar.create(file));
} catch (IOException e) {
// ignore, not a valid zip/jar
}
}
}
return new Classpath(entries, mutableentries);
}
}