content: /*
   *  Licensed to the Apache Software Foundation (ASF) under one
   *  or more contributor license agreements.  See the NOTICE file
   *  distributed with this work for additional information
   *  regarding copyright ownership.  The ASF licenses this file
   *  to you under the Apache License, Version 2.0 (the
   *  "License"); you may not use this file except in compliance
   *  with the License.  You may obtain a copy of the License at
   *
   *        http://www.apache.org/licenses/LICENSE-2.0
   *
   *  Unless required by applicable law or agreed to in writing,
   *  software distributed under the License is distributed on an
   *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
   *  KIND, either express or implied.  See the License for the
   *  specific language governing permissions and limitations
   *  under the License.
   */
  package org.apache.causeway.applib.annotation;
  
  import java.lang.annotation.ElementType;
  import java.lang.annotation.Inherited;
  import java.lang.annotation.Retention;
  import java.lang.annotation.RetentionPolicy;
  import java.lang.annotation.Target;
  
  import org.apache.causeway.applib.events.domain.ActionDomainEvent;
  import org.apache.causeway.applib.services.command.Command;
  import org.apache.causeway.applib.services.commanddto.conmap.ContentMappingServiceForCommandDto;
  import org.apache.causeway.applib.services.commanddto.conmap.ContentMappingServiceForCommandsDto;
  import org.apache.causeway.applib.services.commanddto.processor.CommandDtoProcessor;
  import org.apache.causeway.applib.services.iactn.Execution;
  import org.apache.causeway.applib.services.publishing.spi.CommandSubscriber;
  import org.apache.causeway.applib.services.publishing.spi.ExecutionSubscriber;
  import org.apache.causeway.applib.value.Blob;
  import org.apache.causeway.applib.value.Clob;
  
  /**
   * Groups together all domain-specific metadata for an invokable action on a
   * domain object or domain service.
   *
   * @see Property
   * @see Collection
   * @see DomainObject
   * @see ActionLayout
   *
   * @since 1.x {@index}
   */
  @Inherited
  @Target({
          ElementType.METHOD,
          ElementType.TYPE,
          ElementType.ANNOTATION_TYPE }
  )
  @Retention(RetentionPolicy.RUNTIME)
  @DomainObject(nature=Nature.MIXIN, mixinMethod = "act") // meta annotation, only applies at class level
  @Domain.Include // meta annotation, in support of meta-model validation
  public @interface Action {
  
      /**
       * References a collection of a certain element type (by its member-id),
       * for an action with scalar or collection parameters of that element type;
       * the action's choices will be automatically populated from checkboxes rendered in the collection
       * (multi-select).
       *
       * <p>
       *     This will also result in the action being rendered near to the collection, similar to the way in
       *     which {@link ActionLayout#associateWith()} does.
       * </p>
       *
       * <p>
       *     If there are multiple actions associated with a collection, either by way of {@link Action#choicesFrom()} or
       *     using {@link ActionLayout#associateWith()}, then their order in the UI can be influenced using
       *     {@link ActionLayout#sequence()}.
       * </p>
       *
       * @see ActionLayout#associateWith()
       * @see ActionLayout#sequence()
       */
      String choicesFrom()
              default "";
  
      /**
       * The {@link CommandDtoProcessor} to process this command's DTO.
       *
       * <p>
       *     The processor itself is used by {@link ContentMappingServiceForCommandDto} and
       *     {@link ContentMappingServiceForCommandsDto} to dynamically transform the DTOs.
       * </p>
       *
       * @see Property#commandDtoProcessor()
       * @see Action#commandPublishing()
       */
      Class<? extends CommandDtoProcessor> commandDtoProcessor()
              default CommandDtoProcessor.class;
  
      /**
       * Whether action invocations, captured as {@link Command}s,
       * should be published to {@link CommandSubscriber}s.
       *
       * @see Property#commandPublishing()
       * @see Action#commandDtoProcessor()
       */
      Publishing commandPublishing()
              default Publishing.NOT_SPECIFIED;
  
      /**
       * Indicates that an invocation of the action should be posted to the
       * {@link org.apache.causeway.applib.services.eventbus.EventBusService} using a custom (subclass of)
       * {@link org.apache.causeway.applib.events.domain.ActionDomainEvent}.
       *
       * <p>
       *     Subscribers of this event can interact with the business rule
       *     checking (hide, disable, validate) and its modification (before and
       *     after).
       * </p>
       *
       * <p>For example:
       * </p>
       *
       * <pre>
       * public class SomeObject{
       *     public static class ChangeStartDateDomainEvent extends ActionDomainEvent&lt;SomeObject&gt; { ... }
       *
       *     &#64;Action(domainEvent=ChangedStartDateDomainEvent.class)
       *     public void changeStartDate(final Date startDate) { ...}
       *     ...
       * }
       * </pre>
       *
       * <p>
       * This subclass must provide a no-arg constructor; the fields are set reflectively.
       * </p>
       *
       * @see Property#domainEvent()
       * @see Collection#domainEvent()
       * @see DomainObject#actionDomainEvent()
       */
      Class<? extends ActionDomainEvent<?>> domainEvent()
              default ActionDomainEvent.Default.class;
  
      /**
       * Whether {@link Execution}s (triggered by action invocations), should
       * be published to {@link ExecutionSubscriber}s.
       *
       * @see Property#executionPublishing()
       */
      Publishing executionPublishing()
              default Publishing.NOT_SPECIFIED;
  
      /**
       * Whether the action is restricted to prototyping, or whether it is
       * available also in production mode.
       *
       * <p>
       *     By default there are no restrictions, with the action being available in all environments.
       * </p>
       */
      RestrictTo restrictTo()
              default RestrictTo.NOT_SPECIFIED;
  
      /**
       * The action semantics, either
       * {@link SemanticsOf#SAFE_AND_REQUEST_CACHEABLE cached},
       * {@link SemanticsOf#SAFE safe} (query-only),
       * {@link SemanticsOf#IDEMPOTENT idempotent} or
       * {@link SemanticsOf#NON_IDEMPOTENT non-idempotent}.
       *
       * <p>
       * The action's semantics determine whether objects are modified as the
       * result of invoking this action (if not, the results can be cached for the
       * remainder of the request).  If the objects do cause a change in state,
       * they additionally determine whether re-invoking the action would result
       * in a further change.
       * </p>
       *
       * <p>
       *     There are also `...ARE_YOU_SURE` variants
       *     (@link {@link SemanticsOf#IDEMPOTENT_ARE_YOU_SURE} and
       *     (@link {@link SemanticsOf#NON_IDEMPOTENT_ARE_YOU_SURE} that cause a
       *     confirmation dialog to be displayed in the Wicket viewer.
       * </p>
       */
      SemanticsOf semantics()
              default SemanticsOf.NOT_SPECIFIED;
  
      /**
       * If the action returns a collection, then this hints as to the run-time
       * type of the objects within that collection.
       *
       * <p>
       *     This is only provided as a fallback; usually the framework can infer
       *     the element type of the collection from the action method's
       *     return type (eg if it returns <code>Collection</code> instead of <code>Collection&lt;Customer&gt;</code>)
       * </p>
       *
       * @see Collection#typeOf()
       */
      Class<?> typeOf()
              default void.class; // represents unspecified
  
      /**
       * For downloading {@link Blob} or {@link Clob}, optionally restrict the files accepted (eg <tt>.xslx</tt>).
       *
       * <p>
       * The value should be of the form "file_extension|audio/*|video/*|image/*|media_type".
       * </p>
       *
       * @see <a href="http://www.w3schools.com/tags/att_input_accept.asp">http://www.w3schools.com</a>
       * @see Parameter#fileAccept()
       * @see Property#fileAccept()
       */
      String fileAccept()
              default "";
  
  }
  