Removes loader, adds some missing features, refactors for easier comprehension and maintenance

This commit is contained in:
Guillaume Tâche
2024-11-30 17:47:47 +01:00
parent 102927b040
commit 17d112fb41
177 changed files with 17395 additions and 31206 deletions

View File

@@ -3,6 +3,7 @@ package com.github.gtache.fxml.compiler;
/**
* Generates compiled FXML code
*/
@FunctionalInterface
public interface Generator {
/**

View File

@@ -1,6 +1,7 @@
package com.github.gtache.fxml.compiler.parsing;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.SequencedCollection;
import java.util.SequencedMap;
@@ -27,4 +28,9 @@ public interface ParsedConstant extends ParsedObject {
default SequencedMap<ParsedProperty, SequencedCollection<ParsedObject>> properties() {
return new LinkedHashMap<>();
}
@Override
default SequencedCollection<ParsedObject> children() {
return List.of();
}
}

View File

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

View File

@@ -0,0 +1,39 @@
package com.github.gtache.fxml.compiler.parsing;
import java.util.Map;
import java.util.SequencedCollection;
import java.util.SequencedMap;
/**
* Special {@link ParsedObject} for fx:define
*/
@FunctionalInterface
public interface ParsedDefine extends ParsedObject {
/**
* Returns the object defined by this fx:define
*
* @return The object
*/
ParsedObject object();
@Override
default String className() {
return object().className();
}
@Override
default Map<String, ParsedProperty> attributes() {
return object().attributes();
}
@Override
default SequencedMap<ParsedProperty, SequencedCollection<ParsedObject>> properties() {
return object().properties();
}
@Override
default SequencedCollection<ParsedObject> children() {
return object().children();
}
}

View File

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

View File

@@ -1,6 +1,7 @@
package com.github.gtache.fxml.compiler.parsing;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.SequencedCollection;
import java.util.SequencedMap;
@@ -61,4 +62,9 @@ public interface ParsedInclude extends ParsedObject {
default SequencedMap<ParsedProperty, SequencedCollection<ParsedObject>> properties() {
return new LinkedHashMap<>();
}
@Override
default SequencedCollection<ParsedObject> children() {
return List.of();
}
}

View File

@@ -29,4 +29,11 @@ public interface ParsedObject {
* @return The properties
*/
SequencedMap<ParsedProperty, SequencedCollection<ParsedObject>> properties();
/**
* Returns the children (fx:define, fx:copy, etc.) contained in this object
*
* @return The children
*/
SequencedCollection<ParsedObject> children();
}

View File

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

View File

@@ -0,0 +1,41 @@
package com.github.gtache.fxml.compiler.parsing;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.SequencedCollection;
import java.util.SequencedMap;
/**
* Special {@link ParsedObject} for simple text
*/
@FunctionalInterface
public interface ParsedText extends ParsedObject {
/**
* Returns the text value
*
* @return The value
*/
String text();
@Override
default String className() {
return "java.lang.String";
}
@Override
default SequencedCollection<ParsedObject> children() {
return List.of();
}
@Override
default SequencedMap<ParsedProperty, SequencedCollection<ParsedObject>> properties() {
return new LinkedHashMap<>();
}
@Override
default Map<String, ParsedProperty> attributes() {
return Map.of();
}
}

View File

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

View File

@@ -0,0 +1,53 @@
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.nio.file.Files;
import java.nio.file.Paths;
import static java.util.Objects.requireNonNull;
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 TestFXMLParser {
private final FXMLParser parser;
private final String content;
private final ParsedObject object;
TestFXMLParser(@Mock final ParsedObject object) {
this.parser = spy(FXMLParser.class);
this.content = "content";
this.object = requireNonNull(object);
}
@BeforeEach
void beforeEach() throws ParseException {
when(parser.parse(content)).thenReturn(object);
}
@Test
void testParse() throws Exception {
final var file = Files.createTempFile("test", ".fxml");
try {
Files.writeString(file, content);
assertEquals(object, parser.parse(file));
verify(parser).parse(content);
} finally {
Files.deleteIfExists(file);
}
}
@Test
void testParseIOException() throws Exception {
final var file = Paths.get("whatever");
assertThrows(ParseException.class, () -> parser.parse(file));
verify(parser, never()).parse(content);
}
}

View File

@@ -9,6 +9,7 @@ import org.mockito.junit.jupiter.MockitoExtension;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@@ -53,4 +54,9 @@ class TestParsedConstant {
void testProperties() {
assertEquals(new LinkedHashMap<>(), constant.properties());
}
@Test
void testChildren() {
assertEquals(List.of(), constant.children());
}
}

View File

@@ -0,0 +1,67 @@
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.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.spy;
import static org.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class)
class TestParsedCopy {
private final Map<String, ParsedProperty> attributes;
private final ParsedProperty property;
private final String string;
private final ParsedCopy reference;
TestParsedCopy(@Mock final ParsedProperty property) {
this.attributes = new HashMap<>();
this.property = Objects.requireNonNull(property);
this.string = "str/ing";
this.reference = spy(ParsedCopy.class);
}
@BeforeEach
void beforeEach() {
when(reference.attributes()).thenReturn(attributes);
when(property.value()).thenReturn(string);
}
@Test
void testSourceNull() {
assertThrows(IllegalStateException.class, reference::source);
}
@Test
void testSource() {
attributes.put("source", property);
assertEquals(string, reference.source());
}
@Test
void testClassName() {
assertEquals(ParsedCopy.class.getName(), reference.className());
}
@Test
void testProperties() {
assertEquals(new LinkedHashMap<>(), reference.properties());
}
@Test
void testChildren() {
assertEquals(List.of(), reference.children());
}
}

View File

@@ -0,0 +1,80 @@
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.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.SequencedCollection;
import static java.util.Objects.requireNonNull;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.*;
@ExtendWith(MockitoExtension.class)
class TestParsedDefine {
private final ParsedProperty property;
private final ParsedObject object;
private final String string;
private final ParsedDefine define;
TestParsedDefine(@Mock final ParsedProperty property, @Mock final ParsedObject object) {
this.property = requireNonNull(property);
this.object = requireNonNull(object);
this.string = "str/ing";
this.define = spy(ParsedDefine.class);
}
@BeforeEach
void beforeEach() {
when(property.value()).thenReturn(string);
when(define.object()).thenReturn(object);
when(object.className()).thenReturn(string);
when(object.children()).thenReturn(List.of(define));
final var map = new LinkedHashMap<ParsedProperty, SequencedCollection<ParsedObject>>();
map.put(property, List.of(object));
when(object.properties()).thenReturn(map);
when(object.attributes()).thenReturn(Map.of(string, property));
}
@Test
void testObject() {
assertEquals(object, define.object());
}
@Test
void testClassName() {
assertEquals(string, define.className());
verify(define).object();
verify(object).className();
}
@Test
void testAttributes() {
assertEquals(Map.of(string, property), define.attributes());
verify(define).object();
verify(object).attributes();
}
@Test
void testProperties() {
final var map = new LinkedHashMap<ParsedProperty, SequencedCollection<ParsedObject>>();
map.put(property, List.of(object));
assertEquals(map, define.properties());
verify(define).object();
verify(object).properties();
}
@Test
void testChildren() {
assertEquals(List.of(define), define.children());
verify(define).object();
verify(object).children();
}
}

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 TestParsedFactory {
private final Map<String, ParsedProperty> attributes;
private final ParsedProperty property;
private final String string;
private final ParsedFactory value;
TestParsedFactory(@Mock final ParsedProperty property) {
this.attributes = new HashMap<>();
this.property = Objects.requireNonNull(property);
this.string = "str/ing";
this.value = spy(ParsedFactory.class);
}
@BeforeEach
void beforeEach() {
when(value.attributes()).thenReturn(attributes);
when(property.value()).thenReturn(string);
}
@Test
void testConstantNull() {
assertThrows(IllegalStateException.class, value::factory);
}
@Test
void testConstant() {
attributes.put("fx:factory", property);
assertEquals(string, value.factory());
}
@Test
void testProperties() {
assertEquals(new LinkedHashMap<>(), value.properties());
}
}

View File

@@ -9,6 +9,7 @@ import org.mockito.junit.jupiter.MockitoExtension;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@@ -79,4 +80,9 @@ class TestParsedInclude {
void testProperties() {
assertEquals(new LinkedHashMap<>(), include.properties());
}
@Test
void testChildren() {
assertEquals(List.of(), include.children());
}
}

View File

@@ -0,0 +1,67 @@
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.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.spy;
import static org.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class)
class TestParsedReference {
private final Map<String, ParsedProperty> attributes;
private final ParsedProperty property;
private final String string;
private final ParsedReference reference;
TestParsedReference(@Mock final ParsedProperty property) {
this.attributes = new HashMap<>();
this.property = Objects.requireNonNull(property);
this.string = "str/ing";
this.reference = spy(ParsedReference.class);
}
@BeforeEach
void beforeEach() {
when(reference.attributes()).thenReturn(attributes);
when(property.value()).thenReturn(string);
}
@Test
void testSourceNull() {
assertThrows(IllegalStateException.class, reference::source);
}
@Test
void testSource() {
attributes.put("source", property);
assertEquals(string, reference.source());
}
@Test
void testClassName() {
assertEquals(ParsedReference.class.getName(), reference.className());
}
@Test
void testProperties() {
assertEquals(new LinkedHashMap<>(), reference.properties());
}
@Test
void testChildren() {
assertEquals(List.of(), reference.children());
}
}

View File

@@ -0,0 +1,39 @@
package com.github.gtache.fxml.compiler.parsing;
import org.junit.jupiter.api.Test;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.spy;
class TestParsedText {
private final ParsedText parsedText;
TestParsedText() {
this.parsedText = spy(ParsedText.class);
}
@Test
void testClassName() {
assertEquals(String.class.getName(), parsedText.className());
}
@Test
void testChildren() {
assertEquals(List.of(), parsedText.children());
}
@Test
void testProperties() {
assertEquals(new LinkedHashMap<>(), parsedText.properties());
}
@Test
void testAttributes() {
assertEquals(Map.of(), parsedText.attributes());
}
}

View File

@@ -0,0 +1,62 @@
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.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.spy;
import static org.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class)
class TestParsedValue {
private final Map<String, ParsedProperty> attributes;
private final ParsedProperty property;
private final String string;
private final ParsedValue value;
TestParsedValue(@Mock final ParsedProperty property) {
this.attributes = new HashMap<>();
this.property = Objects.requireNonNull(property);
this.string = "str/ing";
this.value = spy(ParsedValue.class);
}
@BeforeEach
void beforeEach() {
when(value.attributes()).thenReturn(attributes);
when(property.value()).thenReturn(string);
}
@Test
void testConstantNull() {
assertThrows(IllegalStateException.class, value::value);
}
@Test
void testConstant() {
attributes.put("fx:value", property);
assertEquals(string, value.value());
}
@Test
void testProperties() {
assertEquals(new LinkedHashMap<>(), value.properties());
}
@Test
void testChildren() {
assertEquals(List.of(), value.children());
}
}