001package arez.annotations; 002 003import arez.component.ComponentObservable; 004import java.lang.annotation.Documented; 005import java.lang.annotation.ElementType; 006import java.lang.annotation.Target; 007 008/** 009 * Methods and fields annotated by this annotation should be observed for the alive lifetime of the component. 010 * 011 * <p>This annotation is typically used when a field references an {@link ArezComponent} annotated class that has 012 * {@link ArezComponent#disposeOnDeactivate()} set to <code>true</code>. This results in the current component 013 * observing the referenced component and thus preventing it from being disposed for the lifetime of the 014 * current component.</p> 015 * 016 * <p>It should be noted that it is preferable for the field that defines the observed component to be marked 017 * with this annotation rather than the method accessor. The reason is that the annotation processor will issue 018 * a warning if a field that the processor identifies as a potential dependency if it is not annotated with 019 * {@link AutoObserve}, {@link CascadeDispose} or {@link ComponentDependency}.</p> 020 * 021 * <p>If the element annotated is a method then the method must comply with the additional constraints:</p> 022 * <ul> 023 * <li>Must not be annotated with any other arez annotation other than {@link Reference} or {@link Observable}</li> 024 * <li>Must have 0 parameters</li> 025 * <li>Must return a value compatible with {@link ComponentObservable}, unless 026 * {@link #validateTypeAtRuntime()} is <code>true</code></li> 027 * <li>Must not be private</li> 028 * <li>Must not be static</li> 029 * <li>Must not be abstract unless the method is annotated with {@link Reference} or {@link Observable} in which 030 * case it MUST be abstract</li> 031 * <li>Must not throw exceptions</li> 032 * <li>Must be accessible to the class annotated by the {@link ArezComponent} annotation.</li> 033 * </ul> 034 * 035 * <p>If the element annotated is a field then the field must comply with the additional constraints:</p> 036 * <ul> 037 * <li>Must be final</li> 038 * <li>Must not be private</li> 039 * <li>Must not be static</li> 040 * <li>Must be compatible with {@link ComponentObservable}, unless {@link #validateTypeAtRuntime()} is 041 * <code>true</code></li> 042 * <li>Must be accessible to the class annotated by the {@link ArezComponent} annotation.</li> 043 * <li>Should not be public. A warning will be generated but can be suppressed by the {@link SuppressWarnings} or {@link SuppressArezWarnings} annotations with a key "Arez:PublicField".</li> 044 * <li> 045 * Should not be protected if in the class annotated with the {@link ArezComponent} annotation as the field is not 046 * expected to be accessed outside the component. A warning will be generated but can be suppressed by the 047 * {@link SuppressWarnings} or {@link SuppressArezWarnings} annotations with a key "Arez:ProtectedField". 048 * </li> 049 * </ul> 050 * 051 * <p>If {@link #validateTypeAtRuntime()} is set to <code>true</code> then the declared type of the field or method 052 * must be annotated with {@link ArezComponentLike}. In this mode, type compatibility is validated at runtime 053 * rather than compile time while still treating the declared type as component-like for validation only.</p> 054 * 055 * <p>This annotation is only supported on elements contained within a type annotated by 056 * {@link ArezComponent} or {@link ArezComponentLike}. Other usages will fail compilation.</p> 057 */ 058@Documented 059@Target( { ElementType.METHOD, ElementType.FIELD } ) 060public @interface AutoObserve 061{ 062 /** 063 * Return true and the value of the annotated field or method will be validated at runtime rather than compile time. 064 * This is useful when the declared type is annotated with {@link ArezComponentLike} but the runtime value is 065 * known to implement {@link ComponentObservable}. 066 * 067 * @return true to defer validation of types until runtime. 068 */ 069 boolean validateTypeAtRuntime() default false; 070}