Adds maven wrapper ; rework internal a bit ; Adds all tests for core
This commit is contained in:
19
.mvn/wrapper/maven-wrapper.properties
vendored
Normal file
19
.mvn/wrapper/maven-wrapper.properties
vendored
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
# Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
# or more contributor license agreements. See the NOTICE file
|
||||||
|
# distributed with this work for additional information
|
||||||
|
# regarding copyright ownership. The ASF licenses this file
|
||||||
|
# to you under the Apache License, Version 2.0 (the
|
||||||
|
# "License"); you may not use this file except in compliance
|
||||||
|
# with the License. You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing,
|
||||||
|
# software distributed under the License is distributed on an
|
||||||
|
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
# KIND, either express or implied. See the License for the
|
||||||
|
# specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
wrapperVersion=3.3.2
|
||||||
|
distributionType=only-script
|
||||||
|
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip
|
||||||
120
README.md
120
README.md
@@ -6,8 +6,9 @@ This projects aims at generating Java code from FXML files.
|
|||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
- Java 21 (at least for the plugin, the generated code can be compatible with older Java versions)
|
- Java 21+ for the plugin
|
||||||
- Maven 3.8.0
|
- The generated code can be compatible with older java versions.
|
||||||
|
- Maven 3.6.3+
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
@@ -79,100 +80,55 @@ Optionally add dependencies to the plugin (e.g. when using MediaView and control
|
|||||||
|
|
||||||
## Disadvantages
|
## Disadvantages
|
||||||
|
|
||||||
|
- `fx:script` is not supported
|
||||||
- Possible bugs (file an issue if you see one)
|
- Possible bugs (file an issue if you see one)
|
||||||
- Expression binding is limited
|
- Expression binding is limited
|
||||||
- Probably not fully compatible with all FXML features (file an issue if you need one in specific)
|
- Probably not fully compatible with all FXML features (file an issue if you need one in specific)
|
||||||
|
|
||||||
## Parameters
|
## Parameters
|
||||||
|
|
||||||
|
### Controller injection
|
||||||
|
|
||||||
|
There are two ways to inject controllers into a view:
|
||||||
|
|
||||||
|
- `INSTANCE`: Inject the controller instance
|
||||||
|
- This is the default injection method
|
||||||
|
- `FACTORY`: Inject the controller factory
|
||||||
|
- This injection method is required if the FXML tree contains multiple times the same controller class.
|
||||||
|
- By default, the factory is a `Supplier<Controller>`, but if used in conjunction with `field-injection`set to
|
||||||
|
`FACTORY`, the factory is a `Function<Map<String, Object>, Controller>`.
|
||||||
|
|
||||||
### Field injection
|
### Field injection
|
||||||
|
|
||||||
There are four ways to inject fields into a controller:
|
There are four ways to inject fields into a controller:
|
||||||
|
|
||||||
- `REFLECTION`: Inject fields using reflection (like FXMLLoader)
|
- `REFLECTION`: Inject fields using reflection (like FXMLLoader)
|
||||||
-
|
|
||||||
- ```java
|
|
||||||
try {
|
|
||||||
final var field = controller.getClass().getDeclaredField(fieldName);
|
|
||||||
field.setAccessible(true);
|
|
||||||
field.set(controller, object);
|
|
||||||
} catch (final NoSuchFieldException | IllegalAccessException e) {
|
|
||||||
throw new RuntimeException("Error using reflection on " + fieldName, e);
|
|
||||||
}
|
|
||||||
```
|
|
||||||
-
|
|
||||||
- Slowest method
|
- Slowest method
|
||||||
-
|
|
||||||
- Fully compatible with FXMLLoader, so this allows easy switching between the two.
|
- Fully compatible with FXMLLoader, so this allows easy switching between the two.
|
||||||
-
|
|
||||||
- This is the default injection method (for compatibility reasons).
|
- This is the default injection method (for compatibility reasons).
|
||||||
- `ASSIGN`: variable assignment
|
- `ASSIGN`: variable assignment
|
||||||
-
|
|
||||||
- `controller.field = value`
|
- `controller.field = value`
|
||||||
-
|
|
||||||
- This means that the field must be accessible from the view (e.g. package-private).
|
- This means that the field must be accessible from the view (e.g. package-private).
|
||||||
- `SETTERS`: controller setters methods
|
- `SETTERS`: controller setters methods
|
||||||
-
|
|
||||||
- `controller.setField(value)`
|
- `controller.setField(value)`
|
||||||
- `FACTORY`: controller factory
|
- `FACTORY`: controller factory
|
||||||
-
|
|
||||||
- `controller = factory.create(fieldMap)`
|
- `controller = factory.create(fieldMap)`
|
||||||
-
|
- `factory` is a `Function<Map<String, Object>, Controller>` instance that is created at runtime and passed to the
|
||||||
- `factory` is a `ControllerFactory` instance that is created at runtime and passed to the view.
|
view.
|
||||||
-
|
|
||||||
- `fieldMap` is a map of field name (String) to value (Object) that is computed during the view `load` method.
|
- `fieldMap` is a map of field name (String) to value (Object) that is computed during the view `load` method.
|
||||||
-
|
|
||||||
- This allows the controller to have final fields.
|
- This allows the controller to have final fields.
|
||||||
|
- This also forces the `controller-injection` method to be `FACTORY`.
|
||||||
|
|
||||||
### Method injections
|
### Method injections
|
||||||
|
|
||||||
There are two ways to inject methods (meaning use them as event handlers) into a controller:
|
There are two ways to inject methods (meaning use them as event handlers) into a controller:
|
||||||
|
|
||||||
- `REFLECTION`: Inject methods using reflection (like FXMLLoader)
|
- `REFLECTION`: Inject methods using reflection (like FXMLLoader)
|
||||||
-
|
|
||||||
- ```java
|
|
||||||
try {
|
|
||||||
final java.lang.reflect.Method method;
|
|
||||||
final var methods = java.util.Arrays.stream(controller.getClass().getDeclaredMethods())
|
|
||||||
.filter(m -> m.getName().equals(methodName)).toList();
|
|
||||||
if (methods.size() > 1) {
|
|
||||||
final var eventMethods = methods.stream().filter(m ->
|
|
||||||
m.getParameterCount() == 1 && javafx.event.Event.class.isAssignableFrom(m.getParameterTypes()[0])).toList();
|
|
||||||
if (eventMethods.size() == 1) {
|
|
||||||
method = eventMethods.getFirst();
|
|
||||||
} else {
|
|
||||||
final var emptyMethods = methods.stream().filter(m -> m.getParameterCount() == 0).toList();
|
|
||||||
if (emptyMethods.size() == 1) {
|
|
||||||
method = emptyMethods.getFirst();
|
|
||||||
} else {
|
|
||||||
throw new IllegalArgumentException("Multiple matching methods for " + methodName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (methods.size() == 1) {
|
|
||||||
method = methods.getFirst();
|
|
||||||
} else {
|
|
||||||
throw new IllegalArgumentException("No matching method for " + methodName);
|
|
||||||
}
|
|
||||||
method.setAccessible(true);
|
|
||||||
if (method.getParameterCount() == 0) {
|
|
||||||
method.invoke(controller);
|
|
||||||
} else {
|
|
||||||
method.invoke(controller, event);
|
|
||||||
}
|
|
||||||
} catch (final IllegalAccessException | java.lang.reflect.InvocationTargetException ex) {
|
|
||||||
throw new RuntimeException("Error using reflection on " + methodName, ex);
|
|
||||||
}
|
|
||||||
```
|
|
||||||
-
|
|
||||||
- Slowest method
|
- Slowest method
|
||||||
-
|
|
||||||
- Fully compatible with FXMLLoader, so this allows easy switching between the two.
|
- Fully compatible with FXMLLoader, so this allows easy switching between the two.
|
||||||
-
|
|
||||||
- This is the default injection method (for compatibility reasons).
|
- This is the default injection method (for compatibility reasons).
|
||||||
- `REFERENCE`: Directly reference the method
|
- `REFERENCE`: Directly reference the method
|
||||||
-
|
|
||||||
- `controller.method(event)`
|
- `controller.method(event)`
|
||||||
-
|
|
||||||
- This means that the method must be accessible from the view (e.g. package-private).
|
- This means that the method must be accessible from the view (e.g. package-private).
|
||||||
|
|
||||||
### Resource bundle injection
|
### Resource bundle injection
|
||||||
@@ -180,31 +136,23 @@ There are two ways to inject methods (meaning use them as event handlers) into a
|
|||||||
There are three ways to inject resource bundles into a controller:
|
There are three ways to inject resource bundles into a controller:
|
||||||
|
|
||||||
- `CONSTRUCTOR`: Inject resource bundle in the view constructor
|
- `CONSTRUCTOR`: Inject resource bundle in the view constructor
|
||||||
-
|
|
||||||
- ```java
|
- ```java
|
||||||
view = new View(controller, resourceBundle);
|
view = new View(controller, resourceBundle);
|
||||||
```
|
```
|
||||||
-
|
|
||||||
- This is the default injection method because it is the most similar to FXMLLoader (
|
- This is the default injection method because it is the most similar to FXMLLoader (
|
||||||
`FXMLLoader.setResources(resourceBundle)`).
|
`FXMLLoader.setResources(resourceBundle)`).
|
||||||
- `CONSTRUCTOR_FUNCTION`: Injects a function in the view constructor
|
- `CONSTRUCTOR_FUNCTION`: Injects a function in the view constructor
|
||||||
-
|
|
||||||
- `bundleFunction.apply(key)`
|
- `bundleFunction.apply(key)`
|
||||||
-
|
|
||||||
- The function takes a string (the key) and returns a string (the value)
|
- The function takes a string (the key) and returns a string (the value)
|
||||||
- This allows using another object than a resource bundle for example
|
- This allows using another object than a resource bundle for example
|
||||||
- `GETTER`: Retrieves the resource bundle using a controller getter method
|
- `CONSTRUCTOR_NAME`: Injects the resource bundle name in the view constructor
|
||||||
-
|
|
||||||
- `controller.resources()`
|
|
||||||
-
|
|
||||||
- The method name (resources) was chosen because it matches the name of the field injected by FXMLLoader.
|
|
||||||
-
|
|
||||||
- The method must be accessible from the view (e.g. package-private).
|
|
||||||
- `GET-BUNDLE`: Injects the bundle name in the view constructor and retrieves it using
|
|
||||||
`ResourceBundle.getBundle(bundleName)`
|
|
||||||
-
|
|
||||||
- `ResourceBundle.getBundle(bundleName)`
|
- `ResourceBundle.getBundle(bundleName)`
|
||||||
- Also used when fx:include specifies a resource attribute to pass it to the included view.
|
- `GETTER`: Retrieves the resource bundle using a controller getter method
|
||||||
|
- `controller.resources()`
|
||||||
|
- The method name (resources) was chosen because it matches the name of the field injected by FXMLLoader.
|
||||||
|
- The method must be accessible from the view (e.g. package-private).
|
||||||
|
- `GET-BUNDLE`: Retrieves the resource bundle using a resource path
|
||||||
|
- The resource path is passed to the generator (see [Maven Plugin](#maven-plugin)).
|
||||||
|
|
||||||
## View creation
|
## View creation
|
||||||
|
|
||||||
@@ -229,47 +177,43 @@ The smallest constructor will have only one argument: The controller (or control
|
|||||||
### Parameters
|
### Parameters
|
||||||
|
|
||||||
- output-directory
|
- output-directory
|
||||||
-
|
|
||||||
- The output directory of the generated classes
|
- The output directory of the generated classes
|
||||||
-
|
|
||||||
- default: `${project.build.directory}/generated-sources/java`)
|
- default: `${project.build.directory}/generated-sources/java`)
|
||||||
- target-version
|
- target-version
|
||||||
-
|
|
||||||
- The target Java version for the generated code
|
- The target Java version for the generated code
|
||||||
- default: `21`
|
- default: `21`
|
||||||
- minimum: `8`
|
- minimum: `8`
|
||||||
- File an issue if the generated code is not compatible with the target version
|
- File an issue if the generated code is not compatible with the target version
|
||||||
- use-image-inputstream-constructor
|
- use-image-inputstream-constructor
|
||||||
-
|
|
||||||
- Use the InputStream constructor for Image instead of the String (URL) one.
|
- Use the InputStream constructor for Image instead of the String (URL) one.
|
||||||
-
|
|
||||||
- default: `true`
|
- default: `true`
|
||||||
- Disables background loading
|
- Disables background loading
|
||||||
|
- controller-injection
|
||||||
|
- The type of controller injections to use (see [Controller injection](#controller-injection))
|
||||||
|
- default: `INSTANCE`
|
||||||
- field-injection
|
- field-injection
|
||||||
-
|
|
||||||
- The type of field injections to use (see [Field injection](#field-injection))
|
- The type of field injections to use (see [Field injection](#field-injection))
|
||||||
- default: `REFLECTION`
|
- default: `REFLECTION`
|
||||||
- method-injection
|
- method-injection
|
||||||
-
|
|
||||||
- The type of method injections to use (see [Method injection](#method-injection))
|
- The type of method injections to use (see [Method injection](#method-injection))
|
||||||
- default: `REFLECTION`
|
- default: `REFLECTION`
|
||||||
- bundle-injection
|
- bundle-injection
|
||||||
-
|
|
||||||
- The type of resource bundle injection to use (see [Resource bundle injection](#resource-bundle-injection))
|
- The type of resource bundle injection to use (see [Resource bundle injection](#resource-bundle-injection))
|
||||||
- default: `CONSTRUCTOR`
|
- default: `CONSTRUCTOR`
|
||||||
- bundle-map
|
- bundle-map
|
||||||
-
|
|
||||||
- A map of resource bundle name to resource bundle path
|
- A map of resource bundle name to resource bundle path
|
||||||
- Used with `GET-BUNDLE` injection
|
- Used with `GET-BUNDLE` injection
|
||||||
- default: `{}`
|
- default: `{}`
|
||||||
|
- parallelism
|
||||||
|
- The number of threads to use for compilation
|
||||||
|
- default: `1`
|
||||||
|
- if `<1`, the number of cores will be used
|
||||||
|
|
||||||
### Limitations
|
### Limitations
|
||||||
|
|
||||||
- Given that the plugin operates during the `generate-sources` phase, it doesn't have access to the classes of the
|
- Given that the plugin operates during the `generate-sources` phase, it doesn't have access to the classes of the
|
||||||
application.
|
application.
|
||||||
-
|
|
||||||
- The controller info (fields, methods) is obtained from the source file and may therefore be inaccurate.
|
- The controller info (fields, methods) is obtained from the source file and may therefore be inaccurate.
|
||||||
-
|
|
||||||
- Custom classes instantiated in the FXML files are not available during generation and may therefore cause it to
|
- Custom classes instantiated in the FXML files are not available during generation and may therefore cause it to
|
||||||
fail.
|
fail.
|
||||||
- If the application uses e.g. WebView, the javafx-web dependency must be added to the plugin dependencies.
|
- If the application uses e.g. WebView, the javafx-web dependency must be added to the plugin dependencies.
|
||||||
@@ -1,11 +1,9 @@
|
|||||||
package com.github.gtache.fxml.compiler.impl;
|
package com.github.gtache.fxml.compiler;
|
||||||
|
|
||||||
import com.github.gtache.fxml.compiler.InjectionType;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base field {@link InjectionType}s
|
* Base field {@link InjectionType}s
|
||||||
*/
|
*/
|
||||||
public enum ControllerFieldInjectionTypes implements InjectionType {
|
public enum ControllerFieldInjectionType implements InjectionType {
|
||||||
/**
|
/**
|
||||||
* Inject using variable assignment
|
* Inject using variable assignment
|
||||||
*/
|
*/
|
||||||
@@ -1,11 +1,9 @@
|
|||||||
package com.github.gtache.fxml.compiler.impl;
|
package com.github.gtache.fxml.compiler;
|
||||||
|
|
||||||
import com.github.gtache.fxml.compiler.InjectionType;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base controller {@link InjectionType}s
|
* Base controller {@link InjectionType}s
|
||||||
*/
|
*/
|
||||||
public enum ControllerInjectionTypes implements InjectionType {
|
public enum ControllerInjectionType implements InjectionType {
|
||||||
/**
|
/**
|
||||||
* Inject the controller instance
|
* Inject the controller instance
|
||||||
*/
|
*/
|
||||||
@@ -1,6 +1,4 @@
|
|||||||
package com.github.gtache.fxml.compiler.impl;
|
package com.github.gtache.fxml.compiler;
|
||||||
|
|
||||||
import com.github.gtache.fxml.compiler.InjectionType;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base methods {@link InjectionType}s
|
* Base methods {@link InjectionType}s
|
||||||
@@ -36,26 +36,26 @@ public interface GenerationParameters {
|
|||||||
*
|
*
|
||||||
* @return The injection
|
* @return The injection
|
||||||
*/
|
*/
|
||||||
InjectionType controllerInjectionType();
|
ControllerInjectionType controllerInjectionType();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the field injection to use
|
* Returns the field injection to use
|
||||||
*
|
*
|
||||||
* @return The injection
|
* @return The injection
|
||||||
*/
|
*/
|
||||||
InjectionType fieldInjectionType();
|
ControllerFieldInjectionType fieldInjectionType();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the method injection to use
|
* Returns the method injection to use
|
||||||
*
|
*
|
||||||
* @return The injection
|
* @return The injection
|
||||||
*/
|
*/
|
||||||
InjectionType methodInjectionType();
|
ControllerMethodsInjectionType methodInjectionType();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the resource injection to use
|
* Returns the resource injection to use
|
||||||
*
|
*
|
||||||
* @return The injection
|
* @return The injection
|
||||||
*/
|
*/
|
||||||
InjectionType resourceInjectionType();
|
ResourceBundleInjectionType resourceInjectionType();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,9 @@
|
|||||||
package com.github.gtache.fxml.compiler.impl;
|
package com.github.gtache.fxml.compiler;
|
||||||
|
|
||||||
import com.github.gtache.fxml.compiler.InjectionType;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base {@link InjectionType}s for resource bundles
|
* Base {@link InjectionType}s for resource bundles
|
||||||
*/
|
*/
|
||||||
public enum ResourceBundleInjectionTypes implements InjectionType {
|
public enum ResourceBundleInjectionType implements InjectionType {
|
||||||
/**
|
/**
|
||||||
* Resource bundle is injected in the constructor
|
* Resource bundle is injected in the constructor
|
||||||
*/
|
*/
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
package com.github.gtache.fxml.compiler;
|
||||||
|
|
||||||
|
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.Objects;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
@ExtendWith(MockitoExtension.class)
|
||||||
|
class TestGenerationException {
|
||||||
|
|
||||||
|
private final String message;
|
||||||
|
private final Throwable throwable;
|
||||||
|
private final String throwableString;
|
||||||
|
|
||||||
|
TestGenerationException(@Mock final Throwable throwable) {
|
||||||
|
this.message = "message";
|
||||||
|
this.throwable = Objects.requireNonNull(throwable);
|
||||||
|
this.throwableString = "throwable";
|
||||||
|
}
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void beforeEach() {
|
||||||
|
when(throwable.toString()).thenReturn(throwableString);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testOnlyMessage() {
|
||||||
|
final var exception = new GenerationException(message);
|
||||||
|
assertEquals(message, exception.getMessage());
|
||||||
|
assertNull(exception.getCause());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testOnlyCause() {
|
||||||
|
final var exception = new GenerationException(throwable);
|
||||||
|
assertEquals(throwableString, exception.getMessage());
|
||||||
|
assertEquals(throwable, exception.getCause());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testMessageAndCause() {
|
||||||
|
final var exception = new GenerationException(message, throwable);
|
||||||
|
assertEquals(message, exception.getMessage());
|
||||||
|
assertEquals(throwable, exception.getCause());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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.util.Objects;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
@ExtendWith(MockitoExtension.class)
|
||||||
|
class TestParseException {
|
||||||
|
|
||||||
|
private final String message;
|
||||||
|
private final Throwable throwable;
|
||||||
|
private final String throwableString;
|
||||||
|
|
||||||
|
TestParseException(@Mock final Throwable throwable) {
|
||||||
|
this.message = "message";
|
||||||
|
this.throwable = Objects.requireNonNull(throwable);
|
||||||
|
this.throwableString = "throwable";
|
||||||
|
}
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void beforeEach() {
|
||||||
|
when(throwable.toString()).thenReturn(throwableString);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testOnlyMessage() {
|
||||||
|
final var exception = new ParseException(message);
|
||||||
|
assertEquals(message, exception.getMessage());
|
||||||
|
assertNull(exception.getCause());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testOnlyCause() {
|
||||||
|
final var exception = new ParseException(throwable);
|
||||||
|
assertEquals(throwableString, exception.getMessage());
|
||||||
|
assertEquals(throwable, exception.getCause());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testMessageAndCause() {
|
||||||
|
final var exception = new ParseException(message, throwable);
|
||||||
|
assertEquals(message, exception.getMessage());
|
||||||
|
assertEquals(throwable, exception.getCause());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -18,6 +18,14 @@ public record ControllerInfoImpl(String className, Map<String, Boolean> handlerH
|
|||||||
Map<String, ControllerFieldInfo> fieldInfo,
|
Map<String, ControllerFieldInfo> fieldInfo,
|
||||||
boolean hasInitialize) implements ControllerInfo {
|
boolean hasInitialize) implements ControllerInfo {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates a new controller info
|
||||||
|
* @param className The controller class name
|
||||||
|
* @param handlerHasArgument The mapping of method name to true if the method has an argument
|
||||||
|
* @param fieldInfo The mapping of property name to controller field info
|
||||||
|
* @param hasInitialize True if the controller has an initialize method
|
||||||
|
* @throws NullPointerException If any parameter is null
|
||||||
|
*/
|
||||||
public ControllerInfoImpl {
|
public ControllerInfoImpl {
|
||||||
Objects.requireNonNull(className);
|
Objects.requireNonNull(className);
|
||||||
handlerHasArgument = Map.copyOf(handlerHasArgument);
|
handlerHasArgument = Map.copyOf(handlerHasArgument);
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
package com.github.gtache.fxml.compiler.impl;
|
package com.github.gtache.fxml.compiler.impl;
|
||||||
|
|
||||||
|
import com.github.gtache.fxml.compiler.ControllerFieldInjectionType;
|
||||||
|
import com.github.gtache.fxml.compiler.ControllerInjectionType;
|
||||||
|
import com.github.gtache.fxml.compiler.ControllerMethodsInjectionType;
|
||||||
import com.github.gtache.fxml.compiler.GenerationParameters;
|
import com.github.gtache.fxml.compiler.GenerationParameters;
|
||||||
import com.github.gtache.fxml.compiler.InjectionType;
|
import com.github.gtache.fxml.compiler.ResourceBundleInjectionType;
|
||||||
import com.github.gtache.fxml.compiler.compatibility.GenerationCompatibility;
|
import com.github.gtache.fxml.compiler.compatibility.GenerationCompatibility;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -22,11 +25,23 @@ import static java.util.Objects.requireNonNull;
|
|||||||
*/
|
*/
|
||||||
public record GenerationParametersImpl(GenerationCompatibility compatibility, boolean useImageInputStreamConstructor,
|
public record GenerationParametersImpl(GenerationCompatibility compatibility, boolean useImageInputStreamConstructor,
|
||||||
Map<String, String> bundleMap,
|
Map<String, String> bundleMap,
|
||||||
InjectionType controllerInjectionType,
|
ControllerInjectionType controllerInjectionType,
|
||||||
InjectionType fieldInjectionType,
|
ControllerFieldInjectionType fieldInjectionType,
|
||||||
InjectionType methodInjectionType,
|
ControllerMethodsInjectionType methodInjectionType,
|
||||||
InjectionType resourceInjectionType) implements GenerationParameters {
|
ResourceBundleInjectionType resourceInjectionType) implements GenerationParameters {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates new parameters
|
||||||
|
*
|
||||||
|
* @param compatibility The compatibility info
|
||||||
|
* @param useImageInputStreamConstructor True if the InputStream constructor should be used
|
||||||
|
* @param bundleMap The mapping of controller class to resource bundle path
|
||||||
|
* @param controllerInjectionType The controller injection type
|
||||||
|
* @param fieldInjectionType The field injection type
|
||||||
|
* @param methodInjectionType The method injection type
|
||||||
|
* @param resourceInjectionType The resource injection type
|
||||||
|
* @throws NullPointerException if any parameter is null
|
||||||
|
*/
|
||||||
public GenerationParametersImpl {
|
public GenerationParametersImpl {
|
||||||
requireNonNull(compatibility);
|
requireNonNull(compatibility);
|
||||||
bundleMap = Map.copyOf(bundleMap);
|
bundleMap = Map.copyOf(bundleMap);
|
||||||
|
|||||||
@@ -20,6 +20,15 @@ import java.util.Objects;
|
|||||||
public record GenerationRequestImpl(GenerationParameters parameters, ControllerInfo controllerInfo,
|
public record GenerationRequestImpl(GenerationParameters parameters, ControllerInfo controllerInfo,
|
||||||
SourceInfo sourceInfo, ParsedObject rootObject,
|
SourceInfo sourceInfo, ParsedObject rootObject,
|
||||||
String outputClassName) implements GenerationRequest {
|
String outputClassName) implements GenerationRequest {
|
||||||
|
/**
|
||||||
|
* Instantiates a new request
|
||||||
|
* @param parameters The generation parameters
|
||||||
|
* @param controllerInfo The controller info
|
||||||
|
* @param sourceInfo The source info
|
||||||
|
* @param rootObject The root object
|
||||||
|
* @param outputClassName The output class name
|
||||||
|
* @throws NullPointerException If any parameter is null
|
||||||
|
*/
|
||||||
public GenerationRequestImpl {
|
public GenerationRequestImpl {
|
||||||
Objects.requireNonNull(parameters);
|
Objects.requireNonNull(parameters);
|
||||||
Objects.requireNonNull(controllerInfo);
|
Objects.requireNonNull(controllerInfo);
|
||||||
|
|||||||
@@ -6,6 +6,9 @@ import com.github.gtache.fxml.compiler.Generator;
|
|||||||
import com.github.gtache.fxml.compiler.impl.internal.GenerationProgress;
|
import com.github.gtache.fxml.compiler.impl.internal.GenerationProgress;
|
||||||
import com.github.gtache.fxml.compiler.impl.internal.HelperProvider;
|
import com.github.gtache.fxml.compiler.impl.internal.HelperProvider;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
//TODO handle binding (${})
|
//TODO handle binding (${})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -13,10 +16,28 @@ import com.github.gtache.fxml.compiler.impl.internal.HelperProvider;
|
|||||||
*/
|
*/
|
||||||
public class GeneratorImpl implements Generator {
|
public class GeneratorImpl implements Generator {
|
||||||
|
|
||||||
|
|
||||||
|
private final Function<GenerationProgress, HelperProvider> helperProviderFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates a new generator
|
||||||
|
*/
|
||||||
|
public GeneratorImpl() {
|
||||||
|
this(HelperProvider::new);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used for testing
|
||||||
|
* @param helperProviderFactory The helper provider factory
|
||||||
|
*/
|
||||||
|
GeneratorImpl(final Function<GenerationProgress, HelperProvider> helperProviderFactory) {
|
||||||
|
this.helperProviderFactory = Objects.requireNonNull(helperProviderFactory);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String generate(final GenerationRequest request) throws GenerationException {
|
public String generate(final GenerationRequest request) throws GenerationException {
|
||||||
final var progress = new GenerationProgress(request);
|
final var progress = new GenerationProgress(request);
|
||||||
final var helperProvider = new HelperProvider(progress);
|
final var helperProvider = helperProviderFactory.apply(progress);
|
||||||
final var className = request.outputClassName();
|
final var className = request.outputClassName();
|
||||||
final var pkgName = className.substring(0, className.lastIndexOf('.'));
|
final var pkgName = className.substring(0, className.lastIndexOf('.'));
|
||||||
final var simpleClassName = className.substring(className.lastIndexOf('.') + 1);
|
final var simpleClassName = className.substring(className.lastIndexOf('.') + 1);
|
||||||
@@ -43,7 +64,9 @@ public class GeneratorImpl implements Generator {
|
|||||||
private static void formatControllerMethod(final GenerationProgress progress, final String controllerInjectionClass) {
|
private static void formatControllerMethod(final GenerationProgress progress, final String controllerInjectionClass) {
|
||||||
final var sb = progress.stringBuilder();
|
final var sb = progress.stringBuilder();
|
||||||
sb.append(" /**\n");
|
sb.append(" /**\n");
|
||||||
|
sb.append(" * Returns the controller if available\n");
|
||||||
sb.append(" * @return The controller\n");
|
sb.append(" * @return The controller\n");
|
||||||
|
sb.append(" * @throws IllegalStateException If the view is not loaded\n");
|
||||||
sb.append(" */\n");
|
sb.append(" */\n");
|
||||||
sb.append(" public ").append(controllerInjectionClass).append(" controller() {\n");
|
sb.append(" public ").append(controllerInjectionClass).append(" controller() {\n");
|
||||||
sb.append(" if (loaded) {\n");
|
sb.append(" if (loaded) {\n");
|
||||||
|
|||||||
@@ -22,6 +22,16 @@ public record SourceInfoImpl(String generatedClassName, String controllerClassNa
|
|||||||
Map<String, SourceInfo> sourceToSourceInfo,
|
Map<String, SourceInfo> sourceToSourceInfo,
|
||||||
boolean requiresResourceBundle) implements SourceInfo {
|
boolean requiresResourceBundle) implements SourceInfo {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates a new source info
|
||||||
|
* @param generatedClassName The generated class name
|
||||||
|
* @param controllerClassName The controller class name
|
||||||
|
* @param sourceFile The source file
|
||||||
|
* @param includedSources The included sources
|
||||||
|
* @param sourceToSourceInfo The mapping of source value to source info
|
||||||
|
* @param requiresResourceBundle True if the subtree requires a resource bundle
|
||||||
|
* @throws NullPointerException If any parameter is null
|
||||||
|
*/
|
||||||
public SourceInfoImpl {
|
public SourceInfoImpl {
|
||||||
Objects.requireNonNull(generatedClassName);
|
Objects.requireNonNull(generatedClassName);
|
||||||
Objects.requireNonNull(controllerClassName);
|
Objects.requireNonNull(controllerClassName);
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import java.util.ArrayList;
|
|||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -17,10 +16,8 @@ import java.util.Set;
|
|||||||
*/
|
*/
|
||||||
final class ConstructorHelper {
|
final class ConstructorHelper {
|
||||||
|
|
||||||
private final HelperProvider helperProvider;
|
private ConstructorHelper() {
|
||||||
|
|
||||||
ConstructorHelper(final HelperProvider helperProvider) {
|
|
||||||
this.helperProvider = Objects.requireNonNull(helperProvider);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -31,22 +28,22 @@ final class ConstructorHelper {
|
|||||||
* @return The list of constructor arguments
|
* @return The list of constructor arguments
|
||||||
* @throws GenerationException if an error occurs
|
* @throws GenerationException if an error occurs
|
||||||
*/
|
*/
|
||||||
List<String> getListConstructorArgs(final ConstructorArgs constructorArgs, final ParsedObject parsedObject) throws GenerationException {
|
static List<String> getListConstructorArgs(final ConstructorArgs constructorArgs, final ParsedObject parsedObject) throws GenerationException {
|
||||||
final var args = new ArrayList<String>(constructorArgs.namedArgs().size());
|
final var args = new ArrayList<String>(constructorArgs.namedArgs().size());
|
||||||
final var valueFormatter = helperProvider.getValueFormatter();
|
|
||||||
for (final var entry : constructorArgs.namedArgs().entrySet()) {
|
for (final var entry : constructorArgs.namedArgs().entrySet()) {
|
||||||
final var type = entry.getValue().type();
|
final var parameter = entry.getValue();
|
||||||
|
final var type = parameter.type();
|
||||||
final var p = parsedObject.attributes().get(entry.getKey());
|
final var p = parsedObject.attributes().get(entry.getKey());
|
||||||
if (p == null) {
|
if (p == null) {
|
||||||
final var c = parsedObject.properties().entrySet().stream().filter(e ->
|
final var c = parsedObject.properties().entrySet().stream().filter(e ->
|
||||||
e.getKey().name().equals(entry.getKey())).findFirst().orElse(null);
|
e.getKey().name().equals(entry.getKey())).findFirst().orElse(null);
|
||||||
if (c == null) {
|
if (c == null) {
|
||||||
args.add(valueFormatter.toString(entry.getValue().defaultValue(), type));
|
args.add(ValueFormatter.toString(parameter.defaultValue(), type));
|
||||||
} else {
|
} else {
|
||||||
throw new GenerationException("Constructor using complex property not supported yet");
|
throw new GenerationException("Constructor using complex property not supported yet");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
args.add(valueFormatter.toString(p.value(), type));
|
args.add(ValueFormatter.toString(p.value(), type));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return args;
|
return args;
|
||||||
@@ -69,7 +66,8 @@ final class ConstructorHelper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (matchingConstructorArgs == null) {
|
if (matchingConstructorArgs == null) {
|
||||||
return Arrays.stream(constructors).filter(c -> c.getParameterCount() == 0).findFirst().map(c -> new ConstructorArgs(c, new LinkedHashMap<>())).orElse(null);
|
return Arrays.stream(constructors).filter(c -> c.getParameterCount() == 0).findFirst()
|
||||||
|
.map(c -> new ConstructorArgs(c, new LinkedHashMap<>())).orElse(null);
|
||||||
} else {
|
} else {
|
||||||
return matchingConstructorArgs;
|
return matchingConstructorArgs;
|
||||||
}
|
}
|
||||||
@@ -83,6 +81,10 @@ final class ConstructorHelper {
|
|||||||
* @return The number of matching arguments
|
* @return The number of matching arguments
|
||||||
*/
|
*/
|
||||||
private static long getMatchingArgsCount(final ConstructorArgs constructorArgs, final Set<String> allPropertyNames) {
|
private static long getMatchingArgsCount(final ConstructorArgs constructorArgs, final Set<String> allPropertyNames) {
|
||||||
return constructorArgs.namedArgs().keySet().stream().filter(allPropertyNames::contains).count();
|
if (constructorArgs.namedArgs().keySet().stream().anyMatch(s -> !allPropertyNames.contains(s))) {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return constructorArgs.namedArgs().keySet().stream().filter(allPropertyNames::contains).count();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
package com.github.gtache.fxml.compiler.impl.internal;
|
package com.github.gtache.fxml.compiler.impl.internal;
|
||||||
|
|
||||||
|
import com.github.gtache.fxml.compiler.ControllerFieldInjectionType;
|
||||||
import com.github.gtache.fxml.compiler.ControllerInfo;
|
import com.github.gtache.fxml.compiler.ControllerInfo;
|
||||||
import com.github.gtache.fxml.compiler.GenerationException;
|
import com.github.gtache.fxml.compiler.ControllerMethodsInjectionType;
|
||||||
import com.github.gtache.fxml.compiler.InjectionType;
|
|
||||||
import com.github.gtache.fxml.compiler.impl.ControllerFieldInjectionTypes;
|
|
||||||
import com.github.gtache.fxml.compiler.impl.ControllerMethodsInjectionType;
|
|
||||||
import com.github.gtache.fxml.compiler.impl.GeneratorImpl;
|
import com.github.gtache.fxml.compiler.impl.GeneratorImpl;
|
||||||
import com.github.gtache.fxml.compiler.parsing.ParsedProperty;
|
import com.github.gtache.fxml.compiler.parsing.ParsedProperty;
|
||||||
|
|
||||||
@@ -18,14 +16,15 @@ import static java.util.Objects.requireNonNull;
|
|||||||
final class ControllerInjector {
|
final class ControllerInjector {
|
||||||
|
|
||||||
private final ControllerInfo controllerInfo;
|
private final ControllerInfo controllerInfo;
|
||||||
private final InjectionType fieldInjectionType;
|
private final ControllerFieldInjectionType fieldInjectionType;
|
||||||
private final InjectionType methodInjectionType;
|
private final ControllerMethodsInjectionType methodInjectionType;
|
||||||
private final StringBuilder sb;
|
private final StringBuilder sb;
|
||||||
private final SequencedCollection<String> controllerFactoryPostAction;
|
private final SequencedCollection<String> controllerFactoryPostAction;
|
||||||
|
|
||||||
ControllerInjector(final ControllerInfo controllerInfo, final InjectionType fieldInjectionType, final InjectionType methodInjectionType,
|
ControllerInjector(final ControllerInfo controllerInfo, final ControllerFieldInjectionType fieldInjectionType,
|
||||||
final StringBuilder sb, final SequencedCollection<String> controllerFactoryPostAction) {
|
final ControllerMethodsInjectionType methodInjectionType, final StringBuilder sb,
|
||||||
this.controllerInfo = controllerInfo;
|
final SequencedCollection<String> controllerFactoryPostAction) {
|
||||||
|
this.controllerInfo = requireNonNull(controllerInfo);
|
||||||
this.fieldInjectionType = requireNonNull(fieldInjectionType);
|
this.fieldInjectionType = requireNonNull(fieldInjectionType);
|
||||||
this.methodInjectionType = requireNonNull(methodInjectionType);
|
this.methodInjectionType = requireNonNull(methodInjectionType);
|
||||||
this.sb = requireNonNull(sb);
|
this.sb = requireNonNull(sb);
|
||||||
@@ -37,23 +36,18 @@ final class ControllerInjector {
|
|||||||
*
|
*
|
||||||
* @param id The object id
|
* @param id The object id
|
||||||
* @param variable The object variable
|
* @param variable The object variable
|
||||||
* @throws GenerationException if an error occurs
|
|
||||||
*/
|
*/
|
||||||
void injectControllerField(final String id, final String variable) throws GenerationException {
|
void injectControllerField(final String id, final String variable) {
|
||||||
if (fieldInjectionType instanceof final ControllerFieldInjectionTypes types) {
|
switch (fieldInjectionType) {
|
||||||
switch (types) {
|
case FACTORY ->
|
||||||
case FACTORY ->
|
sb.append(" fieldMap.put(\"").append(id).append("\", ").append(variable).append(");\n");
|
||||||
sb.append(" fieldMap.put(\"").append(id).append("\", ").append(variable).append(");\n");
|
case ASSIGN -> sb.append(" controller.").append(id).append(" = ").append(variable).append(";\n");
|
||||||
case ASSIGN -> sb.append(" controller.").append(id).append(" = ").append(variable).append(";\n");
|
case SETTERS -> {
|
||||||
case SETTERS -> {
|
final var setMethod = GenerationHelper.getSetMethod(id);
|
||||||
final var setMethod = GenerationHelper.getSetMethod(id);
|
sb.append(" controller.").append(setMethod).append("(").append(variable).append(");\n");
|
||||||
sb.append(" controller.").append(setMethod).append("(").append(variable).append(");\n");
|
|
||||||
}
|
|
||||||
case REFLECTION ->
|
|
||||||
sb.append(" injectField(\"").append(id).append("\", ").append(variable).append(");\n");
|
|
||||||
}
|
}
|
||||||
} else {
|
case REFLECTION ->
|
||||||
throw new GenerationException("Unknown controller injection type : " + fieldInjectionType);
|
sb.append(" injectField(\"").append(id).append("\", ").append(variable).append(");\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,9 +56,8 @@ final class ControllerInjector {
|
|||||||
*
|
*
|
||||||
* @param property The property to inject
|
* @param property The property to inject
|
||||||
* @param parentVariable The parent variable
|
* @param parentVariable The parent variable
|
||||||
* @throws GenerationException if an error occurs
|
|
||||||
*/
|
*/
|
||||||
void injectEventHandlerControllerMethod(final ParsedProperty property, final String parentVariable) throws GenerationException {
|
void injectEventHandlerControllerMethod(final ParsedProperty property, final String parentVariable) {
|
||||||
injectControllerMethod(getEventHandlerMethodInjection(property, parentVariable));
|
injectControllerMethod(getEventHandlerMethodInjection(property, parentVariable));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,9 +67,8 @@ final class ControllerInjector {
|
|||||||
* @param property The property to inject
|
* @param property The property to inject
|
||||||
* @param parentVariable The parent variable
|
* @param parentVariable The parent variable
|
||||||
* @param argumentClazz The argument class
|
* @param argumentClazz The argument class
|
||||||
* @throws GenerationException if an error occurs
|
|
||||||
*/
|
*/
|
||||||
void injectCallbackControllerMethod(final ParsedProperty property, final String parentVariable, final String argumentClazz) throws GenerationException {
|
void injectCallbackControllerMethod(final ParsedProperty property, final String parentVariable, final String argumentClazz) {
|
||||||
injectControllerMethod(getCallbackMethodInjection(property, parentVariable, argumentClazz));
|
injectControllerMethod(getCallbackMethodInjection(property, parentVariable, argumentClazz));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,16 +76,11 @@ final class ControllerInjector {
|
|||||||
* Injects a controller method
|
* Injects a controller method
|
||||||
*
|
*
|
||||||
* @param methodInjection The method injection
|
* @param methodInjection The method injection
|
||||||
* @throws GenerationException if an error occurs
|
|
||||||
*/
|
*/
|
||||||
private void injectControllerMethod(final String methodInjection) throws GenerationException {
|
private void injectControllerMethod(final String methodInjection) {
|
||||||
if (fieldInjectionType instanceof final ControllerFieldInjectionTypes fieldTypes) {
|
switch (fieldInjectionType) {
|
||||||
switch (fieldTypes) {
|
case FACTORY -> controllerFactoryPostAction.add(methodInjection);
|
||||||
case FACTORY -> controllerFactoryPostAction.add(methodInjection);
|
case ASSIGN, SETTERS, REFLECTION -> sb.append(methodInjection);
|
||||||
case ASSIGN, SETTERS, REFLECTION -> sb.append(methodInjection);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw getUnknownInjectionException(fieldInjectionType);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -103,27 +90,22 @@ final class ControllerInjector {
|
|||||||
* @param property The property
|
* @param property The property
|
||||||
* @param parentVariable The parent variable
|
* @param parentVariable The parent variable
|
||||||
* @return The method injection
|
* @return The method injection
|
||||||
* @throws GenerationException if an error occurs
|
|
||||||
*/
|
*/
|
||||||
private String getEventHandlerMethodInjection(final ParsedProperty property, final String parentVariable) throws GenerationException {
|
private String getEventHandlerMethodInjection(final ParsedProperty property, final String parentVariable) {
|
||||||
final var setMethod = GenerationHelper.getSetMethod(property.name());
|
final var setMethod = GenerationHelper.getSetMethod(property.name());
|
||||||
final var controllerMethod = property.value().replace("#", "");
|
final var controllerMethod = property.value().replace("#", "");
|
||||||
if (methodInjectionType instanceof final ControllerMethodsInjectionType methodTypes) {
|
return switch (methodInjectionType) {
|
||||||
return switch (methodTypes) {
|
case REFERENCE -> {
|
||||||
case REFERENCE -> {
|
final var hasArgument = controllerInfo.handlerHasArgument(controllerMethod);
|
||||||
final var hasArgument = controllerInfo.handlerHasArgument(controllerMethod);
|
if (hasArgument) {
|
||||||
if (hasArgument) {
|
yield " " + parentVariable + "." + setMethod + "(controller::" + controllerMethod + ");\n";
|
||||||
yield " " + parentVariable + "." + setMethod + "(controller::" + controllerMethod + ");\n";
|
} else {
|
||||||
} else {
|
yield " " + parentVariable + "." + setMethod + "(e -> controller." + controllerMethod + "());\n";
|
||||||
yield " " + parentVariable + "." + setMethod + "(e -> controller." + controllerMethod + "());\n";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
case REFLECTION ->
|
}
|
||||||
" " + parentVariable + "." + setMethod + "(e -> callEventHandlerMethod(\"" + controllerMethod + "\", e));\n";
|
case REFLECTION ->
|
||||||
};
|
" " + parentVariable + "." + setMethod + "(e -> callEventHandlerMethod(\"" + controllerMethod + "\", e));\n";
|
||||||
} else {
|
};
|
||||||
throw getUnknownInjectionException(methodInjectionType);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -133,24 +115,15 @@ final class ControllerInjector {
|
|||||||
* @param parentVariable The parent variable
|
* @param parentVariable The parent variable
|
||||||
* @param argumentClazz The argument class
|
* @param argumentClazz The argument class
|
||||||
* @return The method injection
|
* @return The method injection
|
||||||
* @throws GenerationException if an error occurs
|
|
||||||
*/
|
*/
|
||||||
private String getCallbackMethodInjection(final ParsedProperty property, final String parentVariable, final String argumentClazz) throws GenerationException {
|
private String getCallbackMethodInjection(final ParsedProperty property, final String parentVariable, final String argumentClazz) {
|
||||||
final var setMethod = GenerationHelper.getSetMethod(property.name());
|
final var setMethod = GenerationHelper.getSetMethod(property.name());
|
||||||
final var controllerMethod = property.value().replace("#", "");
|
final var controllerMethod = property.value().replace("#", "");
|
||||||
if (methodInjectionType instanceof final ControllerMethodsInjectionType methodTypes) {
|
return switch (methodInjectionType) {
|
||||||
return switch (methodTypes) {
|
case REFERENCE ->
|
||||||
case REFERENCE ->
|
" " + parentVariable + "." + setMethod + "(controller::" + controllerMethod + ");\n";
|
||||||
" " + parentVariable + "." + setMethod + "(controller::" + controllerMethod + ");\n";
|
case REFLECTION ->
|
||||||
case REFLECTION ->
|
" " + parentVariable + "." + setMethod + "(e -> callCallbackMethod(\"" + controllerMethod + "\", e, " + argumentClazz + "));\n";
|
||||||
" " + parentVariable + "." + setMethod + "(e -> callCallbackMethod(\"" + controllerMethod + "\", e, " + argumentClazz + "));\n";
|
};
|
||||||
};
|
|
||||||
} else {
|
|
||||||
throw getUnknownInjectionException(methodInjectionType);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static GenerationException getUnknownInjectionException(final InjectionType type) {
|
|
||||||
return new GenerationException("Unknown injection type : " + type);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,27 +1,27 @@
|
|||||||
package com.github.gtache.fxml.compiler.impl.internal;
|
package com.github.gtache.fxml.compiler.impl.internal;
|
||||||
|
|
||||||
|
import com.github.gtache.fxml.compiler.ControllerFieldInjectionType;
|
||||||
import com.github.gtache.fxml.compiler.GenerationException;
|
import com.github.gtache.fxml.compiler.GenerationException;
|
||||||
import com.github.gtache.fxml.compiler.InjectionType;
|
|
||||||
import com.github.gtache.fxml.compiler.impl.ControllerFieldInjectionTypes;
|
|
||||||
import com.github.gtache.fxml.compiler.impl.GeneratorImpl;
|
import com.github.gtache.fxml.compiler.impl.GeneratorImpl;
|
||||||
import com.github.gtache.fxml.compiler.parsing.ParsedProperty;
|
import com.github.gtache.fxml.compiler.parsing.ParsedProperty;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.SequencedCollection;
|
import java.util.SequencedCollection;
|
||||||
|
|
||||||
import static com.github.gtache.fxml.compiler.impl.internal.GenerationHelper.EXPRESSION_PREFIX;
|
import static com.github.gtache.fxml.compiler.impl.internal.GenerationHelper.EXPRESSION_PREFIX;
|
||||||
import static java.util.Objects.requireNonNull;
|
import static java.util.Objects.requireNonNull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper methods for {@link GeneratorImpl} to set fields
|
* Helper methods for {@link GeneratorImpl} to set nodes properties using controller's fields
|
||||||
*/
|
*/
|
||||||
final class FieldSetter {
|
final class FieldSetter {
|
||||||
|
|
||||||
private final HelperProvider helperProvider;
|
private final HelperProvider helperProvider;
|
||||||
private final InjectionType fieldInjectionType;
|
private final ControllerFieldInjectionType fieldInjectionType;
|
||||||
private final StringBuilder sb;
|
private final StringBuilder sb;
|
||||||
private final SequencedCollection<String> controllerFactoryPostAction;
|
private final SequencedCollection<String> controllerFactoryPostAction;
|
||||||
|
|
||||||
FieldSetter(final HelperProvider helperProvider, final InjectionType fieldInjectionType,
|
FieldSetter(final HelperProvider helperProvider, final ControllerFieldInjectionType fieldInjectionType,
|
||||||
final StringBuilder sb, final SequencedCollection<String> controllerFactoryPostAction) {
|
final StringBuilder sb, final SequencedCollection<String> controllerFactoryPostAction) {
|
||||||
this.helperProvider = requireNonNull(helperProvider);
|
this.helperProvider = requireNonNull(helperProvider);
|
||||||
this.fieldInjectionType = requireNonNull(fieldInjectionType);
|
this.fieldInjectionType = requireNonNull(fieldInjectionType);
|
||||||
@@ -34,7 +34,7 @@ final class FieldSetter {
|
|||||||
*
|
*
|
||||||
* @param property The property to inject
|
* @param property The property to inject
|
||||||
* @param parentVariable The parent variable
|
* @param parentVariable The parent variable
|
||||||
* @throws GenerationException if an error occurs@
|
* @throws GenerationException if an error occurs
|
||||||
*/
|
*/
|
||||||
void setEventHandler(final ParsedProperty property, final String parentVariable) throws GenerationException {
|
void setEventHandler(final ParsedProperty property, final String parentVariable) throws GenerationException {
|
||||||
setField(property, parentVariable, "javafx.event.EventHandler");
|
setField(property, parentVariable, "javafx.event.EventHandler");
|
||||||
@@ -50,54 +50,66 @@ final class FieldSetter {
|
|||||||
* @throws GenerationException if an error occurs
|
* @throws GenerationException if an error occurs
|
||||||
*/
|
*/
|
||||||
void setField(final ParsedProperty property, final String parentVariable, final String fieldType) throws GenerationException {
|
void setField(final ParsedProperty property, final String parentVariable, final String fieldType) throws GenerationException {
|
||||||
if (fieldInjectionType instanceof final ControllerFieldInjectionTypes fieldTypes) {
|
switch (fieldInjectionType) {
|
||||||
switch (fieldTypes) {
|
case ASSIGN -> setAssign(property, parentVariable);
|
||||||
case ASSIGN -> setAssign(property, parentVariable);
|
case FACTORY -> setFactory(property, parentVariable);
|
||||||
case FACTORY -> setFactory(property, parentVariable);
|
case REFLECTION -> setReflection(property, parentVariable, fieldType);
|
||||||
case SETTERS -> setSetter(property, parentVariable);
|
case SETTERS -> setSetter(property, parentVariable);
|
||||||
case REFLECTION -> setReflection(property, parentVariable, fieldType);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw new GenerationException("Unknown injection type : " + fieldInjectionType);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setAssign(final ParsedProperty property, final String parentVariable) {
|
private void setAssign(final ParsedProperty property, final String parentVariable) throws GenerationException {
|
||||||
final var methodName = GenerationHelper.getSetMethod(property);
|
final var methodName = GenerationHelper.getSetMethod(property);
|
||||||
final var value = property.value().replace(EXPRESSION_PREFIX, "");
|
final var value = property.value().replace(EXPRESSION_PREFIX, "");
|
||||||
sb.append(" ").append(parentVariable).append(".").append(methodName).append("(").append(value).append(");\n");
|
final var split = value.split("\\.");
|
||||||
|
final var holderName = split[0];
|
||||||
|
if (Objects.equals(holderName, "controller")) {
|
||||||
|
sb.append(" ").append(parentVariable).append(".").append(methodName).append("(").append(value).append(");\n");
|
||||||
|
} else {
|
||||||
|
throw new GenerationException("Unexpected variable holder : " + holderName + " ; expected : controller");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setFactory(final ParsedProperty property, final String parentVariable) {
|
private void setFactory(final ParsedProperty property, final String parentVariable) throws GenerationException {
|
||||||
controllerFactoryPostAction.add(getSetString(property, parentVariable));
|
controllerFactoryPostAction.add(getSetString(property, parentVariable));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setSetter(final ParsedProperty property, final String parentVariable) {
|
private void setSetter(final ParsedProperty property, final String parentVariable) throws GenerationException {
|
||||||
sb.append(getSetString(property, parentVariable));
|
sb.append(getSetString(property, parentVariable));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String getSetString(final ParsedProperty property, final String parentVariable) {
|
private static String getSetString(final ParsedProperty property, final String parentVariable) throws GenerationException {
|
||||||
final var methodName = GenerationHelper.getSetMethod(property);
|
final var methodName = GenerationHelper.getSetMethod(property);
|
||||||
final var value = property.value().replace(EXPRESSION_PREFIX, "");
|
final var value = property.value().replace(EXPRESSION_PREFIX, "");
|
||||||
final var split = value.split("\\.");
|
final var split = value.split("\\.");
|
||||||
final var getterName = GenerationHelper.getGetMethod(split[1]);
|
final var holderName = split[0];
|
||||||
return " " + parentVariable + "." + methodName + "(" + split[0] + "." + getterName + ");\n";
|
if (Objects.equals(holderName, "controller")) {
|
||||||
|
final var getterName = GenerationHelper.getGetMethod(split[1]);
|
||||||
|
return " " + parentVariable + "." + methodName + "(controller." + getterName + "());\n";
|
||||||
|
} else {
|
||||||
|
throw new GenerationException("Unexpected variable holder : " + holderName + " ; expected : controller");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setReflection(final ParsedProperty property, final String parentVariable, final String fieldType) {
|
private void setReflection(final ParsedProperty property, final String parentVariable, final String fieldType) throws GenerationException {
|
||||||
final var methodName = GenerationHelper.getSetMethod(property);
|
final var methodName = GenerationHelper.getSetMethod(property);
|
||||||
final var value = property.value().replace(EXPRESSION_PREFIX, "");
|
final var value = property.value().replace(EXPRESSION_PREFIX, "");
|
||||||
final var split = value.split("\\.");
|
final var split = value.split("\\.");
|
||||||
final var fieldName = split[1];
|
final var holderName = split[0];
|
||||||
sb.append(" try {\n");
|
if (Objects.equals(holderName, "controller")) {
|
||||||
sb.append(" ").append(helperProvider.getCompatibilityHelper().getStartVar("java.lang.reflect.Field", 0))
|
final var fieldName = split[1];
|
||||||
.append("field = controller.getClass().getDeclaredField(\"").append(fieldName).append("\");\n");
|
sb.append(" try {\n");
|
||||||
sb.append(" field.setAccessible(true);\n");
|
sb.append(" ").append(helperProvider.getCompatibilityHelper().getStartVar("java.lang.reflect.Field", 0))
|
||||||
sb.append(" final var value = (").append(fieldType).append(") field.get(controller);\n");
|
.append("field = controller.getClass().getDeclaredField(\"").append(fieldName).append("\");\n");
|
||||||
sb.append(" ").append(parentVariable).append(".").append(methodName).append("(value);\n");
|
sb.append(" field.setAccessible(true);\n");
|
||||||
sb.append(" } catch (final NoSuchFieldException | IllegalAccessException e) {\n");
|
sb.append(" final var value = (").append(fieldType).append(") field.get(controller);\n");
|
||||||
sb.append(" throw new RuntimeException(e);\n");
|
sb.append(" ").append(parentVariable).append(".").append(methodName).append("(value);\n");
|
||||||
sb.append(" }\n");
|
sb.append(" } catch (final NoSuchFieldException | IllegalAccessException e) {\n");
|
||||||
|
sb.append(" throw new RuntimeException(e);\n");
|
||||||
|
sb.append(" }\n");
|
||||||
|
} else {
|
||||||
|
throw new GenerationException("Unexpected variable holder : " + holderName + " ; expected : controller");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,14 +41,17 @@ final class FontFormatter {
|
|||||||
final var fp = value.fontPosture();
|
final var fp = value.fontPosture();
|
||||||
final var size = value.size();
|
final var size = value.size();
|
||||||
final var name = value.name();
|
final var name = value.name();
|
||||||
if (url != null) {
|
if (url == null) {
|
||||||
formatURL(url, size, variableName);
|
if (name == null) {
|
||||||
} else if (fw == null && fp == null) {
|
throw new GenerationException("Font must have a name or url : " + parsedObject);
|
||||||
formatNoStyle(name, size, variableName);
|
} else if (fw == null && fp == null) {
|
||||||
|
formatNoStyle(name, size, variableName);
|
||||||
|
} else {
|
||||||
|
formatStyle(fw, fp, size, name, variableName);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
formatStyle(fw, fp, size, name, variableName);
|
formatURL(url, size, variableName);
|
||||||
}
|
}
|
||||||
helperProvider.getGenerationHelper().handleId(parsedObject, variableName);
|
|
||||||
} else {
|
} else {
|
||||||
throw new GenerationException("Font cannot have children or properties : " + parsedObject);
|
throw new GenerationException("Font cannot have children or properties : " + parsedObject);
|
||||||
}
|
}
|
||||||
@@ -57,7 +60,7 @@ final class FontFormatter {
|
|||||||
private void formatURL(final URL url, final double size, final String variableName) {
|
private void formatURL(final URL url, final double size, final String variableName) {
|
||||||
final var urlVariableName = helperProvider.getURLFormatter().formatURL(url.toString());
|
final var urlVariableName = helperProvider.getURLFormatter().formatURL(url.toString());
|
||||||
sb.append(" final javafx.scene.text.Font ").append(variableName).append(";\n");
|
sb.append(" final javafx.scene.text.Font ").append(variableName).append(";\n");
|
||||||
sb.append(" try (").append(helperProvider.getCompatibilityHelper().getStartVar("java.io.InputStream", 0)).append(" in = ").append(urlVariableName).append(".openStream()) {\n");
|
sb.append(" try (").append(helperProvider.getCompatibilityHelper().getStartVar("java.io.InputStream", 0)).append("in = ").append(urlVariableName).append(".openStream()) {\n");
|
||||||
sb.append(" ").append(variableName).append(" = javafx.scene.text.Font.loadFont(in, ").append(size).append(");\n");
|
sb.append(" ").append(variableName).append(" = javafx.scene.text.Font.loadFont(in, ").append(size).append(");\n");
|
||||||
sb.append(" } catch (final java.io.IOException e) {\n");
|
sb.append(" } catch (final java.io.IOException e) {\n");
|
||||||
sb.append(" throw new RuntimeException(e);\n");
|
sb.append(" throw new RuntimeException(e);\n");
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
package com.github.gtache.fxml.compiler.impl.internal;
|
package com.github.gtache.fxml.compiler.impl.internal;
|
||||||
|
|
||||||
import com.github.gtache.fxml.compiler.ControllerInfo;
|
|
||||||
import com.github.gtache.fxml.compiler.GenerationException;
|
|
||||||
import com.github.gtache.fxml.compiler.impl.GeneratorImpl;
|
import com.github.gtache.fxml.compiler.impl.GeneratorImpl;
|
||||||
import com.github.gtache.fxml.compiler.parsing.ParsedObject;
|
import com.github.gtache.fxml.compiler.parsing.ParsedObject;
|
||||||
import com.github.gtache.fxml.compiler.parsing.ParsedProperty;
|
import com.github.gtache.fxml.compiler.parsing.ParsedProperty;
|
||||||
@@ -11,8 +9,6 @@ import org.apache.logging.log4j.Logger;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import static java.util.Objects.requireNonNull;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Various helper methods for {@link GeneratorImpl}
|
* Various helper methods for {@link GeneratorImpl}
|
||||||
*/
|
*/
|
||||||
@@ -31,42 +27,8 @@ final class GenerationHelper {
|
|||||||
static final String BINDING_EXPRESSION_PREFIX = "${";
|
static final String BINDING_EXPRESSION_PREFIX = "${";
|
||||||
static final String BI_DIRECTIONAL_BINDING_PREFIX = "#{";
|
static final String BI_DIRECTIONAL_BINDING_PREFIX = "#{";
|
||||||
|
|
||||||
private final HelperProvider helperProvider;
|
private GenerationHelper() {
|
||||||
private final ControllerInfo controllerInfo;
|
|
||||||
private final Map<String, VariableInfo> idToVariableInfo;
|
|
||||||
|
|
||||||
GenerationHelper(final HelperProvider helperProvider, final ControllerInfo controllerInfo, final Map<String, VariableInfo> idToVariableInfo) {
|
|
||||||
this.helperProvider = requireNonNull(helperProvider);
|
|
||||||
this.controllerInfo = requireNonNull(controllerInfo);
|
|
||||||
this.idToVariableInfo = requireNonNull(idToVariableInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handles the fx:id attribute of an object
|
|
||||||
*
|
|
||||||
* @param parsedObject The parsed object
|
|
||||||
* @param variableName The variable name
|
|
||||||
* @throws GenerationException if an error occurs
|
|
||||||
*/
|
|
||||||
void handleId(final ParsedObject parsedObject, final String variableName) throws GenerationException {
|
|
||||||
final var id = parsedObject.attributes().get(FX_ID);
|
|
||||||
if (id != null) {
|
|
||||||
final var idValue = id.value();
|
|
||||||
final String className;
|
|
||||||
if (controllerInfo.fieldInfo(idValue) == null) {
|
|
||||||
className = parsedObject.className();
|
|
||||||
logger.debug("Not injecting {} because it is not found in controller", idValue);
|
|
||||||
} else {
|
|
||||||
final var reflectionHelper = helperProvider.getReflectionHelper();
|
|
||||||
if (ReflectionHelper.isGeneric(ReflectionHelper.getClass(parsedObject.className()))) {
|
|
||||||
className = parsedObject.className() + reflectionHelper.getGenericTypes(parsedObject);
|
|
||||||
} else {
|
|
||||||
className = parsedObject.className();
|
|
||||||
}
|
|
||||||
helperProvider.getControllerInjector().injectControllerField(idValue, variableName);
|
|
||||||
}
|
|
||||||
idToVariableInfo.put(idValue, new VariableInfo(idValue, parsedObject, variableName, className));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -4,27 +4,17 @@ import com.github.gtache.fxml.compiler.GenerationRequest;
|
|||||||
import com.github.gtache.fxml.compiler.impl.GeneratorImpl;
|
import com.github.gtache.fxml.compiler.impl.GeneratorImpl;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.SequencedCollection;
|
import java.util.SequencedCollection;
|
||||||
import java.util.SequencedMap;
|
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used by {@link GeneratorImpl} to track the generation progress
|
* Used by {@link GeneratorImpl} to track the generation progress
|
||||||
*
|
*
|
||||||
* @param request The generation request
|
* @param request The generation request
|
||||||
* @param idToVariableInfo The id to variable info
|
|
||||||
* @param variableNameCounters The variable name counters for variable name generation
|
|
||||||
* @param controllerClassToVariable The controller class to variable mapping
|
|
||||||
* @param controllerFactoryPostAction The controller factory post action for factory injection
|
* @param controllerFactoryPostAction The controller factory post action for factory injection
|
||||||
* @param stringBuilder The string builder
|
* @param stringBuilder The string builder
|
||||||
*/
|
*/
|
||||||
public record GenerationProgress(GenerationRequest request, Map<String, VariableInfo> idToVariableInfo,
|
public record GenerationProgress(GenerationRequest request,
|
||||||
Map<String, AtomicInteger> variableNameCounters,
|
|
||||||
SequencedMap<String, String> controllerClassToVariable,
|
|
||||||
SequencedCollection<String> controllerFactoryPostAction,
|
SequencedCollection<String> controllerFactoryPostAction,
|
||||||
StringBuilder stringBuilder) {
|
StringBuilder stringBuilder) {
|
||||||
|
|
||||||
@@ -32,18 +22,12 @@ public record GenerationProgress(GenerationRequest request, Map<String, Variable
|
|||||||
* Instantiates a new GenerationProgress
|
* Instantiates a new GenerationProgress
|
||||||
*
|
*
|
||||||
* @param request The generation request
|
* @param request The generation request
|
||||||
* @param idToVariableInfo The id to variable info mapping
|
|
||||||
* @param variableNameCounters The variable name counters
|
|
||||||
* @param controllerClassToVariable The controller class to variable mapping
|
|
||||||
* @param controllerFactoryPostAction The controller factory post action
|
* @param controllerFactoryPostAction The controller factory post action
|
||||||
* @param stringBuilder The string builder
|
* @param stringBuilder The string builder
|
||||||
* @throws NullPointerException if any parameter is null
|
* @throws NullPointerException if any parameter is null
|
||||||
*/
|
*/
|
||||||
public GenerationProgress {
|
public GenerationProgress {
|
||||||
Objects.requireNonNull(request);
|
Objects.requireNonNull(request);
|
||||||
Objects.requireNonNull(idToVariableInfo);
|
|
||||||
Objects.requireNonNull(variableNameCounters);
|
|
||||||
Objects.requireNonNull(controllerClassToVariable);
|
|
||||||
Objects.requireNonNull(controllerFactoryPostAction);
|
Objects.requireNonNull(controllerFactoryPostAction);
|
||||||
Objects.requireNonNull(stringBuilder);
|
Objects.requireNonNull(stringBuilder);
|
||||||
}
|
}
|
||||||
@@ -55,17 +39,6 @@ public record GenerationProgress(GenerationRequest request, Map<String, Variable
|
|||||||
* @throws NullPointerException if request is null
|
* @throws NullPointerException if request is null
|
||||||
*/
|
*/
|
||||||
public GenerationProgress(final GenerationRequest request) {
|
public GenerationProgress(final GenerationRequest request) {
|
||||||
this(request, new HashMap<>(), new HashMap<>(), new LinkedHashMap<>(), new ArrayList<>(), new StringBuilder());
|
this(request, new ArrayList<>(), new StringBuilder());
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the next available variable name for the given prefix
|
|
||||||
*
|
|
||||||
* @param prefix The variable name prefix
|
|
||||||
* @return The next available variable name
|
|
||||||
*/
|
|
||||||
String getNextVariableName(final String prefix) {
|
|
||||||
final var counter = variableNameCounters.computeIfAbsent(prefix, k -> new AtomicInteger(0));
|
|
||||||
return prefix + counter.getAndIncrement();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
package com.github.gtache.fxml.compiler.impl.internal;
|
package com.github.gtache.fxml.compiler.impl.internal;
|
||||||
|
|
||||||
import com.github.gtache.fxml.compiler.InjectionType;
|
import com.github.gtache.fxml.compiler.ControllerFieldInjectionType;
|
||||||
import com.github.gtache.fxml.compiler.impl.ControllerFieldInjectionTypes;
|
import com.github.gtache.fxml.compiler.ControllerMethodsInjectionType;
|
||||||
import com.github.gtache.fxml.compiler.impl.ControllerMethodsInjectionType;
|
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
@@ -12,11 +11,12 @@ import java.util.Objects;
|
|||||||
public final class HelperMethodsFormatter {
|
public final class HelperMethodsFormatter {
|
||||||
|
|
||||||
private final HelperProvider helperProvider;
|
private final HelperProvider helperProvider;
|
||||||
private final InjectionType fieldInjectionType;
|
private final ControllerFieldInjectionType fieldInjectionType;
|
||||||
private final InjectionType methodInjectionType;
|
private final ControllerMethodsInjectionType methodInjectionType;
|
||||||
private final StringBuilder sb;
|
private final StringBuilder sb;
|
||||||
|
|
||||||
HelperMethodsFormatter(final HelperProvider helperProvider, final InjectionType fieldInjectionType, final InjectionType methodInjectionType, final StringBuilder sb) {
|
HelperMethodsFormatter(final HelperProvider helperProvider, final ControllerFieldInjectionType fieldInjectionType,
|
||||||
|
final ControllerMethodsInjectionType methodInjectionType, final StringBuilder sb) {
|
||||||
this.helperProvider = Objects.requireNonNull(helperProvider);
|
this.helperProvider = Objects.requireNonNull(helperProvider);
|
||||||
this.fieldInjectionType = Objects.requireNonNull(fieldInjectionType);
|
this.fieldInjectionType = Objects.requireNonNull(fieldInjectionType);
|
||||||
this.methodInjectionType = Objects.requireNonNull(methodInjectionType);
|
this.methodInjectionType = Objects.requireNonNull(methodInjectionType);
|
||||||
@@ -73,7 +73,7 @@ public final class HelperMethodsFormatter {
|
|||||||
sb.append(" .filter(m -> m.getName().equals(methodName))").append(toList).append(";\n");
|
sb.append(" .filter(m -> m.getName().equals(methodName))").append(toList).append(";\n");
|
||||||
sb.append(" if (methods.size() > 1) {\n");
|
sb.append(" if (methods.size() > 1) {\n");
|
||||||
sb.append(" ").append(startVariableMethodList).append("eventMethods = methods.stream().filter(m ->\n");
|
sb.append(" ").append(startVariableMethodList).append("eventMethods = methods.stream().filter(m ->\n");
|
||||||
sb.append(" m.getParameterCount() == 1 && clazz.isAssignableFrom(m.getParameterTypes()[0]))").append(toList).append(";\n");
|
sb.append(" m.getParameterCount() == 2 && clazz.isAssignableFrom(m.getParameterTypes()[1]))").append(toList).append(";\n");
|
||||||
sb.append(" if (eventMethods.size() == 1) {\n");
|
sb.append(" if (eventMethods.size() == 1) {\n");
|
||||||
sb.append(" method = eventMethods").append(getFirst).append(";\n");
|
sb.append(" method = eventMethods").append(getFirst).append(";\n");
|
||||||
sb.append(" } else {\n");
|
sb.append(" } else {\n");
|
||||||
@@ -91,7 +91,7 @@ public final class HelperMethodsFormatter {
|
|||||||
sb.append(" }\n");
|
sb.append(" }\n");
|
||||||
sb.append(" }\n");
|
sb.append(" }\n");
|
||||||
}
|
}
|
||||||
if (fieldInjectionType == ControllerFieldInjectionTypes.REFLECTION) {
|
if (fieldInjectionType == ControllerFieldInjectionType.REFLECTION) {
|
||||||
sb.append(" private <T> void injectField(final String fieldName, final T object) {\n");
|
sb.append(" private <T> void injectField(final String fieldName, final T object) {\n");
|
||||||
sb.append(" try {\n");
|
sb.append(" try {\n");
|
||||||
sb.append(" ").append(compatibilityHelper.getStartVar("java.lang.reflect.Field", 0)).append("field = controller.getClass().getDeclaredField(fieldName);\n");
|
sb.append(" ").append(compatibilityHelper.getStartVar("java.lang.reflect.Field", 0)).append("field = controller.getClass().getDeclaredField(fieldName);\n");
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ public class HelperProvider {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Instantiates a new helper provider
|
* Instantiates a new helper provider
|
||||||
|
*
|
||||||
* @param progress The generation progress
|
* @param progress The generation progress
|
||||||
*/
|
*/
|
||||||
public HelperProvider(final GenerationProgress progress) {
|
public HelperProvider(final GenerationProgress progress) {
|
||||||
@@ -21,58 +22,66 @@ public class HelperProvider {
|
|||||||
this.helpers = new HashMap<>();
|
this.helpers = new HashMap<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
ConstructorHelper getConstructorHelper() {
|
|
||||||
return (ConstructorHelper) helpers.computeIfAbsent(ConstructorHelper.class, c -> new ConstructorHelper(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
ControllerInjector getControllerInjector() {
|
ControllerInjector getControllerInjector() {
|
||||||
final var request = progress.request();
|
return (ControllerInjector) helpers.computeIfAbsent(ControllerInjector.class, c -> {
|
||||||
final var controllerInfo = request.controllerInfo();
|
final var request = progress.request();
|
||||||
final var parameters = request.parameters();
|
final var controllerInfo = request.controllerInfo();
|
||||||
final var fieldInjectionType = parameters.fieldInjectionType();
|
final var parameters = request.parameters();
|
||||||
final var methodInjectionType = parameters.methodInjectionType();
|
final var fieldInjectionType = parameters.fieldInjectionType();
|
||||||
final var sb = progress.stringBuilder();
|
final var methodInjectionType = parameters.methodInjectionType();
|
||||||
final var controllerFactoryPostAction = progress.controllerFactoryPostAction();
|
final var sb = progress.stringBuilder();
|
||||||
return (ControllerInjector) helpers.computeIfAbsent(ControllerInjector.class, c -> new ControllerInjector(controllerInfo, fieldInjectionType, methodInjectionType, sb, controllerFactoryPostAction));
|
final var controllerFactoryPostAction = progress.controllerFactoryPostAction();
|
||||||
|
return new ControllerInjector(controllerInfo, fieldInjectionType, methodInjectionType, sb, controllerFactoryPostAction);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
FieldSetter getFieldSetter() {
|
FieldSetter getFieldSetter() {
|
||||||
final var fieldInjectionType = progress.request().parameters().fieldInjectionType();
|
return (FieldSetter) helpers.computeIfAbsent(FieldSetter.class, c -> {
|
||||||
final var sb = progress.stringBuilder();
|
final var fieldInjectionType = progress.request().parameters().fieldInjectionType();
|
||||||
final var controllerFactoryPostAction = progress.controllerFactoryPostAction();
|
final var sb = progress.stringBuilder();
|
||||||
return (FieldSetter) helpers.computeIfAbsent(FieldSetter.class, c -> new FieldSetter(this, fieldInjectionType, sb, controllerFactoryPostAction));
|
final var controllerFactoryPostAction = progress.controllerFactoryPostAction();
|
||||||
|
return new FieldSetter(this, fieldInjectionType, sb, controllerFactoryPostAction);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
FontFormatter getFontFormatter() {
|
FontFormatter getFontFormatter() {
|
||||||
final var sb = progress.stringBuilder();
|
return (FontFormatter) helpers.computeIfAbsent(FontFormatter.class, c -> {
|
||||||
return (FontFormatter) helpers.computeIfAbsent(FontFormatter.class, c -> new FontFormatter(this, sb));
|
final var sb = progress.stringBuilder();
|
||||||
|
return new FontFormatter(this, sb);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
GenerationCompatibilityHelper getCompatibilityHelper() {
|
GenerationCompatibilityHelper getCompatibilityHelper() {
|
||||||
final var compatibility = progress.request().parameters().compatibility();
|
return (GenerationCompatibilityHelper) helpers.computeIfAbsent(GenerationCompatibilityHelper.class, c -> {
|
||||||
return (GenerationCompatibilityHelper) helpers.computeIfAbsent(GenerationCompatibilityHelper.class, c -> new GenerationCompatibilityHelper(this, compatibility));
|
final var compatibility = progress.request().parameters().compatibility();
|
||||||
}
|
return new GenerationCompatibilityHelper(this, compatibility);
|
||||||
|
});
|
||||||
GenerationHelper getGenerationHelper() {
|
|
||||||
final var controllerInfo = progress.request().controllerInfo();
|
|
||||||
final var idToVariableInfo = progress.idToVariableInfo();
|
|
||||||
return (GenerationHelper) helpers.computeIfAbsent(GenerationHelper.class, c -> new GenerationHelper(this, controllerInfo, idToVariableInfo));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public HelperMethodsFormatter getHelperMethodsFormatter() {
|
public HelperMethodsFormatter getHelperMethodsFormatter() {
|
||||||
final var parameters = progress.request().parameters();
|
return (HelperMethodsFormatter) helpers.computeIfAbsent(HelperMethodsFormatter.class, c -> {
|
||||||
final var fieldInjectionType = parameters.fieldInjectionType();
|
final var parameters = progress.request().parameters();
|
||||||
final var methodInjectionType = parameters.methodInjectionType();
|
final var fieldInjectionType = parameters.fieldInjectionType();
|
||||||
final var sb = progress.stringBuilder();
|
final var methodInjectionType = parameters.methodInjectionType();
|
||||||
return (HelperMethodsFormatter) helpers.computeIfAbsent(HelperMethodsFormatter.class, c -> new HelperMethodsFormatter(this, fieldInjectionType, methodInjectionType, sb));
|
final var sb = progress.stringBuilder();
|
||||||
|
return new HelperMethodsFormatter(this, fieldInjectionType, methodInjectionType, sb);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
ImageFormatter getImageFormatter() {
|
ImageFormatter getImageFormatter() {
|
||||||
return (ImageFormatter) helpers.computeIfAbsent(ImageFormatter.class, c -> new ImageFormatter(this, progress));
|
return (ImageFormatter) helpers.computeIfAbsent(ImageFormatter.class, c -> {
|
||||||
|
final var sb = progress.stringBuilder();
|
||||||
|
final var useImageInputStreamConstructor = progress.request().parameters().useImageInputStreamConstructor();
|
||||||
|
return new ImageFormatter(this, sb, useImageInputStreamConstructor);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public InitializationFormatter getInitializationFormatter() {
|
public InitializationFormatter getInitializationFormatter() {
|
||||||
return (InitializationFormatter) helpers.computeIfAbsent(InitializationFormatter.class, c -> new InitializationFormatter(this, progress));
|
return (InitializationFormatter) helpers.computeIfAbsent(InitializationFormatter.class, c -> {
|
||||||
|
final var request = progress.request();
|
||||||
|
final var sb = progress.stringBuilder();
|
||||||
|
return new InitializationFormatter(this, request, sb);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public LoadMethodFormatter getLoadMethodFormatter() {
|
public LoadMethodFormatter getLoadMethodFormatter() {
|
||||||
@@ -80,7 +89,11 @@ public class HelperProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ObjectFormatter getObjectFormatter() {
|
ObjectFormatter getObjectFormatter() {
|
||||||
return (ObjectFormatter) helpers.computeIfAbsent(ObjectFormatter.class, c -> new ObjectFormatter(this, progress));
|
return (ObjectFormatter) helpers.computeIfAbsent(ObjectFormatter.class, c -> {
|
||||||
|
final var request = progress.request();
|
||||||
|
final var sb = progress.stringBuilder();
|
||||||
|
return new ObjectFormatter(this, request, sb);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
PropertyFormatter getPropertyFormatter() {
|
PropertyFormatter getPropertyFormatter() {
|
||||||
@@ -88,30 +101,48 @@ public class HelperProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ReflectionHelper getReflectionHelper() {
|
ReflectionHelper getReflectionHelper() {
|
||||||
final var controllerInfo = progress.request().controllerInfo();
|
return (ReflectionHelper) helpers.computeIfAbsent(ReflectionHelper.class, c -> {
|
||||||
return (ReflectionHelper) helpers.computeIfAbsent(ReflectionHelper.class, c -> new ReflectionHelper(controllerInfo));
|
final var controllerInfo = progress.request().controllerInfo();
|
||||||
|
return new ReflectionHelper(controllerInfo);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
SceneFormatter getSceneFormatter() {
|
SceneFormatter getSceneFormatter() {
|
||||||
return (SceneFormatter) helpers.computeIfAbsent(SceneFormatter.class, c -> new SceneFormatter(this, progress));
|
return (SceneFormatter) helpers.computeIfAbsent(SceneFormatter.class, c -> {
|
||||||
|
final var sb = progress.stringBuilder();
|
||||||
|
return new SceneFormatter(this, sb);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
TriangleMeshFormatter getTriangleMeshFormatter() {
|
TriangleMeshFormatter getTriangleMeshFormatter() {
|
||||||
final var sb = progress.stringBuilder();
|
return (TriangleMeshFormatter) helpers.computeIfAbsent(TriangleMeshFormatter.class, c -> {
|
||||||
return (TriangleMeshFormatter) helpers.computeIfAbsent(TriangleMeshFormatter.class, c -> new TriangleMeshFormatter(this, sb));
|
final var sb = progress.stringBuilder();
|
||||||
|
return new TriangleMeshFormatter(this, sb);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
URLFormatter getURLFormatter() {
|
URLFormatter getURLFormatter() {
|
||||||
return (URLFormatter) helpers.computeIfAbsent(URLFormatter.class, c -> new URLFormatter(this, progress));
|
return (URLFormatter) helpers.computeIfAbsent(URLFormatter.class, c -> {
|
||||||
|
final var sb = progress.stringBuilder();
|
||||||
|
return new URLFormatter(this, sb);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
ValueFormatter getValueFormatter() {
|
ValueFormatter getValueFormatter() {
|
||||||
final var resourceInjectionType = progress.request().parameters().resourceInjectionType();
|
return (ValueFormatter) helpers.computeIfAbsent(ValueFormatter.class, c -> {
|
||||||
final var idToVariableInfo = progress.idToVariableInfo();
|
final var resourceInjectionType = progress.request().parameters().resourceInjectionType();
|
||||||
return (ValueFormatter) helpers.computeIfAbsent(ValueFormatter.class, c -> new ValueFormatter(resourceInjectionType, idToVariableInfo));
|
return new ValueFormatter(this, resourceInjectionType);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
VariableProvider getVariableProvider() {
|
||||||
|
return (VariableProvider) helpers.computeIfAbsent(VariableProvider.class, c -> new VariableProvider());
|
||||||
}
|
}
|
||||||
|
|
||||||
WebViewFormatter getWebViewFormatter() {
|
WebViewFormatter getWebViewFormatter() {
|
||||||
return (WebViewFormatter) helpers.computeIfAbsent(WebViewFormatter.class, c -> new WebViewFormatter(this, progress));
|
return (WebViewFormatter) helpers.computeIfAbsent(WebViewFormatter.class, c -> {
|
||||||
|
final var sb = progress.stringBuilder();
|
||||||
|
return new WebViewFormatter(this, sb);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,10 +4,9 @@ import com.github.gtache.fxml.compiler.GenerationException;
|
|||||||
import com.github.gtache.fxml.compiler.impl.GeneratorImpl;
|
import com.github.gtache.fxml.compiler.impl.GeneratorImpl;
|
||||||
import com.github.gtache.fxml.compiler.parsing.ParsedObject;
|
import com.github.gtache.fxml.compiler.parsing.ParsedObject;
|
||||||
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
import static com.github.gtache.fxml.compiler.impl.internal.GenerationHelper.FX_ID;
|
import static com.github.gtache.fxml.compiler.impl.internal.GenerationHelper.FX_ID;
|
||||||
import static com.github.gtache.fxml.compiler.impl.internal.GenerationHelper.getSortedAttributes;
|
import static com.github.gtache.fxml.compiler.impl.internal.GenerationHelper.getSortedAttributes;
|
||||||
|
import static java.util.Objects.requireNonNull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper methods for {@link GeneratorImpl} to format Images
|
* Helper methods for {@link GeneratorImpl} to format Images
|
||||||
@@ -15,11 +14,13 @@ import static com.github.gtache.fxml.compiler.impl.internal.GenerationHelper.get
|
|||||||
final class ImageFormatter {
|
final class ImageFormatter {
|
||||||
|
|
||||||
private final HelperProvider helperProvider;
|
private final HelperProvider helperProvider;
|
||||||
private final GenerationProgress progress;
|
private final StringBuilder sb;
|
||||||
|
private final boolean useImageInputStreamConstructor;
|
||||||
|
|
||||||
ImageFormatter(final HelperProvider helperProvider, final GenerationProgress progress) {
|
ImageFormatter(final HelperProvider helperProvider, final StringBuilder sb, final boolean useImageInputStreamConstructor) {
|
||||||
this.helperProvider = Objects.requireNonNull(helperProvider);
|
this.helperProvider = requireNonNull(helperProvider);
|
||||||
this.progress = Objects.requireNonNull(progress);
|
this.sb = requireNonNull(sb);
|
||||||
|
this.useImageInputStreamConstructor = useImageInputStreamConstructor;
|
||||||
}
|
}
|
||||||
|
|
||||||
void formatImage(final ParsedObject parsedObject, final String variableName) throws GenerationException {
|
void formatImage(final ParsedObject parsedObject, final String variableName) throws GenerationException {
|
||||||
@@ -30,19 +31,6 @@ final class ImageFormatter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void formatInputStream(final String url, final double requestedWidth,
|
|
||||||
final double requestedHeight, final boolean preserveRatio, final boolean smooth, final String variableName) {
|
|
||||||
final var inputStream = progress.getNextVariableName("inputStream");
|
|
||||||
final var sb = progress.stringBuilder();
|
|
||||||
sb.append(" final javafx.scene.image.Image ").append(variableName).append(";\n");
|
|
||||||
sb.append(" try (").append(helperProvider.getCompatibilityHelper().getStartVar("java.io.InputStream", 0)).append(inputStream).append(" = ").append(url).append(".openStream()) {\n");
|
|
||||||
sb.append(" ").append(variableName).append(" = new javafx.scene.image.Image(").append(inputStream);
|
|
||||||
sb.append(", ").append(requestedWidth).append(", ").append(requestedHeight).append(", ").append(preserveRatio).append(", ").append(smooth).append(");\n");
|
|
||||||
sb.append(" } catch (final java.io.IOException e) {\n");
|
|
||||||
sb.append(" throw new RuntimeException(e);\n");
|
|
||||||
sb.append(" }\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void doFormatImage(final ParsedObject parsedObject, final String variableName) throws GenerationException {
|
private void doFormatImage(final ParsedObject parsedObject, final String variableName) throws GenerationException {
|
||||||
final var sortedAttributes = getSortedAttributes(parsedObject);
|
final var sortedAttributes = getSortedAttributes(parsedObject);
|
||||||
String url = null;
|
String url = null;
|
||||||
@@ -65,20 +53,32 @@ final class ImageFormatter {
|
|||||||
default -> throw new GenerationException("Unknown image attribute : " + property.name());
|
default -> throw new GenerationException("Unknown image attribute : " + property.name());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (url == null) {
|
||||||
if (progress.request().parameters().useImageInputStreamConstructor()) {
|
throw new GenerationException("Image must have a url attribute : " + parsedObject);
|
||||||
|
}
|
||||||
|
if (useImageInputStreamConstructor) {
|
||||||
formatInputStream(url, requestedWidth, requestedHeight, preserveRatio, smooth, variableName);
|
formatInputStream(url, requestedWidth, requestedHeight, preserveRatio, smooth, variableName);
|
||||||
} else {
|
} else {
|
||||||
formatURL(url, requestedWidth, requestedHeight, preserveRatio, smooth, backgroundLoading, variableName);
|
formatURL(url, requestedWidth, requestedHeight, preserveRatio, smooth, backgroundLoading, variableName);
|
||||||
}
|
}
|
||||||
helperProvider.getGenerationHelper().handleId(parsedObject, variableName);
|
}
|
||||||
|
|
||||||
|
private void formatInputStream(final String url, final double requestedWidth,
|
||||||
|
final double requestedHeight, final boolean preserveRatio, final boolean smooth, final String variableName) {
|
||||||
|
final var inputStream = helperProvider.getVariableProvider().getNextVariableName("inputStream");
|
||||||
|
sb.append(" final javafx.scene.image.Image ").append(variableName).append(";\n");
|
||||||
|
sb.append(" try (").append(helperProvider.getCompatibilityHelper().getStartVar("java.io.InputStream", 0)).append(inputStream).append(" = ").append(url).append(".openStream()) {\n");
|
||||||
|
sb.append(" ").append(variableName).append(" = new javafx.scene.image.Image(").append(inputStream);
|
||||||
|
sb.append(", ").append(requestedWidth).append(", ").append(requestedHeight).append(", ").append(preserveRatio).append(", ").append(smooth).append(");\n");
|
||||||
|
sb.append(" } catch (final java.io.IOException e) {\n");
|
||||||
|
sb.append(" throw new RuntimeException(e);\n");
|
||||||
|
sb.append(" }\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void formatURL(final String url, final double requestedWidth,
|
private void formatURL(final String url, final double requestedWidth,
|
||||||
final double requestedHeight, final boolean preserveRatio, final boolean smooth,
|
final double requestedHeight, final boolean preserveRatio, final boolean smooth,
|
||||||
final boolean backgroundLoading, final String variableName) {
|
final boolean backgroundLoading, final String variableName) {
|
||||||
final var urlString = progress.getNextVariableName("urlStr");
|
final var urlString = helperProvider.getVariableProvider().getNextVariableName("urlStr");
|
||||||
final var sb = progress.stringBuilder();
|
|
||||||
final var compatibilityHelper = helperProvider.getCompatibilityHelper();
|
final var compatibilityHelper = helperProvider.getCompatibilityHelper();
|
||||||
sb.append(compatibilityHelper.getStartVar("String")).append(urlString).append(" = ").append(url).append(".toString();\n");
|
sb.append(compatibilityHelper.getStartVar("String")).append(urlString).append(" = ").append(url).append(".toString();\n");
|
||||||
sb.append(compatibilityHelper.getStartVar("javafx.scene.image.Image")).append(variableName).append(" = new javafx.scene.image.Image(").append(urlString)
|
sb.append(compatibilityHelper.getStartVar("javafx.scene.image.Image")).append(variableName).append(" = new javafx.scene.image.Image(").append(urlString)
|
||||||
|
|||||||
@@ -1,51 +1,75 @@
|
|||||||
package com.github.gtache.fxml.compiler.impl.internal;
|
package com.github.gtache.fxml.compiler.impl.internal;
|
||||||
|
|
||||||
|
import com.github.gtache.fxml.compiler.ControllerFieldInjectionType;
|
||||||
|
import com.github.gtache.fxml.compiler.ControllerInjectionType;
|
||||||
import com.github.gtache.fxml.compiler.GenerationException;
|
import com.github.gtache.fxml.compiler.GenerationException;
|
||||||
|
import com.github.gtache.fxml.compiler.GenerationRequest;
|
||||||
|
import com.github.gtache.fxml.compiler.InjectionType;
|
||||||
import com.github.gtache.fxml.compiler.SourceInfo;
|
import com.github.gtache.fxml.compiler.SourceInfo;
|
||||||
import com.github.gtache.fxml.compiler.impl.ControllerInjectionTypes;
|
|
||||||
import com.github.gtache.fxml.compiler.impl.ResourceBundleInjectionTypes;
|
|
||||||
import com.github.gtache.fxml.compiler.parsing.ParsedInclude;
|
import com.github.gtache.fxml.compiler.parsing.ParsedInclude;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Objects;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import static java.util.Objects.requireNonNull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility class to provide the view's constructor and fields
|
* Utility class to provide the view's constructor and fields
|
||||||
*/
|
*/
|
||||||
public final class InitializationFormatter {
|
public final class InitializationFormatter {
|
||||||
|
|
||||||
private final HelperProvider helperProvider;
|
private final HelperProvider helperProvider;
|
||||||
private final GenerationProgress progress;
|
private final GenerationRequest request;
|
||||||
|
private final StringBuilder sb;
|
||||||
|
private final Map<String, String> controllerClassToVariable;
|
||||||
|
|
||||||
InitializationFormatter(final HelperProvider helperProvider, final GenerationProgress progress) {
|
InitializationFormatter(final HelperProvider helperProvider, final GenerationRequest request, final StringBuilder sb) {
|
||||||
this.helperProvider = Objects.requireNonNull(helperProvider);
|
this(helperProvider, request, sb, new HashMap<>());
|
||||||
this.progress = Objects.requireNonNull(progress);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
InitializationFormatter(final HelperProvider helperProvider, final GenerationRequest request, final StringBuilder sb, final Map<String, String> controllerClassToVariable) {
|
||||||
|
this.helperProvider = requireNonNull(helperProvider);
|
||||||
|
this.request = requireNonNull(request);
|
||||||
|
this.sb = requireNonNull(sb);
|
||||||
|
this.controllerClassToVariable = requireNonNull(controllerClassToVariable);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Formats the class initialization (fields and constructor)
|
||||||
|
*
|
||||||
|
* @throws GenerationException if an error occurs
|
||||||
|
*/
|
||||||
public void formatFieldsAndConstructor() throws GenerationException {
|
public void formatFieldsAndConstructor() throws GenerationException {
|
||||||
final var className = progress.request().outputClassName();
|
if (!controllerClassToVariable.isEmpty()) {
|
||||||
|
throw new GenerationException("Method has already been called");
|
||||||
|
}
|
||||||
|
final var className = request.outputClassName();
|
||||||
final var simpleClassName = className.substring(className.lastIndexOf('.') + 1);
|
final var simpleClassName = className.substring(className.lastIndexOf('.') + 1);
|
||||||
final var mainControllerClass = progress.request().controllerInfo().className();
|
final var mainControllerClass = request.controllerInfo().className();
|
||||||
final var isFactory = progress.request().parameters().controllerInjectionType() == ControllerInjectionTypes.FACTORY;
|
final var parameters = request.parameters();
|
||||||
|
final var controllerInjectionType = parameters.controllerInjectionType();
|
||||||
|
final var fieldInjectionType = parameters.fieldInjectionType();
|
||||||
|
final var isFactory = controllerInjectionType == ControllerInjectionType.FACTORY;
|
||||||
if (hasDuplicateControllerClass() && !isFactory) {
|
if (hasDuplicateControllerClass() && !isFactory) {
|
||||||
throw new GenerationException("Some controllers in the view tree have the same class ; Factory field injection is required");
|
throw new GenerationException("Some controllers in the view tree have the same class ; Factory controller injection is required");
|
||||||
}
|
}
|
||||||
fillControllers();
|
fillControllers();
|
||||||
final var sb = progress.stringBuilder();
|
final var sortedControllersKeys = controllerClassToVariable.keySet().stream().sorted().toList();
|
||||||
final var controllerMap = progress.controllerClassToVariable();
|
|
||||||
controllerMap.forEach((c, v) -> sb.append(" private final ").append(c).append(" ").append(v).append(isFactory ? "Factory" : "").append(";\n"));
|
|
||||||
final var controllerArg = getVariableName("controller", isFactory);
|
final var controllerArg = getVariableName("controller", isFactory);
|
||||||
final var controllerArgClass = getType(mainControllerClass, isFactory);
|
final var controllerArgClass = getType(mainControllerClass, controllerInjectionType, fieldInjectionType);
|
||||||
final var resourceBundleInfo = getResourceBundleInfo();
|
final var resourceBundleInfo = getResourceBundleInfo();
|
||||||
final var resourceBundleType = resourceBundleInfo.type();
|
final var resourceBundleType = resourceBundleInfo.type();
|
||||||
final var resourceBundleArg = resourceBundleInfo.variableName();
|
final var resourceBundleArg = resourceBundleInfo.variableName();
|
||||||
if (isFactory) {
|
if (isFactory) {
|
||||||
sb.append(" private final ").append(controllerArgClass).append(" ").append(controllerArg).append(";\n");
|
sb.append(" private final ").append(controllerArgClass).append(" ").append(controllerArg).append(";\n");
|
||||||
|
sortedControllersKeys.forEach(e -> sb.append(" private final ").append(getType(e, controllerInjectionType, fieldInjectionType)).append(" ").append(controllerClassToVariable.get(e)).append("Factory").append(";\n"));
|
||||||
sb.append(" private ").append(mainControllerClass).append(" controller;\n");
|
sb.append(" private ").append(mainControllerClass).append(" controller;\n");
|
||||||
} else {
|
} else {
|
||||||
sb.append(" private final ").append(mainControllerClass).append(" controller;\n");
|
sb.append(" private final ").append(mainControllerClass).append(" controller;\n");
|
||||||
|
sortedControllersKeys.forEach(e -> sb.append(" private final ").append(getType(e, controllerInjectionType, fieldInjectionType)).append(" ").append(controllerClassToVariable.get(e)).append(";\n"));
|
||||||
}
|
}
|
||||||
if (resourceBundleType != null) {
|
if (resourceBundleType != null) {
|
||||||
sb.append(" private final ").append(resourceBundleType).append(" ").append(resourceBundleArg).append(";\n");
|
sb.append(" private final ").append(resourceBundleType).append(" ").append(resourceBundleArg).append(";\n");
|
||||||
@@ -55,49 +79,49 @@ public final class InitializationFormatter {
|
|||||||
sb.append(" /**\n");
|
sb.append(" /**\n");
|
||||||
sb.append(" * Instantiates a new ").append(simpleClassName).append("\n");
|
sb.append(" * Instantiates a new ").append(simpleClassName).append("\n");
|
||||||
sb.append(" * @param ").append(controllerArg).append(" The controller ").append(isFactory ? "factory" : "instance").append("\n");
|
sb.append(" * @param ").append(controllerArg).append(" The controller ").append(isFactory ? "factory" : "instance").append("\n");
|
||||||
controllerMap.forEach((c, s) -> sb.append(" * @param ").append(getVariableName(s, isFactory))
|
sortedControllersKeys.forEach(e -> sb.append(" * @param ").append(getVariableName(controllerClassToVariable.get(e), isFactory))
|
||||||
.append(" The subcontroller ").append(isFactory ? "factory" : "instance").append(" for ").append(c).append("\n"));
|
.append(" The subcontroller ").append(isFactory ? "factory" : "instance").append(" for ").append(e).append("\n"));
|
||||||
|
|
||||||
if (resourceBundleType != null) {
|
if (resourceBundleType != null) {
|
||||||
sb.append(" * @param ").append(resourceBundleArg).append(" The resource bundle\n");
|
sb.append(" * @param ").append(resourceBundleArg).append(" The resource bundle\n");
|
||||||
}
|
}
|
||||||
sb.append(" */\n");
|
sb.append(" */\n");
|
||||||
final var arguments = "final " + controllerArgClass + " " + controllerArg +
|
final var arguments = "final " + controllerArgClass + " " + controllerArg +
|
||||||
((controllerMap.isEmpty()) ? "" : ", ") +
|
((sortedControllersKeys.isEmpty()) ? "" : ", ") +
|
||||||
controllerMap.entrySet().stream().map(e -> "final " + getType(e.getKey(), isFactory) + " " + getVariableName(e.getValue(), isFactory))
|
sortedControllersKeys.stream().map(e -> "final " + getType(e, controllerInjectionType, fieldInjectionType) + " " + getVariableName(controllerClassToVariable.get(e), isFactory))
|
||||||
.sorted().collect(Collectors.joining(", "))
|
.sorted().collect(Collectors.joining(", "))
|
||||||
+ (resourceBundleType == null ? "" : ", final " + resourceBundleType + " " + resourceBundleArg);
|
+ (resourceBundleType == null ? "" : ", final " + resourceBundleType + " " + resourceBundleArg);
|
||||||
sb.append(" public ").append(simpleClassName).append("(").append(arguments).append(") {\n");
|
sb.append(" public ").append(simpleClassName).append("(").append(arguments).append(") {\n");
|
||||||
sb.append(" this.").append(controllerArg).append(" = java.util.Objects.requireNonNull(").append(controllerArg).append(");\n");
|
sb.append(" this.").append(controllerArg).append(" = java.util.Objects.requireNonNull(").append(controllerArg).append(");\n");
|
||||||
controllerMap.values().forEach(s -> sb.append(" this.").append(getVariableName(s, isFactory)).append(" = java.util.Objects.requireNonNull(").append(getVariableName(s, isFactory)).append(");\n"));
|
sortedControllersKeys.forEach(s -> {
|
||||||
|
final var variableName = getVariableName(controllerClassToVariable.get(s), isFactory);
|
||||||
|
sb.append(" this.").append(variableName).append(" = java.util.Objects.requireNonNull(").append(variableName).append(");\n");
|
||||||
|
});
|
||||||
if (resourceBundleType != null) {
|
if (resourceBundleType != null) {
|
||||||
sb.append(" this.").append(resourceBundleArg).append(" = java.util.Objects.requireNonNull(").append(resourceBundleArg).append(");\n");
|
sb.append(" this.").append(resourceBundleArg).append(" = java.util.Objects.requireNonNull(").append(resourceBundleArg).append(");\n");
|
||||||
}
|
}
|
||||||
sb.append(" }\n");
|
sb.append(" }\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
private ResourceBundleInfo getResourceBundleInfo() throws GenerationException {
|
private ResourceBundleInfo getResourceBundleInfo() {
|
||||||
final var injectionType = progress.request().parameters().resourceInjectionType();
|
final var injectionType = request.parameters().resourceInjectionType();
|
||||||
if (injectionType instanceof final ResourceBundleInjectionTypes types) {
|
return switch (injectionType) {
|
||||||
return switch (types) {
|
case CONSTRUCTOR -> new ResourceBundleInfo("java.util.ResourceBundle", "resourceBundle");
|
||||||
case CONSTRUCTOR -> new ResourceBundleInfo("java.util.ResourceBundle", "resourceBundle");
|
case CONSTRUCTOR_FUNCTION ->
|
||||||
case CONSTRUCTOR_FUNCTION ->
|
new ResourceBundleInfo("java.util.function.Function<String, String>", "resourceBundleFunction");
|
||||||
new ResourceBundleInfo("java.util.function.Function<String, String>", "resourceBundleFunction");
|
case CONSTRUCTOR_NAME -> new ResourceBundleInfo("String", "resourceBundleName");
|
||||||
case CONSTRUCTOR_NAME -> new ResourceBundleInfo("String", "resourceBundleName");
|
case GETTER, GET_BUNDLE -> new ResourceBundleInfo(null, null);
|
||||||
case GETTER -> new ResourceBundleInfo(null, null);
|
};
|
||||||
case GET_BUNDLE -> new ResourceBundleInfo(null, null);
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
throw new GenerationException("Unknown resource injection type : " + injectionType);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private record ResourceBundleInfo(String type, String variableName) {
|
private record ResourceBundleInfo(String type, String variableName) {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String getType(final String controllerClass, final boolean isFactory) {
|
private static String getType(final String controllerClass, final InjectionType controllerInjectionTypes, final InjectionType fieldInjectionTypes) {
|
||||||
if (isFactory) {
|
if (fieldInjectionTypes == ControllerFieldInjectionType.FACTORY) {
|
||||||
return "java.util.function.Function<java.util.Map<String, Object>, " + controllerClass + ">";
|
return "java.util.function.Function<java.util.Map<String, Object>, " + controllerClass + ">";
|
||||||
|
} else if (controllerInjectionTypes == ControllerInjectionType.FACTORY) {
|
||||||
|
return "java.util.function.Supplier<" + controllerClass + ">";
|
||||||
} else {
|
} else {
|
||||||
return controllerClass;
|
return controllerClass;
|
||||||
}
|
}
|
||||||
@@ -105,19 +129,15 @@ public final class InitializationFormatter {
|
|||||||
|
|
||||||
private static String getVariableName(final String variableName, final boolean isFactory) {
|
private static String getVariableName(final String variableName, final boolean isFactory) {
|
||||||
if (isFactory) {
|
if (isFactory) {
|
||||||
return getVariableName(variableName, "Factory");
|
return variableName + "Factory";
|
||||||
} else {
|
} else {
|
||||||
return variableName;
|
return variableName;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String getVariableName(final String variableName, final String suffix) {
|
|
||||||
return variableName + suffix;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean hasDuplicateControllerClass() {
|
private boolean hasDuplicateControllerClass() {
|
||||||
final var set = new HashSet<String>();
|
final var set = new HashSet<String>();
|
||||||
return hasDuplicateControllerClass(progress.request().sourceInfo(), set);
|
return hasDuplicateControllerClass(request.sourceInfo(), set);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean hasDuplicateControllerClass(final SourceInfo info, final Set<String> controllers) {
|
private static boolean hasDuplicateControllerClass(final SourceInfo info, final Set<String> controllers) {
|
||||||
@@ -125,15 +145,17 @@ public final class InitializationFormatter {
|
|||||||
if (controllers.contains(controllerClass)) {
|
if (controllers.contains(controllerClass)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
controllers.add(controllerClass);
|
||||||
return info.includedSources().stream().anyMatch(s -> hasDuplicateControllerClass(s, controllers));
|
return info.includedSources().stream().anyMatch(s -> hasDuplicateControllerClass(s, controllers));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void fillControllers() {
|
private void fillControllers() {
|
||||||
progress.request().sourceInfo().includedSources().forEach(this::fillControllers);
|
request.sourceInfo().includedSources().forEach(this::fillControllers);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void fillControllers(final SourceInfo info) {
|
private void fillControllers(final SourceInfo info) {
|
||||||
progress.controllerClassToVariable().put(info.controllerClassName(), progress.getNextVariableName(GenerationHelper.getVariablePrefix(info.controllerClassName())));
|
controllerClassToVariable.put(info.controllerClassName(), helperProvider.getVariableProvider()
|
||||||
|
.getNextVariableName(GenerationHelper.getVariablePrefix(info.controllerClassName())));
|
||||||
info.includedSources().forEach(this::fillControllers);
|
info.includedSources().forEach(this::fillControllers);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -143,58 +165,55 @@ public final class InitializationFormatter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String formatSubViewConstructorCall(final ParsedInclude include) throws GenerationException {
|
String formatSubViewConstructorCall(final ParsedInclude include) throws GenerationException {
|
||||||
final var request = progress.request();
|
|
||||||
final var info = request.sourceInfo();
|
final var info = request.sourceInfo();
|
||||||
final var subInfo = info.sourceToSourceInfo().get(include.source());
|
final var subInfo = info.sourceToSourceInfo().get(include.source());
|
||||||
if (subInfo == null) {
|
if (subInfo == null) {
|
||||||
throw new GenerationException("Unknown include source : " + include.source());
|
throw new GenerationException("Unknown include source : " + include.source());
|
||||||
} else {
|
} else {
|
||||||
final var isFactory = request.parameters().controllerInjectionType() == ControllerInjectionTypes.FACTORY;
|
final var isFactory = request.parameters().controllerInjectionType() == ControllerInjectionType.FACTORY;
|
||||||
final var subClassName = subInfo.controllerClassName();
|
final var subClassName = subInfo.controllerClassName();
|
||||||
final var subControllerVariable = getVariableName(progress.controllerClassToVariable().get(subClassName), isFactory);
|
final var subControllerVariable = getVariableName(controllerClassToVariable.get(subClassName), isFactory);
|
||||||
final var subControllers = new HashSet<String>();
|
final var subControllers = new HashSet<String>();
|
||||||
subInfo.includedSources().forEach(s -> fillControllers(s, subControllers));
|
subInfo.includedSources().forEach(s -> fillControllers(s, subControllers));
|
||||||
final var arguments = subControllers.stream().sorted().map(c -> getVariableName(progress.controllerClassToVariable().get(c), isFactory)).collect(Collectors.joining(", "));
|
final var arguments = subControllers.stream().sorted().map(c -> getVariableName(controllerClassToVariable.get(c), isFactory)).collect(Collectors.joining(", "));
|
||||||
final var bundleVariable = subInfo.requiresResourceBundle() ? getBundleVariable(include) : null;
|
final var bundleVariable = subInfo.requiresResourceBundle() ? getBundleVariable(include) : null;
|
||||||
final var argumentList = subControllerVariable + (arguments.isEmpty() ? "" : ", " + arguments) + (bundleVariable == null ? "" : ", " + bundleVariable);
|
final var argumentList = subControllerVariable + (arguments.isEmpty() ? "" : ", " + arguments) + (bundleVariable == null ? "" : ", " + bundleVariable);
|
||||||
final var subViewName = subInfo.generatedClassName();
|
final var subViewName = subInfo.generatedClassName();
|
||||||
final var variable = progress.getNextVariableName(GenerationHelper.getVariablePrefix(subViewName));
|
final var variable = helperProvider.getVariableProvider().getNextVariableName(GenerationHelper.getVariablePrefix(subViewName));
|
||||||
progress.stringBuilder().append(helperProvider.getCompatibilityHelper().getStartVar(subViewName)).append(variable).append(" = new ").append(subViewName).append("(").append(argumentList).append(");\n");
|
sb.append(helperProvider.getCompatibilityHelper().getStartVar(subViewName)).append(variable).append(" = new ").append(subViewName).append("(").append(argumentList).append(");\n");
|
||||||
return variable;
|
return variable;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getBundleVariable(final ParsedInclude include) throws GenerationException {
|
private String getBundleVariable(final ParsedInclude include) {
|
||||||
final var info = getResourceBundleInfo();
|
final var info = getResourceBundleInfo();
|
||||||
if (info.type() == null) {
|
if (info.type() == null) {
|
||||||
return null;
|
return null;
|
||||||
} else if (include.resources() == null) {
|
} else if (include.resources() == null) {
|
||||||
return info.variableName();
|
return info.variableName();
|
||||||
} else {
|
} else {
|
||||||
final var sb = progress.stringBuilder();
|
final var compatibilityHelper = helperProvider.getCompatibilityHelper();
|
||||||
if (progress.request().parameters().resourceInjectionType() instanceof final ResourceBundleInjectionTypes types) {
|
final var variableProvider = helperProvider.getVariableProvider();
|
||||||
final var compatibilityHelper = helperProvider.getCompatibilityHelper();
|
return switch (request.parameters().resourceInjectionType()) {
|
||||||
return switch (types) {
|
case GETTER, GET_BUNDLE -> null;
|
||||||
case GETTER, GET_BUNDLE -> null;
|
case CONSTRUCTOR_NAME -> {
|
||||||
case CONSTRUCTOR_NAME -> {
|
final var bundleVariable = variableProvider.getNextVariableName("resourceBundleName");
|
||||||
final var bundleVariable = progress.getNextVariableName("resourceBundleName");
|
sb.append(compatibilityHelper.getStartVar("String")).append(bundleVariable).append(" = \"").append(include.resources()).append("\";\n");
|
||||||
sb.append(compatibilityHelper.getStartVar("String")).append(bundleVariable).append(" = \"").append(include.resources()).append("\";\n");
|
yield bundleVariable;
|
||||||
yield bundleVariable;
|
}
|
||||||
}
|
case CONSTRUCTOR_FUNCTION -> {
|
||||||
case CONSTRUCTOR_FUNCTION -> {
|
final var bundleVariable = variableProvider.getNextVariableName("resourceBundle");
|
||||||
final var bundleVariable = progress.getNextVariableName("resourceBundleFunction");
|
sb.append(compatibilityHelper.getStartVar("java.util.ResourceBundle")).append(bundleVariable).append(" = java.util.ResourceBundle.getBundle(\"").append(include.resources()).append("\");\n");
|
||||||
sb.append(compatibilityHelper.getStartVar("java.util.function.Function<String, String>")).append(bundleVariable).append(" = (java.util.function.Function<String, String>) s -> \"").append(include.resources()).append("\";\n");
|
final var bundleFunctionVariable = variableProvider.getNextVariableName("resourceBundleFunction");
|
||||||
yield bundleVariable;
|
sb.append(compatibilityHelper.getStartVar("java.util.function.Function<String, String>")).append(bundleFunctionVariable).append(" = (java.util.function.Function<String, String>) s -> ").append(bundleVariable).append(".getString(s);\n");
|
||||||
}
|
yield bundleFunctionVariable;
|
||||||
case CONSTRUCTOR -> {
|
}
|
||||||
final var bundleVariable = progress.getNextVariableName("resourceBundle");
|
case CONSTRUCTOR -> {
|
||||||
sb.append(compatibilityHelper.getStartVar("java.util.ResourceBundle")).append(bundleVariable).append(" = java.util.ResourceBundle.getBundle(\"").append(include.resources()).append("\");\n");
|
final var bundleVariable = variableProvider.getNextVariableName("resourceBundle");
|
||||||
yield bundleVariable;
|
sb.append(compatibilityHelper.getStartVar("java.util.ResourceBundle")).append(bundleVariable).append(" = java.util.ResourceBundle.getBundle(\"").append(include.resources()).append("\");\n");
|
||||||
}
|
yield bundleVariable;
|
||||||
};
|
}
|
||||||
} else {
|
};
|
||||||
throw new GenerationException("Unknown resource injection type : " + progress.request().parameters().resourceInjectionType());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
package com.github.gtache.fxml.compiler.impl.internal;
|
package com.github.gtache.fxml.compiler.impl.internal;
|
||||||
|
|
||||||
|
import com.github.gtache.fxml.compiler.ControllerFieldInjectionType;
|
||||||
|
import com.github.gtache.fxml.compiler.ControllerInjectionType;
|
||||||
|
import com.github.gtache.fxml.compiler.ControllerMethodsInjectionType;
|
||||||
import com.github.gtache.fxml.compiler.GenerationException;
|
import com.github.gtache.fxml.compiler.GenerationException;
|
||||||
import com.github.gtache.fxml.compiler.impl.ControllerFieldInjectionTypes;
|
import com.github.gtache.fxml.compiler.ResourceBundleInjectionType;
|
||||||
import com.github.gtache.fxml.compiler.impl.ControllerMethodsInjectionType;
|
|
||||||
import com.github.gtache.fxml.compiler.impl.ResourceBundleInjectionTypes;
|
|
||||||
|
|
||||||
import static java.util.Objects.requireNonNull;
|
import static java.util.Objects.requireNonNull;
|
||||||
|
|
||||||
@@ -29,7 +30,8 @@ public final class LoadMethodFormatter {
|
|||||||
final var request = progress.request();
|
final var request = progress.request();
|
||||||
final var rootObject = request.rootObject();
|
final var rootObject = request.rootObject();
|
||||||
final var parameters = progress.request().parameters();
|
final var parameters = progress.request().parameters();
|
||||||
final var controllerInjectionType = parameters.fieldInjectionType();
|
final var controllerInjectionType = parameters.controllerInjectionType();
|
||||||
|
final var fieldInjectionType = parameters.fieldInjectionType();
|
||||||
final var controllerClass = progress.request().controllerInfo().className();
|
final var controllerClass = progress.request().controllerInfo().className();
|
||||||
final var sb = progress.stringBuilder();
|
final var sb = progress.stringBuilder();
|
||||||
sb.append(" /**\n");
|
sb.append(" /**\n");
|
||||||
@@ -43,35 +45,38 @@ public final class LoadMethodFormatter {
|
|||||||
sb.append(" }\n");
|
sb.append(" }\n");
|
||||||
final var resourceBundleInjection = parameters.resourceInjectionType();
|
final var resourceBundleInjection = parameters.resourceInjectionType();
|
||||||
final var generationCompatibilityHelper = helperProvider.getCompatibilityHelper();
|
final var generationCompatibilityHelper = helperProvider.getCompatibilityHelper();
|
||||||
if (resourceBundleInjection == ResourceBundleInjectionTypes.CONSTRUCTOR_NAME) {
|
if (resourceBundleInjection == ResourceBundleInjectionType.CONSTRUCTOR_NAME) {
|
||||||
sb.append(generationCompatibilityHelper.getStartVar("java.util.ResourceBundle")).append("resourceBundle = java.util.ResourceBundle.getBundle(\"resourceBundleName\");\n");
|
sb.append(generationCompatibilityHelper.getStartVar("java.util.ResourceBundle")).append("resourceBundle = java.util.ResourceBundle.getBundle(resourceBundleName);\n");
|
||||||
} else if (resourceBundleInjection == ResourceBundleInjectionTypes.GET_BUNDLE && parameters.bundleMap().containsKey(controllerClass)) {
|
} else if (resourceBundleInjection == ResourceBundleInjectionType.GET_BUNDLE && parameters.bundleMap().containsKey(controllerClass)) {
|
||||||
sb.append(generationCompatibilityHelper.getStartVar("java.util.ResourceBundle")).append("resourceBundle = java.util.ResourceBundle.getBundle(\"").append(parameters.bundleMap().get(controllerClass)).append("\");\n");
|
sb.append(generationCompatibilityHelper.getStartVar("java.util.ResourceBundle")).append("resourceBundle = java.util.ResourceBundle.getBundle(\"")
|
||||||
|
.append(parameters.bundleMap().get(controllerClass)).append("\");\n");
|
||||||
}
|
}
|
||||||
if (controllerInjectionType == ControllerFieldInjectionTypes.FACTORY) {
|
if (fieldInjectionType == ControllerFieldInjectionType.FACTORY) {
|
||||||
sb.append(generationCompatibilityHelper.getStartVar("java.util.Map<String, Object>")).append("fieldMap = new java.util.HashMap<String, Object>();\n");
|
sb.append(generationCompatibilityHelper.getStartVar("java.util.Map<String, Object>")).append("fieldMap = new java.util.HashMap<String, Object>();\n");
|
||||||
|
} else if (controllerInjectionType == ControllerInjectionType.FACTORY) {
|
||||||
|
sb.append(" controller = controllerFactory.create();\n");
|
||||||
}
|
}
|
||||||
final var variableName = progress.getNextVariableName(GenerationHelper.getVariablePrefix(rootObject));
|
final var variableName = helperProvider.getVariableProvider().getNextVariableName(GenerationHelper.getVariablePrefix(rootObject));
|
||||||
helperProvider.getObjectFormatter().format(rootObject, variableName);
|
helperProvider.getObjectFormatter().format(rootObject, variableName);
|
||||||
if (controllerInjectionType == ControllerFieldInjectionTypes.FACTORY) {
|
if (fieldInjectionType == ControllerFieldInjectionType.FACTORY) {
|
||||||
sb.append(" controller = (").append(controllerClass).append(") controllerFactory.create(fieldMap);\n");
|
sb.append(" controller = controllerFactory.create(fieldMap);\n");
|
||||||
progress.controllerFactoryPostAction().forEach(sb::append);
|
progress.controllerFactoryPostAction().forEach(sb::append);
|
||||||
}
|
}
|
||||||
if (parameters.methodInjectionType() == ControllerMethodsInjectionType.REFLECTION) {
|
if (request.controllerInfo().hasInitialize()) {
|
||||||
sb.append(" try {\n");
|
if (parameters.methodInjectionType() == ControllerMethodsInjectionType.REFLECTION) {
|
||||||
sb.append(" ").append(generationCompatibilityHelper.getStartVar("java.lang.reflect.Method", 0)).append("initialize = controller.getClass().getDeclaredMethod(\"initialize\");\n");
|
sb.append(" try {\n");
|
||||||
sb.append(" initialize.setAccessible(true);\n");
|
sb.append(" ").append(generationCompatibilityHelper.getStartVar("java.lang.reflect.Method", 0)).append("initialize = controller.getClass().getDeclaredMethod(\"initialize\");\n");
|
||||||
sb.append(" initialize.invoke(controller);\n");
|
sb.append(" initialize.setAccessible(true);\n");
|
||||||
sb.append(" } catch (final java.lang.reflect.InvocationTargetException | IllegalAccessException e) {\n");
|
sb.append(" initialize.invoke(controller);\n");
|
||||||
sb.append(" throw new RuntimeException(\"Error using reflection\", e);\n");
|
sb.append(" } catch (final java.lang.reflect.InvocationTargetException | IllegalAccessException | NoSuchMethodException e) {\n");
|
||||||
sb.append(" } catch (final NoSuchMethodException ignored) {\n");
|
sb.append(" throw new RuntimeException(\"Error using reflection\", e);\n");
|
||||||
sb.append(" }\n");
|
sb.append(" }\n");
|
||||||
} else {
|
} else {
|
||||||
sb.append(" controller.initialize();\n");
|
sb.append(" controller.initialize();\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
sb.append(" loaded = true;\n");
|
sb.append(" loaded = true;\n");
|
||||||
sb.append(" return (T) ").append(variableName).append(";\n");
|
sb.append(" return (T) ").append(variableName).append(";\n");
|
||||||
sb.append(" }\n");
|
sb.append(" }\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.github.gtache.fxml.compiler.impl.internal;
|
package com.github.gtache.fxml.compiler.impl.internal;
|
||||||
|
|
||||||
import com.github.gtache.fxml.compiler.GenerationException;
|
import com.github.gtache.fxml.compiler.GenerationException;
|
||||||
|
import com.github.gtache.fxml.compiler.GenerationRequest;
|
||||||
import com.github.gtache.fxml.compiler.impl.GeneratorImpl;
|
import com.github.gtache.fxml.compiler.impl.GeneratorImpl;
|
||||||
import com.github.gtache.fxml.compiler.parsing.*;
|
import com.github.gtache.fxml.compiler.parsing.*;
|
||||||
import com.github.gtache.fxml.compiler.parsing.impl.ParsedPropertyImpl;
|
import com.github.gtache.fxml.compiler.parsing.impl.ParsedPropertyImpl;
|
||||||
@@ -21,7 +22,7 @@ import static java.util.Objects.requireNonNull;
|
|||||||
/**
|
/**
|
||||||
* Helper methods for {@link GeneratorImpl} to format properties
|
* Helper methods for {@link GeneratorImpl} to format properties
|
||||||
*/
|
*/
|
||||||
public final class ObjectFormatter {
|
final class ObjectFormatter {
|
||||||
|
|
||||||
private static final Logger logger = LogManager.getLogger(ObjectFormatter.class);
|
private static final Logger logger = LogManager.getLogger(ObjectFormatter.class);
|
||||||
|
|
||||||
@@ -47,11 +48,13 @@ public final class ObjectFormatter {
|
|||||||
);
|
);
|
||||||
|
|
||||||
private final HelperProvider helperProvider;
|
private final HelperProvider helperProvider;
|
||||||
private final GenerationProgress progress;
|
private final GenerationRequest request;
|
||||||
|
private final StringBuilder sb;
|
||||||
|
|
||||||
ObjectFormatter(final HelperProvider helperProvider, final GenerationProgress progress) {
|
ObjectFormatter(final HelperProvider helperProvider, final GenerationRequest request, final StringBuilder sb) {
|
||||||
this.helperProvider = requireNonNull(helperProvider);
|
this.helperProvider = requireNonNull(helperProvider);
|
||||||
this.progress = requireNonNull(progress);
|
this.request = requireNonNull(request);
|
||||||
|
this.sb = requireNonNull(sb);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -73,6 +76,70 @@ public final class ObjectFormatter {
|
|||||||
case final ParsedText text -> formatText(text, variableName);
|
case final ParsedText text -> formatText(text, variableName);
|
||||||
default -> formatObject(parsedObject, variableName);
|
default -> formatObject(parsedObject, variableName);
|
||||||
}
|
}
|
||||||
|
handleId(parsedObject, variableName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles the fx:id attribute of an object
|
||||||
|
*
|
||||||
|
* @param parsedObject The parsed object
|
||||||
|
* @param variableName The variable name
|
||||||
|
* @throws GenerationException if an error occurs
|
||||||
|
*/
|
||||||
|
private void handleId(final ParsedObject parsedObject, final String variableName) throws GenerationException {
|
||||||
|
final var id = parsedObject.attributes().get(FX_ID);
|
||||||
|
if (id == null) {
|
||||||
|
handleIdProperty(parsedObject, variableName);
|
||||||
|
} else {
|
||||||
|
final var idValue = id.value();
|
||||||
|
handleId(parsedObject, variableName, idValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleIdProperty(final ParsedObject parsedObject, final String variableName) throws GenerationException {
|
||||||
|
final var property = parsedObject.properties().entrySet().stream().filter(
|
||||||
|
e -> e.getKey().name().equals(FX_ID) && e.getKey().sourceType() == null).findFirst().orElse(null);
|
||||||
|
if (property != null) {
|
||||||
|
final var values = property.getValue();
|
||||||
|
formatDefines(values);
|
||||||
|
final var notDefinedChildren = getNotDefines(values);
|
||||||
|
if (notDefinedChildren.size() == 1) {
|
||||||
|
final var object = notDefinedChildren.getFirst();
|
||||||
|
if (object instanceof final ParsedText text) {
|
||||||
|
final var idValue = text.text();
|
||||||
|
handleId(parsedObject, variableName, idValue);
|
||||||
|
} else {
|
||||||
|
throw new GenerationException("Malformed fx:id property : " + parsedObject);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new GenerationException("Malformed fx:id property : " + parsedObject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static SequencedCollection<ParsedDefine> getDefines(final SequencedCollection<ParsedObject> objects) {
|
||||||
|
return objects.stream().filter(ParsedDefine.class::isInstance).map(ParsedDefine.class::cast).toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static SequencedCollection<ParsedObject> getNotDefines(final SequencedCollection<ParsedObject> objects) {
|
||||||
|
return objects.stream().filter(c -> !(c instanceof ParsedDefine)).toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleId(final ParsedObject parsedObject, final String variableName, final String value) throws GenerationException {
|
||||||
|
final String className;
|
||||||
|
if (request.controllerInfo().fieldInfo(value) == null) {
|
||||||
|
className = parsedObject.className();
|
||||||
|
logger.debug("Not injecting {} because it is not found in controller", value);
|
||||||
|
} else {
|
||||||
|
final var reflectionHelper = helperProvider.getReflectionHelper();
|
||||||
|
if (ReflectionHelper.isGeneric(ReflectionHelper.getClass(parsedObject.className()))) {
|
||||||
|
className = parsedObject.className() + reflectionHelper.getGenericTypes(parsedObject);
|
||||||
|
} else {
|
||||||
|
className = parsedObject.className();
|
||||||
|
}
|
||||||
|
helperProvider.getControllerInjector().injectControllerField(value, variableName);
|
||||||
|
}
|
||||||
|
helperProvider.getVariableProvider().addVariableInfo(value, new VariableInfo(value, parsedObject, variableName, className));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -82,7 +149,8 @@ public final class ObjectFormatter {
|
|||||||
* @param variableName The variable name
|
* @param variableName The variable name
|
||||||
*/
|
*/
|
||||||
private void formatText(final ParsedText text, final String variableName) {
|
private void formatText(final ParsedText text, final String variableName) {
|
||||||
progress.stringBuilder().append(helperProvider.getCompatibilityHelper().getStartVar("String")).append(variableName).append(" = \"").append(text.text()).append("\";\n");
|
sb.append(helperProvider.getCompatibilityHelper().getStartVar("String"))
|
||||||
|
.append(variableName).append(" = \"").append(text.text()).append("\";\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -112,9 +180,9 @@ public final class ObjectFormatter {
|
|||||||
case "javafx.scene.text.Font" -> helperProvider.getFontFormatter().formatFont(parsedObject, variableName);
|
case "javafx.scene.text.Font" -> helperProvider.getFontFormatter().formatFont(parsedObject, variableName);
|
||||||
case "javafx.scene.image.Image" ->
|
case "javafx.scene.image.Image" ->
|
||||||
helperProvider.getImageFormatter().formatImage(parsedObject, variableName);
|
helperProvider.getImageFormatter().formatImage(parsedObject, variableName);
|
||||||
case "java.net.URL" -> helperProvider.getURLFormatter().formatURL(parsedObject, variableName);
|
|
||||||
case "javafx.scene.shape.TriangleMesh" ->
|
case "javafx.scene.shape.TriangleMesh" ->
|
||||||
helperProvider.getTriangleMeshFormatter().formatTriangleMesh(parsedObject, variableName);
|
helperProvider.getTriangleMeshFormatter().formatTriangleMesh(parsedObject, variableName);
|
||||||
|
case "java.net.URL" -> helperProvider.getURLFormatter().formatURL(parsedObject, variableName);
|
||||||
case "javafx.scene.web.WebView" ->
|
case "javafx.scene.web.WebView" ->
|
||||||
helperProvider.getWebViewFormatter().formatWebView(parsedObject, variableName);
|
helperProvider.getWebViewFormatter().formatWebView(parsedObject, variableName);
|
||||||
default -> throw new IllegalArgumentException("Unknown builder class : " + className);
|
default -> throw new IllegalArgumentException("Unknown builder class : " + className);
|
||||||
@@ -137,17 +205,13 @@ public final class ObjectFormatter {
|
|||||||
throw new GenerationException("Invalid attributes for simple class : " + parsedObject);
|
throw new GenerationException("Invalid attributes for simple class : " + parsedObject);
|
||||||
}
|
}
|
||||||
final var value = getSimpleValue(parsedObject);
|
final var value = getSimpleValue(parsedObject);
|
||||||
final var valueStr = helperProvider.getValueFormatter().toString(value, ReflectionHelper.getClass(parsedObject.className()));
|
final var valueStr = ValueFormatter.toString(value, ReflectionHelper.getClass(parsedObject.className()));
|
||||||
progress.stringBuilder().append(helperProvider.getCompatibilityHelper().getStartVar(parsedObject)).append(variableName).append(" = ").append(valueStr).append(";\n");
|
sb.append(helperProvider.getCompatibilityHelper().getStartVar(parsedObject)).append(variableName).append(" = ").append(valueStr).append(";\n");
|
||||||
helperProvider.getGenerationHelper().handleId(parsedObject, variableName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getSimpleValue(final ParsedObject parsedObject) throws GenerationException {
|
private String getSimpleValue(final ParsedObject parsedObject) throws GenerationException {
|
||||||
final var definedChildren = parsedObject.children().stream().filter(ParsedDefine.class::isInstance).toList();
|
formatDefines(parsedObject.children());
|
||||||
for (final var definedChild : definedChildren) {
|
final var notDefinedChildren = getNotDefines(parsedObject.children());
|
||||||
formatObject(definedChild, progress.getNextVariableName("define"));
|
|
||||||
}
|
|
||||||
final var notDefinedChildren = parsedObject.children().stream().filter(c -> !(c instanceof ParsedDefine)).toList();
|
|
||||||
if (parsedObject.attributes().containsKey(FX_VALUE)) {
|
if (parsedObject.attributes().containsKey(FX_VALUE)) {
|
||||||
return getSimpleFXValue(parsedObject, notDefinedChildren);
|
return getSimpleFXValue(parsedObject, notDefinedChildren);
|
||||||
} else if (parsedObject.attributes().containsKey(VALUE)) {
|
} else if (parsedObject.attributes().containsKey(VALUE)) {
|
||||||
@@ -157,6 +221,13 @@ public final class ObjectFormatter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void formatDefines(final SequencedCollection<ParsedObject> values) throws GenerationException {
|
||||||
|
final var defines = getDefines(values);
|
||||||
|
for (final var definedChild : defines) {
|
||||||
|
format(definedChild, helperProvider.getVariableProvider().getNextVariableName("define"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static String getSimpleFXValue(final ParsedObject parsedObject, final Collection<ParsedObject> notDefinedChildren) throws GenerationException {
|
private static String getSimpleFXValue(final ParsedObject parsedObject, final Collection<ParsedObject> notDefinedChildren) throws GenerationException {
|
||||||
if (notDefinedChildren.isEmpty() && !parsedObject.attributes().containsKey(VALUE)) {
|
if (notDefinedChildren.isEmpty() && !parsedObject.attributes().containsKey(VALUE)) {
|
||||||
return parsedObject.attributes().get(FX_VALUE).value();
|
return parsedObject.attributes().get(FX_VALUE).value();
|
||||||
@@ -186,7 +257,7 @@ public final class ObjectFormatter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isSimpleClass(final ParsedObject object) throws GenerationException {
|
private static boolean isSimpleClass(final ParsedObject object) throws GenerationException {
|
||||||
final var className = object.className();
|
final var className = object.className();
|
||||||
if (SIMPLE_CLASSES.contains(className)) {
|
if (SIMPLE_CLASSES.contains(className)) {
|
||||||
return true;
|
return true;
|
||||||
@@ -199,35 +270,31 @@ public final class ObjectFormatter {
|
|||||||
private void formatComplexClass(final ParsedObject parsedObject, final String variableName) throws GenerationException {
|
private void formatComplexClass(final ParsedObject parsedObject, final String variableName) throws GenerationException {
|
||||||
final var clazz = ReflectionHelper.getClass(parsedObject.className());
|
final var clazz = ReflectionHelper.getClass(parsedObject.className());
|
||||||
final var children = parsedObject.children();
|
final var children = parsedObject.children();
|
||||||
final var definedChildren = children.stream().filter(ParsedDefine.class::isInstance).toList();
|
final var notDefinedChildren = getNotDefines(children);
|
||||||
final var notDefinedChildren = children.stream().filter(c -> !(c instanceof ParsedDefine)).toList();
|
|
||||||
final var constructors = clazz.getConstructors();
|
final var constructors = clazz.getConstructors();
|
||||||
final var allPropertyNames = new HashSet<>(parsedObject.attributes().keySet());
|
final var allAttributesNames = new HashSet<>(parsedObject.attributes().keySet());
|
||||||
allPropertyNames.addAll(parsedObject.properties().keySet().stream().map(ParsedProperty::name).collect(Collectors.toSet()));
|
allAttributesNames.addAll(parsedObject.properties().keySet().stream().map(ParsedProperty::name).collect(Collectors.toSet()));
|
||||||
if (!definedChildren.isEmpty()) {
|
formatDefines(children);
|
||||||
for (final var definedChild : definedChildren) {
|
|
||||||
format(definedChild, progress.getNextVariableName("define"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!notDefinedChildren.isEmpty()) {
|
if (!notDefinedChildren.isEmpty()) {
|
||||||
final var defaultProperty = ReflectionHelper.getDefaultProperty(parsedObject.className());
|
final var defaultProperty = ReflectionHelper.getDefaultProperty(parsedObject.className());
|
||||||
if (defaultProperty != null) {
|
if (defaultProperty != null) {
|
||||||
allPropertyNames.add(defaultProperty);
|
allAttributesNames.add(defaultProperty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
final var constructorArgs = ConstructorHelper.getMatchingConstructorArgs(constructors, allPropertyNames);
|
final var constructorArgs = ConstructorHelper.getMatchingConstructorArgs(constructors, allAttributesNames);
|
||||||
if (constructorArgs == null) {
|
if (constructorArgs == null) {
|
||||||
formatNoConstructor(parsedObject, variableName, allPropertyNames);
|
formatNoConstructor(parsedObject, variableName, allAttributesNames);
|
||||||
} else {
|
} else {
|
||||||
formatConstructor(parsedObject, variableName, constructorArgs);
|
formatConstructor(parsedObject, variableName, constructorArgs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void formatNoConstructor(final ParsedObject parsedObject, final String variableName, final Collection<String> allPropertyNames) throws GenerationException {
|
private void formatNoConstructor(final ParsedObject parsedObject, final String variableName, final Collection<String> allAttributesNames) throws GenerationException {
|
||||||
final var clazz = ReflectionHelper.getClass(parsedObject.className());
|
final var clazz = ReflectionHelper.getClass(parsedObject.className());
|
||||||
if (allPropertyNames.size() == 1 && allPropertyNames.iterator().next().equals("fx:constant")) {
|
if (allAttributesNames.contains("fx:constant") && (allAttributesNames.size() == 1 ||
|
||||||
|
(allAttributesNames.size() == 2 && allAttributesNames.contains("fx:id")))) {
|
||||||
final var property = parsedObject.attributes().get("fx:constant");
|
final var property = parsedObject.attributes().get("fx:constant");
|
||||||
progress.stringBuilder().append(helperProvider.getCompatibilityHelper().getStartVar(parsedObject)).append(variableName).append(" = ").append(clazz.getCanonicalName()).append(".").append(property.value()).append(";\n");
|
sb.append(helperProvider.getCompatibilityHelper().getStartVar(parsedObject)).append(variableName).append(" = ").append(clazz.getCanonicalName()).append(".").append(property.value()).append(";\n");
|
||||||
} else {
|
} else {
|
||||||
throw new GenerationException("Cannot find constructor for " + clazz.getCanonicalName());
|
throw new GenerationException("Cannot find constructor for " + clazz.getCanonicalName());
|
||||||
}
|
}
|
||||||
@@ -235,30 +302,31 @@ public final class ObjectFormatter {
|
|||||||
|
|
||||||
private void formatConstructor(final ParsedObject parsedObject, final String variableName, final ConstructorArgs constructorArgs) throws GenerationException {
|
private void formatConstructor(final ParsedObject parsedObject, final String variableName, final ConstructorArgs constructorArgs) throws GenerationException {
|
||||||
final var reflectionHelper = helperProvider.getReflectionHelper();
|
final var reflectionHelper = helperProvider.getReflectionHelper();
|
||||||
final var args = helperProvider.getConstructorHelper().getListConstructorArgs(constructorArgs, parsedObject);
|
final var args = ConstructorHelper.getListConstructorArgs(constructorArgs, parsedObject);
|
||||||
final var genericTypes = reflectionHelper.getGenericTypes(parsedObject);
|
final var genericTypes = reflectionHelper.getGenericTypes(parsedObject);
|
||||||
progress.stringBuilder().append(helperProvider.getCompatibilityHelper().getStartVar(parsedObject)).append(variableName).append(NEW_ASSIGN).append(parsedObject.className())
|
sb.append(helperProvider.getCompatibilityHelper().getStartVar(parsedObject)).append(variableName)
|
||||||
.append(genericTypes).append("(").append(String.join(", ", args)).append(");\n");
|
.append(NEW_ASSIGN).append(parsedObject.className()).append(genericTypes).append("(")
|
||||||
|
.append(String.join(", ", args)).append(");\n");
|
||||||
final var sortedAttributes = getSortedAttributes(parsedObject);
|
final var sortedAttributes = getSortedAttributes(parsedObject);
|
||||||
for (final var value : sortedAttributes) {
|
for (final var value : sortedAttributes) {
|
||||||
if (!constructorArgs.namedArgs().containsKey(value.name())) {
|
if (!constructorArgs.namedArgs().containsKey(value.name())) {
|
||||||
helperProvider.getPropertyFormatter().formatProperty(value, parsedObject, variableName);
|
helperProvider.getPropertyFormatter().formatProperty(value, parsedObject, variableName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
final var sortedProperties = parsedObject.properties().entrySet().stream().sorted(Comparator.comparing(e -> e.getKey().name())).toList();
|
final var sortedProperties = parsedObject.properties().entrySet().stream().sorted(Comparator.comparing(p -> p.getKey().name())).toList();
|
||||||
for (final var e : sortedProperties) {
|
for (final var e : sortedProperties) {
|
||||||
if (!constructorArgs.namedArgs().containsKey(e.getKey().name())) {
|
if (!constructorArgs.namedArgs().containsKey(e.getKey().name())) {
|
||||||
final var p = e.getKey();
|
final var p = e.getKey();
|
||||||
final var o = e.getValue();
|
final var o = e.getValue();
|
||||||
formatChild(parsedObject, p, o, variableName);
|
helperProvider.getPropertyFormatter().formatProperty(p, o, parsedObject, variableName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
final var notDefinedChildren = parsedObject.children().stream().filter(c -> !(c instanceof ParsedDefine)).toList();
|
final var notDefinedChildren = parsedObject.children().stream().filter(c -> !(c instanceof ParsedDefine)).toList();
|
||||||
if (!notDefinedChildren.isEmpty()) {
|
if (!notDefinedChildren.isEmpty()) {
|
||||||
final var defaultProperty = ReflectionHelper.getDefaultProperty(parsedObject.className());
|
final var defaultProperty = ReflectionHelper.getDefaultProperty(parsedObject.className());
|
||||||
if (!constructorArgs.namedArgs().containsKey(defaultProperty)) {
|
if (!constructorArgs.namedArgs().containsKey(defaultProperty)) {
|
||||||
final var property = new ParsedPropertyImpl(defaultProperty, null, null);
|
final var property = new ParsedPropertyImpl(defaultProperty, null, "");
|
||||||
formatChild(parsedObject, property, notDefinedChildren, variableName);
|
helperProvider.getPropertyFormatter().formatProperty(property, notDefinedChildren, parsedObject, variableName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -270,20 +338,21 @@ public final class ObjectFormatter {
|
|||||||
* @param subNodeName The sub node name
|
* @param subNodeName The sub node name
|
||||||
*/
|
*/
|
||||||
private void formatInclude(final ParsedInclude include, final String subNodeName) throws GenerationException {
|
private void formatInclude(final ParsedInclude include, final String subNodeName) throws GenerationException {
|
||||||
final var subViewVariable = progress.getNextVariableName("view");
|
final var subViewVariable = helperProvider.getVariableProvider().getNextVariableName("view");
|
||||||
final var viewVariable = helperProvider.getInitializationFormatter().formatSubViewConstructorCall(include);
|
final var viewVariable = helperProvider.getInitializationFormatter().formatSubViewConstructorCall(include);
|
||||||
progress.stringBuilder().append(" final javafx.scene.Parent ").append(subNodeName).append(" = ").append(viewVariable).append(".load();\n");
|
sb.append(" final javafx.scene.Parent ").append(subNodeName).append(" = ").append(viewVariable).append(".load();\n");
|
||||||
injectSubController(include, subViewVariable);
|
injectSubController(include, subViewVariable);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void injectSubController(final ParsedInclude include, final String subViewVariable) throws GenerationException {
|
private void injectSubController(final ParsedInclude include, final String subViewVariable) {
|
||||||
final var id = include.controllerId();
|
final var id = include.controllerId();
|
||||||
if (id != null) {
|
if (id != null) {
|
||||||
final var subControllerVariable = progress.getNextVariableName("controller");
|
final var variableProvider = helperProvider.getVariableProvider();
|
||||||
final var controllerClass = progress.request().sourceInfo().sourceToSourceInfo().get(include.source()).controllerClassName();
|
final var subControllerVariable = variableProvider.getNextVariableName("controller");
|
||||||
progress.stringBuilder().append(helperProvider.getCompatibilityHelper().getStartVar(controllerClass)).append(subControllerVariable).append(" = ").append(subViewVariable).append(".controller();\n");
|
final var controllerClass = request.sourceInfo().sourceToSourceInfo().get(include.source()).controllerClassName();
|
||||||
progress.idToVariableInfo().put(id, new VariableInfo(id, include, subControllerVariable, controllerClass));
|
sb.append(helperProvider.getCompatibilityHelper().getStartVar(controllerClass)).append(subControllerVariable).append(" = ").append(subViewVariable).append(".controller();\n");
|
||||||
if (progress.request().controllerInfo().fieldInfo(id) == null) {
|
variableProvider.addVariableInfo(id, new VariableInfo(id, include, subControllerVariable, controllerClass));
|
||||||
|
if (request.controllerInfo().fieldInfo(id) == null) {
|
||||||
logger.debug("Not injecting {} because it is not found in controller", id);
|
logger.debug("Not injecting {} because it is not found in controller", id);
|
||||||
} else {
|
} else {
|
||||||
helperProvider.getControllerInjector().injectControllerField(id, subControllerVariable);
|
helperProvider.getControllerInjector().injectControllerField(id, subControllerVariable);
|
||||||
@@ -294,12 +363,12 @@ public final class ObjectFormatter {
|
|||||||
/**
|
/**
|
||||||
* Formats a fx:define
|
* Formats a fx:define
|
||||||
*
|
*
|
||||||
* @param define The parsed define
|
* @param define The parsed define
|
||||||
* @throws GenerationException if an error occurs
|
* @throws GenerationException if an error occurs
|
||||||
*/
|
*/
|
||||||
private void formatDefine(final ParsedObject define) throws GenerationException {
|
private void formatDefine(final ParsedObject define) throws GenerationException {
|
||||||
for (final var child : define.children()) {
|
for (final var child : define.children()) {
|
||||||
format(child, progress.getNextVariableName("definedObject"));
|
format(child, helperProvider.getVariableProvider().getNextVariableName("definedObject"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -311,12 +380,12 @@ public final class ObjectFormatter {
|
|||||||
*/
|
*/
|
||||||
private void formatReference(final ParsedReference reference, final String variableName) throws GenerationException {
|
private void formatReference(final ParsedReference reference, final String variableName) throws GenerationException {
|
||||||
final var id = reference.source();
|
final var id = reference.source();
|
||||||
final var variableInfo = progress.idToVariableInfo().get(id);
|
final var variableInfo = helperProvider.getVariableProvider().getVariableInfo(id);
|
||||||
if (variableInfo == null) {
|
if (variableInfo == null) {
|
||||||
throw new GenerationException("Unknown id : " + id);
|
throw new GenerationException("Unknown id : " + id);
|
||||||
}
|
}
|
||||||
final var referenceName = variableInfo.variableName();
|
final var referenceName = variableInfo.variableName();
|
||||||
progress.stringBuilder().append(helperProvider.getCompatibilityHelper().getStartVar(variableInfo.className())).append(variableName).append(" = ").append(referenceName).append(";\n");
|
sb.append(helperProvider.getCompatibilityHelper().getStartVar(variableInfo.className())).append(variableName).append(" = ").append(referenceName).append(";\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -328,12 +397,13 @@ public final class ObjectFormatter {
|
|||||||
*/
|
*/
|
||||||
private void formatCopy(final ParsedCopy copy, final String variableName) throws GenerationException {
|
private void formatCopy(final ParsedCopy copy, final String variableName) throws GenerationException {
|
||||||
final var id = copy.source();
|
final var id = copy.source();
|
||||||
final var variableInfo = progress.idToVariableInfo().get(id);
|
final var variableInfo = helperProvider.getVariableProvider().getVariableInfo(id);
|
||||||
if (variableInfo == null) {
|
if (variableInfo == null) {
|
||||||
throw new GenerationException("Unknown id : " + id);
|
throw new GenerationException("Unknown id : " + id);
|
||||||
}
|
}
|
||||||
final var copyVariable = variableInfo.variableName();
|
final var copyVariable = variableInfo.variableName();
|
||||||
progress.stringBuilder().append(helperProvider.getCompatibilityHelper().getStartVar(variableInfo.className())).append(variableName).append(NEW_ASSIGN).append(variableInfo.className()).append("(").append(copyVariable).append(");\n");
|
sb.append(helperProvider.getCompatibilityHelper().getStartVar(variableInfo.className())).append(variableName)
|
||||||
|
.append(NEW_ASSIGN).append(variableInfo.className()).append("(").append(copyVariable).append(");\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -342,8 +412,9 @@ public final class ObjectFormatter {
|
|||||||
* @param constant The constant
|
* @param constant The constant
|
||||||
* @param variableName The variable name
|
* @param variableName The variable name
|
||||||
*/
|
*/
|
||||||
private void formatConstant(final ParsedConstant constant, final String variableName) throws GenerationException {
|
private void formatConstant(final ParsedConstant constant, final String variableName) {
|
||||||
progress.stringBuilder().append(helperProvider.getCompatibilityHelper().getStartVar(constant.className())).append(variableName).append(" = ").append(constant.className()).append(".").append(constant.constant()).append(";\n");
|
sb.append(helperProvider.getCompatibilityHelper().getStartVar(constant.className()))
|
||||||
|
.append(variableName).append(" = ").append(constant.className()).append(".").append(constant.constant()).append(";\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -352,8 +423,8 @@ public final class ObjectFormatter {
|
|||||||
* @param value The value
|
* @param value The value
|
||||||
* @param variableName The variable name
|
* @param variableName The variable name
|
||||||
*/
|
*/
|
||||||
private void formatValue(final ParsedValue value, final String variableName) throws GenerationException {
|
private void formatValue(final ParsedValue value, final String variableName) {
|
||||||
progress.stringBuilder().append(helperProvider.getCompatibilityHelper().getStartVar(value.className())).append(variableName).append(" = ").append(value.className()).append(".valueOf(\"").append(value.value()).append("\");\n");
|
sb.append(helperProvider.getCompatibilityHelper().getStartVar(value.className())).append(variableName).append(" = ").append(value.className()).append(".valueOf(\"").append(value.value()).append("\");\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -364,128 +435,23 @@ public final class ObjectFormatter {
|
|||||||
*/
|
*/
|
||||||
private void formatFactory(final ParsedFactory factory, final String variableName) throws GenerationException {
|
private void formatFactory(final ParsedFactory factory, final String variableName) throws GenerationException {
|
||||||
final var variables = new ArrayList<String>();
|
final var variables = new ArrayList<String>();
|
||||||
|
for (final var child : factory.children()) {
|
||||||
|
final var vn = helperProvider.getVariableProvider().getNextVariableName(getVariablePrefix(child));
|
||||||
|
format(child, vn);
|
||||||
|
}
|
||||||
for (final var argument : factory.arguments()) {
|
for (final var argument : factory.arguments()) {
|
||||||
final var argumentVariable = progress.getNextVariableName("arg");
|
final var argumentVariable = helperProvider.getVariableProvider().getNextVariableName("arg");
|
||||||
variables.add(argumentVariable);
|
variables.add(argumentVariable);
|
||||||
format(argument, argumentVariable);
|
format(argument, argumentVariable);
|
||||||
}
|
}
|
||||||
final var compatibilityHelper = helperProvider.getCompatibilityHelper();
|
final var compatibilityHelper = helperProvider.getCompatibilityHelper();
|
||||||
if (progress.request().parameters().compatibility().useVar()) {
|
if (request.parameters().compatibility().useVar()) {
|
||||||
progress.stringBuilder().append(compatibilityHelper.getStartVar(factory.className())).append(variableName).append(" = ").append(factory.className())
|
sb.append(compatibilityHelper.getStartVar(factory.className())).append(variableName).append(" = ").append(factory.className())
|
||||||
.append(".").append(factory.factory()).append("(").append(String.join(", ", variables)).append(");\n");
|
.append(".").append(factory.factory()).append("(").append(String.join(", ", variables)).append(");\n");
|
||||||
} else {
|
} else {
|
||||||
final var returnType = ReflectionHelper.getReturnType(factory.className(), factory.factory());
|
final var returnType = ReflectionHelper.getReturnType(factory.className(), factory.factory());
|
||||||
progress.stringBuilder().append(compatibilityHelper.getStartVar(returnType)).append(variableName).append(" = ").append(factory.className())
|
sb.append(compatibilityHelper.getStartVar(returnType)).append(variableName).append(" = ").append(factory.className())
|
||||||
.append(".").append(factory.factory()).append("(").append(String.join(", ", variables)).append(");\n");
|
.append(".").append(factory.factory()).append("(").append(String.join(", ", variables)).append(");\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Formats the children objects of a property
|
|
||||||
*
|
|
||||||
* @param parent The parent object
|
|
||||||
* @param property The parent property
|
|
||||||
* @param objects The child objects
|
|
||||||
* @param parentVariable The parent object variable
|
|
||||||
*/
|
|
||||||
private void formatChild(final ParsedObject parent, final ParsedProperty property,
|
|
||||||
final Iterable<? extends ParsedObject> objects, final String parentVariable) throws GenerationException {
|
|
||||||
final var propertyName = property.name();
|
|
||||||
final var variables = new ArrayList<String>();
|
|
||||||
for (final var object : objects) {
|
|
||||||
final var vn = progress.getNextVariableName(getVariablePrefix(object));
|
|
||||||
format(object, vn);
|
|
||||||
if (!(object instanceof ParsedDefine)) {
|
|
||||||
variables.add(vn);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (variables.size() > 1) {
|
|
||||||
formatMultipleChildren(variables, propertyName, parent, parentVariable);
|
|
||||||
} else if (variables.size() == 1) {
|
|
||||||
final var vn = variables.getFirst();
|
|
||||||
formatSingleChild(vn, property, parent, parentVariable);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Formats children objects given that they are more than one
|
|
||||||
*
|
|
||||||
* @param variables The children variables
|
|
||||||
* @param propertyName The property name
|
|
||||||
* @param parent The parent object
|
|
||||||
* @param parentVariable The parent object variable
|
|
||||||
*/
|
|
||||||
private void formatMultipleChildren(final Iterable<String> variables, final String propertyName, final ParsedObject parent,
|
|
||||||
final String parentVariable) throws GenerationException {
|
|
||||||
final var getMethod = getGetMethod(propertyName);
|
|
||||||
if (ReflectionHelper.hasMethod(ReflectionHelper.getClass(parent.className()), getMethod)) {
|
|
||||||
progress.stringBuilder().append(" ").append(parentVariable).append(".").append(getMethod).append("().addAll(").append(helperProvider.getCompatibilityHelper().getListOf()).append(String.join(", ", variables)).append("));\n");
|
|
||||||
} else {
|
|
||||||
throw getCannotSetException(propertyName, parent.className());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Formats a single child object
|
|
||||||
*
|
|
||||||
* @param variableName The child's variable name
|
|
||||||
* @param property The parent property
|
|
||||||
* @param parent The parent object
|
|
||||||
* @param parentVariable The parent object variable
|
|
||||||
*/
|
|
||||||
private void formatSingleChild(final String variableName, final ParsedProperty property, final ParsedObject parent,
|
|
||||||
final String parentVariable) throws GenerationException {
|
|
||||||
if (property.sourceType() == null) {
|
|
||||||
formatSingleChildInstance(variableName, property, parent, parentVariable);
|
|
||||||
} else {
|
|
||||||
formatSingleChildStatic(variableName, property, parentVariable);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Formats a single child object using an instance method on the parent object
|
|
||||||
*
|
|
||||||
* @param variableName The child's variable name
|
|
||||||
* @param property The parent property
|
|
||||||
* @param parent The parent object
|
|
||||||
* @param parentVariable The parent object variable
|
|
||||||
*/
|
|
||||||
private void formatSingleChildInstance(final String variableName,
|
|
||||||
final ParsedProperty property, final ParsedObject parent,
|
|
||||||
final String parentVariable) throws GenerationException {
|
|
||||||
final var setMethod = getSetMethod(property);
|
|
||||||
final var getMethod = getGetMethod(property);
|
|
||||||
final var parentClass = ReflectionHelper.getClass(parent.className());
|
|
||||||
final var sb = progress.stringBuilder();
|
|
||||||
if (ReflectionHelper.hasMethod(parentClass, setMethod)) {
|
|
||||||
sb.append(" ").append(parentVariable).append(".").append(setMethod).append("(").append(variableName).append(");\n");
|
|
||||||
} else if (ReflectionHelper.hasMethod(parentClass, getMethod)) {
|
|
||||||
//Probably a list method that has only one element
|
|
||||||
sb.append(" ").append(parentVariable).append(".").append(getMethod).append("().addAll(").append(helperProvider.getCompatibilityHelper().getListOf()).append(variableName).append("));\n");
|
|
||||||
} else {
|
|
||||||
throw getCannotSetException(property.name(), parent.className());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Formats a child object using a static method
|
|
||||||
*
|
|
||||||
* @param variableName The child's variable name
|
|
||||||
* @param property The parent property
|
|
||||||
* @param parentVariable The parent variable
|
|
||||||
*/
|
|
||||||
private void formatSingleChildStatic(final String variableName,
|
|
||||||
final ParsedProperty property, final String parentVariable) throws GenerationException {
|
|
||||||
final var setMethod = getSetMethod(property);
|
|
||||||
if (ReflectionHelper.hasStaticMethod(ReflectionHelper.getClass(property.sourceType()), setMethod)) {
|
|
||||||
progress.stringBuilder().append(" ").append(property.sourceType()).append(".").append(setMethod)
|
|
||||||
.append("(").append(parentVariable).append(", ").append(variableName).append(");\n");
|
|
||||||
} else {
|
|
||||||
throw getCannotSetException(property.name(), property.sourceType());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static GenerationException getCannotSetException(final String propertyName, final String className) {
|
|
||||||
return new GenerationException("Cannot set " + propertyName + " on " + className);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,21 @@
|
|||||||
package com.github.gtache.fxml.compiler.impl.internal;
|
package com.github.gtache.fxml.compiler.impl.internal;
|
||||||
|
|
||||||
|
import com.github.gtache.fxml.compiler.ControllerFieldInjectionType;
|
||||||
import com.github.gtache.fxml.compiler.GenerationException;
|
import com.github.gtache.fxml.compiler.GenerationException;
|
||||||
import com.github.gtache.fxml.compiler.impl.ControllerFieldInjectionTypes;
|
import com.github.gtache.fxml.compiler.ResourceBundleInjectionType;
|
||||||
import com.github.gtache.fxml.compiler.impl.GeneratorImpl;
|
import com.github.gtache.fxml.compiler.impl.GeneratorImpl;
|
||||||
import com.github.gtache.fxml.compiler.impl.ResourceBundleInjectionTypes;
|
import com.github.gtache.fxml.compiler.parsing.ParsedDefine;
|
||||||
import com.github.gtache.fxml.compiler.parsing.ParsedObject;
|
import com.github.gtache.fxml.compiler.parsing.ParsedObject;
|
||||||
import com.github.gtache.fxml.compiler.parsing.ParsedProperty;
|
import com.github.gtache.fxml.compiler.parsing.ParsedProperty;
|
||||||
|
import com.github.gtache.fxml.compiler.parsing.ParsedText;
|
||||||
|
import com.github.gtache.fxml.compiler.parsing.impl.ParsedPropertyImpl;
|
||||||
import javafx.event.EventHandler;
|
import javafx.event.EventHandler;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.SequencedCollection;
|
||||||
|
|
||||||
import static com.github.gtache.fxml.compiler.impl.internal.GenerationHelper.FX_ID;
|
import static com.github.gtache.fxml.compiler.impl.internal.GenerationHelper.*;
|
||||||
import static com.github.gtache.fxml.compiler.impl.internal.GenerationHelper.RESOURCE_KEY_PREFIX;
|
|
||||||
import static java.util.Objects.requireNonNull;
|
import static java.util.Objects.requireNonNull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -39,7 +43,7 @@ final class PropertyFormatter {
|
|||||||
void formatProperty(final ParsedProperty property, final ParsedObject parent, final String parentVariable) throws GenerationException {
|
void formatProperty(final ParsedProperty property, final ParsedObject parent, final String parentVariable) throws GenerationException {
|
||||||
final var propertyName = property.name();
|
final var propertyName = property.name();
|
||||||
if (propertyName.equals(FX_ID)) {
|
if (propertyName.equals(FX_ID)) {
|
||||||
helperProvider.getGenerationHelper().handleId(parent, parentVariable);
|
//Do nothing
|
||||||
} else if (propertyName.equals("fx:controller")) {
|
} else if (propertyName.equals("fx:controller")) {
|
||||||
checkDuplicateController(parent);
|
checkDuplicateController(parent);
|
||||||
} else if (Objects.equals(property.sourceType(), EventHandler.class.getName())) {
|
} else if (Objects.equals(property.sourceType(), EventHandler.class.getName())) {
|
||||||
@@ -51,6 +55,27 @@ final class PropertyFormatter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Formats a complex property (containing a list of objects).
|
||||||
|
* The values should not contain any ParsedDefine
|
||||||
|
*
|
||||||
|
* @param property The property to format
|
||||||
|
* @param values The property's values
|
||||||
|
* @param parent The property's parent object
|
||||||
|
* @param parentVariable The parent variable
|
||||||
|
* @throws GenerationException if an error occurs or if the values contain a ParsedDefine
|
||||||
|
*/
|
||||||
|
void formatProperty(final ParsedProperty property, final SequencedCollection<? extends ParsedObject> values, final ParsedObject parent, final String parentVariable) throws GenerationException {
|
||||||
|
if (values.stream().anyMatch(ParsedDefine.class::isInstance)) {
|
||||||
|
throw new GenerationException("Values should not contain any ParsedDefine");
|
||||||
|
} else if (values.size() == 1 && values.getFirst() instanceof final ParsedText text) {
|
||||||
|
final var newProperty = new ParsedPropertyImpl(property.name(), property.sourceType(), text.text());
|
||||||
|
formatProperty(newProperty, parent, parentVariable);
|
||||||
|
} else {
|
||||||
|
formatChild(parent, property, values, parentVariable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void checkDuplicateController(final ParsedObject parent) throws GenerationException {
|
private void checkDuplicateController(final ParsedObject parent) throws GenerationException {
|
||||||
if (parent != progress.request().rootObject()) {
|
if (parent != progress.request().rootObject()) {
|
||||||
throw new GenerationException("Invalid nested controller");
|
throw new GenerationException("Invalid nested controller");
|
||||||
@@ -66,7 +91,7 @@ final class PropertyFormatter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void handleStaticProperty(final ParsedProperty property, final String parentVariable, final String propertyName) throws GenerationException {
|
private void handleStaticProperty(final ParsedProperty property, final String parentVariable, final String propertyName) throws GenerationException {
|
||||||
final var setMethod = GenerationHelper.getSetMethod(propertyName);
|
final var setMethod = getSetMethod(propertyName);
|
||||||
final var propertySourceTypeClass = ReflectionHelper.getClass(property.sourceType());
|
final var propertySourceTypeClass = ReflectionHelper.getClass(property.sourceType());
|
||||||
if (ReflectionHelper.hasStaticMethod(propertySourceTypeClass, setMethod)) {
|
if (ReflectionHelper.hasStaticMethod(propertySourceTypeClass, setMethod)) {
|
||||||
final var method = ReflectionHelper.getStaticMethod(propertySourceTypeClass, setMethod);
|
final var method = ReflectionHelper.getStaticMethod(propertySourceTypeClass, setMethod);
|
||||||
@@ -80,8 +105,8 @@ final class PropertyFormatter {
|
|||||||
|
|
||||||
private void handleProperty(final ParsedProperty property, final ParsedObject parent, final String parentVariable) throws GenerationException {
|
private void handleProperty(final ParsedProperty property, final ParsedObject parent, final String parentVariable) throws GenerationException {
|
||||||
final var propertyName = property.name();
|
final var propertyName = property.name();
|
||||||
final var setMethod = GenerationHelper.getSetMethod(propertyName);
|
final var setMethod = getSetMethod(propertyName);
|
||||||
final var getMethod = GenerationHelper.getGetMethod(propertyName);
|
final var getMethod = getGetMethod(propertyName);
|
||||||
final var parentClass = ReflectionHelper.getClass(parent.className());
|
final var parentClass = ReflectionHelper.getClass(parent.className());
|
||||||
if (ReflectionHelper.hasMethod(parentClass, setMethod)) {
|
if (ReflectionHelper.hasMethod(parentClass, setMethod)) {
|
||||||
handleSetProperty(property, parentClass, parentVariable);
|
handleSetProperty(property, parentClass, parentVariable);
|
||||||
@@ -93,7 +118,7 @@ final class PropertyFormatter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void handleSetProperty(final ParsedProperty property, final Class<?> parentClass, final String parentVariable) throws GenerationException {
|
private void handleSetProperty(final ParsedProperty property, final Class<?> parentClass, final String parentVariable) throws GenerationException {
|
||||||
final var setMethod = GenerationHelper.getSetMethod(property.name());
|
final var setMethod = getSetMethod(property.name());
|
||||||
final var method = ReflectionHelper.getMethod(parentClass, setMethod);
|
final var method = ReflectionHelper.getMethod(parentClass, setMethod);
|
||||||
final var parameterType = method.getParameterTypes()[0];
|
final var parameterType = method.getParameterTypes()[0];
|
||||||
final var arg = helperProvider.getValueFormatter().getArg(property.value(), parameterType);
|
final var arg = helperProvider.getValueFormatter().getArg(property.value(), parameterType);
|
||||||
@@ -101,12 +126,15 @@ final class PropertyFormatter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void handleGetProperty(final ParsedProperty property, final Class<?> parentClass, final String parentVariable) throws GenerationException {
|
private void handleGetProperty(final ParsedProperty property, final Class<?> parentClass, final String parentVariable) throws GenerationException {
|
||||||
final var getMethod = GenerationHelper.getGetMethod(property.name());
|
final var getMethod = getGetMethod(property.name());
|
||||||
final var method = ReflectionHelper.getMethod(parentClass, getMethod);
|
final var method = ReflectionHelper.getMethod(parentClass, getMethod);
|
||||||
final var returnType = method.getReturnType();
|
final var returnType = method.getReturnType();
|
||||||
if (ReflectionHelper.hasMethod(returnType, "addAll")) {
|
if (ReflectionHelper.hasMethod(returnType, "addAll")) {
|
||||||
final var arg = helperProvider.getValueFormatter().getArg(property.value(), String.class);
|
final var arg = helperProvider.getValueFormatter().getArg(property.value(), String.class);
|
||||||
setLaterIfNeeded(property, String.class, " " + parentVariable + "." + getMethod + "().addAll(" + helperProvider.getCompatibilityHelper().getListOf() + arg + "));\n");
|
setLaterIfNeeded(property, String.class, " " + parentVariable + "." + getMethod + "().addAll(" +
|
||||||
|
helperProvider.getCompatibilityHelper().getListOf() + arg + "));\n");
|
||||||
|
} else {
|
||||||
|
throw new GenerationException("Cannot set " + property.name() + " on " + parentClass);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,11 +147,119 @@ final class PropertyFormatter {
|
|||||||
*/
|
*/
|
||||||
private void setLaterIfNeeded(final ParsedProperty property, final Class<?> type, final String arg) {
|
private void setLaterIfNeeded(final ParsedProperty property, final Class<?> type, final String arg) {
|
||||||
final var parameters = progress.request().parameters();
|
final var parameters = progress.request().parameters();
|
||||||
if (type == String.class && property.value().startsWith(RESOURCE_KEY_PREFIX) && parameters.resourceInjectionType() == ResourceBundleInjectionTypes.GETTER
|
if (type == String.class && property.value().startsWith(RESOURCE_KEY_PREFIX) && parameters.resourceInjectionType() == ResourceBundleInjectionType.GETTER
|
||||||
&& parameters.fieldInjectionType() == ControllerFieldInjectionTypes.FACTORY) {
|
&& parameters.fieldInjectionType() == ControllerFieldInjectionType.FACTORY) {
|
||||||
progress.controllerFactoryPostAction().add(arg);
|
progress.controllerFactoryPostAction().add(arg);
|
||||||
} else {
|
} else {
|
||||||
progress.stringBuilder().append(arg);
|
progress.stringBuilder().append(arg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Formats the children objects of a property
|
||||||
|
*
|
||||||
|
* @param parent The parent object
|
||||||
|
* @param property The parent property
|
||||||
|
* @param objects The child objects
|
||||||
|
* @param parentVariable The parent object variable
|
||||||
|
*/
|
||||||
|
private void formatChild(final ParsedObject parent, final ParsedProperty property,
|
||||||
|
final Iterable<? extends ParsedObject> objects, final String parentVariable) throws GenerationException {
|
||||||
|
final var propertyName = property.name();
|
||||||
|
final var variables = new ArrayList<String>();
|
||||||
|
for (final var object : objects) {
|
||||||
|
final var vn = helperProvider.getVariableProvider().getNextVariableName(getVariablePrefix(object));
|
||||||
|
helperProvider.getObjectFormatter().format(object, vn);
|
||||||
|
variables.add(vn);
|
||||||
|
}
|
||||||
|
if (variables.size() > 1) {
|
||||||
|
formatMultipleChildren(variables, propertyName, parent, parentVariable);
|
||||||
|
} else if (variables.size() == 1) {
|
||||||
|
final var vn = variables.getFirst();
|
||||||
|
formatSingleChild(vn, property, parent, parentVariable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Formats children objects given that they are more than one
|
||||||
|
*
|
||||||
|
* @param variables The children variables
|
||||||
|
* @param propertyName The property name
|
||||||
|
* @param parent The parent object
|
||||||
|
* @param parentVariable The parent object variable
|
||||||
|
*/
|
||||||
|
private void formatMultipleChildren(final Iterable<String> variables, final String propertyName, final ParsedObject parent,
|
||||||
|
final String parentVariable) throws GenerationException {
|
||||||
|
final var getMethod = getGetMethod(propertyName);
|
||||||
|
if (ReflectionHelper.hasMethod(ReflectionHelper.getClass(parent.className()), getMethod)) {
|
||||||
|
progress.stringBuilder().append(" ").append(parentVariable).append(".").append(getMethod).append("().addAll(").append(helperProvider.getCompatibilityHelper().getListOf()).append(String.join(", ", variables)).append("));\n");
|
||||||
|
} else {
|
||||||
|
throw getCannotSetException(propertyName, parent.className());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Formats a single child object
|
||||||
|
*
|
||||||
|
* @param variableName The child's variable name
|
||||||
|
* @param property The parent property
|
||||||
|
* @param parent The parent object
|
||||||
|
* @param parentVariable The parent object variable
|
||||||
|
*/
|
||||||
|
private void formatSingleChild(final String variableName, final ParsedProperty property, final ParsedObject parent,
|
||||||
|
final String parentVariable) throws GenerationException {
|
||||||
|
if (property.sourceType() == null) {
|
||||||
|
formatSingleChildInstance(variableName, property, parent, parentVariable);
|
||||||
|
} else {
|
||||||
|
formatSingleChildStatic(variableName, property, parentVariable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Formats a single child object using an instance method on the parent object
|
||||||
|
*
|
||||||
|
* @param variableName The child's variable name
|
||||||
|
* @param property The parent property
|
||||||
|
* @param parent The parent object
|
||||||
|
* @param parentVariable The parent object variable
|
||||||
|
*/
|
||||||
|
private void formatSingleChildInstance(final String variableName,
|
||||||
|
final ParsedProperty property, final ParsedObject parent,
|
||||||
|
final String parentVariable) throws GenerationException {
|
||||||
|
final var setMethod = getSetMethod(property);
|
||||||
|
final var getMethod = getGetMethod(property);
|
||||||
|
final var parentClass = ReflectionHelper.getClass(parent.className());
|
||||||
|
final var sb = progress.stringBuilder();
|
||||||
|
if (ReflectionHelper.hasMethod(parentClass, setMethod)) {
|
||||||
|
sb.append(" ").append(parentVariable).append(".").append(setMethod).append("(").append(variableName).append(");\n");
|
||||||
|
} else if (ReflectionHelper.hasMethod(parentClass, getMethod)) {
|
||||||
|
//Probably a list method that has only one element
|
||||||
|
sb.append(" ").append(parentVariable).append(".").append(getMethod).append("().addAll(").append(helperProvider.getCompatibilityHelper().getListOf()).append(variableName).append("));\n");
|
||||||
|
} else {
|
||||||
|
throw getCannotSetException(property.name(), parent.className());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Formats a child object using a static method
|
||||||
|
*
|
||||||
|
* @param variableName The child's variable name
|
||||||
|
* @param property The parent property
|
||||||
|
* @param parentVariable The parent variable
|
||||||
|
*/
|
||||||
|
private void formatSingleChildStatic(final String variableName,
|
||||||
|
final ParsedProperty property, final String parentVariable) throws GenerationException {
|
||||||
|
final var setMethod = getSetMethod(property);
|
||||||
|
if (ReflectionHelper.hasStaticMethod(ReflectionHelper.getClass(property.sourceType()), setMethod)) {
|
||||||
|
progress.stringBuilder().append(" ").append(property.sourceType()).append(".").append(setMethod)
|
||||||
|
.append("(").append(parentVariable).append(", ").append(variableName).append(");\n");
|
||||||
|
} else {
|
||||||
|
throw getCannotSetException(property.name(), property.sourceType());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static GenerationException getCannotSetException(final String propertyName, final String className) {
|
||||||
|
return new GenerationException("Cannot set " + propertyName + " on " + className);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,11 +2,16 @@ package com.github.gtache.fxml.compiler.impl.internal;
|
|||||||
|
|
||||||
import com.github.gtache.fxml.compiler.GenerationException;
|
import com.github.gtache.fxml.compiler.GenerationException;
|
||||||
import com.github.gtache.fxml.compiler.impl.GeneratorImpl;
|
import com.github.gtache.fxml.compiler.impl.GeneratorImpl;
|
||||||
|
import com.github.gtache.fxml.compiler.parsing.ParsedDefine;
|
||||||
import com.github.gtache.fxml.compiler.parsing.ParsedObject;
|
import com.github.gtache.fxml.compiler.parsing.ParsedObject;
|
||||||
|
import com.github.gtache.fxml.compiler.parsing.ParsedProperty;
|
||||||
|
import com.github.gtache.fxml.compiler.parsing.impl.ParsedPropertyImpl;
|
||||||
import javafx.scene.paint.Color;
|
import javafx.scene.paint.Color;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import static com.github.gtache.fxml.compiler.impl.internal.GenerationHelper.FX_ID;
|
import static com.github.gtache.fxml.compiler.impl.internal.GenerationHelper.FX_ID;
|
||||||
import static com.github.gtache.fxml.compiler.impl.internal.GenerationHelper.getSortedAttributes;
|
import static com.github.gtache.fxml.compiler.impl.internal.GenerationHelper.getSortedAttributes;
|
||||||
@@ -17,17 +22,21 @@ import static java.util.Objects.requireNonNull;
|
|||||||
*/
|
*/
|
||||||
final class SceneFormatter {
|
final class SceneFormatter {
|
||||||
|
|
||||||
private final HelperProvider helperProvider;
|
private static final ParsedProperty ROOT_PROPERTY = new ParsedPropertyImpl("root", null, "");
|
||||||
private final GenerationProgress progress;
|
|
||||||
|
|
||||||
SceneFormatter(final HelperProvider helperProvider, final GenerationProgress progress) {
|
private final HelperProvider helperProvider;
|
||||||
|
private final StringBuilder sb;
|
||||||
|
|
||||||
|
SceneFormatter(final HelperProvider helperProvider, final StringBuilder sb) {
|
||||||
this.helperProvider = requireNonNull(helperProvider);
|
this.helperProvider = requireNonNull(helperProvider);
|
||||||
this.progress = requireNonNull(progress);
|
this.sb = requireNonNull(sb);
|
||||||
}
|
}
|
||||||
|
|
||||||
void formatScene(final ParsedObject parsedObject, final String variableName) throws GenerationException {
|
void formatScene(final ParsedObject parsedObject, final String variableName) throws GenerationException {
|
||||||
|
checkPropertiesAndChildren(parsedObject);
|
||||||
|
formatDefines(parsedObject);
|
||||||
final var root = findRoot(parsedObject);
|
final var root = findRoot(parsedObject);
|
||||||
final var rootVariableName = progress.getNextVariableName("root");
|
final var rootVariableName = helperProvider.getVariableProvider().getNextVariableName("root");
|
||||||
helperProvider.getObjectFormatter().format(root, rootVariableName);
|
helperProvider.getObjectFormatter().format(root, rootVariableName);
|
||||||
final var sortedAttributes = getSortedAttributes(parsedObject);
|
final var sortedAttributes = getSortedAttributes(parsedObject);
|
||||||
double width = -1;
|
double width = -1;
|
||||||
@@ -46,31 +55,64 @@ final class SceneFormatter {
|
|||||||
default -> throw new GenerationException("Unknown font attribute : " + property.name());
|
default -> throw new GenerationException("Unknown font attribute : " + property.name());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
final var sb = progress.stringBuilder();
|
|
||||||
sb.append(helperProvider.getCompatibilityHelper().getStartVar("javafx.scene.Scene")).append(variableName).append(" = new javafx.scene.Scene(").append(rootVariableName).append(", ")
|
sb.append(helperProvider.getCompatibilityHelper().getStartVar("javafx.scene.Scene")).append(variableName).append(" = new javafx.scene.Scene(").append(rootVariableName).append(", ")
|
||||||
.append(width).append(", ").append(height).append(", javafx.scene.paint.Color.valueOf(\"").append(paint).append("\"));\n");
|
.append(width).append(", ").append(height).append(", javafx.scene.paint.Color.valueOf(\"").append(paint).append("\"));\n");
|
||||||
addStylesheets(variableName, stylesheets);
|
addStylesheets(variableName, stylesheets);
|
||||||
helperProvider.getGenerationHelper().handleId(parsedObject, variableName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ParsedObject findRoot(final ParsedObject parsedObject) throws GenerationException {
|
private void formatDefines(final ParsedObject parsedObject) throws GenerationException {
|
||||||
final var rootProperty = parsedObject.properties().entrySet().stream().filter(e -> e.getKey().name().equals("root"))
|
final var objectFormatter = helperProvider.getObjectFormatter();
|
||||||
.filter(e -> e.getValue().size() == 1)
|
for (final var define : parsedObject.children()) {
|
||||||
.map(e -> e.getValue().getFirst()).findFirst().orElse(null);
|
if (define instanceof ParsedDefine) {
|
||||||
if (rootProperty != null) {
|
objectFormatter.format(define, helperProvider.getVariableProvider().getNextVariableName("define"));
|
||||||
return rootProperty;
|
}
|
||||||
} else if (parsedObject.children().size() == 1) {
|
}
|
||||||
return parsedObject.children().getFirst();
|
for (final var define : parsedObject.properties().getOrDefault(ROOT_PROPERTY, List.of())) {
|
||||||
} else {
|
if (define instanceof ParsedDefine) {
|
||||||
throw new GenerationException("Scene must have a root");
|
objectFormatter.format(define, helperProvider.getVariableProvider().getNextVariableName("define"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addStylesheets(final String variableName, final Collection<String> stylesheets) throws GenerationException {
|
private static ParsedObject findRoot(final ParsedObject parsedObject) throws GenerationException {
|
||||||
|
final var rootPropertyChildren = parsedObject.properties().get(ROOT_PROPERTY);
|
||||||
|
if (rootPropertyChildren == null) {
|
||||||
|
return getNonDefineObjects(parsedObject.children()).findFirst()
|
||||||
|
.orElseThrow(() -> new GenerationException("Expected only one child for scene : " + parsedObject));
|
||||||
|
} else {
|
||||||
|
return getNonDefineObjects(rootPropertyChildren).findFirst()
|
||||||
|
.orElseThrow(() -> new GenerationException("Expected only one root property child for scene : " + parsedObject));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Stream<ParsedObject> getNonDefineObjects(final Collection<ParsedObject> objects) {
|
||||||
|
return objects.stream().filter(c -> !(c instanceof ParsedDefine));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void checkPropertiesAndChildren(final ParsedObject parsedObject) throws GenerationException {
|
||||||
|
if (parsedObject.properties().keySet().stream().anyMatch(k -> !k.equals(ROOT_PROPERTY))) {
|
||||||
|
throw new GenerationException("Unsupported scene properties : " + parsedObject);
|
||||||
|
}
|
||||||
|
final var nonDefineCount = getNonDefineObjects(parsedObject.children()).count();
|
||||||
|
final var rootPropertyChildren = parsedObject.properties().get(ROOT_PROPERTY);
|
||||||
|
if (rootPropertyChildren == null) {
|
||||||
|
if (nonDefineCount != 1) {
|
||||||
|
throw new GenerationException("Expected only one child for scene : " + parsedObject);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
final var nonDefinePropertyChildren = getNonDefineObjects(rootPropertyChildren).count();
|
||||||
|
if (nonDefinePropertyChildren != 1) {
|
||||||
|
throw new GenerationException("Expected only one root property child for scene : " + parsedObject);
|
||||||
|
} else if (nonDefineCount != 0) {
|
||||||
|
throw new GenerationException("Expected no children for scene : " + parsedObject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addStylesheets(final String variableName, final Collection<String> stylesheets) {
|
||||||
if (!stylesheets.isEmpty()) {
|
if (!stylesheets.isEmpty()) {
|
||||||
final var urlVariables = helperProvider.getURLFormatter().formatURL(stylesheets);
|
final var urlVariables = helperProvider.getURLFormatter().formatURL(stylesheets);
|
||||||
final var tmpVariable = progress.getNextVariableName("stylesheets");
|
final var tmpVariable = helperProvider.getVariableProvider().getNextVariableName("stylesheets");
|
||||||
final var sb = progress.stringBuilder();
|
|
||||||
final var compatibilityHelper = helperProvider.getCompatibilityHelper();
|
final var compatibilityHelper = helperProvider.getCompatibilityHelper();
|
||||||
sb.append(compatibilityHelper.getStartVar("java.util.List<String>")).append(tmpVariable).append(" = ").append(variableName).append(".getStyleSheets();\n");
|
sb.append(compatibilityHelper.getStartVar("java.util.List<String>")).append(tmpVariable).append(" = ").append(variableName).append(".getStyleSheets();\n");
|
||||||
sb.append(" ").append(tmpVariable).append(".addAll(").append(compatibilityHelper.getListOf()).append(String.join(", ", urlVariables)).append("));\n");
|
sb.append(" ").append(tmpVariable).append(".addAll(").append(compatibilityHelper.getListOf()).append(String.join(", ", urlVariables)).append("));\n");
|
||||||
|
|||||||
@@ -76,7 +76,6 @@ final class TriangleMeshFormatter {
|
|||||||
setFaces(variableName, faces);
|
setFaces(variableName, faces);
|
||||||
setFaceSmoothingGroups(variableName, faceSmoothingGroups);
|
setFaceSmoothingGroups(variableName, faceSmoothingGroups);
|
||||||
setVertexFormat(variableName, vertexFormat);
|
setVertexFormat(variableName, vertexFormat);
|
||||||
helperProvider.getGenerationHelper().handleId(parsedObject, variableName);
|
|
||||||
} else {
|
} else {
|
||||||
throw new GenerationException("Image cannot have children or properties : " + parsedObject);
|
throw new GenerationException("Image cannot have children or properties : " + parsedObject);
|
||||||
}
|
}
|
||||||
@@ -133,8 +132,8 @@ final class TriangleMeshFormatter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static <T> List<T> parseList(final CharSequence value, final Function<? super String, ? extends T> parser) {
|
private static <T> List<T> parseList(final CharSequence value, final Function<? super String, ? extends T> parser) {
|
||||||
final var splitPattern = Pattern.compile("[\\s+,]");
|
final var splitPattern = Pattern.compile("\\s*,\\s*|\\s+");
|
||||||
final var split = splitPattern.split(value);
|
final var split = splitPattern.split(value);
|
||||||
return Arrays.stream(split).map(parser).collect(Collectors.toList());
|
return Arrays.stream(split).map(String::trim).filter(s -> !s.isEmpty()).map(parser).collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,11 +17,11 @@ import static java.util.Objects.requireNonNull;
|
|||||||
final class URLFormatter {
|
final class URLFormatter {
|
||||||
|
|
||||||
private final HelperProvider helperProvider;
|
private final HelperProvider helperProvider;
|
||||||
private final GenerationProgress progress;
|
private final StringBuilder sb;
|
||||||
|
|
||||||
URLFormatter(final HelperProvider helperProvider, final GenerationProgress progress) {
|
URLFormatter(final HelperProvider helperProvider, final StringBuilder sb) {
|
||||||
this.helperProvider = requireNonNull(helperProvider);
|
this.helperProvider = requireNonNull(helperProvider);
|
||||||
this.progress = requireNonNull(progress);
|
this.sb = requireNonNull(sb);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<String> formatURL(final Iterable<String> stylesheets) {
|
List<String> formatURL(final Iterable<String> stylesheets) {
|
||||||
@@ -33,8 +33,7 @@ final class URLFormatter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String formatURL(final String url) {
|
String formatURL(final String url) {
|
||||||
final var variableName = progress.getNextVariableName("url");
|
final var variableName = helperProvider.getVariableProvider().getNextVariableName("url");
|
||||||
final var sb = progress.stringBuilder();
|
|
||||||
if (url.startsWith(RELATIVE_PATH_PREFIX)) {
|
if (url.startsWith(RELATIVE_PATH_PREFIX)) {
|
||||||
sb.append(getStartURL()).append(variableName).append(" = getClass().getResource(\"").append(url.substring(1)).append("\");\n");
|
sb.append(getStartURL()).append(variableName).append(" = getClass().getResource(\"").append(url.substring(1)).append("\");\n");
|
||||||
} else {
|
} else {
|
||||||
@@ -62,8 +61,7 @@ final class URLFormatter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
//FIXME only relative path (@) ?
|
//FIXME only relative path (@) ?
|
||||||
progress.stringBuilder().append(getStartURL()).append(variableName).append(" = getClass().getResource(\"").append(value).append("\");\n");
|
sb.append(getStartURL()).append(variableName).append(" = getClass().getResource(\"").append(value).append("\");\n");
|
||||||
helperProvider.getGenerationHelper().handleId(parsedObject, variableName);
|
|
||||||
} else {
|
} else {
|
||||||
throw new GenerationException("URL cannot have children or properties : " + parsedObject);
|
throw new GenerationException("URL cannot have children or properties : " + parsedObject);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,9 @@
|
|||||||
package com.github.gtache.fxml.compiler.impl.internal;
|
package com.github.gtache.fxml.compiler.impl.internal;
|
||||||
|
|
||||||
import com.github.gtache.fxml.compiler.GenerationException;
|
import com.github.gtache.fxml.compiler.GenerationException;
|
||||||
import com.github.gtache.fxml.compiler.InjectionType;
|
import com.github.gtache.fxml.compiler.ResourceBundleInjectionType;
|
||||||
import com.github.gtache.fxml.compiler.impl.GeneratorImpl;
|
import com.github.gtache.fxml.compiler.impl.GeneratorImpl;
|
||||||
import com.github.gtache.fxml.compiler.impl.ResourceBundleInjectionTypes;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import static com.github.gtache.fxml.compiler.impl.internal.GenerationHelper.*;
|
import static com.github.gtache.fxml.compiler.impl.internal.GenerationHelper.*;
|
||||||
@@ -20,12 +18,12 @@ final class ValueFormatter {
|
|||||||
private static final Pattern DECIMAL_PATTERN = Pattern.compile("\\d+(?:\\.\\d+)?");
|
private static final Pattern DECIMAL_PATTERN = Pattern.compile("\\d+(?:\\.\\d+)?");
|
||||||
private static final Pattern START_BACKSLASH_PATTERN = Pattern.compile("^\\\\");
|
private static final Pattern START_BACKSLASH_PATTERN = Pattern.compile("^\\\\");
|
||||||
|
|
||||||
private final InjectionType resourceInjectionType;
|
private final HelperProvider helperProvider;
|
||||||
private final Map<String, VariableInfo> idToVariableInfo;
|
private final ResourceBundleInjectionType resourceInjectionType;
|
||||||
|
|
||||||
ValueFormatter(final InjectionType resourceInjectionType, final Map<String, VariableInfo> idToVariableInfo) {
|
ValueFormatter(final HelperProvider helperProvider, final ResourceBundleInjectionType resourceInjectionType) {
|
||||||
|
this.helperProvider = requireNonNull(helperProvider);
|
||||||
this.resourceInjectionType = requireNonNull(resourceInjectionType);
|
this.resourceInjectionType = requireNonNull(resourceInjectionType);
|
||||||
this.idToVariableInfo = requireNonNull(idToVariableInfo);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -45,7 +43,7 @@ final class ValueFormatter {
|
|||||||
} else if (value.startsWith(BINDING_EXPRESSION_PREFIX)) {
|
} else if (value.startsWith(BINDING_EXPRESSION_PREFIX)) {
|
||||||
throw new GenerationException("Not implemented yet");
|
throw new GenerationException("Not implemented yet");
|
||||||
} else if (value.startsWith(EXPRESSION_PREFIX)) {
|
} else if (value.startsWith(EXPRESSION_PREFIX)) {
|
||||||
final var variable = idToVariableInfo.get(value.substring(1));
|
final var variable = helperProvider.getVariableProvider().getVariableInfo(value.substring(1));
|
||||||
if (variable == null) {
|
if (variable == null) {
|
||||||
throw new GenerationException("Unknown variable : " + value.substring(1));
|
throw new GenerationException("Unknown variable : " + value.substring(1));
|
||||||
}
|
}
|
||||||
@@ -62,20 +60,15 @@ final class ValueFormatter {
|
|||||||
/**
|
/**
|
||||||
* Gets the resource bundle value for the given value
|
* Gets the resource bundle value for the given value
|
||||||
*
|
*
|
||||||
* @param value The value
|
* @param value The value
|
||||||
* @return The resource bundle value
|
* @return The resource bundle value
|
||||||
* @throws GenerationException if an error occurs
|
|
||||||
*/
|
*/
|
||||||
private String getBundleValue(final String value) throws GenerationException {
|
private String getBundleValue(final String value) {
|
||||||
if (resourceInjectionType instanceof final ResourceBundleInjectionTypes types) {
|
return switch (resourceInjectionType) {
|
||||||
return switch (types) {
|
case CONSTRUCTOR, GET_BUNDLE, CONSTRUCTOR_NAME -> "resourceBundle.getString(\"" + value + "\")";
|
||||||
case CONSTRUCTOR, GET_BUNDLE, CONSTRUCTOR_NAME -> "resourceBundle.getString(\"" + value + "\")";
|
case GETTER -> "controller.resources().getString(\"" + value + "\")";
|
||||||
case GETTER -> "controller.resources().getString(\"" + value + "\")";
|
case CONSTRUCTOR_FUNCTION -> "resourceBundleFunction.apply(\"" + value + "\")";
|
||||||
case CONSTRUCTOR_FUNCTION -> "resourceBundleFunction.apply(\"" + value + "\")";
|
};
|
||||||
};
|
|
||||||
} else {
|
|
||||||
throw new GenerationException("Unknown resource bundle injection type : " + resourceInjectionType);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -86,7 +79,7 @@ final class ValueFormatter {
|
|||||||
* @param clazz The value class
|
* @param clazz The value class
|
||||||
* @return The computed string value
|
* @return The computed string value
|
||||||
*/
|
*/
|
||||||
String toString(final String value, final Class<?> clazz) {
|
static String toString(final String value, final Class<?> clazz) {
|
||||||
if (clazz == String.class) {
|
if (clazz == String.class) {
|
||||||
return "\"" + START_BACKSLASH_PATTERN.matcher(value).replaceAll("").replace("\\", "\\\\")
|
return "\"" + START_BACKSLASH_PATTERN.matcher(value).replaceAll("").replace("\\", "\\\\")
|
||||||
.replace("\"", "\\\"") + "\"";
|
.replace("\"", "\\\"") + "\"";
|
||||||
|
|||||||
@@ -13,7 +13,15 @@ import java.util.Objects;
|
|||||||
* @param className The class name of the variable
|
* @param className The class name of the variable
|
||||||
*/
|
*/
|
||||||
record VariableInfo(String id, ParsedObject parsedObject, String variableName, String className) {
|
record VariableInfo(String id, ParsedObject parsedObject, String variableName, String className) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates a new variable info
|
||||||
|
* @param id The fx:id of the variable
|
||||||
|
* @param parsedObject The parsed object of the variable
|
||||||
|
* @param variableName The variable name
|
||||||
|
* @param className The class name of the variable
|
||||||
|
* @throws NullPointerException if any parameter is null
|
||||||
|
*/
|
||||||
VariableInfo {
|
VariableInfo {
|
||||||
Objects.requireNonNull(id);
|
Objects.requireNonNull(id);
|
||||||
Objects.requireNonNull(parsedObject);
|
Objects.requireNonNull(parsedObject);
|
||||||
|
|||||||
@@ -0,0 +1,51 @@
|
|||||||
|
package com.github.gtache.fxml.compiler.impl.internal;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provider of variable names and info
|
||||||
|
*/
|
||||||
|
class VariableProvider {
|
||||||
|
|
||||||
|
private final Map<String, AtomicInteger> variableNameCounters;
|
||||||
|
private final Map<String, VariableInfo> idToVariableInfo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates a new provider
|
||||||
|
*/
|
||||||
|
VariableProvider() {
|
||||||
|
this.variableNameCounters = new HashMap<>();
|
||||||
|
this.idToVariableInfo = new HashMap<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the next available variable name for the given prefix
|
||||||
|
*
|
||||||
|
* @param prefix The variable name prefix
|
||||||
|
* @return The next available variable name
|
||||||
|
*/
|
||||||
|
String getNextVariableName(final String prefix) {
|
||||||
|
final var counter = variableNameCounters.computeIfAbsent(prefix, k -> new AtomicInteger(0));
|
||||||
|
return prefix + counter.getAndIncrement();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a variable info
|
||||||
|
* @param id The variable id
|
||||||
|
* @param variableInfo The variable info
|
||||||
|
*/
|
||||||
|
void addVariableInfo(final String id, final VariableInfo variableInfo) {
|
||||||
|
idToVariableInfo.put(id, variableInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the variable info
|
||||||
|
* @param id The variable id
|
||||||
|
* @return The variable info
|
||||||
|
*/
|
||||||
|
VariableInfo getVariableInfo(final String id) {
|
||||||
|
return idToVariableInfo.get(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -15,11 +15,11 @@ import static java.util.Objects.requireNonNull;
|
|||||||
final class WebViewFormatter {
|
final class WebViewFormatter {
|
||||||
|
|
||||||
private final HelperProvider helperProvider;
|
private final HelperProvider helperProvider;
|
||||||
private final GenerationProgress progress;
|
private final StringBuilder sb;
|
||||||
|
|
||||||
WebViewFormatter(final HelperProvider helperProvider, final GenerationProgress progress) {
|
WebViewFormatter(final HelperProvider helperProvider, final StringBuilder sb) {
|
||||||
this.helperProvider = requireNonNull(helperProvider);
|
this.helperProvider = requireNonNull(helperProvider);
|
||||||
this.progress = requireNonNull(progress);
|
this.sb = requireNonNull(sb);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -32,15 +32,13 @@ final class WebViewFormatter {
|
|||||||
void formatWebView(final ParsedObject parsedObject, final String variableName) throws GenerationException {
|
void formatWebView(final ParsedObject parsedObject, final String variableName) throws GenerationException {
|
||||||
if (parsedObject.children().isEmpty() && parsedObject.properties().isEmpty()) {
|
if (parsedObject.children().isEmpty() && parsedObject.properties().isEmpty()) {
|
||||||
final var sortedAttributes = getSortedAttributes(parsedObject);
|
final var sortedAttributes = getSortedAttributes(parsedObject);
|
||||||
final var sb = progress.stringBuilder();
|
|
||||||
final var compatibilityHelper = helperProvider.getCompatibilityHelper();
|
final var compatibilityHelper = helperProvider.getCompatibilityHelper();
|
||||||
sb.append(compatibilityHelper.getStartVar("javafx.scene.web.WebView")).append(variableName).append(" = new javafx.scene.web.WebView();\n");
|
sb.append(compatibilityHelper.getStartVar("javafx.scene.web.WebView")).append(variableName).append(" = new javafx.scene.web.WebView();\n");
|
||||||
final var engineVariable = progress.getNextVariableName("engine");
|
final var engineVariable = helperProvider.getVariableProvider().getNextVariableName("engine");
|
||||||
sb.append(compatibilityHelper.getStartVar("javafx.scene.web.WebEngine")).append(engineVariable).append(" = ").append(variableName).append(".getEngine();\n");
|
sb.append(compatibilityHelper.getStartVar("javafx.scene.web.WebEngine")).append(engineVariable).append(" = ").append(variableName).append(".getEngine();\n");
|
||||||
for (final var value : sortedAttributes) {
|
for (final var value : sortedAttributes) {
|
||||||
formatAttribute(value, parsedObject, variableName, engineVariable);
|
formatAttribute(value, parsedObject, variableName, engineVariable);
|
||||||
}
|
}
|
||||||
helperProvider.getGenerationHelper().handleId(parsedObject, variableName);
|
|
||||||
} else {
|
} else {
|
||||||
throw new GenerationException("WebView cannot have children or properties : " + parsedObject);
|
throw new GenerationException("WebView cannot have children or properties : " + parsedObject);
|
||||||
}
|
}
|
||||||
@@ -95,7 +93,7 @@ final class WebViewFormatter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void injectLocation(final ParsedProperty value, final String engineVariable) {
|
private void injectLocation(final ParsedProperty value, final String engineVariable) {
|
||||||
progress.stringBuilder().append(" ").append(engineVariable).append(".load(\"").append(value.value()).append("\");\n");
|
sb.append(" ").append(engineVariable).append(".load(\"").append(value.value()).append("\");\n");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,12 +10,36 @@ import java.util.Objects;
|
|||||||
* Implementation of {@link ParsedConstant}
|
* Implementation of {@link ParsedConstant}
|
||||||
*
|
*
|
||||||
* @param className The constant class
|
* @param className The constant class
|
||||||
* @param attributes The constant properties
|
* @param attributes The constant attributes
|
||||||
*/
|
*/
|
||||||
public record ParsedConstantImpl(String className, Map<String, ParsedProperty> attributes) implements ParsedConstant {
|
public record ParsedConstantImpl(String className, Map<String, ParsedProperty> attributes) implements ParsedConstant {
|
||||||
|
|
||||||
|
private static final String FX_CONSTANT = "fx:constant";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates the constant
|
||||||
|
*
|
||||||
|
* @param className The constant class
|
||||||
|
* @param attributes The constant attributes
|
||||||
|
* @throws NullPointerException if any argument is null
|
||||||
|
* @throws IllegalArgumentException If the attributes do not contain fx:constant
|
||||||
|
*/
|
||||||
public ParsedConstantImpl {
|
public ParsedConstantImpl {
|
||||||
Objects.requireNonNull(className);
|
Objects.requireNonNull(className);
|
||||||
|
if (!attributes.containsKey(FX_CONSTANT)) {
|
||||||
|
throw new IllegalArgumentException("Missing " + FX_CONSTANT);
|
||||||
|
}
|
||||||
attributes = Map.copyOf(attributes);
|
attributes = Map.copyOf(attributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates the constant
|
||||||
|
*
|
||||||
|
* @param className The constant class
|
||||||
|
* @param value The constant value
|
||||||
|
* @throws NullPointerException if any argument is null
|
||||||
|
*/
|
||||||
|
public ParsedConstantImpl(final String className, final String value) {
|
||||||
|
this(className, Map.of(FX_CONSTANT, new ParsedPropertyImpl(FX_CONSTANT, null, value)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,11 +8,33 @@ import java.util.Map;
|
|||||||
/**
|
/**
|
||||||
* Implementation of {@link ParsedCopy}
|
* Implementation of {@link ParsedCopy}
|
||||||
*
|
*
|
||||||
* @param attributes The reference properties
|
* @param attributes The copy attributes
|
||||||
*/
|
*/
|
||||||
public record ParsedCopyImpl(Map<String, ParsedProperty> attributes) implements ParsedCopy {
|
public record ParsedCopyImpl(Map<String, ParsedProperty> attributes) implements ParsedCopy {
|
||||||
|
|
||||||
|
private static final String SOURCE = "source";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates the copy
|
||||||
|
*
|
||||||
|
* @param attributes The copy attributes
|
||||||
|
* @throws NullPointerException If the attributes are null
|
||||||
|
* @throws IllegalArgumentException If the attributes don't contain source
|
||||||
|
*/
|
||||||
public ParsedCopyImpl {
|
public ParsedCopyImpl {
|
||||||
attributes = Map.copyOf(attributes);
|
attributes = Map.copyOf(attributes);
|
||||||
|
if (!attributes.containsKey(SOURCE)) {
|
||||||
|
throw new IllegalArgumentException("Missing " + SOURCE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates the copy
|
||||||
|
*
|
||||||
|
* @param source The source
|
||||||
|
* @throws NullPointerException If the source is null
|
||||||
|
*/
|
||||||
|
public ParsedCopyImpl(final String source) {
|
||||||
|
this(Map.of(SOURCE, new ParsedPropertyImpl(SOURCE, null, source)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,12 +8,15 @@ import java.util.List;
|
|||||||
/**
|
/**
|
||||||
* Implementation of {@link ParsedObject}
|
* Implementation of {@link ParsedObject}
|
||||||
*
|
*
|
||||||
* @param className The object class
|
* @param children The objects in this define
|
||||||
* @param attributes The object properties
|
|
||||||
* @param properties The object children (complex properties)
|
|
||||||
*/
|
*/
|
||||||
public record ParsedDefineImpl(List<ParsedObject> children) implements ParsedDefine {
|
public record ParsedDefineImpl(List<ParsedObject> children) implements ParsedDefine {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates the define
|
||||||
|
* @param children The children
|
||||||
|
* @throws NullPointerException If the children are null
|
||||||
|
*/
|
||||||
public ParsedDefineImpl {
|
public ParsedDefineImpl {
|
||||||
children = List.copyOf(children);
|
children = List.copyOf(children);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,13 +13,23 @@ import java.util.SequencedCollection;
|
|||||||
* Implementation of {@link ParsedFactory}
|
* Implementation of {@link ParsedFactory}
|
||||||
*
|
*
|
||||||
* @param className The factory class
|
* @param className The factory class
|
||||||
* @param attributes The factory properties
|
* @param attributes The factory attributes
|
||||||
* @param arguments The factory arguments
|
* @param arguments The factory arguments
|
||||||
|
* @param children The factory children
|
||||||
*/
|
*/
|
||||||
public record ParsedFactoryImpl(String className, Map<String, ParsedProperty> attributes,
|
public record ParsedFactoryImpl(String className, Map<String, ParsedProperty> attributes,
|
||||||
SequencedCollection<ParsedObject> arguments,
|
SequencedCollection<ParsedObject> arguments,
|
||||||
SequencedCollection<ParsedObject> children) implements ParsedFactory {
|
SequencedCollection<ParsedObject> children) implements ParsedFactory {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates the factory
|
||||||
|
*
|
||||||
|
* @param className The factory class
|
||||||
|
* @param attributes The factory attributes
|
||||||
|
* @param arguments The factory arguments
|
||||||
|
* @param children The factory children
|
||||||
|
* @throws NullPointerException if any argument is null
|
||||||
|
*/
|
||||||
public ParsedFactoryImpl {
|
public ParsedFactoryImpl {
|
||||||
Objects.requireNonNull(className);
|
Objects.requireNonNull(className);
|
||||||
attributes = Map.copyOf(attributes);
|
attributes = Map.copyOf(attributes);
|
||||||
|
|||||||
@@ -3,16 +3,53 @@ package com.github.gtache.fxml.compiler.parsing.impl;
|
|||||||
import com.github.gtache.fxml.compiler.parsing.ParsedInclude;
|
import com.github.gtache.fxml.compiler.parsing.ParsedInclude;
|
||||||
import com.github.gtache.fxml.compiler.parsing.ParsedProperty;
|
import com.github.gtache.fxml.compiler.parsing.ParsedProperty;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of {@link ParsedInclude}
|
* Implementation of {@link ParsedInclude}
|
||||||
*
|
*
|
||||||
* @param attributes The object properties
|
* @param attributes The include attributes
|
||||||
*/
|
*/
|
||||||
public record ParsedIncludeImpl(Map<String, ParsedProperty> attributes) implements ParsedInclude {
|
public record ParsedIncludeImpl(Map<String, ParsedProperty> attributes) implements ParsedInclude {
|
||||||
|
|
||||||
|
private static final String SOURCE = "source";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates an include
|
||||||
|
*
|
||||||
|
* @param attributes The include attributes
|
||||||
|
* @throws NullPointerException If attributes is null
|
||||||
|
* @throws IllegalArgumentException If attributes does not contain source
|
||||||
|
*/
|
||||||
public ParsedIncludeImpl {
|
public ParsedIncludeImpl {
|
||||||
|
if (!attributes.containsKey(SOURCE)) {
|
||||||
|
throw new IllegalArgumentException("Missing " + SOURCE);
|
||||||
|
}
|
||||||
attributes = Map.copyOf(attributes);
|
attributes = Map.copyOf(attributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates an include
|
||||||
|
*
|
||||||
|
* @param source The source
|
||||||
|
* @param resources The resources
|
||||||
|
* @param fxId The fx:id
|
||||||
|
* @throws NullPointerException If source is null
|
||||||
|
*/
|
||||||
|
public ParsedIncludeImpl(final String source, final String resources, final String fxId) {
|
||||||
|
this(createAttributes(source, resources, fxId));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Map<String, ParsedProperty> createAttributes(final String source, final String resources, final String fxId) {
|
||||||
|
final var map = HashMap.<String, ParsedProperty>newHashMap(3);
|
||||||
|
map.put(SOURCE, new ParsedPropertyImpl(SOURCE, null, source));
|
||||||
|
if (resources != null) {
|
||||||
|
map.put("resources", new ParsedPropertyImpl("resources", null, resources));
|
||||||
|
}
|
||||||
|
if (fxId != null) {
|
||||||
|
map.put("fx:id", new ParsedPropertyImpl("fx:id", null, fxId));
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,13 +15,22 @@ import java.util.SequencedMap;
|
|||||||
* Implementation of {@link ParsedObject}
|
* Implementation of {@link ParsedObject}
|
||||||
*
|
*
|
||||||
* @param className The object class
|
* @param className The object class
|
||||||
* @param attributes The object properties
|
* @param attributes The object attributes
|
||||||
* @param properties The object children (complex properties)
|
* @param properties The object properties
|
||||||
|
* @param children The object children
|
||||||
*/
|
*/
|
||||||
public record ParsedObjectImpl(String className, Map<String, ParsedProperty> attributes,
|
public record ParsedObjectImpl(String className, Map<String, ParsedProperty> attributes,
|
||||||
SequencedMap<ParsedProperty, SequencedCollection<ParsedObject>> properties,
|
SequencedMap<ParsedProperty, SequencedCollection<ParsedObject>> properties,
|
||||||
SequencedCollection<ParsedObject> children) implements ParsedObject {
|
SequencedCollection<ParsedObject> children) implements ParsedObject {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates a new object
|
||||||
|
* @param className The object class
|
||||||
|
* @param attributes The object attributes
|
||||||
|
* @param properties The object properties
|
||||||
|
* @param children The object children
|
||||||
|
* @throws NullPointerException if any parameter is null
|
||||||
|
*/
|
||||||
public ParsedObjectImpl {
|
public ParsedObjectImpl {
|
||||||
Objects.requireNonNull(className);
|
Objects.requireNonNull(className);
|
||||||
attributes = Map.copyOf(attributes);
|
attributes = Map.copyOf(attributes);
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package com.github.gtache.fxml.compiler.parsing.impl;
|
|||||||
|
|
||||||
import com.github.gtache.fxml.compiler.parsing.ParsedProperty;
|
import com.github.gtache.fxml.compiler.parsing.ParsedProperty;
|
||||||
|
|
||||||
import java.util.Objects;
|
import static java.util.Objects.requireNonNull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of {@link ParsedProperty}
|
* Implementation of {@link ParsedProperty}
|
||||||
@@ -10,11 +10,18 @@ import java.util.Objects;
|
|||||||
* @param name The property name
|
* @param name The property name
|
||||||
* @param sourceType The property source type
|
* @param sourceType The property source type
|
||||||
* @param value The property value
|
* @param value The property value
|
||||||
* @param defines The property defines
|
|
||||||
*/
|
*/
|
||||||
public record ParsedPropertyImpl(String name, String sourceType, String value) implements ParsedProperty {
|
public record ParsedPropertyImpl(String name, String sourceType, String value) implements ParsedProperty {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates a property
|
||||||
|
* @param name The property name
|
||||||
|
* @param sourceType The property source type
|
||||||
|
* @param value The property value
|
||||||
|
* @throws NullPointerException If the name or value is null
|
||||||
|
*/
|
||||||
public ParsedPropertyImpl {
|
public ParsedPropertyImpl {
|
||||||
Objects.requireNonNull(name);
|
requireNonNull(name);
|
||||||
|
requireNonNull(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,11 +8,33 @@ import java.util.Map;
|
|||||||
/**
|
/**
|
||||||
* Implementation of {@link ParsedReference}
|
* Implementation of {@link ParsedReference}
|
||||||
*
|
*
|
||||||
* @param attributes The reference properties
|
* @param attributes The reference attributes
|
||||||
*/
|
*/
|
||||||
public record ParsedReferenceImpl(Map<String, ParsedProperty> attributes) implements ParsedReference {
|
public record ParsedReferenceImpl(Map<String, ParsedProperty> attributes) implements ParsedReference {
|
||||||
|
|
||||||
|
private static final String SOURCE = "source";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates a new reference
|
||||||
|
*
|
||||||
|
* @param attributes The reference attributes
|
||||||
|
* @throws NullPointerException If the attributes are null
|
||||||
|
* @throws IllegalArgumentException If the attributes do not contain source
|
||||||
|
*/
|
||||||
public ParsedReferenceImpl {
|
public ParsedReferenceImpl {
|
||||||
|
if (!attributes.containsKey(SOURCE)) {
|
||||||
|
throw new IllegalArgumentException("Missing " + SOURCE);
|
||||||
|
}
|
||||||
attributes = Map.copyOf(attributes);
|
attributes = Map.copyOf(attributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates a new reference
|
||||||
|
*
|
||||||
|
* @param source The reference source
|
||||||
|
* @throws NullPointerException If the source is null
|
||||||
|
*/
|
||||||
|
public ParsedReferenceImpl(final String source) {
|
||||||
|
this(Map.of(SOURCE, new ParsedPropertyImpl(SOURCE, null, source)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,8 +14,32 @@ import java.util.Objects;
|
|||||||
*/
|
*/
|
||||||
public record ParsedValueImpl(String className, Map<String, ParsedProperty> attributes) implements ParsedValue {
|
public record ParsedValueImpl(String className, Map<String, ParsedProperty> attributes) implements ParsedValue {
|
||||||
|
|
||||||
|
private static final String FX_VALUE = "fx:value";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates a new value
|
||||||
|
*
|
||||||
|
* @param className The value class
|
||||||
|
* @param attributes The value properties
|
||||||
|
* @throws NullPointerException If any parameter is null
|
||||||
|
* @throws IllegalArgumentException If the attributes don't contain fx:value
|
||||||
|
*/
|
||||||
public ParsedValueImpl {
|
public ParsedValueImpl {
|
||||||
Objects.requireNonNull(className);
|
Objects.requireNonNull(className);
|
||||||
|
if (!attributes.containsKey(FX_VALUE)) {
|
||||||
|
throw new IllegalArgumentException("Missing " + FX_VALUE);
|
||||||
|
}
|
||||||
attributes = Map.copyOf(attributes);
|
attributes = Map.copyOf(attributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates a new value
|
||||||
|
*
|
||||||
|
* @param className The value class
|
||||||
|
* @param value The value
|
||||||
|
* @throws NullPointerException If any parameter is null
|
||||||
|
*/
|
||||||
|
public ParsedValueImpl(final String className, final String value) {
|
||||||
|
this(className, Map.of(FX_VALUE, new ParsedPropertyImpl(FX_VALUE, null, value)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ module com.github.gtache.fxml.compiler.core {
|
|||||||
requires transitive com.github.gtache.fxml.compiler.api;
|
requires transitive com.github.gtache.fxml.compiler.api;
|
||||||
requires transitive javafx.graphics;
|
requires transitive javafx.graphics;
|
||||||
requires org.apache.logging.log4j;
|
requires org.apache.logging.log4j;
|
||||||
requires java.sql;
|
|
||||||
|
|
||||||
exports com.github.gtache.fxml.compiler.impl;
|
exports com.github.gtache.fxml.compiler.impl;
|
||||||
exports com.github.gtache.fxml.compiler.parsing.impl;
|
exports com.github.gtache.fxml.compiler.parsing.impl;
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
package com.github.gtache.fxml.compiler.impl;
|
package com.github.gtache.fxml.compiler.impl;
|
||||||
|
|
||||||
|
import com.github.gtache.fxml.compiler.ControllerFieldInjectionType;
|
||||||
|
import com.github.gtache.fxml.compiler.ControllerInjectionType;
|
||||||
|
import com.github.gtache.fxml.compiler.ControllerMethodsInjectionType;
|
||||||
import com.github.gtache.fxml.compiler.GenerationParameters;
|
import com.github.gtache.fxml.compiler.GenerationParameters;
|
||||||
import com.github.gtache.fxml.compiler.InjectionType;
|
import com.github.gtache.fxml.compiler.ResourceBundleInjectionType;
|
||||||
import com.github.gtache.fxml.compiler.compatibility.GenerationCompatibility;
|
import com.github.gtache.fxml.compiler.compatibility.GenerationCompatibility;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
@@ -20,15 +23,15 @@ class TestGenerationParametersImpl {
|
|||||||
private final GenerationCompatibility compatibility;
|
private final GenerationCompatibility compatibility;
|
||||||
private final boolean useImageInputStreamConstructor;
|
private final boolean useImageInputStreamConstructor;
|
||||||
private final Map<String, String> bundleMap;
|
private final Map<String, String> bundleMap;
|
||||||
private final InjectionType controllerInjectionType;
|
private final ControllerInjectionType controllerInjectionType;
|
||||||
private final InjectionType fieldInjectionType;
|
private final ControllerFieldInjectionType fieldInjectionType;
|
||||||
private final InjectionType methodInjectionType;
|
private final ControllerMethodsInjectionType methodInjectionType;
|
||||||
private final InjectionType resourceInjectionType;
|
private final ResourceBundleInjectionType resourceInjectionType;
|
||||||
private final GenerationParameters parameters;
|
private final GenerationParameters parameters;
|
||||||
|
|
||||||
TestGenerationParametersImpl(@Mock final GenerationCompatibility compatibility, @Mock final InjectionType controllerInjectionType,
|
TestGenerationParametersImpl(@Mock final GenerationCompatibility compatibility, @Mock final ControllerInjectionType controllerInjectionType,
|
||||||
@Mock final InjectionType fieldInjectionType, @Mock final InjectionType methodInjectionType,
|
@Mock final ControllerFieldInjectionType fieldInjectionType, @Mock final ControllerMethodsInjectionType methodInjectionType,
|
||||||
@Mock final InjectionType resourceInjectionType) {
|
@Mock final ResourceBundleInjectionType resourceInjectionType) {
|
||||||
this.compatibility = requireNonNull(compatibility);
|
this.compatibility = requireNonNull(compatibility);
|
||||||
this.useImageInputStreamConstructor = true;
|
this.useImageInputStreamConstructor = true;
|
||||||
this.controllerInjectionType = requireNonNull(controllerInjectionType);
|
this.controllerInjectionType = requireNonNull(controllerInjectionType);
|
||||||
|
|||||||
@@ -0,0 +1,91 @@
|
|||||||
|
package com.github.gtache.fxml.compiler.impl;
|
||||||
|
|
||||||
|
import com.github.gtache.fxml.compiler.ControllerInfo;
|
||||||
|
import com.github.gtache.fxml.compiler.GenerationException;
|
||||||
|
import com.github.gtache.fxml.compiler.GenerationRequest;
|
||||||
|
import com.github.gtache.fxml.compiler.Generator;
|
||||||
|
import com.github.gtache.fxml.compiler.impl.internal.HelperMethodsFormatter;
|
||||||
|
import com.github.gtache.fxml.compiler.impl.internal.HelperProvider;
|
||||||
|
import com.github.gtache.fxml.compiler.impl.internal.InitializationFormatter;
|
||||||
|
import com.github.gtache.fxml.compiler.impl.internal.LoadMethodFormatter;
|
||||||
|
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 static java.util.Objects.requireNonNull;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
@ExtendWith(MockitoExtension.class)
|
||||||
|
class TestGeneratorImpl {
|
||||||
|
|
||||||
|
private final HelperProvider helperProvider;
|
||||||
|
private final InitializationFormatter initializationFormatter;
|
||||||
|
private final LoadMethodFormatter loadMethodFormatter;
|
||||||
|
private final HelperMethodsFormatter helperMethodsFormatter;
|
||||||
|
private final GenerationRequest request;
|
||||||
|
private final String outputClassName;
|
||||||
|
private final ControllerInfo controllerInfo;
|
||||||
|
private final String className;
|
||||||
|
private final Generator generator;
|
||||||
|
|
||||||
|
TestGeneratorImpl(@Mock final HelperProvider helperProvider, @Mock final InitializationFormatter initializationFormatter,
|
||||||
|
@Mock final LoadMethodFormatter loadMethodFormatter, @Mock final HelperMethodsFormatter helperMethodsFormatter,
|
||||||
|
@Mock final GenerationRequest request, @Mock final ControllerInfo controllerInfo) {
|
||||||
|
this.helperProvider = requireNonNull(helperProvider);
|
||||||
|
this.initializationFormatter = requireNonNull(initializationFormatter);
|
||||||
|
this.loadMethodFormatter = requireNonNull(loadMethodFormatter);
|
||||||
|
this.helperMethodsFormatter = requireNonNull(helperMethodsFormatter);
|
||||||
|
this.request = requireNonNull(request);
|
||||||
|
this.controllerInfo = requireNonNull(controllerInfo);
|
||||||
|
this.outputClassName = "com.github.gtache.fxml.compiler.OutputClass";
|
||||||
|
this.className = "com.github.gtache.fxml.compiler.ControllerClass";
|
||||||
|
this.generator = new GeneratorImpl(p -> helperProvider);
|
||||||
|
}
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void beforeEach() {
|
||||||
|
when(helperProvider.getInitializationFormatter()).thenReturn(initializationFormatter);
|
||||||
|
when(helperProvider.getLoadMethodFormatter()).thenReturn(loadMethodFormatter);
|
||||||
|
when(helperProvider.getHelperMethodsFormatter()).thenReturn(helperMethodsFormatter);
|
||||||
|
when(request.outputClassName()).thenReturn(outputClassName);
|
||||||
|
when(request.controllerInfo()).thenReturn(controllerInfo);
|
||||||
|
when(controllerInfo.className()).thenReturn(className);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testGenerate() throws GenerationException {
|
||||||
|
final var expected = """
|
||||||
|
package com.github.gtache.fxml.compiler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generated code
|
||||||
|
*/
|
||||||
|
public final class OutputClass {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the controller if available
|
||||||
|
* @return The controller
|
||||||
|
* @throws IllegalStateException If the view is not loaded
|
||||||
|
*/
|
||||||
|
public com.github.gtache.fxml.compiler.ControllerClass controller() {
|
||||||
|
if (loaded) {
|
||||||
|
return controller;
|
||||||
|
} else {
|
||||||
|
throw new IllegalStateException("Not loaded");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
""";
|
||||||
|
assertEquals(expected, generator.generate(request));
|
||||||
|
verify(initializationFormatter).formatFieldsAndConstructor();
|
||||||
|
verify(loadMethodFormatter).formatLoadMethod();
|
||||||
|
verify(helperMethodsFormatter).formatHelperMethods();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,8 +1,123 @@
|
|||||||
package com.github.gtache.fxml.compiler.impl.internal;
|
package com.github.gtache.fxml.compiler.impl.internal;
|
||||||
|
|
||||||
|
import com.github.gtache.fxml.compiler.GenerationException;
|
||||||
|
import com.github.gtache.fxml.compiler.parsing.ParsedObject;
|
||||||
|
import com.github.gtache.fxml.compiler.parsing.ParsedProperty;
|
||||||
|
import com.github.gtache.fxml.compiler.parsing.impl.ParsedPropertyImpl;
|
||||||
|
import javafx.beans.NamedArg;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
import org.mockito.Mock;
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
|
||||||
|
import java.lang.annotation.Annotation;
|
||||||
|
import java.lang.reflect.Constructor;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.SequencedCollection;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
class TestConstructorHelper {
|
class TestConstructorHelper {
|
||||||
|
|
||||||
|
private final ConstructorArgs args;
|
||||||
|
private final Constructor<Object>[] constructors;
|
||||||
|
private final ParsedObject parsedObject;
|
||||||
|
private final Set<String> propertyNames;
|
||||||
|
|
||||||
|
TestConstructorHelper(@Mock final ConstructorArgs args, @Mock final Constructor<Object> constructor1,
|
||||||
|
@Mock final Constructor<Object> constructor2, @Mock final ParsedObject parsedObject) {
|
||||||
|
this.args = Objects.requireNonNull(args);
|
||||||
|
this.constructors = new Constructor[]{constructor1, constructor2};
|
||||||
|
this.parsedObject = Objects.requireNonNull(parsedObject);
|
||||||
|
this.propertyNames = Set.of("p1", "p2");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testGetListConstructorArgsExists() throws GenerationException {
|
||||||
|
final var namedArgs = new LinkedHashMap<String, Parameter>();
|
||||||
|
namedArgs.put("p1", new Parameter("p1", int.class, "1"));
|
||||||
|
namedArgs.put("p2", new Parameter("p2", String.class, "value2"));
|
||||||
|
when(args.namedArgs()).thenReturn(namedArgs);
|
||||||
|
final var attributes = new HashMap<String, ParsedProperty>();
|
||||||
|
when(parsedObject.attributes()).thenReturn(attributes);
|
||||||
|
attributes.put("p1", new ParsedPropertyImpl("p1", null, "10"));
|
||||||
|
attributes.put("p2", new ParsedPropertyImpl("p2", null, "value"));
|
||||||
|
final var expected = List.of("10", "\"value\"");
|
||||||
|
assertEquals(expected, ConstructorHelper.getListConstructorArgs(args, parsedObject));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void tesGetListConstructorArgsDefault() throws GenerationException {
|
||||||
|
final var namedArgs = new LinkedHashMap<String, Parameter>();
|
||||||
|
namedArgs.put("p1", new Parameter("p1", int.class, "1"));
|
||||||
|
namedArgs.put("p2", new Parameter("p2", String.class, "value2"));
|
||||||
|
when(args.namedArgs()).thenReturn(namedArgs);
|
||||||
|
when(parsedObject.attributes()).thenReturn(Map.of());
|
||||||
|
when(parsedObject.properties()).thenReturn(new LinkedHashMap<>());
|
||||||
|
final var expected = List.of("1", "\"value2\"");
|
||||||
|
assertEquals(expected, ConstructorHelper.getListConstructorArgs(args, parsedObject));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void tetsGetListConstructorArgsComplex() {
|
||||||
|
final var namedArgs = new LinkedHashMap<String, Parameter>();
|
||||||
|
namedArgs.put("p1", new Parameter("p1", int.class, "1"));
|
||||||
|
when(args.namedArgs()).thenReturn(namedArgs);
|
||||||
|
when(parsedObject.attributes()).thenReturn(Map.of());
|
||||||
|
final var properties = new LinkedHashMap<ParsedProperty, SequencedCollection<ParsedObject>>();
|
||||||
|
properties.put(new ParsedPropertyImpl("p1", null, "1"), List.of());
|
||||||
|
when(parsedObject.properties()).thenReturn(properties);
|
||||||
|
assertThrows(GenerationException.class, () -> ConstructorHelper.getListConstructorArgs(args, parsedObject));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testGetMatchingConstructorArgs() {
|
||||||
|
final var namedArgs = new LinkedHashMap<String, Parameter>();
|
||||||
|
namedArgs.put("p1", new Parameter("p1", int.class, "0"));
|
||||||
|
namedArgs.put("p2", new Parameter("p2", String.class, "value2"));
|
||||||
|
|
||||||
|
when(constructors[0].getParameterAnnotations()).thenReturn(new Annotation[0][]);
|
||||||
|
when(constructors[1].getParameterAnnotations()).thenReturn(new Annotation[][]{{new NamedArgImpl("p1", "")}, {
|
||||||
|
new NamedArgImpl("p2", "value2")}});
|
||||||
|
when(constructors[1].getParameterTypes()).thenReturn(new Class[]{int.class, String.class});
|
||||||
|
final var expectedArgs = new ConstructorArgs(constructors[1], namedArgs);
|
||||||
|
assertEquals(expectedArgs, ConstructorHelper.getMatchingConstructorArgs(constructors, propertyNames));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testGetMatchingConstructorArgsEmpty() {
|
||||||
|
final var namedArgs = new LinkedHashMap<String, Parameter>();
|
||||||
|
|
||||||
|
when(constructors[0].getParameterAnnotations()).thenReturn(new Annotation[0][]);
|
||||||
|
when(constructors[1].getParameterAnnotations()).thenReturn(new Annotation[0][]);
|
||||||
|
when(constructors[0].getParameterCount()).thenReturn(0);
|
||||||
|
when(constructors[1].getParameterCount()).thenReturn(1);
|
||||||
|
final var expectedArgs = new ConstructorArgs(constructors[0], namedArgs);
|
||||||
|
assertEquals(expectedArgs, ConstructorHelper.getMatchingConstructorArgs(constructors, propertyNames));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testGetMatchingConstructorArgsNull() {
|
||||||
|
when(constructors[0].getParameterAnnotations()).thenReturn(new Annotation[0][]);
|
||||||
|
when(constructors[1].getParameterAnnotations()).thenReturn(new Annotation[0][]);
|
||||||
|
when(constructors[0].getParameterCount()).thenReturn(1);
|
||||||
|
when(constructors[1].getParameterCount()).thenReturn(1);
|
||||||
|
assertNull(ConstructorHelper.getMatchingConstructorArgs(constructors, propertyNames));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private record NamedArgImpl(String value, String defaultValue) implements NamedArg {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<? extends Annotation> annotationType() {
|
||||||
|
return NamedArg.class;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
package com.github.gtache.fxml.compiler.impl.internal;
|
package com.github.gtache.fxml.compiler.impl.internal;
|
||||||
|
|
||||||
|
import com.github.gtache.fxml.compiler.ControllerFieldInjectionType;
|
||||||
import com.github.gtache.fxml.compiler.ControllerInfo;
|
import com.github.gtache.fxml.compiler.ControllerInfo;
|
||||||
import com.github.gtache.fxml.compiler.GenerationException;
|
import com.github.gtache.fxml.compiler.ControllerMethodsInjectionType;
|
||||||
import com.github.gtache.fxml.compiler.InjectionType;
|
|
||||||
import com.github.gtache.fxml.compiler.impl.ControllerFieldInjectionTypes;
|
|
||||||
import com.github.gtache.fxml.compiler.impl.ControllerMethodsInjectionType;
|
|
||||||
import com.github.gtache.fxml.compiler.parsing.ParsedProperty;
|
import com.github.gtache.fxml.compiler.parsing.ParsedProperty;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
@@ -17,7 +15,6 @@ import java.util.List;
|
|||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.*;
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
import static org.mockito.Mockito.mock;
|
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
@@ -49,8 +46,8 @@ class TestControllerInjector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testInjectControllerFieldFactory() throws GenerationException {
|
void testInjectControllerFieldFactory() {
|
||||||
final var injector = new ControllerInjector(controllerInfo, ControllerFieldInjectionTypes.FACTORY, ControllerMethodsInjectionType.REFERENCE, sb, controllerFactoryPostAction);
|
final var injector = new ControllerInjector(controllerInfo, ControllerFieldInjectionType.FACTORY, ControllerMethodsInjectionType.REFERENCE, sb, controllerFactoryPostAction);
|
||||||
injector.injectControllerField(id, variable);
|
injector.injectControllerField(id, variable);
|
||||||
final var expected = " fieldMap.put(\"" + id + "\", " + variable + ");\n";
|
final var expected = " fieldMap.put(\"" + id + "\", " + variable + ");\n";
|
||||||
assertEquals(expected, sb.toString());
|
assertEquals(expected, sb.toString());
|
||||||
@@ -58,8 +55,8 @@ class TestControllerInjector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testInjectControllerFieldAssign() throws GenerationException {
|
void testInjectControllerFieldAssign() {
|
||||||
final var injector = new ControllerInjector(controllerInfo, ControllerFieldInjectionTypes.ASSIGN, ControllerMethodsInjectionType.REFERENCE, sb, controllerFactoryPostAction);
|
final var injector = new ControllerInjector(controllerInfo, ControllerFieldInjectionType.ASSIGN, com.github.gtache.fxml.compiler.ControllerMethodsInjectionType.REFERENCE, sb, controllerFactoryPostAction);
|
||||||
injector.injectControllerField(id, variable);
|
injector.injectControllerField(id, variable);
|
||||||
final var expected = " controller." + id + " = " + variable + ";\n";
|
final var expected = " controller." + id + " = " + variable + ";\n";
|
||||||
assertEquals(expected, sb.toString());
|
assertEquals(expected, sb.toString());
|
||||||
@@ -67,8 +64,8 @@ class TestControllerInjector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testInjectControllerFieldSetters() throws GenerationException {
|
void testInjectControllerFieldSetters() {
|
||||||
final var injector = new ControllerInjector(controllerInfo, ControllerFieldInjectionTypes.SETTERS, ControllerMethodsInjectionType.REFERENCE, sb, controllerFactoryPostAction);
|
final var injector = new ControllerInjector(controllerInfo, ControllerFieldInjectionType.SETTERS, com.github.gtache.fxml.compiler.ControllerMethodsInjectionType.REFERENCE, sb, controllerFactoryPostAction);
|
||||||
injector.injectControllerField(id, variable);
|
injector.injectControllerField(id, variable);
|
||||||
final var expected = " controller." + GenerationHelper.getSetMethod(id) + "(" + variable + ");\n";
|
final var expected = " controller." + GenerationHelper.getSetMethod(id) + "(" + variable + ");\n";
|
||||||
assertEquals(expected, sb.toString());
|
assertEquals(expected, sb.toString());
|
||||||
@@ -76,8 +73,8 @@ class TestControllerInjector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testInjectControllerFieldReflection() throws GenerationException {
|
void testInjectControllerFieldReflection() {
|
||||||
final var injector = new ControllerInjector(controllerInfo, ControllerFieldInjectionTypes.REFLECTION, ControllerMethodsInjectionType.REFERENCE, sb, controllerFactoryPostAction);
|
final var injector = new ControllerInjector(controllerInfo, ControllerFieldInjectionType.REFLECTION, com.github.gtache.fxml.compiler.ControllerMethodsInjectionType.REFERENCE, sb, controllerFactoryPostAction);
|
||||||
injector.injectControllerField(id, variable);
|
injector.injectControllerField(id, variable);
|
||||||
final var expected = " injectField(\"" + id + "\", " + variable + ");\n";
|
final var expected = " injectField(\"" + id + "\", " + variable + ");\n";
|
||||||
assertEquals(expected, sb.toString());
|
assertEquals(expected, sb.toString());
|
||||||
@@ -85,14 +82,8 @@ class TestControllerInjector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testInjectControllerFieldUnknown() {
|
void testInjectEventHandlerReferenceFactoryNoArgument() {
|
||||||
final var injector = new ControllerInjector(controllerInfo, mock(InjectionType.class), ControllerMethodsInjectionType.REFERENCE, sb, controllerFactoryPostAction);
|
final var injector = new ControllerInjector(controllerInfo, ControllerFieldInjectionType.FACTORY, com.github.gtache.fxml.compiler.ControllerMethodsInjectionType.REFERENCE, sb, controllerFactoryPostAction);
|
||||||
assertThrows(GenerationException.class, () -> injector.injectControllerField(id, variable));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testInjectEventHandlerReferenceFactoryNoArgument() throws GenerationException {
|
|
||||||
final var injector = new ControllerInjector(controllerInfo, ControllerFieldInjectionTypes.FACTORY, ControllerMethodsInjectionType.REFERENCE, sb, controllerFactoryPostAction);
|
|
||||||
injector.injectEventHandlerControllerMethod(property, variable);
|
injector.injectEventHandlerControllerMethod(property, variable);
|
||||||
final var expected = " " + variable + "." + GenerationHelper.getSetMethod(property.name()) + "(e -> controller." + property.value().replace("#", "") + "());\n";
|
final var expected = " " + variable + "." + GenerationHelper.getSetMethod(property.name()) + "(e -> controller." + property.value().replace("#", "") + "());\n";
|
||||||
assertEquals(1, controllerFactoryPostAction.size());
|
assertEquals(1, controllerFactoryPostAction.size());
|
||||||
@@ -101,8 +92,8 @@ class TestControllerInjector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testInjectEventHandlerReferenceFactoryWithArgument() throws GenerationException {
|
void testInjectEventHandlerReferenceFactoryWithArgument() {
|
||||||
final var injector = new ControllerInjector(controllerInfo, ControllerFieldInjectionTypes.FACTORY, ControllerMethodsInjectionType.REFERENCE, sb, controllerFactoryPostAction);
|
final var injector = new ControllerInjector(controllerInfo, ControllerFieldInjectionType.FACTORY, com.github.gtache.fxml.compiler.ControllerMethodsInjectionType.REFERENCE, sb, controllerFactoryPostAction);
|
||||||
when(controllerInfo.handlerHasArgument(propertyValue.replace("#", ""))).thenReturn(true);
|
when(controllerInfo.handlerHasArgument(propertyValue.replace("#", ""))).thenReturn(true);
|
||||||
injector.injectEventHandlerControllerMethod(property, variable);
|
injector.injectEventHandlerControllerMethod(property, variable);
|
||||||
final var expected = " " + variable + "." + GenerationHelper.getSetMethod(property.name()) + "(controller::" + propertyValue.replace("#", "") + ");\n";
|
final var expected = " " + variable + "." + GenerationHelper.getSetMethod(property.name()) + "(controller::" + propertyValue.replace("#", "") + ");\n";
|
||||||
@@ -112,8 +103,8 @@ class TestControllerInjector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testInjectEventHandlerReflectionAssign() throws GenerationException {
|
void testInjectEventHandlerReflectionAssign() {
|
||||||
final var injector = new ControllerInjector(controllerInfo, ControllerFieldInjectionTypes.ASSIGN, ControllerMethodsInjectionType.REFLECTION, sb, controllerFactoryPostAction);
|
final var injector = new ControllerInjector(controllerInfo, ControllerFieldInjectionType.ASSIGN, com.github.gtache.fxml.compiler.ControllerMethodsInjectionType.REFLECTION, sb, controllerFactoryPostAction);
|
||||||
injector.injectEventHandlerControllerMethod(property, variable);
|
injector.injectEventHandlerControllerMethod(property, variable);
|
||||||
final var expected = " " + variable + "." + GenerationHelper.getSetMethod(property.name()) + "(e -> callEventHandlerMethod(\"" + propertyValue.replace("#", "") + "\", e));\n";
|
final var expected = " " + variable + "." + GenerationHelper.getSetMethod(property.name()) + "(e -> callEventHandlerMethod(\"" + propertyValue.replace("#", "") + "\", e));\n";
|
||||||
assertEquals(expected, sb.toString());
|
assertEquals(expected, sb.toString());
|
||||||
@@ -121,20 +112,8 @@ class TestControllerInjector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testInjectEventHandlerUnknownMethod() {
|
void testInjectCallbackReflectionSetters() {
|
||||||
final var injector = new ControllerInjector(controllerInfo, ControllerFieldInjectionTypes.ASSIGN, mock(InjectionType.class), sb, controllerFactoryPostAction);
|
final var injector = new ControllerInjector(controllerInfo, ControllerFieldInjectionType.ASSIGN, com.github.gtache.fxml.compiler.ControllerMethodsInjectionType.REFLECTION, sb, controllerFactoryPostAction);
|
||||||
assertThrows(GenerationException.class, () -> injector.injectEventHandlerControllerMethod(property, variable));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testInjectEventHandlerUnknownField() {
|
|
||||||
final var injector = new ControllerInjector(controllerInfo, mock(InjectionType.class), ControllerMethodsInjectionType.REFLECTION, sb, controllerFactoryPostAction);
|
|
||||||
assertThrows(GenerationException.class, () -> injector.injectEventHandlerControllerMethod(property, variable));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testInjectCallbackReflectionSetters() throws GenerationException {
|
|
||||||
final var injector = new ControllerInjector(controllerInfo, ControllerFieldInjectionTypes.ASSIGN, ControllerMethodsInjectionType.REFLECTION, sb, controllerFactoryPostAction);
|
|
||||||
injector.injectCallbackControllerMethod(property, variable, "clazz");
|
injector.injectCallbackControllerMethod(property, variable, "clazz");
|
||||||
final var expected = " " + variable + "." + GenerationHelper.getSetMethod(property.name()) + "(e -> callCallbackMethod(\"" + propertyValue.replace("#", "") + "\", e, clazz));\n";
|
final var expected = " " + variable + "." + GenerationHelper.getSetMethod(property.name()) + "(e -> callCallbackMethod(\"" + propertyValue.replace("#", "") + "\", e, clazz));\n";
|
||||||
assertEquals(expected, sb.toString());
|
assertEquals(expected, sb.toString());
|
||||||
@@ -142,12 +121,21 @@ class TestControllerInjector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testInjectCallbackReferenceFactory() throws GenerationException {
|
void testInjectCallbackReferenceFactory() {
|
||||||
final var injector = new ControllerInjector(controllerInfo, ControllerFieldInjectionTypes.FACTORY, ControllerMethodsInjectionType.REFERENCE, sb, controllerFactoryPostAction);
|
final var injector = new ControllerInjector(controllerInfo, ControllerFieldInjectionType.FACTORY, com.github.gtache.fxml.compiler.ControllerMethodsInjectionType.REFERENCE, sb, controllerFactoryPostAction);
|
||||||
injector.injectCallbackControllerMethod(property, variable, "clazz");
|
injector.injectCallbackControllerMethod(property, variable, "clazz");
|
||||||
final var expected = " " + variable + "." + GenerationHelper.getSetMethod(property.name()) + "(controller::" + propertyValue.replace("#", "") + ");\n";
|
final var expected = " " + variable + "." + GenerationHelper.getSetMethod(property.name()) + "(controller::" + propertyValue.replace("#", "") + ");\n";
|
||||||
assertEquals(1, controllerFactoryPostAction.size());
|
assertEquals(1, controllerFactoryPostAction.size());
|
||||||
assertEquals(expected, controllerFactoryPostAction.getFirst());
|
assertEquals(expected, controllerFactoryPostAction.getFirst());
|
||||||
assertEquals("", sb.toString());
|
assertEquals("", sb.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testIllegal() {
|
||||||
|
assertThrows(NullPointerException.class, () -> new ControllerInjector(null, ControllerFieldInjectionType.ASSIGN, ControllerMethodsInjectionType.REFERENCE, sb, controllerFactoryPostAction));
|
||||||
|
assertThrows(NullPointerException.class, () -> new ControllerInjector(controllerInfo, null, ControllerMethodsInjectionType.REFERENCE, sb, controllerFactoryPostAction));
|
||||||
|
assertThrows(NullPointerException.class, () -> new ControllerInjector(controllerInfo, ControllerFieldInjectionType.ASSIGN, null, sb, controllerFactoryPostAction));
|
||||||
|
assertThrows(NullPointerException.class, () -> new ControllerInjector(controllerInfo, ControllerFieldInjectionType.ASSIGN, ControllerMethodsInjectionType.REFERENCE, null, controllerFactoryPostAction));
|
||||||
|
assertThrows(NullPointerException.class, () -> new ControllerInjector(controllerInfo, ControllerFieldInjectionType.ASSIGN, ControllerMethodsInjectionType.REFERENCE, sb, null));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,134 @@
|
|||||||
package com.github.gtache.fxml.compiler.impl.internal;
|
package com.github.gtache.fxml.compiler.impl.internal;
|
||||||
|
|
||||||
|
import com.github.gtache.fxml.compiler.ControllerFieldInjectionType;
|
||||||
|
import com.github.gtache.fxml.compiler.GenerationException;
|
||||||
|
import com.github.gtache.fxml.compiler.parsing.ParsedProperty;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
import org.mockito.Mock;
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.SequencedCollection;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
import static org.mockito.ArgumentMatchers.anyInt;
|
||||||
|
import static org.mockito.ArgumentMatchers.anyString;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
class TestFieldSetter {
|
class TestFieldSetter {
|
||||||
|
|
||||||
|
private final HelperProvider helperProvider;
|
||||||
|
private final GenerationCompatibilityHelper compatibilityHelper;
|
||||||
|
private final StringBuilder sb;
|
||||||
|
private final SequencedCollection<String> controllerFactoryPostAction;
|
||||||
|
private final ParsedProperty property;
|
||||||
|
private final String propertyName;
|
||||||
|
private final String propertyValue;
|
||||||
|
private final String parentVariable;
|
||||||
|
|
||||||
|
TestFieldSetter(@Mock final HelperProvider helperProvider, @Mock final GenerationCompatibilityHelper compatibilityHelper,
|
||||||
|
@Mock final ParsedProperty property) {
|
||||||
|
this.helperProvider = Objects.requireNonNull(helperProvider);
|
||||||
|
this.compatibilityHelper = Objects.requireNonNull(compatibilityHelper);
|
||||||
|
this.property = Objects.requireNonNull(property);
|
||||||
|
this.propertyName = "propertyName";
|
||||||
|
this.propertyValue = "$controller.value";
|
||||||
|
this.parentVariable = "variable";
|
||||||
|
this.sb = new StringBuilder();
|
||||||
|
this.controllerFactoryPostAction = new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void beforeEach() {
|
||||||
|
when(helperProvider.getCompatibilityHelper()).thenReturn(compatibilityHelper);
|
||||||
|
when(compatibilityHelper.getStartVar(anyString(), anyInt())).then(i -> i.getArgument(0));
|
||||||
|
when(property.name()).thenReturn(propertyName);
|
||||||
|
when(property.value()).thenReturn(propertyValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testSetEventHandlerAssign() throws GenerationException {
|
||||||
|
final var setter = new FieldSetter(helperProvider, ControllerFieldInjectionType.ASSIGN, sb, controllerFactoryPostAction);
|
||||||
|
setter.setEventHandler(property, parentVariable);
|
||||||
|
final var expected = " " + parentVariable + ".setPropertyName(controller.value);\n";
|
||||||
|
assertEquals(expected, sb.toString());
|
||||||
|
assertTrue(controllerFactoryPostAction.isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testSetFieldAssignException() {
|
||||||
|
final var setter = new FieldSetter(helperProvider, ControllerFieldInjectionType.ASSIGN, sb, controllerFactoryPostAction);
|
||||||
|
when(property.value()).thenReturn("x.value");
|
||||||
|
assertThrows(GenerationException.class, () -> setter.setField(property, parentVariable, ""));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testSetFieldFactory() throws GenerationException {
|
||||||
|
final var setter = new FieldSetter(helperProvider, ControllerFieldInjectionType.FACTORY, sb, controllerFactoryPostAction);
|
||||||
|
setter.setField(property, parentVariable, "");
|
||||||
|
final var expected = " " + parentVariable + ".setPropertyName(controller.getValue());\n";
|
||||||
|
assertEquals("", sb.toString());
|
||||||
|
assertEquals(List.of(expected), controllerFactoryPostAction);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testSetFieldFactoryException() {
|
||||||
|
final var setter = new FieldSetter(helperProvider, ControllerFieldInjectionType.FACTORY, sb, controllerFactoryPostAction);
|
||||||
|
when(property.value()).thenReturn("x.value");
|
||||||
|
assertThrows(GenerationException.class, () -> setter.setField(property, parentVariable, ""));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testSetReflection() throws GenerationException {
|
||||||
|
final var setter = new FieldSetter(helperProvider, ControllerFieldInjectionType.REFLECTION, sb, controllerFactoryPostAction);
|
||||||
|
setter.setField(property, parentVariable, "javafx.scene.control.Button");
|
||||||
|
final var expected = """
|
||||||
|
try {
|
||||||
|
java.lang.reflect.Fieldfield = controller.getClass().getDeclaredField("value");
|
||||||
|
field.setAccessible(true);
|
||||||
|
final var value = (javafx.scene.control.Button) field.get(controller);
|
||||||
|
variable.setPropertyName(value);
|
||||||
|
} catch (final NoSuchFieldException | IllegalAccessException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
""";
|
||||||
|
assertEquals(expected, sb.toString());
|
||||||
|
assertTrue(controllerFactoryPostAction.isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testSetReflectionException() {
|
||||||
|
final var setter = new FieldSetter(helperProvider, ControllerFieldInjectionType.REFLECTION, sb, controllerFactoryPostAction);
|
||||||
|
when(property.value()).thenReturn("x.value");
|
||||||
|
assertThrows(GenerationException.class, () -> setter.setField(property, parentVariable, ""));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testSetFieldSetters() throws GenerationException {
|
||||||
|
final var setter = new FieldSetter(helperProvider, ControllerFieldInjectionType.SETTERS, sb, controllerFactoryPostAction);
|
||||||
|
setter.setField(property, parentVariable, "");
|
||||||
|
final var expected = " " + parentVariable + ".setPropertyName(controller.getValue());\n";
|
||||||
|
assertEquals(expected, sb.toString());
|
||||||
|
assertTrue(controllerFactoryPostAction.isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testSetFieldSettersException() {
|
||||||
|
final var setter = new FieldSetter(helperProvider, ControllerFieldInjectionType.SETTERS, sb, controllerFactoryPostAction);
|
||||||
|
when(property.value()).thenReturn("x.value");
|
||||||
|
assertThrows(GenerationException.class, () -> setter.setField(property, parentVariable, ""));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testIllegal() {
|
||||||
|
assertThrows(NullPointerException.class, () -> new FieldSetter(null, ControllerFieldInjectionType.ASSIGN, sb, controllerFactoryPostAction));
|
||||||
|
assertThrows(NullPointerException.class, () -> new FieldSetter(helperProvider, null, sb, controllerFactoryPostAction));
|
||||||
|
assertThrows(NullPointerException.class, () -> new FieldSetter(helperProvider, ControllerFieldInjectionType.ASSIGN, null, controllerFactoryPostAction));
|
||||||
|
assertThrows(NullPointerException.class, () -> new FieldSetter(helperProvider, ControllerFieldInjectionType.ASSIGN, sb, null));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,189 @@
|
|||||||
package com.github.gtache.fxml.compiler.impl.internal;
|
package com.github.gtache.fxml.compiler.impl.internal;
|
||||||
|
|
||||||
|
import com.github.gtache.fxml.compiler.GenerationException;
|
||||||
|
import com.github.gtache.fxml.compiler.parsing.ParsedObject;
|
||||||
|
import com.github.gtache.fxml.compiler.parsing.ParsedProperty;
|
||||||
|
import com.github.gtache.fxml.compiler.parsing.impl.ParsedPropertyImpl;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
import org.mockito.Mock;
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
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 java.util.SequencedCollection;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
import static org.mockito.ArgumentMatchers.anyInt;
|
||||||
|
import static org.mockito.ArgumentMatchers.anyString;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
class TestFontFormatter {
|
class TestFontFormatter {
|
||||||
|
|
||||||
|
private final HelperProvider helperProvider;
|
||||||
|
private final GenerationCompatibilityHelper compatibilityHelper;
|
||||||
|
private final URLFormatter urlFormatter;
|
||||||
|
private final StringBuilder sb;
|
||||||
|
private final ParsedObject parsedObject;
|
||||||
|
private final Map<String, ParsedProperty> attributes;
|
||||||
|
private final String variableName;
|
||||||
|
private final FontFormatter fontFormatter;
|
||||||
|
|
||||||
|
TestFontFormatter(@Mock final HelperProvider helperProvider,
|
||||||
|
@Mock final GenerationCompatibilityHelper compatibilityHelper, @Mock final URLFormatter urlFormatter,
|
||||||
|
@Mock final ParsedObject parsedObject) {
|
||||||
|
this.helperProvider = Objects.requireNonNull(helperProvider);
|
||||||
|
this.compatibilityHelper = Objects.requireNonNull(compatibilityHelper);
|
||||||
|
this.urlFormatter = Objects.requireNonNull(urlFormatter);
|
||||||
|
this.parsedObject = Objects.requireNonNull(parsedObject);
|
||||||
|
this.attributes = new HashMap<>();
|
||||||
|
this.variableName = "variable";
|
||||||
|
this.sb = new StringBuilder();
|
||||||
|
this.fontFormatter = new FontFormatter(helperProvider, sb);
|
||||||
|
}
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void beforeEach() throws GenerationException {
|
||||||
|
when(helperProvider.getCompatibilityHelper()).thenReturn(compatibilityHelper);
|
||||||
|
when(helperProvider.getURLFormatter()).thenReturn(urlFormatter);
|
||||||
|
when(parsedObject.attributes()).thenReturn(attributes);
|
||||||
|
when(parsedObject.children()).thenReturn(List.of());
|
||||||
|
when(parsedObject.properties()).thenReturn(new LinkedHashMap<>());
|
||||||
|
when(compatibilityHelper.getStartVar(anyString())).then(i -> i.getArgument(0));
|
||||||
|
when(compatibilityHelper.getStartVar(anyString(), anyInt())).then(i -> i.getArgument(0));
|
||||||
|
when(urlFormatter.formatURL(anyString())).then(i -> i.getArgument(0) + "url");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testHasChildren() {
|
||||||
|
when(parsedObject.children()).thenReturn(List.of(parsedObject));
|
||||||
|
assertThrows(GenerationException.class, () -> fontFormatter.formatFont(parsedObject, variableName));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testHasProperties() {
|
||||||
|
final var properties = new LinkedHashMap<ParsedProperty, SequencedCollection<ParsedObject>>();
|
||||||
|
properties.put(new ParsedPropertyImpl("str", null, ""), List.of(parsedObject));
|
||||||
|
when(parsedObject.properties()).thenReturn(properties);
|
||||||
|
assertThrows(GenerationException.class, () -> fontFormatter.formatFont(parsedObject, variableName));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testUnknownAttribute() {
|
||||||
|
attributes.put("unknown", new ParsedPropertyImpl("unknown", null, "value"));
|
||||||
|
assertThrows(GenerationException.class, () -> fontFormatter.formatFont(parsedObject, variableName));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testNoNameNorURL() {
|
||||||
|
attributes.put("size", new ParsedPropertyImpl("size", null, "14.0"));
|
||||||
|
attributes.put("style", new ParsedPropertyImpl("style", null, "Bold italic"));
|
||||||
|
attributes.put("fx:id", new ParsedPropertyImpl("fx:id", null, "id"));
|
||||||
|
assertThrows(GenerationException.class, () -> fontFormatter.formatFont(parsedObject, variableName));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testNameDefault() throws GenerationException {
|
||||||
|
attributes.put("name", new ParsedPropertyImpl("name", null, "Arial"));
|
||||||
|
final var expected = """
|
||||||
|
javafx.scene.text.Fontvariable = new javafx.scene.text.Font("Arial", 12.0);
|
||||||
|
""";
|
||||||
|
fontFormatter.formatFont(parsedObject, variableName);
|
||||||
|
assertEquals(expected, sb.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testName() throws GenerationException {
|
||||||
|
attributes.put("name", new ParsedPropertyImpl("name", null, "Arial"));
|
||||||
|
attributes.put("size", new ParsedPropertyImpl("size", null, "14.0"));
|
||||||
|
final var expected = """
|
||||||
|
javafx.scene.text.Fontvariable = new javafx.scene.text.Font("Arial", 14.0);
|
||||||
|
""";
|
||||||
|
fontFormatter.formatFont(parsedObject, variableName);
|
||||||
|
assertEquals(expected, sb.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testNameWeight() throws GenerationException {
|
||||||
|
attributes.put("name", new ParsedPropertyImpl("name", null, "Arial"));
|
||||||
|
attributes.put("size", new ParsedPropertyImpl("size", null, "14.0"));
|
||||||
|
attributes.put("style", new ParsedPropertyImpl("style", null, "bold"));
|
||||||
|
final var expected = """
|
||||||
|
javafx.scene.text.Fontvariable = new javafx.scene.text.Font("Arial", javafx.scene.text.FontWeight.BOLD, javafx.scene.text.FontPosture.REGULAR, 14.0);
|
||||||
|
""";
|
||||||
|
fontFormatter.formatFont(parsedObject, variableName);
|
||||||
|
assertEquals(expected, sb.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testNamePosture() throws GenerationException {
|
||||||
|
attributes.put("name", new ParsedPropertyImpl("name", null, "Arial"));
|
||||||
|
attributes.put("size", new ParsedPropertyImpl("size", null, "14.0"));
|
||||||
|
attributes.put("style", new ParsedPropertyImpl("style", null, "italic"));
|
||||||
|
final var expected = """
|
||||||
|
javafx.scene.text.Fontvariable = new javafx.scene.text.Font("Arial", javafx.scene.text.FontWeight.NORMAL, javafx.scene.text.FontPosture.ITALIC, 14.0);
|
||||||
|
""";
|
||||||
|
fontFormatter.formatFont(parsedObject, variableName);
|
||||||
|
assertEquals(expected, sb.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testNameStyle() throws GenerationException {
|
||||||
|
attributes.put("name", new ParsedPropertyImpl("name", null, "Arial"));
|
||||||
|
attributes.put("size", new ParsedPropertyImpl("size", null, "14.0"));
|
||||||
|
attributes.put("style", new ParsedPropertyImpl("style", null, "bold italic"));
|
||||||
|
final var expected = """
|
||||||
|
javafx.scene.text.Fontvariable = new javafx.scene.text.Font("Arial", javafx.scene.text.FontWeight.BOLD, javafx.scene.text.FontPosture.ITALIC, 14.0);
|
||||||
|
""";
|
||||||
|
fontFormatter.formatFont(parsedObject, variableName);
|
||||||
|
assertEquals(expected, sb.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testURL() throws GenerationException {
|
||||||
|
attributes.put("url", new ParsedPropertyImpl("url", null, "file:/urlValue"));
|
||||||
|
final var expected = """
|
||||||
|
final javafx.scene.text.Font variable;
|
||||||
|
try (java.io.InputStreamin = file:/urlValueurl.openStream()) {
|
||||||
|
variable = javafx.scene.text.Font.loadFont(in, 12.0);
|
||||||
|
} catch (final java.io.IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
""";
|
||||||
|
fontFormatter.formatFont(parsedObject, variableName);
|
||||||
|
assertEquals(expected, sb.toString());
|
||||||
|
verify(urlFormatter).formatURL("file:/urlValue");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testURLAllAttributes() throws GenerationException {
|
||||||
|
attributes.put("url", new ParsedPropertyImpl("url", null, "file:/urlValue"));
|
||||||
|
attributes.put("name", new ParsedPropertyImpl("name", null, "Arial"));
|
||||||
|
attributes.put("size", new ParsedPropertyImpl("size", null, "14.0"));
|
||||||
|
attributes.put("style", new ParsedPropertyImpl("style", null, "bold italic"));
|
||||||
|
final var expected = """
|
||||||
|
final javafx.scene.text.Font variable;
|
||||||
|
try (java.io.InputStreamin = file:/urlValueurl.openStream()) {
|
||||||
|
variable = javafx.scene.text.Font.loadFont(in, 14.0);
|
||||||
|
} catch (final java.io.IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
""";
|
||||||
|
fontFormatter.formatFont(parsedObject, variableName);
|
||||||
|
assertEquals(expected, sb.toString());
|
||||||
|
verify(urlFormatter).formatURL("file:/urlValue");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testIllegal() {
|
||||||
|
assertThrows(NullPointerException.class, () -> new FontFormatter(null, sb));
|
||||||
|
assertThrows(NullPointerException.class, () -> new FontFormatter(helperProvider, null));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import org.mockito.junit.jupiter.MockitoExtension;
|
|||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
@@ -123,4 +124,10 @@ class TestGenerationCompatibilityHelper {
|
|||||||
when(compatibility.useCollectionsOf()).thenReturn(false);
|
when(compatibility.useCollectionsOf()).thenReturn(false);
|
||||||
assertEquals("java.util.Arrays.asList(", compatibilityHelper.getListOf());
|
assertEquals("java.util.Arrays.asList(", compatibilityHelper.getListOf());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testIllegal() {
|
||||||
|
assertThrows(NullPointerException.class, () -> new GenerationCompatibilityHelper(null, compatibility));
|
||||||
|
assertThrows(NullPointerException.class, () -> new GenerationCompatibilityHelper(helperProvider, null));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,5 @@
|
|||||||
package com.github.gtache.fxml.compiler.impl.internal;
|
package com.github.gtache.fxml.compiler.impl.internal;
|
||||||
|
|
||||||
import com.github.gtache.fxml.compiler.ControllerFieldInfo;
|
|
||||||
import com.github.gtache.fxml.compiler.ControllerInfo;
|
|
||||||
import com.github.gtache.fxml.compiler.GenerationRequest;
|
|
||||||
import com.github.gtache.fxml.compiler.parsing.ParsedObject;
|
import com.github.gtache.fxml.compiler.parsing.ParsedObject;
|
||||||
import com.github.gtache.fxml.compiler.parsing.ParsedProperty;
|
import com.github.gtache.fxml.compiler.parsing.ParsedProperty;
|
||||||
import com.github.gtache.fxml.compiler.parsing.impl.ParsedPropertyImpl;
|
import com.github.gtache.fxml.compiler.parsing.impl.ParsedPropertyImpl;
|
||||||
@@ -23,29 +20,15 @@ import static org.mockito.Mockito.when;
|
|||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
class TestGenerationHelper {
|
class TestGenerationHelper {
|
||||||
|
|
||||||
private final GenerationProgress progress;
|
private final ParsedObject parsedObject;
|
||||||
private final GenerationRequest request;
|
|
||||||
private final ControllerInfo controllerInfo;
|
|
||||||
private final ControllerFieldInfo fieldInfo;
|
|
||||||
private final Map<String, VariableInfo> idToVariableInfo;
|
|
||||||
private final String variableName;
|
|
||||||
private final ParsedObject object;
|
|
||||||
private final Map<String, ParsedProperty> attributes;
|
private final Map<String, ParsedProperty> attributes;
|
||||||
private final String className;
|
private final String className;
|
||||||
private final ParsedProperty property;
|
private final ParsedProperty property;
|
||||||
private final String propertyName;
|
private final String propertyName;
|
||||||
|
|
||||||
TestGenerationHelper(@Mock final GenerationProgress progress, @Mock final GenerationRequest request,
|
TestGenerationHelper(@Mock final ParsedObject parsedObject, @Mock final ParsedProperty property) {
|
||||||
@Mock final ControllerInfo controllerInfo, @Mock final ControllerFieldInfo fieldInfo,
|
this.parsedObject = Objects.requireNonNull(parsedObject);
|
||||||
@Mock final ParsedObject object, @Mock final ParsedProperty property) {
|
|
||||||
this.progress = Objects.requireNonNull(progress);
|
|
||||||
this.request = Objects.requireNonNull(request);
|
|
||||||
this.controllerInfo = Objects.requireNonNull(controllerInfo);
|
|
||||||
this.fieldInfo = Objects.requireNonNull(fieldInfo);
|
|
||||||
this.object = Objects.requireNonNull(object);
|
|
||||||
this.property = Objects.requireNonNull(property);
|
this.property = Objects.requireNonNull(property);
|
||||||
this.idToVariableInfo = new HashMap<>();
|
|
||||||
this.variableName = "variable";
|
|
||||||
this.attributes = new HashMap<>();
|
this.attributes = new HashMap<>();
|
||||||
this.className = "java.lang.String";
|
this.className = "java.lang.String";
|
||||||
this.propertyName = "property";
|
this.propertyName = "property";
|
||||||
@@ -53,17 +36,14 @@ class TestGenerationHelper {
|
|||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
void beforeEach() {
|
void beforeEach() {
|
||||||
when(progress.request()).thenReturn(request);
|
when(parsedObject.attributes()).thenReturn(attributes);
|
||||||
when(request.controllerInfo()).thenReturn(controllerInfo);
|
when(parsedObject.className()).thenReturn(className);
|
||||||
when(object.attributes()).thenReturn(attributes);
|
|
||||||
when(object.className()).thenReturn(className);
|
|
||||||
when(property.name()).thenReturn(propertyName);
|
when(property.name()).thenReturn(propertyName);
|
||||||
when(progress.idToVariableInfo()).thenReturn(idToVariableInfo);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testGetVariablePrefixObject() {
|
void testGetVariablePrefixObject() {
|
||||||
assertEquals("string", GenerationHelper.getVariablePrefix(object));
|
assertEquals("string", GenerationHelper.getVariablePrefix(parsedObject));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -97,6 +77,6 @@ class TestGenerationHelper {
|
|||||||
attributes.put("b", new ParsedPropertyImpl("b", null, "valueB"));
|
attributes.put("b", new ParsedPropertyImpl("b", null, "valueB"));
|
||||||
attributes.put("c", new ParsedPropertyImpl("c", null, "valueC"));
|
attributes.put("c", new ParsedPropertyImpl("c", null, "valueC"));
|
||||||
final var expected = List.of(attributes.get("a"), attributes.get("b"), attributes.get("c"));
|
final var expected = List.of(attributes.get("a"), attributes.get("b"), attributes.get("c"));
|
||||||
assertEquals(expected, GenerationHelper.getSortedAttributes(object));
|
assertEquals(expected, GenerationHelper.getSortedAttributes(parsedObject));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,13 +7,8 @@ import org.mockito.Mock;
|
|||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.SequencedCollection;
|
import java.util.SequencedCollection;
|
||||||
import java.util.SequencedMap;
|
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
|
||||||
|
|
||||||
import static java.util.Objects.requireNonNull;
|
import static java.util.Objects.requireNonNull;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
@@ -23,51 +18,27 @@ import static org.junit.jupiter.api.Assertions.assertThrows;
|
|||||||
class TestGenerationProgress {
|
class TestGenerationProgress {
|
||||||
|
|
||||||
private final GenerationRequest request;
|
private final GenerationRequest request;
|
||||||
private final VariableInfo variableInfo;
|
|
||||||
private final Map<String, VariableInfo> idToVariableInfo;
|
|
||||||
private final Map<String, AtomicInteger> variableNameCounters;
|
|
||||||
private final SequencedMap<String, String> controllerClassToVariable;
|
|
||||||
private final SequencedCollection<String> controllerFactoryPostAction;
|
private final SequencedCollection<String> controllerFactoryPostAction;
|
||||||
private final StringBuilder sb;
|
private final StringBuilder sb;
|
||||||
private final GenerationProgress progress;
|
private final GenerationProgress progress;
|
||||||
|
|
||||||
TestGenerationProgress(@Mock final GenerationRequest request, @Mock final VariableInfo variableInfo) {
|
TestGenerationProgress(@Mock final GenerationRequest request) {
|
||||||
this.request = requireNonNull(request);
|
this.request = requireNonNull(request);
|
||||||
this.variableInfo = requireNonNull(variableInfo);
|
|
||||||
this.idToVariableInfo = new HashMap<>();
|
|
||||||
idToVariableInfo.put("var1", variableInfo);
|
|
||||||
this.controllerClassToVariable = new LinkedHashMap<String, String>();
|
|
||||||
controllerClassToVariable.put("bla", "var1");
|
|
||||||
controllerClassToVariable.put("bla2", "var2");
|
|
||||||
this.variableNameCounters = new HashMap<>();
|
|
||||||
variableNameCounters.put("var", new AtomicInteger(0));
|
|
||||||
this.controllerFactoryPostAction = new ArrayList<>();
|
this.controllerFactoryPostAction = new ArrayList<>();
|
||||||
controllerFactoryPostAction.add("bla");
|
controllerFactoryPostAction.add("bla");
|
||||||
this.sb = new StringBuilder("test");
|
this.sb = new StringBuilder("test");
|
||||||
this.progress = new GenerationProgress(request, idToVariableInfo, variableNameCounters, controllerClassToVariable, controllerFactoryPostAction, sb);
|
this.progress = new GenerationProgress(request, controllerFactoryPostAction, sb);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testGetters() {
|
void testGetters() {
|
||||||
assertEquals(request, progress.request());
|
assertEquals(request, progress.request());
|
||||||
assertEquals(idToVariableInfo, progress.idToVariableInfo());
|
|
||||||
assertEquals(variableNameCounters, progress.variableNameCounters());
|
|
||||||
assertEquals(controllerClassToVariable, progress.controllerClassToVariable());
|
|
||||||
assertEquals(controllerFactoryPostAction, progress.controllerFactoryPostAction());
|
assertEquals(controllerFactoryPostAction, progress.controllerFactoryPostAction());
|
||||||
assertEquals(sb, progress.stringBuilder());
|
assertEquals(sb, progress.stringBuilder());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testConstructorDoesntCopy() {
|
void testConstructorDoesntCopy() {
|
||||||
idToVariableInfo.clear();
|
|
||||||
assertEquals(idToVariableInfo, progress.idToVariableInfo());
|
|
||||||
|
|
||||||
variableNameCounters.clear();
|
|
||||||
assertEquals(variableNameCounters, progress.variableNameCounters());
|
|
||||||
|
|
||||||
controllerClassToVariable.clear();
|
|
||||||
assertEquals(controllerClassToVariable, progress.controllerClassToVariable());
|
|
||||||
|
|
||||||
controllerFactoryPostAction.clear();
|
controllerFactoryPostAction.clear();
|
||||||
assertEquals(controllerFactoryPostAction, progress.controllerFactoryPostAction());
|
assertEquals(controllerFactoryPostAction, progress.controllerFactoryPostAction());
|
||||||
|
|
||||||
@@ -77,15 +48,6 @@ class TestGenerationProgress {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testCanModify() {
|
void testCanModify() {
|
||||||
progress.idToVariableInfo().put("var3", variableInfo);
|
|
||||||
assertEquals(idToVariableInfo, progress.idToVariableInfo());
|
|
||||||
|
|
||||||
progress.variableNameCounters().put("var5", new AtomicInteger(0));
|
|
||||||
assertEquals(variableNameCounters, progress.variableNameCounters());
|
|
||||||
|
|
||||||
progress.controllerClassToVariable().put("bla3", "var3");
|
|
||||||
assertEquals(controllerClassToVariable, progress.controllerClassToVariable());
|
|
||||||
|
|
||||||
progress.controllerFactoryPostAction().add("bla2");
|
progress.controllerFactoryPostAction().add("bla2");
|
||||||
assertEquals(controllerFactoryPostAction, progress.controllerFactoryPostAction());
|
assertEquals(controllerFactoryPostAction, progress.controllerFactoryPostAction());
|
||||||
|
|
||||||
@@ -97,29 +59,15 @@ class TestGenerationProgress {
|
|||||||
void testOtherConstructor() {
|
void testOtherConstructor() {
|
||||||
final var progress2 = new GenerationProgress(request);
|
final var progress2 = new GenerationProgress(request);
|
||||||
assertEquals(request, progress2.request());
|
assertEquals(request, progress2.request());
|
||||||
assertEquals(Map.of(), progress2.idToVariableInfo());
|
|
||||||
assertEquals(Map.of(), progress2.variableNameCounters());
|
|
||||||
assertEquals(Map.of(), progress2.controllerClassToVariable());
|
|
||||||
assertEquals(List.of(), progress2.controllerFactoryPostAction());
|
assertEquals(List.of(), progress2.controllerFactoryPostAction());
|
||||||
assertEquals("", progress2.stringBuilder().toString());
|
assertEquals("", progress2.stringBuilder().toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
void testGetNextVariableName() {
|
|
||||||
assertEquals("var0", progress.getNextVariableName("var"));
|
|
||||||
assertEquals("var1", progress.getNextVariableName("var"));
|
|
||||||
assertEquals("var2", progress.getNextVariableName("var"));
|
|
||||||
assertEquals("bla0", progress.getNextVariableName("bla"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testIllegal() {
|
void testIllegal() {
|
||||||
assertThrows(NullPointerException.class, () -> new GenerationProgress(null, idToVariableInfo, variableNameCounters, controllerClassToVariable, controllerFactoryPostAction, sb));
|
assertThrows(NullPointerException.class, () -> new GenerationProgress(null, controllerFactoryPostAction, sb));
|
||||||
assertThrows(NullPointerException.class, () -> new GenerationProgress(request, null, variableNameCounters, controllerClassToVariable, controllerFactoryPostAction, sb));
|
assertThrows(NullPointerException.class, () -> new GenerationProgress(request, null, sb));
|
||||||
assertThrows(NullPointerException.class, () -> new GenerationProgress(request, idToVariableInfo, null, controllerClassToVariable, controllerFactoryPostAction, sb));
|
assertThrows(NullPointerException.class, () -> new GenerationProgress(request, controllerFactoryPostAction, null));
|
||||||
assertThrows(NullPointerException.class, () -> new GenerationProgress(request, idToVariableInfo, variableNameCounters, null, controllerFactoryPostAction, sb));
|
|
||||||
assertThrows(NullPointerException.class, () -> new GenerationProgress(request, idToVariableInfo, variableNameCounters, controllerClassToVariable, null, sb));
|
|
||||||
assertThrows(NullPointerException.class, () -> new GenerationProgress(request, idToVariableInfo, variableNameCounters, controllerClassToVariable, controllerFactoryPostAction, null));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,217 @@
|
|||||||
package com.github.gtache.fxml.compiler.impl.internal;
|
package com.github.gtache.fxml.compiler.impl.internal;
|
||||||
|
|
||||||
|
import com.github.gtache.fxml.compiler.ControllerFieldInjectionType;
|
||||||
|
import com.github.gtache.fxml.compiler.ControllerMethodsInjectionType;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
import org.mockito.Mock;
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
|
||||||
|
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.anyInt;
|
||||||
|
import static org.mockito.ArgumentMatchers.anyString;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
class TestHelperMethodsFormatter {
|
class TestHelperMethodsFormatter {
|
||||||
|
|
||||||
|
private final HelperProvider helperProvider;
|
||||||
|
private final GenerationCompatibilityHelper compatibilityHelper;
|
||||||
|
private final StringBuilder sb;
|
||||||
|
|
||||||
|
TestHelperMethodsFormatter(@Mock final HelperProvider helperProvider, @Mock final GenerationCompatibilityHelper compatibilityHelper) {
|
||||||
|
this.helperProvider = Objects.requireNonNull(helperProvider);
|
||||||
|
this.compatibilityHelper = Objects.requireNonNull(compatibilityHelper);
|
||||||
|
this.sb = new StringBuilder();
|
||||||
|
}
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void beforeEach() {
|
||||||
|
when(helperProvider.getCompatibilityHelper()).thenReturn(compatibilityHelper);
|
||||||
|
when(compatibilityHelper.getStartVar(anyString())).then(i -> i.getArgument(0));
|
||||||
|
when(compatibilityHelper.getStartVar(anyString(), anyInt())).then(i -> i.getArgument(0));
|
||||||
|
when(compatibilityHelper.getListOf()).thenReturn("listof(");
|
||||||
|
when(compatibilityHelper.getGetFirst()).thenReturn(".getFirst()");
|
||||||
|
when(compatibilityHelper.getToList()).thenReturn(".toList()");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testMethodReflection() {
|
||||||
|
final var helperMethodsFormatter = new HelperMethodsFormatter(helperProvider, ControllerFieldInjectionType.ASSIGN, ControllerMethodsInjectionType.REFLECTION, sb);
|
||||||
|
final var expected = """
|
||||||
|
private <T extends javafx.event.Event> void callEventHandlerMethod(final String methodName, final T event) {
|
||||||
|
try {
|
||||||
|
final java.lang.reflect.Method method;
|
||||||
|
java.util.List<java.lang.reflect.Method>methods = java.util.Arrays.stream(controller.getClass().getDeclaredMethods())
|
||||||
|
.filter(m -> m.getName().equals(methodName)).toList();
|
||||||
|
if (methods.size() > 1) {
|
||||||
|
java.util.List<java.lang.reflect.Method>eventMethods = methods.stream().filter(m ->
|
||||||
|
m.getParameterCount() == 1 && javafx.event.Event.class.isAssignableFrom(m.getParameterTypes()[0])).toList();
|
||||||
|
if (eventMethods.size() == 1) {
|
||||||
|
method = eventMethods.getFirst();
|
||||||
|
} else {
|
||||||
|
java.util.List<java.lang.reflect.Method>emptyMethods = methods.stream().filter(m -> m.getParameterCount() == 0).toList();
|
||||||
|
if (emptyMethods.size() == 1) {
|
||||||
|
method = emptyMethods.getFirst();
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("Multiple matching methods for " + methodName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (methods.size() == 1) {
|
||||||
|
method = methods.getFirst();
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("No matching method for " + methodName);
|
||||||
|
}
|
||||||
|
method.setAccessible(true);
|
||||||
|
if (method.getParameterCount() == 0) {
|
||||||
|
method.invoke(controller);
|
||||||
|
} else {
|
||||||
|
method.invoke(controller, event);
|
||||||
|
}
|
||||||
|
} catch (final IllegalAccessException | java.lang.reflect.InvocationTargetException ex) {
|
||||||
|
throw new RuntimeException("Error using reflection on " + methodName, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T, U> U callCallbackMethod(final String methodName, final T value, final Class<T> clazz) {
|
||||||
|
try {
|
||||||
|
final java.lang.reflect.Method method;
|
||||||
|
java.util.List<java.lang.reflect.Method>methods = java.util.Arrays.stream(controller.getClass().getDeclaredMethods())
|
||||||
|
.filter(m -> m.getName().equals(methodName)).toList();
|
||||||
|
if (methods.size() > 1) {
|
||||||
|
java.util.List<java.lang.reflect.Method>eventMethods = methods.stream().filter(m ->
|
||||||
|
m.getParameterCount() == 2 && clazz.isAssignableFrom(m.getParameterTypes()[1])).toList();
|
||||||
|
if (eventMethods.size() == 1) {
|
||||||
|
method = eventMethods.getFirst();
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("Multiple matching methods for " + methodName);
|
||||||
|
}
|
||||||
|
} else if (methods.size() == 1) {
|
||||||
|
method = methods.getFirst();
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("No matching method for " + methodName);
|
||||||
|
}
|
||||||
|
method.setAccessible(true);
|
||||||
|
return (U) method.invoke(controller, value);
|
||||||
|
} catch (final IllegalAccessException | java.lang.reflect.InvocationTargetException ex) {
|
||||||
|
throw new RuntimeException("Error using reflection on " + methodName, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
""";
|
||||||
|
helperMethodsFormatter.formatHelperMethods();
|
||||||
|
assertEquals(expected, sb.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFieldReflection() {
|
||||||
|
final var helperMethodsFormatter = new HelperMethodsFormatter(helperProvider, ControllerFieldInjectionType.REFLECTION, ControllerMethodsInjectionType.REFERENCE, sb);
|
||||||
|
final var expected = """
|
||||||
|
private <T> void injectField(final String fieldName, final T object) {
|
||||||
|
try {
|
||||||
|
java.lang.reflect.Fieldfield = controller.getClass().getDeclaredField(fieldName);
|
||||||
|
field.setAccessible(true);
|
||||||
|
field.set(controller, object);
|
||||||
|
} catch (final NoSuchFieldException | IllegalAccessException e) {
|
||||||
|
throw new RuntimeException("Error using reflection on " + fieldName, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
""";
|
||||||
|
helperMethodsFormatter.formatHelperMethods();
|
||||||
|
assertEquals(expected, sb.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testNoReflection() {
|
||||||
|
final var helperMethodsFormatter = new HelperMethodsFormatter(helperProvider, ControllerFieldInjectionType.FACTORY, ControllerMethodsInjectionType.REFERENCE, sb);
|
||||||
|
helperMethodsFormatter.formatHelperMethods();
|
||||||
|
assertEquals("", sb.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testBothReflection() {
|
||||||
|
final var helperMethodsFormatter = new HelperMethodsFormatter(helperProvider, ControllerFieldInjectionType.REFLECTION, ControllerMethodsInjectionType.REFLECTION, sb);
|
||||||
|
final var expected = """
|
||||||
|
private <T extends javafx.event.Event> void callEventHandlerMethod(final String methodName, final T event) {
|
||||||
|
try {
|
||||||
|
final java.lang.reflect.Method method;
|
||||||
|
java.util.List<java.lang.reflect.Method>methods = java.util.Arrays.stream(controller.getClass().getDeclaredMethods())
|
||||||
|
.filter(m -> m.getName().equals(methodName)).toList();
|
||||||
|
if (methods.size() > 1) {
|
||||||
|
java.util.List<java.lang.reflect.Method>eventMethods = methods.stream().filter(m ->
|
||||||
|
m.getParameterCount() == 1 && javafx.event.Event.class.isAssignableFrom(m.getParameterTypes()[0])).toList();
|
||||||
|
if (eventMethods.size() == 1) {
|
||||||
|
method = eventMethods.getFirst();
|
||||||
|
} else {
|
||||||
|
java.util.List<java.lang.reflect.Method>emptyMethods = methods.stream().filter(m -> m.getParameterCount() == 0).toList();
|
||||||
|
if (emptyMethods.size() == 1) {
|
||||||
|
method = emptyMethods.getFirst();
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("Multiple matching methods for " + methodName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (methods.size() == 1) {
|
||||||
|
method = methods.getFirst();
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("No matching method for " + methodName);
|
||||||
|
}
|
||||||
|
method.setAccessible(true);
|
||||||
|
if (method.getParameterCount() == 0) {
|
||||||
|
method.invoke(controller);
|
||||||
|
} else {
|
||||||
|
method.invoke(controller, event);
|
||||||
|
}
|
||||||
|
} catch (final IllegalAccessException | java.lang.reflect.InvocationTargetException ex) {
|
||||||
|
throw new RuntimeException("Error using reflection on " + methodName, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T, U> U callCallbackMethod(final String methodName, final T value, final Class<T> clazz) {
|
||||||
|
try {
|
||||||
|
final java.lang.reflect.Method method;
|
||||||
|
java.util.List<java.lang.reflect.Method>methods = java.util.Arrays.stream(controller.getClass().getDeclaredMethods())
|
||||||
|
.filter(m -> m.getName().equals(methodName)).toList();
|
||||||
|
if (methods.size() > 1) {
|
||||||
|
java.util.List<java.lang.reflect.Method>eventMethods = methods.stream().filter(m ->
|
||||||
|
m.getParameterCount() == 2 && clazz.isAssignableFrom(m.getParameterTypes()[1])).toList();
|
||||||
|
if (eventMethods.size() == 1) {
|
||||||
|
method = eventMethods.getFirst();
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("Multiple matching methods for " + methodName);
|
||||||
|
}
|
||||||
|
} else if (methods.size() == 1) {
|
||||||
|
method = methods.getFirst();
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("No matching method for " + methodName);
|
||||||
|
}
|
||||||
|
method.setAccessible(true);
|
||||||
|
return (U) method.invoke(controller, value);
|
||||||
|
} catch (final IllegalAccessException | java.lang.reflect.InvocationTargetException ex) {
|
||||||
|
throw new RuntimeException("Error using reflection on " + methodName, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private <T> void injectField(final String fieldName, final T object) {
|
||||||
|
try {
|
||||||
|
java.lang.reflect.Fieldfield = controller.getClass().getDeclaredField(fieldName);
|
||||||
|
field.setAccessible(true);
|
||||||
|
field.set(controller, object);
|
||||||
|
} catch (final NoSuchFieldException | IllegalAccessException e) {
|
||||||
|
throw new RuntimeException("Error using reflection on " + fieldName, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
""";
|
||||||
|
helperMethodsFormatter.formatHelperMethods();
|
||||||
|
assertEquals(expected, sb.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testIllegal() {
|
||||||
|
assertThrows(NullPointerException.class, () -> new HelperMethodsFormatter(null, ControllerFieldInjectionType.FACTORY, ControllerMethodsInjectionType.REFERENCE, sb));
|
||||||
|
assertThrows(NullPointerException.class, () -> new HelperMethodsFormatter(helperProvider, null, ControllerMethodsInjectionType.REFERENCE, sb));
|
||||||
|
assertThrows(NullPointerException.class, () -> new HelperMethodsFormatter(helperProvider, ControllerFieldInjectionType.FACTORY, null, sb));
|
||||||
|
assertThrows(NullPointerException.class, () -> new HelperMethodsFormatter(helperProvider, ControllerFieldInjectionType.FACTORY, ControllerMethodsInjectionType.REFERENCE, null));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,169 @@
|
|||||||
|
package com.github.gtache.fxml.compiler.impl.internal;
|
||||||
|
|
||||||
|
import com.github.gtache.fxml.compiler.ControllerFieldInjectionType;
|
||||||
|
import com.github.gtache.fxml.compiler.ControllerInfo;
|
||||||
|
import com.github.gtache.fxml.compiler.ControllerInjectionType;
|
||||||
|
import com.github.gtache.fxml.compiler.ControllerMethodsInjectionType;
|
||||||
|
import com.github.gtache.fxml.compiler.GenerationParameters;
|
||||||
|
import com.github.gtache.fxml.compiler.GenerationRequest;
|
||||||
|
import com.github.gtache.fxml.compiler.ResourceBundleInjectionType;
|
||||||
|
import com.github.gtache.fxml.compiler.compatibility.GenerationCompatibility;
|
||||||
|
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.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertSame;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
@ExtendWith(MockitoExtension.class)
|
||||||
|
class TestHelperProvider {
|
||||||
|
private final GenerationProgress progress;
|
||||||
|
private final GenerationRequest request;
|
||||||
|
private final GenerationParameters parameters;
|
||||||
|
private final GenerationCompatibility compatibility;
|
||||||
|
private final ControllerInjectionType controllerInjectionType;
|
||||||
|
private final ControllerFieldInjectionType fieldInjectionType;
|
||||||
|
private final ControllerMethodsInjectionType methodInjectionType;
|
||||||
|
private final ResourceBundleInjectionType resourceInjectionType;
|
||||||
|
private final ControllerInfo controllerInfo;
|
||||||
|
private final StringBuilder sb;
|
||||||
|
private final List<String> controllerFactoryPostAction;
|
||||||
|
private final HelperProvider helperProvider;
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void beforeEach() {
|
||||||
|
when(progress.request()).thenReturn(request);
|
||||||
|
when(request.parameters()).thenReturn(parameters);
|
||||||
|
when(request.controllerInfo()).thenReturn(controllerInfo);
|
||||||
|
when(parameters.controllerInjectionType()).thenReturn(controllerInjectionType);
|
||||||
|
when(parameters.fieldInjectionType()).thenReturn(fieldInjectionType);
|
||||||
|
when(parameters.methodInjectionType()).thenReturn(methodInjectionType);
|
||||||
|
when(parameters.resourceInjectionType()).thenReturn(resourceInjectionType);
|
||||||
|
when(parameters.compatibility()).thenReturn(compatibility);
|
||||||
|
when(progress.stringBuilder()).thenReturn(sb);
|
||||||
|
when(progress.controllerFactoryPostAction()).thenReturn(controllerFactoryPostAction);
|
||||||
|
}
|
||||||
|
|
||||||
|
TestHelperProvider(@Mock final GenerationProgress progress, @Mock final GenerationRequest request, @Mock final GenerationCompatibility compatibility,
|
||||||
|
@Mock final GenerationParameters parameters, @Mock final ControllerInfo controllerInfo) {
|
||||||
|
this.progress = Objects.requireNonNull(progress);
|
||||||
|
this.request = Objects.requireNonNull(request);
|
||||||
|
this.compatibility = Objects.requireNonNull(compatibility);
|
||||||
|
this.parameters = Objects.requireNonNull(parameters);
|
||||||
|
this.controllerInfo = Objects.requireNonNull(controllerInfo);
|
||||||
|
this.controllerInjectionType = ControllerInjectionType.INSTANCE;
|
||||||
|
this.fieldInjectionType = ControllerFieldInjectionType.FACTORY;
|
||||||
|
this.methodInjectionType = ControllerMethodsInjectionType.REFLECTION;
|
||||||
|
this.resourceInjectionType = ResourceBundleInjectionType.CONSTRUCTOR;
|
||||||
|
this.sb = new StringBuilder();
|
||||||
|
this.controllerFactoryPostAction = List.of();
|
||||||
|
this.helperProvider = new HelperProvider(progress);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testControllerInjector() {
|
||||||
|
final var injector = helperProvider.getControllerInjector();
|
||||||
|
assertSame(injector, helperProvider.getControllerInjector());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testGetFieldSetter() {
|
||||||
|
final var fieldSetter = helperProvider.getFieldSetter();
|
||||||
|
assertSame(fieldSetter, helperProvider.getFieldSetter());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testGetFontFormatter() {
|
||||||
|
final var fontFormatter = helperProvider.getFontFormatter();
|
||||||
|
assertSame(fontFormatter, helperProvider.getFontFormatter());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testGetCompatibilityHelper() {
|
||||||
|
final var compatibilityHelper = helperProvider.getCompatibilityHelper();
|
||||||
|
assertSame(compatibilityHelper, helperProvider.getCompatibilityHelper());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testGetHelperMethodsFormatter() {
|
||||||
|
final var helperMethodsFormatter = helperProvider.getHelperMethodsFormatter();
|
||||||
|
assertSame(helperMethodsFormatter, helperProvider.getHelperMethodsFormatter());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testGetImageFormatter() {
|
||||||
|
final var imageFormatter = helperProvider.getImageFormatter();
|
||||||
|
assertSame(imageFormatter, helperProvider.getImageFormatter());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testGetInitializationFormatter() {
|
||||||
|
final var initializationFormatter = helperProvider.getInitializationFormatter();
|
||||||
|
assertSame(initializationFormatter, helperProvider.getInitializationFormatter());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testGetLoadMethodFormatter() {
|
||||||
|
final var loadMethodFormatter = helperProvider.getLoadMethodFormatter();
|
||||||
|
assertSame(loadMethodFormatter, helperProvider.getLoadMethodFormatter());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testGetObjectFormatter() {
|
||||||
|
final var objectFormatter = helperProvider.getObjectFormatter();
|
||||||
|
assertSame(objectFormatter, helperProvider.getObjectFormatter());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testGetPropertyFormatter() {
|
||||||
|
final var propertyFormatter = helperProvider.getPropertyFormatter();
|
||||||
|
assertSame(propertyFormatter, helperProvider.getPropertyFormatter());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testGetReflectionHelper() {
|
||||||
|
final var reflectionHelper = helperProvider.getReflectionHelper();
|
||||||
|
assertSame(reflectionHelper, helperProvider.getReflectionHelper());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testGetSceneFormatter() {
|
||||||
|
final var sceneFormatter = helperProvider.getSceneFormatter();
|
||||||
|
assertSame(sceneFormatter, helperProvider.getSceneFormatter());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testGetTriangleMeshFormatter() {
|
||||||
|
final var triangleMeshFormatter = helperProvider.getTriangleMeshFormatter();
|
||||||
|
assertSame(triangleMeshFormatter, helperProvider.getTriangleMeshFormatter());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testGetURLFormatter() {
|
||||||
|
final var urlFormatter = helperProvider.getURLFormatter();
|
||||||
|
assertSame(urlFormatter, helperProvider.getURLFormatter());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testGetValueFormatter() {
|
||||||
|
final var valueFormatter = helperProvider.getValueFormatter();
|
||||||
|
assertSame(valueFormatter, helperProvider.getValueFormatter());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testGetVariableProvider() {
|
||||||
|
final var variableProvider = helperProvider.getVariableProvider();
|
||||||
|
assertSame(variableProvider, helperProvider.getVariableProvider());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void getWebViewFormatter() {
|
||||||
|
final var webViewFormatter = helperProvider.getWebViewFormatter();
|
||||||
|
assertSame(webViewFormatter, helperProvider.getWebViewFormatter());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,8 +1,173 @@
|
|||||||
package com.github.gtache.fxml.compiler.impl.internal;
|
package com.github.gtache.fxml.compiler.impl.internal;
|
||||||
|
|
||||||
|
import com.github.gtache.fxml.compiler.GenerationException;
|
||||||
|
import com.github.gtache.fxml.compiler.parsing.ParsedObject;
|
||||||
|
import com.github.gtache.fxml.compiler.parsing.ParsedProperty;
|
||||||
|
import com.github.gtache.fxml.compiler.parsing.impl.ParsedPropertyImpl;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
import org.mockito.Mock;
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
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 java.util.SequencedCollection;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
import static org.mockito.ArgumentMatchers.anyString;
|
||||||
|
import static org.mockito.Mockito.*;
|
||||||
|
|
||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
class TestImageFormatter {
|
class TestImageFormatter {
|
||||||
|
|
||||||
|
private final HelperProvider helperProvider;
|
||||||
|
private final GenerationCompatibilityHelper compatibilityHelper;
|
||||||
|
private final URLFormatter urlFormatter;
|
||||||
|
private final VariableProvider variableProvider;
|
||||||
|
private final ParsedObject parsedObject;
|
||||||
|
private final Map<String, ParsedProperty> attributes;
|
||||||
|
private final String variableName;
|
||||||
|
private final StringBuilder sb;
|
||||||
|
private final ImageFormatter imageFormatter;
|
||||||
|
|
||||||
|
TestImageFormatter(@Mock final HelperProvider helperProvider, @Mock final GenerationCompatibilityHelper compatibilityHelper,
|
||||||
|
@Mock final URLFormatter urlFormatter, @Mock final VariableProvider variableProvider,
|
||||||
|
@Mock final ParsedObject parsedObject) {
|
||||||
|
this.helperProvider = Objects.requireNonNull(helperProvider);
|
||||||
|
this.compatibilityHelper = Objects.requireNonNull(compatibilityHelper);
|
||||||
|
this.urlFormatter = Objects.requireNonNull(urlFormatter);
|
||||||
|
this.variableProvider = Objects.requireNonNull(variableProvider);
|
||||||
|
this.parsedObject = Objects.requireNonNull(parsedObject);
|
||||||
|
this.attributes = new HashMap<>();
|
||||||
|
this.variableName = "variable";
|
||||||
|
this.sb = new StringBuilder();
|
||||||
|
this.imageFormatter = new ImageFormatter(helperProvider, sb, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void beforeEach() throws GenerationException {
|
||||||
|
when(helperProvider.getCompatibilityHelper()).thenReturn(compatibilityHelper);
|
||||||
|
when(helperProvider.getURLFormatter()).thenReturn(urlFormatter);
|
||||||
|
when(helperProvider.getVariableProvider()).thenReturn(variableProvider);
|
||||||
|
when(variableProvider.getNextVariableName(anyString())).then(i -> i.getArgument(0));
|
||||||
|
when(parsedObject.children()).thenReturn(List.of());
|
||||||
|
when(parsedObject.properties()).thenReturn(new LinkedHashMap<>());
|
||||||
|
when(parsedObject.attributes()).thenReturn(attributes);
|
||||||
|
when(urlFormatter.formatURL(anyString())).then(i -> i.getArgument(0) + "url");
|
||||||
|
when(compatibilityHelper.getStartVar(anyString())).then(i -> i.getArgument(0));
|
||||||
|
when(compatibilityHelper.getStartVar(anyString(), anyInt())).then(i -> i.getArgument(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testHasChildren() {
|
||||||
|
when(parsedObject.children()).thenReturn(List.of(parsedObject));
|
||||||
|
assertThrows(GenerationException.class, () -> imageFormatter.formatImage(parsedObject, variableName));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testHasProperties() {
|
||||||
|
final var properties = new LinkedHashMap<ParsedProperty, SequencedCollection<ParsedObject>>();
|
||||||
|
properties.put(new ParsedPropertyImpl("str", null, ""), List.of(parsedObject));
|
||||||
|
when(parsedObject.properties()).thenReturn(properties);
|
||||||
|
assertThrows(GenerationException.class, () -> imageFormatter.formatImage(parsedObject, variableName));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testUnknownAttribute() {
|
||||||
|
attributes.put("unknown", new ParsedPropertyImpl("unknown", null, "value"));
|
||||||
|
assertThrows(GenerationException.class, () -> imageFormatter.formatImage(parsedObject, variableName));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testMissingUrl() {
|
||||||
|
attributes.put("requestedWidth", new ParsedPropertyImpl("requestedWidth", null, "50"));
|
||||||
|
attributes.put("requestedHeight", new ParsedPropertyImpl("requestedHeight", null, "12.0"));
|
||||||
|
attributes.put("preserveRatio", new ParsedPropertyImpl("preserveRatio", null, "true"));
|
||||||
|
attributes.put("smooth", new ParsedPropertyImpl("smooth", null, "true"));
|
||||||
|
attributes.put("backgroundLoading", new ParsedPropertyImpl("backgroundLoading", null, "true"));
|
||||||
|
attributes.put("fx:id", new ParsedPropertyImpl("fx:id", null, "id"));
|
||||||
|
|
||||||
|
assertThrows(GenerationException.class, () -> imageFormatter.formatImage(parsedObject, variableName));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testMinimumAttributesURL() throws GenerationException {
|
||||||
|
final var urlImageFormatter = new ImageFormatter(helperProvider, sb, false);
|
||||||
|
attributes.put("url", new ParsedPropertyImpl("url", null, "urlValue"));
|
||||||
|
final var expected = """
|
||||||
|
StringurlStr = urlValueurl.toString();
|
||||||
|
javafx.scene.image.Imagevariable = new javafx.scene.image.Image(urlStr, 0.0, 0.0, false, false, false);
|
||||||
|
""";
|
||||||
|
urlImageFormatter.formatImage(parsedObject, variableName);
|
||||||
|
assertEquals(expected, sb.toString());
|
||||||
|
verify(urlFormatter).formatURL("urlValue");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testAllAttributesURL() throws GenerationException {
|
||||||
|
final var urlImageFormatter = new ImageFormatter(helperProvider, sb, false);
|
||||||
|
attributes.put("url", new ParsedPropertyImpl("url", null, "urlValue"));
|
||||||
|
attributes.put("requestedWidth", new ParsedPropertyImpl("requestedWidth", null, "50"));
|
||||||
|
attributes.put("requestedHeight", new ParsedPropertyImpl("requestedHeight", null, "12.0"));
|
||||||
|
attributes.put("preserveRatio", new ParsedPropertyImpl("preserveRatio", null, "true"));
|
||||||
|
attributes.put("smooth", new ParsedPropertyImpl("smooth", null, "true"));
|
||||||
|
attributes.put("backgroundLoading", new ParsedPropertyImpl("backgroundLoading", null, "true"));
|
||||||
|
attributes.put("fx:id", new ParsedPropertyImpl("fx:id", null, "id"));
|
||||||
|
final var expected = """
|
||||||
|
StringurlStr = urlValueurl.toString();
|
||||||
|
javafx.scene.image.Imagevariable = new javafx.scene.image.Image(urlStr, 50.0, 12.0, true, true, true);
|
||||||
|
""";
|
||||||
|
urlImageFormatter.formatImage(parsedObject, variableName);
|
||||||
|
assertEquals(expected, sb.toString());
|
||||||
|
verify(urlFormatter).formatURL("urlValue");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testMinimumAttributesInputStream() throws GenerationException {
|
||||||
|
attributes.put("url", new ParsedPropertyImpl("url", null, "urlValue"));
|
||||||
|
final var expected = """
|
||||||
|
final javafx.scene.image.Image variable;
|
||||||
|
try (java.io.InputStreaminputStream = urlValueurl.openStream()) {
|
||||||
|
variable = new javafx.scene.image.Image(inputStream, 0.0, 0.0, false, false);
|
||||||
|
} catch (final java.io.IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
""";
|
||||||
|
imageFormatter.formatImage(parsedObject, variableName);
|
||||||
|
assertEquals(expected, sb.toString());
|
||||||
|
verify(urlFormatter).formatURL("urlValue");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testAllAttributesInputStream() throws GenerationException {
|
||||||
|
attributes.put("url", new ParsedPropertyImpl("url", null, "urlValue"));
|
||||||
|
attributes.put("requestedWidth", new ParsedPropertyImpl("requestedWidth", null, "50"));
|
||||||
|
attributes.put("requestedHeight", new ParsedPropertyImpl("requestedHeight", null, "12.0"));
|
||||||
|
attributes.put("preserveRatio", new ParsedPropertyImpl("preserveRatio", null, "true"));
|
||||||
|
attributes.put("smooth", new ParsedPropertyImpl("smooth", null, "true"));
|
||||||
|
attributes.put("backgroundLoading", new ParsedPropertyImpl("backgroundLoading", null, "true"));
|
||||||
|
attributes.put("fx:id", new ParsedPropertyImpl("fx:id", null, "id"));
|
||||||
|
final var expected = """
|
||||||
|
final javafx.scene.image.Image variable;
|
||||||
|
try (java.io.InputStreaminputStream = urlValueurl.openStream()) {
|
||||||
|
variable = new javafx.scene.image.Image(inputStream, 50.0, 12.0, true, true);
|
||||||
|
} catch (final java.io.IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
""";
|
||||||
|
imageFormatter.formatImage(parsedObject, variableName);
|
||||||
|
assertEquals(expected, sb.toString());
|
||||||
|
verify(urlFormatter).formatURL("urlValue");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testIllegal() {
|
||||||
|
assertThrows(NullPointerException.class, () -> new ImageFormatter(null, sb, true));
|
||||||
|
assertThrows(NullPointerException.class, () -> new ImageFormatter(helperProvider, null, true));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,12 @@
|
|||||||
package com.github.gtache.fxml.compiler.impl.internal;
|
package com.github.gtache.fxml.compiler.impl.internal;
|
||||||
|
|
||||||
|
import com.github.gtache.fxml.compiler.ControllerFieldInjectionType;
|
||||||
|
import com.github.gtache.fxml.compiler.ControllerInfo;
|
||||||
|
import com.github.gtache.fxml.compiler.ControllerInjectionType;
|
||||||
import com.github.gtache.fxml.compiler.GenerationException;
|
import com.github.gtache.fxml.compiler.GenerationException;
|
||||||
import com.github.gtache.fxml.compiler.GenerationParameters;
|
import com.github.gtache.fxml.compiler.GenerationParameters;
|
||||||
import com.github.gtache.fxml.compiler.GenerationRequest;
|
import com.github.gtache.fxml.compiler.GenerationRequest;
|
||||||
|
import com.github.gtache.fxml.compiler.ResourceBundleInjectionType;
|
||||||
import com.github.gtache.fxml.compiler.SourceInfo;
|
import com.github.gtache.fxml.compiler.SourceInfo;
|
||||||
import com.github.gtache.fxml.compiler.parsing.ParsedInclude;
|
import com.github.gtache.fxml.compiler.parsing.ParsedInclude;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
@@ -12,51 +16,577 @@ import org.mockito.Mock;
|
|||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
import static org.mockito.ArgumentMatchers.anyString;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
class TestInitializationFormatter {
|
class TestInitializationFormatter {
|
||||||
|
|
||||||
private final GenerationProgress progress;
|
|
||||||
private final GenerationRequest request;
|
private final GenerationRequest request;
|
||||||
private final GenerationParameters parameters;
|
private final GenerationParameters parameters;
|
||||||
private final HelperProvider helperProvider;
|
private final HelperProvider helperProvider;
|
||||||
private final StringBuilder stringBuilder;
|
private final GenerationCompatibilityHelper compatibilityHelper;
|
||||||
|
private final VariableProvider variableProvider;
|
||||||
|
private final ControllerInfo controllerInfo;
|
||||||
private final SourceInfo sourceInfo;
|
private final SourceInfo sourceInfo;
|
||||||
private final ParsedInclude include;
|
private final ParsedInclude include;
|
||||||
private final Map<String, SourceInfo> sourceToSourceInfo;
|
private final Map<String, SourceInfo> sourceToSourceInfo;
|
||||||
|
private final StringBuilder sb;
|
||||||
|
private final Map<String, String> controllerClassToVariable;
|
||||||
private final InitializationFormatter initializationFormatter;
|
private final InitializationFormatter initializationFormatter;
|
||||||
|
|
||||||
|
|
||||||
TestInitializationFormatter(@Mock final GenerationProgress progress, @Mock final GenerationRequest request,
|
TestInitializationFormatter(@Mock final GenerationRequest request, @Mock final GenerationParameters parameters, @Mock final GenerationCompatibilityHelper compatibilityHelper,
|
||||||
@Mock final GenerationParameters parameters, @Mock final HelperProvider helperProvider,
|
@Mock final HelperProvider helperProvider, @Mock final VariableProvider variableProvider,
|
||||||
@Mock final SourceInfo sourceInfo, @Mock final ParsedInclude include) {
|
@Mock final ControllerInfo controllerInfo, @Mock final SourceInfo sourceInfo,
|
||||||
this.progress = Objects.requireNonNull(progress);
|
@Mock final ParsedInclude include) {
|
||||||
this.request = Objects.requireNonNull(request);
|
this.request = Objects.requireNonNull(request);
|
||||||
this.parameters = Objects.requireNonNull(parameters);
|
this.parameters = Objects.requireNonNull(parameters);
|
||||||
this.stringBuilder = new StringBuilder();
|
|
||||||
this.helperProvider = Objects.requireNonNull(helperProvider);
|
this.helperProvider = Objects.requireNonNull(helperProvider);
|
||||||
|
this.compatibilityHelper = Objects.requireNonNull(compatibilityHelper);
|
||||||
|
this.variableProvider = Objects.requireNonNull(variableProvider);
|
||||||
|
this.controllerInfo = Objects.requireNonNull(controllerInfo);
|
||||||
this.sourceInfo = Objects.requireNonNull(sourceInfo);
|
this.sourceInfo = Objects.requireNonNull(sourceInfo);
|
||||||
this.include = Objects.requireNonNull(include);
|
this.include = Objects.requireNonNull(include);
|
||||||
this.sourceToSourceInfo = new HashMap<>();
|
this.sourceToSourceInfo = new HashMap<>();
|
||||||
this.initializationFormatter = new InitializationFormatter(helperProvider, progress);
|
this.sb = new StringBuilder();
|
||||||
|
this.controllerClassToVariable = new HashMap<>();
|
||||||
|
this.initializationFormatter = new InitializationFormatter(helperProvider, request, sb, controllerClassToVariable);
|
||||||
}
|
}
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
void beforeEach() {
|
void beforeEach() {
|
||||||
|
when(helperProvider.getCompatibilityHelper()).thenReturn(compatibilityHelper);
|
||||||
|
when(helperProvider.getVariableProvider()).thenReturn(variableProvider);
|
||||||
|
when(compatibilityHelper.getStartVar(anyString())).then(i -> i.getArgument(0));
|
||||||
|
when(variableProvider.getNextVariableName(anyString())).then(i -> i.getArgument(0));
|
||||||
when(request.parameters()).thenReturn(parameters);
|
when(request.parameters()).thenReturn(parameters);
|
||||||
when(progress.request()).thenReturn(request);
|
when(request.outputClassName()).thenReturn("com.github.gtache.fxml.OutputClassName");
|
||||||
when(progress.stringBuilder()).thenReturn(stringBuilder);
|
|
||||||
when(request.sourceInfo()).thenReturn(sourceInfo);
|
when(request.sourceInfo()).thenReturn(sourceInfo);
|
||||||
|
when(request.controllerInfo()).thenReturn(controllerInfo);
|
||||||
|
when(controllerInfo.className()).thenReturn("com.github.gtache.fxml.ControllerClassName");
|
||||||
when(sourceInfo.sourceToSourceInfo()).thenReturn(sourceToSourceInfo);
|
when(sourceInfo.sourceToSourceInfo()).thenReturn(sourceToSourceInfo);
|
||||||
|
when(parameters.resourceInjectionType()).thenReturn(ResourceBundleInjectionType.GET_BUNDLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testDuplicateControllersNoFactory(@Mock final SourceInfo sourceInfo2, @Mock final SourceInfo sourceInfo3,
|
||||||
|
@Mock final SourceInfo sourceInfo4) {
|
||||||
|
when(sourceInfo.controllerClassName()).thenReturn("controller");
|
||||||
|
when(sourceInfo.includedSources()).thenReturn(List.of(sourceInfo2));
|
||||||
|
when(sourceInfo2.controllerClassName()).thenReturn("controller2");
|
||||||
|
when(sourceInfo2.includedSources()).thenReturn(List.of(sourceInfo3, sourceInfo4));
|
||||||
|
when(sourceInfo3.controllerClassName()).thenReturn("controller3");
|
||||||
|
when(sourceInfo3.includedSources()).thenReturn(List.of(sourceInfo4));
|
||||||
|
when(sourceInfo4.controllerClassName()).thenReturn("controller4");
|
||||||
|
assertThrows(GenerationException.class, initializationFormatter::formatFieldsAndConstructor);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFormatFieldFactory() throws GenerationException {
|
||||||
|
when(parameters.controllerInjectionType()).thenReturn(ControllerInjectionType.FACTORY);
|
||||||
|
when(parameters.fieldInjectionType()).thenReturn(ControllerFieldInjectionType.FACTORY);
|
||||||
|
final var expected = """
|
||||||
|
private final java.util.function.Function<java.util.Map<String, Object>, com.github.gtache.fxml.ControllerClassName> controllerFactory;
|
||||||
|
private com.github.gtache.fxml.ControllerClassName controller;
|
||||||
|
private boolean loaded;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates a new OutputClassName
|
||||||
|
* @param controllerFactory The controller factory
|
||||||
|
*/
|
||||||
|
public OutputClassName(final java.util.function.Function<java.util.Map<String, Object>, com.github.gtache.fxml.ControllerClassName> controllerFactory) {
|
||||||
|
this.controllerFactory = java.util.Objects.requireNonNull(controllerFactory);
|
||||||
|
}
|
||||||
|
""";
|
||||||
|
initializationFormatter.formatFieldsAndConstructor();
|
||||||
|
assertEquals(expected, sb.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFormatBaseFactory() throws GenerationException {
|
||||||
|
when(parameters.controllerInjectionType()).thenReturn(ControllerInjectionType.FACTORY);
|
||||||
|
final var expected = """
|
||||||
|
private final java.util.function.Supplier<com.github.gtache.fxml.ControllerClassName> controllerFactory;
|
||||||
|
private com.github.gtache.fxml.ControllerClassName controller;
|
||||||
|
private boolean loaded;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates a new OutputClassName
|
||||||
|
* @param controllerFactory The controller factory
|
||||||
|
*/
|
||||||
|
public OutputClassName(final java.util.function.Supplier<com.github.gtache.fxml.ControllerClassName> controllerFactory) {
|
||||||
|
this.controllerFactory = java.util.Objects.requireNonNull(controllerFactory);
|
||||||
|
}
|
||||||
|
""";
|
||||||
|
initializationFormatter.formatFieldsAndConstructor();
|
||||||
|
assertEquals(expected, sb.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFormatInstance() throws GenerationException {
|
||||||
|
when(parameters.controllerInjectionType()).thenReturn(ControllerInjectionType.INSTANCE);
|
||||||
|
final var expected = """
|
||||||
|
private final com.github.gtache.fxml.ControllerClassName controller;
|
||||||
|
private boolean loaded;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates a new OutputClassName
|
||||||
|
* @param controller The controller instance
|
||||||
|
*/
|
||||||
|
public OutputClassName(final com.github.gtache.fxml.ControllerClassName controller) {
|
||||||
|
this.controller = java.util.Objects.requireNonNull(controller);
|
||||||
|
}
|
||||||
|
""";
|
||||||
|
initializationFormatter.formatFieldsAndConstructor();
|
||||||
|
assertEquals(expected, sb.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testConstructorResourceBundle() throws GenerationException {
|
||||||
|
when(parameters.controllerInjectionType()).thenReturn(ControllerInjectionType.INSTANCE);
|
||||||
|
when(parameters.resourceInjectionType()).thenReturn(ResourceBundleInjectionType.CONSTRUCTOR);
|
||||||
|
final var expected = """
|
||||||
|
private final com.github.gtache.fxml.ControllerClassName controller;
|
||||||
|
private final java.util.ResourceBundle resourceBundle;
|
||||||
|
private boolean loaded;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates a new OutputClassName
|
||||||
|
* @param controller The controller instance
|
||||||
|
* @param resourceBundle The resource bundle
|
||||||
|
*/
|
||||||
|
public OutputClassName(final com.github.gtache.fxml.ControllerClassName controller, final java.util.ResourceBundle resourceBundle) {
|
||||||
|
this.controller = java.util.Objects.requireNonNull(controller);
|
||||||
|
this.resourceBundle = java.util.Objects.requireNonNull(resourceBundle);
|
||||||
|
}
|
||||||
|
""";
|
||||||
|
initializationFormatter.formatFieldsAndConstructor();
|
||||||
|
assertEquals(expected, sb.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testConstructorFunctionResourceBundle() throws GenerationException {
|
||||||
|
when(parameters.controllerInjectionType()).thenReturn(ControllerInjectionType.INSTANCE);
|
||||||
|
when(parameters.resourceInjectionType()).thenReturn(ResourceBundleInjectionType.CONSTRUCTOR_FUNCTION);
|
||||||
|
final var expected = """
|
||||||
|
private final com.github.gtache.fxml.ControllerClassName controller;
|
||||||
|
private final java.util.function.Function<String, String> resourceBundleFunction;
|
||||||
|
private boolean loaded;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates a new OutputClassName
|
||||||
|
* @param controller The controller instance
|
||||||
|
* @param resourceBundleFunction The resource bundle
|
||||||
|
*/
|
||||||
|
public OutputClassName(final com.github.gtache.fxml.ControllerClassName controller, final java.util.function.Function<String, String> resourceBundleFunction) {
|
||||||
|
this.controller = java.util.Objects.requireNonNull(controller);
|
||||||
|
this.resourceBundleFunction = java.util.Objects.requireNonNull(resourceBundleFunction);
|
||||||
|
}
|
||||||
|
""";
|
||||||
|
initializationFormatter.formatFieldsAndConstructor();
|
||||||
|
assertEquals(expected, sb.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testConstructorNamedResourceBundle() throws GenerationException {
|
||||||
|
when(parameters.controllerInjectionType()).thenReturn(ControllerInjectionType.INSTANCE);
|
||||||
|
when(parameters.resourceInjectionType()).thenReturn(ResourceBundleInjectionType.CONSTRUCTOR_NAME);
|
||||||
|
final var expected = """
|
||||||
|
private final com.github.gtache.fxml.ControllerClassName controller;
|
||||||
|
private final String resourceBundleName;
|
||||||
|
private boolean loaded;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates a new OutputClassName
|
||||||
|
* @param controller The controller instance
|
||||||
|
* @param resourceBundleName The resource bundle
|
||||||
|
*/
|
||||||
|
public OutputClassName(final com.github.gtache.fxml.ControllerClassName controller, final String resourceBundleName) {
|
||||||
|
this.controller = java.util.Objects.requireNonNull(controller);
|
||||||
|
this.resourceBundleName = java.util.Objects.requireNonNull(resourceBundleName);
|
||||||
|
}
|
||||||
|
""";
|
||||||
|
initializationFormatter.formatFieldsAndConstructor();
|
||||||
|
assertEquals(expected, sb.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testHasControllersFieldFactory() throws GenerationException {
|
||||||
|
when(parameters.controllerInjectionType()).thenReturn(ControllerInjectionType.FACTORY);
|
||||||
|
when(parameters.fieldInjectionType()).thenReturn(ControllerFieldInjectionType.FACTORY);
|
||||||
|
final var expected = """
|
||||||
|
private final java.util.function.Function<java.util.Map<String, Object>, com.github.gtache.fxml.ControllerClassName> controllerFactory;
|
||||||
|
private final java.util.function.Function<java.util.Map<String, Object>, com.github.gtache.fxml.Controller2> controller2Factory;
|
||||||
|
private final java.util.function.Function<java.util.Map<String, Object>, com.github.gtache.fxml.Controller3> controller3Factory;
|
||||||
|
private com.github.gtache.fxml.ControllerClassName controller;
|
||||||
|
private boolean loaded;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates a new OutputClassName
|
||||||
|
* @param controllerFactory The controller factory
|
||||||
|
* @param controller2Factory The subcontroller factory for com.github.gtache.fxml.Controller2
|
||||||
|
* @param controller3Factory The subcontroller factory for com.github.gtache.fxml.Controller3
|
||||||
|
*/
|
||||||
|
public OutputClassName(final java.util.function.Function<java.util.Map<String, Object>, com.github.gtache.fxml.ControllerClassName> controllerFactory, final java.util.function.Function<java.util.Map<String, Object>, com.github.gtache.fxml.Controller2> controller2Factory, final java.util.function.Function<java.util.Map<String, Object>, com.github.gtache.fxml.Controller3> controller3Factory) {
|
||||||
|
this.controllerFactory = java.util.Objects.requireNonNull(controllerFactory);
|
||||||
|
this.controller2Factory = java.util.Objects.requireNonNull(controller2Factory);
|
||||||
|
this.controller3Factory = java.util.Objects.requireNonNull(controller3Factory);
|
||||||
|
}
|
||||||
|
""";
|
||||||
|
final var source2 = mock(SourceInfo.class);
|
||||||
|
when(source2.controllerClassName()).thenReturn("com.github.gtache.fxml.Controller2");
|
||||||
|
final var source3 = mock(SourceInfo.class);
|
||||||
|
when(source3.controllerClassName()).thenReturn("com.github.gtache.fxml.Controller3");
|
||||||
|
when(sourceInfo.includedSources()).thenReturn(List.of(source2));
|
||||||
|
when(source2.includedSources()).thenReturn(List.of(source3));
|
||||||
|
initializationFormatter.formatFieldsAndConstructor();
|
||||||
|
assertEquals(expected, sb.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testHasControllersBaseFactory() throws GenerationException {
|
||||||
|
when(parameters.controllerInjectionType()).thenReturn(ControllerInjectionType.FACTORY);
|
||||||
|
final var expected = """
|
||||||
|
private final java.util.function.Supplier<com.github.gtache.fxml.ControllerClassName> controllerFactory;
|
||||||
|
private final java.util.function.Supplier<com.github.gtache.fxml.Controller2> controller2Factory;
|
||||||
|
private final java.util.function.Supplier<com.github.gtache.fxml.Controller3> controller3Factory;
|
||||||
|
private com.github.gtache.fxml.ControllerClassName controller;
|
||||||
|
private boolean loaded;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates a new OutputClassName
|
||||||
|
* @param controllerFactory The controller factory
|
||||||
|
* @param controller2Factory The subcontroller factory for com.github.gtache.fxml.Controller2
|
||||||
|
* @param controller3Factory The subcontroller factory for com.github.gtache.fxml.Controller3
|
||||||
|
*/
|
||||||
|
public OutputClassName(final java.util.function.Supplier<com.github.gtache.fxml.ControllerClassName> controllerFactory, final java.util.function.Supplier<com.github.gtache.fxml.Controller2> controller2Factory, final java.util.function.Supplier<com.github.gtache.fxml.Controller3> controller3Factory) {
|
||||||
|
this.controllerFactory = java.util.Objects.requireNonNull(controllerFactory);
|
||||||
|
this.controller2Factory = java.util.Objects.requireNonNull(controller2Factory);
|
||||||
|
this.controller3Factory = java.util.Objects.requireNonNull(controller3Factory);
|
||||||
|
}
|
||||||
|
""";
|
||||||
|
final var source2 = mock(SourceInfo.class);
|
||||||
|
when(source2.controllerClassName()).thenReturn("com.github.gtache.fxml.Controller2");
|
||||||
|
final var source3 = mock(SourceInfo.class);
|
||||||
|
when(source3.controllerClassName()).thenReturn("com.github.gtache.fxml.Controller3");
|
||||||
|
when(sourceInfo.includedSources()).thenReturn(List.of(source2));
|
||||||
|
when(source2.includedSources()).thenReturn(List.of(source3));
|
||||||
|
initializationFormatter.formatFieldsAndConstructor();
|
||||||
|
assertEquals(expected, sb.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testHasControllersInstance() throws GenerationException {
|
||||||
|
when(parameters.controllerInjectionType()).thenReturn(ControllerInjectionType.INSTANCE);
|
||||||
|
final var expected = """
|
||||||
|
private final com.github.gtache.fxml.ControllerClassName controller;
|
||||||
|
private final com.github.gtache.fxml.Controller2 controller2;
|
||||||
|
private final com.github.gtache.fxml.Controller3 controller3;
|
||||||
|
private boolean loaded;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates a new OutputClassName
|
||||||
|
* @param controller The controller instance
|
||||||
|
* @param controller2 The subcontroller instance for com.github.gtache.fxml.Controller2
|
||||||
|
* @param controller3 The subcontroller instance for com.github.gtache.fxml.Controller3
|
||||||
|
*/
|
||||||
|
public OutputClassName(final com.github.gtache.fxml.ControllerClassName controller, final com.github.gtache.fxml.Controller2 controller2, final com.github.gtache.fxml.Controller3 controller3) {
|
||||||
|
this.controller = java.util.Objects.requireNonNull(controller);
|
||||||
|
this.controller2 = java.util.Objects.requireNonNull(controller2);
|
||||||
|
this.controller3 = java.util.Objects.requireNonNull(controller3);
|
||||||
|
}
|
||||||
|
""";
|
||||||
|
final var source2 = mock(SourceInfo.class);
|
||||||
|
when(source2.controllerClassName()).thenReturn("com.github.gtache.fxml.Controller2");
|
||||||
|
final var source3 = mock(SourceInfo.class);
|
||||||
|
when(source3.controllerClassName()).thenReturn("com.github.gtache.fxml.Controller3");
|
||||||
|
when(sourceInfo.includedSources()).thenReturn(List.of(source2));
|
||||||
|
when(source2.includedSources()).thenReturn(List.of(source3));
|
||||||
|
initializationFormatter.formatFieldsAndConstructor();
|
||||||
|
assertEquals(expected, sb.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testComplete() throws GenerationException {
|
||||||
|
when(parameters.controllerInjectionType()).thenReturn(ControllerInjectionType.FACTORY);
|
||||||
|
when(parameters.resourceInjectionType()).thenReturn(ResourceBundleInjectionType.CONSTRUCTOR);
|
||||||
|
final var expected = """
|
||||||
|
private final java.util.function.Supplier<com.github.gtache.fxml.ControllerClassName> controllerFactory;
|
||||||
|
private final java.util.function.Supplier<com.github.gtache.fxml.Controller2> controller2Factory;
|
||||||
|
private final java.util.function.Supplier<com.github.gtache.fxml.Controller3> controller3Factory;
|
||||||
|
private com.github.gtache.fxml.ControllerClassName controller;
|
||||||
|
private final java.util.ResourceBundle resourceBundle;
|
||||||
|
private boolean loaded;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates a new OutputClassName
|
||||||
|
* @param controllerFactory The controller factory
|
||||||
|
* @param controller2Factory The subcontroller factory for com.github.gtache.fxml.Controller2
|
||||||
|
* @param controller3Factory The subcontroller factory for com.github.gtache.fxml.Controller3
|
||||||
|
* @param resourceBundle The resource bundle
|
||||||
|
*/
|
||||||
|
public OutputClassName(final java.util.function.Supplier<com.github.gtache.fxml.ControllerClassName> controllerFactory, final java.util.function.Supplier<com.github.gtache.fxml.Controller2> controller2Factory, final java.util.function.Supplier<com.github.gtache.fxml.Controller3> controller3Factory, final java.util.ResourceBundle resourceBundle) {
|
||||||
|
this.controllerFactory = java.util.Objects.requireNonNull(controllerFactory);
|
||||||
|
this.controller2Factory = java.util.Objects.requireNonNull(controller2Factory);
|
||||||
|
this.controller3Factory = java.util.Objects.requireNonNull(controller3Factory);
|
||||||
|
this.resourceBundle = java.util.Objects.requireNonNull(resourceBundle);
|
||||||
|
}
|
||||||
|
""";
|
||||||
|
final var source2 = mock(SourceInfo.class);
|
||||||
|
when(source2.controllerClassName()).thenReturn("com.github.gtache.fxml.Controller2");
|
||||||
|
final var source3 = mock(SourceInfo.class);
|
||||||
|
when(source3.controllerClassName()).thenReturn("com.github.gtache.fxml.Controller3");
|
||||||
|
when(sourceInfo.includedSources()).thenReturn(List.of(source2, source3));
|
||||||
|
when(source2.includedSources()).thenReturn(List.of(source3));
|
||||||
|
initializationFormatter.formatFieldsAndConstructor();
|
||||||
|
assertEquals(expected, sb.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testFormatSubViewConstructorCallNullSubInfo() {
|
void testFormatSubViewConstructorCallNullSubInfo() {
|
||||||
assertThrows(GenerationException.class, () -> initializationFormatter.formatSubViewConstructorCall(include));
|
assertThrows(GenerationException.class, () -> initializationFormatter.formatSubViewConstructorCall(include));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFormatSubViewInstance(@Mock final SourceInfo subInfo) throws GenerationException {
|
||||||
|
when(include.source()).thenReturn("source");
|
||||||
|
when(parameters.controllerInjectionType()).thenReturn(ControllerInjectionType.INSTANCE);
|
||||||
|
sourceToSourceInfo.put("source", subInfo);
|
||||||
|
when(subInfo.controllerClassName()).thenReturn("com.github.gtache.fxml.Controller2");
|
||||||
|
controllerClassToVariable.put("com.github.gtache.fxml.Controller2", "controller2");
|
||||||
|
when(subInfo.generatedClassName()).thenReturn("com.github.gtache.fxml.View2");
|
||||||
|
when(subInfo.includedSources()).thenReturn(List.of());
|
||||||
|
final var expected = "com.github.gtache.fxml.View2view2 = new com.github.gtache.fxml.View2(controller2);\n";
|
||||||
|
assertEquals("view2", initializationFormatter.formatSubViewConstructorCall(include));
|
||||||
|
assertEquals(expected, sb.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFormatSubViewFactory(@Mock final SourceInfo subInfo) throws GenerationException {
|
||||||
|
when(include.source()).thenReturn("source");
|
||||||
|
when(parameters.controllerInjectionType()).thenReturn(ControllerInjectionType.FACTORY);
|
||||||
|
sourceToSourceInfo.put("source", subInfo);
|
||||||
|
when(subInfo.controllerClassName()).thenReturn("com.github.gtache.fxml.Controller2");
|
||||||
|
controllerClassToVariable.put("com.github.gtache.fxml.Controller2", "controller2");
|
||||||
|
when(subInfo.generatedClassName()).thenReturn("com.github.gtache.fxml.View2");
|
||||||
|
when(subInfo.includedSources()).thenReturn(List.of());
|
||||||
|
final var expected = "com.github.gtache.fxml.View2view2 = new com.github.gtache.fxml.View2(controller2Factory);\n";
|
||||||
|
assertEquals("view2", initializationFormatter.formatSubViewConstructorCall(include));
|
||||||
|
assertEquals(expected, sb.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFormatSubViewMultipleInstanceFactory(@Mock final SourceInfo subInfo) throws GenerationException {
|
||||||
|
final var source3 = mock(SourceInfo.class);
|
||||||
|
when(source3.controllerClassName()).thenReturn("com.github.gtache.fxml.Controller3");
|
||||||
|
when(source3.includedSources()).thenReturn(List.of());
|
||||||
|
final var source4 = mock(SourceInfo.class);
|
||||||
|
when(source4.controllerClassName()).thenReturn("com.github.gtache.fxml.Controller4");
|
||||||
|
when(source4.includedSources()).thenReturn(List.of());
|
||||||
|
when(subInfo.includedSources()).thenReturn(List.of(source3, source4));
|
||||||
|
when(include.source()).thenReturn("source");
|
||||||
|
when(parameters.controllerInjectionType()).thenReturn(ControllerInjectionType.FACTORY);
|
||||||
|
sourceToSourceInfo.put("source", subInfo);
|
||||||
|
when(subInfo.controllerClassName()).thenReturn("com.github.gtache.fxml.Controller2");
|
||||||
|
controllerClassToVariable.put("com.github.gtache.fxml.Controller2", "controller2");
|
||||||
|
controllerClassToVariable.put("com.github.gtache.fxml.Controller3", "controller3");
|
||||||
|
controllerClassToVariable.put("com.github.gtache.fxml.Controller4", "controller4");
|
||||||
|
when(subInfo.generatedClassName()).thenReturn("com.github.gtache.fxml.View2");
|
||||||
|
final var expected = "com.github.gtache.fxml.View2view2 = new com.github.gtache.fxml.View2(controller2Factory, controller3Factory, controller4Factory);\n";
|
||||||
|
assertEquals("view2", initializationFormatter.formatSubViewConstructorCall(include));
|
||||||
|
assertEquals(expected, sb.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFormatSubViewMultipleInstance(@Mock final SourceInfo subInfo) throws GenerationException {
|
||||||
|
final var source3 = mock(SourceInfo.class);
|
||||||
|
when(source3.controllerClassName()).thenReturn("com.github.gtache.fxml.Controller3");
|
||||||
|
when(source3.includedSources()).thenReturn(List.of());
|
||||||
|
final var source4 = mock(SourceInfo.class);
|
||||||
|
when(source4.controllerClassName()).thenReturn("com.github.gtache.fxml.Controller4");
|
||||||
|
when(source4.includedSources()).thenReturn(List.of());
|
||||||
|
when(subInfo.includedSources()).thenReturn(List.of(source3, source4));
|
||||||
|
when(include.source()).thenReturn("source");
|
||||||
|
when(parameters.controllerInjectionType()).thenReturn(ControllerInjectionType.INSTANCE);
|
||||||
|
sourceToSourceInfo.put("source", subInfo);
|
||||||
|
when(subInfo.controllerClassName()).thenReturn("com.github.gtache.fxml.Controller2");
|
||||||
|
controllerClassToVariable.put("com.github.gtache.fxml.Controller2", "controller2");
|
||||||
|
controllerClassToVariable.put("com.github.gtache.fxml.Controller3", "controller3");
|
||||||
|
controllerClassToVariable.put("com.github.gtache.fxml.Controller4", "controller4");
|
||||||
|
when(subInfo.generatedClassName()).thenReturn("com.github.gtache.fxml.View2");
|
||||||
|
final var expected = "com.github.gtache.fxml.View2view2 = new com.github.gtache.fxml.View2(controller2, controller3, controller4);\n";
|
||||||
|
assertEquals("view2", initializationFormatter.formatSubViewConstructorCall(include));
|
||||||
|
assertEquals(expected, sb.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFormatSubViewRequiresBundleGetter(@Mock final SourceInfo subInfo) throws GenerationException {
|
||||||
|
when(subInfo.includedSources()).thenReturn(List.of());
|
||||||
|
when(subInfo.requiresResourceBundle()).thenReturn(true);
|
||||||
|
when(include.source()).thenReturn("source");
|
||||||
|
when(parameters.controllerInjectionType()).thenReturn(ControllerInjectionType.INSTANCE);
|
||||||
|
when(parameters.resourceInjectionType()).thenReturn(ResourceBundleInjectionType.GETTER);
|
||||||
|
sourceToSourceInfo.put("source", subInfo);
|
||||||
|
when(subInfo.controllerClassName()).thenReturn("com.github.gtache.fxml.Controller2");
|
||||||
|
when(subInfo.generatedClassName()).thenReturn("com.github.gtache.fxml.View2");
|
||||||
|
controllerClassToVariable.put("com.github.gtache.fxml.Controller2", "controller2");
|
||||||
|
final var expected = "com.github.gtache.fxml.View2view2 = new com.github.gtache.fxml.View2(controller2);\n";
|
||||||
|
assertEquals("view2", initializationFormatter.formatSubViewConstructorCall(include));
|
||||||
|
assertEquals(expected, sb.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFormatSubViewRequiresBundleGetBundle(@Mock final SourceInfo subInfo) throws GenerationException {
|
||||||
|
when(subInfo.includedSources()).thenReturn(List.of());
|
||||||
|
when(subInfo.requiresResourceBundle()).thenReturn(true);
|
||||||
|
when(include.source()).thenReturn("source");
|
||||||
|
when(parameters.controllerInjectionType()).thenReturn(ControllerInjectionType.INSTANCE);
|
||||||
|
when(parameters.resourceInjectionType()).thenReturn(ResourceBundleInjectionType.GET_BUNDLE);
|
||||||
|
sourceToSourceInfo.put("source", subInfo);
|
||||||
|
when(subInfo.controllerClassName()).thenReturn("com.github.gtache.fxml.Controller2");
|
||||||
|
when(subInfo.generatedClassName()).thenReturn("com.github.gtache.fxml.View2");
|
||||||
|
controllerClassToVariable.put("com.github.gtache.fxml.Controller2", "controller2");
|
||||||
|
final var expected = "com.github.gtache.fxml.View2view2 = new com.github.gtache.fxml.View2(controller2);\n";
|
||||||
|
assertEquals("view2", initializationFormatter.formatSubViewConstructorCall(include));
|
||||||
|
assertEquals(expected, sb.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFormatSubViewRequiresBundleConstructorNoResources(@Mock final SourceInfo subInfo) throws GenerationException {
|
||||||
|
when(subInfo.includedSources()).thenReturn(List.of());
|
||||||
|
when(subInfo.requiresResourceBundle()).thenReturn(true);
|
||||||
|
when(include.source()).thenReturn("source");
|
||||||
|
when(parameters.controllerInjectionType()).thenReturn(ControllerInjectionType.INSTANCE);
|
||||||
|
when(parameters.resourceInjectionType()).thenReturn(ResourceBundleInjectionType.CONSTRUCTOR);
|
||||||
|
sourceToSourceInfo.put("source", subInfo);
|
||||||
|
when(subInfo.controllerClassName()).thenReturn("com.github.gtache.fxml.Controller2");
|
||||||
|
when(subInfo.generatedClassName()).thenReturn("com.github.gtache.fxml.View2");
|
||||||
|
controllerClassToVariable.put("com.github.gtache.fxml.Controller2", "controller2");
|
||||||
|
final var expected = "com.github.gtache.fxml.View2view2 = new com.github.gtache.fxml.View2(controller2, resourceBundle);\n";
|
||||||
|
assertEquals("view2", initializationFormatter.formatSubViewConstructorCall(include));
|
||||||
|
assertEquals(expected, sb.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFormatSubViewRequiresBundleConstructorFunctionNoResources(@Mock final SourceInfo subInfo) throws GenerationException {
|
||||||
|
when(subInfo.includedSources()).thenReturn(List.of());
|
||||||
|
when(subInfo.requiresResourceBundle()).thenReturn(true);
|
||||||
|
when(include.source()).thenReturn("source");
|
||||||
|
when(parameters.controllerInjectionType()).thenReturn(ControllerInjectionType.INSTANCE);
|
||||||
|
when(parameters.resourceInjectionType()).thenReturn(ResourceBundleInjectionType.CONSTRUCTOR_FUNCTION);
|
||||||
|
sourceToSourceInfo.put("source", subInfo);
|
||||||
|
when(subInfo.controllerClassName()).thenReturn("com.github.gtache.fxml.Controller2");
|
||||||
|
when(subInfo.generatedClassName()).thenReturn("com.github.gtache.fxml.View2");
|
||||||
|
controllerClassToVariable.put("com.github.gtache.fxml.Controller2", "controller2");
|
||||||
|
final var expected = "com.github.gtache.fxml.View2view2 = new com.github.gtache.fxml.View2(controller2, resourceBundleFunction);\n";
|
||||||
|
assertEquals("view2", initializationFormatter.formatSubViewConstructorCall(include));
|
||||||
|
assertEquals(expected, sb.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFormatSubViewRequiresBundleConstructorNameNoResources(@Mock final SourceInfo subInfo) throws GenerationException {
|
||||||
|
when(subInfo.includedSources()).thenReturn(List.of());
|
||||||
|
when(subInfo.requiresResourceBundle()).thenReturn(true);
|
||||||
|
when(include.source()).thenReturn("source");
|
||||||
|
when(parameters.controllerInjectionType()).thenReturn(ControllerInjectionType.INSTANCE);
|
||||||
|
when(parameters.resourceInjectionType()).thenReturn(ResourceBundleInjectionType.CONSTRUCTOR_NAME);
|
||||||
|
sourceToSourceInfo.put("source", subInfo);
|
||||||
|
when(subInfo.controllerClassName()).thenReturn("com.github.gtache.fxml.Controller2");
|
||||||
|
when(subInfo.generatedClassName()).thenReturn("com.github.gtache.fxml.View2");
|
||||||
|
controllerClassToVariable.put("com.github.gtache.fxml.Controller2", "controller2");
|
||||||
|
final var expected = "com.github.gtache.fxml.View2view2 = new com.github.gtache.fxml.View2(controller2, resourceBundleName);\n";
|
||||||
|
assertEquals("view2", initializationFormatter.formatSubViewConstructorCall(include));
|
||||||
|
assertEquals(expected, sb.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFormatSubViewRequiresBundleConstructorResources(@Mock final SourceInfo subInfo) throws GenerationException {
|
||||||
|
when(subInfo.includedSources()).thenReturn(List.of());
|
||||||
|
when(subInfo.requiresResourceBundle()).thenReturn(true);
|
||||||
|
when(include.source()).thenReturn("source");
|
||||||
|
when(parameters.controllerInjectionType()).thenReturn(ControllerInjectionType.INSTANCE);
|
||||||
|
when(parameters.resourceInjectionType()).thenReturn(ResourceBundleInjectionType.CONSTRUCTOR);
|
||||||
|
sourceToSourceInfo.put("source", subInfo);
|
||||||
|
when(subInfo.controllerClassName()).thenReturn("com.github.gtache.fxml.Controller2");
|
||||||
|
when(subInfo.generatedClassName()).thenReturn("com.github.gtache.fxml.View2");
|
||||||
|
controllerClassToVariable.put("com.github.gtache.fxml.Controller2", "controller2");
|
||||||
|
when(include.resources()).thenReturn("resources");
|
||||||
|
final var expected = "java.util.ResourceBundleresourceBundle = java.util.ResourceBundle.getBundle(\"resources\");\ncom.github.gtache.fxml.View2view2 = new com.github.gtache.fxml.View2(controller2, resourceBundle);\n";
|
||||||
|
assertEquals("view2", initializationFormatter.formatSubViewConstructorCall(include));
|
||||||
|
assertEquals(expected, sb.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFormatSubViewRequiresBundleConstructorFunctionResources(@Mock final SourceInfo subInfo) throws GenerationException {
|
||||||
|
when(subInfo.includedSources()).thenReturn(List.of());
|
||||||
|
when(subInfo.requiresResourceBundle()).thenReturn(true);
|
||||||
|
when(include.source()).thenReturn("source");
|
||||||
|
when(parameters.controllerInjectionType()).thenReturn(ControllerInjectionType.INSTANCE);
|
||||||
|
when(parameters.resourceInjectionType()).thenReturn(ResourceBundleInjectionType.CONSTRUCTOR_FUNCTION);
|
||||||
|
sourceToSourceInfo.put("source", subInfo);
|
||||||
|
when(subInfo.controllerClassName()).thenReturn("com.github.gtache.fxml.Controller2");
|
||||||
|
when(subInfo.generatedClassName()).thenReturn("com.github.gtache.fxml.View2");
|
||||||
|
controllerClassToVariable.put("com.github.gtache.fxml.Controller2", "controller2");
|
||||||
|
when(include.resources()).thenReturn("resources");
|
||||||
|
final var expected = "java.util.ResourceBundleresourceBundle = java.util.ResourceBundle.getBundle(\"resources\");\njava.util.function.Function<String, String>resourceBundleFunction = (java.util.function.Function<String, String>) s -> resourceBundle.getString(s);\ncom.github.gtache.fxml.View2view2 = new com.github.gtache.fxml.View2(controller2, resourceBundleFunction);\n";
|
||||||
|
assertEquals("view2", initializationFormatter.formatSubViewConstructorCall(include));
|
||||||
|
assertEquals(expected, sb.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFormatSubViewRequiresBundleConstructorName(@Mock final SourceInfo subInfo) throws GenerationException {
|
||||||
|
when(subInfo.includedSources()).thenReturn(List.of());
|
||||||
|
when(subInfo.requiresResourceBundle()).thenReturn(true);
|
||||||
|
when(include.source()).thenReturn("source");
|
||||||
|
when(parameters.controllerInjectionType()).thenReturn(ControllerInjectionType.INSTANCE);
|
||||||
|
when(parameters.resourceInjectionType()).thenReturn(ResourceBundleInjectionType.CONSTRUCTOR_NAME);
|
||||||
|
sourceToSourceInfo.put("source", subInfo);
|
||||||
|
when(subInfo.controllerClassName()).thenReturn("com.github.gtache.fxml.Controller2");
|
||||||
|
when(subInfo.generatedClassName()).thenReturn("com.github.gtache.fxml.View2");
|
||||||
|
controllerClassToVariable.put("com.github.gtache.fxml.Controller2", "controller2");
|
||||||
|
when(include.resources()).thenReturn("resources");
|
||||||
|
final var expected = "StringresourceBundleName = \"resources\";\ncom.github.gtache.fxml.View2view2 = new com.github.gtache.fxml.View2(controller2, resourceBundleName);\n";
|
||||||
|
assertEquals("view2", initializationFormatter.formatSubViewConstructorCall(include));
|
||||||
|
assertEquals(expected, sb.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFormatSubViewComplete(@Mock final SourceInfo subInfo) throws GenerationException {
|
||||||
|
final var source3 = mock(SourceInfo.class);
|
||||||
|
when(source3.controllerClassName()).thenReturn("com.github.gtache.fxml.Controller3");
|
||||||
|
when(source3.includedSources()).thenReturn(List.of());
|
||||||
|
final var source4 = mock(SourceInfo.class);
|
||||||
|
when(source4.controllerClassName()).thenReturn("com.github.gtache.fxml.Controller4");
|
||||||
|
when(source4.includedSources()).thenReturn(List.of(source3));
|
||||||
|
when(subInfo.includedSources()).thenReturn(List.of(source4));
|
||||||
|
when(subInfo.requiresResourceBundle()).thenReturn(true);
|
||||||
|
when(include.source()).thenReturn("source");
|
||||||
|
when(parameters.controllerInjectionType()).thenReturn(ControllerInjectionType.INSTANCE);
|
||||||
|
when(parameters.resourceInjectionType()).thenReturn(ResourceBundleInjectionType.CONSTRUCTOR_NAME);
|
||||||
|
sourceToSourceInfo.put("source", subInfo);
|
||||||
|
when(subInfo.controllerClassName()).thenReturn("com.github.gtache.fxml.Controller2");
|
||||||
|
when(subInfo.generatedClassName()).thenReturn("com.github.gtache.fxml.View2");
|
||||||
|
controllerClassToVariable.put("com.github.gtache.fxml.Controller2", "controller2");
|
||||||
|
controllerClassToVariable.put("com.github.gtache.fxml.Controller3", "controller3");
|
||||||
|
controllerClassToVariable.put("com.github.gtache.fxml.Controller4", "controller4");
|
||||||
|
when(include.resources()).thenReturn("resources");
|
||||||
|
final var expected = "StringresourceBundleName = \"resources\";\ncom.github.gtache.fxml.View2view2 = new com.github.gtache.fxml.View2(controller2, controller3, controller4, resourceBundleName);\n";
|
||||||
|
assertEquals("view2", initializationFormatter.formatSubViewConstructorCall(include));
|
||||||
|
assertEquals(expected, sb.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testIllegal() {
|
||||||
|
assertThrows(NullPointerException.class, () -> new InitializationFormatter(null, request, sb));
|
||||||
|
assertThrows(NullPointerException.class, () -> new InitializationFormatter(helperProvider, null, sb));
|
||||||
|
assertThrows(NullPointerException.class, () -> new InitializationFormatter(helperProvider, request, null));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,203 @@
|
|||||||
package com.github.gtache.fxml.compiler.impl.internal;
|
package com.github.gtache.fxml.compiler.impl.internal;
|
||||||
|
|
||||||
|
import com.github.gtache.fxml.compiler.ControllerFieldInjectionType;
|
||||||
|
import com.github.gtache.fxml.compiler.ControllerInfo;
|
||||||
|
import com.github.gtache.fxml.compiler.ControllerInjectionType;
|
||||||
|
import com.github.gtache.fxml.compiler.ControllerMethodsInjectionType;
|
||||||
|
import com.github.gtache.fxml.compiler.GenerationException;
|
||||||
|
import com.github.gtache.fxml.compiler.GenerationParameters;
|
||||||
|
import com.github.gtache.fxml.compiler.GenerationRequest;
|
||||||
|
import com.github.gtache.fxml.compiler.ResourceBundleInjectionType;
|
||||||
|
import com.github.gtache.fxml.compiler.parsing.ParsedObject;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
import org.mockito.Mock;
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
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.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.Mockito.*;
|
||||||
|
|
||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
class TestLoadMethodFormatter {
|
class TestLoadMethodFormatter {
|
||||||
}
|
|
||||||
|
private final HelperProvider helperProvider;
|
||||||
|
private final ObjectFormatter objectFormatter;
|
||||||
|
private final GenerationCompatibilityHelper compatibilityHelper;
|
||||||
|
private final VariableProvider variableProvider;
|
||||||
|
private final GenerationProgress progress;
|
||||||
|
private final GenerationRequest request;
|
||||||
|
private final GenerationParameters parameters;
|
||||||
|
private final ParsedObject object;
|
||||||
|
private final ControllerInfo controllerInfo;
|
||||||
|
private final String className;
|
||||||
|
private final StringBuilder sb;
|
||||||
|
private final List<String> controllerFactoryPostAction;
|
||||||
|
private final LoadMethodFormatter loadMethodFormatter;
|
||||||
|
|
||||||
|
TestLoadMethodFormatter(@Mock final HelperProvider helperProvider, @Mock final ObjectFormatter objectFormatter,
|
||||||
|
@Mock final GenerationCompatibilityHelper compatibilityHelper, @Mock final VariableProvider variableProvider,
|
||||||
|
@Mock final GenerationProgress progress, @Mock final GenerationRequest request, @Mock final GenerationParameters parameters,
|
||||||
|
@Mock final ParsedObject object, @Mock final ControllerInfo controllerInfo) {
|
||||||
|
this.helperProvider = Objects.requireNonNull(helperProvider);
|
||||||
|
this.objectFormatter = Objects.requireNonNull(objectFormatter);
|
||||||
|
this.compatibilityHelper = Objects.requireNonNull(compatibilityHelper);
|
||||||
|
this.variableProvider = Objects.requireNonNull(variableProvider);
|
||||||
|
this.request = Objects.requireNonNull(request);
|
||||||
|
this.parameters = Objects.requireNonNull(parameters);
|
||||||
|
this.object = Objects.requireNonNull(object);
|
||||||
|
this.controllerInfo = Objects.requireNonNull(controllerInfo);
|
||||||
|
this.className = "class";
|
||||||
|
this.sb = new StringBuilder();
|
||||||
|
this.controllerFactoryPostAction = new ArrayList<>();
|
||||||
|
this.progress = Objects.requireNonNull(progress);
|
||||||
|
this.loadMethodFormatter = new LoadMethodFormatter(helperProvider, progress);
|
||||||
|
}
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void beforeEach() throws GenerationException {
|
||||||
|
when(helperProvider.getObjectFormatter()).thenReturn(objectFormatter);
|
||||||
|
when(helperProvider.getCompatibilityHelper()).thenReturn(compatibilityHelper);
|
||||||
|
when(helperProvider.getVariableProvider()).thenReturn(variableProvider);
|
||||||
|
when(object.className()).thenReturn(className);
|
||||||
|
when(progress.request()).thenReturn(request);
|
||||||
|
when(request.controllerInfo()).thenReturn(controllerInfo);
|
||||||
|
when(request.parameters()).thenReturn(parameters);
|
||||||
|
when(request.rootObject()).thenReturn(object);
|
||||||
|
when(progress.stringBuilder()).thenReturn(sb);
|
||||||
|
when(progress.controllerFactoryPostAction()).thenReturn(controllerFactoryPostAction);
|
||||||
|
when(variableProvider.getNextVariableName(any(String.class))).then(i -> i.getArgument(0));
|
||||||
|
doAnswer(i -> sb.append(i.getArgument(0) + "-" + i.getArgument(1))).when(objectFormatter).format(any(), any());
|
||||||
|
when(controllerInfo.className()).thenReturn(className);
|
||||||
|
when(compatibilityHelper.getStartVar(anyString())).then(i -> i.getArgument(0));
|
||||||
|
when(compatibilityHelper.getStartVar(anyString(), anyInt())).then(i -> i.getArgument(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testEasiestCase() throws GenerationException {
|
||||||
|
when(object.toString()).thenReturn("object");
|
||||||
|
loadMethodFormatter.formatLoadMethod();
|
||||||
|
final var expected = """
|
||||||
|
/**
|
||||||
|
* Loads the view. Can only be called once.
|
||||||
|
*
|
||||||
|
* @return The view parent
|
||||||
|
*/
|
||||||
|
public <T> T load() {
|
||||||
|
if (loaded) {
|
||||||
|
throw new IllegalStateException("Already loaded");
|
||||||
|
}
|
||||||
|
object-class loaded = true;
|
||||||
|
return (T) class;
|
||||||
|
}
|
||||||
|
""";
|
||||||
|
assertEquals(expected, sb.toString());
|
||||||
|
verify(objectFormatter).format(object, "class");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testConstructorNameFactoryInitialize() throws GenerationException {
|
||||||
|
when(parameters.resourceInjectionType()).thenReturn(ResourceBundleInjectionType.CONSTRUCTOR_NAME);
|
||||||
|
when(parameters.controllerInjectionType()).thenReturn(ControllerInjectionType.FACTORY);
|
||||||
|
when(controllerInfo.hasInitialize()).thenReturn(true);
|
||||||
|
when(object.toString()).thenReturn("object");
|
||||||
|
loadMethodFormatter.formatLoadMethod();
|
||||||
|
final var expected = """
|
||||||
|
/**
|
||||||
|
* Loads the view. Can only be called once.
|
||||||
|
*
|
||||||
|
* @return The view parent
|
||||||
|
*/
|
||||||
|
public <T> T load() {
|
||||||
|
if (loaded) {
|
||||||
|
throw new IllegalStateException("Already loaded");
|
||||||
|
}
|
||||||
|
java.util.ResourceBundleresourceBundle = java.util.ResourceBundle.getBundle(resourceBundleName);
|
||||||
|
controller = controllerFactory.create();
|
||||||
|
object-class controller.initialize();
|
||||||
|
loaded = true;
|
||||||
|
return (T) class;
|
||||||
|
}
|
||||||
|
""";
|
||||||
|
assertEquals(expected, sb.toString());
|
||||||
|
verify(objectFormatter).format(object, "class");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testGetBundleFieldFactoryReflectionInitialize() throws GenerationException {
|
||||||
|
when(parameters.resourceInjectionType()).thenReturn(ResourceBundleInjectionType.GET_BUNDLE);
|
||||||
|
when(parameters.fieldInjectionType()).thenReturn(ControllerFieldInjectionType.FACTORY);
|
||||||
|
when(parameters.methodInjectionType()).thenReturn(ControllerMethodsInjectionType.REFLECTION);
|
||||||
|
when(parameters.bundleMap()).thenReturn(Map.of(className, "bundle"));
|
||||||
|
when(controllerInfo.hasInitialize()).thenReturn(true);
|
||||||
|
when(object.toString()).thenReturn("object");
|
||||||
|
loadMethodFormatter.formatLoadMethod();
|
||||||
|
final var expected = """
|
||||||
|
/**
|
||||||
|
* Loads the view. Can only be called once.
|
||||||
|
*
|
||||||
|
* @return The view parent
|
||||||
|
*/
|
||||||
|
public <T> T load() {
|
||||||
|
if (loaded) {
|
||||||
|
throw new IllegalStateException("Already loaded");
|
||||||
|
}
|
||||||
|
java.util.ResourceBundleresourceBundle = java.util.ResourceBundle.getBundle("bundle");
|
||||||
|
java.util.Map<String, Object>fieldMap = new java.util.HashMap<String, Object>();
|
||||||
|
object-class controller = controllerFactory.create(fieldMap);
|
||||||
|
try {
|
||||||
|
java.lang.reflect.Methodinitialize = controller.getClass().getDeclaredMethod("initialize");
|
||||||
|
initialize.setAccessible(true);
|
||||||
|
initialize.invoke(controller);
|
||||||
|
} catch (final java.lang.reflect.InvocationTargetException | IllegalAccessException | NoSuchMethodException e) {
|
||||||
|
throw new RuntimeException("Error using reflection", e);
|
||||||
|
}
|
||||||
|
loaded = true;
|
||||||
|
return (T) class;
|
||||||
|
}
|
||||||
|
""";
|
||||||
|
assertEquals(expected, sb.toString());
|
||||||
|
verify(objectFormatter).format(object, "class");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testGetBundleFieldFactoryReflectionNoBundle() throws GenerationException {
|
||||||
|
when(parameters.resourceInjectionType()).thenReturn(ResourceBundleInjectionType.GET_BUNDLE);
|
||||||
|
when(parameters.fieldInjectionType()).thenReturn(ControllerFieldInjectionType.FACTORY);
|
||||||
|
when(parameters.methodInjectionType()).thenReturn(com.github.gtache.fxml.compiler.ControllerMethodsInjectionType.REFLECTION);
|
||||||
|
when(parameters.bundleMap()).thenReturn(Map.of());
|
||||||
|
when(object.toString()).thenReturn("object");
|
||||||
|
loadMethodFormatter.formatLoadMethod();
|
||||||
|
final var expected = """
|
||||||
|
/**
|
||||||
|
* Loads the view. Can only be called once.
|
||||||
|
*
|
||||||
|
* @return The view parent
|
||||||
|
*/
|
||||||
|
public <T> T load() {
|
||||||
|
if (loaded) {
|
||||||
|
throw new IllegalStateException("Already loaded");
|
||||||
|
}
|
||||||
|
java.util.Map<String, Object>fieldMap = new java.util.HashMap<String, Object>();
|
||||||
|
object-class controller = controllerFactory.create(fieldMap);
|
||||||
|
loaded = true;
|
||||||
|
return (T) class;
|
||||||
|
}
|
||||||
|
""";
|
||||||
|
assertEquals(expected, sb.toString());
|
||||||
|
verify(objectFormatter).format(object, "class");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testIllegal() {
|
||||||
|
assertThrows(NullPointerException.class, () -> new LoadMethodFormatter(null, progress));
|
||||||
|
assertThrows(NullPointerException.class, () -> new LoadMethodFormatter(helperProvider, null));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,8 +1,631 @@
|
|||||||
package com.github.gtache.fxml.compiler.impl.internal;
|
package com.github.gtache.fxml.compiler.impl.internal;
|
||||||
|
|
||||||
|
import com.github.gtache.fxml.compiler.ControllerFieldInfo;
|
||||||
|
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.GenerationRequest;
|
||||||
|
import com.github.gtache.fxml.compiler.SourceInfo;
|
||||||
|
import com.github.gtache.fxml.compiler.compatibility.GenerationCompatibility;
|
||||||
|
import com.github.gtache.fxml.compiler.parsing.ParsedDefine;
|
||||||
|
import com.github.gtache.fxml.compiler.parsing.ParsedInclude;
|
||||||
|
import com.github.gtache.fxml.compiler.parsing.ParsedObject;
|
||||||
|
import com.github.gtache.fxml.compiler.parsing.ParsedProperty;
|
||||||
|
import com.github.gtache.fxml.compiler.parsing.ParsedReference;
|
||||||
|
import com.github.gtache.fxml.compiler.parsing.impl.*;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
import org.mockito.Mock;
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
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 java.util.SequencedCollection;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
import static org.mockito.ArgumentMatchers.anyInt;
|
||||||
|
import static org.mockito.ArgumentMatchers.anyString;
|
||||||
|
import static org.mockito.Mockito.*;
|
||||||
|
|
||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
class TestObjectFormatter {
|
class TestObjectFormatter {
|
||||||
}
|
|
||||||
|
private final HelperProvider helperProvider;
|
||||||
|
private final ControllerInjector controllerInjector;
|
||||||
|
private final GenerationCompatibilityHelper compatibilityHelper;
|
||||||
|
private final InitializationFormatter initializationFormatter;
|
||||||
|
private final ReflectionHelper reflectionHelper;
|
||||||
|
private final VariableProvider variableProvider;
|
||||||
|
private final GenerationRequest request;
|
||||||
|
private final ControllerInfo controllerInfo;
|
||||||
|
private final SourceInfo sourceInfo;
|
||||||
|
private final StringBuilder sb;
|
||||||
|
private final String variableName;
|
||||||
|
private final ObjectFormatter objectFormatter;
|
||||||
|
|
||||||
|
|
||||||
|
TestObjectFormatter(@Mock final HelperProvider helperProvider, @Mock final GenerationCompatibilityHelper compatibilityHelper,
|
||||||
|
@Mock final InitializationFormatter initializationFormatter, @Mock final ReflectionHelper reflectionHelper,
|
||||||
|
@Mock final VariableProvider variableProvider, @Mock final GenerationRequest request,
|
||||||
|
@Mock final ControllerInfo controllerInfo, @Mock final ControllerInjector controllerInjector,
|
||||||
|
@Mock final SourceInfo sourceInfo) {
|
||||||
|
this.helperProvider = Objects.requireNonNull(helperProvider);
|
||||||
|
this.controllerInjector = Objects.requireNonNull(controllerInjector);
|
||||||
|
this.compatibilityHelper = Objects.requireNonNull(compatibilityHelper);
|
||||||
|
this.initializationFormatter = Objects.requireNonNull(initializationFormatter);
|
||||||
|
this.reflectionHelper = Objects.requireNonNull(reflectionHelper);
|
||||||
|
this.variableProvider = Objects.requireNonNull(variableProvider);
|
||||||
|
this.request = Objects.requireNonNull(request);
|
||||||
|
this.controllerInfo = Objects.requireNonNull(controllerInfo);
|
||||||
|
this.sourceInfo = Objects.requireNonNull(sourceInfo);
|
||||||
|
this.sb = new StringBuilder();
|
||||||
|
this.variableName = "variable";
|
||||||
|
this.objectFormatter = spy(new ObjectFormatter(helperProvider, request, sb));
|
||||||
|
}
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void beforeEach() throws GenerationException {
|
||||||
|
when(helperProvider.getCompatibilityHelper()).thenReturn(compatibilityHelper);
|
||||||
|
when(helperProvider.getControllerInjector()).thenReturn(controllerInjector);
|
||||||
|
when(helperProvider.getInitializationFormatter()).thenReturn(initializationFormatter);
|
||||||
|
when(helperProvider.getReflectionHelper()).thenReturn(reflectionHelper);
|
||||||
|
when(helperProvider.getVariableProvider()).thenReturn(variableProvider);
|
||||||
|
when(compatibilityHelper.getStartVar(anyString())).then(i -> i.getArgument(0));
|
||||||
|
when(compatibilityHelper.getStartVar(anyString(), anyInt())).then(i -> i.getArgument(0));
|
||||||
|
when(variableProvider.getNextVariableName(anyString())).then(i -> i.getArgument(0));
|
||||||
|
when(request.controllerInfo()).thenReturn(controllerInfo);
|
||||||
|
when(request.sourceInfo()).thenReturn(sourceInfo);
|
||||||
|
doAnswer(i -> {
|
||||||
|
final var value = (ParsedInclude) i.getArgument(0);
|
||||||
|
sb.append("include(").append(value.source()).append(", ").append(value.resources()).append(")");
|
||||||
|
return "view";
|
||||||
|
}).when(initializationFormatter).formatSubViewConstructorCall(any());
|
||||||
|
doAnswer(i -> {
|
||||||
|
final var id = (String) i.getArgument(0);
|
||||||
|
final var variable = (String) i.getArgument(1);
|
||||||
|
sb.append("inject(").append(id).append(", ").append(variable).append(")");
|
||||||
|
return null;
|
||||||
|
}).when(controllerInjector).injectControllerField(anyString(), anyString());
|
||||||
|
when(compatibilityHelper.getStartVar(any(ParsedObject.class))).thenReturn("startVar");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testHandleIdNull() throws GenerationException {
|
||||||
|
final var parsedObject = new ParsedValueImpl("className", Map.of("fx:value", new ParsedPropertyImpl("fx:value", null, "value")));
|
||||||
|
objectFormatter.format(parsedObject, variableName);
|
||||||
|
verifyNoInteractions(controllerInjector, reflectionHelper, variableProvider);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testHandleIdNotFound() throws GenerationException {
|
||||||
|
final var className = "className";
|
||||||
|
final var value = "id";
|
||||||
|
final var parsedObject = new ParsedValueImpl(className, Map.of("fx:id", new ParsedPropertyImpl("fx:id", null, value),
|
||||||
|
"fx:value", new ParsedPropertyImpl("fx:value", null, "value")));
|
||||||
|
objectFormatter.format(parsedObject, variableName);
|
||||||
|
final var variableInfo = new VariableInfo(value, parsedObject, variableName, className);
|
||||||
|
verify(variableProvider).addVariableInfo(value, variableInfo);
|
||||||
|
verifyNoInteractions(controllerInjector, reflectionHelper);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testHandleIdGeneric(@Mock final ControllerFieldInfo fieldInfo) throws GenerationException {
|
||||||
|
final var value = "id";
|
||||||
|
final var genericClassName = "javafx.scene.control.ComboBox";
|
||||||
|
final var parsedObject = new ParsedValueImpl(genericClassName, Map.of("fx:id", new ParsedPropertyImpl("fx:id", null, value),
|
||||||
|
"fx:value", new ParsedPropertyImpl("fx:value", null, "value")));
|
||||||
|
final var genericTypes = "<java.lang.String, java.lang.Integer>";
|
||||||
|
when(reflectionHelper.getGenericTypes(parsedObject)).thenReturn("<java.lang.String, java.lang.Integer>");
|
||||||
|
when(controllerInfo.fieldInfo(value)).thenReturn(fieldInfo);
|
||||||
|
objectFormatter.format(parsedObject, variableName);
|
||||||
|
final var variableInfo = new VariableInfo(value, parsedObject, variableName, genericClassName + genericTypes);
|
||||||
|
verify(variableProvider).addVariableInfo(value, variableInfo);
|
||||||
|
verify(reflectionHelper).getGenericTypes(parsedObject);
|
||||||
|
verify(controllerInfo).fieldInfo(value);
|
||||||
|
verify(controllerInjector).injectControllerField(value, variableName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testHandleId(@Mock final ControllerFieldInfo fieldInfo) throws GenerationException {
|
||||||
|
final var className = "java.lang.String";
|
||||||
|
final var value = "id";
|
||||||
|
final var parsedObject = new ParsedValueImpl(className, Map.of("fx:id", new ParsedPropertyImpl("fx:id", null, value),
|
||||||
|
"fx:value", new ParsedPropertyImpl("fx:value", null, "value")));
|
||||||
|
when(controllerInfo.fieldInfo(value)).thenReturn(fieldInfo);
|
||||||
|
objectFormatter.format(parsedObject, variableName);
|
||||||
|
final var variableInfo = new VariableInfo(value, parsedObject, variableName, className);
|
||||||
|
verify(variableProvider).addVariableInfo(value, variableInfo);
|
||||||
|
verify(controllerInfo).fieldInfo(value);
|
||||||
|
verify(controllerInjector).injectControllerField(value, variableName);
|
||||||
|
verifyNoInteractions(reflectionHelper);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testHandleIdPropertyTooManyChildren(@Mock final ControllerFieldInfo fieldInfo, @Mock PropertyFormatter propertyFormatter) {
|
||||||
|
when(helperProvider.getPropertyFormatter()).thenReturn(propertyFormatter);
|
||||||
|
final var className = "javafx.scene.control.Label";
|
||||||
|
final var value = "id";
|
||||||
|
final var properties = new LinkedHashMap<ParsedProperty, SequencedCollection<ParsedObject>>();
|
||||||
|
properties.put(new ParsedPropertyImpl("fx:id", null, ""), List.of(new ParsedTextImpl("value"), new ParsedTextImpl("value2")));
|
||||||
|
final var parsedObject = new ParsedObjectImpl(className, Map.of(), properties, List.of());
|
||||||
|
when(controllerInfo.fieldInfo(value)).thenReturn(fieldInfo);
|
||||||
|
assertThrows(GenerationException.class, () -> objectFormatter.format(parsedObject, variableName));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testHandleIdPropertyNoChildren(@Mock final ControllerFieldInfo fieldInfo, @Mock PropertyFormatter propertyFormatter) {
|
||||||
|
when(helperProvider.getPropertyFormatter()).thenReturn(propertyFormatter);
|
||||||
|
final var className = "javafx.scene.control.Label";
|
||||||
|
final var value = "id";
|
||||||
|
final var properties = new LinkedHashMap<ParsedProperty, SequencedCollection<ParsedObject>>();
|
||||||
|
properties.put(new ParsedPropertyImpl("fx:id", null, ""), List.of());
|
||||||
|
final var parsedObject = new ParsedObjectImpl(className, Map.of(), properties, List.of());
|
||||||
|
when(controllerInfo.fieldInfo(value)).thenReturn(fieldInfo);
|
||||||
|
assertThrows(GenerationException.class, () -> objectFormatter.format(parsedObject, variableName));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testHandleIdPropertyNotText(@Mock final ControllerFieldInfo fieldInfo, @Mock PropertyFormatter propertyFormatter) {
|
||||||
|
when(helperProvider.getPropertyFormatter()).thenReturn(propertyFormatter);
|
||||||
|
final var className = "javafx.scene.control.Label";
|
||||||
|
final var value = "id";
|
||||||
|
final var properties = new LinkedHashMap<ParsedProperty, SequencedCollection<ParsedObject>>();
|
||||||
|
properties.put(new ParsedPropertyImpl("fx:id", null, ""), List.of(mock(ParsedObject.class)));
|
||||||
|
final var parsedObject = new ParsedObjectImpl(className, Map.of(), properties, List.of());
|
||||||
|
when(controllerInfo.fieldInfo(value)).thenReturn(fieldInfo);
|
||||||
|
assertThrows(GenerationException.class, () -> objectFormatter.format(parsedObject, variableName));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testHandleIdProperty(@Mock final ControllerFieldInfo fieldInfo, @Mock PropertyFormatter propertyFormatter) throws GenerationException {
|
||||||
|
when(helperProvider.getPropertyFormatter()).thenReturn(propertyFormatter);
|
||||||
|
final var className = "javafx.scene.control.Label";
|
||||||
|
final var value = "id";
|
||||||
|
final var properties = new LinkedHashMap<ParsedProperty, SequencedCollection<ParsedObject>>();
|
||||||
|
final var define = mock(ParsedDefine.class);
|
||||||
|
properties.put(new ParsedPropertyImpl("fx:id", null, ""), List.of(define, new ParsedTextImpl(value)));
|
||||||
|
final var parsedObject = new ParsedObjectImpl(className, Map.of(), properties, List.of());
|
||||||
|
when(controllerInfo.fieldInfo(value)).thenReturn(fieldInfo);
|
||||||
|
doNothing().when(objectFormatter).format(define, "define");
|
||||||
|
objectFormatter.format(parsedObject, variableName);
|
||||||
|
final var variableInfo = new VariableInfo(value, parsedObject, variableName, className);
|
||||||
|
verify(variableProvider).addVariableInfo(value, variableInfo);
|
||||||
|
verify(controllerInfo).fieldInfo(value);
|
||||||
|
verify(controllerInjector).injectControllerField(value, variableName);
|
||||||
|
verify(objectFormatter).format(define, "define");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFormatConstant() throws GenerationException {
|
||||||
|
final var className = "java.lang.String";
|
||||||
|
final var attributes = new HashMap<String, ParsedProperty>();
|
||||||
|
attributes.put("fx:constant", new ParsedPropertyImpl("fx:constant", null, "value"));
|
||||||
|
final var constant = new ParsedConstantImpl(className, attributes);
|
||||||
|
objectFormatter.format(constant, variableName);
|
||||||
|
final var expected = "java.lang.String" + variableName + " = " + className + "." + constant.constant() + ";\n";
|
||||||
|
assertEquals(expected, sb.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFormatCopyNoInfo() {
|
||||||
|
final var copy = new ParsedCopyImpl("source");
|
||||||
|
assertThrows(GenerationException.class, () -> objectFormatter.format(copy, variableName));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFormatCopy(@Mock final VariableInfo variableInfo) throws GenerationException {
|
||||||
|
when(variableProvider.getVariableInfo("source")).thenReturn(variableInfo);
|
||||||
|
final var infoVariableName = "vn";
|
||||||
|
when(variableInfo.variableName()).thenReturn(infoVariableName);
|
||||||
|
final var className = "className";
|
||||||
|
when(variableInfo.className()).thenReturn(className);
|
||||||
|
final var copy = new ParsedCopyImpl("source");
|
||||||
|
objectFormatter.format(copy, variableName);
|
||||||
|
final var expected = "classNamevariable = new className(vn);\n";
|
||||||
|
assertEquals(expected, sb.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFormatDefine(@Mock final ParsedObject inner, @Mock final ParsedReference inner2) throws GenerationException {
|
||||||
|
final var define = new ParsedDefineImpl(List.of(inner, inner2));
|
||||||
|
doAnswer(i -> sb.append("object")).when(objectFormatter).format(inner, "definedObject");
|
||||||
|
doAnswer(i -> sb.append("reference")).when(objectFormatter).format(inner2, "definedObject");
|
||||||
|
objectFormatter.format(define, variableName);
|
||||||
|
assertEquals("objectreference", sb.toString());
|
||||||
|
verify(objectFormatter).format(inner, "definedObject");
|
||||||
|
verify(objectFormatter).format(inner2, "definedObject");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFormatFactoryVar(@Mock final GenerationParameters parameters, @Mock final GenerationCompatibility compatibility) throws GenerationException {
|
||||||
|
when(parameters.compatibility()).thenReturn(compatibility);
|
||||||
|
when(request.parameters()).thenReturn(parameters);
|
||||||
|
when(compatibility.useVar()).thenReturn(true);
|
||||||
|
|
||||||
|
final var children = List.<ParsedObject>of(new ParsedDefineImpl(List.of()));
|
||||||
|
final var arguments = List.of(mock(ParsedObject.class), mock(ParsedObject.class));
|
||||||
|
for (final var c : children) {
|
||||||
|
doAnswer(i -> {
|
||||||
|
final var object = (ParsedObject) i.getArgument(0);
|
||||||
|
sb.append("define");
|
||||||
|
return object;
|
||||||
|
}).when(objectFormatter).format(c, "parseddefine");
|
||||||
|
}
|
||||||
|
for (final var a : arguments) {
|
||||||
|
doAnswer(i -> {
|
||||||
|
final var object = (ParsedObject) i.getArgument(0);
|
||||||
|
sb.append("argument");
|
||||||
|
return object;
|
||||||
|
}).when(objectFormatter).format(a, "arg");
|
||||||
|
}
|
||||||
|
final var factory = new ParsedFactoryImpl("javafx.collections.FXCollections",
|
||||||
|
Map.of("fx:factory", new ParsedPropertyImpl("fx:factory", null, "observableArrayList")),
|
||||||
|
arguments, children);
|
||||||
|
objectFormatter.format(factory, variableName);
|
||||||
|
assertEquals("defineargumentargumentjavafx.collections.FXCollectionsvariable = javafx.collections.FXCollections.observableArrayList(arg, arg);\n", sb.toString());
|
||||||
|
for (final var child : children) {
|
||||||
|
verify(objectFormatter).format(child, "parseddefine");
|
||||||
|
}
|
||||||
|
for (final var argument : arguments) {
|
||||||
|
verify(objectFormatter).format(argument, "arg");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFormatFactory(@Mock final GenerationParameters parameters, @Mock final GenerationCompatibility compatibility) throws GenerationException {
|
||||||
|
when(parameters.compatibility()).thenReturn(compatibility);
|
||||||
|
when(request.parameters()).thenReturn(parameters);
|
||||||
|
|
||||||
|
final var children = List.<ParsedObject>of(new ParsedDefineImpl(List.of()));
|
||||||
|
for (final var c : children) {
|
||||||
|
doAnswer(i -> {
|
||||||
|
final var object = (ParsedObject) i.getArgument(0);
|
||||||
|
sb.append("define");
|
||||||
|
return object;
|
||||||
|
}).when(objectFormatter).format(c, "parseddefine");
|
||||||
|
}
|
||||||
|
final var factory = new ParsedFactoryImpl("javafx.collections.FXCollections",
|
||||||
|
Map.of("fx:factory", new ParsedPropertyImpl("fx:factory", null, "emptyObservableList")),
|
||||||
|
List.of(), children);
|
||||||
|
objectFormatter.format(factory, variableName);
|
||||||
|
assertEquals("definejavafx.collections.ObservableListvariable = javafx.collections.FXCollections.emptyObservableList();\n", sb.toString());
|
||||||
|
for (final var child : children) {
|
||||||
|
verify(objectFormatter).format(child, "parseddefine");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFormatIncludeOnlySource() throws GenerationException {
|
||||||
|
final var include = new ParsedIncludeImpl("source", null, null);
|
||||||
|
objectFormatter.format(include, variableName);
|
||||||
|
final var expected = "include(source, null) final javafx.scene.Parent variable = view.load();\n";
|
||||||
|
assertEquals(expected, sb.toString());
|
||||||
|
verify(initializationFormatter).formatSubViewConstructorCall(include);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFormatIncludeIDNotInController(@Mock final SourceInfo innerSourceInfo) throws GenerationException {
|
||||||
|
final var controllerClassName = "controllerClassName";
|
||||||
|
final var source = "source";
|
||||||
|
when(innerSourceInfo.controllerClassName()).thenReturn(controllerClassName);
|
||||||
|
final var sourceToSourceInfo = Map.of(source, innerSourceInfo);
|
||||||
|
when(sourceInfo.sourceToSourceInfo()).thenReturn(sourceToSourceInfo);
|
||||||
|
final var include = new ParsedIncludeImpl("source", "resources", "id");
|
||||||
|
objectFormatter.format(include, variableName);
|
||||||
|
final var expected = "include(source, resources) final javafx.scene.Parent variable = view.load();\n" +
|
||||||
|
"controllerClassNamecontroller = view.controller();\n";
|
||||||
|
assertEquals(expected, sb.toString());
|
||||||
|
verify(initializationFormatter).formatSubViewConstructorCall(include);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFormatIncludeID(@Mock final ControllerFieldInfo fieldInfo, @Mock final SourceInfo innerSourceInfo) throws GenerationException {
|
||||||
|
when(controllerInfo.fieldInfo("id")).thenReturn(fieldInfo);
|
||||||
|
when(controllerInfo.fieldInfo("idController")).thenReturn(fieldInfo);
|
||||||
|
final var controllerClassName = "controllerClassName";
|
||||||
|
final var source = "source";
|
||||||
|
when(innerSourceInfo.controllerClassName()).thenReturn(controllerClassName);
|
||||||
|
final var sourceToSourceInfo = Map.of(source, innerSourceInfo);
|
||||||
|
when(sourceInfo.sourceToSourceInfo()).thenReturn(sourceToSourceInfo);
|
||||||
|
final var include = new ParsedIncludeImpl(source, "resources", "id");
|
||||||
|
objectFormatter.format(include, variableName);
|
||||||
|
final var expected = "include(source, resources) final javafx.scene.Parent variable = view.load();\n" +
|
||||||
|
"controllerClassNamecontroller = view.controller();\ninject(idController, controller)inject(id, variable)";
|
||||||
|
assertEquals(expected, sb.toString());
|
||||||
|
verify(initializationFormatter).formatSubViewConstructorCall(include);
|
||||||
|
verify(controllerInjector).injectControllerField("id", "variable");
|
||||||
|
verify(controllerInjector).injectControllerField("idController", "controller");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFormatReferenceNullVariable() {
|
||||||
|
final var reference = new ParsedReferenceImpl("source");
|
||||||
|
assertThrows(GenerationException.class, () -> objectFormatter.format(reference, null));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFormatReference(@Mock final VariableInfo variableInfo) throws GenerationException {
|
||||||
|
when(variableProvider.getVariableInfo("source")).thenReturn(variableInfo);
|
||||||
|
final var infoVariableName = "vn";
|
||||||
|
when(variableInfo.variableName()).thenReturn(infoVariableName);
|
||||||
|
final var className = "className";
|
||||||
|
when(variableInfo.className()).thenReturn(className);
|
||||||
|
final var reference = new ParsedReferenceImpl("source");
|
||||||
|
objectFormatter.format(reference, variableName);
|
||||||
|
final var expected = "classNamevariable = vn;\n";
|
||||||
|
assertEquals(expected, sb.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFormatValue() throws GenerationException {
|
||||||
|
final var value = new ParsedValueImpl("className", "value");
|
||||||
|
objectFormatter.format(value, variableName);
|
||||||
|
final var expected = "classNamevariable = className.valueOf(\"value\");\n";
|
||||||
|
assertEquals(expected, sb.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFormatText() throws GenerationException {
|
||||||
|
final var text = new ParsedTextImpl("text");
|
||||||
|
objectFormatter.format(text, variableName);
|
||||||
|
final var expected = "Stringvariable = \"text\";\n";
|
||||||
|
assertEquals(expected, sb.toString());
|
||||||
|
verifyNoInteractions(variableProvider);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFormatScene(@Mock final SceneFormatter sceneFormatter) throws GenerationException {
|
||||||
|
when(helperProvider.getSceneFormatter()).thenReturn(sceneFormatter);
|
||||||
|
final var object = new ParsedObjectImpl("javafx.scene.Scene", Map.of(), new LinkedHashMap<>(), List.of());
|
||||||
|
doAnswer(i -> sb.append("scene")).when(sceneFormatter).formatScene(object, variableName);
|
||||||
|
objectFormatter.format(object, variableName);
|
||||||
|
assertEquals("scene", sb.toString());
|
||||||
|
verify(sceneFormatter).formatScene(object, variableName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFormatFont(@Mock final FontFormatter fontFormatter) throws GenerationException {
|
||||||
|
when(helperProvider.getFontFormatter()).thenReturn(fontFormatter);
|
||||||
|
final var object = new ParsedObjectImpl("javafx.scene.text.Font", Map.of(), new LinkedHashMap<>(), List.of());
|
||||||
|
doAnswer(i -> sb.append("font")).when(fontFormatter).formatFont(object, variableName);
|
||||||
|
objectFormatter.format(object, variableName);
|
||||||
|
assertEquals("font", sb.toString());
|
||||||
|
verify(fontFormatter).formatFont(object, variableName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFormatImage(@Mock final ImageFormatter imageFormatter) throws GenerationException {
|
||||||
|
when(helperProvider.getImageFormatter()).thenReturn(imageFormatter);
|
||||||
|
final var object = new ParsedObjectImpl("javafx.scene.image.Image", Map.of(), new LinkedHashMap<>(), List.of());
|
||||||
|
doAnswer(i -> sb.append("image")).when(imageFormatter).formatImage(object, variableName);
|
||||||
|
objectFormatter.format(object, variableName);
|
||||||
|
assertEquals("image", sb.toString());
|
||||||
|
verify(imageFormatter).formatImage(object, variableName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFormatTriangleMesh(@Mock final TriangleMeshFormatter triangleMeshFormatter) throws GenerationException {
|
||||||
|
when(helperProvider.getTriangleMeshFormatter()).thenReturn(triangleMeshFormatter);
|
||||||
|
final var object = new ParsedObjectImpl("javafx.scene.shape.TriangleMesh", Map.of(), new LinkedHashMap<>(), List.of());
|
||||||
|
doAnswer(i -> sb.append("triangleMesh")).when(triangleMeshFormatter).formatTriangleMesh(object, variableName);
|
||||||
|
objectFormatter.format(object, variableName);
|
||||||
|
assertEquals("triangleMesh", sb.toString());
|
||||||
|
verify(triangleMeshFormatter).formatTriangleMesh(object, variableName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFormatURL(@Mock final URLFormatter urlFormatter) throws GenerationException {
|
||||||
|
when(helperProvider.getURLFormatter()).thenReturn(urlFormatter);
|
||||||
|
final var object = new ParsedObjectImpl("java.net.URL", Map.of(), new LinkedHashMap<>(), List.of());
|
||||||
|
doAnswer(i -> sb.append("url")).when(urlFormatter).formatURL(object, variableName);
|
||||||
|
objectFormatter.format(object, variableName);
|
||||||
|
assertEquals("url", sb.toString());
|
||||||
|
verify(urlFormatter).formatURL(object, variableName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFormatWebView(@Mock final WebViewFormatter webViewFormatter) throws GenerationException {
|
||||||
|
when(helperProvider.getWebViewFormatter()).thenReturn(webViewFormatter);
|
||||||
|
final var object = new ParsedObjectImpl("javafx.scene.web.WebView", Map.of(), new LinkedHashMap<>(), List.of());
|
||||||
|
doAnswer(i -> sb.append("webView")).when(webViewFormatter).formatWebView(object, variableName);
|
||||||
|
objectFormatter.format(object, variableName);
|
||||||
|
assertEquals("webView", sb.toString());
|
||||||
|
verify(webViewFormatter).formatWebView(object, variableName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFormatSimpleClassProperties() {
|
||||||
|
final var properties = new LinkedHashMap<ParsedProperty, SequencedCollection<ParsedObject>>();
|
||||||
|
properties.put(new ParsedPropertyImpl("str", null, ""), List.of(mock(ParsedObject.class)));
|
||||||
|
final var parsedObject = new ParsedObjectImpl("java.lang.String", Map.of(), properties, List.of());
|
||||||
|
assertThrows(GenerationException.class, () -> objectFormatter.format(parsedObject, variableName));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFormatSimpleClassInvalidAttribute() {
|
||||||
|
final var parsedObject = new ParsedObjectImpl("java.lang.Integer", Map.of("invalid", new ParsedPropertyImpl("invalid", null, "4")), new LinkedHashMap<>(), List.of());
|
||||||
|
assertThrows(GenerationException.class, () -> objectFormatter.format(parsedObject, variableName));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFormatSimpleClassFXValueHasChildren() {
|
||||||
|
final var parsedObject = new ParsedObjectImpl("java.lang.Byte", Map.of("fx:value", new ParsedPropertyImpl("fx:value", null, "1")), new LinkedHashMap<>(), List.of(mock(ParsedObject.class)));
|
||||||
|
assertThrows(GenerationException.class, () -> objectFormatter.format(parsedObject, variableName));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFormatSimpleClassFXValueHasValue() {
|
||||||
|
final var parsedObject = new ParsedObjectImpl("java.lang.Short", Map.of("fx:value", new ParsedPropertyImpl("fx:value", null, "2"), "value", new ParsedPropertyImpl("value", null, "value")), new LinkedHashMap<>(), List.of());
|
||||||
|
assertThrows(GenerationException.class, () -> objectFormatter.format(parsedObject, variableName));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFormatSimpleClassFXValue() throws GenerationException {
|
||||||
|
final var parsedObject = new ParsedObjectImpl("java.lang.Long", Map.of("fx:value", new ParsedPropertyImpl("fx:value", null, "3")), new LinkedHashMap<>(), List.of());
|
||||||
|
final var expected = "startVarvariable = 3;\n";
|
||||||
|
objectFormatter.format(parsedObject, variableName);
|
||||||
|
assertEquals(expected, sb.toString());
|
||||||
|
verify(compatibilityHelper).getStartVar(parsedObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFormatSimpleClassValueHasChildren() {
|
||||||
|
final var parsedObject = new ParsedObjectImpl("java.lang.Float", Map.of("value", new ParsedPropertyImpl("value", null, "4")), new LinkedHashMap<>(), List.of(mock(ParsedObject.class)));
|
||||||
|
assertThrows(GenerationException.class, () -> objectFormatter.format(parsedObject, variableName));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFormatSimpleClassValue() throws GenerationException {
|
||||||
|
final var parsedObject = new ParsedObjectImpl("java.lang.Double", Map.of("value", new ParsedPropertyImpl("value", null, "5")), new LinkedHashMap<>(), List.of());
|
||||||
|
final var expected = "startVarvariable = 5;\n";
|
||||||
|
objectFormatter.format(parsedObject, variableName);
|
||||||
|
assertEquals(expected, sb.toString());
|
||||||
|
verify(compatibilityHelper).getStartVar(parsedObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFormatSimpleClassNoChildren() {
|
||||||
|
final var parsedObject = new ParsedObjectImpl("javafx.geometry.Pos", Map.of(), new LinkedHashMap<>(), List.of());
|
||||||
|
assertThrows(GenerationException.class, () -> objectFormatter.format(parsedObject, variableName));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFormatSimpleClassChildren() {
|
||||||
|
final var parsedObject = new ParsedObjectImpl("javafx.geometry.Pos", Map.of(), new LinkedHashMap<>(), List.of(mock(ParsedObject.class), mock(ParsedObject.class)));
|
||||||
|
assertThrows(GenerationException.class, () -> objectFormatter.format(parsedObject, variableName));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFormatSimpleClassChildNotText() {
|
||||||
|
final var parsedObject = new ParsedObjectImpl("javafx.geometry.Pos", Map.of(), new LinkedHashMap<>(), List.of(mock(ParsedObject.class)));
|
||||||
|
assertThrows(GenerationException.class, () -> objectFormatter.format(parsedObject, variableName));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFormatSimpleClassChild() throws GenerationException {
|
||||||
|
final var define = mock(ParsedDefine.class);
|
||||||
|
doAnswer(i -> sb.append("define")).when(objectFormatter).format(define, "define");
|
||||||
|
final var text = new ParsedTextImpl("TOP_LEFT");
|
||||||
|
final var parsedObject = new ParsedObjectImpl("javafx.geometry.Pos", Map.of(), new LinkedHashMap<>(), List.of(define, text));
|
||||||
|
final var expected = "definestartVarvariable = javafx.geometry.Pos.TOP_LEFT;\n";
|
||||||
|
objectFormatter.format(parsedObject, variableName);
|
||||||
|
assertEquals(expected, sb.toString());
|
||||||
|
verify(objectFormatter).format(define, "define");
|
||||||
|
verify(compatibilityHelper).getStartVar(parsedObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFormatNoConstructorNoProperties() {
|
||||||
|
final var className = "javafx.scene.Cursor";
|
||||||
|
final var parsedObject = new ParsedObjectImpl(className, Map.of(), new LinkedHashMap<>(), List.of());
|
||||||
|
assertThrows(GenerationException.class, () -> objectFormatter.format(parsedObject, variableName));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFormatNoConstructorTooManyProperties() {
|
||||||
|
final var className = "javafx.scene.Cursor";
|
||||||
|
final var attributes = new HashMap<String, ParsedProperty>();
|
||||||
|
attributes.put("fx:constant", new ParsedPropertyImpl("fx:constant", null, "value"));
|
||||||
|
attributes.put("fx:id", new ParsedPropertyImpl("fx:id", null, "id"));
|
||||||
|
attributes.put("value", new ParsedPropertyImpl("value", null, "value"));
|
||||||
|
final var parsedObject = new ParsedObjectImpl(className, attributes, new LinkedHashMap<>(), List.of());
|
||||||
|
assertThrows(GenerationException.class, () -> objectFormatter.format(parsedObject, variableName));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFormatNoConstructorNoFXConstant() {
|
||||||
|
final var className = "javafx.scene.Cursor";
|
||||||
|
final var attributes = new HashMap<String, ParsedProperty>();
|
||||||
|
attributes.put("fx:id", new ParsedPropertyImpl("fx:id", null, "id"));
|
||||||
|
final var parsedObject = new ParsedObjectImpl(className, attributes, new LinkedHashMap<>(), List.of());
|
||||||
|
assertThrows(GenerationException.class, () -> objectFormatter.format(parsedObject, variableName));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFormatNoConstructor() throws GenerationException {
|
||||||
|
final var className = "javafx.scene.Cursor";
|
||||||
|
final var attributes = new HashMap<String, ParsedProperty>();
|
||||||
|
attributes.put("fx:constant", new ParsedPropertyImpl("fx:constant", null, "TEXT"));
|
||||||
|
final var parsedObject = new ParsedObjectImpl(className, attributes, new LinkedHashMap<>(), List.of());
|
||||||
|
final var expected = "startVarvariable = javafx.scene.Cursor.TEXT;\n";
|
||||||
|
objectFormatter.format(parsedObject, variableName);
|
||||||
|
assertEquals(expected, sb.toString());
|
||||||
|
verify(compatibilityHelper).getStartVar(parsedObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFormatConstructorNamedArgs(@Mock final PropertyFormatter propertyFormatter) throws GenerationException {
|
||||||
|
when(helperProvider.getPropertyFormatter()).thenReturn(propertyFormatter);
|
||||||
|
doAnswer(i -> sb.append("property")).when(propertyFormatter).formatProperty(any(ParsedProperty.class), any(), any());
|
||||||
|
final var className = "javafx.scene.control.Spinner";
|
||||||
|
final var attributes = Map.<String, ParsedProperty>of("min", new ParsedPropertyImpl("min", null, "1"),
|
||||||
|
"max", new ParsedPropertyImpl("max", null, "2"), "editable", new ParsedPropertyImpl("editable", null, "false"),
|
||||||
|
"initialValue", new ParsedPropertyImpl("initialValue", null, "3"));
|
||||||
|
final var label = new ParsedObjectImpl("javafx.scene.control.Label", Map.of(), new LinkedHashMap<>(), List.of());
|
||||||
|
final var properties = new LinkedHashMap<ParsedProperty, SequencedCollection<ParsedObject>>();
|
||||||
|
properties.put(new ParsedPropertyImpl("childrenUnmodifiable", null, ""), List.of(label));
|
||||||
|
final var define = mock(ParsedDefine.class);
|
||||||
|
doAnswer(i -> sb.append("define")).when(objectFormatter).format(define, "define");
|
||||||
|
final var parsedObject = new ParsedObjectImpl(className, attributes, properties, List.of(define));
|
||||||
|
when(reflectionHelper.getGenericTypes(parsedObject)).thenReturn("<bla>");
|
||||||
|
objectFormatter.format(parsedObject, variableName);
|
||||||
|
final var expected = "definestartVarvariable = new javafx.scene.control.Spinner<bla>(1, 2, 3);\nproperty";
|
||||||
|
assertEquals(expected, sb.toString());
|
||||||
|
verify(propertyFormatter).formatProperty(new ParsedPropertyImpl("editable", null, "false"), parsedObject, variableName);
|
||||||
|
verify(propertyFormatter).formatProperty(new ParsedPropertyImpl("childrenUnmodifiable", null, ""), List.of(label), parsedObject, variableName);
|
||||||
|
verify(objectFormatter).format(define, "define");
|
||||||
|
verify(compatibilityHelper).getStartVar(parsedObject);
|
||||||
|
verify(reflectionHelper).getGenericTypes(parsedObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFormatConstructorDefault(@Mock final PropertyFormatter propertyFormatter) throws GenerationException {
|
||||||
|
when(helperProvider.getPropertyFormatter()).thenReturn(propertyFormatter);
|
||||||
|
doAnswer(i -> sb.append("property")).when(propertyFormatter).formatProperty(any(ParsedProperty.class), anyList(), any(), any());
|
||||||
|
final var className = "javafx.scene.control.Spinner";
|
||||||
|
final var attributes = Map.<String, ParsedProperty>of();
|
||||||
|
final var label = new ParsedObjectImpl("javafx.scene.control.Label", Map.of(), new LinkedHashMap<>(), List.of());
|
||||||
|
final var property = new ParsedPropertyImpl("childrenUnmodifiable", null, "");
|
||||||
|
final var properties = new LinkedHashMap<ParsedProperty, SequencedCollection<ParsedObject>>();
|
||||||
|
properties.put(property, List.of(label, label));
|
||||||
|
final var parsedObject = new ParsedObjectImpl(className, attributes, properties, List.of());
|
||||||
|
when(reflectionHelper.getGenericTypes(parsedObject)).thenReturn("");
|
||||||
|
objectFormatter.format(parsedObject, variableName);
|
||||||
|
final var expected = "startVarvariable = new javafx.scene.control.Spinner();\nproperty";
|
||||||
|
assertEquals(expected, sb.toString());
|
||||||
|
verify(propertyFormatter).formatProperty(property, List.of(label, label), parsedObject, variableName);
|
||||||
|
verify(compatibilityHelper).getStartVar(parsedObject);
|
||||||
|
verify(reflectionHelper).getGenericTypes(parsedObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFormatConstructorDefaultProperty(@Mock final PropertyFormatter propertyFormatter) throws GenerationException {
|
||||||
|
when(helperProvider.getPropertyFormatter()).thenReturn(propertyFormatter);
|
||||||
|
doAnswer(i -> sb.append("property")).when(propertyFormatter).formatProperty(any(ParsedProperty.class), anyList(), any(), any());
|
||||||
|
final var className = "javafx.scene.layout.StackPane";
|
||||||
|
final var attributes = Map.<String, ParsedProperty>of();
|
||||||
|
final var label = new ParsedObjectImpl("javafx.scene.control.Label", Map.of(), new LinkedHashMap<>(), List.of());
|
||||||
|
final var children = List.<ParsedObject>of(label, label);
|
||||||
|
final var parsedObject = new ParsedObjectImpl(className, attributes, new LinkedHashMap<>(), children);
|
||||||
|
when(reflectionHelper.getGenericTypes(parsedObject)).thenReturn("");
|
||||||
|
objectFormatter.format(parsedObject, variableName);
|
||||||
|
final var expected = "startVarvariable = new javafx.scene.layout.StackPane();\nproperty";
|
||||||
|
assertEquals(expected, sb.toString());
|
||||||
|
verify(propertyFormatter).formatProperty(new ParsedPropertyImpl("children", null, ""), children, parsedObject, variableName);
|
||||||
|
verify(compatibilityHelper).getStartVar(parsedObject);
|
||||||
|
verify(reflectionHelper).getGenericTypes(parsedObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testIllegal() {
|
||||||
|
assertThrows(NullPointerException.class, () -> new ObjectFormatter(null, request, sb));
|
||||||
|
assertThrows(NullPointerException.class, () -> new ObjectFormatter(helperProvider, null, sb));
|
||||||
|
assertThrows(NullPointerException.class, () -> new ObjectFormatter(helperProvider, request, null));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,8 +1,342 @@
|
|||||||
package com.github.gtache.fxml.compiler.impl.internal;
|
package com.github.gtache.fxml.compiler.impl.internal;
|
||||||
|
|
||||||
|
import com.github.gtache.fxml.compiler.ControllerFieldInjectionType;
|
||||||
|
import com.github.gtache.fxml.compiler.GenerationException;
|
||||||
|
import com.github.gtache.fxml.compiler.GenerationParameters;
|
||||||
|
import com.github.gtache.fxml.compiler.GenerationRequest;
|
||||||
|
import com.github.gtache.fxml.compiler.ResourceBundleInjectionType;
|
||||||
|
import com.github.gtache.fxml.compiler.parsing.ParsedDefine;
|
||||||
|
import com.github.gtache.fxml.compiler.parsing.ParsedObject;
|
||||||
|
import com.github.gtache.fxml.compiler.parsing.ParsedProperty;
|
||||||
|
import com.github.gtache.fxml.compiler.parsing.impl.ParsedObjectImpl;
|
||||||
|
import com.github.gtache.fxml.compiler.parsing.impl.ParsedPropertyImpl;
|
||||||
|
import com.github.gtache.fxml.compiler.parsing.impl.ParsedTextImpl;
|
||||||
|
import javafx.event.EventHandler;
|
||||||
|
import javafx.scene.layout.HBox;
|
||||||
|
import javafx.scene.layout.Priority;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
import org.mockito.Mock;
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.SequencedCollection;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.ArgumentMatchers.anyString;
|
||||||
|
import static org.mockito.Mockito.*;
|
||||||
|
|
||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
class TestPropertyFormatter {
|
class TestPropertyFormatter {
|
||||||
|
|
||||||
|
private final HelperProvider helperProvider;
|
||||||
|
private final VariableProvider variableProvider;
|
||||||
|
private final GenerationCompatibilityHelper compatibilityHelper;
|
||||||
|
private final ControllerInjector controllerInjector;
|
||||||
|
private final FieldSetter fieldSetter;
|
||||||
|
private final ValueFormatter valueFormatter;
|
||||||
|
private final GenerationProgress progress;
|
||||||
|
private final GenerationRequest request;
|
||||||
|
private final GenerationParameters parameters;
|
||||||
|
private final ParsedObject rootObject;
|
||||||
|
private final ParsedProperty property;
|
||||||
|
private final String variableName;
|
||||||
|
private final StringBuilder sb;
|
||||||
|
private final List<String> controllerFactoryPostAction;
|
||||||
|
private final PropertyFormatter propertyFormatter;
|
||||||
|
|
||||||
|
TestPropertyFormatter(@Mock final HelperProvider helperProvider, @Mock final VariableProvider variableProvider,
|
||||||
|
@Mock final GenerationCompatibilityHelper compatibilityHelper, @Mock final ControllerInjector controllerInjector,
|
||||||
|
@Mock final FieldSetter fieldSetter, @Mock final ValueFormatter valueFormatter, @Mock final GenerationProgress progress,
|
||||||
|
@Mock final GenerationRequest request, @Mock final GenerationParameters parameters,
|
||||||
|
@Mock final ParsedObject rootObject, @Mock final ParsedProperty property) {
|
||||||
|
this.helperProvider = Objects.requireNonNull(helperProvider);
|
||||||
|
this.variableProvider = Objects.requireNonNull(variableProvider);
|
||||||
|
this.compatibilityHelper = Objects.requireNonNull(compatibilityHelper);
|
||||||
|
this.controllerInjector = Objects.requireNonNull(controllerInjector);
|
||||||
|
this.fieldSetter = Objects.requireNonNull(fieldSetter);
|
||||||
|
this.valueFormatter = Objects.requireNonNull(valueFormatter);
|
||||||
|
this.progress = Objects.requireNonNull(progress);
|
||||||
|
this.request = Objects.requireNonNull(request);
|
||||||
|
this.parameters = Objects.requireNonNull(parameters);
|
||||||
|
this.rootObject = Objects.requireNonNull(rootObject);
|
||||||
|
this.property = Objects.requireNonNull(property);
|
||||||
|
this.variableName = "variable";
|
||||||
|
this.sb = new StringBuilder();
|
||||||
|
this.controllerFactoryPostAction = new ArrayList<>();
|
||||||
|
this.propertyFormatter = spy(new PropertyFormatter(helperProvider, progress));
|
||||||
|
}
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void beforeEach() throws GenerationException {
|
||||||
|
when(helperProvider.getCompatibilityHelper()).thenReturn(compatibilityHelper);
|
||||||
|
when(helperProvider.getControllerInjector()).thenReturn(controllerInjector);
|
||||||
|
when(helperProvider.getFieldSetter()).thenReturn(fieldSetter);
|
||||||
|
when(helperProvider.getValueFormatter()).thenReturn(valueFormatter);
|
||||||
|
when(helperProvider.getVariableProvider()).thenReturn(variableProvider);
|
||||||
|
when(variableProvider.getNextVariableName(anyString())).then(i -> i.getArgument(0));
|
||||||
|
when(progress.request()).thenReturn(request);
|
||||||
|
when(request.parameters()).thenReturn(parameters);
|
||||||
|
when(request.rootObject()).thenReturn(rootObject);
|
||||||
|
when(progress.stringBuilder()).thenReturn(sb);
|
||||||
|
when(progress.controllerFactoryPostAction()).thenReturn(controllerFactoryPostAction);
|
||||||
|
when(compatibilityHelper.getListOf()).thenReturn("listof(");
|
||||||
|
when(valueFormatter.getArg(anyString(), any())).then(i -> i.getArgument(0) + "-" + i.getArgument(1));
|
||||||
|
doAnswer(i -> sb.append(i.getArgument(0) + "-" + i.getArgument(1))).when(controllerInjector).injectEventHandlerControllerMethod(any(), anyString());
|
||||||
|
doAnswer(i -> sb.append(i.getArgument(0) + "-" + i.getArgument(1))).when(fieldSetter).setEventHandler(any(), anyString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFormatPropertyId() throws GenerationException {
|
||||||
|
when(property.name()).thenReturn("fx:id");
|
||||||
|
propertyFormatter.formatProperty(property, rootObject, variableName);
|
||||||
|
assertEquals("", sb.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFormatControllerSame() {
|
||||||
|
when(property.name()).thenReturn("fx:controller");
|
||||||
|
assertDoesNotThrow(() -> propertyFormatter.formatProperty(property, rootObject, variableName));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFormatControllerDifferent() {
|
||||||
|
when(property.name()).thenReturn("fx:controller");
|
||||||
|
assertThrows(GenerationException.class, () -> propertyFormatter.formatProperty(property, mock(ParsedObject.class), variableName));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFormatEventHandlerMethod() throws GenerationException {
|
||||||
|
when(property.name()).thenReturn("onAction");
|
||||||
|
when(property.sourceType()).thenReturn(EventHandler.class.getName());
|
||||||
|
when(property.value()).thenReturn("#method");
|
||||||
|
propertyFormatter.formatProperty(property, rootObject, variableName);
|
||||||
|
final var expected = property + "-" + variableName;
|
||||||
|
assertEquals(expected, sb.toString());
|
||||||
|
verify(controllerInjector).injectEventHandlerControllerMethod(property, variableName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFormatEventHandlerField() throws GenerationException {
|
||||||
|
when(property.name()).thenReturn("onAction");
|
||||||
|
when(property.sourceType()).thenReturn(EventHandler.class.getName());
|
||||||
|
when(property.value()).thenReturn("field");
|
||||||
|
propertyFormatter.formatProperty(property, rootObject, variableName);
|
||||||
|
final var expected = property + "-" + variableName;
|
||||||
|
assertEquals(expected, sb.toString());
|
||||||
|
verify(fieldSetter).setEventHandler(property, variableName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFormatStaticProperty() throws GenerationException {
|
||||||
|
when(property.sourceType()).thenReturn(HBox.class.getName());
|
||||||
|
when(property.name()).thenReturn("hgrow");
|
||||||
|
when(property.value()).thenReturn("value");
|
||||||
|
propertyFormatter.formatProperty(property, rootObject, variableName);
|
||||||
|
final var arg = "value-" + Priority.class;
|
||||||
|
final var expected = " javafx.scene.layout.HBox.setHgrow(" + variableName + ", " + arg + ");\n";
|
||||||
|
assertEquals(expected, sb.toString());
|
||||||
|
verify(valueFormatter).getArg("value", Priority.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFormatStaticNotFound() {
|
||||||
|
when(property.sourceType()).thenReturn(HBox.class.getName());
|
||||||
|
when(property.name()).thenReturn("vvvvvvv");
|
||||||
|
when(property.value()).thenReturn("value");
|
||||||
|
assertThrows(GenerationException.class, () -> propertyFormatter.formatProperty(property, rootObject, variableName));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFormatSetProperty() throws GenerationException {
|
||||||
|
when(rootObject.className()).thenReturn("javafx.scene.control.Label");
|
||||||
|
when(property.name()).thenReturn("text");
|
||||||
|
when(property.value()).thenReturn("value");
|
||||||
|
propertyFormatter.formatProperty(property, rootObject, variableName);
|
||||||
|
final var arg = "value-" + String.class;
|
||||||
|
final var expected = " " + variableName + ".setText(" + arg + ");\n";
|
||||||
|
assertEquals(expected, sb.toString());
|
||||||
|
verify(valueFormatter).getArg("value", String.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFormatSetPropertyLater() throws GenerationException {
|
||||||
|
when(parameters.resourceInjectionType()).thenReturn(ResourceBundleInjectionType.GETTER);
|
||||||
|
when(parameters.fieldInjectionType()).thenReturn(ControllerFieldInjectionType.FACTORY);
|
||||||
|
when(rootObject.className()).thenReturn("javafx.scene.control.Label");
|
||||||
|
when(property.name()).thenReturn("text");
|
||||||
|
when(property.value()).thenReturn("%value");
|
||||||
|
propertyFormatter.formatProperty(property, rootObject, variableName);
|
||||||
|
final var arg = "%value-" + String.class;
|
||||||
|
final var expected = " " + variableName + ".setText(" + arg + ");\n";
|
||||||
|
assertEquals("", sb.toString());
|
||||||
|
assertEquals(1, controllerFactoryPostAction.size());
|
||||||
|
assertEquals(expected, controllerFactoryPostAction.getFirst());
|
||||||
|
verify(valueFormatter).getArg("%value", String.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFormatGetProperty() throws GenerationException {
|
||||||
|
when(rootObject.className()).thenReturn("javafx.scene.layout.HBox");
|
||||||
|
when(property.name()).thenReturn("children");
|
||||||
|
when(property.value()).thenReturn("value");
|
||||||
|
propertyFormatter.formatProperty(property, rootObject, variableName);
|
||||||
|
final var arg = "value-" + String.class;
|
||||||
|
final var expected = " " + variableName + ".getChildren().addAll(listof(" + arg + "));\n";
|
||||||
|
assertEquals(expected, sb.toString());
|
||||||
|
verify(valueFormatter).getArg("value", String.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFormatNoProperty() {
|
||||||
|
when(rootObject.className()).thenReturn("javafx.scene.layout.HBox");
|
||||||
|
when(property.name()).thenReturn("whatever");
|
||||||
|
when(property.value()).thenReturn("value");
|
||||||
|
assertThrows(GenerationException.class, () -> propertyFormatter.formatProperty(property, rootObject, variableName));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFormatListParsedDefine() {
|
||||||
|
final var values = List.of(mock(ParsedDefine.class));
|
||||||
|
assertThrows(GenerationException.class, () -> propertyFormatter.formatProperty(property, values, rootObject, variableName));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFormatListSingleValue() throws GenerationException {
|
||||||
|
final var text = new ParsedTextImpl("text");
|
||||||
|
final var values = List.of(text);
|
||||||
|
final var emptyProperty = new ParsedPropertyImpl("name", null, "");
|
||||||
|
final var newProperty = new ParsedPropertyImpl("name", null, text.text());
|
||||||
|
doNothing().when(propertyFormatter).formatProperty(newProperty, rootObject, variableName);
|
||||||
|
propertyFormatter.formatProperty(emptyProperty, values, rootObject, variableName);
|
||||||
|
verify(propertyFormatter).formatProperty(newProperty, rootObject, variableName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFormatListSingleValueStatic() throws GenerationException {
|
||||||
|
final var text = new ParsedTextImpl("text");
|
||||||
|
final var values = List.of(text);
|
||||||
|
final var emptyProperty = new ParsedPropertyImpl("name", String.class.getName(), "");
|
||||||
|
final var newProperty = new ParsedPropertyImpl("name", String.class.getName(), text.text());
|
||||||
|
doNothing().when(propertyFormatter).formatProperty(newProperty, rootObject, variableName);
|
||||||
|
propertyFormatter.formatProperty(emptyProperty, values, rootObject, variableName);
|
||||||
|
verify(propertyFormatter).formatProperty(newProperty, rootObject, variableName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFormatSingleChildSet(@Mock final ObjectFormatter objectFormatter) throws GenerationException {
|
||||||
|
when(helperProvider.getObjectFormatter()).thenReturn(objectFormatter);
|
||||||
|
final var className = "javafx.scene.layout.BorderPane";
|
||||||
|
final var properties = new LinkedHashMap<ParsedProperty, SequencedCollection<ParsedObject>>();
|
||||||
|
final var parsedObject = new ParsedObjectImpl(className, Map.of(), properties, List.of());
|
||||||
|
when(property.name()).thenReturn("center");
|
||||||
|
final var child = new ParsedObjectImpl("javafx.scene.control.Label", Map.of(), new LinkedHashMap<>(), List.of());
|
||||||
|
final var objects = List.of(child);
|
||||||
|
doAnswer(i -> sb.append("object")).when(objectFormatter).format(child, "label");
|
||||||
|
propertyFormatter.formatProperty(property, objects, parsedObject, variableName);
|
||||||
|
final var expected = "object variable.setCenter(label);\n";
|
||||||
|
assertEquals(expected, sb.toString());
|
||||||
|
verify(objectFormatter).format(child, "label");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFormatSingleChildGet(@Mock final ObjectFormatter objectFormatter) throws GenerationException {
|
||||||
|
when(helperProvider.getObjectFormatter()).thenReturn(objectFormatter);
|
||||||
|
final var className = "javafx.scene.layout.HBox";
|
||||||
|
final var properties = new LinkedHashMap<ParsedProperty, SequencedCollection<ParsedObject>>();
|
||||||
|
final var parsedObject = new ParsedObjectImpl(className, Map.of(), properties, List.of());
|
||||||
|
when(property.name()).thenReturn("children");
|
||||||
|
final var child = new ParsedObjectImpl("javafx.scene.control.Label", Map.of(), new LinkedHashMap<>(), List.of());
|
||||||
|
final var objects = List.of(child);
|
||||||
|
doAnswer(i -> sb.append("object")).when(objectFormatter).format(child, "label");
|
||||||
|
propertyFormatter.formatProperty(property, objects, parsedObject, variableName);
|
||||||
|
final var expected = "object variable.getChildren().addAll(listof(label));\n";
|
||||||
|
assertEquals(expected, sb.toString());
|
||||||
|
verify(objectFormatter).format(child, "label");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFormatSingleChildNoSetter(@Mock final ObjectFormatter objectFormatter) throws GenerationException {
|
||||||
|
when(helperProvider.getObjectFormatter()).thenReturn(objectFormatter);
|
||||||
|
final var className = "javafx.scene.layout.BorderPane";
|
||||||
|
final var properties = new LinkedHashMap<ParsedProperty, SequencedCollection<ParsedObject>>();
|
||||||
|
final var parsedObject = new ParsedObjectImpl(className, Map.of(), properties, List.of());
|
||||||
|
when(property.name()).thenReturn("blabla");
|
||||||
|
final var child = new ParsedObjectImpl("javafx.scene.control.Label", Map.of(), new LinkedHashMap<>(), List.of());
|
||||||
|
final var objects = List.of(child);
|
||||||
|
assertThrows(GenerationException.class, () -> propertyFormatter.formatProperty(property, objects, parsedObject, variableName));
|
||||||
|
verify(objectFormatter).format(child, "label");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFormatChildrenGet(@Mock final ObjectFormatter objectFormatter) throws GenerationException {
|
||||||
|
when(helperProvider.getObjectFormatter()).thenReturn(objectFormatter);
|
||||||
|
final var className = "javafx.scene.layout.HBox";
|
||||||
|
final var properties = new LinkedHashMap<ParsedProperty, SequencedCollection<ParsedObject>>();
|
||||||
|
final var parsedObject = new ParsedObjectImpl(className, Map.of(), properties, List.of());
|
||||||
|
when(property.name()).thenReturn("children");
|
||||||
|
final var child = new ParsedObjectImpl("javafx.scene.control.Label", Map.of(), new LinkedHashMap<>(), List.of());
|
||||||
|
final var objects = List.of(child, child);
|
||||||
|
doAnswer(i -> sb.append("object")).when(objectFormatter).format(child, "label");
|
||||||
|
propertyFormatter.formatProperty(property, objects, parsedObject, variableName);
|
||||||
|
final var expected = "objectobject variable.getChildren().addAll(listof(label, label));\n";
|
||||||
|
assertEquals(expected, sb.toString());
|
||||||
|
verify(objectFormatter, times(2)).format(child, "label");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFormatChildrenNoGetter(@Mock final ObjectFormatter objectFormatter) throws GenerationException {
|
||||||
|
when(helperProvider.getObjectFormatter()).thenReturn(objectFormatter);
|
||||||
|
final var className = "javafx.scene.layout.HBox";
|
||||||
|
final var properties = new LinkedHashMap<ParsedProperty, SequencedCollection<ParsedObject>>();
|
||||||
|
final var parsedObject = new ParsedObjectImpl(className, Map.of(), properties, List.of());
|
||||||
|
when(property.name()).thenReturn("blabla");
|
||||||
|
final var child = new ParsedObjectImpl("javafx.scene.control.Label", Map.of(), new LinkedHashMap<>(), List.of());
|
||||||
|
final var objects = List.of(child, child);
|
||||||
|
assertThrows(GenerationException.class, () -> propertyFormatter.formatProperty(property, objects, parsedObject, variableName));
|
||||||
|
verify(objectFormatter, times(2)).format(child, "label");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFormatSingleStaticChild(@Mock final ObjectFormatter objectFormatter) throws GenerationException {
|
||||||
|
when(helperProvider.getObjectFormatter()).thenReturn(objectFormatter);
|
||||||
|
final var className = "javafx.scene.layout.BorderPane";
|
||||||
|
final var properties = new LinkedHashMap<ParsedProperty, SequencedCollection<ParsedObject>>();
|
||||||
|
final var parsedObject = new ParsedObjectImpl(className, Map.of(), properties, List.of());
|
||||||
|
when(property.name()).thenReturn("fillHeight");
|
||||||
|
when(property.sourceType()).thenReturn("javafx.scene.layout.GridPane");
|
||||||
|
final var child = new ParsedObjectImpl("javafx.scene.control.Label", Map.of(), new LinkedHashMap<>(), List.of());
|
||||||
|
final var objects = List.of(child);
|
||||||
|
doAnswer(i -> sb.append("object")).when(objectFormatter).format(child, "label");
|
||||||
|
propertyFormatter.formatProperty(property, objects, parsedObject, variableName);
|
||||||
|
final var expected = "object javafx.scene.layout.GridPane.setFillHeight(variable, label);\n";
|
||||||
|
assertEquals(expected, sb.toString());
|
||||||
|
verify(objectFormatter).format(child, "label");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFormatSingleStaticChildNoSetter(@Mock final ObjectFormatter objectFormatter) throws GenerationException {
|
||||||
|
when(helperProvider.getObjectFormatter()).thenReturn(objectFormatter);
|
||||||
|
final var className = "javafx.scene.layout.BorderPane";
|
||||||
|
final var properties = new LinkedHashMap<ParsedProperty, SequencedCollection<ParsedObject>>();
|
||||||
|
final var parsedObject = new ParsedObjectImpl(className, Map.of(), properties, List.of());
|
||||||
|
when(property.name()).thenReturn("blabla");
|
||||||
|
when(property.sourceType()).thenReturn("javafx.scene.layout.GridPane");
|
||||||
|
final var child = new ParsedObjectImpl("javafx.scene.control.Label", Map.of(), new LinkedHashMap<>(), List.of());
|
||||||
|
final var objects = List.of(child);
|
||||||
|
assertThrows(GenerationException.class, () -> propertyFormatter.formatProperty(property, objects, parsedObject, variableName));
|
||||||
|
verify(objectFormatter).format(child, "label");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testIllegal() {
|
||||||
|
assertThrows(NullPointerException.class, () -> new PropertyFormatter(null, progress));
|
||||||
|
assertThrows(NullPointerException.class, () -> new PropertyFormatter(helperProvider, null));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ class TestReflectionHelper {
|
|||||||
parameters.put("p16", new Parameter("p16", Double.class, "0"));
|
parameters.put("p16", new Parameter("p16", Double.class, "0"));
|
||||||
parameters.put("p17", new Parameter("p17", String.class, "null"));
|
parameters.put("p17", new Parameter("p17", String.class, "null"));
|
||||||
parameters.put("p18", new Parameter("p18", Object.class, "null"));
|
parameters.put("p18", new Parameter("p18", Object.class, "null"));
|
||||||
final var defaultConstructor = Arrays.stream(WholeConstructorArgs.class.getConstructors()).filter(c -> c.getParameterCount() == 18).findFirst().orElseThrow();
|
final var defaultConstructor = Arrays.stream(WholeConstructorArgs.class.getDeclaredConstructors()).filter(c -> c.getParameterCount() == 18).findFirst().orElseThrow();
|
||||||
final var expected = new ConstructorArgs(defaultConstructor, parameters);
|
final var expected = new ConstructorArgs(defaultConstructor, parameters);
|
||||||
final var actual = ReflectionHelper.getConstructorArgs(defaultConstructor);
|
final var actual = ReflectionHelper.getConstructorArgs(defaultConstructor);
|
||||||
assertEquals(expected, actual);
|
assertEquals(expected, actual);
|
||||||
@@ -132,7 +132,7 @@ class TestReflectionHelper {
|
|||||||
parameters.put("p13", new Parameter("p13", float.class, "5.5"));
|
parameters.put("p13", new Parameter("p13", float.class, "5.5"));
|
||||||
parameters.put("p15", new Parameter("p15", double.class, "6.6"));
|
parameters.put("p15", new Parameter("p15", double.class, "6.6"));
|
||||||
parameters.put("p17", new Parameter("p17", String.class, "str"));
|
parameters.put("p17", new Parameter("p17", String.class, "str"));
|
||||||
final var constructor = Arrays.stream(WholeConstructorArgs.class.getConstructors()).filter(c -> c.getParameterCount() == 9).findFirst().orElseThrow();
|
final var constructor = Arrays.stream(WholeConstructorArgs.class.getDeclaredConstructors()).filter(c -> c.getParameterCount() == 9).findFirst().orElseThrow();
|
||||||
final var expected = new ConstructorArgs(constructor, parameters);
|
final var expected = new ConstructorArgs(constructor, parameters);
|
||||||
final var actual = ReflectionHelper.getConstructorArgs(constructor);
|
final var actual = ReflectionHelper.getConstructorArgs(constructor);
|
||||||
assertEquals(expected, actual);
|
assertEquals(expected, actual);
|
||||||
@@ -140,7 +140,7 @@ class TestReflectionHelper {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testGetConstructorArgsNoNamedArgs() {
|
void testGetConstructorArgsNoNamedArgs() {
|
||||||
final var constructor = Arrays.stream(WholeConstructorArgs.class.getConstructors()).filter(c -> c.getParameterCount() == 2).findFirst().orElseThrow();
|
final var constructor = Arrays.stream(WholeConstructorArgs.class.getDeclaredConstructors()).filter(c -> c.getParameterCount() == 2).findFirst().orElseThrow();
|
||||||
final var expected = new ConstructorArgs(constructor, new LinkedHashMap<>());
|
final var expected = new ConstructorArgs(constructor, new LinkedHashMap<>());
|
||||||
final var actual = ReflectionHelper.getConstructorArgs(constructor);
|
final var actual = ReflectionHelper.getConstructorArgs(constructor);
|
||||||
assertEquals(expected, actual);
|
assertEquals(expected, actual);
|
||||||
@@ -148,7 +148,7 @@ class TestReflectionHelper {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testGetConstructorArgsMixed() {
|
void testGetConstructorArgsMixed() {
|
||||||
final var constructor = Arrays.stream(WholeConstructorArgs.class.getConstructors()).filter(c -> c.getParameterCount() == 3).findFirst().orElseThrow();
|
final var constructor = Arrays.stream(WholeConstructorArgs.class.getDeclaredConstructors()).filter(c -> c.getParameterCount() == 3).findFirst().orElseThrow();
|
||||||
assertThrows(IllegalStateException.class, () -> ReflectionHelper.getConstructorArgs(constructor));
|
assertThrows(IllegalStateException.class, () -> ReflectionHelper.getConstructorArgs(constructor));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -212,4 +212,25 @@ class TestReflectionHelper {
|
|||||||
when(fieldInfo.genericTypes()).thenReturn(List.of(new GenericTypesImpl("java.lang.String", List.of()), new GenericTypesImpl("java.lang.Integer", List.of())));
|
when(fieldInfo.genericTypes()).thenReturn(List.of(new GenericTypesImpl("java.lang.String", List.of()), new GenericTypesImpl("java.lang.Integer", List.of())));
|
||||||
assertEquals("<java.lang.String, java.lang.Integer>", reflectionHelper.getGenericTypes(parsedObject));
|
assertEquals("<java.lang.String, java.lang.Integer>", reflectionHelper.getGenericTypes(parsedObject));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testGetGenericTypesRecursive() throws GenerationException {
|
||||||
|
when(fieldInfo.genericTypes()).thenReturn(List.of(new GenericTypesImpl("java.lang.String", List.of(new GenericTypesImpl("java.lang.Integer", List.of()), new GenericTypesImpl("java.lang.Short", List.of()))), new GenericTypesImpl("java.lang.Byte", List.of())));
|
||||||
|
assertEquals("<java.lang.String<java.lang.Integer, java.lang.Short>, java.lang.Byte>", reflectionHelper.getGenericTypes(parsedObject));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testGetReturnTypeNotFound() {
|
||||||
|
assertThrows(GenerationException.class, () -> ReflectionHelper.getReturnType("java.lang.String", "whatever"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testGetReturnType() throws GenerationException {
|
||||||
|
assertEquals(String.class.getName(), ReflectionHelper.getReturnType("java.lang.String", "valueOf"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testIllegal() {
|
||||||
|
assertThrows(NullPointerException.class, () -> new ReflectionHelper(null));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,172 @@
|
|||||||
package com.github.gtache.fxml.compiler.impl.internal;
|
package com.github.gtache.fxml.compiler.impl.internal;
|
||||||
|
|
||||||
|
import com.github.gtache.fxml.compiler.GenerationException;
|
||||||
|
import com.github.gtache.fxml.compiler.parsing.ParsedDefine;
|
||||||
|
import com.github.gtache.fxml.compiler.parsing.ParsedObject;
|
||||||
|
import com.github.gtache.fxml.compiler.parsing.ParsedProperty;
|
||||||
|
import com.github.gtache.fxml.compiler.parsing.impl.ParsedPropertyImpl;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
import org.mockito.Mock;
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.SequencedCollection;
|
||||||
|
import java.util.SequencedMap;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.ArgumentMatchers.anyString;
|
||||||
|
import static org.mockito.Mockito.*;
|
||||||
|
|
||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
class TestSceneFormatter {
|
class TestSceneFormatter {
|
||||||
|
|
||||||
|
private final HelperProvider helperProvider;
|
||||||
|
private final ObjectFormatter objectFormatter;
|
||||||
|
private final GenerationCompatibilityHelper compatibilityHelper;
|
||||||
|
private final URLFormatter urlFormatter;
|
||||||
|
private final VariableProvider variableProvider;
|
||||||
|
private final StringBuilder sb;
|
||||||
|
private final ParsedObject parsedObject;
|
||||||
|
private final SequencedCollection<ParsedObject> children;
|
||||||
|
private final SequencedMap<ParsedProperty, SequencedCollection<ParsedObject>> properties;
|
||||||
|
private final Map<String, ParsedProperty> attributes;
|
||||||
|
private final String variableName;
|
||||||
|
private final SceneFormatter sceneFormatter;
|
||||||
|
|
||||||
|
TestSceneFormatter(@Mock final HelperProvider helperProvider, @Mock final ObjectFormatter objectFormatter,
|
||||||
|
@Mock final GenerationCompatibilityHelper compatibilityHelper, @Mock final VariableProvider variableProvider,
|
||||||
|
@Mock final URLFormatter urlFormatter, @Mock final ParsedObject parsedObject) {
|
||||||
|
this.helperProvider = Objects.requireNonNull(helperProvider);
|
||||||
|
this.objectFormatter = Objects.requireNonNull(objectFormatter);
|
||||||
|
this.compatibilityHelper = Objects.requireNonNull(compatibilityHelper);
|
||||||
|
this.urlFormatter = Objects.requireNonNull(urlFormatter);
|
||||||
|
this.variableProvider = Objects.requireNonNull(variableProvider);
|
||||||
|
this.parsedObject = Objects.requireNonNull(parsedObject);
|
||||||
|
this.children = new ArrayList<>();
|
||||||
|
this.properties = new LinkedHashMap<>();
|
||||||
|
this.attributes = new HashMap<>();
|
||||||
|
this.variableName = "variable";
|
||||||
|
this.sb = new StringBuilder();
|
||||||
|
this.sceneFormatter = new SceneFormatter(helperProvider, sb);
|
||||||
|
}
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void beforeEach() throws GenerationException {
|
||||||
|
when(helperProvider.getObjectFormatter()).thenReturn(objectFormatter);
|
||||||
|
when(helperProvider.getCompatibilityHelper()).thenReturn(compatibilityHelper);
|
||||||
|
when(helperProvider.getURLFormatter()).thenReturn(urlFormatter);
|
||||||
|
when(helperProvider.getVariableProvider()).thenReturn(variableProvider);
|
||||||
|
when(parsedObject.children()).thenReturn(children);
|
||||||
|
when(parsedObject.properties()).thenReturn(properties);
|
||||||
|
when(parsedObject.attributes()).thenReturn(attributes);
|
||||||
|
when(compatibilityHelper.getStartVar(anyString())).then(i -> i.getArgument(0));
|
||||||
|
when(compatibilityHelper.getListOf()).thenReturn("listof(");
|
||||||
|
when(variableProvider.getNextVariableName(anyString())).then(i -> i.getArgument(0));
|
||||||
|
doAnswer(i -> sb.append((String) i.getArgument(1))).when(objectFormatter).format(any(), any());
|
||||||
|
doAnswer(i -> {
|
||||||
|
sb.append(((List<String>) i.getArgument(0)).getFirst());
|
||||||
|
return List.of("1", "2");
|
||||||
|
}).when(urlFormatter).formatURL(anyIterable());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testUnknownAttribute() {
|
||||||
|
properties.put(new ParsedPropertyImpl("root", null, ""), List.of(parsedObject));
|
||||||
|
attributes.put("unknown", new ParsedPropertyImpl("unknown", null, "value"));
|
||||||
|
assertThrows(GenerationException.class, () -> sceneFormatter.formatScene(parsedObject, variableName));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testNonRootProperty() {
|
||||||
|
properties.put(new ParsedPropertyImpl("property", null, ""), List.of(parsedObject));
|
||||||
|
assertThrows(GenerationException.class, () -> sceneFormatter.formatScene(parsedObject, variableName));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testRootPropertyNonEmptyChildren() {
|
||||||
|
properties.put(new ParsedPropertyImpl("root", null, ""), List.of(parsedObject));
|
||||||
|
children.add(parsedObject);
|
||||||
|
assertThrows(GenerationException.class, () -> sceneFormatter.formatScene(parsedObject, variableName));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testRootPropertyEmptyChild() {
|
||||||
|
properties.put(new ParsedPropertyImpl("root", null, ""), List.of());
|
||||||
|
assertThrows(GenerationException.class, () -> sceneFormatter.formatScene(parsedObject, variableName));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testRootPropertyNonOneChild() {
|
||||||
|
properties.put(new ParsedPropertyImpl("root", null, ""), List.of(parsedObject, parsedObject));
|
||||||
|
assertThrows(GenerationException.class, () -> sceneFormatter.formatScene(parsedObject, variableName));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testNonRootPropertyEmptyChild() {
|
||||||
|
assertThrows(GenerationException.class, () -> sceneFormatter.formatScene(parsedObject, variableName));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testNonRootPropertyMultipleChildren() {
|
||||||
|
children.add(parsedObject);
|
||||||
|
children.add(parsedObject);
|
||||||
|
assertThrows(GenerationException.class, () -> sceneFormatter.formatScene(parsedObject, variableName));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testDefaultAttributesProperty() throws GenerationException {
|
||||||
|
final var rootObject = mock(ParsedObject.class);
|
||||||
|
final var define = mock(ParsedDefine.class);
|
||||||
|
properties.put(new ParsedPropertyImpl("root", null, ""), List.of(define, rootObject));
|
||||||
|
sceneFormatter.formatScene(parsedObject, variableName);
|
||||||
|
final var expected = "definerootjavafx.scene.Scenevariable = new javafx.scene.Scene(root, -1.0, -1.0, javafx.scene.paint.Color.valueOf(\"0xffffffff\"));\n";
|
||||||
|
assertEquals(expected, sb.toString());
|
||||||
|
verify(objectFormatter).format(define, "define");
|
||||||
|
verify(objectFormatter).format(rootObject, "root");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testDefaultAttributesChild() throws GenerationException {
|
||||||
|
final var rootObject = mock(ParsedObject.class);
|
||||||
|
final var define = mock(ParsedDefine.class);
|
||||||
|
children.add(define);
|
||||||
|
children.add(rootObject);
|
||||||
|
sceneFormatter.formatScene(parsedObject, variableName);
|
||||||
|
final var expected = "definerootjavafx.scene.Scenevariable = new javafx.scene.Scene(root, -1.0, -1.0, javafx.scene.paint.Color.valueOf(\"0xffffffff\"));\n";
|
||||||
|
assertEquals(expected, sb.toString());
|
||||||
|
verify(objectFormatter).format(define, "define");
|
||||||
|
verify(objectFormatter).format(rootObject, "root");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testAllAttributesProperty() throws GenerationException {
|
||||||
|
final var rootObject = mock(ParsedObject.class);
|
||||||
|
properties.put(new ParsedPropertyImpl("root", null, ""), List.of(rootObject));
|
||||||
|
attributes.put("width", new ParsedPropertyImpl("width", null, "100"));
|
||||||
|
attributes.put("height", new ParsedPropertyImpl("height", null, "200"));
|
||||||
|
attributes.put("fill", new ParsedPropertyImpl("fill", null, "#FF0000"));
|
||||||
|
attributes.put("stylesheets", new ParsedPropertyImpl("stylesheets", null, "style.css"));
|
||||||
|
sceneFormatter.formatScene(parsedObject, variableName);
|
||||||
|
final var expected = "rootjavafx.scene.Scenevariable = new javafx.scene.Scene(root, 100.0, 200.0, javafx.scene.paint.Color.valueOf(\"#FF0000\"));\n" +
|
||||||
|
"style.cssjava.util.List<String>stylesheets = variable.getStyleSheets();\n" +
|
||||||
|
" stylesheets.addAll(listof(1, 2));\n";
|
||||||
|
assertEquals(expected, sb.toString());
|
||||||
|
verify(objectFormatter).format(rootObject, "root");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testIllegal() {
|
||||||
|
assertThrows(NullPointerException.class, () -> new SceneFormatter(null, sb));
|
||||||
|
assertThrows(NullPointerException.class, () -> new SceneFormatter(helperProvider, null));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,143 @@
|
|||||||
package com.github.gtache.fxml.compiler.impl.internal;
|
package com.github.gtache.fxml.compiler.impl.internal;
|
||||||
|
|
||||||
|
import com.github.gtache.fxml.compiler.GenerationException;
|
||||||
|
import com.github.gtache.fxml.compiler.parsing.ParsedObject;
|
||||||
|
import com.github.gtache.fxml.compiler.parsing.ParsedProperty;
|
||||||
|
import com.github.gtache.fxml.compiler.parsing.impl.ParsedPropertyImpl;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
import org.mockito.Mock;
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
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 java.util.SequencedCollection;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
import static org.mockito.Mockito.anyString;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
class TestTriangleMeshFormatter {
|
class TestTriangleMeshFormatter {
|
||||||
|
|
||||||
|
private final HelperProvider helperProvider;
|
||||||
|
private final GenerationCompatibilityHelper compatibilityHelper;
|
||||||
|
private final StringBuilder sb;
|
||||||
|
private final ParsedObject parsedObject;
|
||||||
|
private final String variableName;
|
||||||
|
private final Map<String, ParsedProperty> attributes;
|
||||||
|
private final TriangleMeshFormatter triangleMeshFormatter;
|
||||||
|
|
||||||
|
TestTriangleMeshFormatter(@Mock final HelperProvider helperProvider, @Mock final GenerationCompatibilityHelper compatibilityHelper,
|
||||||
|
@Mock final ParsedObject parsedObject) {
|
||||||
|
this.helperProvider = Objects.requireNonNull(helperProvider);
|
||||||
|
this.compatibilityHelper = Objects.requireNonNull(compatibilityHelper);
|
||||||
|
this.sb = new StringBuilder();
|
||||||
|
this.parsedObject = Objects.requireNonNull(parsedObject);
|
||||||
|
this.attributes = new HashMap<>();
|
||||||
|
this.variableName = "variable";
|
||||||
|
this.triangleMeshFormatter = new TriangleMeshFormatter(helperProvider, sb);
|
||||||
|
}
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void beforeEach() throws GenerationException {
|
||||||
|
when(helperProvider.getCompatibilityHelper()).thenReturn(compatibilityHelper);
|
||||||
|
when(parsedObject.attributes()).thenReturn(attributes);
|
||||||
|
when(parsedObject.children()).thenReturn(List.of());
|
||||||
|
when(parsedObject.properties()).thenReturn(new LinkedHashMap<>());
|
||||||
|
when(compatibilityHelper.getStartVar(anyString())).then(i -> i.getArgument(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFormatChildren() {
|
||||||
|
when(parsedObject.children()).thenReturn(List.of(parsedObject));
|
||||||
|
assertThrows(GenerationException.class, () -> triangleMeshFormatter.formatTriangleMesh(parsedObject, variableName));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFormatProperties() {
|
||||||
|
final var map = new LinkedHashMap<ParsedProperty, SequencedCollection<ParsedObject>>();
|
||||||
|
map.put(new ParsedPropertyImpl("str", null, ""), List.of());
|
||||||
|
when(parsedObject.properties()).thenReturn(map);
|
||||||
|
assertThrows(GenerationException.class, () -> triangleMeshFormatter.formatTriangleMesh(parsedObject, variableName));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFormatUnknownAttribute() {
|
||||||
|
attributes.put("unknown", new ParsedPropertyImpl("unknown", null, "value"));
|
||||||
|
assertThrows(GenerationException.class, () -> triangleMeshFormatter.formatTriangleMesh(parsedObject, variableName));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testNoAttributes() throws GenerationException {
|
||||||
|
triangleMeshFormatter.formatTriangleMesh(parsedObject, variableName);
|
||||||
|
final var expected = "javafx.scene.shape.TriangleMeshvariable = new javafx.scene.shape.TriangleMesh();\n";
|
||||||
|
assertEquals(expected, sb.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testUnknownVertexFormat() {
|
||||||
|
final var vertexFormat = "unknown";
|
||||||
|
attributes.put("vertexFormat", new ParsedPropertyImpl("vertexFormat", null, vertexFormat));
|
||||||
|
assertThrows(GenerationException.class, () -> triangleMeshFormatter.formatTriangleMesh(parsedObject, variableName));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testVertexFormatPointNormalTexCoord() throws GenerationException {
|
||||||
|
final var vertexFormat = "point_normal_texcoord";
|
||||||
|
attributes.put("vertexFormat", new ParsedPropertyImpl("vertexFormat", null, vertexFormat));
|
||||||
|
triangleMeshFormatter.formatTriangleMesh(parsedObject, variableName);
|
||||||
|
final var expected = """
|
||||||
|
javafx.scene.shape.TriangleMeshvariable = new javafx.scene.shape.TriangleMesh();
|
||||||
|
variable.setVertexFormat(javafx.scene.shape.VertexFormat.POINT_NORMAL_TEXCOORD);
|
||||||
|
""";
|
||||||
|
assertEquals(expected, sb.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testAllAttributes() throws GenerationException {
|
||||||
|
final var points = "3.0, 4.1, 5, 6f";
|
||||||
|
final var texCoords = " 7 8 9.3 10.0f ";
|
||||||
|
final var normals = " 7 , 8f 9.3f";
|
||||||
|
final var faces = "1 2, 3 ,4";
|
||||||
|
final var faceSmoothingGroups = " 1 22 3 ";
|
||||||
|
final var vertexFormat = "point_texcoord";
|
||||||
|
|
||||||
|
final var pointsProperty = new ParsedPropertyImpl("points", null, points);
|
||||||
|
final var texCoordsProperty = new ParsedPropertyImpl("texCoords", null, texCoords);
|
||||||
|
final var normalsProperty = new ParsedPropertyImpl("normals", null, normals);
|
||||||
|
final var facesProperty = new ParsedPropertyImpl("faces", null, faces);
|
||||||
|
final var faceSmoothingGroupsProperty = new ParsedPropertyImpl("faceSmoothingGroups", null, faceSmoothingGroups);
|
||||||
|
final var vertexFormatProperty = new ParsedPropertyImpl("vertexFormat", null, vertexFormat);
|
||||||
|
|
||||||
|
attributes.put("points", pointsProperty);
|
||||||
|
attributes.put("texCoords", texCoordsProperty);
|
||||||
|
attributes.put("normals", normalsProperty);
|
||||||
|
attributes.put("faces", facesProperty);
|
||||||
|
attributes.put("faceSmoothingGroups", faceSmoothingGroupsProperty);
|
||||||
|
attributes.put("vertexFormat", vertexFormatProperty);
|
||||||
|
attributes.put("fx:id", new ParsedPropertyImpl("fx:id", null, "id"));
|
||||||
|
triangleMeshFormatter.formatTriangleMesh(parsedObject, variableName);
|
||||||
|
final var expected = """
|
||||||
|
javafx.scene.shape.TriangleMeshvariable = new javafx.scene.shape.TriangleMesh();
|
||||||
|
variable.getPoints().setAll(new float[]{3.0, 4.1, 5.0, 6.0});
|
||||||
|
variable.getTexCoords().setAll(new float[]{7.0, 8.0, 9.3, 10.0});
|
||||||
|
variable.getNormals().setAll(new float[]{7.0, 8.0, 9.3});
|
||||||
|
variable.getFaces().setAll(new int[]{1, 2, 3, 4});
|
||||||
|
variable.getFaceSmoothingGroups().setAll(new int[]{1, 22, 3});
|
||||||
|
variable.setVertexFormat(javafx.scene.shape.VertexFormat.POINT_TEXCOORD);
|
||||||
|
""";
|
||||||
|
assertEquals(expected, sb.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testIllegal() {
|
||||||
|
assertThrows(NullPointerException.class, () -> new TriangleMeshFormatter(null, sb));
|
||||||
|
assertThrows(NullPointerException.class, () -> new TriangleMeshFormatter(helperProvider, null));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,55 +18,53 @@ import java.util.SequencedCollection;
|
|||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
import static org.mockito.ArgumentMatchers.anyString;
|
import static org.mockito.Mockito.anyString;
|
||||||
import static org.mockito.Mockito.*;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
class TestURLFormatter {
|
class TestURLFormatter {
|
||||||
|
|
||||||
private final HelperProvider helperProvider;
|
private final HelperProvider helperProvider;
|
||||||
private final GenerationHelper generationHelper;
|
|
||||||
private final GenerationCompatibilityHelper compatibilityHelper;
|
private final GenerationCompatibilityHelper compatibilityHelper;
|
||||||
|
private final VariableProvider variableProvider;
|
||||||
private final ParsedObject parsedObject;
|
private final ParsedObject parsedObject;
|
||||||
private final String variableName;
|
private final String variableName;
|
||||||
private final StringBuilder sb;
|
private final StringBuilder sb;
|
||||||
private final GenerationProgress progress;
|
|
||||||
private final URLFormatter urlFormatter;
|
private final URLFormatter urlFormatter;
|
||||||
|
|
||||||
TestURLFormatter(@Mock final HelperProvider helperProvider, @Mock final GenerationHelper generationHelper,
|
TestURLFormatter(@Mock final HelperProvider helperProvider, @Mock final VariableProvider variableProvider,
|
||||||
@Mock final GenerationCompatibilityHelper compatibilityHelper, @Mock final ParsedObject parsedObject,
|
@Mock final GenerationCompatibilityHelper compatibilityHelper, @Mock final ParsedObject parsedObject) {
|
||||||
@Mock final GenerationProgress progress) {
|
|
||||||
this.helperProvider = Objects.requireNonNull(helperProvider);
|
this.helperProvider = Objects.requireNonNull(helperProvider);
|
||||||
this.generationHelper = Objects.requireNonNull(generationHelper);
|
this.variableProvider = Objects.requireNonNull(variableProvider);
|
||||||
this.compatibilityHelper = Objects.requireNonNull(compatibilityHelper);
|
this.compatibilityHelper = Objects.requireNonNull(compatibilityHelper);
|
||||||
this.parsedObject = Objects.requireNonNull(parsedObject);
|
this.parsedObject = Objects.requireNonNull(parsedObject);
|
||||||
this.progress = Objects.requireNonNull(progress);
|
|
||||||
this.sb = new StringBuilder();
|
this.sb = new StringBuilder();
|
||||||
this.variableName = "variable";
|
this.variableName = "variable";
|
||||||
this.urlFormatter = new URLFormatter(helperProvider, progress);
|
this.urlFormatter = new URLFormatter(helperProvider, sb);
|
||||||
}
|
}
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
void beforeEach() throws GenerationException {
|
void beforeEach() throws GenerationException {
|
||||||
when(helperProvider.getCompatibilityHelper()).thenReturn(compatibilityHelper);
|
when(helperProvider.getCompatibilityHelper()).thenReturn(compatibilityHelper);
|
||||||
when(helperProvider.getGenerationHelper()).thenReturn(generationHelper);
|
when(helperProvider.getVariableProvider()).thenReturn(variableProvider);
|
||||||
when(progress.stringBuilder()).thenReturn(sb);
|
when(variableProvider.getNextVariableName("url")).thenReturn("url1", "url2");
|
||||||
when(progress.getNextVariableName("url")).thenReturn("url1", "url2");
|
|
||||||
when(compatibilityHelper.getStartVar(anyString())).then(i -> i.getArgument(0));
|
when(compatibilityHelper.getStartVar(anyString())).then(i -> i.getArgument(0));
|
||||||
when(parsedObject.children()).thenReturn(List.of());
|
when(parsedObject.children()).thenReturn(List.of());
|
||||||
when(parsedObject.properties()).thenReturn(new LinkedHashMap<>());
|
when(parsedObject.properties()).thenReturn(new LinkedHashMap<>());
|
||||||
doAnswer(i -> sb.append("handleId")).when(generationHelper).handleId(any(), anyString());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testFormatURLSheets() {
|
void testFormatURLSheets() {
|
||||||
final var styleSheets = List.of("style1.css", "@style2.css");
|
final var styleSheets = List.of("style1.css", "@style2.css");
|
||||||
final var expected = " final java.net.URL url1;\n" +
|
final var expected = """
|
||||||
" try {\n" +
|
final java.net.URL url1;
|
||||||
" url1 = new java.net.URI(\"style1.css\").toURL();\n" +
|
try {
|
||||||
" } catch (final java.net.MalformedURLException | java.net.URISyntaxException e) {\n" +
|
url1 = new java.net.URI("style1.css").toURL();
|
||||||
" throw new RuntimeException(\"Couldn't parse url : style1.css\", e);\n" +
|
} catch (final java.net.MalformedURLException | java.net.URISyntaxException e) {
|
||||||
" }\njava.net.URLurl2 = getClass().getResource(\"style2.css\");\n";
|
throw new RuntimeException("Couldn't parse url : style1.css", e);
|
||||||
|
}
|
||||||
|
java.net.URLurl2 = getClass().getResource("style2.css");
|
||||||
|
""";
|
||||||
assertEquals(List.of("url1", "url2"), urlFormatter.formatURL(styleSheets));
|
assertEquals(List.of("url1", "url2"), urlFormatter.formatURL(styleSheets));
|
||||||
assertEquals(expected, sb.toString());
|
assertEquals(expected, sb.toString());
|
||||||
}
|
}
|
||||||
@@ -80,7 +78,7 @@ class TestURLFormatter {
|
|||||||
@Test
|
@Test
|
||||||
void testFormatURLObjectProperties() {
|
void testFormatURLObjectProperties() {
|
||||||
final var map = new LinkedHashMap<ParsedProperty, SequencedCollection<ParsedObject>>();
|
final var map = new LinkedHashMap<ParsedProperty, SequencedCollection<ParsedObject>>();
|
||||||
map.put(mock(ParsedProperty.class), List.of());
|
map.put(new ParsedPropertyImpl("str", null, ""), List.of());
|
||||||
when(parsedObject.properties()).thenReturn(map);
|
when(parsedObject.properties()).thenReturn(map);
|
||||||
assertThrows(GenerationException.class, () -> urlFormatter.formatURL(parsedObject, variableName));
|
assertThrows(GenerationException.class, () -> urlFormatter.formatURL(parsedObject, variableName));
|
||||||
}
|
}
|
||||||
@@ -101,8 +99,13 @@ class TestURLFormatter {
|
|||||||
when(parsedObject.attributes()).thenReturn(attributes);
|
when(parsedObject.attributes()).thenReturn(attributes);
|
||||||
|
|
||||||
urlFormatter.formatURL(parsedObject, variableName);
|
urlFormatter.formatURL(parsedObject, variableName);
|
||||||
final var expected = "java.net.URL" + variableName + " = getClass().getResource(\"key\");\nhandleId";
|
final var expected = "java.net.URL" + variableName + " = getClass().getResource(\"key\");\n";
|
||||||
assertEquals(expected, sb.toString());
|
assertEquals(expected, sb.toString());
|
||||||
verify(generationHelper).handleId(parsedObject, variableName);
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testIllegal() {
|
||||||
|
assertThrows(NullPointerException.class, () -> new URLFormatter(null, sb));
|
||||||
|
assertThrows(NullPointerException.class, () -> new URLFormatter(helperProvider, null));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,20 +1,18 @@
|
|||||||
package com.github.gtache.fxml.compiler.impl.internal;
|
package com.github.gtache.fxml.compiler.impl.internal;
|
||||||
|
|
||||||
import com.github.gtache.fxml.compiler.GenerationException;
|
import com.github.gtache.fxml.compiler.GenerationException;
|
||||||
import com.github.gtache.fxml.compiler.InjectionType;
|
import com.github.gtache.fxml.compiler.ResourceBundleInjectionType;
|
||||||
import com.github.gtache.fxml.compiler.impl.ResourceBundleInjectionTypes;
|
|
||||||
import javafx.geometry.Pos;
|
import javafx.geometry.Pos;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Objects;
|
||||||
|
|
||||||
import static java.util.Objects.requireNonNull;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
@@ -23,39 +21,40 @@ import static org.mockito.Mockito.when;
|
|||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
class TestValueFormatter {
|
class TestValueFormatter {
|
||||||
|
|
||||||
private final Map<String, VariableInfo> idToVariableInfo;
|
private final HelperProvider helperProvider;
|
||||||
private final InjectionType resourceInjectionType;
|
private final VariableProvider variableProvider;
|
||||||
private final ValueFormatter formatter;
|
private final ValueFormatter formatter;
|
||||||
|
|
||||||
TestValueFormatter(@Mock final InjectionType resourceInjectionType) {
|
TestValueFormatter(@Mock final HelperProvider helperProvider, @Mock final VariableProvider variableProvider,
|
||||||
this.resourceInjectionType = requireNonNull(resourceInjectionType);
|
@Mock final ResourceBundleInjectionType resourceInjectionType) {
|
||||||
this.idToVariableInfo = new HashMap<>();
|
this.helperProvider = Objects.requireNonNull(helperProvider);
|
||||||
this.formatter = new ValueFormatter(resourceInjectionType, idToVariableInfo);
|
this.variableProvider = Objects.requireNonNull(variableProvider);
|
||||||
|
this.formatter = new ValueFormatter(helperProvider, resourceInjectionType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@BeforeEach
|
||||||
void testGetArgStringResourceUnknown() {
|
void beforeEach() {
|
||||||
assertThrows(GenerationException.class, () -> formatter.getArg("%value", String.class));
|
when(helperProvider.getVariableProvider()).thenReturn(variableProvider);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testGetArgStringResourceSimpleGet() throws GenerationException {
|
void testGetArgStringResourceSimpleGet() throws GenerationException {
|
||||||
final var types = List.of(ResourceBundleInjectionTypes.CONSTRUCTOR, ResourceBundleInjectionTypes.CONSTRUCTOR_NAME, ResourceBundleInjectionTypes.GET_BUNDLE);
|
final var types = List.of(ResourceBundleInjectionType.CONSTRUCTOR, ResourceBundleInjectionType.CONSTRUCTOR_NAME, ResourceBundleInjectionType.GET_BUNDLE);
|
||||||
for (final var type : types) {
|
for (final var type : types) {
|
||||||
final var resourceFormatter = new ValueFormatter(type, idToVariableInfo);
|
final var resourceFormatter = new ValueFormatter(helperProvider, type);
|
||||||
assertEquals("resourceBundle.getString(\"value\")", resourceFormatter.getArg("%value", String.class));
|
assertEquals("resourceBundle.getString(\"value\")", resourceFormatter.getArg("%value", String.class));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testGetArgStringResourceController() throws GenerationException {
|
void testGetArgStringResourceController() throws GenerationException {
|
||||||
final var resourceFormatter = new ValueFormatter(ResourceBundleInjectionTypes.GETTER, idToVariableInfo);
|
final var resourceFormatter = new ValueFormatter(helperProvider, ResourceBundleInjectionType.GETTER);
|
||||||
assertEquals("controller.resources().getString(\"value\")", resourceFormatter.getArg("%value", String.class));
|
assertEquals("controller.resources().getString(\"value\")", resourceFormatter.getArg("%value", String.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testGetArgStringResourceFunction() throws GenerationException {
|
void testGetArgStringResourceFunction() throws GenerationException {
|
||||||
final var resourceFormatter = new ValueFormatter(ResourceBundleInjectionTypes.CONSTRUCTOR_FUNCTION, idToVariableInfo);
|
final var resourceFormatter = new ValueFormatter(helperProvider, ResourceBundleInjectionType.CONSTRUCTOR_FUNCTION);
|
||||||
assertEquals("resourceBundleFunction.apply(\"value\")", resourceFormatter.getArg("%value", String.class));
|
assertEquals("resourceBundleFunction.apply(\"value\")", resourceFormatter.getArg("%value", String.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,8 +77,8 @@ class TestValueFormatter {
|
|||||||
@Test
|
@Test
|
||||||
void testGetArgExpression() throws GenerationException {
|
void testGetArgExpression() throws GenerationException {
|
||||||
final var info = mock(VariableInfo.class);
|
final var info = mock(VariableInfo.class);
|
||||||
|
when(variableProvider.getVariableInfo("value")).thenReturn(info);
|
||||||
when(info.variableName()).thenReturn("variable");
|
when(info.variableName()).thenReturn("variable");
|
||||||
idToVariableInfo.put("value", info);
|
|
||||||
assertEquals("variable", formatter.getArg("$value", String.class));
|
assertEquals("variable", formatter.getArg("$value", String.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,32 +89,32 @@ class TestValueFormatter {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testToStringString() {
|
void testToStringString() {
|
||||||
assertEquals("\"value\"", formatter.toString("value", String.class));
|
assertEquals("\"value\"", ValueFormatter.toString("value", String.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testToStringEscape() {
|
void testToStringEscape() {
|
||||||
assertEquals("\"val\\\\u\\\"e\"", formatter.toString("\\val\\u\"e", String.class));
|
assertEquals("\"val\\\\u\\\"e\"", ValueFormatter.toString("\\val\\u\"e", String.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testToStringChar() {
|
void testToStringChar() {
|
||||||
assertEquals("'v'", formatter.toString("v", char.class));
|
assertEquals("'v'", ValueFormatter.toString("v", char.class));
|
||||||
assertEquals("'v'", formatter.toString("v", Character.class));
|
assertEquals("'v'", ValueFormatter.toString("v", Character.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testToStringBoolean() {
|
void testToStringBoolean() {
|
||||||
assertEquals("true", formatter.toString("true", boolean.class));
|
assertEquals("true", ValueFormatter.toString("true", boolean.class));
|
||||||
assertEquals("true", formatter.toString("true", Boolean.class));
|
assertEquals("true", ValueFormatter.toString("true", Boolean.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testToStringInteger() {
|
void testToStringInteger() {
|
||||||
final var types = List.of(byte.class, Byte.class, short.class, Short.class, long.class, Long.class, int.class, Integer.class);
|
final var types = List.of(byte.class, Byte.class, short.class, Short.class, long.class, Long.class, int.class, Integer.class);
|
||||||
for (final var type : types) {
|
for (final var type : types) {
|
||||||
assertEquals("1", formatter.toString("1", type));
|
assertEquals("1", ValueFormatter.toString("1", type));
|
||||||
assertEquals(ReflectionHelper.getWrapperClass(type) + ".valueOf(\"value\")", formatter.toString("value", type));
|
assertEquals(ReflectionHelper.getWrapperClass(type) + ".valueOf(\"value\")", ValueFormatter.toString("value", type));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,23 +122,29 @@ class TestValueFormatter {
|
|||||||
void testToStringDecimal() {
|
void testToStringDecimal() {
|
||||||
final var types = List.of(float.class, Float.class, double.class, Double.class);
|
final var types = List.of(float.class, Float.class, double.class, Double.class);
|
||||||
for (final var type : types) {
|
for (final var type : types) {
|
||||||
assertEquals("1.0", formatter.toString("1.0", type));
|
assertEquals("1.0", ValueFormatter.toString("1.0", type));
|
||||||
assertEquals(ReflectionHelper.getWrapperClass(type) + ".valueOf(\"value\")", formatter.toString("value", type));
|
assertEquals(ReflectionHelper.getWrapperClass(type) + ".valueOf(\"value\")", ValueFormatter.toString("value", type));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testToStringValueOfEnum() {
|
void testToStringValueOfEnum() {
|
||||||
assertEquals("javafx.geometry.Pos.value", formatter.toString("value", Pos.class));
|
assertEquals("javafx.geometry.Pos.value", ValueFormatter.toString("value", Pos.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testToStringValueOfColor() {
|
void testToStringValueOfColor() {
|
||||||
assertEquals("javafx.scene.paint.Color.valueOf(\"value\")", formatter.toString("value", javafx.scene.paint.Color.class));
|
assertEquals("javafx.scene.paint.Color.valueOf(\"value\")", ValueFormatter.toString("value", javafx.scene.paint.Color.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testOther() {
|
void testOther() {
|
||||||
assertEquals("value", formatter.toString("value", Object.class));
|
assertEquals("value", ValueFormatter.toString("value", Object.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testIllegal() {
|
||||||
|
assertThrows(NullPointerException.class, () -> new ValueFormatter(null, ResourceBundleInjectionType.CONSTRUCTOR));
|
||||||
|
assertThrows(NullPointerException.class, () -> new ValueFormatter(helperProvider, null));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,39 @@
|
|||||||
|
package com.github.gtache.fxml.compiler.impl.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.util.Objects;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||||
|
|
||||||
|
@ExtendWith(MockitoExtension.class)
|
||||||
|
class TestVariableProvider {
|
||||||
|
|
||||||
|
private final VariableInfo variableInfo;
|
||||||
|
private final String id;
|
||||||
|
private final VariableProvider provider;
|
||||||
|
|
||||||
|
TestVariableProvider(@Mock final VariableInfo variableInfo) {
|
||||||
|
this.variableInfo = Objects.requireNonNull(variableInfo);
|
||||||
|
this.id = "id";
|
||||||
|
this.provider = new VariableProvider();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testGetVariableName() {
|
||||||
|
assertEquals("var0", provider.getNextVariableName("var"));
|
||||||
|
assertEquals("var1", provider.getNextVariableName("var"));
|
||||||
|
assertEquals("other0", provider.getNextVariableName("other"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testAddVariableInfo() {
|
||||||
|
assertNull(provider.getVariableInfo(id));
|
||||||
|
provider.addVariableInfo(id, variableInfo);
|
||||||
|
assertEquals(variableInfo, provider.getVariableInfo(id));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,7 +19,6 @@ import java.util.SequencedCollection;
|
|||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
import static org.mockito.ArgumentMatchers.*;
|
|
||||||
import static org.mockito.Mockito.*;
|
import static org.mockito.Mockito.*;
|
||||||
|
|
||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
@@ -30,35 +29,30 @@ class TestWebViewFormatter {
|
|||||||
private final ControllerInjector controllerInjector;
|
private final ControllerInjector controllerInjector;
|
||||||
private final FieldSetter fieldSetter;
|
private final FieldSetter fieldSetter;
|
||||||
private final PropertyFormatter propertyFormatter;
|
private final PropertyFormatter propertyFormatter;
|
||||||
private final GenerationHelper generationHelper;
|
private final VariableProvider variableProvider;
|
||||||
private final GenerationProgress progress;
|
|
||||||
private final ParsedObject parsedObject;
|
private final ParsedObject parsedObject;
|
||||||
private final String variableName;
|
private final String variableName;
|
||||||
private final String engineVariable;
|
private final String engineVariable;
|
||||||
private final ParsedProperty parsedProperty;
|
|
||||||
private final StringBuilder sb;
|
private final StringBuilder sb;
|
||||||
private final Map<String, ParsedProperty> attributes;
|
private final Map<String, ParsedProperty> attributes;
|
||||||
private final WebViewFormatter webViewFormatter;
|
private final WebViewFormatter webViewFormatter;
|
||||||
|
|
||||||
TestWebViewFormatter(@Mock final HelperProvider helperProvider, @Mock final GenerationCompatibilityHelper compatibilityHelper,
|
TestWebViewFormatter(@Mock final HelperProvider helperProvider, @Mock final GenerationCompatibilityHelper compatibilityHelper,
|
||||||
@Mock final ControllerInjector controllerInjector, @Mock final FieldSetter fieldSetter,
|
@Mock final ControllerInjector controllerInjector, @Mock final FieldSetter fieldSetter,
|
||||||
@Mock final PropertyFormatter propertyFormatter, @Mock final GenerationHelper generationHelper,
|
@Mock final PropertyFormatter propertyFormatter, @Mock final VariableProvider variableProvider,
|
||||||
@Mock final GenerationProgress progress, @Mock final ParsedObject parsedObject,
|
@Mock final ParsedObject parsedObject) {
|
||||||
@Mock final ParsedProperty parsedProperty) {
|
|
||||||
this.helperProvider = Objects.requireNonNull(helperProvider);
|
this.helperProvider = Objects.requireNonNull(helperProvider);
|
||||||
this.compatibilityHelper = Objects.requireNonNull(compatibilityHelper);
|
this.compatibilityHelper = Objects.requireNonNull(compatibilityHelper);
|
||||||
this.controllerInjector = Objects.requireNonNull(controllerInjector);
|
this.controllerInjector = Objects.requireNonNull(controllerInjector);
|
||||||
this.fieldSetter = Objects.requireNonNull(fieldSetter);
|
this.fieldSetter = Objects.requireNonNull(fieldSetter);
|
||||||
this.propertyFormatter = Objects.requireNonNull(propertyFormatter);
|
this.propertyFormatter = Objects.requireNonNull(propertyFormatter);
|
||||||
this.generationHelper = Objects.requireNonNull(generationHelper);
|
this.variableProvider = Objects.requireNonNull(variableProvider);
|
||||||
this.progress = Objects.requireNonNull(progress);
|
|
||||||
this.parsedObject = Objects.requireNonNull(parsedObject);
|
this.parsedObject = Objects.requireNonNull(parsedObject);
|
||||||
this.variableName = "variable";
|
this.variableName = "variable";
|
||||||
this.engineVariable = "engine";
|
this.engineVariable = "engine";
|
||||||
this.parsedProperty = Objects.requireNonNull(parsedProperty);
|
|
||||||
this.sb = new StringBuilder();
|
this.sb = new StringBuilder();
|
||||||
this.attributes = new HashMap<>();
|
this.attributes = new HashMap<>();
|
||||||
this.webViewFormatter = new WebViewFormatter(helperProvider, progress);
|
this.webViewFormatter = new WebViewFormatter(helperProvider, sb);
|
||||||
}
|
}
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
@@ -68,19 +62,17 @@ class TestWebViewFormatter {
|
|||||||
when(helperProvider.getCompatibilityHelper()).thenReturn(compatibilityHelper);
|
when(helperProvider.getCompatibilityHelper()).thenReturn(compatibilityHelper);
|
||||||
when(helperProvider.getControllerInjector()).thenReturn(controllerInjector);
|
when(helperProvider.getControllerInjector()).thenReturn(controllerInjector);
|
||||||
when(helperProvider.getFieldSetter()).thenReturn(fieldSetter);
|
when(helperProvider.getFieldSetter()).thenReturn(fieldSetter);
|
||||||
when(helperProvider.getGenerationHelper()).thenReturn(generationHelper);
|
|
||||||
when(helperProvider.getPropertyFormatter()).thenReturn(propertyFormatter);
|
when(helperProvider.getPropertyFormatter()).thenReturn(propertyFormatter);
|
||||||
|
when(helperProvider.getVariableProvider()).thenReturn(variableProvider);
|
||||||
when(compatibilityHelper.getStartVar(anyString())).then(i -> i.getArgument(0));
|
when(compatibilityHelper.getStartVar(anyString())).then(i -> i.getArgument(0));
|
||||||
doAnswer(i -> sb.append(((ParsedProperty) i.getArgument(0)).value()).append((String) i.getArgument(2))).when(controllerInjector).injectCallbackControllerMethod(any(), eq(engineVariable), any());
|
doAnswer(i -> sb.append(((ParsedProperty) i.getArgument(0)).value()).append((String) i.getArgument(2))).when(controllerInjector).injectCallbackControllerMethod(any(), eq(engineVariable), any());
|
||||||
doAnswer(i -> sb.append(((ParsedProperty) i.getArgument(0)).value())).when(controllerInjector).injectEventHandlerControllerMethod(any(), eq(engineVariable));
|
doAnswer(i -> sb.append(((ParsedProperty) i.getArgument(0)).value())).when(controllerInjector).injectEventHandlerControllerMethod(any(), eq(engineVariable));
|
||||||
doAnswer(i -> sb.append(((ParsedProperty) i.getArgument(0)).value())).when(fieldSetter).setEventHandler(any(), eq(engineVariable));
|
doAnswer(i -> sb.append(((ParsedProperty) i.getArgument(0)).value())).when(fieldSetter).setEventHandler(any(), eq(engineVariable));
|
||||||
doAnswer(i -> sb.append(((ParsedProperty) i.getArgument(0)).value()).append((String) i.getArgument(2))).when(fieldSetter).setField(any(), eq(engineVariable), any());
|
doAnswer(i -> sb.append(((ParsedProperty) i.getArgument(0)).value()).append((String) i.getArgument(2))).when(fieldSetter).setField(any(), eq(engineVariable), any());
|
||||||
doAnswer(i -> sb.append("handleId")).when(generationHelper).handleId(parsedObject, variableName);
|
|
||||||
doAnswer(i -> sb.append(((ParsedProperty) i.getArgument(0)).value())).when(propertyFormatter).formatProperty(any(), any(), any());
|
doAnswer(i -> sb.append(((ParsedProperty) i.getArgument(0)).value())).when(propertyFormatter).formatProperty(any(), any(), any());
|
||||||
when(parsedObject.attributes()).thenReturn(attributes);
|
when(parsedObject.attributes()).thenReturn(attributes);
|
||||||
|
|
||||||
when(progress.stringBuilder()).thenReturn(sb);
|
when(variableProvider.getNextVariableName("engine")).thenReturn(engineVariable);
|
||||||
when(progress.getNextVariableName("engine")).thenReturn(engineVariable);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -92,7 +84,7 @@ class TestWebViewFormatter {
|
|||||||
@Test
|
@Test
|
||||||
void testFormatHasProperty() {
|
void testFormatHasProperty() {
|
||||||
final var properties = new LinkedHashMap<ParsedProperty, SequencedCollection<ParsedObject>>();
|
final var properties = new LinkedHashMap<ParsedProperty, SequencedCollection<ParsedObject>>();
|
||||||
properties.put(parsedProperty, List.of(parsedObject));
|
properties.put(new ParsedPropertyImpl("str", null, ""), List.of(parsedObject));
|
||||||
when(parsedObject.properties()).thenReturn(properties);
|
when(parsedObject.properties()).thenReturn(properties);
|
||||||
assertThrows(GenerationException.class, () -> webViewFormatter.formatWebView(parsedObject, variableName));
|
assertThrows(GenerationException.class, () -> webViewFormatter.formatWebView(parsedObject, variableName));
|
||||||
}
|
}
|
||||||
@@ -111,11 +103,13 @@ class TestWebViewFormatter {
|
|||||||
attributes.put("fx:id", new ParsedPropertyImpl("fx:id", null, "id"));
|
attributes.put("fx:id", new ParsedPropertyImpl("fx:id", null, "id"));
|
||||||
|
|
||||||
webViewFormatter.formatWebView(parsedObject, variableName);
|
webViewFormatter.formatWebView(parsedObject, variableName);
|
||||||
final var expected = "javafx.scene.web.WebViewvariable = new javafx.scene.web.WebView();\n" +
|
final var expected = """
|
||||||
"javafx.scene.web.WebEngineengine = variable.getEngine();\n" +
|
javafx.scene.web.WebViewvariable = new javafx.scene.web.WebView();
|
||||||
"#confirmHandlerString.class#createPopupHandlerjavafx.scene.web.PopupFeatures.class" +
|
javafx.scene.web.WebEngineengine = variable.getEngine();
|
||||||
" engine.load(\"location\");\n#onAlert#onResized#onStatusChanged#onVisibilityChanged#promptHandlerjavafx.scene.web.PromptData.class" +
|
#confirmHandlerString.class#createPopupHandlerjavafx.scene.web.PopupFeatures.class\
|
||||||
"propertyhandleId";
|
engine.load("location");
|
||||||
|
#onAlert#onResized#onStatusChanged#onVisibilityChanged#promptHandlerjavafx.scene.web.PromptData.class\
|
||||||
|
property""";
|
||||||
assertEquals(expected, sb.toString());
|
assertEquals(expected, sb.toString());
|
||||||
verify(propertyFormatter).formatProperty(attributes.get("property"), parsedObject, variableName);
|
verify(propertyFormatter).formatProperty(attributes.get("property"), parsedObject, variableName);
|
||||||
verify(controllerInjector).injectCallbackControllerMethod(attributes.get("confirmHandler"), engineVariable, "String.class");
|
verify(controllerInjector).injectCallbackControllerMethod(attributes.get("confirmHandler"), engineVariable, "String.class");
|
||||||
@@ -125,7 +119,6 @@ class TestWebViewFormatter {
|
|||||||
verify(controllerInjector).injectEventHandlerControllerMethod(attributes.get("onStatusChanged"), engineVariable);
|
verify(controllerInjector).injectEventHandlerControllerMethod(attributes.get("onStatusChanged"), engineVariable);
|
||||||
verify(controllerInjector).injectEventHandlerControllerMethod(attributes.get("onVisibilityChanged"), engineVariable);
|
verify(controllerInjector).injectEventHandlerControllerMethod(attributes.get("onVisibilityChanged"), engineVariable);
|
||||||
verify(controllerInjector).injectCallbackControllerMethod(attributes.get("promptHandler"), engineVariable, "javafx.scene.web.PromptData.class");
|
verify(controllerInjector).injectCallbackControllerMethod(attributes.get("promptHandler"), engineVariable, "javafx.scene.web.PromptData.class");
|
||||||
verify(generationHelper).handleId(parsedObject, variableName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -142,12 +135,14 @@ class TestWebViewFormatter {
|
|||||||
attributes.put("fx:id", new ParsedPropertyImpl("fx:id", null, "id"));
|
attributes.put("fx:id", new ParsedPropertyImpl("fx:id", null, "id"));
|
||||||
|
|
||||||
webViewFormatter.formatWebView(parsedObject, variableName);
|
webViewFormatter.formatWebView(parsedObject, variableName);
|
||||||
final var expected = "javafx.scene.web.WebViewvariable = new javafx.scene.web.WebView();\n" +
|
final var expected = """
|
||||||
"javafx.scene.web.WebEngineengine = variable.getEngine();\n" +
|
javafx.scene.web.WebViewvariable = new javafx.scene.web.WebView();
|
||||||
"$controller.confirmHandlerjavafx.util.Callback$controller.createPopupHandlerjavafx.util.Callback" +
|
javafx.scene.web.WebEngineengine = variable.getEngine();
|
||||||
" engine.load(\"location\");\n$controller.onAlert$controller.onResized$controller.onStatusChanged$controller.onVisibilityChanged" +
|
$controller.confirmHandlerjavafx.util.Callback$controller.createPopupHandlerjavafx.util.Callback\
|
||||||
"$controller.promptHandlerjavafx.util.Callback" +
|
engine.load("location");
|
||||||
"propertyhandleId";
|
$controller.onAlert$controller.onResized$controller.onStatusChanged$controller.onVisibilityChanged\
|
||||||
|
$controller.promptHandlerjavafx.util.Callback\
|
||||||
|
property""";
|
||||||
assertEquals(expected, sb.toString());
|
assertEquals(expected, sb.toString());
|
||||||
|
|
||||||
verify(fieldSetter).setEventHandler(attributes.get("onAlert"), engineVariable);
|
verify(fieldSetter).setEventHandler(attributes.get("onAlert"), engineVariable);
|
||||||
@@ -158,6 +153,11 @@ class TestWebViewFormatter {
|
|||||||
verify(fieldSetter).setField(attributes.get("confirmHandler"), engineVariable, "javafx.util.Callback");
|
verify(fieldSetter).setField(attributes.get("confirmHandler"), engineVariable, "javafx.util.Callback");
|
||||||
verify(fieldSetter).setField(attributes.get("createPopupHandler"), engineVariable, "javafx.util.Callback");
|
verify(fieldSetter).setField(attributes.get("createPopupHandler"), engineVariable, "javafx.util.Callback");
|
||||||
verify(fieldSetter).setField(attributes.get("promptHandler"), engineVariable, "javafx.util.Callback");
|
verify(fieldSetter).setField(attributes.get("promptHandler"), engineVariable, "javafx.util.Callback");
|
||||||
verify(generationHelper).handleId(parsedObject, variableName);
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testIllegal() {
|
||||||
|
assertThrows(NullPointerException.class, () -> new WebViewFormatter(null, sb));
|
||||||
|
assertThrows(NullPointerException.class, () -> new WebViewFormatter(helperProvider, null));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,34 +2,34 @@ package com.github.gtache.fxml.compiler.impl.internal;
|
|||||||
|
|
||||||
import javafx.beans.NamedArg;
|
import javafx.beans.NamedArg;
|
||||||
|
|
||||||
public class WholeConstructorArgs {
|
class WholeConstructorArgs {
|
||||||
public WholeConstructorArgs(@NamedArg("p1") final int p1, @NamedArg("p2") final Integer p2,
|
WholeConstructorArgs(@NamedArg("p1") final int p1, @NamedArg("p2") final Integer p2,
|
||||||
@NamedArg("p3") final char p3, @NamedArg("p4") final Character p4,
|
@NamedArg("p3") final char p3, @NamedArg("p4") final Character p4,
|
||||||
@NamedArg("p5") final boolean p5, @NamedArg("p6") final Boolean p6,
|
@NamedArg("p5") final boolean p5, @NamedArg("p6") final Boolean p6,
|
||||||
@NamedArg("p7") final byte p7, @NamedArg("p8") final Byte p8,
|
@NamedArg("p7") final byte p7, @NamedArg("p8") final Byte p8,
|
||||||
@NamedArg("p9") final short p9, @NamedArg("p10") final Short p10,
|
@NamedArg("p9") final short p9, @NamedArg("p10") final Short p10,
|
||||||
@NamedArg("p11") final long p11, @NamedArg("p12") final Long p12,
|
@NamedArg("p11") final long p11, @NamedArg("p12") final Long p12,
|
||||||
@NamedArg("p13") final float p13, @NamedArg("p14") final Float p14,
|
@NamedArg("p13") final float p13, @NamedArg("p14") final Float p14,
|
||||||
@NamedArg("p15") final double p15, @NamedArg("p16") final Double p16,
|
@NamedArg("p15") final double p15, @NamedArg("p16") final Double p16,
|
||||||
@NamedArg("p17") final String p17, @NamedArg("p18") final Object p18) {
|
@NamedArg("p17") final String p17, @NamedArg("p18") final Object p18) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public WholeConstructorArgs(@NamedArg(value = "p1", defaultValue = "1") final int p1,
|
WholeConstructorArgs(@NamedArg(value = "p1", defaultValue = "1") final int p1,
|
||||||
@NamedArg(value = "p3", defaultValue = "a") final char p3,
|
@NamedArg(value = "p3", defaultValue = "a") final char p3,
|
||||||
@NamedArg(value = "p5", defaultValue = "true") final boolean p5,
|
@NamedArg(value = "p5", defaultValue = "true") final boolean p5,
|
||||||
@NamedArg(value = "p7", defaultValue = "2") final byte p7,
|
@NamedArg(value = "p7", defaultValue = "2") final byte p7,
|
||||||
@NamedArg(value = "p9", defaultValue = "3") final short p9,
|
@NamedArg(value = "p9", defaultValue = "3") final short p9,
|
||||||
@NamedArg(value = "p11", defaultValue = "4") final long p11,
|
@NamedArg(value = "p11", defaultValue = "4") final long p11,
|
||||||
@NamedArg(value = "p13", defaultValue = "5.5") final float p13,
|
@NamedArg(value = "p13", defaultValue = "5.5") final float p13,
|
||||||
@NamedArg(value = "p15", defaultValue = "6.6") final double p15,
|
@NamedArg(value = "p15", defaultValue = "6.6") final double p15,
|
||||||
@NamedArg(value = "p17", defaultValue = "str") final String p17) {
|
@NamedArg(value = "p17", defaultValue = "str") final String p17) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public WholeConstructorArgs(final int p1, final char p3) {
|
WholeConstructorArgs(final int p1, final char p3) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public WholeConstructorArgs(final int p1, @NamedArg("p3") final char p3, @NamedArg("p5") final boolean p5) {
|
WholeConstructorArgs(final int p1, @NamedArg("p3") final char p3, @NamedArg("p5") final boolean p5) {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ class TestParsedConstantImpl {
|
|||||||
|
|
||||||
TestParsedConstantImpl() {
|
TestParsedConstantImpl() {
|
||||||
this.className = "test";
|
this.className = "test";
|
||||||
this.attributes = new HashMap<>(Map.of("fx:constant", new ParsedPropertyImpl("fx:constant", String.class.getName(), "value")));
|
this.attributes = new HashMap<>(Map.of("fx:constant", new ParsedPropertyImpl("fx:constant", null, "value")));
|
||||||
this.constant = new ParsedConstantImpl(className, attributes);
|
this.constant = new ParsedConstantImpl(className, attributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -43,9 +43,19 @@ class TestParsedConstantImpl {
|
|||||||
assertThrows(UnsupportedOperationException.class, objectProperties::clear);
|
assertThrows(UnsupportedOperationException.class, objectProperties::clear);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testOtherConstructor() {
|
||||||
|
final var otherConstant = new ParsedConstantImpl(className, "value");
|
||||||
|
assertEquals(className, otherConstant.className());
|
||||||
|
assertEquals(attributes, otherConstant.attributes());
|
||||||
|
assertEquals("value", otherConstant.constant());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testIllegal() {
|
void testIllegal() {
|
||||||
|
final var emptyMap = Map.<String, ParsedProperty>of();
|
||||||
assertThrows(NullPointerException.class, () -> new ParsedConstantImpl(null, attributes));
|
assertThrows(NullPointerException.class, () -> new ParsedConstantImpl(null, attributes));
|
||||||
assertThrows(NullPointerException.class, () -> new ParsedConstantImpl(className, null));
|
assertThrows(NullPointerException.class, () -> new ParsedConstantImpl(className, (Map<String, ParsedProperty>) null));
|
||||||
|
assertThrows(IllegalArgumentException.class, () -> new ParsedConstantImpl(className, emptyMap));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import org.mockito.Mock;
|
|||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.SequencedMap;
|
import java.util.SequencedMap;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.*;
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
@@ -20,7 +21,7 @@ class TestParsedCopyImpl {
|
|||||||
|
|
||||||
TestParsedCopyImpl(@Mock final ParsedProperty property) {
|
TestParsedCopyImpl(@Mock final ParsedProperty property) {
|
||||||
this.properties = new LinkedHashMap<>();
|
this.properties = new LinkedHashMap<>();
|
||||||
this.properties.put("name", property);
|
this.properties.put("source", property);
|
||||||
this.copy = new ParsedCopyImpl(properties);
|
this.copy = new ParsedCopyImpl(properties);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,8 +46,16 @@ class TestParsedCopyImpl {
|
|||||||
assertThrows(UnsupportedOperationException.class, objectProperties::clear);
|
assertThrows(UnsupportedOperationException.class, objectProperties::clear);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testOtherConstructor() {
|
||||||
|
final var otherCopy = new ParsedCopyImpl("source");
|
||||||
|
assertEquals("source", otherCopy.source());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testIllegal() {
|
void testIllegal() {
|
||||||
assertThrows(NullPointerException.class, () -> new TestParsedCopyImpl(null));
|
assertThrows(NullPointerException.class, () -> new ParsedCopyImpl((Map<String, ParsedProperty>) null));
|
||||||
|
final var emptyMap = Map.<String, ParsedProperty>of();
|
||||||
|
assertThrows(IllegalArgumentException.class, () -> new ParsedCopyImpl(emptyMap));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ class TestParsedDefineImpl {
|
|||||||
private final List<ParsedObject> children;
|
private final List<ParsedObject> children;
|
||||||
private final ParsedDefine parsedDefine;
|
private final ParsedDefine parsedDefine;
|
||||||
|
|
||||||
TestParsedDefineImpl(@Mock ParsedObject parsedObject1, @Mock ParsedObject parsedObject2) {
|
TestParsedDefineImpl(@Mock final ParsedObject parsedObject1, @Mock final ParsedObject parsedObject2) {
|
||||||
this.children = new ArrayList<>(List.of(parsedObject1, parsedObject2));
|
this.children = new ArrayList<>(List.of(parsedObject1, parsedObject2));
|
||||||
this.parsedDefine = new ParsedDefineImpl(children);
|
this.parsedDefine = new ParsedDefineImpl(children);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import org.mockito.Mock;
|
|||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.SequencedMap;
|
import java.util.SequencedMap;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.*;
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
@@ -20,7 +21,7 @@ class TestParsedIncludeImpl {
|
|||||||
|
|
||||||
TestParsedIncludeImpl(@Mock final ParsedProperty property) {
|
TestParsedIncludeImpl(@Mock final ParsedProperty property) {
|
||||||
this.properties = new LinkedHashMap<>();
|
this.properties = new LinkedHashMap<>();
|
||||||
this.properties.put("name", property);
|
this.properties.put("source", property);
|
||||||
this.include = new ParsedIncludeImpl(properties);
|
this.include = new ParsedIncludeImpl(properties);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,8 +46,21 @@ class TestParsedIncludeImpl {
|
|||||||
assertThrows(UnsupportedOperationException.class, objectProperties::clear);
|
assertThrows(UnsupportedOperationException.class, objectProperties::clear);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testOtherConstructor() {
|
||||||
|
final var otherInclude = new ParsedIncludeImpl("s", "r", "f");
|
||||||
|
final var attributes = Map.of("source", new ParsedPropertyImpl("source", null, "s"),
|
||||||
|
"resources", new ParsedPropertyImpl("resources", null, "r"),
|
||||||
|
"fx:id", new ParsedPropertyImpl("fx:id", null, "f"));
|
||||||
|
assertEquals(attributes, otherInclude.attributes());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testIllegal() {
|
void testIllegal() {
|
||||||
assertThrows(NullPointerException.class, () -> new ParsedIncludeImpl(null));
|
assertThrows(NullPointerException.class, () -> new ParsedIncludeImpl(null));
|
||||||
|
assertThrows(NullPointerException.class, () -> new ParsedIncludeImpl(null, "", ""));
|
||||||
|
assertDoesNotThrow(() -> new ParsedIncludeImpl("", null, null));
|
||||||
|
final var emptyMap = Map.<String, ParsedProperty>of();
|
||||||
|
assertThrows(IllegalArgumentException.class, () -> new ParsedIncludeImpl(emptyMap));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ class TestParsedObjectImpl {
|
|||||||
this.attributes = new LinkedHashMap<>();
|
this.attributes = new LinkedHashMap<>();
|
||||||
this.attributes.put("name", property);
|
this.attributes.put("name", property);
|
||||||
this.properties = new LinkedHashMap<>();
|
this.properties = new LinkedHashMap<>();
|
||||||
this.properties.put(property, List.of(object));
|
this.properties.put(new ParsedPropertyImpl("property", null, ""), List.of(object));
|
||||||
this.objects = new ArrayList<>(List.of(define));
|
this.objects = new ArrayList<>(List.of(define));
|
||||||
this.parsedObject = new ParsedObjectImpl(clazz, attributes, properties, objects);
|
this.parsedObject = new ParsedObjectImpl(clazz, attributes, properties, objects);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,6 +30,6 @@ class TestParsedPropertyImpl {
|
|||||||
void testIllegal() {
|
void testIllegal() {
|
||||||
assertThrows(NullPointerException.class, () -> new ParsedPropertyImpl(null, sourceType, value));
|
assertThrows(NullPointerException.class, () -> new ParsedPropertyImpl(null, sourceType, value));
|
||||||
assertDoesNotThrow(() -> new ParsedPropertyImpl(name, null, value));
|
assertDoesNotThrow(() -> new ParsedPropertyImpl(name, null, value));
|
||||||
assertDoesNotThrow(() -> new ParsedPropertyImpl(name, sourceType, null));
|
assertThrows(NullPointerException.class, () -> new ParsedPropertyImpl(name, sourceType, null));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import org.mockito.Mock;
|
|||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.SequencedMap;
|
import java.util.SequencedMap;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.*;
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
@@ -20,7 +21,7 @@ class TestParsedReferenceImpl {
|
|||||||
|
|
||||||
TestParsedReferenceImpl(@Mock final ParsedProperty property) {
|
TestParsedReferenceImpl(@Mock final ParsedProperty property) {
|
||||||
this.properties = new LinkedHashMap<>();
|
this.properties = new LinkedHashMap<>();
|
||||||
this.properties.put("name", property);
|
this.properties.put("source", property);
|
||||||
this.reference = new ParsedReferenceImpl(properties);
|
this.reference = new ParsedReferenceImpl(properties);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,8 +46,16 @@ class TestParsedReferenceImpl {
|
|||||||
assertThrows(UnsupportedOperationException.class, objectProperties::clear);
|
assertThrows(UnsupportedOperationException.class, objectProperties::clear);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testOtherConstructor() {
|
||||||
|
final var otherReference = new ParsedReferenceImpl("name");
|
||||||
|
assertEquals("name", otherReference.source());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testIllegal() {
|
void testIllegal() {
|
||||||
assertThrows(NullPointerException.class, () -> new ParsedReferenceImpl(null));
|
assertThrows(NullPointerException.class, () -> new ParsedReferenceImpl((Map<String, ParsedProperty>) null));
|
||||||
|
final var emptyMap = Map.<String, ParsedProperty>of();
|
||||||
|
assertThrows(IllegalArgumentException.class, () -> new ParsedReferenceImpl(emptyMap));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ class TestParsedValueImpl {
|
|||||||
|
|
||||||
TestParsedValueImpl() {
|
TestParsedValueImpl() {
|
||||||
this.className = "test";
|
this.className = "test";
|
||||||
this.attributes = new HashMap<>(Map.of("fx:value", new ParsedPropertyImpl("fx:value", String.class.getName(), "value")));
|
this.attributes = new HashMap<>(Map.of("fx:value", new ParsedPropertyImpl("fx:value", null, "value")));
|
||||||
this.value = new ParsedValueImpl(className, attributes);
|
this.value = new ParsedValueImpl(className, attributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -43,9 +43,19 @@ class TestParsedValueImpl {
|
|||||||
assertThrows(UnsupportedOperationException.class, objectProperties::clear);
|
assertThrows(UnsupportedOperationException.class, objectProperties::clear);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testOtherConstructor() {
|
||||||
|
final var otherValue = new ParsedValueImpl(className, "value");
|
||||||
|
assertEquals(className, otherValue.className());
|
||||||
|
assertEquals(attributes, otherValue.attributes());
|
||||||
|
assertEquals("value", otherValue.value());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testIllegal() {
|
void testIllegal() {
|
||||||
assertThrows(NullPointerException.class, () -> new ParsedValueImpl(null, attributes));
|
assertThrows(NullPointerException.class, () -> new ParsedValueImpl(null, attributes));
|
||||||
assertThrows(NullPointerException.class, () -> new ParsedValueImpl(className, null));
|
assertThrows(NullPointerException.class, () -> new ParsedValueImpl(className, (Map<String, ParsedProperty>) null));
|
||||||
|
final var emptyMap = Map.<String, ParsedProperty>of();
|
||||||
|
assertThrows(IllegalArgumentException.class, () -> new ParsedValueImpl(className, emptyMap));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
package com.github.gtache.fxml.compiler.maven;
|
package com.github.gtache.fxml.compiler.maven;
|
||||||
|
|
||||||
|
import com.github.gtache.fxml.compiler.ControllerFieldInjectionType;
|
||||||
|
import com.github.gtache.fxml.compiler.ControllerInjectionType;
|
||||||
|
import com.github.gtache.fxml.compiler.ControllerMethodsInjectionType;
|
||||||
|
import com.github.gtache.fxml.compiler.ResourceBundleInjectionType;
|
||||||
import com.github.gtache.fxml.compiler.compatibility.impl.GenerationCompatibilityImpl;
|
import com.github.gtache.fxml.compiler.compatibility.impl.GenerationCompatibilityImpl;
|
||||||
import com.github.gtache.fxml.compiler.impl.ControllerFieldInjectionTypes;
|
|
||||||
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.GenerationParametersImpl;
|
||||||
import com.github.gtache.fxml.compiler.impl.ResourceBundleInjectionTypes;
|
|
||||||
import com.github.gtache.fxml.compiler.maven.internal.CompilationInfo;
|
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.CompilationInfoProvider;
|
||||||
import com.github.gtache.fxml.compiler.maven.internal.Compiler;
|
import com.github.gtache.fxml.compiler.maven.internal.Compiler;
|
||||||
@@ -21,6 +21,9 @@ import org.apache.maven.project.MavenProject;
|
|||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Main mojo for FXML compiler
|
* Main mojo for FXML compiler
|
||||||
@@ -41,31 +44,45 @@ public class FXMLCompilerMojo extends AbstractMojo {
|
|||||||
private boolean useImageInputStreamConstructor;
|
private boolean useImageInputStreamConstructor;
|
||||||
|
|
||||||
@Parameter(property = "controller-injection", defaultValue = "INSTANCE", required = true)
|
@Parameter(property = "controller-injection", defaultValue = "INSTANCE", required = true)
|
||||||
private ControllerInjectionTypes controllerInjectionType;
|
private ControllerInjectionType controllerInjectionType;
|
||||||
|
|
||||||
@Parameter(property = "field-injection", defaultValue = "REFLECTION", required = true)
|
@Parameter(property = "field-injection", defaultValue = "REFLECTION", required = true)
|
||||||
private ControllerFieldInjectionTypes fieldInjectionType;
|
private ControllerFieldInjectionType fieldInjectionType;
|
||||||
|
|
||||||
@Parameter(property = "method-injection", defaultValue = "REFLECTION", required = true)
|
@Parameter(property = "method-injection", defaultValue = "REFLECTION", required = true)
|
||||||
private ControllerMethodsInjectionType methodInjectionType;
|
private ControllerMethodsInjectionType methodInjectionType;
|
||||||
|
|
||||||
@Parameter(property = "resource-injection", defaultValue = "CONSTRUCTOR", required = true)
|
@Parameter(property = "resource-injection", defaultValue = "CONSTRUCTOR", required = true)
|
||||||
private ResourceBundleInjectionTypes resourceInjectionType;
|
private ResourceBundleInjectionType resourceInjectionType;
|
||||||
|
|
||||||
@Parameter(property = "resource-map")
|
@Parameter(property = "resource-map")
|
||||||
private Map<String, String> resourceMap;
|
private Map<String, String> resourceMap;
|
||||||
|
|
||||||
|
@Parameter(property = "parallelism", defaultValue = "1", required = true)
|
||||||
|
private int parallelism;
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute() throws MojoExecutionException {
|
public void execute() throws MojoExecutionException {
|
||||||
if (fieldInjectionType == ControllerFieldInjectionTypes.FACTORY && controllerInjectionType != ControllerInjectionTypes.FACTORY) {
|
if (fieldInjectionType == ControllerFieldInjectionType.FACTORY && controllerInjectionType != ControllerInjectionType.FACTORY) {
|
||||||
getLog().warn("Field injection is set to FACTORY : Forcing controller injection to FACTORY");
|
getLog().warn("Field injection is set to FACTORY : Forcing controller injection to FACTORY");
|
||||||
controllerInjectionType = ControllerInjectionTypes.FACTORY;
|
controllerInjectionType = ControllerInjectionType.FACTORY;
|
||||||
}
|
}
|
||||||
final var fxmls = FXMLProvider.getFXMLs(project);
|
final var fxmls = FXMLProvider.getFXMLs(project);
|
||||||
final var controllerMapping = createControllerMapping(fxmls);
|
if (parallelism < 1) {
|
||||||
final var compilationInfoMapping = createCompilationInfoMapping(fxmls, controllerMapping);
|
parallelism = Runtime.getRuntime().availableProcessors();
|
||||||
compile(compilationInfoMapping);
|
}
|
||||||
|
if (parallelism > 1) {
|
||||||
|
try (final var executor = Executors.newFixedThreadPool(parallelism)) {
|
||||||
|
final var controllerMapping = createControllerMapping(fxmls, executor);
|
||||||
|
final var compilationInfoMapping = createCompilationInfoMapping(fxmls, controllerMapping, executor);
|
||||||
|
compile(compilationInfoMapping, executor);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
final var controllerMapping = createControllerMapping(fxmls);
|
||||||
|
final var compilationInfoMapping = createCompilationInfoMapping(fxmls, controllerMapping);
|
||||||
|
compile(compilationInfoMapping);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Map<Path, String> createControllerMapping(final Map<? extends Path, ? extends Path> fxmls) throws MojoExecutionException {
|
private static Map<Path, String> createControllerMapping(final Map<? extends Path, ? extends Path> fxmls) throws MojoExecutionException {
|
||||||
@@ -76,7 +93,8 @@ public class FXMLCompilerMojo extends AbstractMojo {
|
|||||||
return mapping;
|
return mapping;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<Path, CompilationInfo> createCompilationInfoMapping(final Map<? extends Path, ? extends Path> fxmls, final Map<? extends Path, String> controllerMapping) throws MojoExecutionException {
|
private Map<Path, CompilationInfo> createCompilationInfoMapping(final Map<? extends Path, ? extends Path> fxmls,
|
||||||
|
final Map<? extends Path, String> controllerMapping) throws MojoExecutionException {
|
||||||
final var mapping = new HashMap<Path, CompilationInfo>();
|
final var mapping = new HashMap<Path, CompilationInfo>();
|
||||||
for (final var entry : fxmls.entrySet()) {
|
for (final var entry : fxmls.entrySet()) {
|
||||||
final var info = CompilationInfoProvider.getCompilationInfo(entry.getValue(), entry.getKey(), controllerMapping, outputDirectory, project);
|
final var info = CompilationInfoProvider.getCompilationInfo(entry.getValue(), entry.getKey(), controllerMapping, outputDirectory, project);
|
||||||
@@ -91,4 +109,48 @@ public class FXMLCompilerMojo extends AbstractMojo {
|
|||||||
Compiler.compile(mapping, parameters);
|
Compiler.compile(mapping, parameters);
|
||||||
project.addCompileSourceRoot(outputDirectory.toAbsolutePath().toString());
|
project.addCompileSourceRoot(outputDirectory.toAbsolutePath().toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Map<Path, String> createControllerMapping(final Map<? extends Path, ? extends Path> fxmls,
|
||||||
|
final ExecutorService executor) {
|
||||||
|
final var mapping = new ConcurrentHashMap<Path, String>();
|
||||||
|
for (final var fxml : fxmls.keySet()) {
|
||||||
|
executor.submit(() -> {
|
||||||
|
try {
|
||||||
|
mapping.put(fxml, ControllerProvider.getController(fxml));
|
||||||
|
} catch (final MojoExecutionException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return mapping;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<Path, CompilationInfo> createCompilationInfoMapping(final Map<? extends Path, ? extends Path> fxmls,
|
||||||
|
final Map<? extends Path, String> controllerMapping, final ExecutorService executor) {
|
||||||
|
final var mapping = new ConcurrentHashMap<Path, CompilationInfo>();
|
||||||
|
for (final var entry : fxmls.entrySet()) {
|
||||||
|
executor.submit(() -> {
|
||||||
|
try {
|
||||||
|
final var info = CompilationInfoProvider.getCompilationInfo(entry.getValue(), entry.getKey(), controllerMapping, outputDirectory, project);
|
||||||
|
mapping.put(entry.getKey(), info);
|
||||||
|
} catch (final MojoExecutionException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return mapping;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void compile(final Map<Path, CompilationInfo> mapping, final ExecutorService executor) throws MojoExecutionException {
|
||||||
|
final var parameters = new GenerationParametersImpl(new GenerationCompatibilityImpl(targetVersion), useImageInputStreamConstructor, resourceMap,
|
||||||
|
controllerInjectionType, fieldInjectionType, methodInjectionType, resourceInjectionType);
|
||||||
|
mapping.forEach((p, i) -> executor.submit(() -> {
|
||||||
|
try {
|
||||||
|
Compiler.compile(p, i, mapping, parameters);
|
||||||
|
} catch (final MojoExecutionException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
project.addCompileSourceRoot(outputDirectory.toAbsolutePath().toString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ import org.apache.logging.log4j.LogManager;
|
|||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.apache.maven.plugin.MojoExecutionException;
|
import org.apache.maven.plugin.MojoExecutionException;
|
||||||
|
|
||||||
import javax.inject.Named;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
@@ -21,7 +20,6 @@ import java.util.Map;
|
|||||||
/**
|
/**
|
||||||
* Creates compiled Java code
|
* Creates compiled Java code
|
||||||
*/
|
*/
|
||||||
@Named
|
|
||||||
public final class Compiler {
|
public final class Compiler {
|
||||||
|
|
||||||
private static final Logger logger = LogManager.getLogger(Compiler.class);
|
private static final Logger logger = LogManager.getLogger(Compiler.class);
|
||||||
@@ -45,7 +43,7 @@ public final class Compiler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void compile(final Path inputPath, final CompilationInfo info, final Map<Path, CompilationInfo> mapping, final GenerationParameters parameters) throws MojoExecutionException {
|
public static void compile(final Path inputPath, final CompilationInfo info, final Map<Path, CompilationInfo> mapping, final GenerationParameters parameters) throws MojoExecutionException {
|
||||||
try {
|
try {
|
||||||
logger.info("Parsing {} with {}", inputPath, PARSER.getClass().getSimpleName());
|
logger.info("Parsing {} with {}", inputPath, PARSER.getClass().getSimpleName());
|
||||||
final var root = PARSER.parse(inputPath);
|
final var root = PARSER.parse(inputPath);
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package com.github.gtache.fxml.compiler.maven.internal;
|
|||||||
import org.apache.maven.plugin.MojoExecutionException;
|
import org.apache.maven.plugin.MojoExecutionException;
|
||||||
import org.xml.sax.SAXException;
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
import javax.inject.Named;
|
|
||||||
import javax.xml.parsers.DocumentBuilder;
|
import javax.xml.parsers.DocumentBuilder;
|
||||||
import javax.xml.parsers.DocumentBuilderFactory;
|
import javax.xml.parsers.DocumentBuilderFactory;
|
||||||
import javax.xml.parsers.ParserConfigurationException;
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
@@ -13,7 +12,6 @@ import java.nio.file.Path;
|
|||||||
/**
|
/**
|
||||||
* Extracts controller class from FXMLs
|
* Extracts controller class from FXMLs
|
||||||
*/
|
*/
|
||||||
@Named
|
|
||||||
public final class ControllerProvider {
|
public final class ControllerProvider {
|
||||||
private static final DocumentBuilder DOCUMENT_BUILDER;
|
private static final DocumentBuilder DOCUMENT_BUILDER;
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import org.apache.logging.log4j.Logger;
|
|||||||
import org.apache.maven.plugin.MojoExecutionException;
|
import org.apache.maven.plugin.MojoExecutionException;
|
||||||
import org.apache.maven.project.MavenProject;
|
import org.apache.maven.project.MavenProject;
|
||||||
|
|
||||||
import javax.inject.Named;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.FileVisitOption;
|
import java.nio.file.FileVisitOption;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
@@ -17,7 +16,6 @@ import java.util.Map;
|
|||||||
/**
|
/**
|
||||||
* Extracts FXML paths from Maven project
|
* Extracts FXML paths from Maven project
|
||||||
*/
|
*/
|
||||||
@Named
|
|
||||||
public final class FXMLProvider {
|
public final class FXMLProvider {
|
||||||
private static final Logger logger = LogManager.getLogger(FXMLProvider.class);
|
private static final Logger logger = LogManager.getLogger(FXMLProvider.class);
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ import java.util.Objects;
|
|||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
import static org.mockito.ArgumentMatchers.*;
|
|
||||||
import static org.mockito.Mockito.*;
|
import static org.mockito.Mockito.*;
|
||||||
|
|
||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
@@ -41,7 +40,6 @@ class TestCompiler {
|
|||||||
private final SourceInfo sourceInfo;
|
private final SourceInfo sourceInfo;
|
||||||
private final String content;
|
private final String content;
|
||||||
private final GenerationParameters parameters;
|
private final GenerationParameters parameters;
|
||||||
private final Compiler compiler;
|
|
||||||
|
|
||||||
TestCompiler(@Mock final ControllerInfoProvider controllerInfoProvider, @Mock final SourceInfoProvider sourceInfoProvider,
|
TestCompiler(@Mock final ControllerInfoProvider controllerInfoProvider, @Mock final SourceInfoProvider sourceInfoProvider,
|
||||||
@Mock final FXMLParser fxmlParser, @Mock final CompilationInfo compilationInfo, @Mock final ParsedObject object,
|
@Mock final FXMLParser fxmlParser, @Mock final CompilationInfo compilationInfo, @Mock final ParsedObject object,
|
||||||
@@ -57,7 +55,6 @@ class TestCompiler {
|
|||||||
this.content = "content";
|
this.content = "content";
|
||||||
this.parameters = Objects.requireNonNull(parameters);
|
this.parameters = Objects.requireNonNull(parameters);
|
||||||
this.generator = Objects.requireNonNull(generator);
|
this.generator = Objects.requireNonNull(generator);
|
||||||
this.compiler = new Compiler(controllerInfoProvider, sourceInfoProvider, fxmlParser, generator);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
@@ -77,7 +74,7 @@ class TestCompiler {
|
|||||||
when(compilationInfo.outputClass()).thenReturn(outputClass);
|
when(compilationInfo.outputClass()).thenReturn(outputClass);
|
||||||
final var mapping = Map.of(path, compilationInfo);
|
final var mapping = Map.of(path, compilationInfo);
|
||||||
final var request = new GenerationRequestImpl(parameters, controllerInfo, sourceInfo, object, outputClass);
|
final var request = new GenerationRequestImpl(parameters, controllerInfo, sourceInfo, object, outputClass);
|
||||||
compiler.compile(mapping, parameters);
|
Compiler.compile(mapping, parameters);
|
||||||
verify(fxmlParser).parse(path);
|
verify(fxmlParser).parse(path);
|
||||||
ControllerInfoProvider.getControllerInfo(compilationInfo);
|
ControllerInfoProvider.getControllerInfo(compilationInfo);
|
||||||
SourceInfoProvider.getSourceInfo(compilationInfo, mapping);
|
SourceInfoProvider.getSourceInfo(compilationInfo, mapping);
|
||||||
@@ -94,7 +91,7 @@ class TestCompiler {
|
|||||||
when(compilationInfo.outputClass()).thenReturn(outputClass);
|
when(compilationInfo.outputClass()).thenReturn(outputClass);
|
||||||
final var mapping = Map.of(path, compilationInfo);
|
final var mapping = Map.of(path, compilationInfo);
|
||||||
final var request = new GenerationRequestImpl(parameters, controllerInfo, sourceInfo, object, outputClass);
|
final var request = new GenerationRequestImpl(parameters, controllerInfo, sourceInfo, object, outputClass);
|
||||||
assertThrows(MojoExecutionException.class, () -> compiler.compile(mapping, parameters));
|
assertThrows(MojoExecutionException.class, () -> Compiler.compile(mapping, parameters));
|
||||||
verify(fxmlParser).parse(path);
|
verify(fxmlParser).parse(path);
|
||||||
ControllerInfoProvider.getControllerInfo(compilationInfo);
|
ControllerInfoProvider.getControllerInfo(compilationInfo);
|
||||||
SourceInfoProvider.getSourceInfo(compilationInfo, mapping);
|
SourceInfoProvider.getSourceInfo(compilationInfo, mapping);
|
||||||
@@ -111,7 +108,7 @@ class TestCompiler {
|
|||||||
final var mapping = Map.of(path, compilationInfo);
|
final var mapping = Map.of(path, compilationInfo);
|
||||||
final var request = new GenerationRequestImpl(parameters, controllerInfo, sourceInfo, object, outputClass);
|
final var request = new GenerationRequestImpl(parameters, controllerInfo, sourceInfo, object, outputClass);
|
||||||
when(generator.generate(request)).thenThrow(RuntimeException.class);
|
when(generator.generate(request)).thenThrow(RuntimeException.class);
|
||||||
assertThrows(MojoExecutionException.class, () -> compiler.compile(mapping, parameters));
|
assertThrows(MojoExecutionException.class, () -> Compiler.compile(mapping, parameters));
|
||||||
verify(fxmlParser).parse(path);
|
verify(fxmlParser).parse(path);
|
||||||
ControllerInfoProvider.getControllerInfo(compilationInfo);
|
ControllerInfoProvider.getControllerInfo(compilationInfo);
|
||||||
SourceInfoProvider.getSourceInfo(compilationInfo, mapping);
|
SourceInfoProvider.getSourceInfo(compilationInfo, mapping);
|
||||||
@@ -123,7 +120,7 @@ class TestCompiler {
|
|||||||
when(fxmlParser.parse((Path) any())).thenThrow(ParseException.class);
|
when(fxmlParser.parse((Path) any())).thenThrow(ParseException.class);
|
||||||
final var path = tempDir.resolve("fxml1.fxml");
|
final var path = tempDir.resolve("fxml1.fxml");
|
||||||
final var mapping = Map.of(path, compilationInfo);
|
final var mapping = Map.of(path, compilationInfo);
|
||||||
assertThrows(MojoExecutionException.class, () -> compiler.compile(mapping, parameters));
|
assertThrows(MojoExecutionException.class, () -> Compiler.compile(mapping, parameters));
|
||||||
verify(fxmlParser).parse(path);
|
verify(fxmlParser).parse(path);
|
||||||
verifyNoInteractions(controllerInfoProvider, sourceInfoProvider, generator);
|
verifyNoInteractions(controllerInfoProvider, sourceInfoProvider, generator);
|
||||||
}
|
}
|
||||||
@@ -138,18 +135,10 @@ class TestCompiler {
|
|||||||
final var mapping = Map.of(path, compilationInfo);
|
final var mapping = Map.of(path, compilationInfo);
|
||||||
final var request = new GenerationRequestImpl(parameters, controllerInfo, sourceInfo, object, outputClass);
|
final var request = new GenerationRequestImpl(parameters, controllerInfo, sourceInfo, object, outputClass);
|
||||||
when(generator.generate(request)).thenThrow(GenerationException.class);
|
when(generator.generate(request)).thenThrow(GenerationException.class);
|
||||||
assertThrows(MojoExecutionException.class, () -> compiler.compile(mapping, parameters));
|
assertThrows(MojoExecutionException.class, () -> Compiler.compile(mapping, parameters));
|
||||||
verify(fxmlParser).parse(path);
|
verify(fxmlParser).parse(path);
|
||||||
ControllerInfoProvider.getControllerInfo(compilationInfo);
|
ControllerInfoProvider.getControllerInfo(compilationInfo);
|
||||||
SourceInfoProvider.getSourceInfo(compilationInfo, mapping);
|
SourceInfoProvider.getSourceInfo(compilationInfo, mapping);
|
||||||
verify(generator).generate(request);
|
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));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,12 +16,6 @@ import static org.junit.jupiter.api.Assertions.assertThrows;
|
|||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
class TestControllerProvider {
|
class TestControllerProvider {
|
||||||
|
|
||||||
private final ControllerProvider provider;
|
|
||||||
|
|
||||||
TestControllerProvider() {
|
|
||||||
this.provider = new ControllerProvider();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testGetController(@TempDir final Path tempDir) throws Exception {
|
void testGetController(@TempDir final Path tempDir) throws Exception {
|
||||||
final var fxml = tempDir.resolve("fxml.fxml");
|
final var fxml = tempDir.resolve("fxml.fxml");
|
||||||
|
|||||||
@@ -22,11 +22,9 @@ import static org.mockito.Mockito.when;
|
|||||||
class TestFXMLProvider {
|
class TestFXMLProvider {
|
||||||
|
|
||||||
private final MavenProject project;
|
private final MavenProject project;
|
||||||
private final FXMLProvider provider;
|
|
||||||
|
|
||||||
TestFXMLProvider(@Mock final MavenProject project) {
|
TestFXMLProvider(@Mock final MavenProject project) {
|
||||||
this.project = Objects.requireNonNull(project);
|
this.project = Objects.requireNonNull(project);
|
||||||
this.provider = new FXMLProvider();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
259
mvnw
vendored
Normal file
259
mvnw
vendored
Normal file
@@ -0,0 +1,259 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# ----------------------------------------------------------------------------
|
||||||
|
# Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
# or more contributor license agreements. See the NOTICE file
|
||||||
|
# distributed with this work for additional information
|
||||||
|
# regarding copyright ownership. The ASF licenses this file
|
||||||
|
# to you under the Apache License, Version 2.0 (the
|
||||||
|
# "License"); you may not use this file except in compliance
|
||||||
|
# with the License. You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing,
|
||||||
|
# software distributed under the License is distributed on an
|
||||||
|
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
# KIND, either express or implied. See the License for the
|
||||||
|
# specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
# ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# ----------------------------------------------------------------------------
|
||||||
|
# Apache Maven Wrapper startup batch script, version 3.3.2
|
||||||
|
#
|
||||||
|
# Optional ENV vars
|
||||||
|
# -----------------
|
||||||
|
# JAVA_HOME - location of a JDK home dir, required when download maven via java source
|
||||||
|
# MVNW_REPOURL - repo url base for downloading maven distribution
|
||||||
|
# MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven
|
||||||
|
# MVNW_VERBOSE - true: enable verbose log; debug: trace the mvnw script; others: silence the output
|
||||||
|
# ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
set -euf
|
||||||
|
[ "${MVNW_VERBOSE-}" != debug ] || set -x
|
||||||
|
|
||||||
|
# OS specific support.
|
||||||
|
native_path() { printf %s\\n "$1"; }
|
||||||
|
case "$(uname)" in
|
||||||
|
CYGWIN* | MINGW*)
|
||||||
|
[ -z "${JAVA_HOME-}" ] || JAVA_HOME="$(cygpath --unix "$JAVA_HOME")"
|
||||||
|
native_path() { cygpath --path --windows "$1"; }
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# set JAVACMD and JAVACCMD
|
||||||
|
set_java_home() {
|
||||||
|
# For Cygwin and MinGW, ensure paths are in Unix format before anything is touched
|
||||||
|
if [ -n "${JAVA_HOME-}" ]; then
|
||||||
|
if [ -x "$JAVA_HOME/jre/sh/java" ]; then
|
||||||
|
# IBM's JDK on AIX uses strange locations for the executables
|
||||||
|
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||||
|
JAVACCMD="$JAVA_HOME/jre/sh/javac"
|
||||||
|
else
|
||||||
|
JAVACMD="$JAVA_HOME/bin/java"
|
||||||
|
JAVACCMD="$JAVA_HOME/bin/javac"
|
||||||
|
|
||||||
|
if [ ! -x "$JAVACMD" ] || [ ! -x "$JAVACCMD" ]; then
|
||||||
|
echo "The JAVA_HOME environment variable is not defined correctly, so mvnw cannot run." >&2
|
||||||
|
echo "JAVA_HOME is set to \"$JAVA_HOME\", but \"\$JAVA_HOME/bin/java\" or \"\$JAVA_HOME/bin/javac\" does not exist." >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
JAVACMD="$(
|
||||||
|
'set' +e
|
||||||
|
'unset' -f command 2>/dev/null
|
||||||
|
'command' -v java
|
||||||
|
)" || :
|
||||||
|
JAVACCMD="$(
|
||||||
|
'set' +e
|
||||||
|
'unset' -f command 2>/dev/null
|
||||||
|
'command' -v javac
|
||||||
|
)" || :
|
||||||
|
|
||||||
|
if [ ! -x "${JAVACMD-}" ] || [ ! -x "${JAVACCMD-}" ]; then
|
||||||
|
echo "The java/javac command does not exist in PATH nor is JAVA_HOME set, so mvnw cannot run." >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# hash string like Java String::hashCode
|
||||||
|
hash_string() {
|
||||||
|
str="${1:-}" h=0
|
||||||
|
while [ -n "$str" ]; do
|
||||||
|
char="${str%"${str#?}"}"
|
||||||
|
h=$(((h * 31 + $(LC_CTYPE=C printf %d "'$char")) % 4294967296))
|
||||||
|
str="${str#?}"
|
||||||
|
done
|
||||||
|
printf %x\\n $h
|
||||||
|
}
|
||||||
|
|
||||||
|
verbose() { :; }
|
||||||
|
[ "${MVNW_VERBOSE-}" != true ] || verbose() { printf %s\\n "${1-}"; }
|
||||||
|
|
||||||
|
die() {
|
||||||
|
printf %s\\n "$1" >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
trim() {
|
||||||
|
# MWRAPPER-139:
|
||||||
|
# Trims trailing and leading whitespace, carriage returns, tabs, and linefeeds.
|
||||||
|
# Needed for removing poorly interpreted newline sequences when running in more
|
||||||
|
# exotic environments such as mingw bash on Windows.
|
||||||
|
printf "%s" "${1}" | tr -d '[:space:]'
|
||||||
|
}
|
||||||
|
|
||||||
|
# parse distributionUrl and optional distributionSha256Sum, requires .mvn/wrapper/maven-wrapper.properties
|
||||||
|
while IFS="=" read -r key value; do
|
||||||
|
case "${key-}" in
|
||||||
|
distributionUrl) distributionUrl=$(trim "${value-}") ;;
|
||||||
|
distributionSha256Sum) distributionSha256Sum=$(trim "${value-}") ;;
|
||||||
|
esac
|
||||||
|
done <"${0%/*}/.mvn/wrapper/maven-wrapper.properties"
|
||||||
|
[ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in ${0%/*}/.mvn/wrapper/maven-wrapper.properties"
|
||||||
|
|
||||||
|
case "${distributionUrl##*/}" in
|
||||||
|
maven-mvnd-*bin.*)
|
||||||
|
MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/
|
||||||
|
case "${PROCESSOR_ARCHITECTURE-}${PROCESSOR_ARCHITEW6432-}:$(uname -a)" in
|
||||||
|
*AMD64:CYGWIN* | *AMD64:MINGW*) distributionPlatform=windows-amd64 ;;
|
||||||
|
:Darwin*x86_64) distributionPlatform=darwin-amd64 ;;
|
||||||
|
:Darwin*arm64) distributionPlatform=darwin-aarch64 ;;
|
||||||
|
:Linux*x86_64*) distributionPlatform=linux-amd64 ;;
|
||||||
|
*)
|
||||||
|
echo "Cannot detect native platform for mvnd on $(uname)-$(uname -m), use pure java version" >&2
|
||||||
|
distributionPlatform=linux-amd64
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
distributionUrl="${distributionUrl%-bin.*}-$distributionPlatform.zip"
|
||||||
|
;;
|
||||||
|
maven-mvnd-*) MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ ;;
|
||||||
|
*) MVN_CMD="mvn${0##*/mvnw}" _MVNW_REPO_PATTERN=/org/apache/maven/ ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# apply MVNW_REPOURL and calculate MAVEN_HOME
|
||||||
|
# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-<version>,maven-mvnd-<version>-<platform>}/<hash>
|
||||||
|
[ -z "${MVNW_REPOURL-}" ] || distributionUrl="$MVNW_REPOURL$_MVNW_REPO_PATTERN${distributionUrl#*"$_MVNW_REPO_PATTERN"}"
|
||||||
|
distributionUrlName="${distributionUrl##*/}"
|
||||||
|
distributionUrlNameMain="${distributionUrlName%.*}"
|
||||||
|
distributionUrlNameMain="${distributionUrlNameMain%-bin}"
|
||||||
|
MAVEN_USER_HOME="${MAVEN_USER_HOME:-${HOME}/.m2}"
|
||||||
|
MAVEN_HOME="${MAVEN_USER_HOME}/wrapper/dists/${distributionUrlNameMain-}/$(hash_string "$distributionUrl")"
|
||||||
|
|
||||||
|
exec_maven() {
|
||||||
|
unset MVNW_VERBOSE MVNW_USERNAME MVNW_PASSWORD MVNW_REPOURL || :
|
||||||
|
exec "$MAVEN_HOME/bin/$MVN_CMD" "$@" || die "cannot exec $MAVEN_HOME/bin/$MVN_CMD"
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ -d "$MAVEN_HOME" ]; then
|
||||||
|
verbose "found existing MAVEN_HOME at $MAVEN_HOME"
|
||||||
|
exec_maven "$@"
|
||||||
|
fi
|
||||||
|
|
||||||
|
case "${distributionUrl-}" in
|
||||||
|
*?-bin.zip | *?maven-mvnd-?*-?*.zip) ;;
|
||||||
|
*) die "distributionUrl is not valid, must match *-bin.zip or maven-mvnd-*.zip, but found '${distributionUrl-}'" ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# prepare tmp dir
|
||||||
|
if TMP_DOWNLOAD_DIR="$(mktemp -d)" && [ -d "$TMP_DOWNLOAD_DIR" ]; then
|
||||||
|
clean() { rm -rf -- "$TMP_DOWNLOAD_DIR"; }
|
||||||
|
trap clean HUP INT TERM EXIT
|
||||||
|
else
|
||||||
|
die "cannot create temp dir"
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p -- "${MAVEN_HOME%/*}"
|
||||||
|
|
||||||
|
# Download and Install Apache Maven
|
||||||
|
verbose "Couldn't find MAVEN_HOME, downloading and installing it ..."
|
||||||
|
verbose "Downloading from: $distributionUrl"
|
||||||
|
verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName"
|
||||||
|
|
||||||
|
# select .zip or .tar.gz
|
||||||
|
if ! command -v unzip >/dev/null; then
|
||||||
|
distributionUrl="${distributionUrl%.zip}.tar.gz"
|
||||||
|
distributionUrlName="${distributionUrl##*/}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# verbose opt
|
||||||
|
__MVNW_QUIET_WGET=--quiet __MVNW_QUIET_CURL=--silent __MVNW_QUIET_UNZIP=-q __MVNW_QUIET_TAR=''
|
||||||
|
[ "${MVNW_VERBOSE-}" != true ] || __MVNW_QUIET_WGET='' __MVNW_QUIET_CURL='' __MVNW_QUIET_UNZIP='' __MVNW_QUIET_TAR=v
|
||||||
|
|
||||||
|
# normalize http auth
|
||||||
|
case "${MVNW_PASSWORD:+has-password}" in
|
||||||
|
'') MVNW_USERNAME='' MVNW_PASSWORD='' ;;
|
||||||
|
has-password) [ -n "${MVNW_USERNAME-}" ] || MVNW_USERNAME='' MVNW_PASSWORD='' ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if [ -z "${MVNW_USERNAME-}" ] && command -v wget >/dev/null; then
|
||||||
|
verbose "Found wget ... using wget"
|
||||||
|
wget ${__MVNW_QUIET_WGET:+"$__MVNW_QUIET_WGET"} "$distributionUrl" -O "$TMP_DOWNLOAD_DIR/$distributionUrlName" || die "wget: Failed to fetch $distributionUrl"
|
||||||
|
elif [ -z "${MVNW_USERNAME-}" ] && command -v curl >/dev/null; then
|
||||||
|
verbose "Found curl ... using curl"
|
||||||
|
curl ${__MVNW_QUIET_CURL:+"$__MVNW_QUIET_CURL"} -f -L -o "$TMP_DOWNLOAD_DIR/$distributionUrlName" "$distributionUrl" || die "curl: Failed to fetch $distributionUrl"
|
||||||
|
elif set_java_home; then
|
||||||
|
verbose "Falling back to use Java to download"
|
||||||
|
javaSource="$TMP_DOWNLOAD_DIR/Downloader.java"
|
||||||
|
targetZip="$TMP_DOWNLOAD_DIR/$distributionUrlName"
|
||||||
|
cat >"$javaSource" <<-END
|
||||||
|
public class Downloader extends java.net.Authenticator
|
||||||
|
{
|
||||||
|
protected java.net.PasswordAuthentication getPasswordAuthentication()
|
||||||
|
{
|
||||||
|
return new java.net.PasswordAuthentication( System.getenv( "MVNW_USERNAME" ), System.getenv( "MVNW_PASSWORD" ).toCharArray() );
|
||||||
|
}
|
||||||
|
public static void main( String[] args ) throws Exception
|
||||||
|
{
|
||||||
|
setDefault( new Downloader() );
|
||||||
|
java.nio.file.Files.copy( java.net.URI.create( args[0] ).toURL().openStream(), java.nio.file.Paths.get( args[1] ).toAbsolutePath().normalize() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
END
|
||||||
|
# For Cygwin/MinGW, switch paths to Windows format before running javac and java
|
||||||
|
verbose " - Compiling Downloader.java ..."
|
||||||
|
"$(native_path "$JAVACCMD")" "$(native_path "$javaSource")" || die "Failed to compile Downloader.java"
|
||||||
|
verbose " - Running Downloader.java ..."
|
||||||
|
"$(native_path "$JAVACMD")" -cp "$(native_path "$TMP_DOWNLOAD_DIR")" Downloader "$distributionUrl" "$(native_path "$targetZip")"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# If specified, validate the SHA-256 sum of the Maven distribution zip file
|
||||||
|
if [ -n "${distributionSha256Sum-}" ]; then
|
||||||
|
distributionSha256Result=false
|
||||||
|
if [ "$MVN_CMD" = mvnd.sh ]; then
|
||||||
|
echo "Checksum validation is not supported for maven-mvnd." >&2
|
||||||
|
echo "Please disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2
|
||||||
|
exit 1
|
||||||
|
elif command -v sha256sum >/dev/null; then
|
||||||
|
if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | sha256sum -c >/dev/null 2>&1; then
|
||||||
|
distributionSha256Result=true
|
||||||
|
fi
|
||||||
|
elif command -v shasum >/dev/null; then
|
||||||
|
if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | shasum -a 256 -c >/dev/null 2>&1; then
|
||||||
|
distributionSha256Result=true
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." >&2
|
||||||
|
echo "Please install either command, or disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [ $distributionSha256Result = false ]; then
|
||||||
|
echo "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised." >&2
|
||||||
|
echo "If you updated your Maven version, you need to update the specified distributionSha256Sum property." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# unzip and move
|
||||||
|
if command -v unzip >/dev/null; then
|
||||||
|
unzip ${__MVNW_QUIET_UNZIP:+"$__MVNW_QUIET_UNZIP"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -d "$TMP_DOWNLOAD_DIR" || die "failed to unzip"
|
||||||
|
else
|
||||||
|
tar xzf${__MVNW_QUIET_TAR:+"$__MVNW_QUIET_TAR"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -C "$TMP_DOWNLOAD_DIR" || die "failed to untar"
|
||||||
|
fi
|
||||||
|
printf %s\\n "$distributionUrl" >"$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/mvnw.url"
|
||||||
|
mv -- "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME"
|
||||||
|
|
||||||
|
clean || :
|
||||||
|
exec_maven "$@"
|
||||||
149
mvnw.cmd
vendored
Normal file
149
mvnw.cmd
vendored
Normal file
@@ -0,0 +1,149 @@
|
|||||||
|
<# : batch portion
|
||||||
|
@REM ----------------------------------------------------------------------------
|
||||||
|
@REM Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
@REM or more contributor license agreements. See the NOTICE file
|
||||||
|
@REM distributed with this work for additional information
|
||||||
|
@REM regarding copyright ownership. The ASF licenses this file
|
||||||
|
@REM to you under the Apache License, Version 2.0 (the
|
||||||
|
@REM "License"); you may not use this file except in compliance
|
||||||
|
@REM with the License. You may obtain a copy of the License at
|
||||||
|
@REM
|
||||||
|
@REM http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
@REM
|
||||||
|
@REM Unless required by applicable law or agreed to in writing,
|
||||||
|
@REM software distributed under the License is distributed on an
|
||||||
|
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
@REM KIND, either express or implied. See the License for the
|
||||||
|
@REM specific language governing permissions and limitations
|
||||||
|
@REM under the License.
|
||||||
|
@REM ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@REM ----------------------------------------------------------------------------
|
||||||
|
@REM Apache Maven Wrapper startup batch script, version 3.3.2
|
||||||
|
@REM
|
||||||
|
@REM Optional ENV vars
|
||||||
|
@REM MVNW_REPOURL - repo url base for downloading maven distribution
|
||||||
|
@REM MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven
|
||||||
|
@REM MVNW_VERBOSE - true: enable verbose log; others: silence the output
|
||||||
|
@REM ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0)
|
||||||
|
@SET __MVNW_CMD__=
|
||||||
|
@SET __MVNW_ERROR__=
|
||||||
|
@SET __MVNW_PSMODULEP_SAVE=%PSModulePath%
|
||||||
|
@SET PSModulePath=
|
||||||
|
@FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @(
|
||||||
|
IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B)
|
||||||
|
)
|
||||||
|
@SET PSModulePath=%__MVNW_PSMODULEP_SAVE%
|
||||||
|
@SET __MVNW_PSMODULEP_SAVE=
|
||||||
|
@SET __MVNW_ARG0_NAME__=
|
||||||
|
@SET MVNW_USERNAME=
|
||||||
|
@SET MVNW_PASSWORD=
|
||||||
|
@IF NOT "%__MVNW_CMD__%"=="" (%__MVNW_CMD__% %*)
|
||||||
|
@echo Cannot start maven from wrapper >&2 && exit /b 1
|
||||||
|
@GOTO :EOF
|
||||||
|
: end batch / begin powershell #>
|
||||||
|
|
||||||
|
$ErrorActionPreference = "Stop"
|
||||||
|
if ($env:MVNW_VERBOSE -eq "true") {
|
||||||
|
$VerbosePreference = "Continue"
|
||||||
|
}
|
||||||
|
|
||||||
|
# calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties
|
||||||
|
$distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl
|
||||||
|
if (!$distributionUrl) {
|
||||||
|
Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties"
|
||||||
|
}
|
||||||
|
|
||||||
|
switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) {
|
||||||
|
"maven-mvnd-*" {
|
||||||
|
$USE_MVND = $true
|
||||||
|
$distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip"
|
||||||
|
$MVN_CMD = "mvnd.cmd"
|
||||||
|
break
|
||||||
|
}
|
||||||
|
default {
|
||||||
|
$USE_MVND = $false
|
||||||
|
$MVN_CMD = $script -replace '^mvnw','mvn'
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# apply MVNW_REPOURL and calculate MAVEN_HOME
|
||||||
|
# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-<version>,maven-mvnd-<version>-<platform>}/<hash>
|
||||||
|
if ($env:MVNW_REPOURL) {
|
||||||
|
$MVNW_REPO_PATTERN = if ($USE_MVND) { "/org/apache/maven/" } else { "/maven/mvnd/" }
|
||||||
|
$distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace '^.*'+$MVNW_REPO_PATTERN,'')"
|
||||||
|
}
|
||||||
|
$distributionUrlName = $distributionUrl -replace '^.*/',''
|
||||||
|
$distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$',''
|
||||||
|
$MAVEN_HOME_PARENT = "$HOME/.m2/wrapper/dists/$distributionUrlNameMain"
|
||||||
|
if ($env:MAVEN_USER_HOME) {
|
||||||
|
$MAVEN_HOME_PARENT = "$env:MAVEN_USER_HOME/wrapper/dists/$distributionUrlNameMain"
|
||||||
|
}
|
||||||
|
$MAVEN_HOME_NAME = ([System.Security.Cryptography.MD5]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join ''
|
||||||
|
$MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME"
|
||||||
|
|
||||||
|
if (Test-Path -Path "$MAVEN_HOME" -PathType Container) {
|
||||||
|
Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME"
|
||||||
|
Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD"
|
||||||
|
exit $?
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) {
|
||||||
|
Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl"
|
||||||
|
}
|
||||||
|
|
||||||
|
# prepare tmp dir
|
||||||
|
$TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile
|
||||||
|
$TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir"
|
||||||
|
$TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null
|
||||||
|
trap {
|
||||||
|
if ($TMP_DOWNLOAD_DIR.Exists) {
|
||||||
|
try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null }
|
||||||
|
catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null
|
||||||
|
|
||||||
|
# Download and Install Apache Maven
|
||||||
|
Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..."
|
||||||
|
Write-Verbose "Downloading from: $distributionUrl"
|
||||||
|
Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName"
|
||||||
|
|
||||||
|
$webclient = New-Object System.Net.WebClient
|
||||||
|
if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) {
|
||||||
|
$webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD)
|
||||||
|
}
|
||||||
|
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
|
||||||
|
$webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null
|
||||||
|
|
||||||
|
# If specified, validate the SHA-256 sum of the Maven distribution zip file
|
||||||
|
$distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum
|
||||||
|
if ($distributionSha256Sum) {
|
||||||
|
if ($USE_MVND) {
|
||||||
|
Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties."
|
||||||
|
}
|
||||||
|
Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash
|
||||||
|
if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) {
|
||||||
|
Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# unzip and move
|
||||||
|
Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null
|
||||||
|
Rename-Item -Path "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" -NewName $MAVEN_HOME_NAME | Out-Null
|
||||||
|
try {
|
||||||
|
Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null
|
||||||
|
} catch {
|
||||||
|
if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) {
|
||||||
|
Write-Error "fail to move MAVEN_HOME"
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null }
|
||||||
|
catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" }
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD"
|
||||||
33
pom.xml
33
pom.xml
@@ -26,7 +26,7 @@
|
|||||||
</organization>
|
</organization>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<maven.min-version>3.8.0</maven.min-version>
|
<maven.min-version>3.6.3</maven.min-version>
|
||||||
<maven.compiler.source>21</maven.compiler.source>
|
<maven.compiler.source>21</maven.compiler.source>
|
||||||
<maven.compiler.target>21</maven.compiler.target>
|
<maven.compiler.target>21</maven.compiler.target>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
@@ -93,8 +93,6 @@
|
|||||||
<version>${plugin.deploy.version}</version>
|
<version>${plugin.deploy.version}</version>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<id>deploy</id>
|
|
||||||
<phase>deploy</phase>
|
|
||||||
<goals>
|
<goals>
|
||||||
<goal>deploy</goal>
|
<goal>deploy</goal>
|
||||||
</goals>
|
</goals>
|
||||||
@@ -107,7 +105,6 @@
|
|||||||
<version>${plugin.enforcer.version}</version>
|
<version>${plugin.enforcer.version}</version>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<id>enforce-versions</id>
|
|
||||||
<goals>
|
<goals>
|
||||||
<goal>enforce</goal>
|
<goal>enforce</goal>
|
||||||
</goals>
|
</goals>
|
||||||
@@ -137,16 +134,8 @@
|
|||||||
<version>${plugin.failsafe.version}</version>
|
<version>${plugin.failsafe.version}</version>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<id>integration-test</id>
|
|
||||||
<phase>test</phase>
|
|
||||||
<goals>
|
<goals>
|
||||||
<goal>integration-test</goal>
|
<goal>integration-test</goal>
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
<execution>
|
|
||||||
<id>verify</id>
|
|
||||||
<phase>verify</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>verify</goal>
|
<goal>verify</goal>
|
||||||
</goals>
|
</goals>
|
||||||
</execution>
|
</execution>
|
||||||
@@ -158,26 +147,10 @@
|
|||||||
<version>${plugin.jacoco.version}</version>
|
<version>${plugin.jacoco.version}</version>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<id>default-prepare-agent</id>
|
|
||||||
<goals>
|
<goals>
|
||||||
<goal>prepare-agent</goal>
|
<goal>prepare-agent</goal>
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
<execution>
|
|
||||||
<id>default-prepare-agent-integration</id>
|
|
||||||
<goals>
|
|
||||||
<goal>prepare-agent-integration</goal>
|
<goal>prepare-agent-integration</goal>
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
<execution>
|
|
||||||
<id>default-report</id>
|
|
||||||
<goals>
|
|
||||||
<goal>report</goal>
|
<goal>report</goal>
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
<execution>
|
|
||||||
<id>default-report-integration</id>
|
|
||||||
<goals>
|
|
||||||
<goal>report-integration</goal>
|
<goal>report-integration</goal>
|
||||||
</goals>
|
</goals>
|
||||||
</execution>
|
</execution>
|
||||||
@@ -189,8 +162,6 @@
|
|||||||
<version>${plugin.javadoc.version}</version>
|
<version>${plugin.javadoc.version}</version>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<id>attach-javadocs</id>
|
|
||||||
<phase>install</phase>
|
|
||||||
<goals>
|
<goals>
|
||||||
<goal>jar</goal>
|
<goal>jar</goal>
|
||||||
</goals>
|
</goals>
|
||||||
@@ -221,8 +192,6 @@
|
|||||||
<version>${plugin.source.version}</version>
|
<version>${plugin.source.version}</version>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<id>attach-sources</id>
|
|
||||||
<phase>package</phase>
|
|
||||||
<goals>
|
<goals>
|
||||||
<goal>jar-no-fork</goal>
|
<goal>jar-no-fork</goal>
|
||||||
</goals>
|
</goals>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* XML parsing module for FXML compiler (not implemented yet)
|
* XML parsing module for FXML compiler
|
||||||
*/
|
*/
|
||||||
module com.github.gtache.fxml.compiler.xml {
|
module com.github.gtache.fxml.compiler.xml {
|
||||||
requires transitive com.github.gtache.fxml.compiler.core;
|
requires transitive com.github.gtache.fxml.compiler.core;
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import java.util.Map;
|
|||||||
import java.util.SequencedMap;
|
import java.util.SequencedMap;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
|
|
||||||
class TestDOMFXMLParser {
|
class TestDOMFXMLParser {
|
||||||
|
|
||||||
@@ -76,6 +77,7 @@ class TestDOMFXMLParser {
|
|||||||
List.of(new ParsedObjectImpl(VBox.class.getName(), newLinkedHashMap("fx:id", new ParsedPropertyImpl("fx:id", null, "vbox")), newLinkedHashMap(), List.of()))
|
List.of(new ParsedObjectImpl(VBox.class.getName(), newLinkedHashMap("fx:id", new ParsedPropertyImpl("fx:id", null, "vbox")), newLinkedHashMap(), List.of()))
|
||||||
), List.of());
|
), List.of());
|
||||||
try (final var in = getClass().getResourceAsStream("loadView.fxml")) {
|
try (final var in = getClass().getResourceAsStream("loadView.fxml")) {
|
||||||
|
assertNotNull(in);
|
||||||
final var content = new String(in.readAllBytes(), StandardCharsets.UTF_8);
|
final var content = new String(in.readAllBytes(), StandardCharsets.UTF_8);
|
||||||
final var actual = parser.parse(content);
|
final var actual = parser.parse(content);
|
||||||
assertEquals(expected, actual);
|
assertEquals(expected, actual);
|
||||||
|
|||||||
@@ -1,144 +0,0 @@
|
|||||||
package com.github.gtache.fxml.compiler.parsing.xml;
|
|
||||||
|
|
||||||
import com.github.gtache.fxml.compiler.ControllerFieldInfo;
|
|
||||||
import com.github.gtache.fxml.compiler.GenerationException;
|
|
||||||
import com.github.gtache.fxml.compiler.GenerationRequest;
|
|
||||||
import com.github.gtache.fxml.compiler.Generator;
|
|
||||||
import com.github.gtache.fxml.compiler.compatibility.impl.GenerationCompatibilityImpl;
|
|
||||||
import com.github.gtache.fxml.compiler.impl.*;
|
|
||||||
import com.github.gtache.fxml.compiler.parsing.ParseException;
|
|
||||||
import org.junit.jupiter.params.ParameterizedTest;
|
|
||||||
import org.junit.jupiter.params.provider.Arguments;
|
|
||||||
import org.junit.jupiter.params.provider.MethodSource;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.Paths;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.stream.Stream;
|
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
|
||||||
|
|
||||||
class TestGeneratorImpl {
|
|
||||||
|
|
||||||
private static final Map<String, ControllerFieldInfo> FIELD_INFO_MAP;
|
|
||||||
|
|
||||||
static {
|
|
||||||
FIELD_INFO_MAP = new HashMap<>();
|
|
||||||
FIELD_INFO_MAP.put("button", new ControllerFieldInfoImpl("button", List.of()));
|
|
||||||
FIELD_INFO_MAP.put("checkBox", new ControllerFieldInfoImpl("checkBox", List.of()));
|
|
||||||
FIELD_INFO_MAP.put("colorPicker", new ControllerFieldInfoImpl("colorPicker", List.of()));
|
|
||||||
FIELD_INFO_MAP.put("color", new ControllerFieldInfoImpl("color", List.of()));
|
|
||||||
FIELD_INFO_MAP.put("comboBox", new ControllerFieldInfoImpl("comboBox", List.of()));
|
|
||||||
FIELD_INFO_MAP.put("listView", new ControllerFieldInfoImpl("listView", List.of("javafx.scene.control.Label")));
|
|
||||||
FIELD_INFO_MAP.put("spinner", new ControllerFieldInfoImpl("spinner", List.of("Double")));
|
|
||||||
FIELD_INFO_MAP.put("tableView", new ControllerFieldInfoImpl("tableView", List.of("javafx.scene.control.TextArea")));
|
|
||||||
FIELD_INFO_MAP.put("treeView", new ControllerFieldInfoImpl("treeView", List.of("String")));
|
|
||||||
FIELD_INFO_MAP.put("treeTableView", new ControllerFieldInfoImpl("treeTableView", List.of("javafx.scene.control.TreeItem<String>")));
|
|
||||||
FIELD_INFO_MAP.put("treeTableColumn1", new ControllerFieldInfoImpl("treeTableColumn1", List.of("javafx.scene.control.TreeItem<String>", "String")));
|
|
||||||
FIELD_INFO_MAP.put("treeTableColumn2", new ControllerFieldInfoImpl("treeTableColumn2", List.of("javafx.scene.control.TreeItem<String>", "Integer")));
|
|
||||||
FIELD_INFO_MAP.put("tableColumn1", new ControllerFieldInfoImpl("tableColumn1", List.of("javafx.scene.control.TextArea", "Float")));
|
|
||||||
FIELD_INFO_MAP.put("tableColumn2", new ControllerFieldInfoImpl("tableColumn2", List.of("javafx.scene.control.TextArea", "String")));
|
|
||||||
}
|
|
||||||
|
|
||||||
private final Generator generator;
|
|
||||||
|
|
||||||
TestGeneratorImpl() {
|
|
||||||
this.generator = new GeneratorImpl();
|
|
||||||
}
|
|
||||||
|
|
||||||
@ParameterizedTest
|
|
||||||
@MethodSource("providesGenerationTestCases")
|
|
||||||
void testGenerate(final String file, final ControllerInjectionTypes controller, final ControllerFieldInjectionTypes field, final ControllerMethodsInjectionType method, final ResourceBundleInjectionTypes bundle) throws Exception {
|
|
||||||
final var request = getRequest(file, controller, field, method, bundle);
|
|
||||||
final var path = Paths.get(getPath(file, controller, field, method, bundle));
|
|
||||||
try (final var in = getClass().getResourceAsStream("/com/github/gtache/fxml/compiler/parsing/xml/" + path)) {
|
|
||||||
assertNotNull(in);
|
|
||||||
final var expected = new String(in.readAllBytes(), StandardCharsets.UTF_8);
|
|
||||||
final var actual = generator.generate(request);
|
|
||||||
assertEquals(expected, actual);
|
|
||||||
} catch (final IOException | GenerationException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(final String[] args) throws GenerationException, IOException, ParseException {
|
|
||||||
final var generator = new GeneratorImpl();
|
|
||||||
final var files = List.of("Controls", "Includes");
|
|
||||||
for (final var file : files) {
|
|
||||||
for (final var controller : ControllerInjectionTypes.values()) {
|
|
||||||
for (final var field : ControllerFieldInjectionTypes.values()) {
|
|
||||||
for (final var method : ControllerMethodsInjectionType.values()) {
|
|
||||||
for (final var bundle : ResourceBundleInjectionTypes.values()) {
|
|
||||||
final var request = getRequest(file, controller, field, method, bundle);
|
|
||||||
final var content = generator.generate(request);
|
|
||||||
final var path = Paths.get(getPath(file, controller, field, method, bundle));
|
|
||||||
Files.writeString(path, content);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String getPath(final String file, final ControllerInjectionTypes controller, final ControllerFieldInjectionTypes field, final ControllerMethodsInjectionType method, final ResourceBundleInjectionTypes bundle) {
|
|
||||||
return "expected-" + file.toLowerCase() + "-" + controller.name().toLowerCase() + "-" + field.name().toLowerCase() + "-" + method.name().toLowerCase() + "-" + bundle.name().replace("_", "").toLowerCase() + ".txt";
|
|
||||||
}
|
|
||||||
|
|
||||||
private static GenerationRequest getRequest(final String file, final ControllerInjectionTypes controller, final ControllerFieldInjectionTypes field,
|
|
||||||
final ControllerMethodsInjectionType method, final ResourceBundleInjectionTypes resource) throws IOException, ParseException {
|
|
||||||
final var controllerClass = "com.github.gtache.fxml.compiler.parsing.xml." + file + "Controller";
|
|
||||||
final var controlsControllerInfo = new ControllerInfoImpl(controllerClass, Map.of("keyPressed", false, "mouseClicked", false),
|
|
||||||
FIELD_INFO_MAP, true);
|
|
||||||
final var includesControllerInfo = new ControllerInfoImpl(controllerClass, Map.of(), Map.of(), true);
|
|
||||||
final var controllerInfo = file.equals("Controls") ? controlsControllerInfo : includesControllerInfo;
|
|
||||||
final var resourceBundlePath = "com.github.gtache.fxml.compiler.parsing.xml." + file + "Bundle";
|
|
||||||
final var viewPath = "/com/github/gtache/fxml/compiler/parsing/xml/" + file.toLowerCase() + "View.fxml";
|
|
||||||
final var controlsSourceInfo = new SourceInfoImpl("com.github.gtache.fxml.compiler.parsing.xml.ControlsController",
|
|
||||||
controllerClass, Paths.get(viewPath), List.of(), Map.of(), true);
|
|
||||||
final var includesSourceInfo = new SourceInfoImpl("com.github.gtache.fxml.compiler.parsing.xml.IncludesController",
|
|
||||||
controllerClass, Paths.get(viewPath), List.of(controlsSourceInfo), Map.of("controlsView.fxml", controlsSourceInfo), true);
|
|
||||||
final var sourceInfo = file.equals("Controls") ? controlsSourceInfo : includesSourceInfo;
|
|
||||||
final var parser = new DOMFXMLParser();
|
|
||||||
try (final var in = TestGeneratorImpl.class.getResourceAsStream(viewPath)) {
|
|
||||||
assertNotNull(in);
|
|
||||||
final var content = new String(in.readAllBytes(), StandardCharsets.UTF_8);
|
|
||||||
final var root = parser.parse(content);
|
|
||||||
return new GenerationRequestImpl(
|
|
||||||
new GenerationParametersImpl(new GenerationCompatibilityImpl(21), false,
|
|
||||||
Map.of(controllerInfo.className(), resourceBundlePath),
|
|
||||||
controller,
|
|
||||||
field,
|
|
||||||
method,
|
|
||||||
resource
|
|
||||||
),
|
|
||||||
controllerInfo,
|
|
||||||
sourceInfo,
|
|
||||||
root,
|
|
||||||
"com.github.gtache.fxml.compiler.parsing.xml." + file + "View"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Stream<Arguments> providesGenerationTestCases() {
|
|
||||||
final var files = List.of("Controls", "Includes");
|
|
||||||
final var list = new ArrayList<Arguments>();
|
|
||||||
for (final var file : files) {
|
|
||||||
for (final var controller : ControllerInjectionTypes.values()) {
|
|
||||||
for (final var field : ControllerFieldInjectionTypes.values()) {
|
|
||||||
for (final var method : ControllerMethodsInjectionType.values()) {
|
|
||||||
for (final var bundle : ResourceBundleInjectionTypes.values()) {
|
|
||||||
list.add(Arguments.of(file, controller, field, method, bundle));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return list.stream();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
include.label=Label
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
media.volume.label=Volume
|
|
||||||
@@ -1,239 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
|
|
||||||
|
|
||||||
<?import javafx.collections.FXCollections?>
|
|
||||||
<?import javafx.geometry.Insets?>
|
|
||||||
<?import javafx.geometry.Point3D?>
|
|
||||||
<?import javafx.scene.control.*?>
|
|
||||||
<?import javafx.scene.Cursor?>
|
|
||||||
<?import javafx.scene.effect.Bloom?>
|
|
||||||
<?import javafx.scene.image.Image?>
|
|
||||||
<?import javafx.scene.image.ImageView?>
|
|
||||||
<?import javafx.scene.layout.*?>
|
|
||||||
<?import javafx.scene.media.MediaView?>
|
|
||||||
<?import javafx.scene.paint.Color?>
|
|
||||||
<?import javafx.scene.text.Font?>
|
|
||||||
<?import javafx.scene.web.HTMLEditor?>
|
|
||||||
<?import javafx.scene.web.WebView?>
|
|
||||||
<?import java.lang.String?>
|
|
||||||
<GridPane fx:id="gridPane" onInputMethodTextChanged="#inputMethodTextChanged" onKeyPressed="#keyPressed"
|
|
||||||
onKeyReleased="#keyReleased"
|
|
||||||
onKeyTyped="#keyTyped" xmlns="http://javafx.com/javafx/22" xmlns:fx="http://javafx.com/fxml/1"
|
|
||||||
fx:controller="com.github.gtache.fxml.compiler.parsing.xml.ControlsController">
|
|
||||||
<fx:define>
|
|
||||||
<FXCollections fx:id="list" fx:factory="observableArrayList">
|
|
||||||
<String>text1</String>
|
|
||||||
<String fx:value="text2"/>
|
|
||||||
<String value="text3"/>
|
|
||||||
</FXCollections>
|
|
||||||
<FXCollections fx:id="emptyMap" fx:factory="emptyObservableMap"/>
|
|
||||||
</fx:define>
|
|
||||||
<rowConstraints>
|
|
||||||
<RowConstraints/>
|
|
||||||
<RowConstraints/>
|
|
||||||
<RowConstraints/>
|
|
||||||
<RowConstraints/>
|
|
||||||
<RowConstraints/>
|
|
||||||
<RowConstraints/>
|
|
||||||
<RowConstraints/>
|
|
||||||
<RowConstraints/>
|
|
||||||
<RowConstraints/>
|
|
||||||
<RowConstraints/>
|
|
||||||
<RowConstraints/>
|
|
||||||
<RowConstraints/>
|
|
||||||
<RowConstraints/>
|
|
||||||
<RowConstraints/>
|
|
||||||
<RowConstraints/>
|
|
||||||
<RowConstraints/>
|
|
||||||
<RowConstraints/>
|
|
||||||
<RowConstraints/>
|
|
||||||
</rowConstraints>
|
|
||||||
<columnConstraints>
|
|
||||||
<ColumnConstraints/>
|
|
||||||
<ColumnConstraints/>
|
|
||||||
<ColumnConstraints minWidth="10.0" prefWidth="100.0"/>
|
|
||||||
</columnConstraints>
|
|
||||||
<children>
|
|
||||||
<fx:define>
|
|
||||||
<String fx:id="str">text</String>
|
|
||||||
</fx:define>
|
|
||||||
<Button fx:id="button">
|
|
||||||
<mnemonicParsing>false</mnemonicParsing>
|
|
||||||
Button
|
|
||||||
</Button>
|
|
||||||
<CheckBox fx:id="checkBox">
|
|
||||||
<indeterminate>true</indeterminate>
|
|
||||||
<mnemonicParsing>false</mnemonicParsing>
|
|
||||||
CheckBox
|
|
||||||
<GridPane.columnIndex>1</GridPane.columnIndex>
|
|
||||||
</CheckBox>
|
|
||||||
<ChoiceBox fx:id="choiceBox" cacheShape="false" centerShape="false" disable="true" focusTraversable="false"
|
|
||||||
prefWidth="150.0"
|
|
||||||
scaleShape="false" visible="false" GridPane.rowIndex="1" accessibleText="$str"/>
|
|
||||||
<ColorPicker fx:id="colorPicker" nodeOrientation="LEFT_TO_RIGHT" opacity="0.5" GridPane.columnIndex="1"
|
|
||||||
GridPane.rowIndex="1">
|
|
||||||
<value>
|
|
||||||
<Color fx:id="color" red="0.7894737124443054" green="0.08771929889917374" blue="0.08771929889917374"/>
|
|
||||||
</value>
|
|
||||||
<opaqueInsets>
|
|
||||||
<Insets bottom="3.0" left="2.0" right="4.0" top="5.0"/>
|
|
||||||
</opaqueInsets>
|
|
||||||
</ColorPicker>
|
|
||||||
<ComboBox fx:id="comboBox" editable="true" prefWidth="150.0" promptText="Text" visibleRowCount="5"
|
|
||||||
GridPane.rowIndex="2">
|
|
||||||
<cursor>
|
|
||||||
<Cursor fx:constant="CLOSED_HAND"/>
|
|
||||||
</cursor>
|
|
||||||
<effect>
|
|
||||||
<Bloom/>
|
|
||||||
</effect>
|
|
||||||
</ComboBox>
|
|
||||||
<DatePicker fx:id="datePicker" showWeekNumbers="true" style="-fx-background-color: #ffffff;"
|
|
||||||
GridPane.columnIndex="1"
|
|
||||||
GridPane.rowIndex="2"/>
|
|
||||||
<HTMLEditor fx:id="htmlEditor"
|
|
||||||
htmlText="<html><head></head><body contenteditable="true"></body></html>"
|
|
||||||
prefHeight="200.0" prefWidth="506.0" styleClass="clazz" stylesheets="@style.css"
|
|
||||||
GridPane.rowIndex="3"/>
|
|
||||||
<Hyperlink fx:id="hyperlink" text="Hyperlink" GridPane.columnIndex="1" GridPane.rowIndex="3"/>
|
|
||||||
<ImageView fx:id="imageView" fitHeight="150.0" fitWidth="200.0" pickOnBounds="true" preserveRatio="true"
|
|
||||||
GridPane.rowIndex="4">
|
|
||||||
<Image url="https://github.com/gtache" backgroundLoading="true" fx:id="image" preserveRatio="true"
|
|
||||||
requestedWidth="200">
|
|
||||||
<smooth>true</smooth>
|
|
||||||
<requestedHeight>100</requestedHeight>
|
|
||||||
</Image>
|
|
||||||
</ImageView>
|
|
||||||
<ImageView>
|
|
||||||
<image>
|
|
||||||
<Image url="@image.png"/>
|
|
||||||
</image>
|
|
||||||
</ImageView>
|
|
||||||
<fx:define>
|
|
||||||
<Image fx:id="definedImage" url="/url"/>
|
|
||||||
</fx:define>
|
|
||||||
<ImageView>
|
|
||||||
<fx:reference source="definedImage"/>
|
|
||||||
</ImageView>
|
|
||||||
<Label fx:id="label" accessibleHelp="TTTTT" blendMode="ADD" cache="true"
|
|
||||||
cacheHint="QUALITY"
|
|
||||||
depthTest="ENABLE" mnemonicParsing="true" mouseTransparent="true" text="%include.label"
|
|
||||||
GridPane.columnIndex="1"
|
|
||||||
GridPane.rowIndex="4">
|
|
||||||
<accessibleText>
|
|
||||||
<fx:copy source="str"/>
|
|
||||||
</accessibleText>
|
|
||||||
</Label>
|
|
||||||
<ListView fx:id="listView" fixedCellSize="20.0" nodeOrientation="RIGHT_TO_LEFT" orientation="HORIZONTAL"
|
|
||||||
prefHeight="200.0"
|
|
||||||
prefWidth="200.0" GridPane.rowIndex="5"/>
|
|
||||||
<MediaView fx:id="mediaView" fitHeight="200.0" fitWidth="200.0" GridPane.columnIndex="1" GridPane.columnSpan="2"
|
|
||||||
GridPane.rowIndex="5" GridPane.rowSpan="2"/>
|
|
||||||
<MenuBar fx:id="menuBar" GridPane.halignment="RIGHT" GridPane.hgrow="ALWAYS" GridPane.rowIndex="7"
|
|
||||||
GridPane.valignment="BASELINE" GridPane.vgrow="SOMETIMES">
|
|
||||||
<Menu fx:id="menu1" mnemonicParsing="false">
|
|
||||||
<text>File</text>
|
|
||||||
<MenuItem fx:id="menuItem1" mnemonicParsing="false" text="Close"/>
|
|
||||||
<MenuItem fx:id="menuItem2" mnemonicParsing="false" text="Open"/>
|
|
||||||
</Menu>
|
|
||||||
<Menu mnemonicParsing="false" text="Edit">
|
|
||||||
<items>
|
|
||||||
<MenuItem mnemonicParsing="false" text="Delete"/>
|
|
||||||
</items>
|
|
||||||
</Menu>
|
|
||||||
<Menu mnemonicParsing="false" text="Help">
|
|
||||||
<items>
|
|
||||||
<MenuItem mnemonicParsing="false" text="About"/>
|
|
||||||
</items>
|
|
||||||
</Menu>
|
|
||||||
</MenuBar>
|
|
||||||
<MenuButton fx:id="menuButton" mnemonicParsing="false" text="MenuButton" GridPane.columnIndex="1"
|
|
||||||
GridPane.rowIndex="7">
|
|
||||||
<items>
|
|
||||||
<MenuItem mnemonicParsing="false" text="Action 1"/>
|
|
||||||
<MenuItem mnemonicParsing="false" text="Action 2"/>
|
|
||||||
</items>
|
|
||||||
<GridPane.margin>
|
|
||||||
<Insets bottom="3.0" left="2.0" right="4.0">
|
|
||||||
<top>5.0</top>
|
|
||||||
</Insets>
|
|
||||||
</GridPane.margin>
|
|
||||||
</MenuButton>
|
|
||||||
<Pagination fx:id="pagination" prefHeight="200.0" prefWidth="200.0" GridPane.rowIndex="8">
|
|
||||||
<padding>
|
|
||||||
<Insets bottom="3.0" left="2.0" right="4.0" top="5.0"/>
|
|
||||||
</padding>
|
|
||||||
</Pagination>
|
|
||||||
<PasswordField fx:id="passwordField" maxHeight="Infinity" maxWidth="5.0" minHeight="-Infinity" minWidth="1.0"
|
|
||||||
prefColumnCount="7"
|
|
||||||
prefHeight="4.0" prefWidth="3.0" GridPane.columnIndex="1" GridPane.rowIndex="8"/>
|
|
||||||
<ProgressBar fx:id="progressBar" layoutX="10.0" layoutY="20.0" prefWidth="200.0" progress="0.0"
|
|
||||||
GridPane.rowIndex="9"/>
|
|
||||||
<ProgressIndicator fx:id="progressIndicator" progress="0.0" rotate="2.0" GridPane.columnIndex="1"
|
|
||||||
GridPane.rowIndex="9">
|
|
||||||
<rotationAxis>
|
|
||||||
<Point3D x="4.0" y="5.0" z="6.0"/>
|
|
||||||
</rotationAxis>
|
|
||||||
</ProgressIndicator>
|
|
||||||
<RadioButton fx:id="radioButton" mnemonicParsing="false" scaleX="7.0" scaleY="2.0" scaleZ="3.0"
|
|
||||||
text="RadioButton" translateX="4.0"
|
|
||||||
translateY="5.0" translateZ="6.0" GridPane.rowIndex="10"/>
|
|
||||||
<ScrollBar fx:id="scrollBarH" GridPane.columnIndex="1" GridPane.rowIndex="10"/>
|
|
||||||
<ScrollBar fx:id="scrollBarV" orientation="VERTICAL" GridPane.rowIndex="11"/>
|
|
||||||
<Separator fx:id="separatorH" onDragDetected="#dragDetected" onDragDone="#dragDone" onDragDropped="#dragDropped"
|
|
||||||
onDragEntered="#dragEntered" onDragExited="#dragExited" onDragOver="#dragOver"
|
|
||||||
onMouseDragEntered="#mouseDragEntered" onMouseDragExited="#mouseDragExited"
|
|
||||||
onMouseDragOver="#mouseDragOver" onMouseDragReleased="#mouseDragReleased" prefWidth="200.0"
|
|
||||||
GridPane.columnIndex="1" GridPane.rowIndex="11"/>
|
|
||||||
<Separator fx:id="separatorV" orientation="VERTICAL" prefHeight="200.0" GridPane.rowIndex="12"/>
|
|
||||||
<Slider fx:id="sliderH" onContextMenuRequested="#contextMenuRequested" onMouseClicked="#mouseClicked"
|
|
||||||
onMouseDragged="#mouseDragged" onMouseEntered="#mouseEntered" onMouseExited="#mouseExited"
|
|
||||||
onMouseMoved="#mouseMoved" onMousePressed="#mousePressed" onMouseReleased="#mouseReleased"
|
|
||||||
onScroll="#onScroll" onScrollFinished="#onScrollFinished" onScrollStarted="#onScrollStarted"
|
|
||||||
GridPane.columnIndex="1" GridPane.rowIndex="12"/>
|
|
||||||
<Slider fx:id="sliderV" onZoom="#onZoom" onZoomFinished="#onZoomFinished" onZoomStarted="#onZoomStarted"
|
|
||||||
orientation="VERTICAL"
|
|
||||||
GridPane.rowIndex="13"/>
|
|
||||||
<Spinner fx:id="spinner" GridPane.columnIndex="1" GridPane.rowIndex="13"/>
|
|
||||||
<SplitMenuButton fx:id="splitMenuButton" mnemonicParsing="false" text="SplitMenuButton" GridPane.rowIndex="14">
|
|
||||||
<items>
|
|
||||||
<MenuItem fx:id="item1" mnemonicParsing="false" text="Action 1"/>
|
|
||||||
<MenuItem fx:id="item2" mnemonicParsing="false" text="Action 2"/>
|
|
||||||
</items>
|
|
||||||
</SplitMenuButton>
|
|
||||||
<TableView fx:id="tableView" prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="1"
|
|
||||||
GridPane.rowIndex="14">
|
|
||||||
<columns>
|
|
||||||
<TableColumn fx:id="tableColumn1" prefWidth="75.0" text="C1"/>
|
|
||||||
<TableColumn fx:id="tableColumn2" prefWidth="75.0" text="C2"/>
|
|
||||||
</columns>
|
|
||||||
</TableView>
|
|
||||||
<TextArea fx:id="textArea" prefHeight="200.0" prefWidth="200.0" GridPane.rowIndex="15">
|
|
||||||
<font>
|
|
||||||
<Font fx:id="font" name="Arial" size="12.0"/>
|
|
||||||
</font>
|
|
||||||
</TextArea>
|
|
||||||
<TextField fx:id="textField" GridPane.columnIndex="1" GridPane.rowIndex="15"/>
|
|
||||||
<ToggleButton mnemonicParsing="false" onAction="#onAction" onRotate="#onRotate"
|
|
||||||
onRotationFinished="#onRotationFinished" onRotationStarted="#onRotationStarted"
|
|
||||||
text="ToggleButton" GridPane.rowIndex="16"/>
|
|
||||||
<TreeTableView fx:id="treeTableView" prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="1"
|
|
||||||
GridPane.rowIndex="16">
|
|
||||||
<columns>
|
|
||||||
<TreeTableColumn fx:id="treeTableColumn1" onEditCancel="#onEditCancel" onEditCommit="#onEditCommit"
|
|
||||||
onEditStart="#onEditStart"
|
|
||||||
prefWidth="75.0" text="C1"/>
|
|
||||||
<TreeTableColumn fx:id="treeTableColumn2" prefWidth="75.0" sortType="DESCENDING" text="C2"/>
|
|
||||||
</columns>
|
|
||||||
</TreeTableView>
|
|
||||||
<TreeView fx:id="treeView" onSwipeDown="#onSwipeDown" onSwipeLeft="#onSwipeLeft" onSwipeRight="#onSwipeRight"
|
|
||||||
onSwipeUp="#onSwipeUp" prefHeight="200.0" prefWidth="200.0" GridPane.rowIndex="17"/>
|
|
||||||
<WebView fx:id="webView" onTouchMoved="#onTouchMoved" onTouchPressed="#onTouchPressed"
|
|
||||||
onTouchReleased="#onTouchReleased"
|
|
||||||
onTouchStationary="#onTouchStationary" prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="1"
|
|
||||||
location="https://github.com/gtache" confirmHandler="$controller.confirmHandler"
|
|
||||||
createPopupHandler="#createPopupHandler"
|
|
||||||
onAlert="$controller.onAlert" onResized="#onResized"
|
|
||||||
GridPane.rowIndex="17"/>
|
|
||||||
</children>
|
|
||||||
</GridPane>
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
|
|
||||||
<?import javafx.scene.layout.HBox?>
|
|
||||||
<HBox xmlns="http://javafx.com/javafx/22" xmlns:fx="http://javafx.com/fxml/1"
|
|
||||||
fx:controller="com.github.gtache.fxml.compiler.parsing.xml.IncludesController">
|
|
||||||
<fx:include source="include1.fxml"/>
|
|
||||||
<fx:include source="include2.fxml"/>
|
|
||||||
<fx:include source="include3.fxml"/>
|
|
||||||
<fx:include resources="com/github/gtache/fxml/compiler/parsing/xml/includes/IncludedBundle" source="include1.fxml"/>
|
|
||||||
</HBox>
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
|
|
||||||
<?import javafx.scene.layout.HBox?>
|
|
||||||
<HBox xmlns="http://javafx.com/javafx/22" xmlns:fx="http://javafx.com/fxml/1"
|
|
||||||
fx:controller="com.github.gtache.fxml.compiler.parsing.xml.IncludesController">
|
|
||||||
<fx:include source="include21.fxml"/>
|
|
||||||
</HBox>
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
|
|
||||||
<?import javafx.scene.control.Label?>
|
|
||||||
<?import javafx.scene.layout.HBox?>
|
|
||||||
<HBox xmlns="http://javafx.com/javafx/22" xmlns:fx="http://javafx.com/fxml/1"
|
|
||||||
fx:controller="com.github.gtache.fxml.compiler.parsing.xml.IncludesController">
|
|
||||||
<Label text="%text"/>
|
|
||||||
</HBox>
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
|
|
||||||
<?import javafx.scene.layout.HBox?>
|
|
||||||
<HBox xmlns="http://javafx.com/javafx/22" xmlns:fx="http://javafx.com/fxml/1"
|
|
||||||
fx:controller="com.github.gtache.fxml.compiler.parsing.xml.IncludesController">
|
|
||||||
<fx:include source="include1.fxml"/>
|
|
||||||
<fx:include source="include2.fxml"/>
|
|
||||||
<fx:include source="include3.fxml"/>
|
|
||||||
<fx:include resources="com/github/gtache/fxml/compiler/parsing/xml/includes/IncludedBundle" source="include1.fxml"/>
|
|
||||||
</HBox>
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
|
|
||||||
<?import javafx.scene.layout.HBox?>
|
|
||||||
<HBox xmlns="http://javafx.com/javafx/22" xmlns:fx="http://javafx.com/fxml/1"
|
|
||||||
fx:controller="com.github.gtache.fxml.compiler.parsing.xml.IncludesController">
|
|
||||||
<fx:include source="include1.fxml"/>
|
|
||||||
<fx:include source="include2.fxml"/>
|
|
||||||
<fx:include source="include3.fxml"/>
|
|
||||||
<fx:include resources="com/github/gtache/fxml/compiler/parsing/xml/includes/IncludedBundle" source="include1.fxml"/>
|
|
||||||
</HBox>
|
|
||||||
@@ -1,141 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
|
|
||||||
<?import javafx.geometry.Insets?>
|
|
||||||
<?import javafx.scene.control.*?>
|
|
||||||
<?import javafx.scene.Group?>
|
|
||||||
<?import javafx.scene.layout.*?>
|
|
||||||
<?import javafx.scene.text.TextFlow?>
|
|
||||||
<BorderPane xmlns="http://javafx.com/javafx/22" xmlns:fx="http://javafx.com/fxml/1"
|
|
||||||
fx:controller="com.github.gtache.fxml.compiler.parsing.xml.IncludesController">
|
|
||||||
<bottom>
|
|
||||||
<VBox BorderPane.alignment="CENTER">
|
|
||||||
<children>
|
|
||||||
<HBox alignment="CENTER" spacing="10.0">
|
|
||||||
<children>
|
|
||||||
<Slider fx:id="playSlider" HBox.hgrow="ALWAYS">
|
|
||||||
<padding>
|
|
||||||
<Insets left="10.0"/>
|
|
||||||
</padding>
|
|
||||||
</Slider>
|
|
||||||
<Label fx:id="playLabel" text="Label">
|
|
||||||
<padding>
|
|
||||||
<Insets right="10.0"/>
|
|
||||||
</padding>
|
|
||||||
</Label>
|
|
||||||
</children>
|
|
||||||
<padding>
|
|
||||||
<Insets top="10.0"/>
|
|
||||||
</padding>
|
|
||||||
</HBox>
|
|
||||||
<HBox alignment="CENTER" spacing="10.0">
|
|
||||||
<children>
|
|
||||||
<Button fx:id="playButton" mnemonicParsing="false" onAction="#playPressed">
|
|
||||||
<HBox.margin>
|
|
||||||
<Insets right="20.0"/>
|
|
||||||
</HBox.margin>
|
|
||||||
</Button>
|
|
||||||
<Label text="%media.volume.label"/>
|
|
||||||
<Slider fx:id="volumeSlider" value="100"/>
|
|
||||||
<Label fx:id="volumeValueLabel" text="Label"/>
|
|
||||||
<fx:include fx:id="controls" source="controlsView.fxml"
|
|
||||||
resources="com/github/gtache/fxml/compiler/parsing/xml/ControlsBundle"/>
|
|
||||||
</children>
|
|
||||||
<padding>
|
|
||||||
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/>
|
|
||||||
</padding>
|
|
||||||
</HBox>
|
|
||||||
</children>
|
|
||||||
</VBox>
|
|
||||||
</bottom>
|
|
||||||
<center>
|
|
||||||
<VBox fx:id="vbox">
|
|
||||||
<children>
|
|
||||||
<ToolBar fx:id="toolBar">
|
|
||||||
<items>
|
|
||||||
<TitledPane fx:id="titledPane">
|
|
||||||
<content>
|
|
||||||
<TilePane fx:id="tilePane">
|
|
||||||
<children>
|
|
||||||
<TextFlow fx:id="textFlow">
|
|
||||||
<children>
|
|
||||||
<TabPane fx:id="tabPane">
|
|
||||||
<tabs>
|
|
||||||
<Tab fx:id="tab">
|
|
||||||
<content>
|
|
||||||
<StackPane fx:id="stackPane">
|
|
||||||
<children>
|
|
||||||
<SplitPane fx:id="splitPane">
|
|
||||||
<items>
|
|
||||||
<ScrollPane fx:id="scrollPane">
|
|
||||||
<content>
|
|
||||||
<Pane fx:id="pane">
|
|
||||||
<children>
|
|
||||||
<HBox fx:id="hbox">
|
|
||||||
<children>
|
|
||||||
<Group fx:id="group">
|
|
||||||
<children>
|
|
||||||
<GridPane
|
|
||||||
fx:id="gridPane">
|
|
||||||
<columnConstraints>
|
|
||||||
<ColumnConstraints
|
|
||||||
fx:id="columnConstraints"
|
|
||||||
hgrow="SOMETIMES"
|
|
||||||
minWidth="10.0"/>
|
|
||||||
</columnConstraints>
|
|
||||||
<rowConstraints>
|
|
||||||
<RowConstraints
|
|
||||||
minHeight="10.0"
|
|
||||||
vgrow="SOMETIMES"/>
|
|
||||||
</rowConstraints>
|
|
||||||
<children>
|
|
||||||
<FlowPane
|
|
||||||
fx:id="flowPane">
|
|
||||||
<children>
|
|
||||||
<DialogPane
|
|
||||||
fx:id="dialogPane">
|
|
||||||
<content>
|
|
||||||
<ButtonBar
|
|
||||||
fx:id="buttonBar">
|
|
||||||
<buttons>
|
|
||||||
<AnchorPane
|
|
||||||
fx:id="anchorPane">
|
|
||||||
<children>
|
|
||||||
<Label managed="false"/>
|
|
||||||
</children>
|
|
||||||
</AnchorPane>
|
|
||||||
</buttons>
|
|
||||||
</ButtonBar>
|
|
||||||
</content>
|
|
||||||
</DialogPane>
|
|
||||||
</children>
|
|
||||||
</FlowPane>
|
|
||||||
</children>
|
|
||||||
</GridPane>
|
|
||||||
</children>
|
|
||||||
</Group>
|
|
||||||
</children>
|
|
||||||
</HBox>
|
|
||||||
</children>
|
|
||||||
</Pane>
|
|
||||||
</content>
|
|
||||||
</ScrollPane>
|
|
||||||
</items>
|
|
||||||
</SplitPane>
|
|
||||||
</children>
|
|
||||||
</StackPane>
|
|
||||||
</content>
|
|
||||||
</Tab>
|
|
||||||
</tabs>
|
|
||||||
</TabPane>
|
|
||||||
</children>
|
|
||||||
</TextFlow>
|
|
||||||
</children>
|
|
||||||
</TilePane>
|
|
||||||
</content>
|
|
||||||
</TitledPane>
|
|
||||||
</items>
|
|
||||||
</ToolBar>
|
|
||||||
</children>
|
|
||||||
</VBox>
|
|
||||||
</center>
|
|
||||||
</BorderPane>
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
.clazz {
|
|
||||||
-fx-font-weight: bold;
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user