package ej.annotation;

import static java.lang.annotation.ElementType.CONSTRUCTOR;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.PACKAGE;
import static java.lang.annotation.ElementType.TYPE;
import javax.annotation.Nonnull;
import javax.annotation.meta.TypeQualifierDefault;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * Indicates that all fields, method return values or parameters can never be <code>null</code> in
 * the annotated package or type.
 * <p>
 * This rule can be overridden on each element by using {@link Nullable} annotation.
 */
@Documented
@Nonnull
@TypeQualifierDefault({ ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.FIELD, ElementType.METHOD, ElementType.PACKAGE, ElementType.PARAMETER, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Target(value = { PACKAGE, TYPE, METHOD, CONSTRUCTOR })
public @interface NonNullByDefault {

    /**
     * When annotating an element with <code>@NonNullByDefault(false)</code>, the
     * default null annotation is not applied. In this case, the appropriate
     * annotation must be specified to each sub-element (<code>@Nullable</code> or
     * <code>@NotNull</code> or none).
     *
     * @return true by default
     */
    boolean value() default true;
}
