ActionSupport.java

  1. package com.github.dakusui.actionunit.core;

  2. import com.github.dakusui.actionunit.actions.*;
  3. import com.github.dakusui.actionunit.actions.cmd.CommanderConfig;
  4. import com.github.dakusui.actionunit.actions.cmd.UnixCommanderFactory;
  5. import com.github.dakusui.actionunit.actions.cmd.unix.Cmd;

  6. import java.util.List;
  7. import java.util.function.Consumer;
  8. import java.util.function.Function;
  9. import java.util.function.Predicate;
  10. import java.util.stream.Stream;

  11. import static com.github.dakusui.actionunit.core.context.ContextConsumer.NOP_CONSUMER;
  12. import static com.github.dakusui.actionunit.utils.InternalUtils.toStringIfOverriddenOrNoname;
  13. import static com.github.dakusui.printables.PrintableFunctionals.printableConsumer;
  14. import static java.util.Arrays.asList;
  15. import static java.util.Objects.requireNonNull;

  16. /**
  17.  * A utility class to build various actions.
  18.  */
  19. public enum ActionSupport {
  20.   ;

  21.   /**
  22.    * Creates an action that does nothing.
  23.    *
  24.    * @return A nop action.
  25.    */
  26.   public static Action nop() {
  27.     // Needs to be instantiated each time this method is called.
  28.     // Otherwise, multiple nops cannot be identified in an action tree.
  29.     return Leaf.of(NOP_CONSUMER);
  30.   }

  31.   public static Action leaf(Consumer<Context> consumer) {
  32.     return Leaf.of(consumer);
  33.   }

  34.   /**
  35.    * Returns an action named with a given string `name`.
  36.    *
  37.    * @param name   A name given to `action`.
  38.    * @param action An action to be named.
  39.    * @return A named action.
  40.    */
  41.   public static Action named(String name, Action action) {
  42.     return Named.of(name, action);
  43.   }

  44.   public static Attempt.Builder attempt(Action action) {
  45.     return new Attempt.Builder(action);
  46.   }

  47.   public static <E> ForEach.Builder<E> forEach(Function<Context, Stream<E>> streamGenerator) {
  48.     return forEach("i", streamGenerator);
  49.   }

  50.   /**
  51.    * Note that the `variableName` is only used for printing the variable in an action tree.
  52.    * Not used for identifying a corresponding entry in the context.
  53.    *
  54.    * @param variableName    A name of variable.
  55.    * @param streamGenerator A function to return stream.
  56.    * @param <E>             The type of the loop variable.
  57.    * @return A builder for `ForEach2` action
  58.    */
  59.   public static <E> ForEach.Builder<E> forEach(String variableName, Function<Context, Stream<E>> streamGenerator) {
  60.     return new ForEach.Builder<>(variableName, streamGenerator);
  61.   }

  62.   /**
  63.    * Returns a builder to create an action repeated while `condition` is satisfied.
  64.    *
  65.    * @param condition A condition to make an action repeated.
  66.    * @return A builder for `While` action.
  67.    * @see While
  68.    * @see While.Builder
  69.    */
  70.   public static While.Builder repeatWhile(Predicate<Context> condition) {
  71.     return new While.Builder(condition);
  72.   }

  73.   /**
  74.    * Returns a builder to create an action performed when `condition` is satisfied.
  75.    *
  76.    * @param cond A condition to make an actiono performed.
  77.    * @return A builder for `When` action
  78.    * @see When
  79.    * @see When.Builder
  80.    */
  81.   public static When.Builder when(Predicate<Context> cond) {
  82.     return new When.Builder(cond);
  83.   }

  84.   public static <T> With.Builder<T> with(Function<Context, T> value) {
  85.     return with("i", value);
  86.   }

  87.   /**
  88.    * Note that `variableName` won't be used to resolve a value of a variable, it is
  89.    * merely intended to be printed in an action-tree or logs.
  90.    *
  91.    * @param variableName human-readable variable name.
  92.    * @param value        A function to give a value to be used a context under the returned action.
  93.    * @param <T>          The type of the variable
  94.    * @return A builder for a `with` action.
  95.    */
  96.   public static <T> With.Builder<T> with(String variableName, Function<Context, T> value) {
  97.     return new With.Builder<>(variableName, value);
  98.   }

  99.   public static Retry.Builder retry(Action action) {
  100.     return new Retry.Builder(action);
  101.   }

  102.   public static TimeOut.Builder timeout(Action action) {
  103.     return new TimeOut.Builder(action);
  104.   }

  105.   public static Action sequential(List<Action> actions) {
  106.     return new Composite.Builder(actions).build();
  107.   }

  108.   public static Action parallel(List<Action> actions) {
  109.     return new Composite.Builder(actions).parallel().build();
  110.   }

  111.   public static Cmd cmd(String program, ContextVariable... knownVariables) {
  112.     return cmd(program, CommanderConfig.DEFAULT, knownVariables);
  113.   }

  114.   public static Cmd cmd(String program, CommanderConfig config, ContextVariable... knownVariables) {
  115.     Cmd ret = new Cmd(config).commandName(requireNonNull(program).trim());
  116.     for (ContextVariable each : knownVariables)
  117.       ret = ret.declareVariable(each);
  118.     return ret.append(" ");
  119.   }

  120.   public static UnixCommanderFactory unix() {
  121.     return unix(CommanderConfig.DEFAULT);
  122.   }

  123.   public static UnixCommanderFactory unix(CommanderConfig config) {
  124.     return UnixCommanderFactory.create(config);
  125.   }

  126.   public static Action simple(String name, Consumer<Context> consumer) {
  127.     return leaf(printableConsumer(consumer).describe(name + ":" + toStringIfOverriddenOrNoname(consumer)));
  128.   }

  129.   /**
  130.    * Creates an action that performs given actions one by one sequentially.
  131.    *
  132.    * @param actions Actions to be performed.
  133.    * @return An action that performs `actions`.
  134.    */
  135.   public static Action sequential(Action... actions) {
  136.     return sequential(asList(actions));
  137.   }

  138.   /**
  139.    * Creates an action that performs given actions one by one sequentially.
  140.    *
  141.    * @param actions Actions to be performed.
  142.    * @return An action that performs `actions`.
  143.    */
  144.   public static Action parallel(Action... actions) {
  145.     return parallel(asList(actions));
  146.   }

  147.   /**
  148.    * Returns an action to build `Ensured` action.
  149.    * By adding actions to the returned builder's methods, you can construct an `Ensured` action, whose
  150.    * target action's success is ensured by those added actions.
  151.    *
  152.    * @param target An action ensured to be successful.
  153.    * @return A builder for an `Ensured` action.
  154.    * @see Ensured
  155.    */
  156.   public static Ensured.Builder ensure(Action target) {
  157.     Ensured.Builder b = new Ensured.Builder();
  158.     b.target(target);
  159.     return b;
  160.   }
  161. }