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;
}
