-
Notifications
You must be signed in to change notification settings - Fork 998
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
implemented Injector class #1022
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package mate.academy.exception; | ||
|
||
public class RequiredAnnotationAbsenceException extends RuntimeException { | ||
public RequiredAnnotationAbsenceException(String message) { | ||
super(message); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,12 @@ | ||
package mate.academy.lib; | ||
|
||
import java.lang.annotation.ElementType; | ||
import java.lang.annotation.Retention; | ||
import java.lang.annotation.RetentionPolicy; | ||
import java.lang.annotation.Target; | ||
|
||
@Retention(RetentionPolicy.RUNTIME) | ||
@Target(ElementType.TYPE) | ||
public @interface Component { | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,12 @@ | ||
package mate.academy.lib; | ||
|
||
import java.lang.annotation.ElementType; | ||
import java.lang.annotation.Retention; | ||
import java.lang.annotation.RetentionPolicy; | ||
import java.lang.annotation.Target; | ||
|
||
@Retention(RetentionPolicy.RUNTIME) | ||
@Target(ElementType.FIELD) | ||
public @interface Inject { | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,79 @@ | ||
package mate.academy.lib; | ||
|
||
import java.lang.reflect.Constructor; | ||
import java.lang.reflect.Field; | ||
import java.util.HashMap; | ||
import java.util.Map; | ||
import java.util.NoSuchElementException; | ||
import mate.academy.exception.RequiredAnnotationAbsenceException; | ||
import mate.academy.service.FileReaderService; | ||
import mate.academy.service.ProductParser; | ||
import mate.academy.service.ProductService; | ||
import mate.academy.service.impl.FileReaderServiceImpl; | ||
import mate.academy.service.impl.ProductParserImpl; | ||
import mate.academy.service.impl.ProductServiceImpl; | ||
|
||
public class Injector { | ||
private static final Injector injector = new Injector(); | ||
private final Map<Class<?>, Object> instances = new HashMap<>(); | ||
private final Map<Class<?>, Class<?>> interfaceImplementations = Map.of( | ||
FileReaderService.class, FileReaderServiceImpl.class, | ||
ProductParser.class, ProductParserImpl.class, | ||
ProductService.class, ProductServiceImpl.class | ||
); | ||
|
||
public static Injector getInjector() { | ||
return injector; | ||
} | ||
|
||
public Object getInstance(Class<?> interfaceClazz) { | ||
return null; | ||
Class<?> clazz = findImplementation(interfaceClazz); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The findImplementation method may return null if the interfaceClazz is not found in the interfaceImplementations map. Consider adding a check to handle this scenario and throw an appropriate exception if no implementation is found. |
||
Object clazzImplementationInstance = createNewInstance(clazz); | ||
|
||
Field[] declaredFields = clazz.getDeclaredFields(); | ||
for (Field field : declaredFields) { | ||
if (field.isAnnotationPresent(Inject.class)) { | ||
Object fieldInstance = getInstance(field.getType()); | ||
try { | ||
field.setAccessible(true); | ||
field.set(clazzImplementationInstance, fieldInstance); | ||
} catch (IllegalAccessException e) { | ||
throw new RuntimeException("Cannot initialize field value. " + "Class: " | ||
+ clazz.getName() + ". Field: " + field.getName()); | ||
} | ||
} | ||
} | ||
|
||
return clazzImplementationInstance; | ||
} | ||
|
||
private Object createNewInstance(Class<?> clazz) { | ||
if (!clazz.isAnnotationPresent(Component.class)) { | ||
throw new RequiredAnnotationAbsenceException( | ||
"Cannot create an instance of the class without Component annotation " | ||
+ clazz); | ||
} | ||
Comment on lines
+51
to
+55
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ensure that all classes you intend to create instances for are annotated with @component. Otherwise, the RequiredAnnotationAbsenceException will be thrown, as seen in this check. |
||
if (instances.containsKey(clazz)) { | ||
return instances.get(clazz); | ||
} | ||
try { | ||
Constructor<?> constructor = clazz.getConstructor(); | ||
Object instance = constructor.newInstance(); | ||
instances.put(clazz, instance); | ||
return instance; | ||
} catch (ReflectiveOperationException e) { | ||
throw new RuntimeException("Cannot create a new instance of: " + clazz.getName()); | ||
} | ||
} | ||
|
||
private Class<?> findImplementation(Class<?> interfaceClazz) { | ||
if (!interfaceImplementations.containsKey(interfaceClazz)) { | ||
throw new NoSuchElementException("The key " + interfaceClazz + " not found in the map " | ||
+ interfaceImplementations); | ||
} | ||
if (interfaceClazz.isInterface()) { | ||
return interfaceImplementations.get(interfaceClazz); | ||
} | ||
return interfaceClazz; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ensure that the Injector class is correctly implemented and configured to return an instance of ProductService. If the Injector is not properly set up, this line may cause a runtime error.