001package sting; 002 003import java.lang.annotation.Documented; 004import java.lang.annotation.ElementType; 005import java.lang.annotation.Retention; 006import java.lang.annotation.RetentionPolicy; 007import java.lang.annotation.Target; 008import javax.annotation.Nonnull; 009 010/** 011 * Annotation that indicates the class that provides the service. 012 * This is an integration meta-annotation rather than a component-defining Sting annotation. 013 * 014 * <p>The class that provides the service may be either a {@link Fragment}-annotated type or an 015 * {@link Injectable}-annotated type. This annotation is applied to another framework's annotation to 016 * simplify integration with Sting. Sting consults it when the framework annotation is applied to a 017 * type element that Sting attempts to include or discover.</p> 018 * 019 * <p>When used for explicit include aliasing, Sting resolves the framework-managed type in an 020 * {@link Injector#includes()} annotation parameter or a {@link Fragment#includes()} annotation 021 * parameter to the provider type. In this case, the resolved provider only needs to exist and be 022 * annotated with {@link Fragment} or {@link Injectable}. The provider does not need to publish the 023 * framework-managed type unless that type must later be resolved as a Sting service.</p> 024 * 025 * <p>When used for auto-discovery, Sting resolves an unresolved service request for the 026 * framework-managed type to the provider type. In this case, the resolved provider must be 027 * annotated with {@link Fragment} or {@link Injectable} and publish the framework-managed type 028 * using the default qualifier.</p> 029 * 030 * <p>Frameworks that synthesize Sting providers should remember that Sting only observes 031 * {@link Eager}, {@link Named}, and {@link Typed} on the resolved provider. Providers used only as 032 * explicit include aliases usually do not need to copy those annotations for the framework-managed 033 * type. Providers intended to support auto-discovery usually should copy them when they need Sting 034 * to treat the framework-managed type as published with those semantics. In practice this means 035 * copying the annotations onto the generated {@link Injectable} subtype, or onto the provider 036 * method declared by the generated {@link Fragment}, depending on the provider style.</p> 037 * 038 * <p>The presence of this annotation does not itself create a Sting binding; the resolved provider 039 * type is what Sting processes.</p> 040 * 041 * <p>It should be noted that Sting will attempt to use any annotation with this name and shape so 042 * that frameworks do not need a direct code dependency on Sting.</p> 043 */ 044@Documented 045@Retention( RetentionPolicy.RUNTIME ) 046@Target( ElementType.ANNOTATION_TYPE ) 047public @interface StingProvider 048{ 049 /** 050 * The name pattern of the class that provides the service. 051 * The name is relative to the reference type (See above for how to determine the reference type). 052 * The package is the same package as the reference type. The pattern can include constant string 053 * parts as well as the following replacements: 054 * 055 * <ul> 056 * <li> 057 * <b>[SimpleName]</b>: The simple name of the class. i.e. For a top-level class like 058 * {@code come.example.MyElement} the simple name is {@code "MyElement"}. For a nested class like 059 * {@code come.example.MyElement.ElementType.Kind} the simple name is {@code "Kind"}. 060 * </li> 061 * <li> 062 * <b>[CompoundName]</b>: The compound name of the class. i.e. For a top-level class like 063 * {@code come.example.MyElement} the compound name is {@code "MyElement"}. For a nested class like 064 * {@code come.example.MyElement.ElementType.Kind} the simple name is {@code "MyElement.ElementType.Kind"}. 065 * </li> 066 * <li> 067 * <b>[EnclosingName]</b>: The compound name of the class with the simple name elided. i.e. For a top-level 068 * class like {@code come.example.MyElement} the enclosing name is {@code ""}. For a nested class like 069 * {@code come.example.MyElement.ElementType.Kind} the enclosing name is {@code "MyElement.ElementType."}. 070 * </li> 071 * <li> 072 * <b>[FlatEnclosingName]</b>: The enclosing name of the class with the dots replaced with underscores. 073 * i.e. For a top-level class like {@code come.example.MyElement} the flat enclosing name is {@code ""}. 074 * For a nested class like {@code come.example.MyElement.ElementType.Kind} the flat enclosing name is 075 * {@code "MyElement_ElementType_"}. 076 * </li> 077 * </ul> 078 * 079 * <p>A typical pattern used by a framework such as <a href="https://arez.github.io/">Arez</a> is 080 * "[FlatEnclosingName]Arez_[SimpleName]"..</p> 081 * 082 * @return the pattern to produce a name. 083 */ 084 @Nonnull 085 String value(); 086}