package proton.inject.binding; import java.lang.annotation.Annotation; import javax.inject.Provider; import android.os.Build; import proton.inject.ConfigurationException; import proton.inject.scope.ApplicationScoped; import proton.inject.scope.ContextScoped; import proton.inject.scope.Dependent; import proton.inject.util.InjectorUtils; public class BindingBuilderImpl<T> implements BindingBuilder<T> { private final Binding<T> mBinding; private final Bindings mBindings; public BindingBuilderImpl(Class<T> clazz, Bindings bindings) { mBinding = new Binding<T>(clazz); mBindings = bindings; mBindings.register(mBinding); if (!InjectorUtils.isAbstract(clazz)) { setScope(clazz); validateAnnotation(clazz); } } @Override public ScopedBuilder to(Class<? extends T> to) { mBinding.setToClass(checkNotNull(to, "to")); setScope(to); validateAnnotation(to); return this; } @Override public ScopedBuilder toProvider(Class<? extends Provider<T>> provider) { mBinding.setProviderClass(checkNotNull(provider, "provider")); setScope(InjectorUtils.toActualClass(provider)); validateAnnotation(provider); return this; } @Override public void toProvider(Provider<T> provider) { mBinding.setProvider(checkNotNull(provider, "provider")); mBinding.setScope(ApplicationScoped.class); validateAnnotation(provider.getClass()); } @Override public void in(Class<? extends Annotation> scope) { mBinding.setScope(checkNotNull(scope, "scope")); } private void setScope(Class<?> clazz) { Annotation[] anns = clazz.getAnnotations(); for (Annotation ann : anns) { if (ApplicationScoped.class.isInstance(ann) || Dependent.class.isInstance(ann) || ContextScoped.class.isInstance(ann)) mBinding.setScope(ann.annotationType()); } } private void validateAnnotation(Class<?> clazz) { AndroidVersion version = clazz.getAnnotation(AndroidVersion.class); if (version != null && Build.VERSION.SDK_INT < version.value()) mBindings.unregister(mBinding); DeviceModel model = clazz.getAnnotation(DeviceModel.class); if (model != null && !Build.MODEL.equals(model.value())) mBindings.unregister(mBinding); } private <I> I checkNotNull(I obj, String msg) { if (obj == null) throw new ConfigurationException(msg); return obj; } }