001package io.avaje.inject.spi;
002
003import io.avaje.inject.BeanScope;
004import jakarta.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 a dependency.
103   */
104  <T> T get(Class<T> cls);
105
106  /**
107   * Get a named dependency.
108   */
109  <T> T get(Class<T> cls, String name);
110
111  /**
112   * Get a dependency for the generic type.
113   */
114  <T> T get(Type cls);
115
116  /**
117   * Get a named dependency for the generic type.
118   */
119  <T> T get(Type cls, String name);
120
121  /**
122   * Get an optional dependency.
123   */
124  <T> Optional<T> getOptional(Class<T> cls);
125
126  /**
127   * Get an optional named dependency.
128   */
129  <T> Optional<T> getOptional(Class<T> cls, String name);
130
131  /**
132   * Get an optional dependency for the generic type.
133   */
134  <T> Optional<T> getOptional(Type cls);
135
136  /**
137   * Get an optional named dependency for the generic type.
138   */
139  <T> Optional<T> getOptional(Type cls, String name);
140
141  /**
142   * Get an optional dependency potentially returning null.
143   */
144  <T> T getNullable(Class<T> cls);
145
146  /**
147   * Get an optional named dependency potentially returning null.
148   */
149  <T> T getNullable(Class<T> cls, String name);
150
151  /**
152   * Get an optional dependency potentially returning null for the generic type.
153   */
154  <T> T getNullable(Type cls);
155
156  /**
157   * Get an optional named dependency potentially returning null for the generic type.
158   */
159  <T> T getNullable(Type cls, String name);
160
161  /**
162   * Return Provider of T given the type.
163   */
164  <T> Provider<T> getProvider(Class<T> cls);
165
166  /**
167   * Return Provider of T given the type and name.
168   */
169  <T> Provider<T> getProvider(Class<T> cls, String name);
170
171  /**
172   * Return Provider of T given the generic type.
173   */
174  <T> Provider<T> getProvider(Type cls);
175
176  /**
177   * Return Provider of T given the generic type and name.
178   */
179  <T> Provider<T> getProvider(Type cls, String name);
180
181  /**
182   * Return Provider for a generic interface type.
183   *
184   * @param cls  The usual implementation class
185   * @param type The generic interface type
186   */
187  <T> Provider<T> getProviderFor(Class<?> cls, Type type);
188
189  /**
190   * Get a list of dependencies for the type.
191   */
192  <T> List<T> list(Class<T> type);
193
194  /**
195   * Get a list of dependencies for the generic type.
196   */
197  <T> List<T> list(Type type);
198
199  /**
200   * Get a set of dependencies for the type.
201   */
202  <T> Set<T> set(Class<T> type);
203
204  /**
205   * Get a set of dependencies for the generic type.
206   */
207  <T> Set<T> set(Type type);
208
209  /**
210   * Return a map of dependencies for the type keyed by qualifier name.
211   */
212  <T> Map<String, T> map(Class<T> type);
213
214  /**
215   * Return a map of dependencies for the generic type keyed by qualifier name.
216   */
217  <T> Map<String, T> map(Type type);
218
219  /**
220   * Build and return the bean scope.
221   */
222  BeanScope build(boolean withShutdownHook);
223}