001package arez.annotations; 002 003import arez.component.DisposeNotifier; 004import java.lang.annotation.Documented; 005import java.lang.annotation.ElementType; 006import java.lang.annotation.Target; 007import javax.annotation.Nonnull; 008 009/** 010 * Methods and fields marked with this annotation are dependencies of the component. 011 * If the dependency is disposed then the component takes an action to cascade the dispose 012 * or null the property referencing the dependency. The dependency MUST implement the 013 * {@link DisposeNotifier} interface. 014 * 015 * <p>It should be noted that it is preferable for the field that defines the dependency is marked 016 * with this annotation rather than the method accessor. The reason is that the annotation processor 017 * will issue a warning if a field that the processor identifies as a potential dependency if it is 018 * not annotated with {@link AutoObserve}, {@link CascadeDispose} or {@link ComponentDependency}.</p> 019 * 020 * <p>If the element annotated is a method then the method must comply with the additional constraints:</p> 021 * <ul> 022 * <li>Must not be annotated with any other arez annotation except {@link Observable}</li> 023 * <li>If not annotated with {@link Observable} then must be final</li> 024 * <li>Must have 0 parameters</li> 025 * <li> 026 * Must return a value that implements {@link DisposeNotifier} or is annotated with {@link ArezComponent}. 027 * This will be checked at compile-time unless {@link #validateTypeAtRuntime()} set to <code>true</code>. 028 * </li> 029 * <li>Must not be private</li> 030 * <li>Must not be static</li> 031 * <li>If not annotated with {@link Observable} then must not be abstract</li> 032 * <li>Must not throw exceptions</li> 033 * <li>Must be accessible to the class annotated by the {@link ArezComponent} annotation.</li> 034 * </ul> 035 * 036 * <p>If the element annotated is a field then the field must comply with the additional constraints:</p> 037 * <ul> 038 * <li>Must be final</li> 039 * <li>Must be a type that implements {@link DisposeNotifier} or is annotated with {@link ArezComponent}</li> 040 * <li>Must not be private</li> 041 * <li>Must not be static</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>This annotation is only supported on elements contained within a type annotated by 052 * {@link ArezComponent} or {@link ArezComponentLike}. Other usages will fail compilation.</p> 053 */ 054@Documented 055@Target( { ElementType.METHOD, ElementType.FIELD } ) 056public @interface ComponentDependency 057{ 058 /** 059 * The action to take when dependency is disposed. 060 */ 061 enum Action 062 { 063 /** 064 * Remove the component. 065 */ 066 CASCADE, 067 /** 068 * Set the {@link Observable} property that holds dependency to null. 069 */ 070 SET_NULL 071 } 072 073 /** 074 * Return the action to take when the dependency is disposed. 075 * A {@link Action#CASCADE} value indicates that the component should be deleted, while a 076 * {@link Action#SET_NULL} value indicates that the observable field should be set to null. 077 * The {@link Action#SET_NULL} is only valid on {@link Observable} properties that have an 078 * associated setter and are not annotated with {@link javax.annotation.Nonnull}. 079 * 080 * @return the action to take when the dependency is disposed. 081 */ 082 @Nonnull 083 Action action() default Action.CASCADE; 084 085 /** 086 * Return true and the value of the annotated field will be validated at runtime rather than at compile time. 087 * This is useful when the field is defined by an interface but the underlying field is guaranteed to implement 088 * {@link DisposeNotifier} at runtime. 089 * 090 * @return true to defer validation of types until runtime. 091 */ 092 boolean validateTypeAtRuntime() default false; 093}