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