Adds maven wrapper ; rework internal a bit ; Adds all tests for core
This commit is contained in:
@@ -1,25 +0,0 @@
|
||||
package com.github.gtache.fxml.compiler.impl;
|
||||
|
||||
import com.github.gtache.fxml.compiler.InjectionType;
|
||||
|
||||
/**
|
||||
* Base field {@link InjectionType}s
|
||||
*/
|
||||
public enum ControllerFieldInjectionTypes implements InjectionType {
|
||||
/**
|
||||
* Inject using variable assignment
|
||||
*/
|
||||
ASSIGN,
|
||||
/**
|
||||
* Inject using a factory
|
||||
*/
|
||||
FACTORY,
|
||||
/**
|
||||
* Inject using reflection
|
||||
*/
|
||||
REFLECTION,
|
||||
/**
|
||||
* Inject using setters
|
||||
*/
|
||||
SETTERS
|
||||
}
|
||||
@@ -18,6 +18,14 @@ public record ControllerInfoImpl(String className, Map<String, Boolean> handlerH
|
||||
Map<String, ControllerFieldInfo> fieldInfo,
|
||||
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 {
|
||||
Objects.requireNonNull(className);
|
||||
handlerHasArgument = Map.copyOf(handlerHasArgument);
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
package com.github.gtache.fxml.compiler.impl;
|
||||
|
||||
import com.github.gtache.fxml.compiler.InjectionType;
|
||||
|
||||
/**
|
||||
* Base controller {@link InjectionType}s
|
||||
*/
|
||||
public enum ControllerInjectionTypes implements InjectionType {
|
||||
/**
|
||||
* Inject the controller instance
|
||||
*/
|
||||
INSTANCE,
|
||||
/**
|
||||
* Inject a controller factory
|
||||
*/
|
||||
FACTORY
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
package com.github.gtache.fxml.compiler.impl;
|
||||
|
||||
import com.github.gtache.fxml.compiler.InjectionType;
|
||||
|
||||
/**
|
||||
* Base methods {@link InjectionType}s
|
||||
*/
|
||||
public enum ControllerMethodsInjectionType implements InjectionType {
|
||||
/**
|
||||
* Inject using visible methods
|
||||
*/
|
||||
REFERENCE,
|
||||
/**
|
||||
* Inject using reflection
|
||||
*/
|
||||
REFLECTION,
|
||||
}
|
||||
@@ -1,7 +1,10 @@
|
||||
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.InjectionType;
|
||||
import com.github.gtache.fxml.compiler.ResourceBundleInjectionType;
|
||||
import com.github.gtache.fxml.compiler.compatibility.GenerationCompatibility;
|
||||
|
||||
import java.util.Map;
|
||||
@@ -22,11 +25,23 @@ import static java.util.Objects.requireNonNull;
|
||||
*/
|
||||
public record GenerationParametersImpl(GenerationCompatibility compatibility, boolean useImageInputStreamConstructor,
|
||||
Map<String, String> bundleMap,
|
||||
InjectionType controllerInjectionType,
|
||||
InjectionType fieldInjectionType,
|
||||
InjectionType methodInjectionType,
|
||||
InjectionType resourceInjectionType) implements GenerationParameters {
|
||||
ControllerInjectionType controllerInjectionType,
|
||||
ControllerFieldInjectionType fieldInjectionType,
|
||||
ControllerMethodsInjectionType methodInjectionType,
|
||||
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 {
|
||||
requireNonNull(compatibility);
|
||||
bundleMap = Map.copyOf(bundleMap);
|
||||
|
||||
@@ -20,6 +20,15 @@ import java.util.Objects;
|
||||
public record GenerationRequestImpl(GenerationParameters parameters, ControllerInfo controllerInfo,
|
||||
SourceInfo sourceInfo, ParsedObject rootObject,
|
||||
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 {
|
||||
Objects.requireNonNull(parameters);
|
||||
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.HelperProvider;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.function.Function;
|
||||
|
||||
//TODO handle binding (${})
|
||||
|
||||
/**
|
||||
@@ -13,10 +16,28 @@ import com.github.gtache.fxml.compiler.impl.internal.HelperProvider;
|
||||
*/
|
||||
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
|
||||
public String generate(final GenerationRequest request) throws GenerationException {
|
||||
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 pkgName = className.substring(0, className.lastIndexOf('.'));
|
||||
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) {
|
||||
final var sb = progress.stringBuilder();
|
||||
sb.append(" /**\n");
|
||||
sb.append(" * Returns the controller if available\n");
|
||||
sb.append(" * @return The controller\n");
|
||||
sb.append(" * @throws IllegalStateException If the view is not loaded\n");
|
||||
sb.append(" */\n");
|
||||
sb.append(" public ").append(controllerInjectionClass).append(" controller() {\n");
|
||||
sb.append(" if (loaded) {\n");
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
package com.github.gtache.fxml.compiler.impl;
|
||||
|
||||
import com.github.gtache.fxml.compiler.InjectionType;
|
||||
|
||||
/**
|
||||
* Base {@link InjectionType}s for resource bundles
|
||||
*/
|
||||
public enum ResourceBundleInjectionTypes implements InjectionType {
|
||||
/**
|
||||
* Resource bundle is injected in the constructor
|
||||
*/
|
||||
CONSTRUCTOR,
|
||||
/**
|
||||
* Resource bundle is injected as a function in the constructor
|
||||
*/
|
||||
CONSTRUCTOR_FUNCTION,
|
||||
/**
|
||||
* Resource bundle name is injected in the constructor
|
||||
*/
|
||||
CONSTRUCTOR_NAME,
|
||||
/**
|
||||
* Resource bundle is loaded using getBundle
|
||||
*/
|
||||
GET_BUNDLE,
|
||||
/**
|
||||
* Resource bundle is retrieved from controller using getter
|
||||
*/
|
||||
GETTER
|
||||
}
|
||||
@@ -22,6 +22,16 @@ public record SourceInfoImpl(String generatedClassName, String controllerClassNa
|
||||
Map<String, SourceInfo> sourceToSourceInfo,
|
||||
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 {
|
||||
Objects.requireNonNull(generatedClassName);
|
||||
Objects.requireNonNull(controllerClassName);
|
||||
|
||||
@@ -9,7 +9,6 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
@@ -17,10 +16,8 @@ import java.util.Set;
|
||||
*/
|
||||
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
|
||||
* @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 valueFormatter = helperProvider.getValueFormatter();
|
||||
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());
|
||||
if (p == null) {
|
||||
final var c = parsedObject.properties().entrySet().stream().filter(e ->
|
||||
e.getKey().name().equals(entry.getKey())).findFirst().orElse(null);
|
||||
if (c == null) {
|
||||
args.add(valueFormatter.toString(entry.getValue().defaultValue(), type));
|
||||
args.add(ValueFormatter.toString(parameter.defaultValue(), type));
|
||||
} else {
|
||||
throw new GenerationException("Constructor using complex property not supported yet");
|
||||
}
|
||||
} else {
|
||||
args.add(valueFormatter.toString(p.value(), type));
|
||||
args.add(ValueFormatter.toString(p.value(), type));
|
||||
}
|
||||
}
|
||||
return args;
|
||||
@@ -69,7 +66,8 @@ final class ConstructorHelper {
|
||||
}
|
||||
}
|
||||
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 {
|
||||
return matchingConstructorArgs;
|
||||
}
|
||||
@@ -83,6 +81,10 @@ final class ConstructorHelper {
|
||||
* @return The number of matching arguments
|
||||
*/
|
||||
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;
|
||||
|
||||
import com.github.gtache.fxml.compiler.ControllerFieldInjectionType;
|
||||
import com.github.gtache.fxml.compiler.ControllerInfo;
|
||||
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.ControllerMethodsInjectionType;
|
||||
import com.github.gtache.fxml.compiler.ControllerMethodsInjectionType;
|
||||
import com.github.gtache.fxml.compiler.impl.GeneratorImpl;
|
||||
import com.github.gtache.fxml.compiler.parsing.ParsedProperty;
|
||||
|
||||
@@ -18,14 +16,15 @@ import static java.util.Objects.requireNonNull;
|
||||
final class ControllerInjector {
|
||||
|
||||
private final ControllerInfo controllerInfo;
|
||||
private final InjectionType fieldInjectionType;
|
||||
private final InjectionType methodInjectionType;
|
||||
private final ControllerFieldInjectionType fieldInjectionType;
|
||||
private final ControllerMethodsInjectionType methodInjectionType;
|
||||
private final StringBuilder sb;
|
||||
private final SequencedCollection<String> controllerFactoryPostAction;
|
||||
|
||||
ControllerInjector(final ControllerInfo controllerInfo, final InjectionType fieldInjectionType, final InjectionType methodInjectionType,
|
||||
final StringBuilder sb, final SequencedCollection<String> controllerFactoryPostAction) {
|
||||
this.controllerInfo = controllerInfo;
|
||||
ControllerInjector(final ControllerInfo controllerInfo, final ControllerFieldInjectionType fieldInjectionType,
|
||||
final ControllerMethodsInjectionType methodInjectionType, final StringBuilder sb,
|
||||
final SequencedCollection<String> controllerFactoryPostAction) {
|
||||
this.controllerInfo = requireNonNull(controllerInfo);
|
||||
this.fieldInjectionType = requireNonNull(fieldInjectionType);
|
||||
this.methodInjectionType = requireNonNull(methodInjectionType);
|
||||
this.sb = requireNonNull(sb);
|
||||
@@ -37,23 +36,18 @@ final class ControllerInjector {
|
||||
*
|
||||
* @param id The object id
|
||||
* @param variable The object variable
|
||||
* @throws GenerationException if an error occurs
|
||||
*/
|
||||
void injectControllerField(final String id, final String variable) throws GenerationException {
|
||||
if (fieldInjectionType instanceof final ControllerFieldInjectionTypes types) {
|
||||
switch (types) {
|
||||
case FACTORY ->
|
||||
sb.append(" fieldMap.put(\"").append(id).append("\", ").append(variable).append(");\n");
|
||||
case ASSIGN -> sb.append(" controller.").append(id).append(" = ").append(variable).append(";\n");
|
||||
case SETTERS -> {
|
||||
final var setMethod = GenerationHelper.getSetMethod(id);
|
||||
sb.append(" controller.").append(setMethod).append("(").append(variable).append(");\n");
|
||||
}
|
||||
case REFLECTION ->
|
||||
sb.append(" injectField(\"").append(id).append("\", ").append(variable).append(");\n");
|
||||
void injectControllerField(final String id, final String variable) {
|
||||
switch (fieldInjectionType) {
|
||||
case FACTORY ->
|
||||
sb.append(" fieldMap.put(\"").append(id).append("\", ").append(variable).append(");\n");
|
||||
case ASSIGN -> sb.append(" controller.").append(id).append(" = ").append(variable).append(";\n");
|
||||
case SETTERS -> {
|
||||
final var setMethod = GenerationHelper.getSetMethod(id);
|
||||
sb.append(" controller.").append(setMethod).append("(").append(variable).append(");\n");
|
||||
}
|
||||
} else {
|
||||
throw new GenerationException("Unknown controller injection type : " + fieldInjectionType);
|
||||
case REFLECTION ->
|
||||
sb.append(" injectField(\"").append(id).append("\", ").append(variable).append(");\n");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,9 +56,8 @@ final class ControllerInjector {
|
||||
*
|
||||
* @param property The property to inject
|
||||
* @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));
|
||||
}
|
||||
|
||||
@@ -74,9 +67,8 @@ final class ControllerInjector {
|
||||
* @param property The property to inject
|
||||
* @param parentVariable The parent variable
|
||||
* @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));
|
||||
}
|
||||
|
||||
@@ -84,16 +76,11 @@ final class ControllerInjector {
|
||||
* Injects a controller method
|
||||
*
|
||||
* @param methodInjection The method injection
|
||||
* @throws GenerationException if an error occurs
|
||||
*/
|
||||
private void injectControllerMethod(final String methodInjection) throws GenerationException {
|
||||
if (fieldInjectionType instanceof final ControllerFieldInjectionTypes fieldTypes) {
|
||||
switch (fieldTypes) {
|
||||
case FACTORY -> controllerFactoryPostAction.add(methodInjection);
|
||||
case ASSIGN, SETTERS, REFLECTION -> sb.append(methodInjection);
|
||||
}
|
||||
} else {
|
||||
throw getUnknownInjectionException(fieldInjectionType);
|
||||
private void injectControllerMethod(final String methodInjection) {
|
||||
switch (fieldInjectionType) {
|
||||
case FACTORY -> controllerFactoryPostAction.add(methodInjection);
|
||||
case ASSIGN, SETTERS, REFLECTION -> sb.append(methodInjection);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,27 +90,22 @@ final class ControllerInjector {
|
||||
* @param property The property
|
||||
* @param parentVariable The parent variable
|
||||
* @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 controllerMethod = property.value().replace("#", "");
|
||||
if (methodInjectionType instanceof final ControllerMethodsInjectionType methodTypes) {
|
||||
return switch (methodTypes) {
|
||||
case REFERENCE -> {
|
||||
final var hasArgument = controllerInfo.handlerHasArgument(controllerMethod);
|
||||
if (hasArgument) {
|
||||
yield " " + parentVariable + "." + setMethod + "(controller::" + controllerMethod + ");\n";
|
||||
} else {
|
||||
yield " " + parentVariable + "." + setMethod + "(e -> controller." + controllerMethod + "());\n";
|
||||
}
|
||||
return switch (methodInjectionType) {
|
||||
case REFERENCE -> {
|
||||
final var hasArgument = controllerInfo.handlerHasArgument(controllerMethod);
|
||||
if (hasArgument) {
|
||||
yield " " + parentVariable + "." + setMethod + "(controller::" + controllerMethod + ");\n";
|
||||
} else {
|
||||
yield " " + parentVariable + "." + setMethod + "(e -> controller." + controllerMethod + "());\n";
|
||||
}
|
||||
case REFLECTION ->
|
||||
" " + parentVariable + "." + setMethod + "(e -> callEventHandlerMethod(\"" + controllerMethod + "\", e));\n";
|
||||
};
|
||||
} else {
|
||||
throw getUnknownInjectionException(methodInjectionType);
|
||||
}
|
||||
}
|
||||
case REFLECTION ->
|
||||
" " + parentVariable + "." + setMethod + "(e -> callEventHandlerMethod(\"" + controllerMethod + "\", e));\n";
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -133,24 +115,15 @@ final class ControllerInjector {
|
||||
* @param parentVariable The parent variable
|
||||
* @param argumentClazz The argument class
|
||||
* @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 controllerMethod = property.value().replace("#", "");
|
||||
if (methodInjectionType instanceof final ControllerMethodsInjectionType methodTypes) {
|
||||
return switch (methodTypes) {
|
||||
case REFERENCE ->
|
||||
" " + parentVariable + "." + setMethod + "(controller::" + controllerMethod + ");\n";
|
||||
case REFLECTION ->
|
||||
" " + 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);
|
||||
return switch (methodInjectionType) {
|
||||
case REFERENCE ->
|
||||
" " + parentVariable + "." + setMethod + "(controller::" + controllerMethod + ");\n";
|
||||
case REFLECTION ->
|
||||
" " + parentVariable + "." + setMethod + "(e -> callCallbackMethod(\"" + controllerMethod + "\", e, " + argumentClazz + "));\n";
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,27 +1,27 @@
|
||||
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.InjectionType;
|
||||
import com.github.gtache.fxml.compiler.impl.ControllerFieldInjectionTypes;
|
||||
import com.github.gtache.fxml.compiler.impl.GeneratorImpl;
|
||||
import com.github.gtache.fxml.compiler.parsing.ParsedProperty;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.SequencedCollection;
|
||||
|
||||
import static com.github.gtache.fxml.compiler.impl.internal.GenerationHelper.EXPRESSION_PREFIX;
|
||||
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 {
|
||||
|
||||
private final HelperProvider helperProvider;
|
||||
private final InjectionType fieldInjectionType;
|
||||
private final ControllerFieldInjectionType fieldInjectionType;
|
||||
private final StringBuilder sb;
|
||||
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) {
|
||||
this.helperProvider = requireNonNull(helperProvider);
|
||||
this.fieldInjectionType = requireNonNull(fieldInjectionType);
|
||||
@@ -34,7 +34,7 @@ final class FieldSetter {
|
||||
*
|
||||
* @param property The property to inject
|
||||
* @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 {
|
||||
setField(property, parentVariable, "javafx.event.EventHandler");
|
||||
@@ -50,54 +50,66 @@ final class FieldSetter {
|
||||
* @throws GenerationException if an error occurs
|
||||
*/
|
||||
void setField(final ParsedProperty property, final String parentVariable, final String fieldType) throws GenerationException {
|
||||
if (fieldInjectionType instanceof final ControllerFieldInjectionTypes fieldTypes) {
|
||||
switch (fieldTypes) {
|
||||
case ASSIGN -> setAssign(property, parentVariable);
|
||||
case FACTORY -> setFactory(property, parentVariable);
|
||||
case SETTERS -> setSetter(property, parentVariable);
|
||||
case REFLECTION -> setReflection(property, parentVariable, fieldType);
|
||||
}
|
||||
} else {
|
||||
throw new GenerationException("Unknown injection type : " + fieldInjectionType);
|
||||
switch (fieldInjectionType) {
|
||||
case ASSIGN -> setAssign(property, parentVariable);
|
||||
case FACTORY -> setFactory(property, parentVariable);
|
||||
case REFLECTION -> setReflection(property, parentVariable, fieldType);
|
||||
case SETTERS -> setSetter(property, parentVariable);
|
||||
}
|
||||
}
|
||||
|
||||
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 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));
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
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 value = property.value().replace(EXPRESSION_PREFIX, "");
|
||||
final var split = value.split("\\.");
|
||||
final var getterName = GenerationHelper.getGetMethod(split[1]);
|
||||
return " " + parentVariable + "." + methodName + "(" + split[0] + "." + getterName + ");\n";
|
||||
final var holderName = split[0];
|
||||
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 value = property.value().replace(EXPRESSION_PREFIX, "");
|
||||
final var split = value.split("\\.");
|
||||
final var fieldName = split[1];
|
||||
sb.append(" try {\n");
|
||||
sb.append(" ").append(helperProvider.getCompatibilityHelper().getStartVar("java.lang.reflect.Field", 0))
|
||||
.append("field = controller.getClass().getDeclaredField(\"").append(fieldName).append("\");\n");
|
||||
sb.append(" field.setAccessible(true);\n");
|
||||
sb.append(" final var value = (").append(fieldType).append(") field.get(controller);\n");
|
||||
sb.append(" ").append(parentVariable).append(".").append(methodName).append("(value);\n");
|
||||
sb.append(" } catch (final NoSuchFieldException | IllegalAccessException e) {\n");
|
||||
sb.append(" throw new RuntimeException(e);\n");
|
||||
sb.append(" }\n");
|
||||
final var holderName = split[0];
|
||||
if (Objects.equals(holderName, "controller")) {
|
||||
final var fieldName = split[1];
|
||||
sb.append(" try {\n");
|
||||
sb.append(" ").append(helperProvider.getCompatibilityHelper().getStartVar("java.lang.reflect.Field", 0))
|
||||
.append("field = controller.getClass().getDeclaredField(\"").append(fieldName).append("\");\n");
|
||||
sb.append(" field.setAccessible(true);\n");
|
||||
sb.append(" final var value = (").append(fieldType).append(") field.get(controller);\n");
|
||||
sb.append(" ").append(parentVariable).append(".").append(methodName).append("(value);\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 size = value.size();
|
||||
final var name = value.name();
|
||||
if (url != null) {
|
||||
formatURL(url, size, variableName);
|
||||
} else if (fw == null && fp == null) {
|
||||
formatNoStyle(name, size, variableName);
|
||||
if (url == null) {
|
||||
if (name == null) {
|
||||
throw new GenerationException("Font must have a name or url : " + parsedObject);
|
||||
} else if (fw == null && fp == null) {
|
||||
formatNoStyle(name, size, variableName);
|
||||
} else {
|
||||
formatStyle(fw, fp, size, name, variableName);
|
||||
}
|
||||
} else {
|
||||
formatStyle(fw, fp, size, name, variableName);
|
||||
formatURL(url, size, variableName);
|
||||
}
|
||||
helperProvider.getGenerationHelper().handleId(parsedObject, variableName);
|
||||
} else {
|
||||
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) {
|
||||
final var urlVariableName = helperProvider.getURLFormatter().formatURL(url.toString());
|
||||
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(" } catch (final java.io.IOException e) {\n");
|
||||
sb.append(" throw new RuntimeException(e);\n");
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
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.parsing.ParsedObject;
|
||||
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.Map;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
/**
|
||||
* Various helper methods for {@link GeneratorImpl}
|
||||
*/
|
||||
@@ -31,42 +27,8 @@ final class GenerationHelper {
|
||||
static final String BINDING_EXPRESSION_PREFIX = "${";
|
||||
static final String BI_DIRECTIONAL_BINDING_PREFIX = "#{";
|
||||
|
||||
private final HelperProvider helperProvider;
|
||||
private final ControllerInfo controllerInfo;
|
||||
private final Map<String, VariableInfo> idToVariableInfo;
|
||||
private GenerationHelper() {
|
||||
|
||||
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 java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.SequencedCollection;
|
||||
import java.util.SequencedMap;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
* Used by {@link GeneratorImpl} to track the generation progress
|
||||
*
|
||||
* @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 stringBuilder The string builder
|
||||
*/
|
||||
public record GenerationProgress(GenerationRequest request, Map<String, VariableInfo> idToVariableInfo,
|
||||
Map<String, AtomicInteger> variableNameCounters,
|
||||
SequencedMap<String, String> controllerClassToVariable,
|
||||
public record GenerationProgress(GenerationRequest request,
|
||||
SequencedCollection<String> controllerFactoryPostAction,
|
||||
StringBuilder stringBuilder) {
|
||||
|
||||
@@ -32,18 +22,12 @@ public record GenerationProgress(GenerationRequest request, Map<String, Variable
|
||||
* Instantiates a new GenerationProgress
|
||||
*
|
||||
* @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 stringBuilder The string builder
|
||||
* @throws NullPointerException if any parameter is null
|
||||
*/
|
||||
public GenerationProgress {
|
||||
Objects.requireNonNull(request);
|
||||
Objects.requireNonNull(idToVariableInfo);
|
||||
Objects.requireNonNull(variableNameCounters);
|
||||
Objects.requireNonNull(controllerClassToVariable);
|
||||
Objects.requireNonNull(controllerFactoryPostAction);
|
||||
Objects.requireNonNull(stringBuilder);
|
||||
}
|
||||
@@ -55,17 +39,6 @@ public record GenerationProgress(GenerationRequest request, Map<String, Variable
|
||||
* @throws NullPointerException if request is null
|
||||
*/
|
||||
public GenerationProgress(final GenerationRequest request) {
|
||||
this(request, new HashMap<>(), new HashMap<>(), new LinkedHashMap<>(), 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();
|
||||
this(request, new ArrayList<>(), new StringBuilder());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
package com.github.gtache.fxml.compiler.impl.internal;
|
||||
|
||||
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.ControllerFieldInjectionType;
|
||||
import com.github.gtache.fxml.compiler.ControllerMethodsInjectionType;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
@@ -12,11 +11,12 @@ import java.util.Objects;
|
||||
public final class HelperMethodsFormatter {
|
||||
|
||||
private final HelperProvider helperProvider;
|
||||
private final InjectionType fieldInjectionType;
|
||||
private final InjectionType methodInjectionType;
|
||||
private final ControllerFieldInjectionType fieldInjectionType;
|
||||
private final ControllerMethodsInjectionType methodInjectionType;
|
||||
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.fieldInjectionType = Objects.requireNonNull(fieldInjectionType);
|
||||
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(" if (methods.size() > 1) {\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(" method = eventMethods").append(getFirst).append(";\n");
|
||||
sb.append(" } else {\n");
|
||||
@@ -91,7 +91,7 @@ public final class HelperMethodsFormatter {
|
||||
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(" try {\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
|
||||
*
|
||||
* @param progress The generation progress
|
||||
*/
|
||||
public HelperProvider(final GenerationProgress progress) {
|
||||
@@ -21,58 +22,66 @@ public class HelperProvider {
|
||||
this.helpers = new HashMap<>();
|
||||
}
|
||||
|
||||
ConstructorHelper getConstructorHelper() {
|
||||
return (ConstructorHelper) helpers.computeIfAbsent(ConstructorHelper.class, c -> new ConstructorHelper(this));
|
||||
}
|
||||
|
||||
ControllerInjector getControllerInjector() {
|
||||
final var request = progress.request();
|
||||
final var controllerInfo = request.controllerInfo();
|
||||
final var parameters = request.parameters();
|
||||
final var fieldInjectionType = parameters.fieldInjectionType();
|
||||
final var methodInjectionType = parameters.methodInjectionType();
|
||||
final var sb = progress.stringBuilder();
|
||||
final var controllerFactoryPostAction = progress.controllerFactoryPostAction();
|
||||
return (ControllerInjector) helpers.computeIfAbsent(ControllerInjector.class, c -> new ControllerInjector(controllerInfo, fieldInjectionType, methodInjectionType, sb, controllerFactoryPostAction));
|
||||
return (ControllerInjector) helpers.computeIfAbsent(ControllerInjector.class, c -> {
|
||||
final var request = progress.request();
|
||||
final var controllerInfo = request.controllerInfo();
|
||||
final var parameters = request.parameters();
|
||||
final var fieldInjectionType = parameters.fieldInjectionType();
|
||||
final var methodInjectionType = parameters.methodInjectionType();
|
||||
final var sb = progress.stringBuilder();
|
||||
final var controllerFactoryPostAction = progress.controllerFactoryPostAction();
|
||||
return new ControllerInjector(controllerInfo, fieldInjectionType, methodInjectionType, sb, controllerFactoryPostAction);
|
||||
});
|
||||
}
|
||||
|
||||
FieldSetter getFieldSetter() {
|
||||
final var fieldInjectionType = progress.request().parameters().fieldInjectionType();
|
||||
final var sb = progress.stringBuilder();
|
||||
final var controllerFactoryPostAction = progress.controllerFactoryPostAction();
|
||||
return (FieldSetter) helpers.computeIfAbsent(FieldSetter.class, c -> new FieldSetter(this, fieldInjectionType, sb, controllerFactoryPostAction));
|
||||
return (FieldSetter) helpers.computeIfAbsent(FieldSetter.class, c -> {
|
||||
final var fieldInjectionType = progress.request().parameters().fieldInjectionType();
|
||||
final var sb = progress.stringBuilder();
|
||||
final var controllerFactoryPostAction = progress.controllerFactoryPostAction();
|
||||
return new FieldSetter(this, fieldInjectionType, sb, controllerFactoryPostAction);
|
||||
});
|
||||
}
|
||||
|
||||
FontFormatter getFontFormatter() {
|
||||
final var sb = progress.stringBuilder();
|
||||
return (FontFormatter) helpers.computeIfAbsent(FontFormatter.class, c -> new FontFormatter(this, sb));
|
||||
return (FontFormatter) helpers.computeIfAbsent(FontFormatter.class, c -> {
|
||||
final var sb = progress.stringBuilder();
|
||||
return new FontFormatter(this, sb);
|
||||
});
|
||||
}
|
||||
|
||||
GenerationCompatibilityHelper getCompatibilityHelper() {
|
||||
final var compatibility = progress.request().parameters().compatibility();
|
||||
return (GenerationCompatibilityHelper) helpers.computeIfAbsent(GenerationCompatibilityHelper.class, c -> 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));
|
||||
return (GenerationCompatibilityHelper) helpers.computeIfAbsent(GenerationCompatibilityHelper.class, c -> {
|
||||
final var compatibility = progress.request().parameters().compatibility();
|
||||
return new GenerationCompatibilityHelper(this, compatibility);
|
||||
});
|
||||
}
|
||||
|
||||
public HelperMethodsFormatter getHelperMethodsFormatter() {
|
||||
final var parameters = progress.request().parameters();
|
||||
final var fieldInjectionType = parameters.fieldInjectionType();
|
||||
final var methodInjectionType = parameters.methodInjectionType();
|
||||
final var sb = progress.stringBuilder();
|
||||
return (HelperMethodsFormatter) helpers.computeIfAbsent(HelperMethodsFormatter.class, c -> new HelperMethodsFormatter(this, fieldInjectionType, methodInjectionType, sb));
|
||||
return (HelperMethodsFormatter) helpers.computeIfAbsent(HelperMethodsFormatter.class, c -> {
|
||||
final var parameters = progress.request().parameters();
|
||||
final var fieldInjectionType = parameters.fieldInjectionType();
|
||||
final var methodInjectionType = parameters.methodInjectionType();
|
||||
final var sb = progress.stringBuilder();
|
||||
return new HelperMethodsFormatter(this, fieldInjectionType, methodInjectionType, sb);
|
||||
});
|
||||
}
|
||||
|
||||
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() {
|
||||
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() {
|
||||
@@ -80,7 +89,11 @@ public class HelperProvider {
|
||||
}
|
||||
|
||||
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() {
|
||||
@@ -88,30 +101,48 @@ public class HelperProvider {
|
||||
}
|
||||
|
||||
ReflectionHelper getReflectionHelper() {
|
||||
final var controllerInfo = progress.request().controllerInfo();
|
||||
return (ReflectionHelper) helpers.computeIfAbsent(ReflectionHelper.class, c -> new ReflectionHelper(controllerInfo));
|
||||
return (ReflectionHelper) helpers.computeIfAbsent(ReflectionHelper.class, c -> {
|
||||
final var controllerInfo = progress.request().controllerInfo();
|
||||
return new ReflectionHelper(controllerInfo);
|
||||
});
|
||||
}
|
||||
|
||||
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() {
|
||||
final var sb = progress.stringBuilder();
|
||||
return (TriangleMeshFormatter) helpers.computeIfAbsent(TriangleMeshFormatter.class, c -> new TriangleMeshFormatter(this, sb));
|
||||
return (TriangleMeshFormatter) helpers.computeIfAbsent(TriangleMeshFormatter.class, c -> {
|
||||
final var sb = progress.stringBuilder();
|
||||
return new TriangleMeshFormatter(this, sb);
|
||||
});
|
||||
}
|
||||
|
||||
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() {
|
||||
final var resourceInjectionType = progress.request().parameters().resourceInjectionType();
|
||||
final var idToVariableInfo = progress.idToVariableInfo();
|
||||
return (ValueFormatter) helpers.computeIfAbsent(ValueFormatter.class, c -> new ValueFormatter(resourceInjectionType, idToVariableInfo));
|
||||
return (ValueFormatter) helpers.computeIfAbsent(ValueFormatter.class, c -> {
|
||||
final var resourceInjectionType = progress.request().parameters().resourceInjectionType();
|
||||
return new ValueFormatter(this, resourceInjectionType);
|
||||
});
|
||||
}
|
||||
|
||||
VariableProvider getVariableProvider() {
|
||||
return (VariableProvider) helpers.computeIfAbsent(VariableProvider.class, c -> new VariableProvider());
|
||||
}
|
||||
|
||||
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.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.getSortedAttributes;
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
/**
|
||||
* 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 {
|
||||
|
||||
private final HelperProvider helperProvider;
|
||||
private final GenerationProgress progress;
|
||||
private final StringBuilder sb;
|
||||
private final boolean useImageInputStreamConstructor;
|
||||
|
||||
ImageFormatter(final HelperProvider helperProvider, final GenerationProgress progress) {
|
||||
this.helperProvider = Objects.requireNonNull(helperProvider);
|
||||
this.progress = Objects.requireNonNull(progress);
|
||||
ImageFormatter(final HelperProvider helperProvider, final StringBuilder sb, final boolean useImageInputStreamConstructor) {
|
||||
this.helperProvider = requireNonNull(helperProvider);
|
||||
this.sb = requireNonNull(sb);
|
||||
this.useImageInputStreamConstructor = useImageInputStreamConstructor;
|
||||
}
|
||||
|
||||
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 {
|
||||
final var sortedAttributes = getSortedAttributes(parsedObject);
|
||||
String url = null;
|
||||
@@ -65,20 +53,32 @@ final class ImageFormatter {
|
||||
default -> throw new GenerationException("Unknown image attribute : " + property.name());
|
||||
}
|
||||
}
|
||||
|
||||
if (progress.request().parameters().useImageInputStreamConstructor()) {
|
||||
if (url == null) {
|
||||
throw new GenerationException("Image must have a url attribute : " + parsedObject);
|
||||
}
|
||||
if (useImageInputStreamConstructor) {
|
||||
formatInputStream(url, requestedWidth, requestedHeight, preserveRatio, smooth, variableName);
|
||||
} else {
|
||||
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,
|
||||
final double requestedHeight, final boolean preserveRatio, final boolean smooth,
|
||||
final boolean backgroundLoading, final String variableName) {
|
||||
final var urlString = progress.getNextVariableName("urlStr");
|
||||
final var sb = progress.stringBuilder();
|
||||
final var urlString = helperProvider.getVariableProvider().getNextVariableName("urlStr");
|
||||
final var compatibilityHelper = helperProvider.getCompatibilityHelper();
|
||||
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)
|
||||
|
||||
@@ -1,51 +1,75 @@
|
||||
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.GenerationRequest;
|
||||
import com.github.gtache.fxml.compiler.InjectionType;
|
||||
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 java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Objects;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
/**
|
||||
* Utility class to provide the view's constructor and fields
|
||||
*/
|
||||
public final class InitializationFormatter {
|
||||
|
||||
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) {
|
||||
this.helperProvider = Objects.requireNonNull(helperProvider);
|
||||
this.progress = Objects.requireNonNull(progress);
|
||||
InitializationFormatter(final HelperProvider helperProvider, final GenerationRequest request, final StringBuilder sb) {
|
||||
this(helperProvider, request, sb, new HashMap<>());
|
||||
}
|
||||
|
||||
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 {
|
||||
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 mainControllerClass = progress.request().controllerInfo().className();
|
||||
final var isFactory = progress.request().parameters().controllerInjectionType() == ControllerInjectionTypes.FACTORY;
|
||||
final var mainControllerClass = request.controllerInfo().className();
|
||||
final var parameters = request.parameters();
|
||||
final var controllerInjectionType = parameters.controllerInjectionType();
|
||||
final var fieldInjectionType = parameters.fieldInjectionType();
|
||||
final var isFactory = controllerInjectionType == ControllerInjectionType.FACTORY;
|
||||
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();
|
||||
final var sb = progress.stringBuilder();
|
||||
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 sortedControllersKeys = controllerClassToVariable.keySet().stream().sorted().toList();
|
||||
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 resourceBundleType = resourceBundleInfo.type();
|
||||
final var resourceBundleArg = resourceBundleInfo.variableName();
|
||||
if (isFactory) {
|
||||
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");
|
||||
} else {
|
||||
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) {
|
||||
sb.append(" private final ").append(resourceBundleType).append(" ").append(resourceBundleArg).append(";\n");
|
||||
@@ -55,49 +79,49 @@ public final class InitializationFormatter {
|
||||
sb.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");
|
||||
controllerMap.forEach((c, s) -> sb.append(" * @param ").append(getVariableName(s, isFactory))
|
||||
.append(" The subcontroller ").append(isFactory ? "factory" : "instance").append(" for ").append(c).append("\n"));
|
||||
sortedControllersKeys.forEach(e -> sb.append(" * @param ").append(getVariableName(controllerClassToVariable.get(e), isFactory))
|
||||
.append(" The subcontroller ").append(isFactory ? "factory" : "instance").append(" for ").append(e).append("\n"));
|
||||
|
||||
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");
|
||||
final var arguments = "final " + controllerArgClass + " " + controllerArg +
|
||||
((controllerMap.isEmpty()) ? "" : ", ") +
|
||||
controllerMap.entrySet().stream().map(e -> "final " + getType(e.getKey(), isFactory) + " " + getVariableName(e.getValue(), isFactory))
|
||||
((sortedControllersKeys.isEmpty()) ? "" : ", ") +
|
||||
sortedControllersKeys.stream().map(e -> "final " + getType(e, controllerInjectionType, fieldInjectionType) + " " + getVariableName(controllerClassToVariable.get(e), isFactory))
|
||||
.sorted().collect(Collectors.joining(", "))
|
||||
+ (resourceBundleType == null ? "" : ", final " + resourceBundleType + " " + resourceBundleArg);
|
||||
sb.append(" public ").append(simpleClassName).append("(").append(arguments).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) {
|
||||
sb.append(" this.").append(resourceBundleArg).append(" = java.util.Objects.requireNonNull(").append(resourceBundleArg).append(");\n");
|
||||
}
|
||||
sb.append(" }\n");
|
||||
}
|
||||
|
||||
private ResourceBundleInfo getResourceBundleInfo() throws GenerationException {
|
||||
final var injectionType = progress.request().parameters().resourceInjectionType();
|
||||
if (injectionType instanceof final ResourceBundleInjectionTypes types) {
|
||||
return switch (types) {
|
||||
case CONSTRUCTOR -> new ResourceBundleInfo("java.util.ResourceBundle", "resourceBundle");
|
||||
case CONSTRUCTOR_FUNCTION ->
|
||||
new ResourceBundleInfo("java.util.function.Function<String, String>", "resourceBundleFunction");
|
||||
case CONSTRUCTOR_NAME -> new ResourceBundleInfo("String", "resourceBundleName");
|
||||
case GETTER -> new ResourceBundleInfo(null, null);
|
||||
case GET_BUNDLE -> new ResourceBundleInfo(null, null);
|
||||
};
|
||||
} else {
|
||||
throw new GenerationException("Unknown resource injection type : " + injectionType);
|
||||
}
|
||||
private ResourceBundleInfo getResourceBundleInfo() {
|
||||
final var injectionType = request.parameters().resourceInjectionType();
|
||||
return switch (injectionType) {
|
||||
case CONSTRUCTOR -> new ResourceBundleInfo("java.util.ResourceBundle", "resourceBundle");
|
||||
case CONSTRUCTOR_FUNCTION ->
|
||||
new ResourceBundleInfo("java.util.function.Function<String, String>", "resourceBundleFunction");
|
||||
case CONSTRUCTOR_NAME -> new ResourceBundleInfo("String", "resourceBundleName");
|
||||
case GETTER, GET_BUNDLE -> new ResourceBundleInfo(null, null);
|
||||
};
|
||||
}
|
||||
|
||||
private record ResourceBundleInfo(String type, String variableName) {
|
||||
}
|
||||
|
||||
private static String getType(final String controllerClass, final boolean isFactory) {
|
||||
if (isFactory) {
|
||||
private static String getType(final String controllerClass, final InjectionType controllerInjectionTypes, final InjectionType fieldInjectionTypes) {
|
||||
if (fieldInjectionTypes == ControllerFieldInjectionType.FACTORY) {
|
||||
return "java.util.function.Function<java.util.Map<String, Object>, " + controllerClass + ">";
|
||||
} else if (controllerInjectionTypes == ControllerInjectionType.FACTORY) {
|
||||
return "java.util.function.Supplier<" + controllerClass + ">";
|
||||
} else {
|
||||
return controllerClass;
|
||||
}
|
||||
@@ -105,19 +129,15 @@ public final class InitializationFormatter {
|
||||
|
||||
private static String getVariableName(final String variableName, final boolean isFactory) {
|
||||
if (isFactory) {
|
||||
return getVariableName(variableName, "Factory");
|
||||
return variableName + "Factory";
|
||||
} else {
|
||||
return variableName;
|
||||
}
|
||||
}
|
||||
|
||||
private static String getVariableName(final String variableName, final String suffix) {
|
||||
return variableName + suffix;
|
||||
}
|
||||
|
||||
private boolean hasDuplicateControllerClass() {
|
||||
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) {
|
||||
@@ -125,15 +145,17 @@ public final class InitializationFormatter {
|
||||
if (controllers.contains(controllerClass)) {
|
||||
return true;
|
||||
}
|
||||
controllers.add(controllerClass);
|
||||
return info.includedSources().stream().anyMatch(s -> hasDuplicateControllerClass(s, controllers));
|
||||
}
|
||||
|
||||
private void fillControllers() {
|
||||
progress.request().sourceInfo().includedSources().forEach(this::fillControllers);
|
||||
request.sourceInfo().includedSources().forEach(this::fillControllers);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -143,58 +165,55 @@ public final class InitializationFormatter {
|
||||
}
|
||||
|
||||
String formatSubViewConstructorCall(final ParsedInclude include) throws GenerationException {
|
||||
final var request = progress.request();
|
||||
final var info = request.sourceInfo();
|
||||
final var subInfo = info.sourceToSourceInfo().get(include.source());
|
||||
if (subInfo == null) {
|
||||
throw new GenerationException("Unknown include source : " + include.source());
|
||||
} else {
|
||||
final var isFactory = request.parameters().controllerInjectionType() == ControllerInjectionTypes.FACTORY;
|
||||
final var isFactory = request.parameters().controllerInjectionType() == ControllerInjectionType.FACTORY;
|
||||
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>();
|
||||
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 argumentList = subControllerVariable + (arguments.isEmpty() ? "" : ", " + arguments) + (bundleVariable == null ? "" : ", " + bundleVariable);
|
||||
final var subViewName = subInfo.generatedClassName();
|
||||
final var variable = progress.getNextVariableName(GenerationHelper.getVariablePrefix(subViewName));
|
||||
progress.stringBuilder().append(helperProvider.getCompatibilityHelper().getStartVar(subViewName)).append(variable).append(" = new ").append(subViewName).append("(").append(argumentList).append(");\n");
|
||||
final var variable = helperProvider.getVariableProvider().getNextVariableName(GenerationHelper.getVariablePrefix(subViewName));
|
||||
sb.append(helperProvider.getCompatibilityHelper().getStartVar(subViewName)).append(variable).append(" = new ").append(subViewName).append("(").append(argumentList).append(");\n");
|
||||
return variable;
|
||||
}
|
||||
}
|
||||
|
||||
private String getBundleVariable(final ParsedInclude include) throws GenerationException {
|
||||
private String getBundleVariable(final ParsedInclude include) {
|
||||
final var info = getResourceBundleInfo();
|
||||
if (info.type() == null) {
|
||||
return null;
|
||||
} else if (include.resources() == null) {
|
||||
return info.variableName();
|
||||
} else {
|
||||
final var sb = progress.stringBuilder();
|
||||
if (progress.request().parameters().resourceInjectionType() instanceof final ResourceBundleInjectionTypes types) {
|
||||
final var compatibilityHelper = helperProvider.getCompatibilityHelper();
|
||||
return switch (types) {
|
||||
case GETTER, GET_BUNDLE -> null;
|
||||
case CONSTRUCTOR_NAME -> {
|
||||
final var bundleVariable = progress.getNextVariableName("resourceBundleName");
|
||||
sb.append(compatibilityHelper.getStartVar("String")).append(bundleVariable).append(" = \"").append(include.resources()).append("\";\n");
|
||||
yield bundleVariable;
|
||||
}
|
||||
case CONSTRUCTOR_FUNCTION -> {
|
||||
final var bundleVariable = progress.getNextVariableName("resourceBundleFunction");
|
||||
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");
|
||||
yield bundleVariable;
|
||||
}
|
||||
case CONSTRUCTOR -> {
|
||||
final var bundleVariable = progress.getNextVariableName("resourceBundle");
|
||||
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());
|
||||
}
|
||||
final var compatibilityHelper = helperProvider.getCompatibilityHelper();
|
||||
final var variableProvider = helperProvider.getVariableProvider();
|
||||
return switch (request.parameters().resourceInjectionType()) {
|
||||
case GETTER, GET_BUNDLE -> null;
|
||||
case CONSTRUCTOR_NAME -> {
|
||||
final var bundleVariable = variableProvider.getNextVariableName("resourceBundleName");
|
||||
sb.append(compatibilityHelper.getStartVar("String")).append(bundleVariable).append(" = \"").append(include.resources()).append("\";\n");
|
||||
yield bundleVariable;
|
||||
}
|
||||
case CONSTRUCTOR_FUNCTION -> {
|
||||
final var bundleVariable = variableProvider.getNextVariableName("resourceBundle");
|
||||
sb.append(compatibilityHelper.getStartVar("java.util.ResourceBundle")).append(bundleVariable).append(" = java.util.ResourceBundle.getBundle(\"").append(include.resources()).append("\");\n");
|
||||
final var bundleFunctionVariable = variableProvider.getNextVariableName("resourceBundleFunction");
|
||||
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 = variableProvider.getNextVariableName("resourceBundle");
|
||||
sb.append(compatibilityHelper.getStartVar("java.util.ResourceBundle")).append(bundleVariable).append(" = java.util.ResourceBundle.getBundle(\"").append(include.resources()).append("\");\n");
|
||||
yield bundleVariable;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
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.impl.ControllerFieldInjectionTypes;
|
||||
import com.github.gtache.fxml.compiler.impl.ControllerMethodsInjectionType;
|
||||
import com.github.gtache.fxml.compiler.impl.ResourceBundleInjectionTypes;
|
||||
import com.github.gtache.fxml.compiler.ResourceBundleInjectionType;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
@@ -29,7 +30,8 @@ public final class LoadMethodFormatter {
|
||||
final var request = progress.request();
|
||||
final var rootObject = request.rootObject();
|
||||
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 sb = progress.stringBuilder();
|
||||
sb.append(" /**\n");
|
||||
@@ -43,35 +45,38 @@ public final class LoadMethodFormatter {
|
||||
sb.append(" }\n");
|
||||
final var resourceBundleInjection = parameters.resourceInjectionType();
|
||||
final var generationCompatibilityHelper = helperProvider.getCompatibilityHelper();
|
||||
if (resourceBundleInjection == ResourceBundleInjectionTypes.CONSTRUCTOR_NAME) {
|
||||
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)) {
|
||||
sb.append(generationCompatibilityHelper.getStartVar("java.util.ResourceBundle")).append("resourceBundle = java.util.ResourceBundle.getBundle(\"").append(parameters.bundleMap().get(controllerClass)).append("\");\n");
|
||||
if (resourceBundleInjection == ResourceBundleInjectionType.CONSTRUCTOR_NAME) {
|
||||
sb.append(generationCompatibilityHelper.getStartVar("java.util.ResourceBundle")).append("resourceBundle = java.util.ResourceBundle.getBundle(resourceBundleName);\n");
|
||||
} 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");
|
||||
}
|
||||
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");
|
||||
} 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);
|
||||
if (controllerInjectionType == ControllerFieldInjectionTypes.FACTORY) {
|
||||
sb.append(" controller = (").append(controllerClass).append(") controllerFactory.create(fieldMap);\n");
|
||||
if (fieldInjectionType == ControllerFieldInjectionType.FACTORY) {
|
||||
sb.append(" controller = controllerFactory.create(fieldMap);\n");
|
||||
progress.controllerFactoryPostAction().forEach(sb::append);
|
||||
}
|
||||
if (parameters.methodInjectionType() == ControllerMethodsInjectionType.REFLECTION) {
|
||||
sb.append(" try {\n");
|
||||
sb.append(" ").append(generationCompatibilityHelper.getStartVar("java.lang.reflect.Method", 0)).append("initialize = controller.getClass().getDeclaredMethod(\"initialize\");\n");
|
||||
sb.append(" initialize.setAccessible(true);\n");
|
||||
sb.append(" initialize.invoke(controller);\n");
|
||||
sb.append(" } catch (final java.lang.reflect.InvocationTargetException | IllegalAccessException e) {\n");
|
||||
sb.append(" throw new RuntimeException(\"Error using reflection\", e);\n");
|
||||
sb.append(" } catch (final NoSuchMethodException ignored) {\n");
|
||||
sb.append(" }\n");
|
||||
} else {
|
||||
sb.append(" controller.initialize();\n");
|
||||
if (request.controllerInfo().hasInitialize()) {
|
||||
if (parameters.methodInjectionType() == ControllerMethodsInjectionType.REFLECTION) {
|
||||
sb.append(" try {\n");
|
||||
sb.append(" ").append(generationCompatibilityHelper.getStartVar("java.lang.reflect.Method", 0)).append("initialize = controller.getClass().getDeclaredMethod(\"initialize\");\n");
|
||||
sb.append(" initialize.setAccessible(true);\n");
|
||||
sb.append(" initialize.invoke(controller);\n");
|
||||
sb.append(" } catch (final java.lang.reflect.InvocationTargetException | IllegalAccessException | NoSuchMethodException e) {\n");
|
||||
sb.append(" throw new RuntimeException(\"Error using reflection\", e);\n");
|
||||
sb.append(" }\n");
|
||||
} else {
|
||||
sb.append(" controller.initialize();\n");
|
||||
}
|
||||
}
|
||||
sb.append(" loaded = true;\n");
|
||||
sb.append(" return (T) ").append(variableName).append(";\n");
|
||||
sb.append(" }\n");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.github.gtache.fxml.compiler.impl.internal;
|
||||
|
||||
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.parsing.*;
|
||||
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
|
||||
*/
|
||||
public final class ObjectFormatter {
|
||||
final class ObjectFormatter {
|
||||
|
||||
private static final Logger logger = LogManager.getLogger(ObjectFormatter.class);
|
||||
|
||||
@@ -47,11 +48,13 @@ public final class ObjectFormatter {
|
||||
);
|
||||
|
||||
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.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);
|
||||
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
|
||||
*/
|
||||
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.image.Image" ->
|
||||
helperProvider.getImageFormatter().formatImage(parsedObject, variableName);
|
||||
case "java.net.URL" -> helperProvider.getURLFormatter().formatURL(parsedObject, variableName);
|
||||
case "javafx.scene.shape.TriangleMesh" ->
|
||||
helperProvider.getTriangleMeshFormatter().formatTriangleMesh(parsedObject, variableName);
|
||||
case "java.net.URL" -> helperProvider.getURLFormatter().formatURL(parsedObject, variableName);
|
||||
case "javafx.scene.web.WebView" ->
|
||||
helperProvider.getWebViewFormatter().formatWebView(parsedObject, variableName);
|
||||
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);
|
||||
}
|
||||
final var value = getSimpleValue(parsedObject);
|
||||
final var valueStr = helperProvider.getValueFormatter().toString(value, ReflectionHelper.getClass(parsedObject.className()));
|
||||
progress.stringBuilder().append(helperProvider.getCompatibilityHelper().getStartVar(parsedObject)).append(variableName).append(" = ").append(valueStr).append(";\n");
|
||||
helperProvider.getGenerationHelper().handleId(parsedObject, variableName);
|
||||
final var valueStr = ValueFormatter.toString(value, ReflectionHelper.getClass(parsedObject.className()));
|
||||
sb.append(helperProvider.getCompatibilityHelper().getStartVar(parsedObject)).append(variableName).append(" = ").append(valueStr).append(";\n");
|
||||
}
|
||||
|
||||
private String getSimpleValue(final ParsedObject parsedObject) throws GenerationException {
|
||||
final var definedChildren = parsedObject.children().stream().filter(ParsedDefine.class::isInstance).toList();
|
||||
for (final var definedChild : definedChildren) {
|
||||
formatObject(definedChild, progress.getNextVariableName("define"));
|
||||
}
|
||||
final var notDefinedChildren = parsedObject.children().stream().filter(c -> !(c instanceof ParsedDefine)).toList();
|
||||
formatDefines(parsedObject.children());
|
||||
final var notDefinedChildren = getNotDefines(parsedObject.children());
|
||||
if (parsedObject.attributes().containsKey(FX_VALUE)) {
|
||||
return getSimpleFXValue(parsedObject, notDefinedChildren);
|
||||
} 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 {
|
||||
if (notDefinedChildren.isEmpty() && !parsedObject.attributes().containsKey(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();
|
||||
if (SIMPLE_CLASSES.contains(className)) {
|
||||
return true;
|
||||
@@ -199,35 +270,31 @@ public final class ObjectFormatter {
|
||||
private void formatComplexClass(final ParsedObject parsedObject, final String variableName) throws GenerationException {
|
||||
final var clazz = ReflectionHelper.getClass(parsedObject.className());
|
||||
final var children = parsedObject.children();
|
||||
final var definedChildren = children.stream().filter(ParsedDefine.class::isInstance).toList();
|
||||
final var notDefinedChildren = children.stream().filter(c -> !(c instanceof ParsedDefine)).toList();
|
||||
final var notDefinedChildren = getNotDefines(children);
|
||||
final var constructors = clazz.getConstructors();
|
||||
final var allPropertyNames = new HashSet<>(parsedObject.attributes().keySet());
|
||||
allPropertyNames.addAll(parsedObject.properties().keySet().stream().map(ParsedProperty::name).collect(Collectors.toSet()));
|
||||
if (!definedChildren.isEmpty()) {
|
||||
for (final var definedChild : definedChildren) {
|
||||
format(definedChild, progress.getNextVariableName("define"));
|
||||
}
|
||||
}
|
||||
final var allAttributesNames = new HashSet<>(parsedObject.attributes().keySet());
|
||||
allAttributesNames.addAll(parsedObject.properties().keySet().stream().map(ParsedProperty::name).collect(Collectors.toSet()));
|
||||
formatDefines(children);
|
||||
if (!notDefinedChildren.isEmpty()) {
|
||||
final var defaultProperty = ReflectionHelper.getDefaultProperty(parsedObject.className());
|
||||
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) {
|
||||
formatNoConstructor(parsedObject, variableName, allPropertyNames);
|
||||
formatNoConstructor(parsedObject, variableName, allAttributesNames);
|
||||
} else {
|
||||
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());
|
||||
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");
|
||||
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 {
|
||||
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 {
|
||||
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);
|
||||
progress.stringBuilder().append(helperProvider.getCompatibilityHelper().getStartVar(parsedObject)).append(variableName).append(NEW_ASSIGN).append(parsedObject.className())
|
||||
.append(genericTypes).append("(").append(String.join(", ", args)).append(");\n");
|
||||
sb.append(helperProvider.getCompatibilityHelper().getStartVar(parsedObject)).append(variableName)
|
||||
.append(NEW_ASSIGN).append(parsedObject.className()).append(genericTypes).append("(")
|
||||
.append(String.join(", ", args)).append(");\n");
|
||||
final var sortedAttributes = getSortedAttributes(parsedObject);
|
||||
for (final var value : sortedAttributes) {
|
||||
if (!constructorArgs.namedArgs().containsKey(value.name())) {
|
||||
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) {
|
||||
if (!constructorArgs.namedArgs().containsKey(e.getKey().name())) {
|
||||
final var p = e.getKey();
|
||||
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();
|
||||
if (!notDefinedChildren.isEmpty()) {
|
||||
final var defaultProperty = ReflectionHelper.getDefaultProperty(parsedObject.className());
|
||||
if (!constructorArgs.namedArgs().containsKey(defaultProperty)) {
|
||||
final var property = new ParsedPropertyImpl(defaultProperty, null, null);
|
||||
formatChild(parsedObject, property, notDefinedChildren, variableName);
|
||||
final var property = new ParsedPropertyImpl(defaultProperty, null, "");
|
||||
helperProvider.getPropertyFormatter().formatProperty(property, notDefinedChildren, parsedObject, variableName);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -270,20 +338,21 @@ public final class ObjectFormatter {
|
||||
* @param subNodeName The sub node name
|
||||
*/
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
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();
|
||||
if (id != null) {
|
||||
final var subControllerVariable = progress.getNextVariableName("controller");
|
||||
final var controllerClass = progress.request().sourceInfo().sourceToSourceInfo().get(include.source()).controllerClassName();
|
||||
progress.stringBuilder().append(helperProvider.getCompatibilityHelper().getStartVar(controllerClass)).append(subControllerVariable).append(" = ").append(subViewVariable).append(".controller();\n");
|
||||
progress.idToVariableInfo().put(id, new VariableInfo(id, include, subControllerVariable, controllerClass));
|
||||
if (progress.request().controllerInfo().fieldInfo(id) == null) {
|
||||
final var variableProvider = helperProvider.getVariableProvider();
|
||||
final var subControllerVariable = variableProvider.getNextVariableName("controller");
|
||||
final var controllerClass = request.sourceInfo().sourceToSourceInfo().get(include.source()).controllerClassName();
|
||||
sb.append(helperProvider.getCompatibilityHelper().getStartVar(controllerClass)).append(subControllerVariable).append(" = ").append(subViewVariable).append(".controller();\n");
|
||||
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);
|
||||
} else {
|
||||
helperProvider.getControllerInjector().injectControllerField(id, subControllerVariable);
|
||||
@@ -294,12 +363,12 @@ public final class ObjectFormatter {
|
||||
/**
|
||||
* Formats a fx:define
|
||||
*
|
||||
* @param define The parsed define
|
||||
* @param define The parsed define
|
||||
* @throws GenerationException if an error occurs
|
||||
*/
|
||||
private void formatDefine(final ParsedObject define) throws GenerationException {
|
||||
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 {
|
||||
final var id = reference.source();
|
||||
final var variableInfo = progress.idToVariableInfo().get(id);
|
||||
final var variableInfo = helperProvider.getVariableProvider().getVariableInfo(id);
|
||||
if (variableInfo == null) {
|
||||
throw new GenerationException("Unknown id : " + id);
|
||||
}
|
||||
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 {
|
||||
final var id = copy.source();
|
||||
final var variableInfo = progress.idToVariableInfo().get(id);
|
||||
final var variableInfo = helperProvider.getVariableProvider().getVariableInfo(id);
|
||||
if (variableInfo == null) {
|
||||
throw new GenerationException("Unknown id : " + id);
|
||||
}
|
||||
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 variableName The variable name
|
||||
*/
|
||||
private void formatConstant(final ParsedConstant constant, final String variableName) throws GenerationException {
|
||||
progress.stringBuilder().append(helperProvider.getCompatibilityHelper().getStartVar(constant.className())).append(variableName).append(" = ").append(constant.className()).append(".").append(constant.constant()).append(";\n");
|
||||
private void formatConstant(final ParsedConstant constant, final String variableName) {
|
||||
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 variableName The variable name
|
||||
*/
|
||||
private void formatValue(final ParsedValue value, final String variableName) throws GenerationException {
|
||||
progress.stringBuilder().append(helperProvider.getCompatibilityHelper().getStartVar(value.className())).append(variableName).append(" = ").append(value.className()).append(".valueOf(\"").append(value.value()).append("\");\n");
|
||||
private void formatValue(final ParsedValue value, final String variableName) {
|
||||
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 {
|
||||
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()) {
|
||||
final var argumentVariable = progress.getNextVariableName("arg");
|
||||
final var argumentVariable = helperProvider.getVariableProvider().getNextVariableName("arg");
|
||||
variables.add(argumentVariable);
|
||||
format(argument, argumentVariable);
|
||||
}
|
||||
final var compatibilityHelper = helperProvider.getCompatibilityHelper();
|
||||
if (progress.request().parameters().compatibility().useVar()) {
|
||||
progress.stringBuilder().append(compatibilityHelper.getStartVar(factory.className())).append(variableName).append(" = ").append(factory.className())
|
||||
if (request.parameters().compatibility().useVar()) {
|
||||
sb.append(compatibilityHelper.getStartVar(factory.className())).append(variableName).append(" = ").append(factory.className())
|
||||
.append(".").append(factory.factory()).append("(").append(String.join(", ", variables)).append(");\n");
|
||||
} else {
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
import com.github.gtache.fxml.compiler.ControllerFieldInjectionType;
|
||||
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.ResourceBundleInjectionTypes;
|
||||
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.ParsedText;
|
||||
import com.github.gtache.fxml.compiler.parsing.impl.ParsedPropertyImpl;
|
||||
import javafx.event.EventHandler;
|
||||
|
||||
import java.util.ArrayList;
|
||||
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.RESOURCE_KEY_PREFIX;
|
||||
import static com.github.gtache.fxml.compiler.impl.internal.GenerationHelper.*;
|
||||
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 {
|
||||
final var propertyName = property.name();
|
||||
if (propertyName.equals(FX_ID)) {
|
||||
helperProvider.getGenerationHelper().handleId(parent, parentVariable);
|
||||
//Do nothing
|
||||
} else if (propertyName.equals("fx:controller")) {
|
||||
checkDuplicateController(parent);
|
||||
} 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 {
|
||||
if (parent != progress.request().rootObject()) {
|
||||
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 {
|
||||
final var setMethod = GenerationHelper.getSetMethod(propertyName);
|
||||
final var setMethod = getSetMethod(propertyName);
|
||||
final var propertySourceTypeClass = ReflectionHelper.getClass(property.sourceType());
|
||||
if (ReflectionHelper.hasStaticMethod(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 {
|
||||
final var propertyName = property.name();
|
||||
final var setMethod = GenerationHelper.getSetMethod(propertyName);
|
||||
final var getMethod = GenerationHelper.getGetMethod(propertyName);
|
||||
final var setMethod = getSetMethod(propertyName);
|
||||
final var getMethod = getGetMethod(propertyName);
|
||||
final var parentClass = ReflectionHelper.getClass(parent.className());
|
||||
if (ReflectionHelper.hasMethod(parentClass, setMethod)) {
|
||||
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 {
|
||||
final var setMethod = GenerationHelper.getSetMethod(property.name());
|
||||
final var setMethod = getSetMethod(property.name());
|
||||
final var method = ReflectionHelper.getMethod(parentClass, setMethod);
|
||||
final var parameterType = method.getParameterTypes()[0];
|
||||
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 {
|
||||
final var getMethod = GenerationHelper.getGetMethod(property.name());
|
||||
final var getMethod = getGetMethod(property.name());
|
||||
final var method = ReflectionHelper.getMethod(parentClass, getMethod);
|
||||
final var returnType = method.getReturnType();
|
||||
if (ReflectionHelper.hasMethod(returnType, "addAll")) {
|
||||
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) {
|
||||
final var parameters = progress.request().parameters();
|
||||
if (type == String.class && property.value().startsWith(RESOURCE_KEY_PREFIX) && parameters.resourceInjectionType() == ResourceBundleInjectionTypes.GETTER
|
||||
&& parameters.fieldInjectionType() == ControllerFieldInjectionTypes.FACTORY) {
|
||||
if (type == String.class && property.value().startsWith(RESOURCE_KEY_PREFIX) && parameters.resourceInjectionType() == ResourceBundleInjectionType.GETTER
|
||||
&& parameters.fieldInjectionType() == ControllerFieldInjectionType.FACTORY) {
|
||||
progress.controllerFactoryPostAction().add(arg);
|
||||
} else {
|
||||
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.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.ParsedProperty;
|
||||
import com.github.gtache.fxml.compiler.parsing.impl.ParsedPropertyImpl;
|
||||
import javafx.scene.paint.Color;
|
||||
|
||||
import java.util.ArrayList;
|
||||
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.getSortedAttributes;
|
||||
@@ -17,17 +22,21 @@ import static java.util.Objects.requireNonNull;
|
||||
*/
|
||||
final class SceneFormatter {
|
||||
|
||||
private final HelperProvider helperProvider;
|
||||
private final GenerationProgress progress;
|
||||
private static final ParsedProperty ROOT_PROPERTY = new ParsedPropertyImpl("root", null, "");
|
||||
|
||||
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.progress = requireNonNull(progress);
|
||||
this.sb = requireNonNull(sb);
|
||||
}
|
||||
|
||||
void formatScene(final ParsedObject parsedObject, final String variableName) throws GenerationException {
|
||||
checkPropertiesAndChildren(parsedObject);
|
||||
formatDefines(parsedObject);
|
||||
final var root = findRoot(parsedObject);
|
||||
final var rootVariableName = progress.getNextVariableName("root");
|
||||
final var rootVariableName = helperProvider.getVariableProvider().getNextVariableName("root");
|
||||
helperProvider.getObjectFormatter().format(root, rootVariableName);
|
||||
final var sortedAttributes = getSortedAttributes(parsedObject);
|
||||
double width = -1;
|
||||
@@ -46,31 +55,64 @@ final class SceneFormatter {
|
||||
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(", ")
|
||||
.append(width).append(", ").append(height).append(", javafx.scene.paint.Color.valueOf(\"").append(paint).append("\"));\n");
|
||||
addStylesheets(variableName, stylesheets);
|
||||
helperProvider.getGenerationHelper().handleId(parsedObject, variableName);
|
||||
}
|
||||
|
||||
private static ParsedObject findRoot(final ParsedObject parsedObject) throws GenerationException {
|
||||
final var rootProperty = parsedObject.properties().entrySet().stream().filter(e -> e.getKey().name().equals("root"))
|
||||
.filter(e -> e.getValue().size() == 1)
|
||||
.map(e -> e.getValue().getFirst()).findFirst().orElse(null);
|
||||
if (rootProperty != null) {
|
||||
return rootProperty;
|
||||
} else if (parsedObject.children().size() == 1) {
|
||||
return parsedObject.children().getFirst();
|
||||
} else {
|
||||
throw new GenerationException("Scene must have a root");
|
||||
private void formatDefines(final ParsedObject parsedObject) throws GenerationException {
|
||||
final var objectFormatter = helperProvider.getObjectFormatter();
|
||||
for (final var define : parsedObject.children()) {
|
||||
if (define instanceof ParsedDefine) {
|
||||
objectFormatter.format(define, helperProvider.getVariableProvider().getNextVariableName("define"));
|
||||
}
|
||||
}
|
||||
for (final var define : parsedObject.properties().getOrDefault(ROOT_PROPERTY, List.of())) {
|
||||
if (define instanceof ParsedDefine) {
|
||||
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()) {
|
||||
final var urlVariables = helperProvider.getURLFormatter().formatURL(stylesheets);
|
||||
final var tmpVariable = progress.getNextVariableName("stylesheets");
|
||||
final var sb = progress.stringBuilder();
|
||||
final var tmpVariable = helperProvider.getVariableProvider().getNextVariableName("stylesheets");
|
||||
final var compatibilityHelper = helperProvider.getCompatibilityHelper();
|
||||
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");
|
||||
|
||||
@@ -76,7 +76,6 @@ final class TriangleMeshFormatter {
|
||||
setFaces(variableName, faces);
|
||||
setFaceSmoothingGroups(variableName, faceSmoothingGroups);
|
||||
setVertexFormat(variableName, vertexFormat);
|
||||
helperProvider.getGenerationHelper().handleId(parsedObject, variableName);
|
||||
} else {
|
||||
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) {
|
||||
final var splitPattern = Pattern.compile("[\\s+,]");
|
||||
final var splitPattern = Pattern.compile("\\s*,\\s*|\\s+");
|
||||
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 {
|
||||
|
||||
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.progress = requireNonNull(progress);
|
||||
this.sb = requireNonNull(sb);
|
||||
}
|
||||
|
||||
List<String> formatURL(final Iterable<String> stylesheets) {
|
||||
@@ -33,8 +33,7 @@ final class URLFormatter {
|
||||
}
|
||||
|
||||
String formatURL(final String url) {
|
||||
final var variableName = progress.getNextVariableName("url");
|
||||
final var sb = progress.stringBuilder();
|
||||
final var variableName = helperProvider.getVariableProvider().getNextVariableName("url");
|
||||
if (url.startsWith(RELATIVE_PATH_PREFIX)) {
|
||||
sb.append(getStartURL()).append(variableName).append(" = getClass().getResource(\"").append(url.substring(1)).append("\");\n");
|
||||
} else {
|
||||
@@ -62,8 +61,7 @@ final class URLFormatter {
|
||||
}
|
||||
}
|
||||
//FIXME only relative path (@) ?
|
||||
progress.stringBuilder().append(getStartURL()).append(variableName).append(" = getClass().getResource(\"").append(value).append("\");\n");
|
||||
helperProvider.getGenerationHelper().handleId(parsedObject, variableName);
|
||||
sb.append(getStartURL()).append(variableName).append(" = getClass().getResource(\"").append(value).append("\");\n");
|
||||
} else {
|
||||
throw new GenerationException("URL cannot have children or properties : " + parsedObject);
|
||||
}
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
package com.github.gtache.fxml.compiler.impl.internal;
|
||||
|
||||
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.ResourceBundleInjectionTypes;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
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 START_BACKSLASH_PATTERN = Pattern.compile("^\\\\");
|
||||
|
||||
private final InjectionType resourceInjectionType;
|
||||
private final Map<String, VariableInfo> idToVariableInfo;
|
||||
private final HelperProvider helperProvider;
|
||||
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.idToVariableInfo = requireNonNull(idToVariableInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -45,7 +43,7 @@ final class ValueFormatter {
|
||||
} else if (value.startsWith(BINDING_EXPRESSION_PREFIX)) {
|
||||
throw new GenerationException("Not implemented yet");
|
||||
} 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) {
|
||||
throw new GenerationException("Unknown variable : " + value.substring(1));
|
||||
}
|
||||
@@ -62,20 +60,15 @@ final class ValueFormatter {
|
||||
/**
|
||||
* Gets the resource bundle value for the given value
|
||||
*
|
||||
* @param value The value
|
||||
* @param value The value
|
||||
* @return The resource bundle value
|
||||
* @throws GenerationException if an error occurs
|
||||
*/
|
||||
private String getBundleValue(final String value) throws GenerationException {
|
||||
if (resourceInjectionType instanceof final ResourceBundleInjectionTypes types) {
|
||||
return switch (types) {
|
||||
case CONSTRUCTOR, GET_BUNDLE, CONSTRUCTOR_NAME -> "resourceBundle.getString(\"" + value + "\")";
|
||||
case GETTER -> "controller.resources().getString(\"" + value + "\")";
|
||||
case CONSTRUCTOR_FUNCTION -> "resourceBundleFunction.apply(\"" + value + "\")";
|
||||
};
|
||||
} else {
|
||||
throw new GenerationException("Unknown resource bundle injection type : " + resourceInjectionType);
|
||||
}
|
||||
private String getBundleValue(final String value) {
|
||||
return switch (resourceInjectionType) {
|
||||
case CONSTRUCTOR, GET_BUNDLE, CONSTRUCTOR_NAME -> "resourceBundle.getString(\"" + value + "\")";
|
||||
case GETTER -> "controller.resources().getString(\"" + value + "\")";
|
||||
case CONSTRUCTOR_FUNCTION -> "resourceBundleFunction.apply(\"" + value + "\")";
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -86,7 +79,7 @@ final class ValueFormatter {
|
||||
* @param clazz The value class
|
||||
* @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) {
|
||||
return "\"" + START_BACKSLASH_PATTERN.matcher(value).replaceAll("").replace("\\", "\\\\")
|
||||
.replace("\"", "\\\"") + "\"";
|
||||
|
||||
@@ -13,7 +13,15 @@ import java.util.Objects;
|
||||
* @param className The class name of the variable
|
||||
*/
|
||||
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 {
|
||||
Objects.requireNonNull(id);
|
||||
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 {
|
||||
|
||||
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.progress = requireNonNull(progress);
|
||||
this.sb = requireNonNull(sb);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -32,15 +32,13 @@ final class WebViewFormatter {
|
||||
void formatWebView(final ParsedObject parsedObject, final String variableName) throws GenerationException {
|
||||
if (parsedObject.children().isEmpty() && parsedObject.properties().isEmpty()) {
|
||||
final var sortedAttributes = getSortedAttributes(parsedObject);
|
||||
final var sb = progress.stringBuilder();
|
||||
final var compatibilityHelper = helperProvider.getCompatibilityHelper();
|
||||
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");
|
||||
for (final var value : sortedAttributes) {
|
||||
formatAttribute(value, parsedObject, variableName, engineVariable);
|
||||
}
|
||||
helperProvider.getGenerationHelper().handleId(parsedObject, variableName);
|
||||
} else {
|
||||
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) {
|
||||
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}
|
||||
*
|
||||
* @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 {
|
||||
|
||||
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 {
|
||||
Objects.requireNonNull(className);
|
||||
if (!attributes.containsKey(FX_CONSTANT)) {
|
||||
throw new IllegalArgumentException("Missing " + FX_CONSTANT);
|
||||
}
|
||||
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}
|
||||
*
|
||||
* @param attributes The reference properties
|
||||
* @param attributes The copy attributes
|
||||
*/
|
||||
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 {
|
||||
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}
|
||||
*
|
||||
* @param className The object class
|
||||
* @param attributes The object properties
|
||||
* @param properties The object children (complex properties)
|
||||
* @param children The objects in this define
|
||||
*/
|
||||
public record ParsedDefineImpl(List<ParsedObject> children) implements ParsedDefine {
|
||||
|
||||
/**
|
||||
* Instantiates the define
|
||||
* @param children The children
|
||||
* @throws NullPointerException If the children are null
|
||||
*/
|
||||
public ParsedDefineImpl {
|
||||
children = List.copyOf(children);
|
||||
}
|
||||
|
||||
@@ -13,13 +13,23 @@ import java.util.SequencedCollection;
|
||||
* Implementation of {@link ParsedFactory}
|
||||
*
|
||||
* @param className The factory class
|
||||
* @param attributes The factory properties
|
||||
* @param attributes The factory attributes
|
||||
* @param arguments The factory arguments
|
||||
* @param children The factory children
|
||||
*/
|
||||
public record ParsedFactoryImpl(String className, Map<String, ParsedProperty> attributes,
|
||||
SequencedCollection<ParsedObject> arguments,
|
||||
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 {
|
||||
Objects.requireNonNull(className);
|
||||
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.ParsedProperty;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Implementation of {@link ParsedInclude}
|
||||
*
|
||||
* @param attributes The object properties
|
||||
* @param attributes The include attributes
|
||||
*/
|
||||
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 {
|
||||
if (!attributes.containsKey(SOURCE)) {
|
||||
throw new IllegalArgumentException("Missing " + SOURCE);
|
||||
}
|
||||
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}
|
||||
*
|
||||
* @param className The object class
|
||||
* @param attributes The object properties
|
||||
* @param properties The object children (complex properties)
|
||||
* @param attributes The object attributes
|
||||
* @param properties The object properties
|
||||
* @param children The object children
|
||||
*/
|
||||
public record ParsedObjectImpl(String className, Map<String, ParsedProperty> attributes,
|
||||
SequencedMap<ParsedProperty, SequencedCollection<ParsedObject>> properties,
|
||||
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 {
|
||||
Objects.requireNonNull(className);
|
||||
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 java.util.Objects;
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
/**
|
||||
* Implementation of {@link ParsedProperty}
|
||||
@@ -10,11 +10,18 @@ import java.util.Objects;
|
||||
* @param name The property name
|
||||
* @param sourceType The property source type
|
||||
* @param value The property value
|
||||
* @param defines The property defines
|
||||
*/
|
||||
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 {
|
||||
Objects.requireNonNull(name);
|
||||
requireNonNull(name);
|
||||
requireNonNull(value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,11 +8,33 @@ import java.util.Map;
|
||||
/**
|
||||
* Implementation of {@link ParsedReference}
|
||||
*
|
||||
* @param attributes The reference properties
|
||||
* @param attributes The reference attributes
|
||||
*/
|
||||
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 {
|
||||
if (!attributes.containsKey(SOURCE)) {
|
||||
throw new IllegalArgumentException("Missing " + SOURCE);
|
||||
}
|
||||
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 {
|
||||
|
||||
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 {
|
||||
Objects.requireNonNull(className);
|
||||
if (!attributes.containsKey(FX_VALUE)) {
|
||||
throw new IllegalArgumentException("Missing " + FX_VALUE);
|
||||
}
|
||||
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 javafx.graphics;
|
||||
requires org.apache.logging.log4j;
|
||||
requires java.sql;
|
||||
|
||||
exports com.github.gtache.fxml.compiler.impl;
|
||||
exports com.github.gtache.fxml.compiler.parsing.impl;
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
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.InjectionType;
|
||||
import com.github.gtache.fxml.compiler.ResourceBundleInjectionType;
|
||||
import com.github.gtache.fxml.compiler.compatibility.GenerationCompatibility;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
@@ -20,15 +23,15 @@ class TestGenerationParametersImpl {
|
||||
private final GenerationCompatibility compatibility;
|
||||
private final boolean useImageInputStreamConstructor;
|
||||
private final Map<String, String> bundleMap;
|
||||
private final InjectionType controllerInjectionType;
|
||||
private final InjectionType fieldInjectionType;
|
||||
private final InjectionType methodInjectionType;
|
||||
private final InjectionType resourceInjectionType;
|
||||
private final ControllerInjectionType controllerInjectionType;
|
||||
private final ControllerFieldInjectionType fieldInjectionType;
|
||||
private final ControllerMethodsInjectionType methodInjectionType;
|
||||
private final ResourceBundleInjectionType resourceInjectionType;
|
||||
private final GenerationParameters parameters;
|
||||
|
||||
TestGenerationParametersImpl(@Mock final GenerationCompatibility compatibility, @Mock final InjectionType controllerInjectionType,
|
||||
@Mock final InjectionType fieldInjectionType, @Mock final InjectionType methodInjectionType,
|
||||
@Mock final InjectionType resourceInjectionType) {
|
||||
TestGenerationParametersImpl(@Mock final GenerationCompatibility compatibility, @Mock final ControllerInjectionType controllerInjectionType,
|
||||
@Mock final ControllerFieldInjectionType fieldInjectionType, @Mock final ControllerMethodsInjectionType methodInjectionType,
|
||||
@Mock final ResourceBundleInjectionType resourceInjectionType) {
|
||||
this.compatibility = requireNonNull(compatibility);
|
||||
this.useImageInputStreamConstructor = true;
|
||||
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;
|
||||
|
||||
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.mockito.Mock;
|
||||
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)
|
||||
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;
|
||||
|
||||
import com.github.gtache.fxml.compiler.ControllerFieldInjectionType;
|
||||
import com.github.gtache.fxml.compiler.ControllerInfo;
|
||||
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.ControllerMethodsInjectionType;
|
||||
import com.github.gtache.fxml.compiler.ControllerMethodsInjectionType;
|
||||
import com.github.gtache.fxml.compiler.parsing.ParsedProperty;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -17,7 +15,6 @@ import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
@@ -49,8 +46,8 @@ class TestControllerInjector {
|
||||
}
|
||||
|
||||
@Test
|
||||
void testInjectControllerFieldFactory() throws GenerationException {
|
||||
final var injector = new ControllerInjector(controllerInfo, ControllerFieldInjectionTypes.FACTORY, ControllerMethodsInjectionType.REFERENCE, sb, controllerFactoryPostAction);
|
||||
void testInjectControllerFieldFactory() {
|
||||
final var injector = new ControllerInjector(controllerInfo, ControllerFieldInjectionType.FACTORY, ControllerMethodsInjectionType.REFERENCE, sb, controllerFactoryPostAction);
|
||||
injector.injectControllerField(id, variable);
|
||||
final var expected = " fieldMap.put(\"" + id + "\", " + variable + ");\n";
|
||||
assertEquals(expected, sb.toString());
|
||||
@@ -58,8 +55,8 @@ class TestControllerInjector {
|
||||
}
|
||||
|
||||
@Test
|
||||
void testInjectControllerFieldAssign() throws GenerationException {
|
||||
final var injector = new ControllerInjector(controllerInfo, ControllerFieldInjectionTypes.ASSIGN, ControllerMethodsInjectionType.REFERENCE, sb, controllerFactoryPostAction);
|
||||
void testInjectControllerFieldAssign() {
|
||||
final var injector = new ControllerInjector(controllerInfo, ControllerFieldInjectionType.ASSIGN, com.github.gtache.fxml.compiler.ControllerMethodsInjectionType.REFERENCE, sb, controllerFactoryPostAction);
|
||||
injector.injectControllerField(id, variable);
|
||||
final var expected = " controller." + id + " = " + variable + ";\n";
|
||||
assertEquals(expected, sb.toString());
|
||||
@@ -67,8 +64,8 @@ class TestControllerInjector {
|
||||
}
|
||||
|
||||
@Test
|
||||
void testInjectControllerFieldSetters() throws GenerationException {
|
||||
final var injector = new ControllerInjector(controllerInfo, ControllerFieldInjectionTypes.SETTERS, ControllerMethodsInjectionType.REFERENCE, sb, controllerFactoryPostAction);
|
||||
void testInjectControllerFieldSetters() {
|
||||
final var injector = new ControllerInjector(controllerInfo, ControllerFieldInjectionType.SETTERS, com.github.gtache.fxml.compiler.ControllerMethodsInjectionType.REFERENCE, sb, controllerFactoryPostAction);
|
||||
injector.injectControllerField(id, variable);
|
||||
final var expected = " controller." + GenerationHelper.getSetMethod(id) + "(" + variable + ");\n";
|
||||
assertEquals(expected, sb.toString());
|
||||
@@ -76,8 +73,8 @@ class TestControllerInjector {
|
||||
}
|
||||
|
||||
@Test
|
||||
void testInjectControllerFieldReflection() throws GenerationException {
|
||||
final var injector = new ControllerInjector(controllerInfo, ControllerFieldInjectionTypes.REFLECTION, ControllerMethodsInjectionType.REFERENCE, sb, controllerFactoryPostAction);
|
||||
void testInjectControllerFieldReflection() {
|
||||
final var injector = new ControllerInjector(controllerInfo, ControllerFieldInjectionType.REFLECTION, com.github.gtache.fxml.compiler.ControllerMethodsInjectionType.REFERENCE, sb, controllerFactoryPostAction);
|
||||
injector.injectControllerField(id, variable);
|
||||
final var expected = " injectField(\"" + id + "\", " + variable + ");\n";
|
||||
assertEquals(expected, sb.toString());
|
||||
@@ -85,14 +82,8 @@ class TestControllerInjector {
|
||||
}
|
||||
|
||||
@Test
|
||||
void testInjectControllerFieldUnknown() {
|
||||
final var injector = new ControllerInjector(controllerInfo, mock(InjectionType.class), 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);
|
||||
void testInjectEventHandlerReferenceFactoryNoArgument() {
|
||||
final var injector = new ControllerInjector(controllerInfo, ControllerFieldInjectionType.FACTORY, com.github.gtache.fxml.compiler.ControllerMethodsInjectionType.REFERENCE, sb, controllerFactoryPostAction);
|
||||
injector.injectEventHandlerControllerMethod(property, variable);
|
||||
final var expected = " " + variable + "." + GenerationHelper.getSetMethod(property.name()) + "(e -> controller." + property.value().replace("#", "") + "());\n";
|
||||
assertEquals(1, controllerFactoryPostAction.size());
|
||||
@@ -101,8 +92,8 @@ class TestControllerInjector {
|
||||
}
|
||||
|
||||
@Test
|
||||
void testInjectEventHandlerReferenceFactoryWithArgument() throws GenerationException {
|
||||
final var injector = new ControllerInjector(controllerInfo, ControllerFieldInjectionTypes.FACTORY, ControllerMethodsInjectionType.REFERENCE, sb, controllerFactoryPostAction);
|
||||
void testInjectEventHandlerReferenceFactoryWithArgument() {
|
||||
final var injector = new ControllerInjector(controllerInfo, ControllerFieldInjectionType.FACTORY, com.github.gtache.fxml.compiler.ControllerMethodsInjectionType.REFERENCE, sb, controllerFactoryPostAction);
|
||||
when(controllerInfo.handlerHasArgument(propertyValue.replace("#", ""))).thenReturn(true);
|
||||
injector.injectEventHandlerControllerMethod(property, variable);
|
||||
final var expected = " " + variable + "." + GenerationHelper.getSetMethod(property.name()) + "(controller::" + propertyValue.replace("#", "") + ");\n";
|
||||
@@ -112,8 +103,8 @@ class TestControllerInjector {
|
||||
}
|
||||
|
||||
@Test
|
||||
void testInjectEventHandlerReflectionAssign() throws GenerationException {
|
||||
final var injector = new ControllerInjector(controllerInfo, ControllerFieldInjectionTypes.ASSIGN, ControllerMethodsInjectionType.REFLECTION, sb, controllerFactoryPostAction);
|
||||
void testInjectEventHandlerReflectionAssign() {
|
||||
final var injector = new ControllerInjector(controllerInfo, ControllerFieldInjectionType.ASSIGN, com.github.gtache.fxml.compiler.ControllerMethodsInjectionType.REFLECTION, sb, controllerFactoryPostAction);
|
||||
injector.injectEventHandlerControllerMethod(property, variable);
|
||||
final var expected = " " + variable + "." + GenerationHelper.getSetMethod(property.name()) + "(e -> callEventHandlerMethod(\"" + propertyValue.replace("#", "") + "\", e));\n";
|
||||
assertEquals(expected, sb.toString());
|
||||
@@ -121,20 +112,8 @@ class TestControllerInjector {
|
||||
}
|
||||
|
||||
@Test
|
||||
void testInjectEventHandlerUnknownMethod() {
|
||||
final var injector = new ControllerInjector(controllerInfo, ControllerFieldInjectionTypes.ASSIGN, mock(InjectionType.class), 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);
|
||||
void testInjectCallbackReflectionSetters() {
|
||||
final var injector = new ControllerInjector(controllerInfo, ControllerFieldInjectionType.ASSIGN, com.github.gtache.fxml.compiler.ControllerMethodsInjectionType.REFLECTION, sb, controllerFactoryPostAction);
|
||||
injector.injectCallbackControllerMethod(property, variable, "clazz");
|
||||
final var expected = " " + variable + "." + GenerationHelper.getSetMethod(property.name()) + "(e -> callCallbackMethod(\"" + propertyValue.replace("#", "") + "\", e, clazz));\n";
|
||||
assertEquals(expected, sb.toString());
|
||||
@@ -142,12 +121,21 @@ class TestControllerInjector {
|
||||
}
|
||||
|
||||
@Test
|
||||
void testInjectCallbackReferenceFactory() throws GenerationException {
|
||||
final var injector = new ControllerInjector(controllerInfo, ControllerFieldInjectionTypes.FACTORY, ControllerMethodsInjectionType.REFERENCE, sb, controllerFactoryPostAction);
|
||||
void testInjectCallbackReferenceFactory() {
|
||||
final var injector = new ControllerInjector(controllerInfo, ControllerFieldInjectionType.FACTORY, com.github.gtache.fxml.compiler.ControllerMethodsInjectionType.REFERENCE, sb, controllerFactoryPostAction);
|
||||
injector.injectCallbackControllerMethod(property, variable, "clazz");
|
||||
final var expected = " " + variable + "." + GenerationHelper.getSetMethod(property.name()) + "(controller::" + propertyValue.replace("#", "") + ");\n";
|
||||
assertEquals(1, controllerFactoryPostAction.size());
|
||||
assertEquals(expected, controllerFactoryPostAction.getFirst());
|
||||
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;
|
||||
|
||||
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.mockito.Mock;
|
||||
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)
|
||||
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;
|
||||
|
||||
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.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import 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)
|
||||
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 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.when;
|
||||
|
||||
@@ -123,4 +124,10 @@ class TestGenerationCompatibilityHelper {
|
||||
when(compatibility.useCollectionsOf()).thenReturn(false);
|
||||
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;
|
||||
|
||||
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.ParsedProperty;
|
||||
import com.github.gtache.fxml.compiler.parsing.impl.ParsedPropertyImpl;
|
||||
@@ -23,29 +20,15 @@ import static org.mockito.Mockito.when;
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class TestGenerationHelper {
|
||||
|
||||
private final GenerationProgress progress;
|
||||
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 ParsedObject parsedObject;
|
||||
private final Map<String, ParsedProperty> attributes;
|
||||
private final String className;
|
||||
private final ParsedProperty property;
|
||||
private final String propertyName;
|
||||
|
||||
TestGenerationHelper(@Mock final GenerationProgress progress, @Mock final GenerationRequest request,
|
||||
@Mock final ControllerInfo controllerInfo, @Mock final ControllerFieldInfo fieldInfo,
|
||||
@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);
|
||||
TestGenerationHelper(@Mock final ParsedObject parsedObject, @Mock final ParsedProperty property) {
|
||||
this.parsedObject = Objects.requireNonNull(parsedObject);
|
||||
this.property = Objects.requireNonNull(property);
|
||||
this.idToVariableInfo = new HashMap<>();
|
||||
this.variableName = "variable";
|
||||
this.attributes = new HashMap<>();
|
||||
this.className = "java.lang.String";
|
||||
this.propertyName = "property";
|
||||
@@ -53,17 +36,14 @@ class TestGenerationHelper {
|
||||
|
||||
@BeforeEach
|
||||
void beforeEach() {
|
||||
when(progress.request()).thenReturn(request);
|
||||
when(request.controllerInfo()).thenReturn(controllerInfo);
|
||||
when(object.attributes()).thenReturn(attributes);
|
||||
when(object.className()).thenReturn(className);
|
||||
when(parsedObject.attributes()).thenReturn(attributes);
|
||||
when(parsedObject.className()).thenReturn(className);
|
||||
when(property.name()).thenReturn(propertyName);
|
||||
when(progress.idToVariableInfo()).thenReturn(idToVariableInfo);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetVariablePrefixObject() {
|
||||
assertEquals("string", GenerationHelper.getVariablePrefix(object));
|
||||
assertEquals("string", GenerationHelper.getVariablePrefix(parsedObject));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -97,6 +77,6 @@ class TestGenerationHelper {
|
||||
attributes.put("b", new ParsedPropertyImpl("b", null, "valueB"));
|
||||
attributes.put("c", new ParsedPropertyImpl("c", null, "valueC"));
|
||||
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 java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.SequencedCollection;
|
||||
import java.util.SequencedMap;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
@@ -23,51 +18,27 @@ import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
class TestGenerationProgress {
|
||||
|
||||
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 StringBuilder sb;
|
||||
private final GenerationProgress progress;
|
||||
|
||||
TestGenerationProgress(@Mock final GenerationRequest request, @Mock final VariableInfo variableInfo) {
|
||||
TestGenerationProgress(@Mock final GenerationRequest 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<>();
|
||||
controllerFactoryPostAction.add("bla");
|
||||
this.sb = new StringBuilder("test");
|
||||
this.progress = new GenerationProgress(request, idToVariableInfo, variableNameCounters, controllerClassToVariable, controllerFactoryPostAction, sb);
|
||||
this.progress = new GenerationProgress(request, controllerFactoryPostAction, sb);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetters() {
|
||||
assertEquals(request, progress.request());
|
||||
assertEquals(idToVariableInfo, progress.idToVariableInfo());
|
||||
assertEquals(variableNameCounters, progress.variableNameCounters());
|
||||
assertEquals(controllerClassToVariable, progress.controllerClassToVariable());
|
||||
assertEquals(controllerFactoryPostAction, progress.controllerFactoryPostAction());
|
||||
assertEquals(sb, progress.stringBuilder());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testConstructorDoesntCopy() {
|
||||
idToVariableInfo.clear();
|
||||
assertEquals(idToVariableInfo, progress.idToVariableInfo());
|
||||
|
||||
variableNameCounters.clear();
|
||||
assertEquals(variableNameCounters, progress.variableNameCounters());
|
||||
|
||||
controllerClassToVariable.clear();
|
||||
assertEquals(controllerClassToVariable, progress.controllerClassToVariable());
|
||||
|
||||
controllerFactoryPostAction.clear();
|
||||
assertEquals(controllerFactoryPostAction, progress.controllerFactoryPostAction());
|
||||
|
||||
@@ -77,15 +48,6 @@ class TestGenerationProgress {
|
||||
|
||||
@Test
|
||||
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");
|
||||
assertEquals(controllerFactoryPostAction, progress.controllerFactoryPostAction());
|
||||
|
||||
@@ -97,29 +59,15 @@ class TestGenerationProgress {
|
||||
void testOtherConstructor() {
|
||||
final var progress2 = new GenerationProgress(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("", 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
|
||||
void testIllegal() {
|
||||
assertThrows(NullPointerException.class, () -> new GenerationProgress(null, idToVariableInfo, variableNameCounters, controllerClassToVariable, controllerFactoryPostAction, sb));
|
||||
assertThrows(NullPointerException.class, () -> new GenerationProgress(request, null, variableNameCounters, controllerClassToVariable, controllerFactoryPostAction, sb));
|
||||
assertThrows(NullPointerException.class, () -> new GenerationProgress(request, idToVariableInfo, null, controllerClassToVariable, controllerFactoryPostAction, sb));
|
||||
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));
|
||||
assertThrows(NullPointerException.class, () -> new GenerationProgress(null, controllerFactoryPostAction, sb));
|
||||
assertThrows(NullPointerException.class, () -> new GenerationProgress(request, null, sb));
|
||||
assertThrows(NullPointerException.class, () -> new GenerationProgress(request, controllerFactoryPostAction, null));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,8 +1,217 @@
|
||||
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.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.assertThrows;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
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;
|
||||
|
||||
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.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import 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)
|
||||
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;
|
||||
|
||||
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.GenerationParameters;
|
||||
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.parsing.ParsedInclude;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
@@ -12,51 +16,577 @@ import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import java.util.HashMap;
|
||||
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.anyString;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class TestInitializationFormatter {
|
||||
|
||||
private final GenerationProgress progress;
|
||||
private final GenerationRequest request;
|
||||
private final GenerationParameters parameters;
|
||||
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 ParsedInclude include;
|
||||
private final Map<String, SourceInfo> sourceToSourceInfo;
|
||||
private final StringBuilder sb;
|
||||
private final Map<String, String> controllerClassToVariable;
|
||||
private final InitializationFormatter initializationFormatter;
|
||||
|
||||
|
||||
TestInitializationFormatter(@Mock final GenerationProgress progress, @Mock final GenerationRequest request,
|
||||
@Mock final GenerationParameters parameters, @Mock final HelperProvider helperProvider,
|
||||
@Mock final SourceInfo sourceInfo, @Mock final ParsedInclude include) {
|
||||
this.progress = Objects.requireNonNull(progress);
|
||||
TestInitializationFormatter(@Mock final GenerationRequest request, @Mock final GenerationParameters parameters, @Mock final GenerationCompatibilityHelper compatibilityHelper,
|
||||
@Mock final HelperProvider helperProvider, @Mock final VariableProvider variableProvider,
|
||||
@Mock final ControllerInfo controllerInfo, @Mock final SourceInfo sourceInfo,
|
||||
@Mock final ParsedInclude include) {
|
||||
this.request = Objects.requireNonNull(request);
|
||||
this.parameters = Objects.requireNonNull(parameters);
|
||||
this.stringBuilder = new StringBuilder();
|
||||
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.include = Objects.requireNonNull(include);
|
||||
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
|
||||
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(progress.request()).thenReturn(request);
|
||||
when(progress.stringBuilder()).thenReturn(stringBuilder);
|
||||
when(request.outputClassName()).thenReturn("com.github.gtache.fxml.OutputClassName");
|
||||
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(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
|
||||
void testFormatSubViewConstructorCallNullSubInfo() {
|
||||
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;
|
||||
|
||||
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.mockito.Mock;
|
||||
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)
|
||||
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;
|
||||
|
||||
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.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import 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)
|
||||
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;
|
||||
|
||||
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.mockito.Mock;
|
||||
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)
|
||||
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("p17", new Parameter("p17", String.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 actual = ReflectionHelper.getConstructorArgs(defaultConstructor);
|
||||
assertEquals(expected, actual);
|
||||
@@ -132,7 +132,7 @@ class TestReflectionHelper {
|
||||
parameters.put("p13", new Parameter("p13", float.class, "5.5"));
|
||||
parameters.put("p15", new Parameter("p15", double.class, "6.6"));
|
||||
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 actual = ReflectionHelper.getConstructorArgs(constructor);
|
||||
assertEquals(expected, actual);
|
||||
@@ -140,7 +140,7 @@ class TestReflectionHelper {
|
||||
|
||||
@Test
|
||||
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 actual = ReflectionHelper.getConstructorArgs(constructor);
|
||||
assertEquals(expected, actual);
|
||||
@@ -148,7 +148,7 @@ class TestReflectionHelper {
|
||||
|
||||
@Test
|
||||
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));
|
||||
}
|
||||
|
||||
@@ -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())));
|
||||
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;
|
||||
|
||||
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.mockito.Mock;
|
||||
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)
|
||||
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;
|
||||
|
||||
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.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import 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)
|
||||
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.assertThrows;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.Mockito.*;
|
||||
import static org.mockito.Mockito.anyString;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class TestURLFormatter {
|
||||
|
||||
private final HelperProvider helperProvider;
|
||||
private final GenerationHelper generationHelper;
|
||||
private final GenerationCompatibilityHelper compatibilityHelper;
|
||||
private final VariableProvider variableProvider;
|
||||
private final ParsedObject parsedObject;
|
||||
private final String variableName;
|
||||
private final StringBuilder sb;
|
||||
private final GenerationProgress progress;
|
||||
private final URLFormatter urlFormatter;
|
||||
|
||||
TestURLFormatter(@Mock final HelperProvider helperProvider, @Mock final GenerationHelper generationHelper,
|
||||
@Mock final GenerationCompatibilityHelper compatibilityHelper, @Mock final ParsedObject parsedObject,
|
||||
@Mock final GenerationProgress progress) {
|
||||
TestURLFormatter(@Mock final HelperProvider helperProvider, @Mock final VariableProvider variableProvider,
|
||||
@Mock final GenerationCompatibilityHelper compatibilityHelper, @Mock final ParsedObject parsedObject) {
|
||||
this.helperProvider = Objects.requireNonNull(helperProvider);
|
||||
this.generationHelper = Objects.requireNonNull(generationHelper);
|
||||
this.variableProvider = Objects.requireNonNull(variableProvider);
|
||||
this.compatibilityHelper = Objects.requireNonNull(compatibilityHelper);
|
||||
this.parsedObject = Objects.requireNonNull(parsedObject);
|
||||
this.progress = Objects.requireNonNull(progress);
|
||||
this.sb = new StringBuilder();
|
||||
this.variableName = "variable";
|
||||
this.urlFormatter = new URLFormatter(helperProvider, progress);
|
||||
this.urlFormatter = new URLFormatter(helperProvider, sb);
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
void beforeEach() throws GenerationException {
|
||||
when(helperProvider.getCompatibilityHelper()).thenReturn(compatibilityHelper);
|
||||
when(helperProvider.getGenerationHelper()).thenReturn(generationHelper);
|
||||
when(progress.stringBuilder()).thenReturn(sb);
|
||||
when(progress.getNextVariableName("url")).thenReturn("url1", "url2");
|
||||
when(helperProvider.getVariableProvider()).thenReturn(variableProvider);
|
||||
when(variableProvider.getNextVariableName("url")).thenReturn("url1", "url2");
|
||||
when(compatibilityHelper.getStartVar(anyString())).then(i -> i.getArgument(0));
|
||||
when(parsedObject.children()).thenReturn(List.of());
|
||||
when(parsedObject.properties()).thenReturn(new LinkedHashMap<>());
|
||||
doAnswer(i -> sb.append("handleId")).when(generationHelper).handleId(any(), anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFormatURLSheets() {
|
||||
final var styleSheets = List.of("style1.css", "@style2.css");
|
||||
final var expected = " final java.net.URL url1;\n" +
|
||||
" try {\n" +
|
||||
" url1 = new java.net.URI(\"style1.css\").toURL();\n" +
|
||||
" } catch (final java.net.MalformedURLException | java.net.URISyntaxException e) {\n" +
|
||||
" throw new RuntimeException(\"Couldn't parse url : style1.css\", e);\n" +
|
||||
" }\njava.net.URLurl2 = getClass().getResource(\"style2.css\");\n";
|
||||
final var expected = """
|
||||
final java.net.URL url1;
|
||||
try {
|
||||
url1 = new java.net.URI("style1.css").toURL();
|
||||
} catch (final java.net.MalformedURLException | java.net.URISyntaxException e) {
|
||||
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(expected, sb.toString());
|
||||
}
|
||||
@@ -80,7 +78,7 @@ class TestURLFormatter {
|
||||
@Test
|
||||
void testFormatURLObjectProperties() {
|
||||
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);
|
||||
assertThrows(GenerationException.class, () -> urlFormatter.formatURL(parsedObject, variableName));
|
||||
}
|
||||
@@ -101,8 +99,13 @@ class TestURLFormatter {
|
||||
when(parsedObject.attributes()).thenReturn(attributes);
|
||||
|
||||
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());
|
||||
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;
|
||||
|
||||
import com.github.gtache.fxml.compiler.GenerationException;
|
||||
import com.github.gtache.fxml.compiler.InjectionType;
|
||||
import com.github.gtache.fxml.compiler.impl.ResourceBundleInjectionTypes;
|
||||
import com.github.gtache.fxml.compiler.ResourceBundleInjectionType;
|
||||
import javafx.geometry.Pos;
|
||||
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.net.URL;
|
||||
import java.util.HashMap;
|
||||
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.assertThrows;
|
||||
import static org.mockito.Mockito.mock;
|
||||
@@ -23,39 +21,40 @@ import static org.mockito.Mockito.when;
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class TestValueFormatter {
|
||||
|
||||
private final Map<String, VariableInfo> idToVariableInfo;
|
||||
private final InjectionType resourceInjectionType;
|
||||
private final HelperProvider helperProvider;
|
||||
private final VariableProvider variableProvider;
|
||||
private final ValueFormatter formatter;
|
||||
|
||||
TestValueFormatter(@Mock final InjectionType resourceInjectionType) {
|
||||
this.resourceInjectionType = requireNonNull(resourceInjectionType);
|
||||
this.idToVariableInfo = new HashMap<>();
|
||||
this.formatter = new ValueFormatter(resourceInjectionType, idToVariableInfo);
|
||||
TestValueFormatter(@Mock final HelperProvider helperProvider, @Mock final VariableProvider variableProvider,
|
||||
@Mock final ResourceBundleInjectionType resourceInjectionType) {
|
||||
this.helperProvider = Objects.requireNonNull(helperProvider);
|
||||
this.variableProvider = Objects.requireNonNull(variableProvider);
|
||||
this.formatter = new ValueFormatter(helperProvider, resourceInjectionType);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetArgStringResourceUnknown() {
|
||||
assertThrows(GenerationException.class, () -> formatter.getArg("%value", String.class));
|
||||
@BeforeEach
|
||||
void beforeEach() {
|
||||
when(helperProvider.getVariableProvider()).thenReturn(variableProvider);
|
||||
}
|
||||
|
||||
@Test
|
||||
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) {
|
||||
final var resourceFormatter = new ValueFormatter(type, idToVariableInfo);
|
||||
final var resourceFormatter = new ValueFormatter(helperProvider, type);
|
||||
assertEquals("resourceBundle.getString(\"value\")", resourceFormatter.getArg("%value", String.class));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
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));
|
||||
}
|
||||
|
||||
@Test
|
||||
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));
|
||||
}
|
||||
|
||||
@@ -78,8 +77,8 @@ class TestValueFormatter {
|
||||
@Test
|
||||
void testGetArgExpression() throws GenerationException {
|
||||
final var info = mock(VariableInfo.class);
|
||||
when(variableProvider.getVariableInfo("value")).thenReturn(info);
|
||||
when(info.variableName()).thenReturn("variable");
|
||||
idToVariableInfo.put("value", info);
|
||||
assertEquals("variable", formatter.getArg("$value", String.class));
|
||||
}
|
||||
|
||||
@@ -90,32 +89,32 @@ class TestValueFormatter {
|
||||
|
||||
@Test
|
||||
void testToStringString() {
|
||||
assertEquals("\"value\"", formatter.toString("value", String.class));
|
||||
assertEquals("\"value\"", ValueFormatter.toString("value", String.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
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
|
||||
void testToStringChar() {
|
||||
assertEquals("'v'", formatter.toString("v", char.class));
|
||||
assertEquals("'v'", formatter.toString("v", Character.class));
|
||||
assertEquals("'v'", ValueFormatter.toString("v", char.class));
|
||||
assertEquals("'v'", ValueFormatter.toString("v", Character.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testToStringBoolean() {
|
||||
assertEquals("true", formatter.toString("true", boolean.class));
|
||||
assertEquals("true", formatter.toString("true", Boolean.class));
|
||||
assertEquals("true", ValueFormatter.toString("true", boolean.class));
|
||||
assertEquals("true", ValueFormatter.toString("true", Boolean.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testToStringInteger() {
|
||||
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) {
|
||||
assertEquals("1", formatter.toString("1", type));
|
||||
assertEquals(ReflectionHelper.getWrapperClass(type) + ".valueOf(\"value\")", formatter.toString("value", type));
|
||||
assertEquals("1", ValueFormatter.toString("1", type));
|
||||
assertEquals(ReflectionHelper.getWrapperClass(type) + ".valueOf(\"value\")", ValueFormatter.toString("value", type));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,23 +122,29 @@ class TestValueFormatter {
|
||||
void testToStringDecimal() {
|
||||
final var types = List.of(float.class, Float.class, double.class, Double.class);
|
||||
for (final var type : types) {
|
||||
assertEquals("1.0", formatter.toString("1.0", type));
|
||||
assertEquals(ReflectionHelper.getWrapperClass(type) + ".valueOf(\"value\")", formatter.toString("value", type));
|
||||
assertEquals("1.0", ValueFormatter.toString("1.0", type));
|
||||
assertEquals(ReflectionHelper.getWrapperClass(type) + ".valueOf(\"value\")", ValueFormatter.toString("value", type));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testToStringValueOfEnum() {
|
||||
assertEquals("javafx.geometry.Pos.value", formatter.toString("value", Pos.class));
|
||||
assertEquals("javafx.geometry.Pos.value", ValueFormatter.toString("value", Pos.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
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
|
||||
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.assertThrows;
|
||||
import static org.mockito.ArgumentMatchers.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
@@ -30,35 +29,30 @@ class TestWebViewFormatter {
|
||||
private final ControllerInjector controllerInjector;
|
||||
private final FieldSetter fieldSetter;
|
||||
private final PropertyFormatter propertyFormatter;
|
||||
private final GenerationHelper generationHelper;
|
||||
private final GenerationProgress progress;
|
||||
private final VariableProvider variableProvider;
|
||||
private final ParsedObject parsedObject;
|
||||
private final String variableName;
|
||||
private final String engineVariable;
|
||||
private final ParsedProperty parsedProperty;
|
||||
private final StringBuilder sb;
|
||||
private final Map<String, ParsedProperty> attributes;
|
||||
private final WebViewFormatter webViewFormatter;
|
||||
|
||||
TestWebViewFormatter(@Mock final HelperProvider helperProvider, @Mock final GenerationCompatibilityHelper compatibilityHelper,
|
||||
@Mock final ControllerInjector controllerInjector, @Mock final FieldSetter fieldSetter,
|
||||
@Mock final PropertyFormatter propertyFormatter, @Mock final GenerationHelper generationHelper,
|
||||
@Mock final GenerationProgress progress, @Mock final ParsedObject parsedObject,
|
||||
@Mock final ParsedProperty parsedProperty) {
|
||||
@Mock final PropertyFormatter propertyFormatter, @Mock final VariableProvider variableProvider,
|
||||
@Mock final ParsedObject parsedObject) {
|
||||
this.helperProvider = Objects.requireNonNull(helperProvider);
|
||||
this.compatibilityHelper = Objects.requireNonNull(compatibilityHelper);
|
||||
this.controllerInjector = Objects.requireNonNull(controllerInjector);
|
||||
this.fieldSetter = Objects.requireNonNull(fieldSetter);
|
||||
this.propertyFormatter = Objects.requireNonNull(propertyFormatter);
|
||||
this.generationHelper = Objects.requireNonNull(generationHelper);
|
||||
this.progress = Objects.requireNonNull(progress);
|
||||
this.variableProvider = Objects.requireNonNull(variableProvider);
|
||||
this.parsedObject = Objects.requireNonNull(parsedObject);
|
||||
this.variableName = "variable";
|
||||
this.engineVariable = "engine";
|
||||
this.parsedProperty = Objects.requireNonNull(parsedProperty);
|
||||
this.sb = new StringBuilder();
|
||||
this.attributes = new HashMap<>();
|
||||
this.webViewFormatter = new WebViewFormatter(helperProvider, progress);
|
||||
this.webViewFormatter = new WebViewFormatter(helperProvider, sb);
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
@@ -68,19 +62,17 @@ class TestWebViewFormatter {
|
||||
when(helperProvider.getCompatibilityHelper()).thenReturn(compatibilityHelper);
|
||||
when(helperProvider.getControllerInjector()).thenReturn(controllerInjector);
|
||||
when(helperProvider.getFieldSetter()).thenReturn(fieldSetter);
|
||||
when(helperProvider.getGenerationHelper()).thenReturn(generationHelper);
|
||||
when(helperProvider.getPropertyFormatter()).thenReturn(propertyFormatter);
|
||||
when(helperProvider.getVariableProvider()).thenReturn(variableProvider);
|
||||
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())).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()).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());
|
||||
when(parsedObject.attributes()).thenReturn(attributes);
|
||||
|
||||
when(progress.stringBuilder()).thenReturn(sb);
|
||||
when(progress.getNextVariableName("engine")).thenReturn(engineVariable);
|
||||
when(variableProvider.getNextVariableName("engine")).thenReturn(engineVariable);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -92,7 +84,7 @@ class TestWebViewFormatter {
|
||||
@Test
|
||||
void testFormatHasProperty() {
|
||||
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);
|
||||
assertThrows(GenerationException.class, () -> webViewFormatter.formatWebView(parsedObject, variableName));
|
||||
}
|
||||
@@ -111,11 +103,13 @@ class TestWebViewFormatter {
|
||||
attributes.put("fx:id", new ParsedPropertyImpl("fx:id", null, "id"));
|
||||
|
||||
webViewFormatter.formatWebView(parsedObject, variableName);
|
||||
final var expected = "javafx.scene.web.WebViewvariable = new javafx.scene.web.WebView();\n" +
|
||||
"javafx.scene.web.WebEngineengine = variable.getEngine();\n" +
|
||||
"#confirmHandlerString.class#createPopupHandlerjavafx.scene.web.PopupFeatures.class" +
|
||||
" engine.load(\"location\");\n#onAlert#onResized#onStatusChanged#onVisibilityChanged#promptHandlerjavafx.scene.web.PromptData.class" +
|
||||
"propertyhandleId";
|
||||
final var expected = """
|
||||
javafx.scene.web.WebViewvariable = new javafx.scene.web.WebView();
|
||||
javafx.scene.web.WebEngineengine = variable.getEngine();
|
||||
#confirmHandlerString.class#createPopupHandlerjavafx.scene.web.PopupFeatures.class\
|
||||
engine.load("location");
|
||||
#onAlert#onResized#onStatusChanged#onVisibilityChanged#promptHandlerjavafx.scene.web.PromptData.class\
|
||||
property""";
|
||||
assertEquals(expected, sb.toString());
|
||||
verify(propertyFormatter).formatProperty(attributes.get("property"), parsedObject, variableName);
|
||||
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("onVisibilityChanged"), engineVariable);
|
||||
verify(controllerInjector).injectCallbackControllerMethod(attributes.get("promptHandler"), engineVariable, "javafx.scene.web.PromptData.class");
|
||||
verify(generationHelper).handleId(parsedObject, variableName);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -142,12 +135,14 @@ class TestWebViewFormatter {
|
||||
attributes.put("fx:id", new ParsedPropertyImpl("fx:id", null, "id"));
|
||||
|
||||
webViewFormatter.formatWebView(parsedObject, variableName);
|
||||
final var expected = "javafx.scene.web.WebViewvariable = new javafx.scene.web.WebView();\n" +
|
||||
"javafx.scene.web.WebEngineengine = variable.getEngine();\n" +
|
||||
"$controller.confirmHandlerjavafx.util.Callback$controller.createPopupHandlerjavafx.util.Callback" +
|
||||
" engine.load(\"location\");\n$controller.onAlert$controller.onResized$controller.onStatusChanged$controller.onVisibilityChanged" +
|
||||
"$controller.promptHandlerjavafx.util.Callback" +
|
||||
"propertyhandleId";
|
||||
final var expected = """
|
||||
javafx.scene.web.WebViewvariable = new javafx.scene.web.WebView();
|
||||
javafx.scene.web.WebEngineengine = variable.getEngine();
|
||||
$controller.confirmHandlerjavafx.util.Callback$controller.createPopupHandlerjavafx.util.Callback\
|
||||
engine.load("location");
|
||||
$controller.onAlert$controller.onResized$controller.onStatusChanged$controller.onVisibilityChanged\
|
||||
$controller.promptHandlerjavafx.util.Callback\
|
||||
property""";
|
||||
assertEquals(expected, sb.toString());
|
||||
|
||||
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("createPopupHandler"), 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;
|
||||
|
||||
public class WholeConstructorArgs {
|
||||
public WholeConstructorArgs(@NamedArg("p1") final int p1, @NamedArg("p2") final Integer p2,
|
||||
@NamedArg("p3") final char p3, @NamedArg("p4") final Character p4,
|
||||
@NamedArg("p5") final boolean p5, @NamedArg("p6") final Boolean p6,
|
||||
@NamedArg("p7") final byte p7, @NamedArg("p8") final Byte p8,
|
||||
@NamedArg("p9") final short p9, @NamedArg("p10") final Short p10,
|
||||
@NamedArg("p11") final long p11, @NamedArg("p12") final Long p12,
|
||||
@NamedArg("p13") final float p13, @NamedArg("p14") final Float p14,
|
||||
@NamedArg("p15") final double p15, @NamedArg("p16") final Double p16,
|
||||
@NamedArg("p17") final String p17, @NamedArg("p18") final Object p18) {
|
||||
class WholeConstructorArgs {
|
||||
WholeConstructorArgs(@NamedArg("p1") final int p1, @NamedArg("p2") final Integer p2,
|
||||
@NamedArg("p3") final char p3, @NamedArg("p4") final Character p4,
|
||||
@NamedArg("p5") final boolean p5, @NamedArg("p6") final Boolean p6,
|
||||
@NamedArg("p7") final byte p7, @NamedArg("p8") final Byte p8,
|
||||
@NamedArg("p9") final short p9, @NamedArg("p10") final Short p10,
|
||||
@NamedArg("p11") final long p11, @NamedArg("p12") final Long p12,
|
||||
@NamedArg("p13") final float p13, @NamedArg("p14") final Float p14,
|
||||
@NamedArg("p15") final double p15, @NamedArg("p16") final Double p16,
|
||||
@NamedArg("p17") final String p17, @NamedArg("p18") final Object p18) {
|
||||
}
|
||||
|
||||
public WholeConstructorArgs(@NamedArg(value = "p1", defaultValue = "1") final int p1,
|
||||
@NamedArg(value = "p3", defaultValue = "a") final char p3,
|
||||
@NamedArg(value = "p5", defaultValue = "true") final boolean p5,
|
||||
@NamedArg(value = "p7", defaultValue = "2") final byte p7,
|
||||
@NamedArg(value = "p9", defaultValue = "3") final short p9,
|
||||
@NamedArg(value = "p11", defaultValue = "4") final long p11,
|
||||
@NamedArg(value = "p13", defaultValue = "5.5") final float p13,
|
||||
@NamedArg(value = "p15", defaultValue = "6.6") final double p15,
|
||||
@NamedArg(value = "p17", defaultValue = "str") final String p17) {
|
||||
WholeConstructorArgs(@NamedArg(value = "p1", defaultValue = "1") final int p1,
|
||||
@NamedArg(value = "p3", defaultValue = "a") final char p3,
|
||||
@NamedArg(value = "p5", defaultValue = "true") final boolean p5,
|
||||
@NamedArg(value = "p7", defaultValue = "2") final byte p7,
|
||||
@NamedArg(value = "p9", defaultValue = "3") final short p9,
|
||||
@NamedArg(value = "p11", defaultValue = "4") final long p11,
|
||||
@NamedArg(value = "p13", defaultValue = "5.5") final float p13,
|
||||
@NamedArg(value = "p15", defaultValue = "6.6") final double p15,
|
||||
@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() {
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -43,9 +43,19 @@ class TestParsedConstantImpl {
|
||||
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
|
||||
void testIllegal() {
|
||||
final var emptyMap = Map.<String, ParsedProperty>of();
|
||||
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 java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.SequencedMap;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
@@ -20,7 +21,7 @@ class TestParsedCopyImpl {
|
||||
|
||||
TestParsedCopyImpl(@Mock final ParsedProperty property) {
|
||||
this.properties = new LinkedHashMap<>();
|
||||
this.properties.put("name", property);
|
||||
this.properties.put("source", property);
|
||||
this.copy = new ParsedCopyImpl(properties);
|
||||
}
|
||||
|
||||
@@ -45,8 +46,16 @@ class TestParsedCopyImpl {
|
||||
assertThrows(UnsupportedOperationException.class, objectProperties::clear);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testOtherConstructor() {
|
||||
final var otherCopy = new ParsedCopyImpl("source");
|
||||
assertEquals("source", otherCopy.source());
|
||||
}
|
||||
|
||||
@Test
|
||||
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 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.parsedDefine = new ParsedDefineImpl(children);
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.SequencedMap;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
@@ -20,7 +21,7 @@ class TestParsedIncludeImpl {
|
||||
|
||||
TestParsedIncludeImpl(@Mock final ParsedProperty property) {
|
||||
this.properties = new LinkedHashMap<>();
|
||||
this.properties.put("name", property);
|
||||
this.properties.put("source", property);
|
||||
this.include = new ParsedIncludeImpl(properties);
|
||||
}
|
||||
|
||||
@@ -45,8 +46,21 @@ class TestParsedIncludeImpl {
|
||||
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
|
||||
void testIllegal() {
|
||||
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.put("name", property);
|
||||
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.parsedObject = new ParsedObjectImpl(clazz, attributes, properties, objects);
|
||||
}
|
||||
|
||||
@@ -30,6 +30,6 @@ class TestParsedPropertyImpl {
|
||||
void testIllegal() {
|
||||
assertThrows(NullPointerException.class, () -> new ParsedPropertyImpl(null, sourceType, 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 java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.SequencedMap;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
@@ -20,7 +21,7 @@ class TestParsedReferenceImpl {
|
||||
|
||||
TestParsedReferenceImpl(@Mock final ParsedProperty property) {
|
||||
this.properties = new LinkedHashMap<>();
|
||||
this.properties.put("name", property);
|
||||
this.properties.put("source", property);
|
||||
this.reference = new ParsedReferenceImpl(properties);
|
||||
}
|
||||
|
||||
@@ -45,8 +46,16 @@ class TestParsedReferenceImpl {
|
||||
assertThrows(UnsupportedOperationException.class, objectProperties::clear);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testOtherConstructor() {
|
||||
final var otherReference = new ParsedReferenceImpl("name");
|
||||
assertEquals("name", otherReference.source());
|
||||
}
|
||||
|
||||
@Test
|
||||
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() {
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -43,9 +43,19 @@ class TestParsedValueImpl {
|
||||
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
|
||||
void testIllegal() {
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user