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@Documented 030@Target( ElementType.METHOD ) 031public @interface Reference 032{ 033 /** 034 * Return the name of the reference relative to the component. The value must conform 035 * to the requirements of a java identifier. If not specified, the name will be derived by assuming 036 * the naming convention "get[Name]" or failing that the name will be the method name. 037 * 038 * @return the name of the reference relative to the component. 039 */ 040 @Nonnull 041 String name() default "<default>"; 042 043 /** 044 * Return the strategy for resolving reference. 045 * 046 * @return the strategy for resolving reference. 047 */ 048 @Nonnull 049 LinkType load() default LinkType.EAGER; 050 051 /** 052 * Return the enum controlling whether there is an inverse for reference. 053 * {@link Feature#ENABLE} tells the annotation processor to expect an inverse and add code 054 * to maintain the inverse. {@link Feature#DISABLE} will generate no code to maintain 055 * inverse module. {@link Feature#AUTODETECT} will be treated as {@link Feature#ENABLE} 056 * if either the {@link #inverseName} or {@link #inverseMultiplicity} is specified. 057 * 058 * @return the enum controlling whether there is an inverse for reference 059 */ 060 @Nonnull 061 Feature inverse() default Feature.AUTODETECT; 062 063 /** 064 * Return the name of the inverse associated with the reference. The value must conform 065 * to the requirements of a java identifier. If not specified, the name will be derived 066 * by camelCasing the simple name of the class on which the {@link Reference} annotation 067 * is placed and then adding an s if {@link #inverseMultiplicity} is {@link Multiplicity#MANY}. 068 * 069 * @return the name of the reference relative to the component. 070 */ 071 @Nonnull 072 String inverseName() default "<default>"; 073 074 /** 075 * Define the expected multiplicity of the inverse associated with the reference. 076 * 077 * @return the expected multiplicity of the inverse associated with the reference. 078 */ 079 @Nonnull 080 Multiplicity inverseMultiplicity() default Multiplicity.MANY; 081}