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

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

package com.google.inject.internal;

import com.google.inject.Binder;
import com.google.inject.Binding;
import com.google.inject.Key;
import com.google.inject.Provider;
import com.google.inject.spi.ConstructorBinding;
import com.google.inject.spi.ConvertedConstantBinding;
import com.google.inject.spi.ExposedBinding;
import com.google.inject.spi.InjectionPoint;
import com.google.inject.spi.InstanceBinding;
import com.google.inject.spi.LinkedKeyBinding;
import com.google.inject.spi.PrivateElements;
import com.google.inject.spi.ProviderBinding;
import com.google.inject.spi.ProviderInstanceBinding;
import com.google.inject.spi.ProviderKeyBinding;
import com.google.inject.spi.UntargettedBinding;

import java.util.Set;

/**
 * Handles {@link Binder#bind} and {@link Binder#bindConstant} elements.
 */
final class BindingProcessor extends AbstractBindingProcessor {

    private final Initializer initializer;

    BindingProcessor(Errors errors, Initializer initializer, ProcessedBindingData bindingData) {
        super(errors, bindingData);
        this.initializer = initializer;
    }

    @Override
    public  Boolean visit(Binding command) {
        Class rawType = command.getKey().getTypeLiteral().getRawType();
        if (Void.class.equals(rawType)) {
            if (command instanceof ProviderInstanceBinding
                    && ((ProviderInstanceBinding) command).getUserSuppliedProvider()
                    instanceof ProviderMethod) {
                errors.voidProviderMethod();
            } else {
                errors.missingConstantValues();
            }
            return true;
        }

        if (rawType == Provider.class) {
            errors.bindingToProvider();
            return true;
        }

        return command.acceptTargetVisitor(new Processor<>((BindingImpl) command) {
            @Override
            public Boolean visit(ConstructorBinding binding) {
                prepareBinding();
                try {
                    ConstructorBindingImpl onInjector = ConstructorBindingImpl.create(injector, key,
                            binding.getConstructor(), source, scoping, errors, false, false);
                    scheduleInitialization(onInjector);
                    putBinding(onInjector);
                } catch (ErrorsException e) {
                    errors.merge(e.getErrors());
                    putBinding(invalidBinding(injector, key, source));
                }
                return true;
            }

            @Override
            public Boolean visit(InstanceBinding binding) {
                prepareBinding();
                Set injectionPoints = binding.getInjectionPoints();
                T instance = binding.getInstance();
                @SuppressWarnings("unchecked") // safe to cast to binding because
                        // the processor was constructed w/ it
                Initializable ref = initializer.requestInjection(
                        injector, instance, (Binding) binding, source, injectionPoints);
                ConstantFactory factory = new ConstantFactory<>(ref);
                InternalFactory scopedFactory =
                        Scoping.scope(key, injector, factory, source, scoping);
                putBinding(new InstanceBindingImpl<>(injector, key, source,
                        scopedFactory, injectionPoints, instance));
                return true;
            }

            @Override
            public Boolean visit(ProviderInstanceBinding binding) {
                prepareBinding();
                javax.inject.Provider provider = binding.getUserSuppliedProvider();
                if (provider instanceof InternalProviderInstanceBindingImpl.Factory) {
                      @SuppressWarnings("unchecked")
                      InternalProviderInstanceBindingImpl.Factory asProviderMethod =
                                  (InternalProviderInstanceBindingImpl.Factory) provider;
                      return visitInternalProviderInstanceBindingFactory(asProviderMethod);
                    }
                Set injectionPoints = binding.getInjectionPoints();
                Initializable> initializable =
                        initializer.requestInjection(injector, provider, null, source, injectionPoints);
                // always visited with Binding
                @SuppressWarnings("unchecked")
                InternalFactory factory = new InternalFactoryToInitializableAdapter<>(
                        initializable, source,
                        injector.provisionListenerStore.get((ProviderInstanceBinding) binding));
                InternalFactory scopedFactory = Scoping.scope(key, injector, factory, source, scoping);
                putBinding(new ProviderInstanceBindingImpl<>(injector, key, source, scopedFactory, scoping,
                        provider, injectionPoints));
                return true;
            }

            @Override
            public Boolean visit(ProviderKeyBinding binding) {
                prepareBinding();
                Key> providerKey = binding.getProviderKey();
                // always visited with Binding
                @SuppressWarnings("unchecked")
                BoundProviderFactory boundProviderFactory = new BoundProviderFactory<>(
                        injector, providerKey, source,
                        injector.provisionListenerStore.get((ProviderKeyBinding) binding));
                bindingData.addCreationListener(boundProviderFactory);
                InternalFactory scopedFactory = Scoping.scope(
                        key, injector, boundProviderFactory, source, scoping);
                putBinding(new LinkedProviderBindingImpl<>(
                        injector, key, source, scopedFactory, scoping, providerKey));
                return true;
            }

            @Override
            public Boolean visit(LinkedKeyBinding binding) {
                prepareBinding();
                Key linkedKey = binding.getLinkedKey();
                if (key.equals(linkedKey)) {
                    errors.recursiveBinding();
                }
                FactoryProxy factory = new FactoryProxy<>(injector, key, linkedKey, source);
                bindingData.addCreationListener(factory);
                InternalFactory scopedFactory =
                        Scoping.scope(key, injector, factory, source, scoping);
                putBinding(new LinkedBindingImpl<>(injector, key, source, scopedFactory, scoping, linkedKey));
                return true;
            }

            /** Handle ProviderMethods specially. */
            private Boolean visitInternalProviderInstanceBindingFactory(
                    InternalProviderInstanceBindingImpl.Factory provider) {
                InternalProviderInstanceBindingImpl binding =
                        new InternalProviderInstanceBindingImpl<>(
                                injector,
                                key,
                                source,
                                provider,
                                Scoping.scope(key, injector, provider, source, scoping),
                                scoping);
                switch (binding.getInitializationTiming()) {
                    case DELAYED:
                        scheduleDelayedInitialization(binding);
                        break;
                    case EAGER:
                        scheduleInitialization(binding);
                        break;
                    default:
                        throw new AssertionError();
                }
                putBinding(binding);
                return true;
            }

            @Override
            public Boolean visit(UntargettedBinding untargetted) {
                return false;
            }

            @Override
            public Boolean visit(ExposedBinding binding) {
                throw new IllegalArgumentException("Cannot apply a non-module element");
            }

            @Override
            public Boolean visit(ConvertedConstantBinding binding) {
                throw new IllegalArgumentException("Cannot apply a non-module element");
            }

            @Override
            public Boolean visit(ProviderBinding binding) {
                throw new IllegalArgumentException("Cannot apply a non-module element");
            }

            @Override
            protected Boolean visitOther(Binding binding) {
                throw new IllegalStateException("BindingProcessor should override all visitations");
            }
        });
    }

    @Override
    public Boolean visit(PrivateElements privateElements) {
        for (Key key : privateElements.getExposedKeys()) {
            bindExposed(privateElements, key);
        }
        return false; // leave the private elements for the PrivateElementsProcessor to handle
    }

    private  void bindExposed(PrivateElements privateElements, Key key) {
        ExposedKeyFactory exposedKeyFactory = new ExposedKeyFactory<>(key, privateElements);
        bindingData.addCreationListener(exposedKeyFactory);
        putBinding(new ExposedBindingImpl<>(
                injector, privateElements.getExposedSource(key), key, exposedKeyFactory, privateElements));
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy