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

toothpick.InternalProviderImpl Maven / Gradle / Ivy

There is a newer version: 3.1.0
Show newest version
package toothpick;

import javax.inject.Provider;
import toothpick.registries.FactoryRegistryLocator;

/**
 * A non thread safe internal provider. It should never be exposed outside of Toothpick.
 *
 * @param  the class of the instances provided by this provider.
 */
public class InternalProviderImpl {
  private volatile T instance;
  private Factory factory;
  private Class factoryClass;
  private volatile Provider providerInstance;
  private Factory> providerFactory;
  private Class> providerFactoryClass;

  protected boolean isProvidingSingletonInScope;
  private boolean isCreatingSingletonInScope;

  public InternalProviderImpl(T instance) {
    if (instance == null) {
      throw new IllegalArgumentException("The instance can't be null.");
    }

    this.instance = instance;
  }

  public InternalProviderImpl(Provider providerInstance, boolean isProvidingSingletonInScope) {
    if (providerInstance == null) {
      throw new IllegalArgumentException("The provider can't be null.");
    }

    this.providerInstance = providerInstance;
    this.isProvidingSingletonInScope = isProvidingSingletonInScope;
  }

  public InternalProviderImpl(Factory factory, boolean isProviderFactory) {
    if (factory == null) {
      throw new IllegalArgumentException("The factory can't be null.");
    }

    if (isProviderFactory) {
      this.providerFactory = (Factory>) factory;
    } else {
      this.factory = (Factory) factory;
    }
  }

  public InternalProviderImpl(Class factoryKeyClass,
      boolean isProviderFactoryClass,
      boolean isCreatingSingletonInScope,
      boolean isProvidingSingletonInScope) {
    if (factoryKeyClass == null) {
      throw new IllegalArgumentException("The factory class can't be null.");
    }

    if (isProviderFactoryClass) {
      this.providerFactoryClass = (Class>) factoryKeyClass;
    } else {
      this.factoryClass = (Class) factoryKeyClass;
    }
    this.isCreatingSingletonInScope = isCreatingSingletonInScope;
    this.isProvidingSingletonInScope = isProvidingSingletonInScope;
  }

  //we lock on the unbound provider itself to prevent concurrent usage
  //of the unbound provider (
  public synchronized T get(Scope scope) {
    if (instance != null) {
      return instance;
    }

    if (providerInstance != null) {
      if (isProvidingSingletonInScope) {
        instance = providerInstance.get();
        //gc
        providerInstance = null;
        return instance;
      }

      return providerInstance.get();
    }

    if (factoryClass != null && factory == null) {
      factory = FactoryRegistryLocator.getFactory(factoryClass);
      //gc
      factoryClass = null;
    }

    if (factory != null) {
      if (!factory.hasScopeAnnotation() && !isCreatingSingletonInScope) {
        return factory.createInstance(scope);
      }
      instance = factory.createInstance(scope);
      //gc
      factory = null;
      return instance;
    }

    if (providerFactoryClass != null && providerFactory == null) {
      providerFactory = FactoryRegistryLocator.getFactory(providerFactoryClass);
      //gc
      providerFactoryClass = null;
    }

    if (providerFactory != null) {
      if (providerFactory.hasProvidesSingletonInScopeAnnotation() || isProvidingSingletonInScope) {
        instance = providerFactory.createInstance(scope).get();
        //gc
        providerFactory = null;
        return instance;
      }
      if (providerFactory.hasScopeAnnotation() || isCreatingSingletonInScope) {
        providerInstance = providerFactory.createInstance(scope);
        //gc
        providerFactory = null;
        return providerInstance.get();
      }

      return providerFactory.createInstance(scope).get();
    }

    throw new IllegalStateException("A provider can only be used with an instance, a provider, a factory or a provider factory. Should not happen.");
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy