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