001package arez.annotations;
002
003import java.lang.annotation.Documented;
004import java.lang.annotation.ElementType;
005import java.lang.annotation.Target;
006import javax.annotation.Nonnull;
007
008/**
009 * Methods marked with this annotation are invoked in an Arez transaction.
010 *
011 * <p>The method that is annotated with this annotation must comply with the additional constraints:</p>
012 * <ul>
013 * <li>Must not be annotated with any other arez annotation</li>
014 * <li>Must not be private</li>
015 * <li>Must not be static</li>
016 * <li>Must not be final</li>
017 * <li>Must not be abstract</li>
018 * <li>Must be accessible to the class annotated by the {@link ArezComponent} annotation.</li>
019 * </ul>
020 *
021 * <p>This annotation is only supported on methods contained within a type annotated by
022 * {@link ArezComponent} or {@link ArezComponentLike}. Other usages will fail compilation.</p>
023 */
024@Documented
025@Target( ElementType.METHOD )
026public @interface Action
027{
028  /**
029   * Return the name of the Action relative to the component.
030   * The value must conform to the requirements of a java identifier.
031   * The name must also be unique across {@link Observable}s,
032   * {@link Memoize}s and {@link Action}s within the scope of the
033   * {@link ArezComponent} annotated element.
034   *
035   * @return the name of the Action relative to the component.
036   */
037  @Nonnull
038  String name() default "<default>";
039
040  /**
041   * Does the action mutate state or not.
042   *
043   * @return true if method should be wrapped in READ_WRITE transaction, false if it should it should be wrapped in READ_ONLY transaction.
044   */
045  boolean mutation() default true;
046
047  /**
048   * Return true if the parameters should be reported to the Arez spy subsystem.
049   * It is useful to disable reporting for large, circular or just uninteresting parameters to the spy infrastructure.
050   *
051   * @return true to report the parameters, false otherwise.
052   */
053  boolean reportParameters() default true;
054
055  /**
056   * Return true if the return value of the action (if any) should be reported to the Arez spy subsystem.
057   * It is useful to disable reporting for large, circular or just uninteresting parameters to the spy infrastructure.
058   *
059   * @return true to report the return value, false otherwise.
060   */
061  boolean reportResult() default true;
062
063  /**
064   * True if the action should always start a new transaction. A false value indicates that the action will
065   * use the invoking transaction if present, otherwise will create a new transaction to invoke action.
066   *
067   * @return true if the action will create a new transaction, false if it will use the existing transaction if present.
068   */
069  boolean requireNewTransaction() default false;
070
071  /**
072   * Flag indicating whether the code should verify that at least one read or write occurs within
073   * the scope of the action.
074   *
075   * @return true to verify action reads or writes observable data.
076   */
077  boolean verifyRequired() default true;
078
079  /**
080   * Flag indicating whether the action will be skipped if the owning component is disposing or disposed.
081   * If set to {@link Feature#AUTODETECT} then the value is inherited from the
082   * {@link ArezComponent#defaultSkipIfDisposed()} parameter on the containing component. If that value is also
083   * {@link Feature#AUTODETECT} then the effective value is treated as {@link Feature#DISABLE}. If the effective
084   * value is {@link Feature#ENABLE} then the action must be a void method.
085   *
086   * @return the flag indicating whether the action will be skipped if the owning component is disposing or disposed.
087   */
088  Feature skipIfDisposed() default Feature.AUTODETECT;
089}