net.pincette.rs.Chain Maven / Gradle / Ivy
package net.pincette.rs;
import java.time.Duration;
import java.util.List;
import java.util.concurrent.CompletionStage;
import java.util.concurrent.Flow.Processor;
import java.util.concurrent.Flow.Publisher;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
/**
* Chains processors after the initial publisher.
*
* @param the object type of the initial publisher.
* @author Werner Donné
* @since 1.0
*/
public class Chain {
private final Publisher publisher;
private Chain(final Publisher publisher) {
this.publisher = publisher;
}
/**
* Creates a chain with the initial publisher.
*
* @param publisher the initial publisher.
* @param the object type of the initial publisher.
* @return The chain.
* @since 1.0
*/
public static Chain with(final Publisher publisher) {
return new Chain<>(publisher);
}
/**
* Appends value to the stream.
*
* @param value the value to emit. It may be null.
* @return the new stream.
* @since 1.0
*/
public Chain after(final T value) {
return map(After.after(value));
}
/**
* Asks the upstream for more elements if it hasn't received any before the timeout, until the
* stream completes.
*
* @since 3.0
*/
public Chain askForever(final Duration timeout) {
return map(AskForever.askForever(timeout));
}
/**
* Appends the result of value to the stream.
*
* @param value the function that produces the value to emit. It may not be null.
* @return the new stream.
* @since 1.2.1
*/
public Chain after(final Supplier value) {
return map(After.after(value));
}
/**
* Puts value before the stream.
*
* @param value the value to emit. It may be null.
* @return the new stream.
* @since 1.0
*/
public Chain before(final T value) {
return map(Before.before(value));
}
/**
* Puts the result of value before the stream.
*
* @param value the function that produces the value to emit. It may not be null.
* @return the new stream.
* @since 1.2.1
*/
public Chain before(final Supplier value) {
return map(Before.before(value));
}
/**
* Buffers a number of values. It always requests the number of values from the publisher that
* equals the buffer size.
*
* @param size the buffer size.
* @return the new stream.
* @since 1.7
*/
public Chain buffer(final int size) {
return map(Buffer.buffer(size));
}
/**
* Buffers a number of values. It always requests the number of values from the publisher that
* equals the buffer size.
*
* @param size the buffer size.
* @param timeout the time after which the buffer requests a new value, even if it hasn't received
* enough elements yet.
* @return the new stream.
* @since 3.0.2
*/
public Chain buffer(final int size, final Duration timeout) {
return map(Buffer.buffer(size, timeout));
}
/**
* When the down stream requests more messages this indicates all messages it has received were
* processed correctly. This is a moment to perform a commit with a function that receives the
* list of uncommitted messages.
*
* @param commit the commit function. New messages are only requested when the completion stage
* returns true.
* @return A new chain with the same object type.
* @since 3.0
*/
public Chain commit(final Function, CompletionStage> commit) {
return map(Commit.commit(commit));
}
/**
* Appends a processor that filters objects using the predicate function.
*
* @param predicate the predicate function.
* @return A new chain with the same object type.
* @since 1.0
*/
public Chain filter(final Predicate predicate) {
return map(Filter.filter(predicate));
}
/**
* Appends a processor that only emits the first value it receives.
*
* @return A new chain with the same object type.
* @since 1.4
*/
public Chain first() {
return map(First.first());
}
/**
* Appends a processor that emits the elements from the generated publisher individually.
*
* @param function the function that generates the publisher.
* @return A new chain with the same object type.
* @since 3.0
*/
public Chain flatMap(final Function> function) {
return map(Flatten.flatMap(function));
}
/**
* Appends a processor that emits the elements from the generated list individually.
*
* @param function the function that generates the list.
* @return A new chain with the same object type.
* @since 3.0
*/
public Chain flatMapList(final Function> function) {
return map(FlattenList.flatMapList(function));
}
/**
* Returns the publisher of the chain.
*
* @return The publisher.
* @since 1.0
*/
public Publisher get() {
return publisher;
}
/**
* Appends a processor that doesn't emit the head of a stream, but instead gives it to a function.
*
* @param head the function that receives the first value.
* @param tail the function that receives all other values.
* @param the object type for the new chain.
* @return The new chain.
* @since 3.0
*/
public Chain headTail(final Consumer head, final Function tail) {
return map(HeadTail.headTail(head, tail));
}
/**
* Appends a processor that only emits the last value it receives.
*
* @return A new chain with the same object type.
* @since 1.4
*/
public Chain last() {
return map(Last.last());
}
/**
* Appends processor to the chain.
*
* @param processor the given processor.
* @param the object type for the new chain.
* @return The new chain.
* @since 1.0
*/
public Chain map(final Processor processor) {
publisher.subscribe(processor);
return new Chain<>(processor);
}
/**
* Appends a processor with the mapping function, which transforms the objects.
*
* @param function the mapping function.
* @param the object type for the new chain.
* @return The new chain.
* @since 1.0
*/
public Chain map(final Function function) {
return map(Mapper.map(function));
}
/**
* Appends a processor with the mapping function, which transforms the objects. The completion
* stages are processed in the order of the stream, which completes only after the last stage is
* completed. The functions are executed in sequence, which means a function call starts only
* after the previous completion stage has completed.
*
* @param function the mapping function.
* @param the object type for the new chain.
* @return The new chain.
* @since 3.1.2
*/
public Chain mapAsyncSequential(final Function> function) {
return map(Async.mapAsyncSequential(function));
}
/**
* Appends a processor with the mapping function, which transforms the objects. The completion
* stages are processed in the order of the stream, which completes only after the last stage is
* completed. This means the functions may start in parallel, but the completions are emitted in
* the proper order.
*
* @param function the mapping function.
* @param the object type for the new chain.
* @return The new chain.
* @since 1.5.1
*/
public Chain mapAsync(final Function> function) {
return map(Async.mapAsync(function));
}
/**
* Appends a processor with the mapping function, which transforms the objects. The functions
* stages are executed in the order of the stream, which completes only after the last stage is
* completed. A function call will also receive the result of the previous call, which is
* null for the first call.
*
* @param function the mapping function.
* @param the object type for the new chain.
* @return The new chain.
* @since 3.0
*/
public Chain mapAsync(final BiFunction> function) {
return map(AsyncDepend.mapAsync(function));
}
/**
* Appends a processor that filters objects using negation of the predicate function.
*
* @param predicate the predicate function.
* @return A new chain with the same object type.
* @since 1.0
*/
public Chain notFilter(final Predicate predicate) {
return map(NotFilter.notFilter(predicate));
}
/**
* Buffers a number of values. It always requests the number of values from the publisher that
* equals the buffer size. It emits the buffered values as a list.
*
* @param size the buffer size.
* @return the new stream.
* @since 2.0
*/
public Chain> per(final int size) {
return map(Per.per(size));
}
/**
* Buffers a number of values. It always requests the number of values from the publisher that
* equals the buffer size. It emits the buffered values as a list.
*
* @param size the buffer size.
* @param timeout the timeout after which the buffer is flushed. It should be positive.
* @return the new stream.
* @since 3.0.2
*/
public Chain> per(final int size, final Duration timeout) {
return map(Per.per(size, timeout));
}
/**
* Buffers a number of values. It always requests the number of values from the publisher that
* equals the buffer size. It emits the buffered values as a list.
*
* @param size the buffer size.
* @param timeout the timeout after which the buffer is flushed. It should be positive.
* @param requestTimeout the time after which an additional element is requested, even if the
* upstream publisher hasn't sent all requested elements yet. This provides the opportunity to
* the publisher to complete properly when it has fewer elements left than the buffer size. It
* may be null.
* @return the new stream.
* @since 3.0.2
*/
public Chain> per(final int size, final Duration timeout, final Duration requestTimeout) {
return map(Per.per(size, timeout, requestTimeout));
}
/**
* Puts value between the emitted values.
*
* @param value the value to emit between the emitted values. It may be null.
* @return The new stream.
* @since 1.0
*/
public Chain separate(final T value) {
return map(Separator.separator(value));
}
/**
* Puts the result of value between the emitted values.
*
* @param value the function that produces the value to emit between the emitted values. It may
* not be null.
* @return The new stream.
* @since 1.2.1
*/
public Chain separate(final Supplier value) {
return map(Separator.separator(value));
}
/**
* When the upstream or downstream could cause races, this processor serializes everything with a
* thread and a blocking queue.
*
* @since 3.0
*/
public Chain split() {
return map(Split.split());
}
/**
* Appends a processor that emits values until it receives one that matches predicate
* , which is also emitted.
*
* @param predicate the predicate function.
* @return A new chain with the same object type.
* @since 1.4
*/
public Chain until(final Predicate predicate) {
return map(Until.until(predicate));
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy