diff --git a/core/src/main/java/de/neitzel/core/commandline/Parameter.java b/core/src/main/java/de/neitzel/core/commandline/Parameter.java index f47ee86..5875f89 100644 --- a/core/src/main/java/de/neitzel/core/commandline/Parameter.java +++ b/core/src/main/java/de/neitzel/core/commandline/Parameter.java @@ -1,7 +1,9 @@ package de.neitzel.core.commandline; -import lombok.*; -import lombok.extern.log4j.Log4j; +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; +import lombok.Singular; import lombok.extern.slf4j.Slf4j; import java.util.List; diff --git a/core/src/main/java/de/neitzel/core/config/Configuration.java b/core/src/main/java/de/neitzel/core/config/Configuration.java index df2f7d9..94d9f3f 100644 --- a/core/src/main/java/de/neitzel/core/config/Configuration.java +++ b/core/src/main/java/de/neitzel/core/config/Configuration.java @@ -48,7 +48,7 @@ public class Configuration { * * @param properties the Properties object containing configuration key-value pairs */ - public Configuration(Properties properties) { + public Configuration(final Properties properties) { this.properties = properties; } diff --git a/core/src/main/java/de/neitzel/core/image/ImageScaler.java b/core/src/main/java/de/neitzel/core/image/ImageScaler.java index bfa7ac2..19ca807 100644 --- a/core/src/main/java/de/neitzel/core/image/ImageScaler.java +++ b/core/src/main/java/de/neitzel/core/image/ImageScaler.java @@ -1,16 +1,20 @@ package de.neitzel.core.image; +import lombok.extern.slf4j.Slf4j; + import javax.imageio.ImageIO; import java.awt.*; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; +import java.io.IOException; import java.io.InputStream; /** * Utility class for scaling images while maintaining the aspect ratio. * Provides methods to create scaled images either as byte arrays or InputStreams. */ +@Slf4j public class ImageScaler { /** @@ -148,7 +152,8 @@ public class ImageScaler { ImageIO.write(scaledImage, TARGET_FORMAT, stream); return stream.toByteArray(); } - } catch (Exception ex) { + } catch (IOException ex) { + log.error("IOException while scaling image.", ex); return null; } } diff --git a/core/src/main/java/de/neitzel/core/inject/ApplicationContext.java b/core/src/main/java/de/neitzel/core/inject/ApplicationContext.java new file mode 100644 index 0000000..aca45d2 --- /dev/null +++ b/core/src/main/java/de/neitzel/core/inject/ApplicationContext.java @@ -0,0 +1,141 @@ +package de.neitzel.core.inject; + +import de.neitzel.core.inject.annotation.Config; + +import java.lang.reflect.Constructor; +import java.util.Map; +import java.util.Objects; +import java.util.stream.Stream; + +/** + * Represents the context of the application and serves as the foundation of a dependency + * injection framework. + * + * The {@code ApplicationContext} is responsible for scanning, instantiating, and managing + * the lifecycle of components. Components are identified through the specified base package + * (or derived from a configuration class) and instantiated based on their dependency + * requirements and scope. The framework supports constructor-based dependency injection + * for resolving and creating components. + */ +public class ApplicationContext { + private final Map, ComponentData> components; + + /** + * Erstellt einen ApplicationContext auf Basis eines expliziten Package-Namens. + * + * @param basePackage das Basis-Package, das nach Komponenten durchsucht werden soll + */ + public ApplicationContext(String basePackage) { + ComponentScanner scanner = new ComponentScanner(basePackage); + this.components = scanner.getInstantiableComponents(); + } + + /** + * Erstellt einen ApplicationContext auf Basis einer Startklasse. + * Das zu scannende Package wird aus der @Config Annotation gelesen (basePackage). + * Wenn keine Annotation vorhanden ist oder kein basePackage gesetzt wurde, wird + * das Package der übergebenen Klasse verwendet. + * + * @param configClass Klasse mit oder ohne @Config Annotation + */ + public ApplicationContext(Class configClass) { + String basePackage; + Config config = configClass.getAnnotation(Config.class); + if (config != null && !config.basePackage().isEmpty()) { + basePackage = config.basePackage(); + } else { + basePackage = configClass.getPackageName(); + } + ComponentScanner scanner = new ComponentScanner(basePackage); + this.components = scanner.getInstantiableComponents(); + } + + /** + * Retrieves an instance of the specified component type from the application context. + * + * This method uses dependency injection to construct the component if it is not already + * a singleton instance. The component's type and scope are determined by the framework, + * and the appropriate initialization and lifecycle management are performed. + * + * @param the type of the component to retrieve + * @param type the {@code Class} object representing the type of the component + * @return an instance of the requested component type + * @throws IllegalArgumentException if no component is found for the specified type + * @throws IllegalStateException if no suitable constructor is found for the component + * @throws RuntimeException if any error occurs during instantiation + */ + @SuppressWarnings("unchecked") + public T getComponent(Class type) { + ComponentData data = components.get(type); + if (data == null) { + throw new IllegalArgumentException("No component found for type: " + type.getName()); + } + + Scope scope = data.getScope(); + Object instance = data.getInstance(); + + if (scope == Scope.SINGLETON && instance != null) { + return (T) instance; + } + + try { + Constructor[] constructors = data.getType().getConstructors(); + for (Constructor constructor : constructors) { + if (canBeInstantiated(constructor, components)) { + Class[] paramTypes = constructor.getParameterTypes(); + Object[] parameters = new Object[paramTypes.length]; + for (int i = 0; i < paramTypes.length; i++) { + parameters[i] = getComponent(paramTypes[i]); + } + instance = constructor.newInstance(parameters); + if (scope == Scope.SINGLETON) { + data.setInstance(instance); + } + return (T) instance; + } + } + + throw new IllegalStateException("Kein passender Konstruktor gefunden für " + type.getName()); + } catch (Exception e) { + throw new RuntimeException("Fehler beim Erstellen der Instanz für " + type.getName(), e); + } + } + + /** + * Determines if a given constructor can be instantiated using the provided parameter map. + * + * The method evaluates whether every parameter type required by the constructor + * is available in the given parameter map. If all parameter types are present, + * the constructor is considered instantiable. + * + * @param constructor the constructor to check for instantiation feasibility + * @param parameterMap a map containing available parameter types and their associated component data + * @return true if all parameter types required by the constructor are contained in the parameter map, false otherwise + */ + private boolean canBeInstantiated(Constructor constructor, Map, ComponentData> parameterMap) { + return Stream.of(constructor.getParameterTypes()).allMatch(parameterMap::containsKey); + } + + /** + * Registers a singleton instance of a specific type into the application context. + * + * This method allows manual addition of singleton components to the context by + * providing a concrete instance of the required type. If the type is already mapped + * to a different instance or type within the context, an {@link IllegalStateException} + * is thrown to prevent replacement of an existing singleton. + * + * @param the type of the component to register + * @param type the class type of the component being added + * @param instance the singleton instance of the component to register + * @throws IllegalStateException if the type is already registered with a different instance + */ + public void addSingleton(Class type, T instance) { + if (components.get(type) == null || + !Objects.equals(components.get(type).getType().getName(), type.getName())) { + + components.put(type, new ComponentData(type, instance)); + } else { + throw new IllegalStateException("Type cannot be replaced: " + type.getName()); + } + } +} diff --git a/core/src/main/java/de/neitzel/core/inject/ComponentData.java b/core/src/main/java/de/neitzel/core/inject/ComponentData.java new file mode 100644 index 0000000..742227e --- /dev/null +++ b/core/src/main/java/de/neitzel/core/inject/ComponentData.java @@ -0,0 +1,89 @@ +package de.neitzel.core.inject; + +import lombok.Getter; + +/** + * Represents a component in a dependency injection framework. + * + * A component is a unit of functionality that is managed by the framework, allowing + * for controlled instantiation and lifecycle management. The component is associated + * with a specific type and a scope. The scope determines whether the component is + * instantiated as a singleton or as a prototype. + */ +@Getter +public class ComponentData { + + /** + * Represents the type of the component being managed by the dependency injection framework. + * + * This variable holds the class object corresponding to the specific type of the component. + * It is used to identify and instantiate the component during the dependency injection process. + * The type is immutable and is specified when the component is created. + */ + private final Class type; + + /** + * Defines the lifecycle and instantiation rules for the associated component. + * + * The {@code Scope} determines whether the component is created as a singleton + * (a single shared instance) or as a prototype (a new instance for each request). + * + * This variable is immutable and represents the specific {@code Scope} assigned + * to the component, influencing its behavior within the dependency injection framework. + */ + private final Scope scope; + + /** + * Stores the instantiated object associated with the component. + * + * This field holds the actual instance of the component's type within the dependency + * injection framework. For components with a {@code SINGLETON} scope, this field is + * set only once and shared across the entire application. For components with a + * {@code PROTOTYPE} scope, this field may be null since a new instance is created + * upon each request. + */ + private Object instance; + + /** + * Constructs a new Component instance with the specified type and scope. + * + * @param type the class type of the component + * @param scope the scope of the component, which determines its lifecycle + */ + public ComponentData(Class type, Scope scope) { + this.type = type; + this.scope = scope; + } + + /** + * Constructs a new ComponentData instance with the specified type and an initial instance. + * + * This can be used to add Singletons manually without scanning for them. + * + * @param type the class type of the component + * @param instance the initial instance of the component + */ + public ComponentData(Class type, Object instance) { + this.type = type; + this.scope = Scope.SINGLETON; + this.instance = instance; + } + + /** + * Sets the instance for this component if it is configured with a {@code SINGLETON} scope. + * This method ensures that the instance is only set once for a {@code SINGLETON} component. + * If an instance has already been set, it throws an {@link IllegalStateException}. + * + * @param instance the object instance to associate with this component + * @throws IllegalStateException if an instance has already been set for this {@code SINGLETON} component + */ + public void setInstance(Object instance) { + if (scope != Scope.SINGLETON) { + return; + } + if (this.instance != null) { + throw new IllegalStateException("Instance already set for singleton: " + type.getName()); + } + this.instance = instance; + } +} diff --git a/core/src/main/java/de/neitzel/core/inject/InjectableComponentScanner.java b/core/src/main/java/de/neitzel/core/inject/ComponentScanner.java similarity index 75% rename from core/src/main/java/de/neitzel/core/inject/InjectableComponentScanner.java rename to core/src/main/java/de/neitzel/core/inject/ComponentScanner.java index 17f73fa..244b443 100644 --- a/core/src/main/java/de/neitzel/core/inject/InjectableComponentScanner.java +++ b/core/src/main/java/de/neitzel/core/inject/ComponentScanner.java @@ -1,6 +1,7 @@ package de.neitzel.core.inject; import de.neitzel.core.inject.annotation.Component; +import de.neitzel.core.inject.annotation.Inject; import org.reflections.Reflections; import java.lang.reflect.Constructor; @@ -13,7 +14,7 @@ import java.util.stream.Collectors; * The resulting analysis identifies unique and shared interfaces/superclasses as well as * potentially instantiable components, collecting relevant errors if instantiation is not feasible. */ -public class InjectableComponentScanner { +public class ComponentScanner { /** * A set that stores classes annotated with {@code @Component}, representing @@ -30,7 +31,7 @@ public class InjectableComponentScanner { * This field is immutable, ensuring thread safety and consistent state * throughout the lifetime of the {@code InjectableComponentScanner}. */ - private final Set> fxmlComponents = new HashSet<>(); + private final Set> components = new HashSet<>(); /** * A set of component types that are not uniquely associated with a single implementation. @@ -75,7 +76,7 @@ public class InjectableComponentScanner { * The resolution process checks if a component can be instantiated based on its * constructor dependencies being resolvable using known types or other registered components. */ - private final Map, Class> instantiableComponents = new HashMap<>(); + private final Map, ComponentData> instantiableComponents = new HashMap<>(); /** * A list of error messages encountered during the scanning and analysis @@ -96,7 +97,7 @@ public class InjectableComponentScanner { * * @param basePackage the base package to scan for injectable components */ - public InjectableComponentScanner(String basePackage) { + public ComponentScanner(String basePackage) { scanForComponents(basePackage); analyzeComponentTypes(); resolveInstantiableComponents(); @@ -110,7 +111,7 @@ public class InjectableComponentScanner { */ private void scanForComponents(String basePackage) { Reflections reflections = new Reflections(basePackage); - fxmlComponents.addAll(reflections.getTypesAnnotatedWith(Component.class)); + components.addAll(reflections.getTypesAnnotatedWith(Component.class)); } /** @@ -135,7 +136,7 @@ public class InjectableComponentScanner { private void analyzeComponentTypes() { Map, List>> superTypesMap = new HashMap<>(); - for (Class component : fxmlComponents) { + for (Class component : components) { Set> allSuperTypes = getAllSuperTypes(component); for (Class superType : allSuperTypes) { @@ -156,44 +157,48 @@ public class InjectableComponentScanner { } /** - * Resolves components from the set of scanned classes that can be instantiated based on their constructors - * and existing known types. The method iteratively processes classes to identify those whose dependencies - * can be satisfied, marking them as resolved and registering them alongside their supertypes. + * Resolves and identifies instantiable components from a set of scanned components. + * This process determines which components can be instantiated based on their dependencies + * and class relationships, while tracking unresolved types and potential conflicts. * - * If progress is made during a pass (i.e., a component is resolved), the process continues until no more - * components can be resolved. Any components that remain unresolved are recorded for further inspection. + * The resolution process involves: + * 1. Iteratively determining which components can be instantiated using the known types + * map. A component is resolvable if its dependencies can be satisfied by the current + * set of known types. + * 2. Registering resolvable components and their superclasses/interfaces into the known + * types map for future iterations. + * 3. Removing successfully resolved components from the unresolved set. + * 4. Repeating the process until no further components can be resolved in a given iteration. * - * The resolved components are stored in a map where each type and its supertypes are associated - * with the component class itself. This map allows for subsequent lookups when verifying dependency satisfiability. + * At the end of the resolution process: + * - Resolvable components are added to the `instantiableComponents` map, which maps types + * to their corresponding instantiable implementations. + * - Unresolved components are identified, and error details are collected to highlight + * dependencies or conflicts preventing their instantiation. * - * If unresolved components remain after the resolution process, detailed instantiation errors are collected - * for debugging or logging purposes. - * - * This method depends on the following utility methods: - * - {@link #canInstantiate(Class, Set)}: Determines if a component can be instantiated based on existing known types. - * - {@link #registerComponentWithSuperTypes(Class, Map)}: Registers a component and its supertypes in the known types map. - * - {@link #collectInstantiationErrors(Set)}: Collects detailed error messages for unresolved components. + * If errors are encountered due to unresolved components, they are logged for further analysis. */ private void resolveInstantiableComponents() { Set> resolved = new HashSet<>(); - Set> unresolved = new HashSet<>(fxmlComponents); - Map, Class> knownTypes = new HashMap<>(); + Set> unresolved = new HashSet<>(components); + Map, ComponentData> knownTypes = new HashMap<>(); + Set> resolvableNow; - boolean progress; do { - progress = false; - Iterator> iterator = unresolved.iterator(); + resolvableNow = unresolved.stream() + .filter(c -> canInstantiate(c, knownTypes.keySet())) + .collect(Collectors.toSet()); - while (iterator.hasNext()) { - Class component = iterator.next(); - if (canInstantiate(component, knownTypes.keySet())) { - resolved.add(component); - registerComponentWithSuperTypes(component, knownTypes); - iterator.remove(); - progress = true; - } + for (Class clazz : resolvableNow) { + Component annotation = clazz.getAnnotation(Component.class); + ComponentData componentInfo = new ComponentData(clazz, annotation.scope()); + + resolved.add(clazz); + registerComponentWithSuperTypes(componentInfo, knownTypes); } - } while (progress); + + unresolved.removeAll(resolvableNow); + } while (!resolvableNow.isEmpty()); instantiableComponents.putAll(knownTypes); @@ -203,16 +208,17 @@ public class InjectableComponentScanner { } /** - * Registers the given component class in the provided map. The component is registered along with all of its - * accessible superclasses and interfaces, unless those types are identified as non-unique. + * Registers a component and its superclasses or interfaces in the provided map of known types. + * This method ensures that the component and its inheritance hierarchy are associated with the + * component's data unless the supertype is marked as non-unique. * - * @param component the component class to register - * @param knownTypes the map where the component and its types will be registered + * @param component the {@code ComponentData} instance representing the component to be registered + * @param knownTypes the map where component types and their data are stored */ - private void registerComponentWithSuperTypes(Class component, Map, Class> knownTypes) { - knownTypes.put(component, component); + private void registerComponentWithSuperTypes(ComponentData component, Map, ComponentData> knownTypes) { + knownTypes.put(component.getType(), component); - for (Class superType : getAllSuperTypes(component)) { + for (Class superType : getAllSuperTypes(component.getType())) { if (!notUniqueTypes.contains(superType)) { knownTypes.put(superType, component); } @@ -220,22 +226,38 @@ public class InjectableComponentScanner { } /** - * Determines whether a given class can be instantiated based on its constructors and - * the provided known types. A class is considered instantiable if it has a parameterless - * constructor or if all the parameter types of its constructors are present in the known types. + * Determines whether the specified component class can be instantiated based on the provided set + * of known types. A component is considered instantiable if it has at least one constructor where + * all parameter types are contained in the known types set or if it has a no-argument constructor. + * Additionally, all fields annotated with {@code @Inject} must have their types present in the + * known types set. * - * @param component the class to check for instantiation eligibility - * @param knownTypes the set of types known to be instantiable and available for constructor injection - * @return true if the class can be instantiated; false otherwise + * @param component the class to check for instantiability + * @param knownTypes the set of currently known types that can be used to satisfy dependencies + * @return {@code true} if the component can be instantiated; {@code false} otherwise */ private boolean canInstantiate(Class component, Set> knownTypes) { + boolean hasValidConstructor = false; + for (Constructor constructor : component.getConstructors()) { Class[] paramTypes = constructor.getParameterTypes(); if (paramTypes.length == 0 || Arrays.stream(paramTypes).allMatch(knownTypes::contains)) { - return true; + hasValidConstructor = true; + break; } } - return false; + + if (!hasValidConstructor) { + return false; + } + + for (var field : component.getDeclaredFields()) { + if (field.isAnnotationPresent(Inject.class) && !knownTypes.contains(field.getType())) { + return false; + } + } + + return true; } /** @@ -256,7 +278,7 @@ public class InjectableComponentScanner { Class[] paramTypes = constructor.getParameterTypes(); List> problematicTypes = Arrays.stream(paramTypes) .filter(t -> !instantiableComponents.containsKey(t) && !notUniqueTypes.contains(t)) - .collect(Collectors.toList()); + .toList(); if (problematicTypes.isEmpty()) { possibleWithUniqueTypes = true; @@ -317,7 +339,7 @@ public class InjectableComponentScanner { * @return A map where the key is a class type and the value is the corresponding class implementation * that can be instantiated. */ - public Map, Class> getInstantiableComponents() { + public Map, ComponentData> getInstantiableComponents() { return instantiableComponents; } diff --git a/core/src/main/java/de/neitzel/core/inject/Scope.java b/core/src/main/java/de/neitzel/core/inject/Scope.java new file mode 100644 index 0000000..0f17a9c --- /dev/null +++ b/core/src/main/java/de/neitzel/core/inject/Scope.java @@ -0,0 +1,41 @@ +package de.neitzel.core.inject; + +/** + * Represents the scope of a component in a dependency injection framework. + *

+ * The scope determines the lifecycle and visibility of a component instance + * within the framework. The available scope types are: + *

+ * - {@code SINGLETON}: A single instance of the component is created and + * shared across the entire application. + * - {@code PROTOTYPE}: A new instance of the component is created + * each time it is requested or injected. + *

+ * This enumeration is typically used in conjunction with the {@code @Component} + * annotation to specify the instantiation behavior of a component. + */ +public enum Scope { + /** + * Specifies that the component should be instantiated as a singleton within the + * dependency injection framework. A single instance of the component is created + * and shared across the entire application lifecycle, ensuring efficient reuse + * of resources and consistent behavior for the component throughout the application. + *

+ * This scope is typically applied to components where maintaining a single shared + * instance is necessary or beneficial, such as managing shared state or providing + * utility services. + */ + SINGLETON, + /** + * Specifies that the component should be instantiated as a prototype within the + * dependency injection framework. A new instance of the component is created + * each time it is requested or injected, ensuring that no two requests or injections + * share the same instance. + *

+ * This scope is typically applied to components where maintaining unique instances + * per request is necessary, such as request-specific data processing or handling + * of transient state. It allows for complete isolation between multiple users + * or operations requiring individual resources. + */ + PROTOTYPE +} diff --git a/core/src/main/java/de/neitzel/core/inject/annotation/Component.java b/core/src/main/java/de/neitzel/core/inject/annotation/Component.java index 73cb855..4351ad9 100644 --- a/core/src/main/java/de/neitzel/core/inject/annotation/Component.java +++ b/core/src/main/java/de/neitzel/core/inject/annotation/Component.java @@ -1,5 +1,7 @@ package de.neitzel.core.inject.annotation; +import de.neitzel.core.inject.Scope; + import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -24,4 +26,12 @@ import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface Component { + /** + * Defines the scope of a component within the dependency injection framework. + * The scope determines whether the component is instantiated as a singleton or + * as a prototype. + * + * @return the scope of the component, defaulting to {@code Scope.SINGLETON}. + */ + Scope scope() default Scope.SINGLETON; } diff --git a/core/src/main/java/de/neitzel/core/inject/annotation/Config.java b/core/src/main/java/de/neitzel/core/inject/annotation/Config.java new file mode 100644 index 0000000..cac196d --- /dev/null +++ b/core/src/main/java/de/neitzel/core/inject/annotation/Config.java @@ -0,0 +1,37 @@ +package de.neitzel.core.inject.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Indicates that an annotated class is a configuration class within a dependency + * injection framework. Classes annotated with {@code @Config} are used as markers + * for defining settings and application-specific configurations required by the + * dependency injection mechanism. + * + * Typically, configuration classes provide metadata required for setting up the + * framework, such as specifying the base package to scan for components. + * + * This annotation must be applied at the type level and is retained at runtime to + * facilitate reflection-based processing. It is intended to serve as a declarative + * representation of configuration options for the dependency injection container. + * + * Attributes: + * - {@code basePackage}: Specifies the package name where the framework should scan + * for classes annotated with dependency injection annotations such as {@code @Component}. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface Config { + /** + * Specifies the base package for component scanning within the dependency + * injection framework. Classes within the defined package and its sub-packages + * can be scanned and identified as candidates for dependency injection. + * + * @return the base package name as a string; returns an empty string by default + * if no specific package is defined. + */ + String basePackage() default ""; +} diff --git a/core/src/main/java/de/neitzel/core/inject/annotation/Inject.java b/core/src/main/java/de/neitzel/core/inject/annotation/Inject.java new file mode 100644 index 0000000..bf2b703 --- /dev/null +++ b/core/src/main/java/de/neitzel/core/inject/annotation/Inject.java @@ -0,0 +1,24 @@ +package de.neitzel.core.inject.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Indicates that a field is a candidate for dependency injection within + * a dependency injection framework. Fields annotated with {@code @Inject} + * are automatically populated with the required component instance during runtime, + * typically by the dependency injection container. + * + * This annotation must be applied at the field level and is retained at runtime + * to enable reflection-based identification and assignment of dependencies. + * + * The framework's dependency resolution mechanism identifies the appropriate + * instance to inject based on the field's type or custom configuration, + * ensuring loose coupling and easier testability. + */ +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +public @interface Inject { +} diff --git a/core/src/main/java/de/neitzel/core/sql/Query.java b/core/src/main/java/de/neitzel/core/sql/Query.java index f92d184..d139534 100644 --- a/core/src/main/java/de/neitzel/core/sql/Query.java +++ b/core/src/main/java/de/neitzel/core/sql/Query.java @@ -1,6 +1,5 @@ package de.neitzel.core.sql; -import lombok.RequiredArgsConstructor; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; diff --git a/core/src/main/java/de/neitzel/core/sql/TrimmingResultSet.java b/core/src/main/java/de/neitzel/core/sql/TrimmingResultSet.java index 1297e67..19ae0c0 100644 --- a/core/src/main/java/de/neitzel/core/sql/TrimmingResultSet.java +++ b/core/src/main/java/de/neitzel/core/sql/TrimmingResultSet.java @@ -1,7 +1,5 @@ package de.neitzel.core.sql; -import lombok.RequiredArgsConstructor; - import java.io.InputStream; import java.io.Reader; import java.math.BigDecimal; diff --git a/core/src/main/java/de/neitzel/core/util/FileUtils.java b/core/src/main/java/de/neitzel/core/util/FileUtils.java index 8606083..6bb3219 100644 --- a/core/src/main/java/de/neitzel/core/util/FileUtils.java +++ b/core/src/main/java/de/neitzel/core/util/FileUtils.java @@ -1,6 +1,5 @@ package de.neitzel.core.util; -import lombok.extern.log4j.Log4j; import lombok.extern.slf4j.Slf4j; import java.io.*; diff --git a/core/src/main/java/de/neitzel/core/util/XmlUtils.java b/core/src/main/java/de/neitzel/core/util/XmlUtils.java index 5c35142..61a96a9 100644 --- a/core/src/main/java/de/neitzel/core/util/XmlUtils.java +++ b/core/src/main/java/de/neitzel/core/util/XmlUtils.java @@ -1,7 +1,6 @@ package de.neitzel.core.util; import lombok.NonNull; -import lombok.extern.log4j.Log4j; import lombok.extern.slf4j.Slf4j; import org.w3c.dom.Document; import org.w3c.dom.Element; diff --git a/core/src/test/java/de/neitzel/core/inject/InjectableComponentScannerTest.java b/core/src/test/java/de/neitzel/core/inject/InjectableComponentScannerTest.java index 49fd066..2f7e140 100644 --- a/core/src/test/java/de/neitzel/core/inject/InjectableComponentScannerTest.java +++ b/core/src/test/java/de/neitzel/core/inject/InjectableComponentScannerTest.java @@ -16,7 +16,7 @@ class InjectableComponentScannerTest { */ @Test void testLoadComponents() { - InjectableComponentScanner scanner = new InjectableComponentScanner("de.neitzel.core.inject.testcomponents.test1ok"); + ComponentScanner scanner = new ComponentScanner("de.neitzel.core.inject.testcomponents.test1ok"); var instantiableComponents = scanner.getInstantiableComponents(); var nonUniqueTypes = scanner.getNotUniqueTypes(); @@ -37,7 +37,7 @@ class InjectableComponentScannerTest { */ @Test void testComponentsFailWithUnknownParameters() { - InjectableComponentScanner scanner = new InjectableComponentScanner("de.neitzel.core.inject.testcomponents.test2fail"); + ComponentScanner scanner = new ComponentScanner("de.neitzel.core.inject.testcomponents.test2fail"); var instantiableComponents = scanner.getInstantiableComponents(); var nonUniqueTypes = scanner.getNotUniqueTypes(); diff --git a/core/src/test/java/de/neitzel/core/inject/testcomponents/test1ok/sub/TestComponent1_2.java b/core/src/test/java/de/neitzel/core/inject/testcomponents/test1ok/sub/TestComponent1_2.java index ff09e32..144828d 100644 --- a/core/src/test/java/de/neitzel/core/inject/testcomponents/test1ok/sub/TestComponent1_2.java +++ b/core/src/test/java/de/neitzel/core/inject/testcomponents/test1ok/sub/TestComponent1_2.java @@ -1,9 +1,9 @@ package de.neitzel.core.inject.testcomponents.test1ok.sub; +import de.neitzel.core.inject.annotation.Component; import de.neitzel.core.inject.testcomponents.test1ok.SuperClass; import de.neitzel.core.inject.testcomponents.test1ok.TestInterface1_1; import de.neitzel.core.inject.testcomponents.test1ok.TestInterface1_2; -import de.neitzel.core.inject.annotation.Component; @Component public class TestComponent1_2 extends SuperClass implements TestInterface1_1, TestInterface1_2 { diff --git a/fx-example/src/main/resources/address.fxml b/fx-example/src/main/resources/address.fxml index 2bc5a08..0fc914f 100644 --- a/fx-example/src/main/resources/address.fxml +++ b/fx-example/src/main/resources/address.fxml @@ -1,8 +1,7 @@ - - - + + - - - + + +