ratpack.stream.TransformablePublisher Maven / Gradle / Ivy
/*
* Copyright 2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ratpack.stream;
import org.reactivestreams.Publisher;
import ratpack.exec.ExecControl;
import ratpack.exec.Promise;
import ratpack.func.Action;
import ratpack.func.Function;
import ratpack.func.Predicate;
import java.util.List;
/**
* A wrapper over a {@link Publisher} that makes it more convenient to chain transformations of different kinds.
*
* Note that this type implements the publisher interface, so behaves just like the publisher that it is wrapping with respect to the {@link Publisher#subscribe(org.reactivestreams.Subscriber)} method.
*
* @param the type of item emitted by this publisher
*/
public interface TransformablePublisher extends Publisher {
/**
* See {@link ratpack.stream.Streams#map(Publisher, Function)}.
*
* @param function the transformation
* @param the type of transformed item
* @return the transformed publisher
*/
default TransformablePublisher map(Function super T, ? extends O> function) {
return Streams.map(this, function);
}
/**
* See {@link ratpack.stream.Streams#flatMap(Publisher, Function)}.
*
* @param function the transformation
* @param the type of transformed item
* @return the transformed publisher
*/
default TransformablePublisher flatMap(Function super T, ? extends Promise extends O>> function) {
return Streams.flatMap(this, function);
}
/**
* See {@link ratpack.stream.Streams#buffer(Publisher)}.
*
* @return a buffering publisher
*/
default TransformablePublisher buffer() {
return Streams.buffer(this);
}
/**
* See {@link ratpack.stream.Streams#gate(Publisher, Action)}.
*
* @param valveReceiver an action that receives a runnable “valve” that when run allows request to start flowing upstream
* @return a publisher that is logically equivalent to the given publisher as far as subscribers are concerned
*/
default TransformablePublisher gate(Action super Runnable> valveReceiver) {
return Streams.gate(this, valveReceiver);
}
/**
* See {@link ratpack.stream.Streams#wiretap(Publisher, Action)}.
*
* @param listener the listener for emitted items
* @return a publisher that is logically equivalent to the given publisher as far as subscribers are concerned
*/
default TransformablePublisher wiretap(Action super StreamEvent super T>> listener) {
return Streams.wiretap(this, listener);
}
/**
* See {@link ratpack.stream.Streams#multicast(Publisher)}.
*
* @return a publisher that respects back pressure for each of its subscribers
*/
default TransformablePublisher multicast() {
return Streams.multicast(this);
}
/**
* See {@link ratpack.stream.Streams#toPromise(Publisher)}.
*
* @return a promise for this publisher's single item
*/
default Promise toPromise() {
return Streams.toPromise(this);
}
/**
* See {@link ratpack.stream.Streams#toPromise(ExecControl, Publisher)}.
*
* @param execControl the exec control to create the promise from
* @return a promise for this publisher's single item
*/
default Promise toPromise(ExecControl execControl) {
return Streams.toPromise(execControl, this);
}
/**
* Consumes the given publisher's items to a list.
*
* This method can be useful when testing, but should be uses with care in production code as it will exhaust memory if the stream is very large.
*
{@code
* import org.reactivestreams.Publisher;
* import ratpack.stream.Streams;
* import ratpack.test.exec.ExecHarness;
*
* import java.util.Arrays;
* import java.util.List;
*
* import static org.junit.Assert.*;
*
* public class Example {
* public static void main(String... args) throws Exception {
* List expected = Arrays.asList("a", "b", "c");
* List result = ExecHarness.yieldSingle(execControl ->
* Streams.publish(expected).toList()
* ).getValue();
*
* assertEquals(Arrays.asList("a", "b", "c"), result);
* }
* }
* }
*
* If the publisher emits an error, the promise will fail and the collected items will be discarded.
*
{@code
* import org.reactivestreams.Publisher;
* import ratpack.stream.Streams;
* import ratpack.test.exec.ExecHarness;
*
* import static org.junit.Assert.*;
*
* public class Example {
* public static void main(String... args) throws Exception {
* Throwable error = ExecHarness.yieldSingle(execControl ->
* Streams.yield(r -> {
* if (r.getRequestNum() < 1) {
* return "a";
* } else {
* throw new RuntimeException("bang!");
* }
* }).toList()
* ).getThrowable();
*
* assertEquals("bang!", error.getMessage());
* }
* }
* }
*
* @return a promise for the stream's contents as a list
*/
default Promise> toList() {
return Streams.toList(this);
}
/**
* See {@link #toList()}.
*
* @param execControl the exec control to create the promise from
* @return a promise for all of this stream's contents as a list
*/
default Promise> toList(ExecControl execControl) {
return Streams.toList(execControl, this);
}
/**
* Convenience method to allow a non Ratpack publisher transform method to be hooked in.
*
* This transformable publisher will be given to the function, that should return a new publisher.
* The returned publisher will then be wrapped in a transformable wrapper which will be returned by this method.
*
* @param transformer a publisher transformer
* @param the type of transformed item
* @return a publisher that respects back pressure for each of its subscribers
*/
default TransformablePublisher transform(java.util.function.Function super TransformablePublisher, ? extends Publisher> transformer) {
return Streams.transformable(transformer.apply(this));
}
/**
* See {@link ratpack.stream.Streams#streamMap(org.reactivestreams.Publisher, ratpack.func.Function)}.
*
* @param function the transformation
* @param the type of transformed item
* @return the transformed publisher
*/
default TransformablePublisher streamMap(Function super WriteStream, ? extends WriteStream> function) {
return Streams.streamMap(this, function);
}
/**
* See {@link ratpack.stream.Streams#filter(Publisher, Predicate)}.
*
* @param filter the filter
* @return the filtered publisher
*/
default TransformablePublisher filter(Predicate filter) {
return Streams.filter(this, filter);
}
}