Finishes implementing, seems to work ; needs to manage define, copy, reference, root

This commit is contained in:
Guillaume Tâche
2024-11-24 20:15:50 +01:00
parent fd145271a0
commit 102927b040
161 changed files with 27870 additions and 9317 deletions

View File

@@ -7,6 +7,7 @@ import java.util.Map;
*
* @param <T> The type of the controller
*/
@FunctionalInterface
public interface ControllerFactory<T> {
/**

View File

@@ -9,6 +9,8 @@ import java.util.Map;
public interface ControllerInfo {
/**
* Returns a mapping of event handler method name -> boolean
*
* @return A mapping of method name to true if the method has an argument
*/
Map<String, Boolean> handlerHasArgument();
@@ -24,12 +26,14 @@ public interface ControllerInfo {
}
/**
* Returns a mapping of property name -> generic types
*
* @return A mapping of property name to generic types
*/
Map<String, List<String>> propertyGenericTypes();
/**
* Returns the generic types for the given property (null if not generic)
* Returns the generic types for the given property (null if not generic or raw)
*
* @param property The property
* @return The generic types

View File

@@ -6,17 +6,23 @@ package com.github.gtache.fxml.compiler;
public interface ControllerInjection {
/**
* Returns the injection type of class fields
*
* @return The injection type for fields
*/
InjectionType fieldInjectionType();
/**
* Returns the injection type for event handlers methods
*
* @return The injection type for event handlers
*/
InjectionType methodInjectionType();
/**
* @return The injection class
* The name of the controller class
*
* @return The class
*/
String injectionClass();
}

View File

@@ -0,0 +1,35 @@
package com.github.gtache.fxml.compiler;
/**
* Exception thrown when a generation error occurs
*/
public class GenerationException extends Exception {
/**
* Instantiates a new GenerationException
*
* @param message The message
*/
public GenerationException(final String message) {
super(message);
}
/**
* Instantiates a new GenerationException
*
* @param message The message
* @param cause The cause
*/
public GenerationException(final String message, final Throwable cause) {
super(message, cause);
}
/**
* Instantiates a new GenerationException
*
* @param cause The cause
*/
public GenerationException(final Throwable cause) {
super(cause);
}
}

View File

@@ -8,22 +8,31 @@ import java.util.Map;
public interface GenerationParameters {
/**
* @return The mapping of controller class name to controller injection
* Returns the mapping of controller class name to controller injection
*
* @return The mapping
*/
Map<String, ControllerInjection> controllerInjections();
/**
* @return The mapping of fx:include source to generated class name
* Returns the mapping of fx:include source to generated class name
*
* @return The mapping
*/
Map<String, String> sourceToGeneratedClassName();
/**
* @return The mapping of fx:include source to controller class name
* Returns the mapping of fx:include source to controller class name
*
* @return The mapping
*/
Map<String, String> sourceToControllerName();
/**
* @return The resource bundle injection to use
* Returns the resource bundle injection to use
*
* @return The injection
*/
ResourceBundleInjection resourceBundleInjection();
}

View File

@@ -8,22 +8,30 @@ import com.github.gtache.fxml.compiler.parsing.ParsedObject;
public interface GenerationRequest {
/**
* @return The main controller info
* Returns the info about the main controller for code generation
*
* @return The info
*/
ControllerInfo controllerInfo();
/**
* @return The request parameters
* Returns the generation parameters
*
* @return The parameters
*/
GenerationParameters parameters();
/**
* @return The object to generate code for
* Returns the object to generate code for
*
* @return The object
*/
ParsedObject rootObject();
/**
* @return The output class name
* Returns the output class name
*
* @return The class name
*/
String outputClassName();
}

View File

@@ -10,6 +10,7 @@ public interface Generator {
*
* @param request The request
* @return The java code
* @throws GenerationException if an error occurs
*/
String generate(GenerationRequest request);
String generate(GenerationRequest request) throws GenerationException;
}

View File

@@ -7,7 +7,9 @@ package com.github.gtache.fxml.compiler;
public interface InjectionType {
/**
* @return The name of the type
* Returns the name of the type
*
* @return The name
*/
String name();
}

View File

@@ -6,12 +6,16 @@ package com.github.gtache.fxml.compiler;
public interface ResourceBundleInjection {
/**
* Returns the injection type for the resource bundle
*
* @return The injection type
*/
InjectionType injectionType();
/**
* @return The resource bundle path
* Returns the resource bundle name
*
* @return The path
*/
String bundleName();
}

View File

@@ -0,0 +1,37 @@
package com.github.gtache.fxml.compiler.parsing;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
/**
* Parses FXML files to object tree
*/
@FunctionalInterface
public interface FXMLParser {
/**
* Parses the given FXML content
*
* @param content The FXML content
* @return The parsed object
* @throws ParseException if an error occurs
*/
ParsedObject parse(final String content) throws ParseException;
/**
* Parses the FXML file at the given path
*
* @param path The path
* @return The parsed object
* @throws ParseException if an error occurs
*/
default ParsedObject parse(final Path path) throws ParseException {
try {
final var content = Files.readString(path);
return parse(content);
} catch (final IOException e) {
throw new ParseException("Error parsing " + path, e);
}
}
}

View File

@@ -0,0 +1,35 @@
package com.github.gtache.fxml.compiler.parsing;
/**
* Exception thrown when a parsing error occurs
*/
public class ParseException extends Exception {
/**
* Instantiates a new ParseException
*
* @param message The message
*/
public ParseException(final String message) {
super(message);
}
/**
* Instantiates a new ParseException
*
* @param message The message
* @param cause The cause
*/
public ParseException(final String message, final Throwable cause) {
super(message, cause);
}
/**
* Instantiates a new ParseException
*
* @param cause The cause
*/
public ParseException(final Throwable cause) {
super(cause);
}
}

View File

@@ -0,0 +1,30 @@
package com.github.gtache.fxml.compiler.parsing;
import java.util.LinkedHashMap;
import java.util.SequencedCollection;
import java.util.SequencedMap;
/**
* Special {@link ParsedObject} for fx:constant
*/
public interface ParsedConstant extends ParsedObject {
/**
* Returns the constant value from fx:constant
*
* @return The value
*/
default String constant() {
final var attribute = attributes().get("fx:constant");
if (attribute == null) {
throw new IllegalStateException("Missing fx:constant");
} else {
return attribute.value();
}
}
@Override
default SequencedMap<ParsedProperty, SequencedCollection<ParsedObject>> properties() {
return new LinkedHashMap<>();
}
}

View File

@@ -11,10 +11,12 @@ import java.util.SequencedMap;
public interface ParsedInclude extends ParsedObject {
/**
* @return The controller id if present
* Returns the subcontroller id (if present)
*
* @return The id
*/
default String controllerId() {
final var property = properties().get("fx:id");
final var property = attributes().get("fx:id");
if (property == null) {
return null;
} else {
@@ -23,10 +25,12 @@ public interface ParsedInclude extends ParsedObject {
}
/**
* @return The resources if present
* Returns the subview resources path if present
*
* @return The resources
*/
default String resources() {
final var property = properties().get("resources");
final var property = attributes().get("resources");
if (property == null) {
return null;
} else {
@@ -35,10 +39,12 @@ public interface ParsedInclude extends ParsedObject {
}
/**
* Returns the include source
*
* @return The source
*/
default String source() {
final var property = properties().get("source");
final var property = attributes().get("source");
if (property == null) {
throw new IllegalStateException("Missing source");
} else {
@@ -47,12 +53,12 @@ public interface ParsedInclude extends ParsedObject {
}
@Override
default Class<?> clazz() {
return ParsedInclude.class;
default String className() {
return ParsedInclude.class.getName();
}
@Override
default SequencedMap<ParsedProperty, SequencedCollection<ParsedObject>> children() {
default SequencedMap<ParsedProperty, SequencedCollection<ParsedObject>> properties() {
return new LinkedHashMap<>();
}
}

View File

@@ -1,5 +1,6 @@
package com.github.gtache.fxml.compiler.parsing;
import java.util.Map;
import java.util.SequencedCollection;
import java.util.SequencedMap;
@@ -9,17 +10,23 @@ import java.util.SequencedMap;
public interface ParsedObject {
/**
* @return The object class
* The type of the object
*
* @return The class name
*/
Class<?> clazz();
String className();
/**
* @return The object properties
* Returns the object's attributes (simple properties)
*
* @return The attributes
*/
SequencedMap<String, ParsedProperty> properties();
Map<String, ParsedProperty> attributes();
/**
* @return The object children (complex properties)
* Returns the object's complex properties
*
* @return The properties
*/
SequencedMap<ParsedProperty, SequencedCollection<ParsedObject>> children();
SequencedMap<ParsedProperty, SequencedCollection<ParsedObject>> properties();
}

View File

@@ -6,17 +6,23 @@ package com.github.gtache.fxml.compiler.parsing;
public interface ParsedProperty {
/**
* @return The property name
* Returns the name of the property
*
* @return The name
*/
String name();
/**
* @return The property source type (in case of static property)
* Returns the source type (owner class) of the property (in case of static property)
*
* @return The source type name
*/
Class<?> sourceType();
String sourceType();
/**
* @return The property value
* Returns the value of the property
*
* @return The value
*/
String value();
}

View File

@@ -0,0 +1,56 @@
package com.github.gtache.fxml.compiler.parsing;
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.util.HashMap;
import java.util.LinkedHashMap;
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.spy;
import static org.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class)
class TestParsedConstant {
private final Map<String, ParsedProperty> attributes;
private final ParsedProperty property;
private final String string;
private final ParsedConstant constant;
TestParsedConstant(@Mock final ParsedProperty property) {
this.attributes = new HashMap<>();
this.property = Objects.requireNonNull(property);
this.string = "str/ing";
this.constant = spy(ParsedConstant.class);
}
@BeforeEach
void beforeEach() {
when(constant.attributes()).thenReturn(attributes);
when(property.value()).thenReturn(string);
}
@Test
void testConstantNull() {
assertThrows(IllegalStateException.class, constant::constant);
}
@Test
void testConstant() {
attributes.put("fx:constant", property);
assertEquals(string, constant.constant());
}
@Test
void testProperties() {
assertEquals(new LinkedHashMap<>(), constant.properties());
}
}

View File

@@ -7,9 +7,10 @@ import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;
import java.util.SequencedMap;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.spy;
@@ -18,13 +19,13 @@ import static org.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class)
class TestParsedInclude {
private final SequencedMap<String, ParsedProperty> properties;
private final Map<String, ParsedProperty> attributes;
private final ParsedProperty property;
private final String string;
private final ParsedInclude include;
TestParsedInclude(@Mock final ParsedProperty property) {
this.properties = new LinkedHashMap<>();
this.attributes = new HashMap<>();
this.property = Objects.requireNonNull(property);
this.string = "str/ing";
this.include = spy(ParsedInclude.class);
@@ -32,7 +33,7 @@ class TestParsedInclude {
@BeforeEach
void beforeEach() {
when(include.properties()).thenReturn(properties);
when(include.attributes()).thenReturn(attributes);
when(property.value()).thenReturn(string);
}
@@ -43,7 +44,7 @@ class TestParsedInclude {
@Test
void testControllerId() {
properties.put("fx:id", property);
attributes.put("fx:id", property);
assertEquals(string + "Controller", include.controllerId());
}
@@ -54,7 +55,7 @@ class TestParsedInclude {
@Test
void testResources() {
properties.put("resources", property);
attributes.put("resources", property);
assertEquals(string.replace("/", "."), include.resources());
}
@@ -65,17 +66,17 @@ class TestParsedInclude {
@Test
void testSource() {
properties.put("source", property);
attributes.put("source", property);
assertEquals(string, include.source());
}
@Test
void testClazz() {
assertEquals(ParsedInclude.class, include.clazz());
void testClassName() {
assertEquals(ParsedInclude.class.getName(), include.className());
}
@Test
void testChildren() {
assertEquals(new LinkedHashMap<>(), include.children());
void testProperties() {
assertEquals(new LinkedHashMap<>(), include.properties());
}
}