All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.javabits.yar.guice.RegistryBinderImpl Maven / Gradle / Ivy

There is a newer version: 3.0.1.RELEASE
Show newest version
package org.javabits.yar.guice;

import com.google.common.annotations.Beta;
import com.google.inject.*;
import com.google.inject.binder.AnnotatedBindingBuilder;
import com.google.inject.binder.AnnotatedConstantBindingBuilder;
import com.google.inject.binder.LinkedBindingBuilder;
import com.google.inject.matcher.Matcher;
import com.google.inject.spi.*;
import org.aopalliance.intercept.MethodInterceptor;
import org.javabits.yar.BlockingSupplier;
import org.javabits.yar.Supplier;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.List;

/**
 * This class is responsible to implement the {@link RegistryBinder} interface
 * and forward the non overloaded methods of {@code Binder} to a delegate.
 */
class RegistryBinderImpl implements RegistryBinder {
    private final Binder binder;

    public RegistryBinderImpl(Binder binder) {
        this.binder = binder;
    }

    @Beta
    @Override
    public  void bindRegistryListener(Matcher> matcher, Key> key) {
        if (isBlockingSupplier(matcher)) {
            throw new IllegalArgumentException("Only simple Supplier are supported. BlockingSupplier are only available as injectable element (constructor/field/method param).");
        } else if (isSupplier(matcher)) {
            throw new IllegalArgumentException("Only simple Supplier are supported. Supplier are only available as injectable element (constructor/field/method param).");
        } else {
            binder.bind(Key.get(GuiceWatcherRegistration.class, UniqueAnnotations.create())).toInstance(GuiceWatcherRegistration.get(matcher, key));
        }
    }

    private   boolean isBlockingSupplier(Matcher> matcher) {
        return isBlockingSupplier(Matchers.getTargetTypeLiteral(matcher));  //To change body of created methods use File | Settings | File Templates.
    }

    private   boolean isSupplier(Matcher> matcher) {
        return isSupplier(Matchers.getTargetTypeLiteral(matcher));
    }

    @Beta
    @Override
    public  void bindRegistryListener(Matcher> matcher, RegistryListener listener) {
        if (isBlockingSupplier(matcher)) {
            throw new IllegalArgumentException("Only simple Type are supported. BlockingSupplier are only available as injectable element (constructor/field/method param).");
        } else if (isSupplier(matcher)) {
            throw new IllegalArgumentException("Only simple Supplier are supported. Supplier are only available as injectable element (constructor/field/method param).");
        } else {
            binder.bind(Key.get(GuiceWatcherRegistration.class, UniqueAnnotations.create())).toInstance(GuiceWatcherRegistration.get(matcher, listener));
        }
        binder.requestInjection(listener);
    }

    @Override
    public  RegistrationLinkedBindingBuilder register(Key key) {
        return new RegistrationBindingBuilderImpl<>(binder, key);
    }

    @Override
    public  RegistrationAnnotatedBindingBuilder register(TypeLiteral typeLiteral) {
        return new RegistrationBindingBuilderImpl<>(binder, typeLiteral);
    }
    // TODO cannot be scoped
    @Override
    public  RegistrationAnnotatedBindingBuilder register(Class type) {
        return new RegistrationBindingBuilderImpl<>(binder, type);
    }

    @Override
    public  RegistryLinkedBindingBuilder bind(Key key) {
        LinkedBindingBuilder bindingBuilder = binder.bind(key);
        return getRegistryBindingBuilderFactory(key).newFrom(key, bindingBuilder);
    }

    @Override
    public  RegistryAnnotatedBindingBuilder bind(TypeLiteral typeLiteral) {
        AnnotatedBindingBuilder bindingBuilder = binder.bind(typeLiteral);
        return getRegistryBindingBuilderFactory(typeLiteral).newFrom(typeLiteral, bindingBuilder);
    }

    @Override
    public  RegistryAnnotatedBindingBuilder bind(Class clazz) {
        AnnotatedBindingBuilder bindingBuilder = binder.bind(clazz);
        return new DefaultRegistryAnnotatedBindingBuilderImpl<>(binder, clazz, bindingBuilder);
    }

    //Guice Binder delegation ------------------------------------------------

    @Override
    public void bindInterceptor(Matcher> classMatcher, Matcher methodMatcher, MethodInterceptor... interceptors) {
        binder.bindInterceptor(classMatcher, methodMatcher, interceptors);
    }

    @Override
    public void bindScope(Class annotationType, Scope scope) {
        binder.bindScope(annotationType, scope);
    }

    @Override
    public AnnotatedConstantBindingBuilder bindConstant() {
        return binder.bindConstant();
    }

    @Override
    public  void requestInjection(TypeLiteral type, T instance) {
        binder.requestInjection(type, instance);
    }

    @Override
    public void requestInjection(Object instance) {
        binder.requestInjection(instance);
    }

    @Override
    public void requestStaticInjection(Class... types) {
        binder.requestStaticInjection(types);
    }

    @Override
    public void install(Module module) {
        binder.install(module);
    }

    @Override
    public Stage currentStage() {
        return binder.currentStage();
    }

    @Override
    public void addError(String message, Object... arguments) {
        binder.addError(message, arguments);
    }

    @Override
    public void addError(Throwable t) {
        binder.addError(t);
    }

    @Override
    public void addError(Message message) {
        binder.addError(message);
    }

    @Override
    public  Provider getProvider(Key key) {
        return binder.getProvider(key);
    }

    @Override
    public  Provider getProvider(Class type) {
        return binder.getProvider(type);
    }

    @Override
    public  MembersInjector getMembersInjector(TypeLiteral typeLiteral) {
        return binder.getMembersInjector(typeLiteral);
    }

    @Override
    public  MembersInjector getMembersInjector(Class type) {
        return binder.getMembersInjector(type);
    }

    @Override
    public void convertToTypes(Matcher> typeMatcher, TypeConverter converter) {
        binder.convertToTypes(typeMatcher, converter);
    }

    @Override
    public void bindListener(Matcher> typeMatcher, TypeListener listener) {
        binder.bindListener(typeMatcher, listener);
    }

    @Override
    public Binder withSource(Object source) {
        return binder.withSource(source);
    }

    @Override
    public Binder skipSources(Class... classesToSkip) {
        return binder.skipSources(classesToSkip);
    }

    @Override
    public PrivateBinder newPrivateBinder() {
        return binder.newPrivateBinder();
    }

    @Override
    public void requireExplicitBindings() {
        binder.requireExplicitBindings();
    }

    @Override
    public void disableCircularProxies() {
        binder.disableCircularProxies();
    }

    @Override
    public  Provider getProvider(Dependency dependency) {
        return binder.getProvider(dependency);
    }

    @Override
    public void bindListener(Matcher> matcher, ProvisionListener... provisionListeners) {
        binder.bindListener(matcher, provisionListeners);
    }

    @Override
    public void requireAtInjectOnConstructors() {
        binder.requireAtInjectOnConstructors();
    }

    @Override
    public void requireExactBindingAnnotations() {
        binder.requireExactBindingAnnotations();
    }

    @Override
    public void scanModulesForAnnotatedMethods(ModuleAnnotatedMethodScanner moduleAnnotatedMethodScanner) {
        binder.scanModulesForAnnotatedMethods(moduleAnnotatedMethodScanner);
    }

    //------------------------------------------------------------------------


    private   RegistryBindingBuilderFactory getRegistryBindingBuilderFactory(Key key) {
        return getRegistryBindingBuilderFactory(key.getTypeLiteral());
    }

    private   RegistryBindingBuilderFactory getRegistryBindingBuilderFactory(TypeLiteral typeLiteral) {
        if (isBlockingSupplier(typeLiteral) || isSupplier(typeLiteral)) {
            return new BlockingSupplierRegistryBindingBuilderFactory();
        } else if (isSupportedCollectionsInterface(typeLiteral)) {
            return new CollectionsRegistryBindingBuilderFactory();
        } else {
            return new SimpleRegistryBindingBuilderFactory();
        }
    }

    private   boolean isBlockingSupplier(TypeLiteral typeLiteral) {
        return BlockingSupplier.class.isAssignableFrom(typeLiteral.getRawType());
    }

    private   boolean isSupplier(TypeLiteral typeLiteral) {
        return Supplier.class.isAssignableFrom(typeLiteral.getRawType())
                || java.util.function.Supplier.class.isAssignableFrom(typeLiteral.getRawType())
                || com.google.common.base.Supplier.class.isAssignableFrom(typeLiteral.getRawType());
    }

    private   boolean isSupportedCollectionsInterface(TypeLiteral typeLiteral) {
        return isClassEqualsToLiteralRowType(List.class, typeLiteral)
                || isClassEqualsToLiteralRowType(Collection.class, typeLiteral)
                || isClassEqualsToLiteralRowType(Iterable.class, typeLiteral);
    }

    private  boolean isClassEqualsToLiteralRowType(Class type, TypeLiteral typeLiteral) {
        return type.equals(typeLiteral.getRawType());
    }

    private interface RegistryBindingBuilderFactory {
         RegistryAnnotatedBindingBuilder newFrom(TypeLiteral typeLiteral, AnnotatedBindingBuilder bindingBuilder);

         RegistryLinkedBindingBuilder newFrom(Key key, LinkedBindingBuilder bindingBuilder);
    }

    private class SimpleRegistryBindingBuilderFactory implements RegistryBindingBuilderFactory {
        @Override
        public  RegistryAnnotatedBindingBuilder newFrom(TypeLiteral typeLiteral, AnnotatedBindingBuilder bindingBuilder) {
            return new DefaultRegistryAnnotatedBindingBuilderImpl<>(binder, typeLiteral, bindingBuilder);
        }

        @Override
        public  RegistryLinkedBindingBuilder newFrom(Key key, LinkedBindingBuilder bindingBuilder) {
            return new DefaultRegistryAnnotatedBindingBuilderImpl<>(binder, key, bindingBuilder);
        }
    }

    private class BlockingSupplierRegistryBindingBuilderFactory implements RegistryBindingBuilderFactory {
        @Override
        public  RegistryAnnotatedBindingBuilder newFrom(TypeLiteral typeLiteral, AnnotatedBindingBuilder bindingBuilder) {
            return new BlockingSupplierRegistryAnnotatedBindingBuilderImpl<>(binder, typeLiteral, bindingBuilder);
        }

        @Override
        public  RegistryLinkedBindingBuilder newFrom(Key key, LinkedBindingBuilder bindingBuilder) {
            return new BlockingSupplierRegistryAnnotatedBindingBuilderImpl<>(binder, key, bindingBuilder);
        }
    }

    private class CollectionsRegistryBindingBuilderFactory implements RegistryBindingBuilderFactory {
        @Override
        public  RegistryAnnotatedBindingBuilder newFrom(TypeLiteral typeLiteral, AnnotatedBindingBuilder bindingBuilder) {
            return new CollectionsRegistryAnnotatedBindingBuilderImpl<>(binder, typeLiteral, bindingBuilder);
        }

        @Override
        public  RegistryLinkedBindingBuilder newFrom(Key key, LinkedBindingBuilder bindingBuilder) {
            return new CollectionsRegistryAnnotatedBindingBuilderImpl<>(binder, key, bindingBuilder);
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy