All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.dakusui.actionunit.visitors.ActionWalker Maven / Gradle / Ivy

There is a newer version: 6.1.5
Show newest version
package com.github.dakusui.actionunit.visitors;

import com.github.dakusui.actionunit.actions.*;
import com.github.dakusui.actionunit.core.Action;
import com.github.dakusui.actionunit.helpers.Checks;
import com.github.dakusui.actionunit.visitors.reporting.Node;

import java.util.Deque;
import java.util.LinkedList;
import java.util.function.Consumer;

abstract class ActionWalker implements Action.Visitor {
  private final ThreadLocal>> _current;
  private       Node                     root;

  ActionWalker() {
    this._current = new ThreadLocal<>();
    this._current.set(new LinkedList<>());
    this.root = null;
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public void visit(Leaf action) {
    handle(
        action,
        leafActionConsumer()
    );
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public void visit(Named action) {
    handle(
        action,
        namedActionConsumer()
    );
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public void visit(Sequential action) {
    handle(
        action,
        sequentialActionConsumer()
    );
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public void visit(Concurrent action) {
    handle(
        action,
        concurrentActionConsumer()
    );
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public  void visit(ForEach action) {
    handle(
        action,
        forEachActionConsumer()
    );
  }

  /**
   * {@inheritDoc}
   */
  public  void visit(While action) {
    handle(
        action,
        whileActionConsumer()
    );
  }

  /**
   * {@inheritDoc}
   */
  public  void visit(When action) {
    handle(
        action,
        whenActionConsumer()
    );
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public  void visit(Attempt action) {
    handle(
        action,
        attemptActionConsumer()
    );
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public void visit(TestAction action) {
    handle(
        action,
        testActionConsumer()
    );
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public void visit(Retry action) {
    handle(
        action,
        retryActionConsumer()
    );
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public void visit(TimeOut action) {
    handle(
        action,
        timeOutActionConsumer()
    );
  }

  protected abstract Consumer leafActionConsumer();

  protected Consumer namedActionConsumer() {
    return (Named named) -> named.getAction().accept(this);
  }

  protected Consumer sequentialActionConsumer() {
    return (Sequential sequential) -> {
      for (Action each : sequential) {
        each.accept(this);
      }
    };
  }

  protected abstract Consumer concurrentActionConsumer();

  protected abstract  Consumer> forEachActionConsumer();

  protected abstract  Consumer> whileActionConsumer();

  protected abstract  Consumer> whenActionConsumer();

  protected abstract  Consumer> attemptActionConsumer();

  protected Consumer testActionConsumer() {
    return (TestAction test) -> {
      test.given().accept(this);
      test.when().accept(this);
      test.then().accept(this);
    };
  }

  protected abstract Consumer retryActionConsumer();

  protected abstract Consumer timeOutActionConsumer();

  protected final  void handle(A action, Consumer handler) {
    @SuppressWarnings("unchecked") Node node = toNode(
        this.getCurrentNode(),
        action
    );
    before(node);
    try {
      handler.accept(action);
      succeeded(node);
    } catch (Error | RuntimeException e) {
      failed(node, e);
      throw e;
    } finally {
      after(node);
    }
  }

  protected  Node toNode(Node parent, A action) {
    return new Node<>(action, action instanceof Leaf);
  }

  @SuppressWarnings({ "unchecked", "WeakerAccess" })
  protected  void before(Node node) {
    if (getCurrentPath().isEmpty()) {
      pushNode(node);
      root = (Node) node;
    } else {
      pushNode(node);
    }
  }

  protected  void succeeded(Node node) {
  }

  protected  void failed(Node node, Throwable e) {
  }

  @SuppressWarnings("WeakerAccess")
  protected  void after(Node node) {
    Checks.checkState(
        this.getCurrentPath().peek() == node,
        "Cannot remove %s from queue=%s", node, this.getCurrentPath()
    );
    popNode();
  }

  @SuppressWarnings("unchecked")
  protected  void pushNode(Node node) {
    this.getCurrentPath().push((Node) node);
  }

  @SuppressWarnings("unchecked")
  protected  Node popNode() {
    return (Node) this.getCurrentPath().pop();
  }

  protected  Node getCurrentNode() {
    return (Node) this.getCurrentPath().peek();
  }

  protected Node getRootNode() {
    return root;
  }

  protected synchronized Deque> getCurrentPath() {
    return _current.get();
  }

  protected void branchPath(Deque> pathSnapshot) {
    this._current.set(new LinkedList<>(pathSnapshot));
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy