001package react4j.annotations; 002 003import arez.annotations.Memoize; 004import arez.annotations.Observable; 005import arez.annotations.Observe; 006import java.lang.annotation.Documented; 007import java.lang.annotation.ElementType; 008import java.lang.annotation.Target; 009import javax.annotation.Nonnull; 010 011/** 012 * Annotation used to specify an input. 013 * The property is extracted from Reacts underlying props object. By default the input is passed as a 014 * value in when creating the view but it can also be retrieved from the react context. 015 * When applied to an abstract method, the input is mutable. 016 * When applied to a constructor parameter, the input is immutable. 017 * 018 * <p>If applied to a method, the method that is annotated with this annotation must also comply with the 019 * following constraints:</p> 020 * <ul> 021 * <li>Must not be annotated with any other react annotation</li> 022 * <li>Must have 0 parameters</li> 023 * <li>Must return a value</li> 024 * <li>Must be an abstract instance method</li> 025 * <li>Must not throw exceptions</li> 026 * <li>Must be accessible from the same package as the class annotated by {@link View}</li> 027 * <li> 028 * Should not be public as not expected to be invoked outside the view. A warning will be generated but can 029 * be suppressed by the {@link SuppressWarnings} or {@link SuppressReact4jWarnings} annotations with a key 030 * "React4j:PublicMethod". This warning is also suppressed by the annotation processor if it is implementing 031 * an interface method. 032 * </li> 033 * <li> 034 * Should not be protected if in the class annotated with the {@link View} annotation as the method is not 035 * expected to be invoked outside the view. A warning will be generated but can be suppressed by the 036 * {@link SuppressWarnings} or {@link SuppressReact4jWarnings} annotations with a key "React4j:ProtectedMethod". 037 * </li> 038 * <li> 039 * Should be annotated with either {@link javax.annotation.Nonnull} or {@link javax.annotation.Nullable} if the 040 * return type is not a primitive. A warning will be generated but can be suppressed by the {@link SuppressWarnings} 041 * or {@link SuppressReact4jWarnings} annotations with a key "React4j:MissingInputNullability". 042 * </li> 043 * </ul> 044 */ 045@Documented 046@Target( { ElementType.METHOD, ElementType.PARAMETER } ) 047public @interface Input 048{ 049 /** 050 * Return the name of the input. 051 * The name is the key used when accessing the input from the inputs object. It is also used when creating 052 * the builder steps associated with inputs that are not sourced from tree context. 053 * 054 * @return the name of the input. 055 */ 056 @Nonnull 057 String name() default "<default>"; 058 059 /** 060 * Return the qualifier used to access value from context. 061 * It must only be specified if {@link #fromTreeContext()} is set to {@code true}. 062 * 063 * @return the qualifier used to access value from context. 064 */ 065 @Nonnull 066 String qualifier() default ""; 067 068 /** 069 * Return {@code true} if the input value should be sourced from tree context rather than supplied when 070 * creating the view. Inputs sourced from tree context are transparently passed from a parent view to 071 * descendant views and do not need to be specified by the user when creating the view. 072 * 073 * @return {@code true} if the input value should be sourced from tree context. 074 */ 075 boolean fromTreeContext() default false; 076 077 /** 078 * Setting indicating whether the input should be supplied when the view is constructed. 079 * This influences validation when enabled and how the Builder class is created. 080 * If set to {@link Feature#ENABLE} then the user MUST supply the input and the builder will require the user 081 * to specify the value. If set to {@link Feature#DISABLE} then the user can optionally supply the input. 082 * If set to {@link Feature#AUTODETECT} then the annotation processor will treat it as {@link Feature#DISABLE} 083 * if there is a corresponding {@link InputDefault} for the input or {@link #fromTreeContext()} is 084 * {@code true}, otherwise it will be treated as {@link Feature#ENABLE}. The value of this setting must not 085 * be {@link Feature#ENABLE} when {@link #fromTreeContext()} is {@code true}. 086 * 087 * @return the flag indicating whether the input needs to be supplied. 088 */ 089 Feature require() default Feature.AUTODETECT; 090 091 /** 092 * Indicate whether the input should be annotated by {@link Observable}. 093 * 094 * <p>If set to {@link Feature#AUTODETECT} then the input will be observable if and only if:</p> 095 * <ul> 096 * <li>the input is not immutable.</li> 097 * <li>the view has at least one method annotated with {@link Memoize} or {@link Observe}.</li> 098 * </ul> 099 * 100 * @return the enum indicating whether input is observable. 101 */ 102 Feature observable() default Feature.AUTODETECT; 103 104}