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

com.google.inject.internal.BindingBuilder Maven / Gradle / Ivy

package com.google.inject.internal;

import com.google.common.collect.ImmutableSet;
import com.google.inject.Binder;
import com.google.inject.ConfigurationException;
import com.google.inject.Key;
import com.google.inject.Provider;
import com.google.inject.TypeLiteral;
import com.google.inject.binder.AnnotatedBindingBuilder;
import com.google.inject.binder.ScopedBindingBuilder;
import com.google.inject.spi.Element;
import com.google.inject.spi.InjectionPoint;
import com.google.inject.spi.Message;

import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.util.List;
import java.util.Set;

import static com.google.common.base.Preconditions.checkNotNull;

/**
 * Bind a non-constant key.
 */
public class BindingBuilder extends AbstractBindingBuilder
        implements AnnotatedBindingBuilder {

    public BindingBuilder(Binder binder, List elements, Object source, Key key) {
        super(binder, elements, source, key);
    }

    @Override
    public BindingBuilder annotatedWith(Class annotationType) {
        annotatedWithInternal(annotationType);
        return this;
    }

    @Override
    public BindingBuilder annotatedWith(Annotation annotation) {
        annotatedWithInternal(annotation);
        return this;
    }

    @Override
    public BindingBuilder to(Class implementation) {
        return to(Key.get(implementation));
    }

    @Override
    public BindingBuilder to(TypeLiteral implementation) {
        return to(Key.get(implementation));
    }

    @Override
    public BindingBuilder to(Key linkedKey) {
        checkNotNull(linkedKey, "linkedKey");
        checkNotTargetted();
        BindingImpl base = getBinding();
        setBinding(new LinkedBindingImpl(
                base.getSource(), base.getKey(), base.getScoping(), linkedKey));
        return this;
    }

    @Override
    public void toInstance(T instance) {
        checkNotTargetted();

        // lookup the injection points, adding any errors to the binder's errors list
        Set injectionPoints;
        if (instance != null) {
            try {
                injectionPoints = InjectionPoint.forInstanceMethodsAndFields(instance.getClass());
            } catch (ConfigurationException e) {
                copyErrorsToBinder(e);
                injectionPoints = e.getPartialValue();
            }
        } else {
            binder.addError(BINDING_TO_NULL);
            injectionPoints = ImmutableSet.of();
        }

        BindingImpl base = getBinding();
        setBinding(new InstanceBindingImpl(
                base.getSource(), base.getKey(), Scoping.EAGER_SINGLETON, injectionPoints, instance));
    }

    @SuppressWarnings("unchecked")
    @Override
    public BindingBuilder toProvider(Provider provider) {
        return toProvider((javax.inject.Provider) provider);
    }

    @Override
    public BindingBuilder toProvider(javax.inject.Provider provider) {
        checkNotNull(provider, "provider");
        checkNotTargetted();

        // lookup the injection points, adding any errors to the binder's errors list
        Set injectionPoints;
        try {
            injectionPoints = InjectionPoint.forInstanceMethodsAndFields(provider.getClass());
        } catch (ConfigurationException e) {
            copyErrorsToBinder(e);
            injectionPoints = e.getPartialValue();
        }

        BindingImpl base = getBinding();
        setBinding(new ProviderInstanceBindingImpl(
                base.getSource(), base.getKey(), base.getScoping(), injectionPoints, provider));
        return this;
    }

    @Override
    public BindingBuilder toProvider(
            Class> providerType) {
        return toProvider(Key.get(providerType));
    }

    @Override
    public BindingBuilder toProvider(
            TypeLiteral> providerType) {
        return toProvider(Key.get(providerType));
    }

    @Override
    public BindingBuilder toProvider(
            Key> providerKey) {
        checkNotNull(providerKey, "providerKey");
        checkNotTargetted();

        BindingImpl base = getBinding();
        setBinding(new LinkedProviderBindingImpl(
                base.getSource(), base.getKey(), base.getScoping(), providerKey));
        return this;
    }

    @Override
    public  ScopedBindingBuilder toConstructor(Constructor constructor) {
        return toConstructor(constructor, TypeLiteral.get(constructor.getDeclaringClass()));
    }

    @Override
    public  ScopedBindingBuilder toConstructor(Constructor constructor,
                                                            TypeLiteral type) {
        checkNotNull(constructor, "constructor");
        checkNotNull(type, "type");
        checkNotTargetted();

        BindingImpl base = getBinding();

        Set injectionPoints;
        try {
            injectionPoints = InjectionPoint.forInstanceMethodsAndFields(type);
        } catch (ConfigurationException e) {
            copyErrorsToBinder(e);
            injectionPoints = e.getPartialValue();
        }

        try {
            InjectionPoint constructorPoint = InjectionPoint.forConstructor(constructor, type);
            setBinding(new ConstructorBindingImpl(base.getKey(), base.getSource(), base.getScoping(),
                    constructorPoint, injectionPoints));
        } catch (ConfigurationException e) {
            copyErrorsToBinder(e);
        }

        return this;
    }

    @Override
    public String toString() {
        return "BindingBuilder<" + getBinding().getKey().getTypeLiteral() + ">";
    }

    private void copyErrorsToBinder(ConfigurationException e) {
        for (Message message : e.getErrorMessages()) {
            binder.addError(message);
        }
    }
}