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

de.team33.testing.async.thebe.Report Maven / Gradle / Ivy

The newest version!
package de.team33.testing.async.thebe;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static java.util.Collections.synchronizedList;
import static java.util.Collections.unmodifiableList;

/**
 * A report of multiple executions of a method.
 *
 * @param  The type of result of the method to be run.
 */
public final class Report {

  private final List results;
  private final List caught;

  @SuppressWarnings("WeakerAccess")
  private Report(final Builder builder) {
    this.results = unmodifiableList(new ArrayList<>(builder.results));
    this.caught = unmodifiableList(new ArrayList<>(builder.caught));
  }

  /**
   * Returns a {@link List} of all results that have accumulated during reporting.
   */
  public final List list() {
    return results;
  }

  /**
   * Returns a limited {@link Stream} of all results that have accumulated during reporting.
   */
  public Stream stream() {
    return results.stream();
  }

  /**
   * Returns a {@link List} of all {@linkplain Throwable exceptions} that occurred during reporting.
   */
  public final List getCaught() {
    return caught;
  }

  /**
   * Returns a {@link List} of all {@linkplain Throwable exceptions} of a certain type that occurred during
   * reporting. Certain derived types can be excluded from the result.
   *
   * @param  The type of {@linkplain Throwable exceptions} to be listed.
   */
  @SuppressWarnings("OverloadedVarargsMethod")
  @SafeVarargs
  public final  List getCaught(final Class xClass,
                                                       final Class... ignorable) {
    return streamCaught(xClass, ignorable).collect(Collectors.toList());
  }

  @SafeVarargs
  private final  Stream streamCaught(final Class xClass,
                                                             final Class... ignorable) {
    return caught.stream()
                 .filter(xClass::isInstance)
                 .map(xClass::cast)
                 .filter(throwable -> Stream.of(ignorable)
                                                .noneMatch(iClass -> iClass.isInstance(throwable)));
  }

  /**
   * Re-throws the first {@linkplain Throwable exception} of a certain type that occurred during
   * reporting after all further {@linkplain Throwable exceptions} of that type have been
   * {@linkplain Throwable#addSuppressed(Throwable) added as suppressed}.
   * Certain derived types can be excluded from processing.
   *
   * @param  The type of {@linkplain Throwable exceptions} to be processed.
   */
  @SafeVarargs
  public final  Report reThrow(final Class xClass,
                                                       final Class... ignorable) throws X {
    // First ...
    final X caught = streamCaught(xClass, ignorable).findAny().orElse(null);
    if (null != caught) {
      // Add the rest ...
      streamCaught(Throwable.class).filter(more -> more != caught)
                                   .forEach(caught::addSuppressed);
      throw caught;
    }
    return this;
  }

  @SuppressWarnings("ProhibitedExceptionDeclared")
  public final Report reThrowAny() throws Exception {
    return reThrow(Error.class).reThrow(Exception.class);
  }

  public final int size() {
    return results.size();
  }

  @SuppressWarnings("UnusedReturnValue")
  static class Builder {

    final List caught = synchronizedList(new LinkedList<>());
    final List results = synchronizedList(new LinkedList<>());

    final Report build() {
      return new Report<>(this);
    }

    final Builder add(final Throwable caught) {
      this.caught.add(caught);
      return this;
    }

    final Builder add(final R result) {
      results.add(result);
      return this;
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy