org.datafx.controller.injection.InjectionHandler Maven / Gradle / Ivy
package org.datafx.controller.injection;
import javassist.util.proxy.MethodHandler;
import javassist.util.proxy.ProxyFactory;
import org.datafx.controller.context.AbstractContext;
import org.datafx.controller.context.ViewContext;
import org.datafx.controller.injection.provider.ContextProvider;
import org.datafx.util.DataFXUtils;
import javax.inject.Inject;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Iterator;
import java.util.ServiceLoader;
public class InjectionHandler {
private final static DependendContext DEPENDEND_CONTEXT = new DependendContext();
private ViewContext viewContext;
public InjectionHandler(ViewContext viewContext) {
this.viewContext = viewContext;
}
private T registerNewInstance(final Class propertyClass, final AbstractContext context) throws IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchMethodException {
for (Constructor> constructor : propertyClass.getConstructors()) {
if (constructor.getParameterCount() == 0) {
T instance = propertyClass.newInstance();
context.register(instance);
injectAllSupportedFields(instance);
return instance;
}
}
//TODO: Special Exception
throw new RuntimeException("No default constructor present!");
}
public T createProxy(final Class propertyClass) throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
final AbstractContext context = getContextForClass(propertyClass);
T registeredObject = context.getRegisteredObject(propertyClass);
if (registeredObject == null) {
registeredObject = registerNewInstance(propertyClass, context);
}
final T innerObject = registeredObject;
ProxyFactory factory = new ProxyFactory();
factory.setSuperclass(propertyClass);
MethodHandler handler = new MethodHandler() {
@Override
public Object invoke(Object self, Method thisMethod, Method proceed, Object[] args) throws Throwable {
AbstractContext context = getContextForClass(propertyClass);
if (context.getRegisteredObject(propertyClass) == null) {
registerNewInstance(propertyClass, context);
}
return thisMethod.invoke(innerObject, args);
}
};
return (T) factory.create(new Class>[0], new Object[0], handler);
}
private void injectAllSupportedFields(T bean) throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
Class cls = (Class) bean.getClass();
for (final Field field : DataFXUtils.getInheritedPrivateFields(cls)) {
if (field.isAnnotationPresent(Inject.class)) {
DataFXUtils.setPrivileged(field, bean, createProxy(field.getType()));
}
}
}
private AbstractContext getContextForClass(Class> cls) {
ServiceLoader contextProvidersLoader = ServiceLoader.load(ContextProvider.class);
Iterator iterator = contextProvidersLoader.iterator();
while (iterator.hasNext()) {
ContextProvider provider = iterator.next();
if (cls.isAnnotationPresent(provider.supportedAnnotation())) {
return provider.getContext(viewContext);
}
}
return DEPENDEND_CONTEXT;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy