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;
008
009/**
010 * Annotates an interface for which a dependency-injected factory implementation is to be generated.
011 * This annotation is a top-level Sting processor entrypoint. The generated implementation is itself a
012 * Sting-managed component and publishes the factory interface via the {@link Typed} annotation.
013 *
014 * <h2>Generated Classname</h2>
015 *
016 * <p>The generated factory implementation uses the standard Sting naming convention and has the name of the
017 * annotated type prepended with {@code Sting_}. For example, the top-level type
018 * {@code mybiz.MyWidgetFactory} will produce the implementation {@code mybiz.Sting_MyWidgetFactory}.
019 * Nested types are also supported but their names have the {@code $} sign replaced with a {@code _}.
020 * i.e. The nested class named {@code mybiz.MyOuterClass.MyWidgetFactory} will generate an implementation
021 * named {@code mybiz.MyOuterClass_Sting_MyWidgetFactory}</p>
022 *
023 * <h2>Factory Methods</h2>
024 *
025 * <p>Abstract instance methods defined on the factory interface are treated as candidate factory methods.
026 * Each candidate method identifies a component type to create and the subset of constructor arguments that
027 * are supplied by the caller at runtime. The factory interface may also declare default methods and these are
028 * inherited by the generated implementation.</p>
029 *
030 * <p>Candidate factory methods must:</p>
031 *
032 * <ul>
033 *   <li>return a concrete class type,</li>
034 *   <li>not declare type parameters,</li>
035 *   <li>not declare thrown exceptions, and</li>
036 *   <li>have parameters whose names and types exactly match constructor parameters on the created type.</li>
037 * </ul>
038 *
039 * <p>The created type must have exactly one constructor accessible from the package containing the factory
040 * interface. Constructor parameters omitted from the factory method are treated as Sting-managed dependencies
041 * and are injected into the generated factory implementation. This makes it possible to combine services managed
042 * by Sting with runtime values supplied by application code.</p>
043 *
044 * <h2>Injector Integration</h2>
045 *
046 * <p>The {@link Factory} annotation is itself annotated with {@link StingProvider}, allowing the factory
047 * interface to be included in an {@link Injector#includes()} or {@link Fragment#includes()} list as a
048 * provider-backed type.
049 * The generated factory implementation is annotated as an {@link Injectable} and {@link Typed} component
050 * so other Sting-managed components can depend upon the factory interface.</p>
051 *
052 * <p>A single factory interface may define multiple factory methods that create different component types.</p>
053 *
054 * <p>Example:</p>
055 *
056 * <pre><code>
057 * class MyWidget {
058 *   MyWidget( {@literal @}Nonnull BackendService backendService, int size ) {
059 *   }
060 * }
061 *
062 * {@literal @}Factory
063 * interface MyWidgetFactory {
064 *   {@literal @}Nonnull
065 *   MyWidget create( int size );
066 * }
067 *
068 * {@literal @}Injector( includes = MyWidgetFactory.class )
069 * interface MyInjector {
070 *   MyWidgetFactory widgetFactory();
071 * }
072 * </code></pre>
073 *
074 * <p>In the example above, Sting generates a factory implementation that injects the {@code BackendService}
075 * dependency and accepts the {@code size} parameter from the caller when {@code create(int)} is invoked.</p>
076 */
077@Documented
078@Retention( RetentionPolicy.RUNTIME )
079@Target( ElementType.TYPE )
080@StingProvider( "[FlatEnclosingName]Sting_[SimpleName]" )
081public @interface Factory
082{
083}