
com.github.jsr330.spi.config.builder.DefaultBinder Maven / Gradle / Ivy
package com.github.jsr330.spi.config.builder;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Map;
import javax.inject.Provider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.github.jsr330.instance.TypeContainer;
import com.github.jsr330.instance.TypeContainer.InstanceMode;
import com.github.jsr330.spi.ClassInjector;
import com.github.jsr330.spi.TypeConfig;
public class DefaultBinder implements LinkingBinder, InitialBinder, TypeBinder, ConditionalBinder, InstancingBinder, TypeConfig {
private static final Logger LOGGER = LoggerFactory.getLogger(DefaultBinder.class);
protected Map> configs = new HashMap>();
protected TypeContainerConfig> currentConfig;
@SuppressWarnings({ "unchecked", "rawtypes" })
protected void checkImplementation() {
if (currentConfig.getProvider() != null) {
return;
}
if (currentConfig.getImplementation() == null) {
if (currentConfig.getType().isInterface() || Modifier.isAbstract(currentConfig.getType().getModifiers())) {
throw new BinderException("can't instance interface or abstract class without a implementation specified.");
} else {
currentConfig.setImplementation((Class) currentConfig.getType());
}
} else {
if (currentConfig.getImplementation().isInterface() || Modifier.isAbstract(currentConfig.getImplementation().getModifiers())) {
throw new BinderException("can't instance interface or abstract class.");
}
}
}
@Override
public TypeConfig build() {
checkImplementation();
LOGGER.debug("build - returning {}", this);
return this;
}
@SuppressWarnings("unchecked")
@Override
public TypeBinder instance(Class type) {
currentConfig = new TypeContainerConfig(type);
configs.put(currentConfig.getType().getName(), currentConfig);
LOGGER.debug("instance - type {}", type);
return (TypeBinder) this;
}
@SuppressWarnings({ "rawtypes", "unchecked" })
@Override
public LinkingBinder and(BindingCondition condition) {
if (condition == null) {
throw new NullPointerException("condition must not be null.");
}
currentConfig.setCondition((BindingCondition) BindingConditions.and((BindingCondition) currentConfig.getCondition(), condition));
LOGGER.debug("and - condition {}", condition);
return this;
}
@SuppressWarnings({ "rawtypes", "unchecked" })
@Override
public LinkingBinder xor(BindingCondition condition) {
if (condition == null) {
throw new NullPointerException("condition must not be null.");
}
currentConfig.setCondition((BindingCondition) BindingConditions.xor((BindingCondition) currentConfig.getCondition(), condition));
LOGGER.debug("xor - condition {}", condition);
return this;
}
@SuppressWarnings({ "rawtypes", "unchecked" })
@Override
public LinkingBinder or(BindingCondition condition) {
if (condition == null) {
throw new NullPointerException("condition must not be null.");
}
currentConfig.setCondition((BindingCondition) BindingConditions.or((BindingCondition) currentConfig.getCondition(), condition));
LOGGER.debug("or - condition {}", condition);
return this;
}
@Override
public InstancingBinder asSingleton() {
currentConfig.setSingleton(true);
checkImplementation();
LOGGER.debug("asSingleton");
return this;
}
@Override
public InstancingBinder asSingleton(Class extends T> type) {
as(type);
return asSingleton();
}
@SuppressWarnings({ "unchecked", "rawtypes" })
@Override
public InstancingBinder as(Class extends T> type) {
currentConfig.setImplementation((Class) type);
checkImplementation();
LOGGER.debug("as - type {}", type);
return this;
}
@SuppressWarnings({ "rawtypes", "unchecked" })
@Override
public ConditionalBinder with(Provider extends T> provider) {
if (provider == null) {
throw new NullPointerException("provider must not be null.");
}
currentConfig.setProvider((Provider) provider);
checkImplementation();
LOGGER.debug("with - provider {}", provider);
return this;
}
@SuppressWarnings({ "rawtypes", "unchecked" })
@Override
public LinkingBinder when(BindingCondition condition) {
if (condition == null) {
throw new NullPointerException("condition must not be null.");
}
currentConfig.setCondition((BindingCondition) condition);
LOGGER.debug("when - condition {}", condition);
return this;
}
@SuppressWarnings({ "rawtypes", "unchecked" })
@Override
public ConditionalBinder using(Constructor constructor) {
currentConfig.setConstructor((Constructor) constructor);
LOGGER.debug("using - constructor {}", constructor);
return this;
}
@Override
public ConditionalBinder using(Method factoryMethod) {
currentConfig.setFactoryMethod(factoryMethod);
LOGGER.debug("using - factoryMethod {}", factoryMethod);
return this;
}
@SuppressWarnings("unchecked")
@Override
public Provider getProvider(final ClassInjector injector, final Class type, final Map[]> inheritanceTree,
final Annotation qualifier, final ClassLoader classLoader) {
TypeContainerConfig config = (TypeContainerConfig) configs.get(type.getName());
LOGGER.debug("getProvider - type {}, qualifier {}", type, qualifier);
if (config != null) {
LOGGER.debug("getProvider - config exists");
if (config.getCondition() != null && !config.getCondition().fulfilled(injector, type, inheritanceTree, qualifier, classLoader)) {
LOGGER.debug("getProvider - condition not fulfilled");
return null;
}
LOGGER.debug("getProvider - returning new provider");
return new Provider() {
@Override
public V get() {
return injector.instance(type, inheritanceTree, classLoader, null, qualifier);
}
};
}
return null;
}
@SuppressWarnings("unchecked")
@Override
public TypeContainer getTypeContainer(ClassInjector injector, Class type, Map[]> inheritanceTree, Annotation qualifier,
ClassLoader classLoader) {
TypeContainerConfig config = (TypeContainerConfig) configs.get(type.getName());
TypeContainer container;
LOGGER.debug("getTypeContainer - type {}, qualifier {}", type, qualifier);
if (config != null && (config.getImplementation() != null || config.getProvider() != null)) {
LOGGER.debug("getTypeContainer - config exists");
if (config.getCondition() != null && !config.getCondition().fulfilled(injector, type, inheritanceTree, qualifier, classLoader)) {
LOGGER.debug("getTypeContainer - condition not fulfilled");
return null;
}
container = new TypeContainer(null, null);
if (config.getFactoryMethod() != null) {
LOGGER.debug("getTypeContainer - using factory method");
container.setType(config.getImplementation());
container.gatherInformation();
container.setSingleton(config.isSingleton());
container.setInstanceMode(InstanceMode.FACTORY_METHOD);
container.setFactoryMethod(config.getFactoryMethod());
container.setConstructor(null);
container.setProvider(null);
} else if (config.getProvider() != null) {
LOGGER.debug("getTypeContainer - using provider");
container.setInstanceMode(InstanceMode.PROVIDER);
container.setProvider(config.getProvider());
container.setFactoryMethod(null);
container.setConstructor(null);
} else {
LOGGER.debug("getTypeContainer - using constructor");
container.setType(config.getImplementation());
container.gatherInformation();
container.setSingleton(config.isSingleton());
container.setInstanceMode(InstanceMode.CONSTRUCTOR);
container.setConstructor(config.getConstructor());
container.setFactoryMethod(null);
container.setProvider(null);
}
return container;
}
return null;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy