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