Finishes testing, cleanup, adds license
This commit is contained in:
@@ -19,12 +19,16 @@ import org.apache.maven.plugins.annotations.Parameter;
|
||||
import org.apache.maven.project.MavenProject;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.CompletionException;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
/**
|
||||
* Main mojo for FXML compiler
|
||||
*/
|
||||
@@ -61,34 +65,66 @@ public class FXMLCompilerMojo extends AbstractMojo {
|
||||
@Parameter(property = "parallelism", defaultValue = "1", required = true)
|
||||
private int parallelism;
|
||||
|
||||
private final Compiler compiler;
|
||||
private final CompilationInfoProvider.Factory compilationInfoProviderFactory;
|
||||
private final ControllerProvider controllerProvider;
|
||||
private final FXMLProvider.Factory fxmlProviderFactory;
|
||||
|
||||
/**
|
||||
* Instantiates a new MOJO with the given helpers (used for testing)
|
||||
*
|
||||
* @param compiler The compiler
|
||||
* @param compilationInfoProviderFactory The compilation info provider
|
||||
* @param controllerProvider The controller provider
|
||||
* @param fxmlProviderFactory The FXML provider factory
|
||||
* @throws NullPointerException If any parameter is null
|
||||
*/
|
||||
FXMLCompilerMojo(final Compiler compiler, final CompilationInfoProvider.Factory compilationInfoProviderFactory,
|
||||
final ControllerProvider controllerProvider, final FXMLProvider.Factory fxmlProviderFactory) {
|
||||
this.compiler = requireNonNull(compiler);
|
||||
this.compilationInfoProviderFactory = requireNonNull(compilationInfoProviderFactory);
|
||||
this.controllerProvider = requireNonNull(controllerProvider);
|
||||
this.fxmlProviderFactory = requireNonNull(fxmlProviderFactory);
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates a new MOJO
|
||||
*/
|
||||
FXMLCompilerMojo() {
|
||||
this(new Compiler(), CompilationInfoProvider::new, new ControllerProvider(), FXMLProvider::new);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() throws MojoExecutionException {
|
||||
if (fieldInjectionType == ControllerFieldInjectionType.FACTORY && controllerInjectionType != ControllerInjectionType.FACTORY) {
|
||||
getLog().warn("Field injection is set to FACTORY : Forcing controller injection to FACTORY");
|
||||
controllerInjectionType = ControllerInjectionType.FACTORY;
|
||||
}
|
||||
final var fxmls = FXMLProvider.getFXMLs(project);
|
||||
if (parallelism < 1) {
|
||||
parallelism = Runtime.getRuntime().availableProcessors();
|
||||
}
|
||||
if (parallelism > 1) {
|
||||
try (final var executor = Executors.newFixedThreadPool(parallelism)) {
|
||||
final var controllerMapping = createControllerMapping(fxmls, executor);
|
||||
final var compilationInfoMapping = createCompilationInfoMapping(fxmls, controllerMapping, executor);
|
||||
compile(compilationInfoMapping, executor);
|
||||
try {
|
||||
if (fieldInjectionType == ControllerFieldInjectionType.FACTORY && controllerInjectionType != ControllerInjectionType.FACTORY) {
|
||||
getLog().warn("Field injection is set to FACTORY : Forcing controller injection to FACTORY");
|
||||
controllerInjectionType = ControllerInjectionType.FACTORY;
|
||||
}
|
||||
} else {
|
||||
final var controllerMapping = createControllerMapping(fxmls);
|
||||
final var compilationInfoMapping = createCompilationInfoMapping(fxmls, controllerMapping);
|
||||
compile(compilationInfoMapping);
|
||||
final var fxmls = fxmlProviderFactory.create(project).getFXMLs();
|
||||
if (parallelism < 1) {
|
||||
parallelism = Runtime.getRuntime().availableProcessors();
|
||||
}
|
||||
if (parallelism > 1) {
|
||||
try (final var executor = Executors.newFixedThreadPool(parallelism)) {
|
||||
final var controllerMapping = createControllerMapping(fxmls, executor);
|
||||
final var compilationInfoMapping = createCompilationInfoMapping(fxmls, controllerMapping, executor);
|
||||
compile(compilationInfoMapping, executor);
|
||||
}
|
||||
} else {
|
||||
final var controllerMapping = createControllerMapping(fxmls);
|
||||
final var compilationInfoMapping = createCompilationInfoMapping(fxmls, controllerMapping);
|
||||
compile(compilationInfoMapping);
|
||||
}
|
||||
} catch (final RuntimeException e) {
|
||||
throw new MojoExecutionException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static Map<Path, String> createControllerMapping(final Map<? extends Path, ? extends Path> fxmls) throws MojoExecutionException {
|
||||
private Map<Path, String> createControllerMapping(final Map<? extends Path, ? extends Path> fxmls) throws MojoExecutionException {
|
||||
final var mapping = new HashMap<Path, String>();
|
||||
for (final var fxml : fxmls.keySet()) {
|
||||
mapping.put(fxml, ControllerProvider.getController(fxml));
|
||||
mapping.put(fxml, controllerProvider.getController(fxml));
|
||||
}
|
||||
return mapping;
|
||||
}
|
||||
@@ -96,8 +132,9 @@ public class FXMLCompilerMojo extends AbstractMojo {
|
||||
private Map<Path, CompilationInfo> createCompilationInfoMapping(final Map<? extends Path, ? extends Path> fxmls,
|
||||
final Map<? extends Path, String> controllerMapping) throws MojoExecutionException {
|
||||
final var mapping = new HashMap<Path, CompilationInfo>();
|
||||
final var compilationInfoProvider = compilationInfoProviderFactory.create(project, outputDirectory);
|
||||
for (final var entry : fxmls.entrySet()) {
|
||||
final var info = CompilationInfoProvider.getCompilationInfo(entry.getValue(), entry.getKey(), controllerMapping, outputDirectory, project);
|
||||
final var info = compilationInfoProvider.getCompilationInfo(entry.getValue(), entry.getKey(), controllerMapping);
|
||||
mapping.put(entry.getKey(), info);
|
||||
}
|
||||
return mapping;
|
||||
@@ -106,51 +143,75 @@ public class FXMLCompilerMojo extends AbstractMojo {
|
||||
private void compile(final Map<Path, CompilationInfo> mapping) throws MojoExecutionException {
|
||||
final var parameters = new GenerationParametersImpl(new GenerationCompatibilityImpl(targetVersion), useImageInputStreamConstructor, resourceMap,
|
||||
controllerInjectionType, fieldInjectionType, methodInjectionType, resourceInjectionType);
|
||||
Compiler.compile(mapping, parameters);
|
||||
compiler.compile(mapping, parameters);
|
||||
project.addCompileSourceRoot(outputDirectory.toAbsolutePath().toString());
|
||||
}
|
||||
|
||||
private static Map<Path, String> createControllerMapping(final Map<? extends Path, ? extends Path> fxmls,
|
||||
final ExecutorService executor) {
|
||||
final var mapping = new ConcurrentHashMap<Path, String>();
|
||||
private Map<Path, String> createControllerMapping(final Map<? extends Path, ? extends Path> fxmls,
|
||||
final Executor executor) {
|
||||
final var futures = new ArrayList<CompletableFuture<ControllerMapping>>(fxmls.size());
|
||||
for (final var fxml : fxmls.keySet()) {
|
||||
executor.submit(() -> {
|
||||
futures.add(CompletableFuture.supplyAsync(() -> {
|
||||
try {
|
||||
mapping.put(fxml, ControllerProvider.getController(fxml));
|
||||
final var controller = controllerProvider.getController(fxml);
|
||||
return new ControllerMapping(fxml, controller);
|
||||
} catch (final MojoExecutionException e) {
|
||||
throw new RuntimeException(e);
|
||||
throw new CompletionException(e);
|
||||
}
|
||||
});
|
||||
}, executor));
|
||||
}
|
||||
final var mapping = new HashMap<Path, String>();
|
||||
futures.forEach(c -> {
|
||||
final var joined = c.join();
|
||||
mapping.put(joined.fxml(), joined.controller());
|
||||
});
|
||||
return mapping;
|
||||
}
|
||||
|
||||
private record ControllerMapping(Path fxml, String controller) {
|
||||
}
|
||||
|
||||
private Map<Path, CompilationInfo> createCompilationInfoMapping(final Map<? extends Path, ? extends Path> fxmls,
|
||||
final Map<? extends Path, String> controllerMapping, final ExecutorService executor) {
|
||||
final var mapping = new ConcurrentHashMap<Path, CompilationInfo>();
|
||||
final Map<? extends Path, String> controllerMapping,
|
||||
final Executor executor) {
|
||||
final var compilationInfoProvider = compilationInfoProviderFactory.create(project, outputDirectory);
|
||||
final var futures = new ArrayList<CompletableFuture<CompilationInfoMapping>>(fxmls.size());
|
||||
for (final var entry : fxmls.entrySet()) {
|
||||
executor.submit(() -> {
|
||||
futures.add(CompletableFuture.supplyAsync(() -> {
|
||||
try {
|
||||
final var info = CompilationInfoProvider.getCompilationInfo(entry.getValue(), entry.getKey(), controllerMapping, outputDirectory, project);
|
||||
mapping.put(entry.getKey(), info);
|
||||
final var info = compilationInfoProvider.getCompilationInfo(entry.getValue(), entry.getKey(),
|
||||
controllerMapping);
|
||||
return new CompilationInfoMapping(entry.getKey(), info);
|
||||
} catch (final MojoExecutionException e) {
|
||||
throw new RuntimeException(e);
|
||||
throw new CompletionException(e);
|
||||
}
|
||||
});
|
||||
}, executor));
|
||||
}
|
||||
final var mapping = new HashMap<Path, CompilationInfo>();
|
||||
futures.forEach(c -> {
|
||||
final var joined = c.join();
|
||||
mapping.put(joined.fxml(), joined.info());
|
||||
});
|
||||
return mapping;
|
||||
}
|
||||
|
||||
private void compile(final Map<Path, CompilationInfo> mapping, final ExecutorService executor) throws MojoExecutionException {
|
||||
final var parameters = new GenerationParametersImpl(new GenerationCompatibilityImpl(targetVersion), useImageInputStreamConstructor, resourceMap,
|
||||
controllerInjectionType, fieldInjectionType, methodInjectionType, resourceInjectionType);
|
||||
mapping.forEach((p, i) -> executor.submit(() -> {
|
||||
private record CompilationInfoMapping(Path fxml, CompilationInfo info) {
|
||||
|
||||
}
|
||||
|
||||
private void compile(final Map<Path, CompilationInfo> mapping, final Executor executor) {
|
||||
final var parameters = new GenerationParametersImpl(new GenerationCompatibilityImpl(targetVersion),
|
||||
useImageInputStreamConstructor, resourceMap, controllerInjectionType, fieldInjectionType,
|
||||
methodInjectionType, resourceInjectionType);
|
||||
final var futures = new ArrayList<CompletableFuture<Void>>(mapping.size());
|
||||
mapping.forEach((p, i) -> futures.add(CompletableFuture.runAsync(() -> {
|
||||
try {
|
||||
Compiler.compile(p, i, mapping, parameters);
|
||||
compiler.compile(p, i, mapping, parameters);
|
||||
} catch (final MojoExecutionException e) {
|
||||
throw new RuntimeException(e);
|
||||
throw new CompletionException(e);
|
||||
}
|
||||
}));
|
||||
}, executor)));
|
||||
futures.forEach(CompletableFuture::join);
|
||||
project.addCompileSourceRoot(outputDirectory.toAbsolutePath().toString());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,10 +24,25 @@ public record CompilationInfo(Path inputFile, Path outputFile, String outputClas
|
||||
String controllerClass, Set<FieldInfo> injectedFields, Set<String> injectedMethods,
|
||||
Map<String, Path> includes, boolean requiresResourceBundle) {
|
||||
|
||||
/**
|
||||
* Instantiates a new info
|
||||
*
|
||||
* @param inputFile The input file
|
||||
* @param outputFile The output file
|
||||
* @param outputClass The output class name
|
||||
* @param controllerFile The controller file
|
||||
* @param controllerClass The controller class name
|
||||
* @param injectedFields The injected fields
|
||||
* @param injectedMethods The injected methods
|
||||
* @param includes The FXML inclusions
|
||||
* @param requiresResourceBundle True if the file requires a resource bundle
|
||||
* @throws NullPointerException if any parameter is null
|
||||
*/
|
||||
public CompilationInfo {
|
||||
Objects.requireNonNull(inputFile);
|
||||
Objects.requireNonNull(outputFile);
|
||||
Objects.requireNonNull(outputClass);
|
||||
Objects.requireNonNull(controllerClass);
|
||||
Objects.requireNonNull(controllerFile);
|
||||
injectedFields = Set.copyOf(injectedFields);
|
||||
injectedMethods = Set.copyOf(injectedMethods);
|
||||
|
||||
@@ -15,10 +15,11 @@ import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
/**
|
||||
* Helper class for {@link FXMLCompilerMojo} to provides {@link CompilationInfo}
|
||||
*/
|
||||
@@ -28,22 +29,31 @@ public final class CompilationInfoProvider {
|
||||
private static final DocumentBuilderFactory DOCUMENT_BUILDER_FACTORY = DocumentBuilderFactory.newInstance();
|
||||
private static final Pattern START_DOT_PATTERN = Pattern.compile("^\\.");
|
||||
|
||||
private CompilationInfoProvider() {
|
||||
private final MavenProject project;
|
||||
private final Path outputDirectory;
|
||||
|
||||
/**
|
||||
* Instantiates the provider
|
||||
*
|
||||
* @param project The Maven project
|
||||
* @param outputDirectory The output directory
|
||||
* @throws NullPointerException If any parameter is null
|
||||
*/
|
||||
public CompilationInfoProvider(final MavenProject project, final Path outputDirectory) {
|
||||
this.project = requireNonNull(project);
|
||||
this.outputDirectory = requireNonNull(outputDirectory);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the compilation info for the given input
|
||||
*
|
||||
* @param root The root path
|
||||
* @param root The root path for the input
|
||||
* @param inputPath The input path
|
||||
* @param controllerMapping The controller mapping
|
||||
* @param outputDirectory The output directory
|
||||
* @param project The Maven project
|
||||
* @return The compilation info
|
||||
* @throws MojoExecutionException If an error occurs
|
||||
*/
|
||||
public static CompilationInfo getCompilationInfo(final Path root, final Path inputPath, final Map<? extends Path, String> controllerMapping,
|
||||
final Path outputDirectory, final MavenProject project) throws MojoExecutionException {
|
||||
public CompilationInfo getCompilationInfo(final Path root, final Path inputPath, final Map<? extends Path, String> controllerMapping) throws MojoExecutionException {
|
||||
logger.info("Parsing {}", inputPath);
|
||||
try {
|
||||
final var documentBuilder = DOCUMENT_BUILDER_FACTORY.newDocumentBuilder();
|
||||
@@ -55,7 +65,7 @@ public final class CompilationInfoProvider {
|
||||
final var outputFilename = getOutputFilename(inputFilename);
|
||||
final var outputClass = getOutputClass(root, inputPath, outputFilename);
|
||||
final var replacedPrefixPath = inputPath.toString().replace(root.toString(), outputDirectory.toString());
|
||||
final var targetPath = Paths.get(replacedPrefixPath.replace(inputFilename, outputFilename));
|
||||
final var targetPath = Path.of(replacedPrefixPath.replace(inputFilename, outputFilename));
|
||||
builder.outputFile(targetPath);
|
||||
builder.outputClass(outputClass);
|
||||
handleNode(document.getDocumentElement(), builder, controllerMapping, project);
|
||||
@@ -170,7 +180,7 @@ public final class CompilationInfoProvider {
|
||||
private static void handleController(final String controllerClass, final CompilationInfo.Builder builder, final MavenProject project) throws MojoExecutionException {
|
||||
final var subPath = controllerClass.replace(".", "/") + ".java";
|
||||
final var path = project.getCompileSourceRoots().stream()
|
||||
.map(s -> Paths.get(s).resolve(subPath))
|
||||
.map(s -> Path.of(s).resolve(subPath))
|
||||
.filter(Files::exists)
|
||||
.findFirst()
|
||||
.orElseThrow(() -> new MojoExecutionException("Cannot find controller " + controllerClass));
|
||||
@@ -178,4 +188,20 @@ public final class CompilationInfoProvider {
|
||||
builder.controllerFile(path);
|
||||
builder.controllerClass(controllerClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory for {@link CompilationInfoProvider}
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface Factory {
|
||||
|
||||
/**
|
||||
* Creates a new compilation info provider
|
||||
*
|
||||
* @param project The Maven project
|
||||
* @param outputDirectory The output directory
|
||||
* @return The compilation info provider
|
||||
*/
|
||||
CompilationInfoProvider create(final MavenProject project, final Path outputDirectory);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Creates compiled Java code
|
||||
@@ -24,10 +25,26 @@ public final class Compiler {
|
||||
|
||||
private static final Logger logger = LogManager.getLogger(Compiler.class);
|
||||
|
||||
private static final FXMLParser PARSER = new DOMFXMLParser();
|
||||
private static final Generator GENERATOR = new GeneratorImpl();
|
||||
private final FXMLParser parser;
|
||||
private final Generator generator;
|
||||
|
||||
private Compiler() {
|
||||
/**
|
||||
* Instantiates a new compiler
|
||||
*
|
||||
* @param parser The parser to use
|
||||
* @param generator The generator to use
|
||||
* @throws NullPointerException If any parameter is null
|
||||
*/
|
||||
Compiler(final FXMLParser parser, final Generator generator) {
|
||||
this.parser = Objects.requireNonNull(parser);
|
||||
this.generator = Objects.requireNonNull(generator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates a new compiler
|
||||
*/
|
||||
public Compiler() {
|
||||
this(new DOMFXMLParser(), new GeneratorImpl());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -37,22 +54,31 @@ public final class Compiler {
|
||||
* @param parameters The generation parameters
|
||||
* @throws MojoExecutionException If an error occurs
|
||||
*/
|
||||
public static void compile(final Map<Path, CompilationInfo> mapping, final GenerationParameters parameters) throws MojoExecutionException {
|
||||
public void compile(final Map<Path, CompilationInfo> mapping, final GenerationParameters parameters) throws MojoExecutionException {
|
||||
for (final var entry : mapping.entrySet()) {
|
||||
compile(entry.getKey(), entry.getValue(), mapping, parameters);
|
||||
}
|
||||
}
|
||||
|
||||
public static void compile(final Path inputPath, final CompilationInfo info, final Map<Path, CompilationInfo> mapping, final GenerationParameters parameters) throws MojoExecutionException {
|
||||
/**
|
||||
* Compiles the given file
|
||||
*
|
||||
* @param inputPath The input path
|
||||
* @param info The compilation info
|
||||
* @param mapping The mapping of file to compile to compilation info
|
||||
* @param parameters The generation parameters
|
||||
* @throws MojoExecutionException If an error occurs
|
||||
*/
|
||||
public void compile(final Path inputPath, final CompilationInfo info, final Map<Path, CompilationInfo> mapping, final GenerationParameters parameters) throws MojoExecutionException {
|
||||
try {
|
||||
logger.info("Parsing {} with {}", inputPath, PARSER.getClass().getSimpleName());
|
||||
final var root = PARSER.parse(inputPath);
|
||||
logger.info("Parsing {} with {}", inputPath, parser.getClass().getSimpleName());
|
||||
final var root = parser.parse(inputPath);
|
||||
final var controllerInfo = ControllerInfoProvider.getControllerInfo(info);
|
||||
final var output = info.outputFile();
|
||||
final var sourceInfo = SourceInfoProvider.getSourceInfo(info, mapping);
|
||||
final var request = new GenerationRequestImpl(parameters, controllerInfo, sourceInfo, root, info.outputClass());
|
||||
logger.info("Compiling {}", inputPath);
|
||||
final var content = GENERATOR.generate(request);
|
||||
final var content = generator.generate(request);
|
||||
final var outputDir = output.getParent();
|
||||
Files.createDirectories(outputDir);
|
||||
Files.writeString(output, content);
|
||||
|
||||
@@ -13,19 +13,21 @@ import java.nio.file.Path;
|
||||
* Extracts controller class from FXMLs
|
||||
*/
|
||||
public final class ControllerProvider {
|
||||
private static final DocumentBuilder DOCUMENT_BUILDER;
|
||||
|
||||
static {
|
||||
private final DocumentBuilder documentBuilder;
|
||||
|
||||
/**
|
||||
* Instantiates a new provider
|
||||
*/
|
||||
public ControllerProvider() {
|
||||
final var factory = DocumentBuilderFactory.newInstance();
|
||||
try {
|
||||
DOCUMENT_BUILDER = DocumentBuilderFactory.newInstance().newDocumentBuilder();
|
||||
this.documentBuilder = factory.newDocumentBuilder();
|
||||
} catch (final ParserConfigurationException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private ControllerProvider() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the controller class for the given FXML
|
||||
*
|
||||
@@ -33,9 +35,9 @@ public final class ControllerProvider {
|
||||
* @return The controller class
|
||||
* @throws MojoExecutionException If an error occurs
|
||||
*/
|
||||
public static String getController(final Path fxml) throws MojoExecutionException {
|
||||
public String getController(final Path fxml) throws MojoExecutionException {
|
||||
try {
|
||||
final var document = DOCUMENT_BUILDER.parse(fxml.toFile());
|
||||
final var document = documentBuilder.parse(fxml.toFile());
|
||||
document.getDocumentElement().normalize();
|
||||
|
||||
final var controller = document.getDocumentElement().getAttribute("fx:controller");
|
||||
|
||||
@@ -9,9 +9,9 @@ import java.io.IOException;
|
||||
import java.nio.file.FileVisitOption;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Extracts FXML paths from Maven project
|
||||
@@ -19,20 +19,28 @@ import java.util.Map;
|
||||
public final class FXMLProvider {
|
||||
private static final Logger logger = LogManager.getLogger(FXMLProvider.class);
|
||||
|
||||
private FXMLProvider() {
|
||||
private final MavenProject project;
|
||||
|
||||
/**
|
||||
* Instantiates a new provider
|
||||
*
|
||||
* @param project The Maven project
|
||||
* @throws NullPointerException If the project is null
|
||||
*/
|
||||
public FXMLProvider(final MavenProject project) {
|
||||
this.project = Objects.requireNonNull(project);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all the FXML files in the project's resources
|
||||
*
|
||||
* @param project The Maven project
|
||||
* @return A mapping of file to resource directory
|
||||
* @throws MojoExecutionException If an error occurs
|
||||
*/
|
||||
public static Map<Path, Path> getFXMLs(final MavenProject project) throws MojoExecutionException {
|
||||
public Map<Path, Path> getFXMLs() throws MojoExecutionException {
|
||||
final var map = new HashMap<Path, Path>();
|
||||
for (final var resource : project.getResources()) {
|
||||
final var path = Paths.get(resource.getDirectory());
|
||||
final var path = Path.of(resource.getDirectory());
|
||||
if (Files.isDirectory(path)) {
|
||||
try (final var stream = Files.find(path, Integer.MAX_VALUE, (p, a) -> p.toString().endsWith(".fxml"), FileVisitOption.FOLLOW_LINKS)) {
|
||||
final var curList = stream.toList();
|
||||
@@ -49,4 +57,18 @@ public final class FXMLProvider {
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory for {@link FXMLProvider}
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface Factory {
|
||||
/**
|
||||
* Creates a new provider
|
||||
*
|
||||
* @param project The Maven project
|
||||
* @return The provider
|
||||
*/
|
||||
FXMLProvider create(final MavenProject project);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,10 +38,17 @@ final class GenericParser {
|
||||
}
|
||||
|
||||
List<GenericTypes> parse() throws MojoExecutionException {
|
||||
return parseGenericTypes();
|
||||
final var parsed = parseGenericTypes();
|
||||
if (index < content.length()) {
|
||||
throw new MojoExecutionException("Expected EOF at " + index + " in " + content);
|
||||
}
|
||||
return parsed;
|
||||
}
|
||||
|
||||
private List<GenericTypes> parseGenericTypes() throws MojoExecutionException {
|
||||
if (content.isEmpty()) {
|
||||
throw new MojoExecutionException("Empty generic types");
|
||||
}
|
||||
final var ret = new ArrayList<GenericTypes>();
|
||||
eatSpaces();
|
||||
eat('<');
|
||||
@@ -52,12 +59,16 @@ final class GenericParser {
|
||||
if (peek() == '<') {
|
||||
final var genericTypes = parseGenericTypes();
|
||||
ret.add(new GenericTypesImpl(type, genericTypes));
|
||||
} else {
|
||||
ret.add(new GenericTypesImpl(type, List.of()));
|
||||
}
|
||||
eatSpaces();
|
||||
if (peek() == ',') {
|
||||
eat(',');
|
||||
} else if (peek() == '>') {
|
||||
eat('>');
|
||||
eatSpaces();
|
||||
return ret;
|
||||
} else if (peek() == ',') {
|
||||
eat(',');
|
||||
ret.add(new GenericTypesImpl(type, List.of()));
|
||||
}
|
||||
} while (index < content.length());
|
||||
return ret;
|
||||
@@ -72,17 +83,17 @@ final class GenericParser {
|
||||
}
|
||||
|
||||
private void eatSpaces() {
|
||||
while (peek() == ' ') {
|
||||
while (index < content.length() && peek() == ' ') {
|
||||
read();
|
||||
}
|
||||
}
|
||||
|
||||
private String parseType() throws MojoExecutionException {
|
||||
final var sb = new StringBuilder();
|
||||
while (peek() != '<' && index < content.length()) {
|
||||
while (peek() != '<' && peek() != '>' && peek() != ',' && index < content.length()) {
|
||||
sb.append(read());
|
||||
}
|
||||
final var type = sb.toString();
|
||||
final var type = sb.toString().trim();
|
||||
if (type.contains(".") || JAVA_LANG_CLASSES.contains(type)) {
|
||||
return type;
|
||||
} else if (imports.containsKey(type)) {
|
||||
|
||||
@@ -32,7 +32,7 @@ final class SourceInfoProvider {
|
||||
final var requiresResourceBundle = info.requiresResourceBundle();
|
||||
final var includesMapping = new HashMap<String, SourceInfo>();
|
||||
includes.forEach((k, v) -> includesMapping.put(k, getSourceInfo(mapping.get(v), mapping)));
|
||||
//FIXME mutliple includes
|
||||
//FIXME mutliple same includes
|
||||
return new SourceInfoImpl(outputClass, controllerClass, inputFile, List.copyOf(includesMapping.values()), includesMapping, requiresResourceBundle);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,209 @@
|
||||
package com.github.gtache.fxml.compiler.maven;
|
||||
|
||||
import com.github.gtache.fxml.compiler.ControllerFieldInjectionType;
|
||||
import com.github.gtache.fxml.compiler.ControllerInjectionType;
|
||||
import com.github.gtache.fxml.compiler.ControllerMethodsInjectionType;
|
||||
import com.github.gtache.fxml.compiler.ResourceBundleInjectionType;
|
||||
import com.github.gtache.fxml.compiler.compatibility.impl.GenerationCompatibilityImpl;
|
||||
import com.github.gtache.fxml.compiler.impl.GenerationParametersImpl;
|
||||
import com.github.gtache.fxml.compiler.maven.internal.CompilationInfo;
|
||||
import com.github.gtache.fxml.compiler.maven.internal.CompilationInfoProvider;
|
||||
import com.github.gtache.fxml.compiler.maven.internal.Compiler;
|
||||
import com.github.gtache.fxml.compiler.maven.internal.ControllerProvider;
|
||||
import com.github.gtache.fxml.compiler.maven.internal.FXMLProvider;
|
||||
import org.apache.maven.plugin.MojoExecutionException;
|
||||
import org.apache.maven.project.MavenProject;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class TestFXMLCompilerMojo {
|
||||
|
||||
private final Compiler compiler;
|
||||
private final CompilationInfoProvider compilationInfoProvider;
|
||||
private final ControllerProvider controllerProvider;
|
||||
private final FXMLProvider fxmlProvider;
|
||||
private final MavenProject mavenProject;
|
||||
private final Path outputDirectory;
|
||||
private final int targetVersion;
|
||||
private final boolean useImageInputStreamConstructor;
|
||||
private final ControllerInjectionType controllerInjectionType;
|
||||
private final ControllerFieldInjectionType controllerFieldInjectionType;
|
||||
private final ControllerMethodsInjectionType controllerMethodsInjectionType;
|
||||
private final ResourceBundleInjectionType resourceBundleInjectionType;
|
||||
private final Map<String, String> resourceMap;
|
||||
private final Map<Path, Path> fxmls;
|
||||
private final CompilationInfo compilationInfo;
|
||||
private final FXMLCompilerMojo mojo;
|
||||
|
||||
TestFXMLCompilerMojo(@Mock final Compiler compiler, @Mock final CompilationInfoProvider compilationInfoProvider,
|
||||
@Mock final ControllerProvider controllerProvider, @Mock final FXMLProvider fxmlProvider,
|
||||
@Mock final MavenProject mavenProject,
|
||||
@Mock final ControllerInjectionType controllerInjectionType,
|
||||
@Mock final ControllerFieldInjectionType controllerFieldInjectionType,
|
||||
@Mock final ControllerMethodsInjectionType controllerMethodsInjectionType,
|
||||
@Mock final ResourceBundleInjectionType resourceBundleInjectionType,
|
||||
@Mock final CompilationInfo compilationInfo) {
|
||||
this.compiler = Objects.requireNonNull(compiler);
|
||||
this.compilationInfoProvider = Objects.requireNonNull(compilationInfoProvider);
|
||||
this.controllerProvider = Objects.requireNonNull(controllerProvider);
|
||||
this.fxmlProvider = Objects.requireNonNull(fxmlProvider);
|
||||
this.mavenProject = Objects.requireNonNull(mavenProject);
|
||||
this.outputDirectory = Path.of("output");
|
||||
this.targetVersion = 11;
|
||||
this.useImageInputStreamConstructor = true;
|
||||
this.controllerInjectionType = Objects.requireNonNull(controllerInjectionType);
|
||||
this.controllerFieldInjectionType = Objects.requireNonNull(controllerFieldInjectionType);
|
||||
this.controllerMethodsInjectionType = Objects.requireNonNull(controllerMethodsInjectionType);
|
||||
this.resourceBundleInjectionType = Objects.requireNonNull(resourceBundleInjectionType);
|
||||
this.resourceMap = Map.of("a", "b", "c", "d");
|
||||
this.compilationInfo = Objects.requireNonNull(compilationInfo);
|
||||
this.fxmls = new HashMap<>();
|
||||
this.mojo = new FXMLCompilerMojo(compiler, (p, o) -> compilationInfoProvider, controllerProvider,
|
||||
p -> fxmlProvider);
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
void beforeEach() throws Exception {
|
||||
setValue("project", mavenProject);
|
||||
setValue("outputDirectory", outputDirectory);
|
||||
setIntValue("targetVersion", targetVersion);
|
||||
setBooleanValue("useImageInputStreamConstructor", useImageInputStreamConstructor);
|
||||
setValue("controllerInjectionType", controllerInjectionType);
|
||||
setValue("fieldInjectionType", controllerFieldInjectionType);
|
||||
setValue("methodInjectionType", controllerMethodsInjectionType);
|
||||
setValue("resourceInjectionType", resourceBundleInjectionType);
|
||||
setValue("resourceMap", resourceMap);
|
||||
when(fxmlProvider.getFXMLs()).thenReturn(fxmls);
|
||||
when(controllerProvider.getController(any())).then(i -> ((Path) i.getArgument(0)).toString());
|
||||
when(compilationInfoProvider.getCompilationInfo(any(), any(), anyMap())).thenReturn(compilationInfo);
|
||||
fxmls.put(Path.of("a"), Path.of("b"));
|
||||
fxmls.put(Path.of("c"), Path.of("d"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testExecuteParallel() throws Exception {
|
||||
final var pathA = Path.of("a");
|
||||
final var pathC = Path.of("c");
|
||||
setIntValue("parallelism", 4);
|
||||
mojo.execute();
|
||||
for (final var p : fxmls.keySet()) {
|
||||
verify(controllerProvider).getController(p);
|
||||
}
|
||||
final var controllerMapping = Map.of(pathA, "a", pathC, "c");
|
||||
for (final var e : fxmls.entrySet()) {
|
||||
verify(compilationInfoProvider).getCompilationInfo(e.getValue(), e.getKey(), controllerMapping);
|
||||
}
|
||||
final var parameters = new GenerationParametersImpl(new GenerationCompatibilityImpl(targetVersion), useImageInputStreamConstructor, resourceMap,
|
||||
controllerInjectionType, controllerFieldInjectionType, controllerMethodsInjectionType, resourceBundleInjectionType);
|
||||
final var compilationInfoMapping = Map.of(pathA, compilationInfo, pathC, compilationInfo);
|
||||
for (final var entry : compilationInfoMapping.entrySet()) {
|
||||
verify(compiler).compile(entry.getKey(), entry.getValue(), compilationInfoMapping, parameters);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testExecuteDefaultCores() throws Exception {
|
||||
final var pathA = Path.of("a");
|
||||
final var pathC = Path.of("c");
|
||||
setIntValue("parallelism", 0);
|
||||
mojo.execute();
|
||||
assertEquals(Runtime.getRuntime().availableProcessors(), getValue("parallelism"));
|
||||
for (final var p : fxmls.keySet()) {
|
||||
verify(controllerProvider).getController(p);
|
||||
}
|
||||
final var controllerMapping = Map.of(pathA, "a", pathC, "c");
|
||||
for (final var e : fxmls.entrySet()) {
|
||||
verify(compilationInfoProvider).getCompilationInfo(e.getValue(), e.getKey(), controllerMapping);
|
||||
}
|
||||
final var parameters = new GenerationParametersImpl(new GenerationCompatibilityImpl(targetVersion), useImageInputStreamConstructor, resourceMap,
|
||||
controllerInjectionType, controllerFieldInjectionType, controllerMethodsInjectionType, resourceBundleInjectionType);
|
||||
final var compilationInfoMapping = Map.of(pathA, compilationInfo, pathC, compilationInfo);
|
||||
for (final var entry : compilationInfoMapping.entrySet()) {
|
||||
verify(compiler).compile(entry.getKey(), entry.getValue(), compilationInfoMapping, parameters);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testControllerProviderException() throws Exception {
|
||||
setIntValue("parallelism", 4);
|
||||
doThrow(MojoExecutionException.class).when(controllerProvider).getController(any());
|
||||
assertThrows(MojoExecutionException.class, mojo::execute);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCompilationInfoProviderException() throws Exception {
|
||||
setIntValue("parallelism", 4);
|
||||
doThrow(MojoExecutionException.class).when(compilationInfoProvider).getCompilationInfo(any(), any(), anyMap());
|
||||
assertThrows(MojoExecutionException.class, mojo::execute);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCompilerException() throws Exception {
|
||||
setIntValue("parallelism", 4);
|
||||
doThrow(MojoExecutionException.class).when(compiler).compile(any(), any(), anyMap(), any());
|
||||
assertThrows(MojoExecutionException.class, mojo::execute);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testExecuteSingleCore() throws Exception {
|
||||
final var pathA = Path.of("a");
|
||||
final var pathC = Path.of("c");
|
||||
setIntValue("parallelism", 1);
|
||||
mojo.execute();
|
||||
for (final var p : fxmls.keySet()) {
|
||||
verify(controllerProvider).getController(p);
|
||||
}
|
||||
final var controllerMapping = Map.of(pathA, "a", pathC, "c");
|
||||
for (final var e : fxmls.entrySet()) {
|
||||
verify(compilationInfoProvider).getCompilationInfo(e.getValue(), e.getKey(), controllerMapping);
|
||||
}
|
||||
final var parameters = new GenerationParametersImpl(new GenerationCompatibilityImpl(targetVersion), useImageInputStreamConstructor, resourceMap,
|
||||
controllerInjectionType, controllerFieldInjectionType, controllerMethodsInjectionType, resourceBundleInjectionType);
|
||||
final var compilationInfoMapping = Map.of(pathA, compilationInfo, pathC, compilationInfo);
|
||||
verify(compiler).compile(compilationInfoMapping, parameters);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testOverrideControllerInjectionType() throws Exception {
|
||||
setValue("fieldInjectionType", ControllerFieldInjectionType.FACTORY);
|
||||
mojo.execute();
|
||||
assertEquals(ControllerInjectionType.FACTORY, getValue("controllerInjectionType"));
|
||||
}
|
||||
|
||||
private Object getValue(final String name) throws Exception {
|
||||
final var field = FXMLCompilerMojo.class.getDeclaredField(name);
|
||||
field.setAccessible(true);
|
||||
return field.get(mojo);
|
||||
}
|
||||
|
||||
private void setBooleanValue(final String name, final boolean value) throws Exception {
|
||||
final var field = FXMLCompilerMojo.class.getDeclaredField(name);
|
||||
field.setAccessible(true);
|
||||
field.setBoolean(mojo, value);
|
||||
}
|
||||
|
||||
private void setIntValue(final String name, final int value) throws Exception {
|
||||
final var field = FXMLCompilerMojo.class.getDeclaredField(name);
|
||||
field.setAccessible(true);
|
||||
field.setInt(mojo, value);
|
||||
}
|
||||
|
||||
private void setValue(final String name, final Object value) throws Exception {
|
||||
final var field = FXMLCompilerMojo.class.getDeclaredField(name);
|
||||
field.setAccessible(true);
|
||||
field.set(mojo, value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,8 +6,6 @@ import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
@@ -24,7 +22,6 @@ class TestCompilationInfoBuilder {
|
||||
private final Set<FieldInfo> injectedFields;
|
||||
private final Set<String> injectedMethods;
|
||||
private final Map<String, Path> includes;
|
||||
private final boolean requiresResourceBundle;
|
||||
private final CompilationInfo info;
|
||||
|
||||
TestCompilationInfoBuilder(@Mock final Path inputFile, @Mock final Path outputFile, @Mock final Path controllerFile, @Mock final FieldInfo fieldInfo) {
|
||||
@@ -33,11 +30,10 @@ class TestCompilationInfoBuilder {
|
||||
this.outputClass = "outputClass";
|
||||
this.controllerFile = Objects.requireNonNull(controllerFile);
|
||||
this.controllerClass = "controllerClass";
|
||||
this.injectedFields = new HashSet<>(Set.of(fieldInfo));
|
||||
this.injectedMethods = new HashSet<>(Set.of("one", "two"));
|
||||
this.includes = new HashMap<>(Map.of("one", Objects.requireNonNull(inputFile)));
|
||||
this.requiresResourceBundle = true;
|
||||
this.info = new CompilationInfo(inputFile, outputFile, outputClass, controllerFile, controllerClass, injectedFields, injectedMethods, includes, requiresResourceBundle);
|
||||
this.injectedFields = Set.of(new FieldInfo("type", "name"));
|
||||
this.injectedMethods = Set.of("one", "two");
|
||||
this.includes = Map.of("one", Objects.requireNonNull(inputFile));
|
||||
this.info = new CompilationInfo(inputFile, outputFile, outputClass, controllerFile, controllerClass, injectedFields, injectedMethods, includes, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -1,8 +1,143 @@
|
||||
package com.github.gtache.fxml.compiler.maven.internal;
|
||||
|
||||
import org.apache.maven.plugin.MojoExecutionException;
|
||||
import org.apache.maven.project.MavenProject;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class TestCompilationInfoProvider {
|
||||
|
||||
private final MavenProject project;
|
||||
|
||||
TestCompilationInfoProvider(@Mock final MavenProject project) {
|
||||
this.project = Objects.requireNonNull(project);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCompleteExample(@TempDir final Path tempDir) throws Exception {
|
||||
final var path = copyFile("infoView.fxml", tempDir);
|
||||
final var includedPath = path.getParent().resolve("includeView.fxml");
|
||||
final var controllerPath = path.getParent().resolve("InfoController.java");
|
||||
final var controllerClass = "com.github.gtache.fxml.compiler.maven.internal.InfoController";
|
||||
Files.createFile(controllerPath);
|
||||
when(project.getCompileSourceRoots()).thenReturn(List.of(tempDir.toString()));
|
||||
final var expected = new CompilationInfo(path, path.getParent().resolve("InfoView.java"),
|
||||
"com.github.gtache.fxml.compiler.maven.internal.InfoView", controllerPath, controllerClass,
|
||||
Set.of(new FieldInfo("javafx.event.EventHandler", "onContextMenuRequested"), new FieldInfo("Button", "button"),
|
||||
new FieldInfo("com.github.gtache.fxml.compiler.maven.internal.IncludeController", "includeViewController")),
|
||||
Set.of("onAction"), Map.of("includeView.fxml", path.getParent().resolve("includeView.fxml")), true);
|
||||
final var compilationInfoProvider = new CompilationInfoProvider(project, tempDir);
|
||||
final var actual = compilationInfoProvider.getCompilationInfo(tempDir, path, Map.of(includedPath, "com.github.gtache.fxml.compiler.maven.internal.IncludeController"));
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testComplexFilename(@TempDir final Path tempDir) throws Exception {
|
||||
final var path = copyFile("com_plex-view.fxml", tempDir);
|
||||
final var controllerPath = path.getParent().resolve("InfoController.java");
|
||||
final var controllerClass = "com.github.gtache.fxml.compiler.maven.internal.InfoController";
|
||||
Files.createFile(controllerPath);
|
||||
when(project.getCompileSourceRoots()).thenReturn(List.of(tempDir.toString()));
|
||||
final var expected = new CompilationInfo(path, path.getParent().resolve("ComPlexView.java"),
|
||||
"com.github.gtache.fxml.compiler.maven.internal.ComPlexView", controllerPath, controllerClass,
|
||||
Set.of(), Set.of(), Map.of(), false);
|
||||
final var compilationInfoProvider = new CompilationInfoProvider(project, tempDir);
|
||||
final var actual = compilationInfoProvider.getCompilationInfo(tempDir, path, Map.of());
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testNoController(@TempDir final Path tempDir) throws Exception {
|
||||
final var path = copyFile("noController.fxml", tempDir);
|
||||
final var controllerPath = path.getParent().resolve("InfoController.java");
|
||||
Files.createFile(controllerPath);
|
||||
when(project.getCompileSourceRoots()).thenReturn(List.of(tempDir.toString()));
|
||||
final var compilationInfoProvider = new CompilationInfoProvider(project, tempDir);
|
||||
assertThrows(MojoExecutionException.class, () -> compilationInfoProvider.getCompilationInfo(tempDir, path, Map.of()));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testIncludeNoSource(@TempDir final Path tempDir) throws Exception {
|
||||
final var path = copyFile("missingSource.fxml", tempDir);
|
||||
final var includedPath = path.getParent().resolve("includeView.fxml");
|
||||
final var controllerPath = path.getParent().resolve("InfoController.java");
|
||||
Files.createFile(controllerPath);
|
||||
when(project.getCompileSourceRoots()).thenReturn(List.of(tempDir.toString()));
|
||||
final var compilationInfoProvider = new CompilationInfoProvider(project, tempDir);
|
||||
assertThrows(MojoExecutionException.class, () -> compilationInfoProvider.getCompilationInfo(tempDir, path, Map.of(includedPath, "com.github.gtache.fxml.compiler.maven.internal.IncludeController")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCantFindControllerFile(@TempDir final Path tempDir) throws Exception {
|
||||
final var path = copyFile("infoView.fxml", tempDir);
|
||||
final var includedPath = path.getParent().resolve("includeView.fxml");
|
||||
final var controllerPath = path.getParent().resolve("InfoController.java");
|
||||
Files.createFile(controllerPath);
|
||||
when(project.getCompileSourceRoots()).thenReturn(List.of());
|
||||
final var compilationInfoProvider = new CompilationInfoProvider(project, tempDir);
|
||||
assertThrows(MojoExecutionException.class, () -> compilationInfoProvider.getCompilationInfo(tempDir, path, Map.of(includedPath, "com.github.gtache.fxml.compiler.maven.internal.IncludeController")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCantFindIncludedControllerClass(@TempDir final Path tempDir) throws Exception {
|
||||
final var path = copyFile("infoView.fxml", tempDir);
|
||||
final var controllerPath = path.getParent().resolve("InfoController.java");
|
||||
Files.createFile(controllerPath);
|
||||
when(project.getCompileSourceRoots()).thenReturn(List.of(tempDir.toString()));
|
||||
final var compilationInfoProvider = new CompilationInfoProvider(project, tempDir);
|
||||
assertThrows(MojoExecutionException.class, () -> compilationInfoProvider.getCompilationInfo(tempDir, path, Map.of()));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testNoResourceBundle(@TempDir final Path tempDir) throws Exception {
|
||||
final var path = copyFile("noResourceBundle.fxml", tempDir);
|
||||
final var includedPath = path.getParent().resolve("includeView.fxml");
|
||||
final var controllerPath = path.getParent().resolve("InfoController.java");
|
||||
final var controllerClass = "com.github.gtache.fxml.compiler.maven.internal.InfoController";
|
||||
Files.createFile(controllerPath);
|
||||
when(project.getCompileSourceRoots()).thenReturn(List.of(tempDir.toString()));
|
||||
final var expected = new CompilationInfo(path, path.getParent().resolve("NoResourceBundle.java"),
|
||||
"com.github.gtache.fxml.compiler.maven.internal.NoResourceBundle", controllerPath, controllerClass,
|
||||
Set.of(new FieldInfo("javafx.event.EventHandler", "onContextMenuRequested"), new FieldInfo("Button", "button"),
|
||||
new FieldInfo("com.github.gtache.fxml.compiler.maven.internal.IncludeController", "includeViewController")),
|
||||
Set.of("onAction"), Map.of("includeView.fxml", path.getParent().resolve("includeView.fxml")), false);
|
||||
final var compilationInfoProvider = new CompilationInfoProvider(project, tempDir);
|
||||
final var actual = compilationInfoProvider.getCompilationInfo(tempDir, path, Map.of(includedPath, "com.github.gtache.fxml.compiler.maven.internal.IncludeController"));
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testUnknownOn(@TempDir final Path tempDir) throws Exception {
|
||||
final var path = copyFile("unknownOn.fxml", tempDir);
|
||||
final var controllerPath = path.getParent().resolve("InfoController.java");
|
||||
Files.createFile(controllerPath);
|
||||
when(project.getCompileSourceRoots()).thenReturn(List.of(tempDir.toString()));
|
||||
final var compilationInfoProvider = new CompilationInfoProvider(project, tempDir);
|
||||
assertThrows(MojoExecutionException.class, () -> compilationInfoProvider.getCompilationInfo(tempDir, path, Map.of()));
|
||||
}
|
||||
|
||||
private Path copyFile(final String source, final Path tempDir) throws IOException {
|
||||
final var out = tempDir.resolve("com").resolve("github").resolve("gtache").resolve("fxml").resolve("compiler").resolve("maven").resolve("internal").resolve(source);
|
||||
Files.createDirectories(out.getParent());
|
||||
try (final var in = getClass().getResourceAsStream(source)) {
|
||||
assertNotNull(in);
|
||||
Files.copy(in, out);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
package com.github.gtache.fxml.compiler.maven.internal;
|
||||
|
||||
import com.github.gtache.fxml.compiler.ControllerInfo;
|
||||
import com.github.gtache.fxml.compiler.GenerationException;
|
||||
import com.github.gtache.fxml.compiler.GenerationParameters;
|
||||
import com.github.gtache.fxml.compiler.Generator;
|
||||
import com.github.gtache.fxml.compiler.SourceInfo;
|
||||
import com.github.gtache.fxml.compiler.impl.GenerationRequestImpl;
|
||||
import com.github.gtache.fxml.compiler.parsing.FXMLParser;
|
||||
import com.github.gtache.fxml.compiler.parsing.ParseException;
|
||||
import com.github.gtache.fxml.compiler.parsing.ParsedObject;
|
||||
import org.apache.maven.plugin.MojoExecutionException;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
@@ -19,7 +18,6 @@ import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
@@ -30,88 +28,88 @@ import static org.mockito.Mockito.*;
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class TestCompiler {
|
||||
|
||||
private final ControllerInfoProvider controllerInfoProvider;
|
||||
private final SourceInfoProvider sourceInfoProvider;
|
||||
private final FXMLParser fxmlParser;
|
||||
private final Generator generator;
|
||||
private final CompilationInfo compilationInfo;
|
||||
private final ParsedObject object;
|
||||
private final ControllerInfo controllerInfo;
|
||||
private final SourceInfo sourceInfo;
|
||||
private final String content;
|
||||
private final GenerationParameters parameters;
|
||||
private final Compiler compiler;
|
||||
|
||||
TestCompiler(@Mock final ControllerInfoProvider controllerInfoProvider, @Mock final SourceInfoProvider sourceInfoProvider,
|
||||
@Mock final FXMLParser fxmlParser, @Mock final CompilationInfo compilationInfo, @Mock final ParsedObject object,
|
||||
@Mock final ControllerInfo controllerInfo, @Mock final SourceInfo sourceInfo,
|
||||
TestCompiler(@Mock final FXMLParser fxmlParser, @Mock final CompilationInfo compilationInfo, @Mock final ParsedObject object,
|
||||
@Mock final GenerationParameters parameters, @Mock final Generator generator) {
|
||||
this.controllerInfoProvider = Objects.requireNonNull(controllerInfoProvider);
|
||||
this.sourceInfoProvider = Objects.requireNonNull(sourceInfoProvider);
|
||||
this.fxmlParser = Objects.requireNonNull(fxmlParser);
|
||||
this.compilationInfo = Objects.requireNonNull(compilationInfo);
|
||||
this.object = Objects.requireNonNull(object);
|
||||
this.controllerInfo = Objects.requireNonNull(controllerInfo);
|
||||
this.sourceInfo = Objects.requireNonNull(sourceInfo);
|
||||
this.content = "content";
|
||||
this.parameters = Objects.requireNonNull(parameters);
|
||||
this.generator = Objects.requireNonNull(generator);
|
||||
this.compiler = new Compiler(fxmlParser, generator);
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
void beforeEach() throws MojoExecutionException, GenerationException, ParseException {
|
||||
void beforeEach() throws GenerationException, ParseException {
|
||||
when(fxmlParser.parse((Path) any())).thenReturn(object);
|
||||
when(ControllerInfoProvider.getControllerInfo(compilationInfo)).thenReturn(controllerInfo);
|
||||
when(SourceInfoProvider.getSourceInfo(eq(compilationInfo), anyMap())).thenReturn(sourceInfo);
|
||||
when(generator.generate(any())).thenReturn(content);
|
||||
when(compilationInfo.outputClass()).thenReturn("outputClass");
|
||||
when(compilationInfo.controllerClass()).thenReturn("controllerClass");
|
||||
when(compilationInfo.includes()).thenReturn(Map.of());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCompile(@TempDir final Path tempDir) throws Exception {
|
||||
final var path = tempDir.resolve("fxml1.fxml");
|
||||
Files.createFile(path);
|
||||
final var outputPath = tempDir.resolve("subFolder").resolve("fxml1.java");
|
||||
final var outputClass = "outputClass";
|
||||
when(compilationInfo.outputFile()).thenReturn(outputPath);
|
||||
when(compilationInfo.outputClass()).thenReturn(outputClass);
|
||||
when(compilationInfo.inputFile()).thenReturn(path);
|
||||
when(compilationInfo.controllerFile()).thenReturn(path);
|
||||
final var controllerInfo = ControllerInfoProvider.getControllerInfo(compilationInfo);
|
||||
final var sourceInfo = SourceInfoProvider.getSourceInfo(compilationInfo, Map.of());
|
||||
final var mapping = Map.of(path, compilationInfo);
|
||||
final var request = new GenerationRequestImpl(parameters, controllerInfo, sourceInfo, object, outputClass);
|
||||
Compiler.compile(mapping, parameters);
|
||||
compiler.compile(mapping, parameters);
|
||||
verify(fxmlParser).parse(path);
|
||||
ControllerInfoProvider.getControllerInfo(compilationInfo);
|
||||
SourceInfoProvider.getSourceInfo(compilationInfo, mapping);
|
||||
verify(generator).generate(request);
|
||||
assertEquals(content, Files.readString(outputPath));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Disabled("Need cross-platform unwritable path")
|
||||
void testCompileIOException(@TempDir final Path tempDir) throws Exception {
|
||||
final var path = tempDir.resolve("fxml1.fxml");
|
||||
final var outputPath = Paths.get("/whatever");
|
||||
Files.createFile(path);
|
||||
final var outputPath = Path.of("/in/a/b/c/whatever");
|
||||
final var outputClass = "outputClass";
|
||||
when(compilationInfo.outputFile()).thenReturn(outputPath);
|
||||
when(compilationInfo.outputClass()).thenReturn(outputClass);
|
||||
when(compilationInfo.inputFile()).thenReturn(path);
|
||||
when(compilationInfo.controllerFile()).thenReturn(path);
|
||||
final var mapping = Map.of(path, compilationInfo);
|
||||
final var controllerInfo = ControllerInfoProvider.getControllerInfo(compilationInfo);
|
||||
final var sourceInfo = SourceInfoProvider.getSourceInfo(compilationInfo, Map.of());
|
||||
final var request = new GenerationRequestImpl(parameters, controllerInfo, sourceInfo, object, outputClass);
|
||||
assertThrows(MojoExecutionException.class, () -> Compiler.compile(mapping, parameters));
|
||||
assertThrows(MojoExecutionException.class, () -> compiler.compile(mapping, parameters));
|
||||
verify(fxmlParser).parse(path);
|
||||
ControllerInfoProvider.getControllerInfo(compilationInfo);
|
||||
SourceInfoProvider.getSourceInfo(compilationInfo, mapping);
|
||||
verify(generator).generate(request);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCompileRuntimeException(@TempDir final Path tempDir) throws Exception {
|
||||
final var path = tempDir.resolve("fxml1.fxml");
|
||||
Files.createFile(path);
|
||||
final var outputPath = tempDir.resolve("subFolder").resolve("fxml1.java");
|
||||
final var outputClass = "outputClass";
|
||||
when(compilationInfo.outputFile()).thenReturn(outputPath);
|
||||
when(compilationInfo.outputClass()).thenReturn(outputClass);
|
||||
when(compilationInfo.inputFile()).thenReturn(path);
|
||||
when(compilationInfo.controllerFile()).thenReturn(path);
|
||||
final var mapping = Map.of(path, compilationInfo);
|
||||
final var controllerInfo = ControllerInfoProvider.getControllerInfo(compilationInfo);
|
||||
final var sourceInfo = SourceInfoProvider.getSourceInfo(compilationInfo, Map.of());
|
||||
final var request = new GenerationRequestImpl(parameters, controllerInfo, sourceInfo, object, outputClass);
|
||||
when(generator.generate(request)).thenThrow(RuntimeException.class);
|
||||
assertThrows(MojoExecutionException.class, () -> Compiler.compile(mapping, parameters));
|
||||
assertThrows(MojoExecutionException.class, () -> compiler.compile(mapping, parameters));
|
||||
verify(fxmlParser).parse(path);
|
||||
ControllerInfoProvider.getControllerInfo(compilationInfo);
|
||||
SourceInfoProvider.getSourceInfo(compilationInfo, mapping);
|
||||
verify(generator).generate(request);
|
||||
}
|
||||
|
||||
@@ -120,25 +118,27 @@ class TestCompiler {
|
||||
when(fxmlParser.parse((Path) any())).thenThrow(ParseException.class);
|
||||
final var path = tempDir.resolve("fxml1.fxml");
|
||||
final var mapping = Map.of(path, compilationInfo);
|
||||
assertThrows(MojoExecutionException.class, () -> Compiler.compile(mapping, parameters));
|
||||
assertThrows(MojoExecutionException.class, () -> compiler.compile(mapping, parameters));
|
||||
verify(fxmlParser).parse(path);
|
||||
verifyNoInteractions(controllerInfoProvider, sourceInfoProvider, generator);
|
||||
verifyNoInteractions(generator);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCompileGenerationException(@TempDir final Path tempDir) throws Exception {
|
||||
final var path = tempDir.resolve("fxml1.fxml");
|
||||
Files.createFile(path);
|
||||
final var outputPath = tempDir.resolve("subFolder").resolve("fxml1.java");
|
||||
final var outputClass = "outputClass";
|
||||
when(compilationInfo.outputFile()).thenReturn(outputPath);
|
||||
when(compilationInfo.outputClass()).thenReturn(outputClass);
|
||||
when(compilationInfo.inputFile()).thenReturn(path);
|
||||
when(compilationInfo.controllerFile()).thenReturn(path);
|
||||
final var mapping = Map.of(path, compilationInfo);
|
||||
final var controllerInfo = ControllerInfoProvider.getControllerInfo(compilationInfo);
|
||||
final var sourceInfo = SourceInfoProvider.getSourceInfo(compilationInfo, Map.of());
|
||||
final var request = new GenerationRequestImpl(parameters, controllerInfo, sourceInfo, object, outputClass);
|
||||
when(generator.generate(request)).thenThrow(GenerationException.class);
|
||||
assertThrows(MojoExecutionException.class, () -> Compiler.compile(mapping, parameters));
|
||||
assertThrows(MojoExecutionException.class, () -> compiler.compile(mapping, parameters));
|
||||
verify(fxmlParser).parse(path);
|
||||
ControllerInfoProvider.getControllerInfo(compilationInfo);
|
||||
SourceInfoProvider.getSourceInfo(compilationInfo, mapping);
|
||||
verify(generator).generate(request);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.github.gtache.fxml.compiler.maven.internal;
|
||||
|
||||
import com.github.gtache.fxml.compiler.impl.ControllerFieldInfoImpl;
|
||||
import com.github.gtache.fxml.compiler.impl.ControllerInfoImpl;
|
||||
import com.github.gtache.fxml.compiler.impl.GenericTypesImpl;
|
||||
import org.apache.maven.plugin.MojoExecutionException;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
@@ -11,10 +12,10 @@ import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
@@ -24,11 +25,9 @@ import static org.mockito.Mockito.when;
|
||||
class TestControllerInfoProvider {
|
||||
|
||||
private final CompilationInfo compilationInfo;
|
||||
private final ControllerInfoProvider controllerInfoProvider;
|
||||
|
||||
TestControllerInfoProvider(@Mock final CompilationInfo compilationInfo) {
|
||||
this.compilationInfo = Objects.requireNonNull(compilationInfo);
|
||||
this.controllerInfoProvider = new ControllerInfoProvider();
|
||||
}
|
||||
|
||||
|
||||
@@ -49,6 +48,7 @@ class TestControllerInfoProvider {
|
||||
private Button button;
|
||||
private ComboBox rawBox;
|
||||
private TableColumn<Integer, ComboBox<String>> tableColumn;
|
||||
private ComboBox<Integer> fullBox;
|
||||
|
||||
@FXML
|
||||
void initialize() {
|
||||
@@ -64,18 +64,47 @@ class TestControllerInfoProvider {
|
||||
}
|
||||
""");
|
||||
when(compilationInfo.controllerFile()).thenReturn(fxml);
|
||||
final var expectedInfo = new ControllerInfoImpl("com.github.gtache.fxml.compiler.maven.internal.LoadController",
|
||||
Map.of("onClick", false, "onOtherClick", true), Map.of("keyEventHandler", new ControllerFieldInfoImpl("keyEventHandler", List.of()),
|
||||
"comboBox", new ControllerFieldInfoImpl("comboBox", List.of("String")), "button", new ControllerFieldInfoImpl("button", List.of()),
|
||||
"rawBox", new ControllerFieldInfoImpl("rawBox", List.of()),
|
||||
"tableColumn", new ControllerFieldInfoImpl("tableColumn", List.of("Integer", "javafx.scene.control.ComboBox<String>"))), true);
|
||||
final var controllerClass = "com.github.gtache.fxml.compiler.maven.internal.LoadController";
|
||||
when(compilationInfo.controllerClass()).thenReturn(controllerClass);
|
||||
when(compilationInfo.injectedFields()).thenReturn(Set.of(new FieldInfo("EventHandler", "keyEventHandler"),
|
||||
new FieldInfo("ComboBox", "comboBox"), new FieldInfo("Button", "button"),
|
||||
new FieldInfo("ComboBox", "rawBox"), new FieldInfo("TableColumn", "tableColumn"),
|
||||
new FieldInfo("ComboBox", "abc"), new FieldInfo("javafx.scene.control.ComboBox", "fullBox")));
|
||||
when(compilationInfo.injectedMethods()).thenReturn(Set.of("onClick", "onOtherClick"));
|
||||
final var expectedInfo = new ControllerInfoImpl(controllerClass,
|
||||
Map.of("onClick", false, "onOtherClick", true), Map.of("keyEventHandler", new ControllerFieldInfoImpl("keyEventHandler", List.of(new GenericTypesImpl("javafx.event.KeyEvent", List.of()))),
|
||||
"comboBox", new ControllerFieldInfoImpl("comboBox", List.of(new GenericTypesImpl("String", List.of()))), "button", new ControllerFieldInfoImpl("button", List.of()),
|
||||
"rawBox", new ControllerFieldInfoImpl("rawBox", List.of()), "fullBox", new ControllerFieldInfoImpl("fullBox", List.of(new GenericTypesImpl("Integer", List.of()))),
|
||||
"tableColumn", new ControllerFieldInfoImpl("tableColumn", List.of(new GenericTypesImpl("Integer", List.of()),
|
||||
new GenericTypesImpl("javafx.scene.control.ComboBox", List.of(new GenericTypesImpl("String", List.of())))))), true);
|
||||
final var actual = ControllerInfoProvider.getControllerInfo(compilationInfo);
|
||||
assertEquals(expectedInfo, actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetControllerInfoMethodNotFound(@TempDir final Path tempDir) throws Exception {
|
||||
final var fxml = tempDir.resolve("fxml.fxml");
|
||||
Files.writeString(fxml, """
|
||||
package com.github.gtache.fxml.compiler.maven.internal;
|
||||
|
||||
import javafx.event.EventHandler;
|
||||
import javafx.event.KeyEvent;
|
||||
import javafx.scene.control.*;
|
||||
|
||||
public class LoadController {
|
||||
|
||||
}
|
||||
""");
|
||||
when(compilationInfo.controllerFile()).thenReturn(fxml);
|
||||
when(compilationInfo.controllerClass()).thenReturn("com.github.gtache.fxml.compiler.maven.internal.LoadController");
|
||||
when(compilationInfo.injectedFields()).thenReturn(Set.of());
|
||||
when(compilationInfo.injectedMethods()).thenReturn(Set.of("onClick"));
|
||||
assertThrows(MojoExecutionException.class, () -> ControllerInfoProvider.getControllerInfo(compilationInfo));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetControllerInfoException() {
|
||||
when(compilationInfo.controllerFile()).thenReturn(Paths.get("/whatever"));
|
||||
when(compilationInfo.controllerFile()).thenReturn(Path.of("/in/a/b/c/whatever"));
|
||||
assertThrows(MojoExecutionException.class, () -> ControllerInfoProvider.getControllerInfo(compilationInfo));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@ import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
@@ -16,6 +15,12 @@ import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class TestControllerProvider {
|
||||
|
||||
private final ControllerProvider controllerProvider;
|
||||
|
||||
TestControllerProvider() {
|
||||
this.controllerProvider = new ControllerProvider();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetController(@TempDir final Path tempDir) throws Exception {
|
||||
final var fxml = tempDir.resolve("fxml.fxml");
|
||||
@@ -23,7 +28,7 @@ class TestControllerProvider {
|
||||
"<BorderPane xmlns=\"http://javafx.com/javafx/22\" xmlns:fx=\"http://javafx.com/fxml/1\"" +
|
||||
" fx:controller=\"LoadController\">" +
|
||||
"</BorderPane>\n");
|
||||
assertEquals("LoadController", ControllerProvider.getController(fxml));
|
||||
assertEquals("LoadController", controllerProvider.getController(fxml));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -32,11 +37,11 @@ class TestControllerProvider {
|
||||
Files.writeString(fxml, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
|
||||
"<BorderPane xmlns=\"http://javafx.com/javafx/22\" xmlns:fx=\"http://javafx.com/fxml/1\">" +
|
||||
"</BorderPane>\n");
|
||||
assertThrows(MojoExecutionException.class, () -> ControllerProvider.getController(fxml));
|
||||
assertThrows(MojoExecutionException.class, () -> controllerProvider.getController(fxml));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetControllerError() {
|
||||
assertThrows(MojoExecutionException.class, () -> ControllerProvider.getController(Paths.get("fxml.fxml")));
|
||||
assertThrows(MojoExecutionException.class, () -> controllerProvider.getController(Path.of("fxml.fxml")));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,20 +22,24 @@ import static org.mockito.Mockito.when;
|
||||
class TestFXMLProvider {
|
||||
|
||||
private final MavenProject project;
|
||||
private final FXMLProvider provider;
|
||||
|
||||
TestFXMLProvider(@Mock final MavenProject project) {
|
||||
this.project = Objects.requireNonNull(project);
|
||||
this.provider = new FXMLProvider(project);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetFXMLs(@TempDir final Path tempDir, @TempDir final Path otherTempDir) throws Exception {
|
||||
final var subFolder = tempDir.resolve("subFolder");
|
||||
Files.createDirectories(subFolder);
|
||||
Files.createFile(subFolder.resolve("subfxml1.fxml"));
|
||||
Files.createFile(subFolder.resolve("subfxml2.fxml"));
|
||||
Files.createFile(tempDir.resolve("fxml1.fxml"));
|
||||
Files.createFile(tempDir.resolve("fxml2.fxml"));
|
||||
|
||||
final var otherSubFolder = otherTempDir.resolve("subFolder");
|
||||
Files.createDirectories(otherSubFolder);
|
||||
Files.createFile(otherSubFolder.resolve("subfxml1.fxml"));
|
||||
Files.createFile(otherSubFolder.resolve("subfxml2.fxml"));
|
||||
Files.createFile(otherTempDir.resolve("fxml1.fxml"));
|
||||
@@ -57,7 +61,7 @@ class TestFXMLProvider {
|
||||
otherTempDir.resolve("fxml1.fxml"), otherTempDir,
|
||||
otherTempDir.resolve("fxml2.fxml"), otherTempDir
|
||||
);
|
||||
final var map = FXMLProvider.getFXMLs(project);
|
||||
final var map = provider.getFXMLs();
|
||||
assertEquals(expected, map);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,15 +2,18 @@ package com.github.gtache.fxml.compiler.maven.internal;
|
||||
|
||||
import com.github.gtache.fxml.compiler.impl.GenericTypesImpl;
|
||||
import org.apache.maven.plugin.MojoExecutionException;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
class TestGenericParser {
|
||||
|
||||
@@ -22,12 +25,34 @@ class TestGenericParser {
|
||||
assertEquals(expectedGenericTypes, parsed);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testNotFound() {
|
||||
final var parser = new GenericParser("<Collection>", Map.of());
|
||||
assertThrows(MojoExecutionException.class, parser::parse);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = {"<String, String<String>>", " < String , String < String > > ",
|
||||
"<String,String<String>>", " <String , String< String> > "})
|
||||
void testWithSpaces(final String genericTypes) throws MojoExecutionException {
|
||||
final var parser = new GenericParser(genericTypes, Map.of());
|
||||
final var expected = List.of(new GenericTypesImpl("String", List.of()), new GenericTypesImpl("String", List.of(new GenericTypesImpl("String", List.of()))));
|
||||
assertEquals(expected, parser.parse());
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = {"", "<String>>", "<<String>", "<String,,String>"})
|
||||
void testInvalid(final String genericTypes) {
|
||||
final var parser = new GenericParser(genericTypes, Map.of());
|
||||
assertThrows(MojoExecutionException.class, parser::parse);
|
||||
}
|
||||
|
||||
private static Stream<Arguments> providesParseTests() {
|
||||
return Stream.of(
|
||||
Arguments.of("<Map<String, TableView<Node, Node>>>",
|
||||
Map.of("Map", "java.util.Map", "String", "java.lang.String", "TableView", "javafx.scene.control.TableView", "Node", "javafx.scene.Node"),
|
||||
List.of(new GenericTypesImpl("java.util.Map",
|
||||
List.of(new GenericTypesImpl("java.lang.String", List.of()), new GenericTypesImpl("javafx.scene.control.TableView",
|
||||
List.of(new GenericTypesImpl("String", List.of()), new GenericTypesImpl("javafx.scene.control.TableView",
|
||||
List.of(new GenericTypesImpl("javafx.scene.Node", List.of()), new GenericTypesImpl("javafx.scene.Node", List.of()))))))),
|
||||
Arguments.of("<Map<String, String>>",
|
||||
Map.of("Map", "java.util.Map"),
|
||||
@@ -39,10 +64,10 @@ class TestGenericParser {
|
||||
Arguments.of("<Collection<String>>",
|
||||
Map.of("Collection", "java.util.Collection", "String", "java.lang.String"),
|
||||
List.of(new GenericTypesImpl("java.util.Collection",
|
||||
List.of(new GenericTypesImpl("java.lang.String", List.of()))))),
|
||||
List.of(new GenericTypesImpl("String", List.of()))))),
|
||||
Arguments.of("<Collection<String>>",
|
||||
Map.of(),
|
||||
List.of(new GenericTypesImpl("Collection",
|
||||
Map.of("Collection", "java.util.Collection"),
|
||||
List.of(new GenericTypesImpl("java.util.Collection",
|
||||
List.of(new GenericTypesImpl("String", List.of())))))
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,49 @@
|
||||
package com.github.gtache.fxml.compiler.maven.internal;
|
||||
|
||||
import com.github.gtache.fxml.compiler.impl.SourceInfoImpl;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class TestSourceInfoProvider {
|
||||
|
||||
@Test
|
||||
void testGetSourceInfo(@Mock final CompilationInfo compilationInfo) {
|
||||
final var outputClass = "outputClass";
|
||||
final var controllerClass = "controllerClass";
|
||||
final var inputFile = Path.of("inputFile");
|
||||
final var includeFile = Path.of("includeFile");
|
||||
final var includes = Map.of("one", includeFile);
|
||||
when(compilationInfo.outputClass()).thenReturn(outputClass);
|
||||
when(compilationInfo.controllerClass()).thenReturn(controllerClass);
|
||||
when(compilationInfo.inputFile()).thenReturn(inputFile);
|
||||
when(compilationInfo.includes()).thenReturn(includes);
|
||||
when(compilationInfo.requiresResourceBundle()).thenReturn(true);
|
||||
|
||||
final var includeCompilationInfo = mock(CompilationInfo.class);
|
||||
final var includeOutputClass = "includeOutputClass";
|
||||
final var includeControllerClass = "includeControllerClass";
|
||||
final var includeInputFile = Path.of("includeInputFile");
|
||||
when(includeCompilationInfo.outputClass()).thenReturn(includeOutputClass);
|
||||
when(includeCompilationInfo.controllerClass()).thenReturn(includeControllerClass);
|
||||
when(includeCompilationInfo.inputFile()).thenReturn(includeInputFile);
|
||||
when(includeCompilationInfo.includes()).thenReturn(Map.of());
|
||||
final var mapping = Map.of(includeFile, includeCompilationInfo);
|
||||
|
||||
final var expectedIncludeSourceInfo = new SourceInfoImpl(includeOutputClass, includeControllerClass, includeInputFile, List.of(), Map.of(), false);
|
||||
assertEquals(expectedIncludeSourceInfo, SourceInfoProvider.getSourceInfo(includeCompilationInfo, mapping));
|
||||
final var expected = new SourceInfoImpl(outputClass, controllerClass, inputFile, List.of(expectedIncludeSourceInfo),
|
||||
Map.of("one", expectedIncludeSourceInfo), true);
|
||||
assertEquals(expected, SourceInfoProvider.getSourceInfo(compilationInfo, mapping));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.scene.layout.BorderPane?>
|
||||
<BorderPane xmlns="http://javafx.com/javafx/22" xmlns:fx="http://javafx.com/fxml/1"
|
||||
fx:controller="com.github.gtache.fxml.compiler.maven.internal.InfoController">
|
||||
<bottom>
|
||||
</bottom>
|
||||
</BorderPane>
|
||||
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.scene.control.Button?>
|
||||
<?import javafx.scene.layout.BorderPane?>
|
||||
<?import javafx.scene.layout.HBox?>
|
||||
<BorderPane xmlns="http://javafx.com/javafx/22" xmlns:fx="http://javafx.com/fxml/1"
|
||||
fx:controller="com.github.gtache.fxml.compiler.maven.internal.InfoController">
|
||||
<bottom>
|
||||
<HBox>
|
||||
<children>
|
||||
<Button fx:id="button" onAction="#onAction" onContextMenuRequested="$controller.onContextMenuRequested"
|
||||
text="%text"/>
|
||||
<fx:include fx:id="includeView" source="includeView.fxml"/>
|
||||
</children>
|
||||
</HBox>
|
||||
</bottom>
|
||||
</BorderPane>
|
||||
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.scene.layout.BorderPane?>
|
||||
<?import javafx.scene.layout.HBox?>
|
||||
<BorderPane xmlns="http://javafx.com/javafx/22" xmlns:fx="http://javafx.com/fxml/1"
|
||||
fx:controller="com.github.gtache.fxml.compiler.maven.internal.InfoController">
|
||||
<bottom>
|
||||
<HBox>
|
||||
<children>
|
||||
<fx:include fx:id="includeView"/>
|
||||
</children>
|
||||
</HBox>
|
||||
</bottom>
|
||||
</BorderPane>
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.scene.layout.BorderPane?>
|
||||
<BorderPane xmlns="http://javafx.com/javafx/22" xmlns:fx="http://javafx.com/fxml/1">
|
||||
<bottom>
|
||||
<fx:include fx:id="includeView" source="includeView.fxml"/>
|
||||
</bottom>
|
||||
</BorderPane>
|
||||
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.scene.control.Button?>
|
||||
<?import javafx.scene.layout.BorderPane?>
|
||||
<?import javafx.scene.layout.HBox?>
|
||||
<BorderPane xmlns="http://javafx.com/javafx/22" xmlns:fx="http://javafx.com/fxml/1"
|
||||
fx:controller="com.github.gtache.fxml.compiler.maven.internal.InfoController">
|
||||
<bottom>
|
||||
<HBox>
|
||||
<children>
|
||||
<Button fx:id="button" onAction="#onAction" onContextMenuRequested="$controller.onContextMenuRequested"
|
||||
text="text"/>
|
||||
<fx:include fx:id="includeView" source="includeView.fxml"/>
|
||||
</children>
|
||||
</HBox>
|
||||
</bottom>
|
||||
</BorderPane>
|
||||
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.scene.control.Button?>
|
||||
<?import javafx.scene.layout.BorderPane?>
|
||||
<?import javafx.scene.layout.HBox?>
|
||||
<BorderPane xmlns="http://javafx.com/javafx/22" xmlns:fx="http://javafx.com/fxml/1"
|
||||
fx:controller="com.github.gtache.fxml.compiler.maven.internal.InfoController">
|
||||
<bottom>
|
||||
<HBox>
|
||||
<children>
|
||||
<Button fx:id="button" onAction="onAction"/>
|
||||
</children>
|
||||
</HBox>
|
||||
</bottom>
|
||||
</BorderPane>
|
||||
Reference in New Issue
Block a user