001package io.avaje.inject;
002
003import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
004import static java.lang.annotation.ElementType.METHOD;
005import static java.lang.annotation.ElementType.TYPE;
006import static java.lang.annotation.RetentionPolicy.CLASS;
007import static java.lang.annotation.RetentionPolicy.RUNTIME;
008
009import java.lang.annotation.Repeatable;
010import java.lang.annotation.Retention;
011import java.lang.annotation.Target;
012
013/**
014 * Expresses a requirement for a bean to be wired/registered into the {@link BeanScope}.
015 *
016 * <pre>{@code
017 *
018 *   @Factory
019 *   public class MyAutoConfiguration {
020 *
021 *     @Bean
022 *     @RequiresProperty("use.service")
023 *     public MyService myService() {
024 *         ...
025 *     }
026 *
027 *   }
028 *
029 * }</pre>
030 *
031 * <p>
032 * In the sample above the MyService bean will get wired only if <code>use.service</code>
033 * is set in Java system properties / Avaje Config.
034 * <p>
035 * {@link io.avaje.inject.spi.ConfigPropertyPlugin} is used to test the property conditions and is loaded via {@link java.util.ServiceLoader}.
036 * <p>
037 * Avaje Config provides an implementation and if it is included in the classpath then
038 * Avaje Config will be used to test the property conditions.
039 * <p>
040 * If no ConfigPropertyPlugin is found then the default implementation is used which uses
041 * {@link System#getProperty(String)} and {@link System#getenv(String)}.
042 */
043@Retention(CLASS)
044@Repeatable(RequiresProperty.Container.class)
045@Target({TYPE, METHOD, ANNOTATION_TYPE})
046public @interface RequiresProperty {
047
048  /**
049   * Expresses that the given property should be set for the bean to load.
050   *
051   * @return the property to check
052   */
053  String value() default "";
054
055  /**
056   * Expresses that the bean or configuration will only be registered if the given properties are
057   * missing.
058   *
059   * @return the properties to check
060   */
061  String[] missing() default {};
062
063  /**
064   * Used in combination with value() to express the required value of the property.
065   *
066   * @return the value the property should be
067   */
068  String equalTo() default "";
069
070  /**
071   * Constraint a property to not equal the given value.
072   *
073   * @return the value the property should not be
074   */
075  String notEqualTo() default "";
076
077  @Retention(RUNTIME)
078  @Target({TYPE, METHOD, ANNOTATION_TYPE})
079  @interface Container {
080
081    /**
082     * The required dependencies.
083     */
084    RequiresProperty[] value();
085  }
086}