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 next bean as having Primary priority.
058   * Highest priority, will be used over any other matching beans.
059   */
060  Builder asPrimary();
061
062  /**
063   * Register the next bean as having Secondary priority.
064   * Lowest priority, only used if no other matching beans are available.
065   */
066  Builder asSecondary();
067
068  /**
069   * Register the next bean as having Prototype scope.
070   */
071  Builder asPrototype();
072
073  /**
074   * Register the provider into the context.
075   */
076  <T> void registerProvider(Provider<T> provider);
077
078  /**
079   * Register the bean instance into the context.
080   *
081   * @param bean The bean instance that has been created.
082   */
083  <T> T register(T bean);
084
085  /**
086   * Register the externally provided bean.
087   *
088   * @param type The type of the provided bean.
089   * @param bean The bean instance
090   */
091  <T> void withBean(Class<T> type, T bean);
092
093  /**
094   * Add lifecycle PostConstruct method.
095   */
096  void addPostConstruct(Runnable runnable);
097
098  /**
099   * Add lifecycle PreDestroy method.
100   */
101  void addPreDestroy(AutoCloseable closeable);
102
103  /**
104   * Check if the instance is AutoCloseable and if so register it with PreDestroy.
105   *
106   * @param maybeAutoCloseable An instance that might be AutoCloseable
107   */
108  void addAutoClosable(Object maybeAutoCloseable);
109
110  /**
111   * Add field and method injection.
112   */
113  void addInjector(Consumer<Builder> injector);
114
115  /**
116   * Get a dependency.
117   */
118  <T> T get(Class<T> cls);
119
120  /**
121   * Get a named dependency.
122   */
123  <T> T get(Class<T> cls, String name);
124
125  /**
126   * Get a dependency for the generic type.
127   */
128  <T> T get(Type cls);
129
130  /**
131   * Get a named dependency for the generic type.
132   */
133  <T> T get(Type cls, String name);
134
135  /**
136   * Get an optional dependency.
137   */
138  <T> Optional<T> getOptional(Class<T> cls);
139
140  /**
141   * Get an optional named dependency.
142   */
143  <T> Optional<T> getOptional(Class<T> cls, String name);
144
145  /**
146   * Get an optional dependency for the generic type.
147   */
148  <T> Optional<T> getOptional(Type cls);
149
150  /**
151   * Get an optional named dependency for the generic type.
152   */
153  <T> Optional<T> getOptional(Type cls, String name);
154
155  /**
156   * Get an optional dependency potentially returning null.
157   */
158  <T> T getNullable(Class<T> cls);
159
160  /**
161   * Get an optional named dependency potentially returning null.
162   */
163  <T> T getNullable(Class<T> cls, String name);
164
165  /**
166   * Get an optional dependency potentially returning null for the generic type.
167   */
168  <T> T getNullable(Type cls);
169
170  /**
171   * Get an optional named dependency potentially returning null for the generic type.
172   */
173  <T> T getNullable(Type cls, String name);
174
175  /**
176   * Return Provider of T given the type.
177   */
178  <T> Provider<T> getProvider(Class<T> cls);
179
180  /**
181   * Return Provider of T given the type and name.
182   */
183  <T> Provider<T> getProvider(Class<T> cls, String name);
184
185  /**
186   * Return Provider of T given the generic type.
187   */
188  <T> Provider<T> getProvider(Type cls);
189
190  /**
191   * Return Provider of T given the generic type and name.
192   */
193  <T> Provider<T> getProvider(Type cls, String name);
194
195  /**
196   * Return Provider for a generic interface type.
197   *
198   * @param cls  The usual implementation class
199   * @param type The generic interface type
200   */
201  <T> Provider<T> getProviderFor(Class<?> cls, Type type);
202
203  /**
204   * Get a list of dependencies for the type.
205   */
206  <T> List<T> list(Class<T> type);
207
208  /**
209   * Get a list of dependencies for the generic type.
210   */
211  <T> List<T> list(Type type);
212
213  /**
214   * Get a set of dependencies for the type.
215   */
216  <T> Set<T> set(Class<T> type);
217
218  /**
219   * Get a set of dependencies for the generic type.
220   */
221  <T> Set<T> set(Type type);
222
223  /**
224   * Return a map of dependencies for the type keyed by qualifier name.
225   */
226  <T> Map<String, T> map(Class<T> type);
227
228  /**
229   * Return a map of dependencies for the generic type keyed by qualifier name.
230   */
231  <T> Map<String, T> map(Type type);
232
233  /**
234   * Build and return the bean scope.
235   */
236  BeanScope build(boolean withShutdownHook);
237}