Skip to content

Commit

Permalink
Merge pull request #39 from digipost/catch-exception-from-resolving-s…
Browse files Browse the repository at this point in the history
…tream-element

forceOnAll will catch exception from resolving Stream element
  • Loading branch information
runeflobakk authored Sep 26, 2024
2 parents 7390e5f + a61ac1d commit 67ac332
Show file tree
Hide file tree
Showing 14 changed files with 360 additions and 115 deletions.
39 changes: 22 additions & 17 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
<dependency>
<groupId>org.junit</groupId>
<artifactId>junit-bom</artifactId>
<version>5.10.2</version>
<version>5.11.1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
Expand All @@ -63,7 +63,7 @@
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-bom</artifactId>
<version>2.0.12</version>
<version>2.0.16</version>
<type>pom</type>
<scope>import</scope>
</dependency>
Expand All @@ -79,24 +79,29 @@
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest</artifactId>
<version>2.2</version>
<version>3.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>nl.jqno.equalsverifier</groupId>
<artifactId>equalsverifier</artifactId>
<version>3.15.6</version>
<version>3.17</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.15.1</version>
<version>2.17.0</version>
<scope>test</scope>
</dependency>
<dependency>
Expand Down Expand Up @@ -158,11 +163,11 @@
<plugin>
<groupId>com.mycila</groupId>
<artifactId>license-maven-plugin</artifactId>
<version>4.3</version>
<version>4.6</version>
</plugin>
<plugin>
<artifactId>maven-enforcer-plugin</artifactId>
<version>3.4.1</version>
<version>3.5.0</version>
<configuration>
<rules>
<requireMavenVersion>
Expand All @@ -185,7 +190,7 @@
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.12.1</version>
<version>3.13.0</version>
<configuration>
<compilerArgs>
<arg>-Xlint</arg>
Expand All @@ -194,31 +199,31 @@
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.2.5</version>
<version>3.5.0</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>3.1.1</version>
<version>3.1.3</version>
</plugin>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.3.2</version>
<version>3.4.0</version>
</plugin>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.6.1</version>
<version>3.8.0</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>3.1.1</version>
<version>3.1.3</version>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.3.1</version>
</plugin>
<plugin>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.6.3</version>
<version>3.10.0</version>
<configuration>
<tags>
<tag>
Expand All @@ -231,20 +236,20 @@
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.3.0</version>
<version>3.4.2</version>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>versions-maven-plugin</artifactId>
<version>2.16.2</version>
<version>2.17.1</version>
<configuration>
<generateBackupPoms>false</generateBackupPoms>
</configuration>
</plugin>
<plugin>
<groupId>com.github.siom79.japicmp</groupId>
<artifactId>japicmp-maven-plugin</artifactId>
<version>0.18.5</version>
<version>0.23.0</version>
<configuration>
<parameter>
<includes>
Expand Down
62 changes: 51 additions & 11 deletions src/main/java/no/digipost/DiggBase.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,12 @@
import java.util.Deque;
import java.util.Objects;
import java.util.Optional;
import java.util.Spliterator;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;

import static java.util.Spliterator.ORDERED;
import static java.util.Spliterators.spliterator;
Expand Down Expand Up @@ -220,8 +222,8 @@ public static Stream<Exception> close(AutoCloseable ... closeables) {

/**
* Create a stream which will yield the exceptions (if any) from invoking an {@link ThrowingConsumer action} on
* several {@code instances}. Consuming the stream will ensure that <strong>all</strong> instances will have
* the action invoked on them, and any exceptions happening will be available through the returned stream.
* several {@code instances}. Consuming the returned stream will ensure that <strong>all</strong> instances will have
* the action attempted on them, and any exceptions happening will be available through the returned stream.
*
* @param action the action to execute for each provided instance
* @param instances the instances to act on with the provided {@code action}.
Expand All @@ -237,24 +239,62 @@ public static <T> Stream<Exception> forceOnAll(ThrowingConsumer<? super T, ? ext

/**
* Create a stream which will yield the exceptions (if any) from invoking an {@link ThrowingConsumer action} on
* several {@code instances}. Consuming the stream will ensure that <strong>all</strong> instances will have
* the action invoked on them, and any exceptions happening will be available through the returned stream.
* several {@code instances}. This also includes exceptions thrown from <em>traversing</em> the given {@link Stream}
* of instances, i.e. should resolving an element from the {@code Stream} cause an exception, it will be caught and
* included in the returned {@code Stream}.
* <p>
* Consuming the returned stream will ensure that <strong>all</strong> traversed instances will have
* the action attempted on them, and any exceptions happening will be available through the returned stream.
*
* @param action the action to execute for each provided instance
* @param instances the instances to act on with the provided {@code action}.
*
* @return the Stream with exceptions, if any
*/
public static <T> Stream<Exception> forceOnAll(ThrowingConsumer<? super T, ? extends Exception> action, Stream<T> instances) {
return instances.filter(Objects::nonNull).flatMap(instance -> {
return StreamSupport.stream(
new FlatMapToExceptionSpliterator<>(action, instances.filter(Objects::nonNull).spliterator()),
instances.isParallel());
}

private static final class FlatMapToExceptionSpliterator<W> implements Spliterator<Exception> {

private final ThrowingConsumer<? super W, ? extends Exception> action;
private final Spliterator<W> wrappedSpliterator;
private final int characteristics;

FlatMapToExceptionSpliterator(ThrowingConsumer<? super W, ? extends Exception> action, Spliterator<W> wrappedSpliterator) {
this.action = action;
this.wrappedSpliterator = wrappedSpliterator;
this.characteristics = wrappedSpliterator.characteristics() & ~(SIZED | SUBSIZED | SORTED);
}

@Override
public boolean tryAdvance(Consumer<? super Exception> exceptionConsumer) {
try {
action.accept(instance);
} catch (Exception exception) {
return Stream.of(exception);
return wrappedSpliterator.tryAdvance(action.ifException(exceptionConsumer::accept));
} catch (Exception e) {
exceptionConsumer.accept(e);
return true;
}
return Stream.empty();
});
}
}

@Override
public Spliterator<Exception> trySplit() {
Spliterator<W> triedSplit = wrappedSpliterator.trySplit();
return triedSplit != null ? new FlatMapToExceptionSpliterator<>(action, triedSplit) : null;
}

@Override
public long estimateSize() {
return Long.MAX_VALUE;
}

@Override
public int characteristics() {
return characteristics;
}
};


/**
Expand Down
42 changes: 42 additions & 0 deletions src/main/java/no/digipost/DiggStreams.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import no.digipost.function.ObjLongFunction;

import java.util.Collection;
import java.util.Objects;
import java.util.Spliterator;
import java.util.Spliterators;
import java.util.concurrent.atomic.AtomicInteger;
Expand All @@ -31,6 +32,18 @@
import java.util.stream.Stream;
import java.util.stream.StreamSupport;

import static java.lang.Integer.toBinaryString;
import static java.util.Spliterator.CONCURRENT;
import static java.util.Spliterator.DISTINCT;
import static java.util.Spliterator.IMMUTABLE;
import static java.util.Spliterator.NONNULL;
import static java.util.Spliterator.ORDERED;
import static java.util.Spliterator.SIZED;
import static java.util.Spliterator.SORTED;
import static java.util.Spliterator.SUBSIZED;
import static java.util.stream.Collectors.joining;
import static no.digipost.DiggBase.friendlyName;

/**
* Utilities for working with {@link Stream}s.
*/
Expand Down Expand Up @@ -197,6 +210,35 @@ public boolean tryAdvance(Consumer<? super P> action) {
}


/**
* Get a description of {@link Spliterator#characteristics() characteristics} of a
* {@code Spliterator}. The returned text is is solely intended for debugging and
* logging purposes, and contents and format may change at any time.
*
* @param spliterator the Spliterator
* @return the description
*/
public static String describeCharacteristics(Spliterator<?> spliterator) {
int value = spliterator.characteristics();
if (value == 0) {
return friendlyName(spliterator.getClass()) + " with no enabled characteristics";
} else {
String enabledCharacteristics = Stream.of(
spliterator.hasCharacteristics(SIZED) ? "sized" : null,
spliterator.hasCharacteristics(SUBSIZED) ? "subsized" : null,
spliterator.hasCharacteristics(DISTINCT) ? "distinct" : null,
spliterator.hasCharacteristics(NONNULL) ? "non-null" : null,
spliterator.hasCharacteristics(IMMUTABLE) ? "immutable" : null,
spliterator.hasCharacteristics(ORDERED) ? "ordered" : null,
spliterator.hasCharacteristics(CONCURRENT) ? "concurrent" : null,
spliterator.hasCharacteristics(SORTED) ? "sorted" : null)
.filter(Objects::nonNull)
.collect(joining(", ", "", ""));
return enabledCharacteristics + " " + friendlyName(spliterator.getClass()) + " (" + toBinaryString(value) + ")";
}
}


private DiggStreams() {
}

Expand Down
Loading

0 comments on commit 67ac332

Please sign in to comment.