Fixes generics, only creates one constructor, adds some tests, adds java compatibility options, rework some classes, fixes some problems
This commit is contained in:
@@ -1,32 +1,24 @@
|
||||
package com.github.gtache.fxml.compiler.maven;
|
||||
|
||||
import com.github.gtache.fxml.compiler.ControllerInjection;
|
||||
import com.github.gtache.fxml.compiler.GenerationException;
|
||||
import com.github.gtache.fxml.compiler.compatibility.impl.GenerationCompatibilityImpl;
|
||||
import com.github.gtache.fxml.compiler.impl.ControllerFieldInjectionTypes;
|
||||
import com.github.gtache.fxml.compiler.impl.ControllerInjectionImpl;
|
||||
import com.github.gtache.fxml.compiler.impl.ControllerInjectionTypes;
|
||||
import com.github.gtache.fxml.compiler.impl.ControllerMethodsInjectionType;
|
||||
import com.github.gtache.fxml.compiler.impl.GenerationParametersImpl;
|
||||
import com.github.gtache.fxml.compiler.impl.GenerationRequestImpl;
|
||||
import com.github.gtache.fxml.compiler.impl.GeneratorImpl;
|
||||
import com.github.gtache.fxml.compiler.impl.ResourceBundleInjectionImpl;
|
||||
import com.github.gtache.fxml.compiler.impl.ResourceBundleInjectionTypes;
|
||||
import com.github.gtache.fxml.compiler.parsing.ParseException;
|
||||
import com.github.gtache.fxml.compiler.parsing.xml.DOMFXMLParser;
|
||||
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.AbstractMojo;
|
||||
import org.apache.maven.plugin.MojoExecutionException;
|
||||
import org.apache.maven.plugins.annotations.LifecyclePhase;
|
||||
import org.apache.maven.plugins.annotations.Mojo;
|
||||
import org.apache.maven.plugins.annotations.Parameter;
|
||||
import org.apache.maven.project.MavenProject;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
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;
|
||||
|
||||
@@ -35,7 +27,6 @@ import java.util.Map;
|
||||
*/
|
||||
@Mojo(name = "compile", defaultPhase = LifecyclePhase.GENERATE_SOURCES)
|
||||
public class FXMLCompilerMojo extends AbstractMojo {
|
||||
private static final DocumentBuilderFactory DOCUMENT_BUILDER_FACTORY = DocumentBuilderFactory.newInstance();
|
||||
|
||||
@Parameter(defaultValue = "${project}", required = true, readonly = true)
|
||||
private MavenProject project;
|
||||
@@ -43,146 +34,61 @@ public class FXMLCompilerMojo extends AbstractMojo {
|
||||
@Parameter(property = "output-directory", defaultValue = "${project.build.directory}/generated-sources/java", required = true)
|
||||
private Path outputDirectory;
|
||||
|
||||
@Parameter(property = "target-version", defaultValue = "21", required = true)
|
||||
private int targetVersion;
|
||||
|
||||
@Parameter(property = "use-image-inputstream-constructor", defaultValue = "true", required = true)
|
||||
private boolean useImageInputStreamConstructor;
|
||||
|
||||
@Parameter(property = "controller-injection", defaultValue = "INSTANCE", required = true)
|
||||
private ControllerInjectionTypes controllerInjectionType;
|
||||
|
||||
@Parameter(property = "field-injection", defaultValue = "REFLECTION", required = true)
|
||||
private ControllerFieldInjectionTypes fieldInjectionTypes;
|
||||
private ControllerFieldInjectionTypes fieldInjectionType;
|
||||
|
||||
@Parameter(property = "method-injection", defaultValue = "REFLECTION", required = true)
|
||||
private ControllerMethodsInjectionType methodsInjectionType;
|
||||
private ControllerMethodsInjectionType methodInjectionType;
|
||||
|
||||
@Parameter(property = "bundle-injection", defaultValue = "CONSTRUCTOR", required = true)
|
||||
private ResourceBundleInjectionTypes bundleInjectionType;
|
||||
@Parameter(property = "resource-injection", defaultValue = "CONSTRUCTOR", required = true)
|
||||
private ResourceBundleInjectionTypes resourceInjectionType;
|
||||
|
||||
@Parameter(property = "resource-map")
|
||||
private Map<String, String> resourceMap;
|
||||
|
||||
@Parameter(property = "bundle-map")
|
||||
private Map<String, String> bundleMap;
|
||||
|
||||
@Override
|
||||
public void execute() throws MojoExecutionException {
|
||||
final var fxmls = getAllFXMLs();
|
||||
final var controllerMapping = createControllerMapping(fxmls);
|
||||
final var mapping = createMapping(fxmls, controllerMapping);
|
||||
compile(mapping);
|
||||
}
|
||||
|
||||
private Map<Path, Path> getAllFXMLs() throws MojoExecutionException {
|
||||
final var map = new HashMap<Path, Path>();
|
||||
for (final var resource : project.getResources()) {
|
||||
final var path = Paths.get(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();
|
||||
getLog().info("Found " + curList);
|
||||
for (final var p : curList) {
|
||||
map.put(p, path);
|
||||
}
|
||||
} catch (final IOException e) {
|
||||
throw new MojoExecutionException("Error reading resources", e);
|
||||
}
|
||||
} else {
|
||||
getLog().info("Directory " + path + " does not exist");
|
||||
}
|
||||
if (fieldInjectionType == ControllerFieldInjectionTypes.FACTORY && controllerInjectionType != ControllerInjectionTypes.FACTORY) {
|
||||
getLog().warn("Field injection is set to FACTORY : Forcing controller injection to FACTORY");
|
||||
controllerInjectionType = ControllerInjectionTypes.FACTORY;
|
||||
}
|
||||
return map;
|
||||
final var fxmls = FXMLProvider.getFXMLs(project);
|
||||
final var controllerMapping = createControllerMapping(fxmls);
|
||||
final var compilationInfoMapping = createCompilationInfoMapping(fxmls, controllerMapping);
|
||||
compile(compilationInfoMapping);
|
||||
}
|
||||
|
||||
private static 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, getControllerClass(fxml));
|
||||
mapping.put(fxml, ControllerProvider.getController(fxml));
|
||||
}
|
||||
return mapping;
|
||||
}
|
||||
|
||||
private static String getControllerClass(final Path fxml) throws MojoExecutionException {
|
||||
try {
|
||||
final var documentBuilder = DOCUMENT_BUILDER_FACTORY.newDocumentBuilder();
|
||||
final var document = documentBuilder.parse(fxml.toFile());
|
||||
document.getDocumentElement().normalize();
|
||||
|
||||
final var controller = document.getDocumentElement().getAttribute("fx:controller");
|
||||
if (controller.isBlank()) {
|
||||
throw new MojoExecutionException("Missing controller attribute for " + fxml);
|
||||
} else {
|
||||
return controller;
|
||||
}
|
||||
} catch (final SAXException | IOException | ParserConfigurationException e) {
|
||||
throw new MojoExecutionException("Error parsing fxml at " + fxml, e);
|
||||
}
|
||||
}
|
||||
|
||||
private Map<Path, CompilationInfo> createMapping(final Map<? extends Path, ? extends Path> fxmls, final Map<? extends Path, String> controllerMapping) throws MojoExecutionException {
|
||||
final var compilationInfoProvider = new CompilationInfoProvider(project, outputDirectory, getLog());
|
||||
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>();
|
||||
for (final var entry : fxmls.entrySet()) {
|
||||
final var info = compilationInfoProvider.getCompilationInfo(entry.getValue(), entry.getKey(), controllerMapping);
|
||||
final var info = CompilationInfoProvider.getCompilationInfo(entry.getValue(), entry.getKey(), controllerMapping, outputDirectory, project);
|
||||
mapping.put(entry.getKey(), info);
|
||||
}
|
||||
return mapping;
|
||||
}
|
||||
|
||||
private void compile(final Map<Path, CompilationInfo> mapping) throws MojoExecutionException {
|
||||
final var generator = new GeneratorImpl();
|
||||
final var parser = new DOMFXMLParser();
|
||||
final var controllerInfoProvider = new ControllerInfoProvider(getLog());
|
||||
try {
|
||||
for (final var entry : mapping.entrySet()) {
|
||||
final var inputPath = entry.getKey();
|
||||
final var info = entry.getValue();
|
||||
getLog().info("Parsing " + inputPath + " with " + parser.getClass().getSimpleName());
|
||||
final var root = parser.parse(inputPath);
|
||||
final var controllerInjection = getControllerInjection(mapping, info);
|
||||
final var sourceToGeneratedClassName = getSourceToGeneratedClassName(mapping, info);
|
||||
final var sourceToControllerName = getSourceToControllerName(mapping, info);
|
||||
final var resourceBundleInjection = new ResourceBundleInjectionImpl(bundleInjectionType, getBundleName(info));
|
||||
final var parameters = new GenerationParametersImpl(controllerInjection, sourceToGeneratedClassName, sourceToControllerName, resourceBundleInjection);
|
||||
final var controllerInfo = controllerInfoProvider.getControllerInfo(info);
|
||||
final var output = info.outputFile();
|
||||
final var request = new GenerationRequestImpl(parameters, controllerInfo, root, info.outputClass());
|
||||
getLog().info("Compiling " + inputPath);
|
||||
final var content = generator.generate(request);
|
||||
final var outputDir = output.getParent();
|
||||
Files.createDirectories(outputDir);
|
||||
Files.writeString(output, content);
|
||||
getLog().info("Compiled " + inputPath + " to " + output);
|
||||
}
|
||||
} catch (final IOException | RuntimeException | ParseException | GenerationException e) {
|
||||
throw new MojoExecutionException("Error compiling fxml", e);
|
||||
}
|
||||
final var parameters = new GenerationParametersImpl(new GenerationCompatibilityImpl(targetVersion), useImageInputStreamConstructor, resourceMap,
|
||||
controllerInjectionType, fieldInjectionType, methodInjectionType, resourceInjectionType);
|
||||
Compiler.compile(mapping, parameters);
|
||||
project.addCompileSourceRoot(outputDirectory.toAbsolutePath().toString());
|
||||
}
|
||||
|
||||
private String getBundleName(final CompilationInfo info) {
|
||||
return bundleMap == null ? "" : bundleMap.getOrDefault(info.inputFile().toString(), "");
|
||||
}
|
||||
|
||||
private static Map<String, String> getSourceToControllerName(final Map<Path, CompilationInfo> mapping, final CompilationInfo info) {
|
||||
final var ret = new HashMap<String, String>();
|
||||
for (final var entry : info.includes().entrySet()) {
|
||||
ret.put(entry.getKey(), mapping.get(entry.getValue()).controllerClass());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
private static Map<String, String> getSourceToGeneratedClassName(final Map<Path, CompilationInfo> mapping, final CompilationInfo info) {
|
||||
final var ret = new HashMap<String, String>();
|
||||
for (final var entry : info.includes().entrySet()) {
|
||||
ret.put(entry.getKey(), mapping.get(entry.getValue()).outputClass());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
private Map<String, ControllerInjection> getControllerInjection(final Map<Path, CompilationInfo> compilationInfoMapping, final CompilationInfo info) {
|
||||
final var ret = new HashMap<String, ControllerInjection>();
|
||||
ret.put(info.controllerClass(), getControllerInjection(info));
|
||||
for (final var entry : info.includes().entrySet()) {
|
||||
final var key = entry.getKey();
|
||||
final var value = entry.getValue();
|
||||
final var subInfo = compilationInfoMapping.get(value);
|
||||
ret.put(key, getControllerInjection(subInfo));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
private ControllerInjection getControllerInjection(final CompilationInfo info) {
|
||||
return new ControllerInjectionImpl(fieldInjectionTypes, methodsInjectionType, info.controllerClass());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.github.gtache.fxml.compiler.maven;
|
||||
package com.github.gtache.fxml.compiler.maven.internal;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.HashMap;
|
||||
@@ -10,21 +10,21 @@ import java.util.Set;
|
||||
/**
|
||||
* Info about FXML file compilation
|
||||
*
|
||||
* @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 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
|
||||
*/
|
||||
record CompilationInfo(Path inputFile, Path outputFile, String outputClass, Path controllerFile,
|
||||
String controllerClass,
|
||||
Set<FieldInfo> injectedFields,
|
||||
Set<String> injectedMethods, Map<String, Path> includes) {
|
||||
public record CompilationInfo(Path inputFile, Path outputFile, String outputClass, Path controllerFile,
|
||||
String controllerClass, Set<FieldInfo> injectedFields, Set<String> injectedMethods,
|
||||
Map<String, Path> includes, boolean requiresResourceBundle) {
|
||||
|
||||
CompilationInfo {
|
||||
public CompilationInfo {
|
||||
Objects.requireNonNull(inputFile);
|
||||
Objects.requireNonNull(outputFile);
|
||||
Objects.requireNonNull(outputClass);
|
||||
@@ -44,6 +44,7 @@ record CompilationInfo(Path inputFile, Path outputFile, String outputClass, Path
|
||||
private String outputClass;
|
||||
private Path controllerFile;
|
||||
private String controllerClass;
|
||||
private boolean requiresResourceBundle;
|
||||
private final Set<FieldInfo> injectedFields;
|
||||
private final Set<String> injectedMethods;
|
||||
private final Map<String, Path> includes;
|
||||
@@ -98,8 +99,13 @@ record CompilationInfo(Path inputFile, Path outputFile, String outputClass, Path
|
||||
return this;
|
||||
}
|
||||
|
||||
Builder requiresResourceBundle() {
|
||||
this.requiresResourceBundle = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
CompilationInfo build() {
|
||||
return new CompilationInfo(inputFile, outputFile, outputClass, controllerFile, controllerClass, injectedFields, injectedMethods, includes);
|
||||
return new CompilationInfo(inputFile, outputFile, outputClass, controllerFile, controllerClass, injectedFields, injectedMethods, includes, requiresResourceBundle);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,10 @@
|
||||
package com.github.gtache.fxml.compiler.maven;
|
||||
package com.github.gtache.fxml.compiler.maven.internal;
|
||||
|
||||
import com.github.gtache.fxml.compiler.maven.FXMLCompilerMojo;
|
||||
import javafx.event.EventHandler;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.maven.plugin.MojoExecutionException;
|
||||
import org.apache.maven.plugin.logging.Log;
|
||||
import org.apache.maven.project.MavenProject;
|
||||
import org.w3c.dom.Node;
|
||||
import org.xml.sax.SAXException;
|
||||
@@ -17,28 +19,32 @@ 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}
|
||||
*/
|
||||
class CompilationInfoProvider {
|
||||
public final class CompilationInfoProvider {
|
||||
|
||||
private static final Logger logger = LogManager.getLogger(CompilationInfoProvider.class);
|
||||
private static final DocumentBuilderFactory DOCUMENT_BUILDER_FACTORY = DocumentBuilderFactory.newInstance();
|
||||
private static final Pattern START_DOT_PATTERN = Pattern.compile("^\\.");
|
||||
|
||||
private final MavenProject project;
|
||||
private final Path outputDirectory;
|
||||
private final Log logger;
|
||||
|
||||
CompilationInfoProvider(final MavenProject project, final Path outputDirectory, final Log logger) {
|
||||
this.project = requireNonNull(project);
|
||||
this.outputDirectory = requireNonNull(outputDirectory);
|
||||
this.logger = requireNonNull(logger);
|
||||
private CompilationInfoProvider() {
|
||||
}
|
||||
|
||||
CompilationInfo getCompilationInfo(final Path root, final Path inputPath, final Map<? extends Path, String> controllerMapping) throws MojoExecutionException {
|
||||
logger.info("Parsing " + inputPath);
|
||||
/**
|
||||
* Gets the compilation info for the given input
|
||||
*
|
||||
* @param root The root path
|
||||
* @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 {
|
||||
logger.info("Parsing {}", inputPath);
|
||||
try {
|
||||
final var documentBuilder = DOCUMENT_BUILDER_FACTORY.newDocumentBuilder();
|
||||
final var document = documentBuilder.parse(inputPath.toFile());
|
||||
@@ -52,8 +58,8 @@ class CompilationInfoProvider {
|
||||
final var targetPath = Paths.get(replacedPrefixPath.replace(inputFilename, outputFilename));
|
||||
builder.outputFile(targetPath);
|
||||
builder.outputClass(outputClass);
|
||||
handleNode(document.getDocumentElement(), builder, controllerMapping);
|
||||
logger.info(inputPath + " will be compiled to " + targetPath);
|
||||
handleNode(document.getDocumentElement(), builder, controllerMapping, project);
|
||||
logger.info("{} will be compiled to {}", inputPath, targetPath);
|
||||
return builder.build();
|
||||
} catch (final SAXException | IOException | ParserConfigurationException e) {
|
||||
throw new MojoExecutionException("Error parsing fxml at " + inputPath, e);
|
||||
@@ -84,15 +90,15 @@ class CompilationInfoProvider {
|
||||
return builder.toString().replace(".fxml", ".java");
|
||||
}
|
||||
|
||||
private void handleNode(final Node node, final CompilationInfo.Builder builder, final Map<? extends Path, String> controllerMapping) throws MojoExecutionException {
|
||||
private static void handleNode(final Node node, final CompilationInfo.Builder builder, final Map<? extends Path, String> controllerMapping, final MavenProject project) throws MojoExecutionException {
|
||||
if (node.getNodeName().equals("fx:include")) {
|
||||
handleInclude(node, builder);
|
||||
}
|
||||
handleAttributes(node, builder, controllerMapping);
|
||||
handleChildren(node, builder, controllerMapping);
|
||||
handleAttributes(node, builder, controllerMapping, project);
|
||||
handleChildren(node, builder, controllerMapping, project);
|
||||
}
|
||||
|
||||
private void handleInclude(final Node node, final CompilationInfo.Builder builder) throws MojoExecutionException {
|
||||
private static void handleInclude(final Node node, final CompilationInfo.Builder builder) throws MojoExecutionException {
|
||||
final var map = node.getAttributes();
|
||||
if (map == null) {
|
||||
throw new MojoExecutionException("Missing attributes for include");
|
||||
@@ -103,7 +109,7 @@ class CompilationInfoProvider {
|
||||
} else {
|
||||
final var source = sourceAttr.getNodeValue();
|
||||
final var path = getRelativePath(builder.inputFile(), source);
|
||||
logger.info("Found include " + source);
|
||||
logger.info("Found include {}", source);
|
||||
builder.addInclude(source, path);
|
||||
}
|
||||
}
|
||||
@@ -113,14 +119,14 @@ class CompilationInfoProvider {
|
||||
return base.getParent().resolve(relative).normalize();
|
||||
}
|
||||
|
||||
private void handleChildren(final Node node, final CompilationInfo.Builder builder, final Map<? extends Path, String> controllerMapping) throws MojoExecutionException {
|
||||
private static void handleChildren(final Node node, final CompilationInfo.Builder builder, final Map<? extends Path, String> controllerMapping, final MavenProject project) throws MojoExecutionException {
|
||||
final var nl = node.getChildNodes();
|
||||
for (var i = 0; i < nl.getLength(); i++) {
|
||||
handleNode(nl.item(i), builder, controllerMapping);
|
||||
handleNode(nl.item(i), builder, controllerMapping, project);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleAttributes(final Node node, final CompilationInfo.Builder builder, final Map<? extends Path, String> controllerMapping) throws MojoExecutionException {
|
||||
private static void handleAttributes(final Node node, final CompilationInfo.Builder builder, final Map<? extends Path, String> controllerMapping, final MavenProject project) throws MojoExecutionException {
|
||||
final var map = node.getAttributes();
|
||||
if (map != null) {
|
||||
for (var i = 0; i < map.getLength(); i++) {
|
||||
@@ -130,20 +136,20 @@ class CompilationInfoProvider {
|
||||
if (name.startsWith("on")) {
|
||||
if (value.startsWith("#")) {
|
||||
final var methodName = value.replace("#", "");
|
||||
logger.debug("Found injected method " + methodName);
|
||||
logger.debug("Found injected method {}", methodName);
|
||||
builder.addInjectedMethod(methodName);
|
||||
} else if (value.startsWith("$controller.")) {
|
||||
final var fieldName = value.replace("$controller.", "");
|
||||
logger.debug("Found injected field " + fieldName);
|
||||
logger.debug("Found injected field {}", fieldName);
|
||||
builder.addInjectedField(fieldName, EventHandler.class.getName());
|
||||
} else {
|
||||
throw new MojoExecutionException("Unexpected attribute " + name + " with value " + value);
|
||||
}
|
||||
} else if (name.equals("fx:controller")) {
|
||||
handleController(value, builder);
|
||||
handleController(value, builder, project);
|
||||
} else if (name.equals("fx:id")) {
|
||||
final var type = node.getNodeName();
|
||||
logger.debug("Found injected field " + value + " of type " + type);
|
||||
logger.debug("Found injected field {} of type {}", value, type);
|
||||
if (type.equals("fx:include")) {
|
||||
final var path = getRelativePath(builder.inputFile(), map.getNamedItem("source").getNodeValue()).normalize();
|
||||
final var controllerClass = controllerMapping.get(path);
|
||||
@@ -154,19 +160,21 @@ class CompilationInfoProvider {
|
||||
} else {
|
||||
builder.addInjectedField(value, type);
|
||||
}
|
||||
} else if (value.startsWith("%")) {
|
||||
builder.requiresResourceBundle();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void handleController(final String controllerClass, final CompilationInfo.Builder builder) throws MojoExecutionException {
|
||||
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))
|
||||
.filter(Files::exists)
|
||||
.findFirst()
|
||||
.orElseThrow(() -> new MojoExecutionException("Cannot find controller " + controllerClass));
|
||||
logger.info("Found controller " + controllerClass);
|
||||
logger.info("Found controller {}", controllerClass);
|
||||
builder.controllerFile(path);
|
||||
builder.controllerClass(controllerClass);
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
package com.github.gtache.fxml.compiler.maven.internal;
|
||||
|
||||
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.impl.GenerationRequestImpl;
|
||||
import com.github.gtache.fxml.compiler.impl.GeneratorImpl;
|
||||
import com.github.gtache.fxml.compiler.parsing.FXMLParser;
|
||||
import com.github.gtache.fxml.compiler.parsing.ParseException;
|
||||
import com.github.gtache.fxml.compiler.parsing.xml.DOMFXMLParser;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.maven.plugin.MojoExecutionException;
|
||||
|
||||
import javax.inject.Named;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Creates compiled Java code
|
||||
*/
|
||||
@Named
|
||||
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 Compiler() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles the given files
|
||||
*
|
||||
* @param mapping The mapping of file to compile to compilation info
|
||||
* @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 {
|
||||
for (final var entry : mapping.entrySet()) {
|
||||
compile(entry.getKey(), entry.getValue(), mapping, parameters);
|
||||
}
|
||||
}
|
||||
|
||||
private static 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);
|
||||
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 outputDir = output.getParent();
|
||||
Files.createDirectories(outputDir);
|
||||
Files.writeString(output, content);
|
||||
logger.info("Compiled {} to {}", inputPath, output);
|
||||
} catch (final IOException | RuntimeException | ParseException | GenerationException e) {
|
||||
throw new MojoExecutionException("Error compiling fxml", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,55 +1,45 @@
|
||||
package com.github.gtache.fxml.compiler.maven;
|
||||
package com.github.gtache.fxml.compiler.maven.internal;
|
||||
|
||||
import com.github.gtache.fxml.compiler.ControllerFieldInfo;
|
||||
import com.github.gtache.fxml.compiler.ControllerInfo;
|
||||
import com.github.gtache.fxml.compiler.impl.ClassesFinder;
|
||||
import com.github.gtache.fxml.compiler.impl.ControllerFieldInfoImpl;
|
||||
import com.github.gtache.fxml.compiler.impl.ControllerInfoImpl;
|
||||
import com.github.gtache.fxml.compiler.maven.FXMLCompilerMojo;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.maven.plugin.MojoExecutionException;
|
||||
import org.apache.maven.plugin.logging.Log;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Helper class for {@link FXMLCompilerMojo} to provides {@link ControllerInfo}
|
||||
*/
|
||||
class ControllerInfoProvider {
|
||||
final class ControllerInfoProvider {
|
||||
|
||||
private static final Logger logger = LogManager.getLogger(ControllerInfoProvider.class);
|
||||
private static final Pattern IMPORT_PATTERN = Pattern.compile("import\\s+(?:static\\s+)?(?<import>[^;]+);");
|
||||
private static final Pattern INITIALIZE_PATTERN = Pattern.compile("void\\s+initialize\\s*\\(\\s*\\)\\s*");
|
||||
|
||||
private static final Set<String> JAVA_LANG_CLASSES;
|
||||
|
||||
static {
|
||||
final var set = new HashSet<String>();
|
||||
set.add("Object");
|
||||
set.add("String");
|
||||
set.add("Boolean");
|
||||
set.add("Character");
|
||||
set.add("Byte");
|
||||
set.add("Short");
|
||||
set.add("Integer");
|
||||
set.add("Long");
|
||||
set.add("Float");
|
||||
set.add("Double");
|
||||
JAVA_LANG_CLASSES = Set.copyOf(set);
|
||||
private ControllerInfoProvider() {
|
||||
}
|
||||
|
||||
private final Log logger;
|
||||
|
||||
ControllerInfoProvider(final Log logger) {
|
||||
this.logger = Objects.requireNonNull(logger);
|
||||
}
|
||||
|
||||
ControllerInfo getControllerInfo(final CompilationInfo info) throws MojoExecutionException {
|
||||
/**
|
||||
* Gets the controller info for the given compilation info
|
||||
*
|
||||
* @param info The compilation info
|
||||
* @return The controller info
|
||||
* @throws MojoExecutionException If an error occurs
|
||||
*/
|
||||
static ControllerInfo getControllerInfo(final CompilationInfo info) throws MojoExecutionException {
|
||||
try {
|
||||
final var content = Files.readString(info.controllerFile());
|
||||
final var imports = getImports(content);
|
||||
@@ -58,16 +48,14 @@ class ControllerInfoProvider {
|
||||
final var name = fieldInfo.name();
|
||||
final var type = fieldInfo.type();
|
||||
if (fillFieldInfo(type, name, content, imports, propertyGenericTypes)) {
|
||||
logger.debug("Found injected field " + name + " of type " + type + " with generic types "
|
||||
+ propertyGenericTypes.get(name) + " in controller " + info.controllerFile());
|
||||
logger.debug("Found injected field {} of type {} with generic types {} in controller {}", name, type, propertyGenericTypes.get(name), info.controllerFile());
|
||||
} else if (type.contains(".")) {
|
||||
final var simpleName = type.substring(type.lastIndexOf('.') + 1);
|
||||
if (fillFieldInfo(simpleName, name, content, imports, propertyGenericTypes)) {
|
||||
logger.debug("Found injected field " + name + " of type " + simpleName + " with generic types "
|
||||
+ propertyGenericTypes.get(name) + " in controller " + info.controllerFile());
|
||||
logger.debug("Found injected field {} of type {} with generic types {} in controller {}", name, simpleName, propertyGenericTypes.get(name), info.controllerFile());
|
||||
}
|
||||
} else {
|
||||
logger.info("Field " + name + "(" + type + ")" + " not found in controller " + info.controllerFile());
|
||||
logger.info("Field {}({}) not found in controller {}", name, type, info.controllerFile());
|
||||
}
|
||||
}
|
||||
final var handlerHasArgument = new HashMap<String, Boolean>();
|
||||
@@ -77,12 +65,13 @@ class ControllerInfoProvider {
|
||||
if (matcher.find()) {
|
||||
final var arg = matcher.group("arg");
|
||||
handlerHasArgument.put(name, arg != null && !arg.isBlank());
|
||||
logger.debug("Found injected method " + name + " with argument " + arg + " in controller " + info.controllerFile());
|
||||
logger.debug("Found injected method {} with argument {} in controller {}", name, arg, info.controllerFile());
|
||||
} else {
|
||||
throw new MojoExecutionException("Cannot find method " + name + " in controller " + info.controllerFile());
|
||||
}
|
||||
}
|
||||
return new ControllerInfoImpl(handlerHasArgument, propertyGenericTypes);
|
||||
final var hasInitialize = INITIALIZE_PATTERN.matcher(content).find();
|
||||
return new ControllerInfoImpl(info.controllerClass(), handlerHasArgument, propertyGenericTypes, hasInitialize);
|
||||
} catch (final IOException e) {
|
||||
throw new MojoExecutionException("Error reading controller " + info.controllerFile(), e);
|
||||
}
|
||||
@@ -115,28 +104,13 @@ class ControllerInfoProvider {
|
||||
}
|
||||
|
||||
private static boolean fillFieldInfo(final String type, final String name, final CharSequence content, final Imports imports, final Map<? super String, ? super ControllerFieldInfo> fieldInfos) throws MojoExecutionException {
|
||||
final var pattern = Pattern.compile(Pattern.quote(type) + "(?<type><[^>]+>)?\\s+" + Pattern.quote(name) + "\\s*;");
|
||||
final var pattern = Pattern.compile(Pattern.quote(type) + "\\s*(?<type><.+>)?\\s*" + Pattern.quote(name) + "\\s*;");
|
||||
final var matcher = pattern.matcher(content);
|
||||
if (matcher.find()) {
|
||||
final var genericTypes = matcher.group("type");
|
||||
if (genericTypes != null && !genericTypes.isBlank()) {
|
||||
final var split = genericTypes.replace("<", "").replace(">", "").split(",");
|
||||
final var resolved = new ArrayList<String>();
|
||||
for (final var s : split) {
|
||||
final var trimmed = s.trim();
|
||||
if (trimmed.contains(".") || JAVA_LANG_CLASSES.contains(trimmed)) {
|
||||
resolved.add(trimmed);
|
||||
} else {
|
||||
final var imported = imports.imports().get(trimmed);
|
||||
if (imported == null) {
|
||||
throw new MojoExecutionException("Cannot find class " + trimmed + " probably in one of " + imports.packages() + " ; " +
|
||||
"Use non-wildcard imports, use fully qualified name or put the classes in a dependency.");
|
||||
} else {
|
||||
resolved.add(imported);
|
||||
}
|
||||
}
|
||||
}
|
||||
fieldInfos.put(name, new ControllerFieldInfoImpl(name, resolved));
|
||||
final var parsed = new GenericParser(genericTypes, imports.imports()).parse();
|
||||
fieldInfos.put(name, new ControllerFieldInfoImpl(name, parsed));
|
||||
} else {
|
||||
fieldInfos.put(name, new ControllerFieldInfoImpl(name, List.of()));
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package com.github.gtache.fxml.compiler.maven.internal;
|
||||
|
||||
import org.apache.maven.plugin.MojoExecutionException;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import javax.inject.Named;
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
|
||||
/**
|
||||
* Extracts controller class from FXMLs
|
||||
*/
|
||||
@Named
|
||||
public final class ControllerProvider {
|
||||
private static final DocumentBuilder DOCUMENT_BUILDER;
|
||||
|
||||
static {
|
||||
try {
|
||||
DOCUMENT_BUILDER = DocumentBuilderFactory.newInstance().newDocumentBuilder();
|
||||
} catch (final ParserConfigurationException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private ControllerProvider() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the controller class for the given FXML
|
||||
*
|
||||
* @param fxml The FXML
|
||||
* @return The controller class
|
||||
* @throws MojoExecutionException If an error occurs
|
||||
*/
|
||||
public static String getController(final Path fxml) throws MojoExecutionException {
|
||||
try {
|
||||
final var document = DOCUMENT_BUILDER.parse(fxml.toFile());
|
||||
document.getDocumentElement().normalize();
|
||||
|
||||
final var controller = document.getDocumentElement().getAttribute("fx:controller");
|
||||
if (controller.isBlank()) {
|
||||
throw new MojoExecutionException("Missing controller attribute for " + fxml);
|
||||
} else {
|
||||
return controller;
|
||||
}
|
||||
} catch (final SAXException | IOException e) {
|
||||
throw new MojoExecutionException("Error parsing fxml at " + fxml, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package com.github.gtache.fxml.compiler.maven.internal;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.maven.plugin.MojoExecutionException;
|
||||
import org.apache.maven.project.MavenProject;
|
||||
|
||||
import javax.inject.Named;
|
||||
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;
|
||||
|
||||
/**
|
||||
* Extracts FXML paths from Maven project
|
||||
*/
|
||||
@Named
|
||||
public final class FXMLProvider {
|
||||
private static final Logger logger = LogManager.getLogger(FXMLProvider.class);
|
||||
|
||||
private FXMLProvider() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 {
|
||||
final var map = new HashMap<Path, Path>();
|
||||
for (final var resource : project.getResources()) {
|
||||
final var path = Paths.get(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();
|
||||
logger.info("Found {}", curList);
|
||||
for (final var p : curList) {
|
||||
map.put(p, path);
|
||||
}
|
||||
} catch (final IOException e) {
|
||||
throw new MojoExecutionException("Error reading resources", e);
|
||||
}
|
||||
} else {
|
||||
logger.info("Directory {} does not exist", path);
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.github.gtache.fxml.compiler.maven;
|
||||
package com.github.gtache.fxml.compiler.maven.internal;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
@@ -9,6 +9,14 @@ import java.util.Objects;
|
||||
* @param name The field name
|
||||
*/
|
||||
record FieldInfo(String type, String name) {
|
||||
|
||||
/**
|
||||
* Instantiates a new info
|
||||
*
|
||||
* @param type The field type
|
||||
* @param name The field name
|
||||
* @throws NullPointerException if any parameter is null
|
||||
*/
|
||||
FieldInfo {
|
||||
Objects.requireNonNull(type);
|
||||
Objects.requireNonNull(name);
|
||||
@@ -0,0 +1,102 @@
|
||||
package com.github.gtache.fxml.compiler.maven.internal;
|
||||
|
||||
import com.github.gtache.fxml.compiler.GenericTypes;
|
||||
import com.github.gtache.fxml.compiler.impl.GenericTypesImpl;
|
||||
import org.apache.maven.plugin.MojoExecutionException;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Parser of generic types
|
||||
*/
|
||||
final class GenericParser {
|
||||
|
||||
private static final Set<String> JAVA_LANG_CLASSES = Set.of(
|
||||
"Boolean",
|
||||
"Byte",
|
||||
"Character",
|
||||
"Double",
|
||||
"Float",
|
||||
"Integer",
|
||||
"Long",
|
||||
"Object",
|
||||
"Short",
|
||||
"String"
|
||||
);
|
||||
|
||||
private final String content;
|
||||
private final Map<String, String> imports;
|
||||
private int index;
|
||||
|
||||
GenericParser(final String content, final Map<String, String> imports) {
|
||||
this.content = Objects.requireNonNull(content);
|
||||
this.imports = Map.copyOf(imports);
|
||||
}
|
||||
|
||||
List<GenericTypes> parse() throws MojoExecutionException {
|
||||
return parseGenericTypes();
|
||||
}
|
||||
|
||||
private List<GenericTypes> parseGenericTypes() throws MojoExecutionException {
|
||||
final var ret = new ArrayList<GenericTypes>();
|
||||
eatSpaces();
|
||||
eat('<');
|
||||
do {
|
||||
eatSpaces();
|
||||
final var type = parseType();
|
||||
eatSpaces();
|
||||
if (peek() == '<') {
|
||||
final var genericTypes = parseGenericTypes();
|
||||
ret.add(new GenericTypesImpl(type, genericTypes));
|
||||
} else if (peek() == '>') {
|
||||
eat('>');
|
||||
return ret;
|
||||
} else if (peek() == ',') {
|
||||
eat(',');
|
||||
ret.add(new GenericTypesImpl(type, List.of()));
|
||||
}
|
||||
} while (index < content.length());
|
||||
return ret;
|
||||
}
|
||||
|
||||
private void eat(final char c) {
|
||||
if (peek() == c) {
|
||||
read();
|
||||
} else {
|
||||
throw new IllegalArgumentException("Expected " + c + " at " + index + " in " + content);
|
||||
}
|
||||
}
|
||||
|
||||
private void eatSpaces() {
|
||||
while (peek() == ' ') {
|
||||
read();
|
||||
}
|
||||
}
|
||||
|
||||
private String parseType() throws MojoExecutionException {
|
||||
final var sb = new StringBuilder();
|
||||
while (peek() != '<' && index < content.length()) {
|
||||
sb.append(read());
|
||||
}
|
||||
final var type = sb.toString();
|
||||
if (type.contains(".") || JAVA_LANG_CLASSES.contains(type)) {
|
||||
return type;
|
||||
} else if (imports.containsKey(type)) {
|
||||
return imports.get(type);
|
||||
} else {
|
||||
throw new MojoExecutionException("Cannot find class " + type + " ; Use fully qualified name or put the classes in a dependency.");
|
||||
}
|
||||
}
|
||||
|
||||
private char peek() {
|
||||
return content.charAt(index);
|
||||
}
|
||||
|
||||
private char read() {
|
||||
return content.charAt(index++);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.github.gtache.fxml.compiler.maven.internal;
|
||||
|
||||
import com.github.gtache.fxml.compiler.SourceInfo;
|
||||
import com.github.gtache.fxml.compiler.impl.SourceInfoImpl;
|
||||
import com.github.gtache.fxml.compiler.maven.FXMLCompilerMojo;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Helper class for {@link FXMLCompilerMojo} to provides {@link SourceInfo}
|
||||
*/
|
||||
final class SourceInfoProvider {
|
||||
|
||||
private SourceInfoProvider() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides the {@link SourceInfo} for the given compilation info
|
||||
*
|
||||
* @param info The compilation info
|
||||
* @param mapping The mapping of file to compilation info
|
||||
* @return The source info
|
||||
*/
|
||||
static SourceInfo getSourceInfo(final CompilationInfo info, final Map<Path, CompilationInfo> mapping) {
|
||||
final var outputClass = info.outputClass();
|
||||
final var controllerClass = info.controllerClass();
|
||||
final var inputFile = info.inputFile();
|
||||
final var includes = info.includes();
|
||||
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
|
||||
return new SourceInfoImpl(outputClass, controllerClass, inputFile, List.copyOf(includesMapping.values()), includesMapping, requiresResourceBundle);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.github.gtache.fxml.compiler.maven;
|
||||
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class TestFXMLCompilerMojo {
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
package com.github.gtache.fxml.compiler.maven.internal;
|
||||
|
||||
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.HashSet;
|
||||
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;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class TestCompilationInfo {
|
||||
private final Path inputFile;
|
||||
private final Path outputFile;
|
||||
private final String outputClass;
|
||||
private final Path controllerFile;
|
||||
private final String controllerClass;
|
||||
private final Set<FieldInfo> injectedFields;
|
||||
private final Set<String> injectedMethods;
|
||||
private final Map<String, Path> includes;
|
||||
private final boolean requiresResourceBundle;
|
||||
private final CompilationInfo info;
|
||||
|
||||
TestCompilationInfo(@Mock final Path inputFile, @Mock final Path outputFile, @Mock final Path controllerFile, @Mock final FieldInfo fieldInfo) {
|
||||
this.inputFile = Objects.requireNonNull(inputFile);
|
||||
this.outputFile = Objects.requireNonNull(outputFile);
|
||||
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);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetters() {
|
||||
assertEquals(inputFile, info.inputFile());
|
||||
assertEquals(outputFile, info.outputFile());
|
||||
assertEquals(outputClass, info.outputClass());
|
||||
assertEquals(controllerFile, info.controllerFile());
|
||||
assertEquals(controllerClass, info.controllerClass());
|
||||
assertEquals(injectedFields, info.injectedFields());
|
||||
assertEquals(injectedMethods, info.injectedMethods());
|
||||
assertEquals(includes, info.includes());
|
||||
assertEquals(requiresResourceBundle, info.requiresResourceBundle());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCopyInjectedFields() {
|
||||
final var originalInjectedFields = info.injectedFields();
|
||||
injectedFields.clear();
|
||||
assertEquals(originalInjectedFields, info.injectedFields());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCopyInjectedMethods() {
|
||||
final var originalInjectedMethods = info.injectedMethods();
|
||||
injectedMethods.clear();
|
||||
assertEquals(originalInjectedMethods, info.injectedMethods());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCopyIncludes() {
|
||||
final var originalIncludes = Map.copyOf(includes);
|
||||
includes.clear();
|
||||
assertEquals(originalIncludes, info.includes());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testUnmodifiableInjectedFields() {
|
||||
final var originalInjectedFields = info.injectedFields();
|
||||
assertThrows(UnsupportedOperationException.class, originalInjectedFields::clear);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testUnmodifiableInjectedMethods() {
|
||||
final var originalInjectedMethods = info.injectedMethods();
|
||||
assertThrows(UnsupportedOperationException.class, originalInjectedMethods::clear);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testUnmodifiableIncludes() {
|
||||
final var originalIncludes = Map.copyOf(includes);
|
||||
assertThrows(UnsupportedOperationException.class, originalIncludes::clear);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testIllegal() {
|
||||
assertThrows(NullPointerException.class, () -> new CompilationInfo(null, outputFile, outputClass, controllerFile, controllerClass, injectedFields, injectedMethods, includes, requiresResourceBundle));
|
||||
assertThrows(NullPointerException.class, () -> new CompilationInfo(inputFile, null, outputClass, controllerFile, controllerClass, injectedFields, injectedMethods, includes, requiresResourceBundle));
|
||||
assertThrows(NullPointerException.class, () -> new CompilationInfo(inputFile, outputFile, null, controllerFile, controllerClass, injectedFields, injectedMethods, includes, requiresResourceBundle));
|
||||
assertThrows(NullPointerException.class, () -> new CompilationInfo(inputFile, outputFile, outputClass, null, controllerClass, injectedFields, injectedMethods, includes, requiresResourceBundle));
|
||||
assertThrows(NullPointerException.class, () -> new CompilationInfo(inputFile, outputFile, outputClass, controllerFile, null, injectedFields, injectedMethods, includes, requiresResourceBundle));
|
||||
assertThrows(NullPointerException.class, () -> new CompilationInfo(inputFile, outputFile, outputClass, controllerFile, controllerClass, null, injectedMethods, includes, requiresResourceBundle));
|
||||
assertThrows(NullPointerException.class, () -> new CompilationInfo(inputFile, outputFile, outputClass, controllerFile, controllerClass, injectedFields, null, includes, requiresResourceBundle));
|
||||
assertThrows(NullPointerException.class, () -> new CompilationInfo(inputFile, outputFile, outputClass, controllerFile, controllerClass, injectedFields, injectedMethods, null, requiresResourceBundle));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package com.github.gtache.fxml.compiler.maven.internal;
|
||||
|
||||
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.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class TestCompilationInfoBuilder {
|
||||
private final Path inputFile;
|
||||
private final Path outputFile;
|
||||
private final String outputClass;
|
||||
private final Path controllerFile;
|
||||
private final String controllerClass;
|
||||
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) {
|
||||
this.inputFile = Objects.requireNonNull(inputFile);
|
||||
this.outputFile = Objects.requireNonNull(outputFile);
|
||||
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);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testBuilder() {
|
||||
final var builder = new CompilationInfo.Builder();
|
||||
builder.inputFile(inputFile);
|
||||
assertEquals(inputFile, builder.inputFile());
|
||||
builder.outputFile(outputFile);
|
||||
builder.outputClass(outputClass);
|
||||
builder.controllerFile(controllerFile);
|
||||
builder.controllerClass(controllerClass);
|
||||
injectedFields.forEach(f -> builder.addInjectedField(f.name(), f.type()));
|
||||
injectedMethods.forEach(builder::addInjectedMethod);
|
||||
includes.forEach(builder::addInclude);
|
||||
builder.requiresResourceBundle();
|
||||
final var actual = builder.build();
|
||||
assertEquals(info, actual);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.github.gtache.fxml.compiler.maven.internal;
|
||||
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class TestCompilationInfoProvider {
|
||||
}
|
||||
@@ -0,0 +1,155 @@
|
||||
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.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.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
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.ArgumentMatchers.*;
|
||||
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,
|
||||
@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(controllerInfoProvider, sourceInfoProvider, fxmlParser, generator);
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
void beforeEach() throws MojoExecutionException, 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);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCompile(@TempDir final Path tempDir) throws Exception {
|
||||
final var path = tempDir.resolve("fxml1.fxml");
|
||||
final var outputPath = tempDir.resolve("subFolder").resolve("fxml1.java");
|
||||
final var outputClass = "outputClass";
|
||||
when(compilationInfo.outputFile()).thenReturn(outputPath);
|
||||
when(compilationInfo.outputClass()).thenReturn(outputClass);
|
||||
final var mapping = Map.of(path, compilationInfo);
|
||||
final var request = new GenerationRequestImpl(parameters, controllerInfo, sourceInfo, object, outputClass);
|
||||
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
|
||||
void testCompileIOException(@TempDir final Path tempDir) throws Exception {
|
||||
final var path = tempDir.resolve("fxml1.fxml");
|
||||
final var outputPath = Paths.get("/whatever");
|
||||
final var outputClass = "outputClass";
|
||||
when(compilationInfo.outputFile()).thenReturn(outputPath);
|
||||
when(compilationInfo.outputClass()).thenReturn(outputClass);
|
||||
final var mapping = Map.of(path, compilationInfo);
|
||||
final var request = new GenerationRequestImpl(parameters, controllerInfo, sourceInfo, object, outputClass);
|
||||
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");
|
||||
final var outputPath = tempDir.resolve("subFolder").resolve("fxml1.java");
|
||||
final var outputClass = "outputClass";
|
||||
when(compilationInfo.outputFile()).thenReturn(outputPath);
|
||||
when(compilationInfo.outputClass()).thenReturn(outputClass);
|
||||
final var mapping = Map.of(path, compilationInfo);
|
||||
final var request = new GenerationRequestImpl(parameters, controllerInfo, sourceInfo, object, outputClass);
|
||||
when(generator.generate(request)).thenThrow(RuntimeException.class);
|
||||
assertThrows(MojoExecutionException.class, () -> compiler.compile(mapping, parameters));
|
||||
verify(fxmlParser).parse(path);
|
||||
ControllerInfoProvider.getControllerInfo(compilationInfo);
|
||||
SourceInfoProvider.getSourceInfo(compilationInfo, mapping);
|
||||
verify(generator).generate(request);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCompileParseException(@TempDir final Path tempDir) throws Exception {
|
||||
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));
|
||||
verify(fxmlParser).parse(path);
|
||||
verifyNoInteractions(controllerInfoProvider, sourceInfoProvider, generator);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCompileGenerationException(@TempDir final Path tempDir) throws Exception {
|
||||
final var path = tempDir.resolve("fxml1.fxml");
|
||||
final var outputPath = tempDir.resolve("subFolder").resolve("fxml1.java");
|
||||
final var outputClass = "outputClass";
|
||||
when(compilationInfo.outputFile()).thenReturn(outputPath);
|
||||
when(compilationInfo.outputClass()).thenReturn(outputClass);
|
||||
final var mapping = Map.of(path, compilationInfo);
|
||||
final var request = new GenerationRequestImpl(parameters, controllerInfo, sourceInfo, object, outputClass);
|
||||
when(generator.generate(request)).thenThrow(GenerationException.class);
|
||||
assertThrows(MojoExecutionException.class, () -> compiler.compile(mapping, parameters));
|
||||
verify(fxmlParser).parse(path);
|
||||
ControllerInfoProvider.getControllerInfo(compilationInfo);
|
||||
SourceInfoProvider.getSourceInfo(compilationInfo, mapping);
|
||||
verify(generator).generate(request);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testIllegal() {
|
||||
assertThrows(NullPointerException.class, () -> new Compiler(null, sourceInfoProvider, fxmlParser, generator));
|
||||
assertThrows(NullPointerException.class, () -> new Compiler(controllerInfoProvider, null, fxmlParser, generator));
|
||||
assertThrows(NullPointerException.class, () -> new Compiler(controllerInfoProvider, sourceInfoProvider, null, generator));
|
||||
assertThrows(NullPointerException.class, () -> new Compiler(controllerInfoProvider, sourceInfoProvider, fxmlParser, null));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
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 org.apache.maven.plugin.MojoExecutionException;
|
||||
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.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 static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class TestControllerInfoProvider {
|
||||
|
||||
private final CompilationInfo compilationInfo;
|
||||
private final ControllerInfoProvider controllerInfoProvider;
|
||||
|
||||
TestControllerInfoProvider(@Mock final CompilationInfo compilationInfo) {
|
||||
this.compilationInfo = Objects.requireNonNull(compilationInfo);
|
||||
this.controllerInfoProvider = new ControllerInfoProvider();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void testGetControllerInfo(@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 {
|
||||
|
||||
private EventHandler<KeyEvent> keyEventHandler;
|
||||
private ComboBox<String> comboBox;
|
||||
private Button button;
|
||||
private ComboBox rawBox;
|
||||
private TableColumn<Integer, ComboBox<String>> tableColumn;
|
||||
|
||||
@FXML
|
||||
void initialize() {
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void onClick(){
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void onOtherClick(final KeyEvent event){
|
||||
}
|
||||
}
|
||||
""");
|
||||
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 actual = ControllerInfoProvider.getControllerInfo(compilationInfo);
|
||||
assertEquals(expectedInfo, actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetControllerInfoException() {
|
||||
when(compilationInfo.controllerFile()).thenReturn(Paths.get("/whatever"));
|
||||
assertThrows(MojoExecutionException.class, () -> ControllerInfoProvider.getControllerInfo(compilationInfo));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package com.github.gtache.fxml.compiler.maven.internal;
|
||||
|
||||
import org.apache.maven.plugin.MojoExecutionException;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
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;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class TestControllerProvider {
|
||||
|
||||
private final ControllerProvider provider;
|
||||
|
||||
TestControllerProvider() {
|
||||
this.provider = new ControllerProvider();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetController(@TempDir final Path tempDir) throws Exception {
|
||||
final var fxml = tempDir.resolve("fxml.fxml");
|
||||
Files.writeString(fxml, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
|
||||
"<BorderPane xmlns=\"http://javafx.com/javafx/22\" xmlns:fx=\"http://javafx.com/fxml/1\"" +
|
||||
" fx:controller=\"LoadController\">" +
|
||||
"</BorderPane>\n");
|
||||
assertEquals("LoadController", ControllerProvider.getController(fxml));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetControllerBlank(@TempDir final Path tempDir) throws Exception {
|
||||
final var fxml = tempDir.resolve("fxml.fxml");
|
||||
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));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetControllerError() {
|
||||
assertThrows(MojoExecutionException.class, () -> ControllerProvider.getController(Paths.get("fxml.fxml")));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package com.github.gtache.fxml.compiler.maven.internal;
|
||||
|
||||
import org.apache.maven.model.Resource;
|
||||
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.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class TestFXMLProvider {
|
||||
|
||||
private final MavenProject project;
|
||||
private final FXMLProvider provider;
|
||||
|
||||
TestFXMLProvider(@Mock final MavenProject project) {
|
||||
this.project = Objects.requireNonNull(project);
|
||||
this.provider = new FXMLProvider();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetFXMLs(@TempDir final Path tempDir, @TempDir final Path otherTempDir) throws Exception {
|
||||
final var subFolder = tempDir.resolve("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.createFile(otherSubFolder.resolve("subfxml1.fxml"));
|
||||
Files.createFile(otherSubFolder.resolve("subfxml2.fxml"));
|
||||
Files.createFile(otherTempDir.resolve("fxml1.fxml"));
|
||||
Files.createFile(otherTempDir.resolve("fxml2.fxml"));
|
||||
|
||||
final var resource1 = mock(Resource.class);
|
||||
final var resource2 = mock(Resource.class);
|
||||
when(resource1.getDirectory()).thenReturn(tempDir.toString());
|
||||
when(resource2.getDirectory()).thenReturn(otherTempDir.toString());
|
||||
when(project.getResources()).thenReturn(List.of(resource1, resource2));
|
||||
|
||||
final var expected = Map.of(
|
||||
subFolder.resolve("subfxml1.fxml"), tempDir,
|
||||
subFolder.resolve("subfxml2.fxml"), tempDir,
|
||||
tempDir.resolve("fxml1.fxml"), tempDir,
|
||||
tempDir.resolve("fxml2.fxml"), tempDir,
|
||||
otherSubFolder.resolve("subfxml1.fxml"), otherTempDir,
|
||||
otherSubFolder.resolve("subfxml2.fxml"), otherTempDir,
|
||||
otherTempDir.resolve("fxml1.fxml"), otherTempDir,
|
||||
otherTempDir.resolve("fxml2.fxml"), otherTempDir
|
||||
);
|
||||
final var map = FXMLProvider.getFXMLs(project);
|
||||
assertEquals(expected, map);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.github.gtache.fxml.compiler.maven.internal;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
class TestFieldInfo {
|
||||
|
||||
private final String type;
|
||||
private final String name;
|
||||
private final FieldInfo fieldInfo;
|
||||
|
||||
TestFieldInfo() {
|
||||
this.type = "type";
|
||||
this.name = "name";
|
||||
this.fieldInfo = new FieldInfo(type, name);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetters() {
|
||||
assertEquals(type, fieldInfo.type());
|
||||
assertEquals(name, fieldInfo.name());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testIllegal() {
|
||||
assertThrows(NullPointerException.class, () -> new FieldInfo(null, name));
|
||||
assertThrows(NullPointerException.class, () -> new FieldInfo(type, null));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
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.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
class TestGenericParser {
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("providesParseTests")
|
||||
void testParse(final String genericTypes, final Map<String, String> imports, final List<GenericTypesImpl> expectedGenericTypes) throws MojoExecutionException {
|
||||
final var parser = new GenericParser(genericTypes, imports);
|
||||
final var parsed = parser.parse();
|
||||
assertEquals(expectedGenericTypes, parsed);
|
||||
}
|
||||
|
||||
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("javafx.scene.Node", List.of()), new GenericTypesImpl("javafx.scene.Node", List.of()))))))),
|
||||
Arguments.of("<Map<String, String>>",
|
||||
Map.of("Map", "java.util.Map"),
|
||||
List.of(new GenericTypesImpl("java.util.Map",
|
||||
List.of(new GenericTypesImpl("String", List.of()), new GenericTypesImpl("String", List.of()))))),
|
||||
Arguments.of("<String>",
|
||||
Map.of(),
|
||||
List.of(new GenericTypesImpl("String", List.of()))),
|
||||
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()))))),
|
||||
Arguments.of("<Collection<String>>",
|
||||
Map.of(),
|
||||
List.of(new GenericTypesImpl("Collection",
|
||||
List.of(new GenericTypesImpl("String", List.of())))))
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.github.gtache.fxml.compiler.maven.internal;
|
||||
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class TestSourceInfoProvider {
|
||||
}
|
||||
Reference in New Issue
Block a user