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