arez.annotations.ArezComponent Maven / Gradle / Ivy
package arez.annotations;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
import javax.annotation.Nonnull;
/**
* Annotation that marks classes to be processed by Arez annotation processor.
* Classes with this annotation can contain {@link Observable} properties,
* {@link Computed} properties, {@link Autorun} methods, {@link Track} methods
* and {@link Action} methods.
*
* The annotation controls the way that contained actions and observables are
* named (if names are enabled in the system.
*
* - The value returned by {@link #name()} indicates the type name for instances
* of this object. If not specified it will default to the SimpleName of the class.
* i.e. The class com.biz.models.MyModel will default to a name of
* "MyModel".
* - The {@link #nameIncludesId()} method indicates whether the names in generated components
* should include the id. If you expect only one instance of this component, it can be simpler
* to elide the id.
*
* The name of any elements contained within the component follows the pattern
* "[ArezComponent.name].[ArezComponent.id].[Element.name]". If the value of {@link #nameIncludesId()}
* is false then the "[ArezComponent.id]." element of the name will be elided.
*
* The type that is annotated with @ArezComponent annotation must comply with the additional constraints:
*
* - Must be a class, not an interface or enum
* - Must be concrete, not abstract
* - Must not be final
* - Must not be a non-static nested class
* - Must have at least one method annotated with {@link Action}, {@link Autorun}, {@link Track}, {@link Computed} or {@link Observable}
*
*
* The annotation processor that handles this annotation will analyze all super classes and super
* interfaces. This includes analysis of default methods on interfaces. So it is perfectly valid to
* add {@link Observable}, {@link Computed}, {@link Action}, {@link PreDispose} and {@link PostDispose}
* annotations to default methods on implemented interfaces.
*/
@Documented
@Target( ElementType.TYPE )
public @interface ArezComponent
{
/**
* Return the name of the type.
* The value must conform to the requirements of a java identifier.
*
* @return the name of the type.
*/
@Nonnull
String name() default "";
/**
* Return true if the name derived for component should include the id, false otherwise.
* If the user does not specify a value for this parameter but does specify the javax.inject.Singleton
* on the same type then the default value of this parameter is false, otherwise it is true.
*
* @return true to include the id in the component name, false otherwise.
*/
boolean nameIncludesId() default true;
/**
* Return true if the component does not need to explicitly declare elements.
* Otherwise if no elements (i.e. {@link Observable}s, {@link Action}s, {@link Autorun}s etc) are defined
* on a component it will generate an error.
*
* @return true if the component does not need to explicitly declare elements, false otherwise.
*/
boolean allowEmpty() default false;
/**
* Return true if the component type does not need to be abstract.
* Otherwise an error will be generated if this annotation is added to a concrete type.
*
* @return true if the component type does not need to be abstract.
*/
boolean allowConcrete() default false;
/**
* Return true if the component should dispose itself once it is no longer "observed".
* By "observed" it means that the component will have {@link arez.component.ComponentObservable#observe(Object)}
* called on it.
*
* @return true if the component should dispose itself once it is no longer "observed".
*/
boolean disposeOnDeactivate() default false;
/**
* Indicate whether an @Inject annotation should be added to constructor of the generated class.
* {@link Feature#ENABLE} will force the addition of an @Inject annotation, {@link Feature#DISABLE}
* will result in no @Inject annotation and {@link Feature#AUTODETECT} will add an @Inject
* if any fields or methods in the component or any parent type has an @Inject annotation OR the class
* has an annotation that is itself annotated with the javax.inject.Scope annotation.
*
* @return enum controlling present of Inject annotation on constructor.
*/
Feature inject() default Feature.AUTODETECT;
/**
* Indicate whether a dagger module should be generated for enhanced component class.
* {@link Feature#ENABLE} will force the generation of the module, {@link Feature#DISABLE}
* will result in no dagger module and {@link Feature#AUTODETECT} will add a dagger
* module if the dagger.Module
class is present on the classpath AND the class
* has an annotation that is itself annotated with the javax.inject.Scope annotation.
*
* @return enum controlling whether a dagger module should be generated for repository.
*/
Feature dagger() default Feature.AUTODETECT;
/**
* Return true if an the generated component should NOT schedule autorun actions at the end of the
* constructor. This is useful if the component creator will trigger schedules manually at a later time.
*
* @return Return true if an the generated component should NOT schedule autorun actions at the end of the constructor.
*/
boolean deferSchedule() default false;
/**
* Indicate whether a component requires that the {@link Object#hashCode()} and {@link Object#equals(Object)}
* methods are implemented. These methods MUST be implemented if the {@link Repository} annotation is present
* but may be implemented in other scenarios. {@link Feature#ENABLE} will force the generation of the methods,
* {@link Feature#DISABLE} will not generate these methods and {@link Feature#AUTODETECT} will generated these
* methods if the {@link Repository} annotation is present.
*
* @return enum controlling whether the {@link Object#hashCode()} and {@link Object#equals(Object)} methods are implemented.
*/
Feature requireEquals() default Feature.AUTODETECT;
}