
com.github.nill14.utils.init.binding.ModuleBinder Maven / Gradle / Ivy
The newest version!
package com.github.nill14.utils.init.binding;
import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import com.github.nill14.utils.init.api.BindingKey;
import com.github.nill14.utils.init.api.IBeanInjector;
import com.github.nill14.utils.init.api.IPropertyResolver;
import com.github.nill14.utils.init.api.IScope;
import com.github.nill14.utils.init.binding.impl.Binding;
import com.github.nill14.utils.init.binding.impl.BindingBuilder;
import com.github.nill14.utils.init.binding.target.AnnotatedElementBindingTargetVisitor;
import com.github.nill14.utils.init.impl.BinderUtils;
import com.github.nill14.utils.init.impl.CallerContext;
import com.github.nill14.utils.init.impl.ChainingPojoInitializer;
import com.github.nill14.utils.init.impl.ChainingPropertyResolver;
import com.github.nill14.utils.init.impl.SimplePropertyResolver;
import com.github.nill14.utils.init.meta.AnnotationScanner;
import com.github.nill14.utils.init.scope.ScopeStrategies;
import com.github.nill14.utils.init.util.Element;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.reflect.TypeToken;
public final class ModuleBinder implements Binder {
private final Map, IScope> scopes = Maps.newHashMap();
private final ChainingPropertyResolver resolver = new ChainingPropertyResolver();
private final List>> elements = Lists.newArrayList();
private final AtomicBoolean configurationLocker = new AtomicBoolean(false);
private final Object source;
private final Binder parent;
public ModuleBinder(Binder parent, Object source) {
this.parent = parent;
this.source = source;
}
private Element> newElement() {
Element> element = new Element>(configurationLocker);
elements.add(element);
return element;
}
@Override
public AnnotatedBindingBuilder bind(TypeToken typeToken) {
return new BindingBuilder(this, newElement(), source, typeToken);
}
@Override
public AnnotatedBindingBuilder bind(Class type) {
return new BindingBuilder(this, newElement(), source, TypeToken.of(type));
}
@Override
public void bindScope(Class extends Annotation> annotationType, IScope scope) {
scopes.put(annotationType, scope); //TODO IScopeStrategy?
}
public IPropertyResolver toResolver() {
ImmutableList> bindings = freezeBindings();
return new SimplePropertyResolver(bindings,
new ChainingPojoInitializer(resolver.getInitializers()));
}
public ImmutableList> freezeBindings() {
configurationLocker.set(true);
ImmutableList> bindings = ImmutableList.copyOf(
elements.stream().map(Element::getValue).map(BinderUtils::scanQualifierAndScope).map(binding -> ScopeStrategies.replaceScopes(binding, scopes)).iterator());
return bindings;
}
public IBeanInjector toBeanInjector() {
// bindScope(Singleton.class, SingletonScope.instance());
ImmutableList> bindings = freezeBindings();
SimplePropertyResolver propertyResolver = new SimplePropertyResolver(bindings,
new ChainingPojoInitializer(resolver.getInitializers()));
return propertyResolver.toBeanInjector(CallerContext.prototype());
}
public void build() {
toBeanInjector();
// return serviceRegistry.toBeanInjector();
}
private Binding scanQualifier(Binding binding) {
AnnotatedElementBindingTargetVisitor targetVisitor = new AnnotatedElementBindingTargetVisitor();
BindingKey bindingKey = binding.getBindingKey();
if (bindingKey.getQualifier() == null) {
AnnotatedElement annotatedElement = binding.getBindingTarget().accept(targetVisitor);
Annotation qualifier = AnnotationScanner.findQualifier(annotatedElement).orElse(null);
return binding.keyWithQualifier(qualifier);
}
return binding;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy