001package arez.annotations; 002 003import arez.Locator; 004import java.lang.annotation.Documented; 005import java.lang.annotation.ElementType; 006import java.lang.annotation.Target; 007import javax.annotation.Nonnull; 008 009/** 010 * A Reference annotation is placed on an abstract method that will resolve to a referenced object. 011 * The reference annotation is paired with a {@link ReferenceId} method that returns the <code>id</code> 012 * of the referenced object. The <code>type</code> of the referenced object is the return type of the method 013 * annotated with <code>@Reference</code>. The <code>type</code> and <code>id</code> are passed to the 014 * {@link Locator#findById(Class, Object)} method when the reference is resolved. 015 * 016 * * <p>The reference can be resolved either eagerly (during a linking phase or when it is modified) or 017 * lazily (when accessed).</p> 018 * 019 * <p>The method must also conform to the following constraints:</p> 020 * <ul> 021 * <li>Must not be annotated with any other arez annotation</li> 022 * <li>Must have 0 parameters</li> 023 * <li>Must return a value</li> 024 * <li>Must be abstract</li> 025 * <li>Must not throw exceptions</li> 026 * <li>Must be accessible to the class annotated by the {@link ArezComponent} annotation.</li> 027 * </ul> 028 * 029 * <p>This annotation is only supported on elements contained within a type annotated by 030 * {@link ArezComponent} or {@link ArezComponentLike}. Other usages will fail compilation.</p> 031 */ 032@Documented 033@Target( ElementType.METHOD ) 034public @interface Reference 035{ 036 /** 037 * Return the name of the reference relative to the component. The value must conform 038 * to the requirements of a java identifier. If not specified, the name will be derived by assuming 039 * the naming convention "get[Name]" or failing that the name will be the method name. 040 * 041 * @return the name of the reference relative to the component. 042 */ 043 @Nonnull 044 String name() default "<default>"; 045 046 /** 047 * Return the strategy for resolving reference. 048 * 049 * @return the strategy for resolving reference. 050 */ 051 @Nonnull 052 LinkType load() default LinkType.EAGER; 053 054 /** 055 * Return the enum controlling whether there is an inverse for reference. 056 * {@link Feature#ENABLE} tells the annotation processor to expect an inverse and add code 057 * to maintain the inverse. {@link Feature#DISABLE} will generate no code to maintain 058 * inverse module. {@link Feature#AUTODETECT} will be treated as {@link Feature#ENABLE} 059 * if either the {@link #inverseName} or {@link #inverseMultiplicity} is specified. 060 * 061 * @return the enum controlling whether there is an inverse for reference 062 */ 063 @Nonnull 064 Feature inverse() default Feature.AUTODETECT; 065 066 /** 067 * Return the name of the inverse associated with the reference. The value must conform 068 * to the requirements of a java identifier. If not specified, the name will be derived 069 * by camelCasing the simple name of the class on which the {@link Reference} annotation 070 * is placed and then adding an s if {@link #inverseMultiplicity} is {@link Multiplicity#MANY}. 071 * 072 * @return the name of the reference relative to the component. 073 */ 074 @Nonnull 075 String inverseName() default "<default>"; 076 077 /** 078 * Define the expected multiplicity of the inverse associated with the reference. 079 * 080 * @return the expected multiplicity of the inverse associated with the reference. 081 */ 082 @Nonnull 083 Multiplicity inverseMultiplicity() default Multiplicity.MANY; 084}