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 profiles       Explicit profiles used
022   * @param suppliedBeans  The list of beans (typically test doubles) supplied when building the context.
023   * @param enrichBeans    The list of classes we want to have with mockito spy enhancement
024   * @param parent         The parent BeanScope
025   * @param parentOverride When false do not add beans that already exist on the parent
026   */
027  @SuppressWarnings("rawtypes")
028  static Builder newBuilder(Set<String> profiles, ConfigPropertyPlugin plugin, List<SuppliedBean> suppliedBeans, List<EnrichBean> enrichBeans, BeanScope parent, boolean parentOverride) {
029    if (suppliedBeans.isEmpty() && enrichBeans.isEmpty()) {
030      // simple case, no mocks or spies
031      return new DBuilder(profiles, plugin, parent, parentOverride);
032    }
033    return new DBuilderExtn(profiles, plugin, parent, parentOverride, suppliedBeans, enrichBeans);
034  }
035
036  /**
037   * Return true if the bean should be created and registered with the context.
038   * <p>
039   * Returning false means there has been a supplied bean already registered and
040   * that we should skip the creation and registration for this bean.
041   *
042   * @param name  The qualifier name
043   * @param types The types that the bean implements and provides
044   */
045  boolean isBeanAbsent(String name, Type... types);
046
047  /**
048   * Return true if the bean should be created and registered with the context.
049   * <p>
050   * Returning false means there has been a supplied bean already registered and
051   * that we should skip the creation and registration for this bean.
052   *
053   * @param types The types that the bean implements and provides
054   */
055  default boolean isBeanAbsent(Type... types) {
056    return isBeanAbsent(null, types);
057  }
058
059  /**
060   * Register the next bean as having Primary priority.
061   * Highest priority, will be used over any other matching beans.
062   */
063  Builder asPrimary();
064
065  /**
066   * Register the next bean as having Secondary priority.
067   * Lowest priority, only used if no other matching beans are available.
068   */
069  Builder asSecondary();
070
071  /**
072   * Register the next bean as having Prototype scope.
073   */
074  Builder asPrototype();
075
076  /**
077   * Register the provider into the context.
078   */
079  <T> void registerProvider(Provider<T> provider);
080
081
082  /**
083   * Register the bean instance into the context.
084   *
085   * @param bean The bean instance that has been created.
086   */
087  <T> T register(T bean);
088
089  /**
090   * Register the externally provided bean.
091   *
092   * @param type The type of the provided bean.
093   * @param bean The bean instance
094   */
095  <T> void withBean(Class<T> type, T bean);
096
097  /**
098   * Add lifecycle PostConstruct method.
099   */
100  void addPostConstruct(Runnable runnable);
101
102  /**
103   * Add lifecycle PostConstruct method.
104   */
105  void addPostConstruct(Consumer<BeanScope> consumer);
106
107  /**
108   * Add lifecycle PreDestroy method.
109   */
110  void addPreDestroy(AutoCloseable closeable);
111
112  /**
113   * Add lifecycle PreDestroy method with a given priority.
114   */
115  void addPreDestroy(AutoCloseable closeable, int priority);
116
117  /**
118   * Check if the instance is AutoCloseable and if so register it with PreDestroy.
119   *
120   * @param maybeAutoCloseable An instance that might be AutoCloseable
121   */
122  void addAutoClosable(Object maybeAutoCloseable);
123
124  /**
125   * Add field and method injection.
126   */
127  void addInjector(Consumer<Builder> injector);
128
129  /**
130   * Get a dependency.
131   */
132  <T> T get(Class<T> cls);
133
134  /**
135   * Get a named dependency.
136   */
137  <T> T get(Class<T> cls, String name);
138
139  /**
140   * Get a dependency for the generic type.
141   */
142  <T> T get(Type cls);
143
144  /**
145   * Get a named dependency for the generic type.
146   */
147  <T> T get(Type cls, String name);
148
149  /**
150   * Get an optional dependency.
151   */
152  <T> Optional<T> getOptional(Class<T> cls);
153
154  /**
155   * Get an optional named dependency.
156   */
157  <T> Optional<T> getOptional(Class<T> cls, String name);
158
159  /**
160   * Get an optional dependency for the generic type.
161   */
162  <T> Optional<T> getOptional(Type cls);
163
164  /**
165   * Get an optional named dependency for the generic type.
166   */
167  <T> Optional<T> getOptional(Type cls, String name);
168
169  /**
170   * Get an optional dependency potentially returning null.
171   */
172  <T> T getNullable(Class<T> cls);
173
174  /**
175   * Get an optional named dependency potentially returning null.
176   */
177  <T> T getNullable(Class<T> cls, String name);
178
179  /**
180   * Get an optional dependency potentially returning null for the generic type.
181   */
182  <T> T getNullable(Type cls);
183
184  /**
185   * Get an optional named dependency potentially returning null for the generic type.
186   */
187  <T> T getNullable(Type cls, String name);
188
189  /**
190   * Return Provider of T given the type.
191   */
192  <T> Provider<T> getProvider(Class<T> cls);
193
194  /**
195   * Return Provider of T given the type and name.
196   */
197  <T> Provider<T> getProvider(Class<T> cls, String name);
198
199  /**
200   * Return Provider of T given the generic type.
201   */
202  <T> Provider<T> getProvider(Type cls);
203
204  /**
205   * Return Provider of T given the generic type and name.
206   */
207  <T> Provider<T> getProvider(Type cls, String name);
208
209  /**
210   * Return Provider for a generic interface type.
211   *
212   * @param cls  The usual implementation class
213   * @param type The generic interface type
214   */
215  <T> Provider<T> getProviderFor(Class<?> cls, Type type);
216
217  /**
218   * Get a list of dependencies for the type.
219   */
220  <T> List<T> list(Class<T> type);
221
222  /**
223   * Get a list of dependencies for the generic type.
224   */
225  <T> List<T> list(Type type);
226
227  /**
228   * Get a set of dependencies for the type.
229   */
230  <T> Set<T> set(Class<T> type);
231
232  /**
233   * Get a set of dependencies for the generic type.
234   */
235  <T> Set<T> set(Type type);
236
237  /**
238   * Return a map of dependencies for the type keyed by qualifier name.
239   */
240  <T> Map<String, T> map(Class<T> type);
241
242  /**
243   * Return a map of dependencies for the generic type keyed by qualifier name.
244   */
245  <T> Map<String, T> map(Type type);
246
247  /**
248   * Return true if the builder contains the given type.
249   */
250  boolean contains(Type type);
251
252  /**
253   * Return true if the builder contains the given type.
254   */
255  boolean contains(String type);
256
257  /**
258   * Return true if the builder contains a bean with the given name.
259   */
260  boolean containsQualifier(String name);
261
262  /**
263   * Return true if the builder contains the given profile
264   */
265  boolean containsProfiles(List<String> type);
266
267  /**
268   * Return true if the builder contains all of the given profile
269   */
270  boolean containsAllProfiles(List<String> type);
271
272  /**
273   * Return the plugin for required properties.
274   */
275  ConfigPropertyPlugin property();
276
277  /**
278   * Build and return the bean scope.
279   */
280  BeanScope build(boolean withShutdownHook, long start);
281
282  /**
283   * Set the current module being wired.
284   */
285  void currentModule(Class<? extends AvajeModule> currentModule);
286}