001package io.avaje.inject.spi;
002
003import io.avaje.inject.BeanScope;
004import javax.inject.Provider;
005
006import java.lang.reflect.Type;
007import java.util.List;
008import java.util.Map;
009import java.util.Optional;
010import java.util.Set;
011import java.util.function.Consumer;
012
013/**
014 * Mutable builder object used when building a bean scope.
015 */
016public interface Builder {
017
018  /**
019   * Create the root level Builder.
020   *
021   * @param suppliedBeans  The list of beans (typically test doubles) supplied when building the context.
022   * @param enrichBeans    The list of classes we want to have with mockito spy enhancement
023   * @param parent         The parent BeanScope
024   * @param parentOverride When false do not add beans that already exist on the parent
025   */
026  @SuppressWarnings("rawtypes")
027  static Builder newBuilder(List<SuppliedBean> suppliedBeans, List<EnrichBean> enrichBeans, BeanScope parent, boolean parentOverride) {
028    if (suppliedBeans.isEmpty() && enrichBeans.isEmpty()) {
029      // simple case, no mocks or spies
030      return new DBuilder(parent, parentOverride);
031    }
032    return new DBuilderExtn(parent, parentOverride, suppliedBeans, enrichBeans);
033  }
034
035  /**
036   * Return true if the bean should be created and registered with the context.
037   * <p/>
038   * Returning false means there has been a supplied bean already registered and
039   * that we should skip the creation and registration for this bean.
040   *
041   * @param name  The qualifier name
042   * @param types The types that the bean implements and provides
043   */
044  boolean isAddBeanFor(String name, Type... types);
045
046  /**
047   * Return true if the bean should be created and registered with the context.
048   * <p/>
049   * Returning false means there has been a supplied bean already registered and
050   * that we should skip the creation and registration for this bean.
051   *
052   * @param types The types that the bean implements and provides
053   */
054  boolean isAddBeanFor(Type... types);
055
056  /**
057   * Register the provider into the context.
058   */
059  <T> void registerProvider(Provider<T> provider);
060
061  /**
062   * Register the bean instance into the context.
063   *
064   * @param bean The bean instance that has been created.
065   */
066  <T> T register(T bean);
067
068  /**
069   * Register the bean as a Primary bean.
070   */
071  <T> T registerPrimary(T bean);
072
073  /**
074   * Register the bean as a secondary bean.
075   */
076  <T> T registerSecondary(T bean);
077
078  /**
079   * Register the externally provided bean.
080   *
081   * @param type The type of the provided bean.
082   * @param bean The bean instance
083   */
084  <T> void withBean(Class<T> type, T bean);
085
086  /**
087   * Add lifecycle PostConstruct method.
088   */
089  void addPostConstruct(Runnable runnable);
090
091  /**
092   * Add lifecycle PreDestroy method.
093   */
094  void addPreDestroy(AutoCloseable closeable);
095
096  /**
097   * Add field and method injection.
098   */
099  void addInjector(Consumer<Builder> injector);
100
101  /**
102   * Get an optional dependency.
103   */
104  <T> Optional<T> getOptional(Type cls);
105
106  /**
107   * Get an optional named dependency.
108   */
109  <T> Optional<T> getOptional(Type cls, String name);
110
111  /**
112   * Get an optional dependency potentially returning null.
113   */
114  <T> T getNullable(Type cls);
115
116  /**
117   * Get an optional named dependency potentially returning null.
118   */
119  <T> T getNullable(Type cls, String name);
120
121  /**
122   * Return Provider of T given the type.
123   */
124  <T> Provider<T> getProvider(Type cls);
125
126  /**
127   * Return Provider of T given the type and name.
128   */
129  <T> Provider<T> getProvider(Type cls, String name);
130
131  /**
132   * Return Provider for a generic interface type.
133   *
134   * @param cls  The usual implementation class
135   * @param type The generic interface type
136   */
137  <T> Provider<T> getProviderFor(Class<?> cls, Type type);
138
139  /**
140   * Get a dependency.
141   */
142  <T> T get(Type cls);
143
144  /**
145   * Get a named dependency.
146   */
147  <T> T get(Type cls, String name);
148
149  /**
150   * Get a list of dependencies for the type.
151   */
152  <T> List<T> list(Type interfaceType);
153
154  /**
155   * Get a set of dependencies for the type.
156   */
157  <T> Set<T> set(Type interfaceType);
158
159  /**
160   * Return a map of dependencies keyed by qualifier name.
161   */
162  <T> Map<String, T> map(Type interfaceType);
163
164  /**
165   * Build and return the bean scope.
166   */
167  BeanScope build(boolean withShutdownHook);
168}