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

com.softwaremill.jox.CollectSource Maven / Gradle / Ivy

The newest version!
package com.softwaremill.jox;

import java.util.function.Function;

public class CollectSource implements Source {
    private final Source original;

    private final Function f;

    /**
     * A view on the {@code original} source, which transforms the received values using the provided function {@code f}.
     * If {@code f} returns {@code null}, the value will be skipped, and another value will be received.
     * 

* The same logic applies to receive clauses created using this source, which can be used in {@link Select#select(SelectClause[])}. * * @param original The original source, from which values are received. * @param f The mapping / filtering function. If the function returns {@code null}, the value will be skipped. */ public CollectSource(Source original, Function f) { this.original = original; this.f = f; } @Override public T receive() throws InterruptedException { while (true) { var r = original.receive(); var t = f.apply(r); // a null indicates that the value should not be collected (skipped) if (t != null) { return t; } } } @Override public Object receiveOrClosed() throws InterruptedException { while (true) { var r = original.receiveOrClosed(); if (r instanceof ChannelClosed c) { return c; } else { //noinspection unchecked var t = f.apply((V) r); // a null indicates that the value should not be collected (skipped) if (t != null) { return t; } } } } @Override public SelectClause receiveClause() { return original.receiveClause(v -> { var t = f.apply(v); if (t != null) { return t; } else { // `null` is a valid return value from a select clause (default for send clauses and allowed for callbacks) // that's why we need a marker to indicate that the value should not be collected, when the result of `f` // is `null`. This is then handled in `Select`. //noinspection unchecked return (T) RestartSelectMarker.RESTART; } }); } @Override public SelectClause receiveClause(Function callback) { return original.receiveClause(v -> { var t = f.apply(v); if (t != null) { return callback.apply(t); } else { //noinspection unchecked return (U) RestartSelectMarker.RESTART; } }); } // delegates for closeable channel @Override public void done() { original.done(); } @Override public Object doneOrClosed() { return original.doneOrClosed(); } @Override public void error(Throwable reason) { original.error(reason); } @Override public Object errorOrClosed(Throwable reason) { return original.errorOrClosed(reason); } @Override public ChannelClosed closedForSend() { return original.closedForSend(); } @Override public ChannelClosed closedForReceive() { return original.closedForReceive(); } }