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