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

io.datakernel.stream.StreamConsumers Maven / Gradle / Ivy

Go to download

Composable asynchronous/reactive streams with powerful data processing capabilities.

The newest version!
/*
 * Copyright (C) 2015 SoftIndex LLC.
 *
 * 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 io.datakernel.stream;

import io.datakernel.async.AsyncGetter;
import io.datakernel.async.ResultCallback;
import io.datakernel.eventloop.Eventloop;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;

public class StreamConsumers {
	private StreamConsumers() {
	}

	public static  Idle idle(Eventloop eventloop) {
		return new Idle<>(eventloop);
	}

	public static  Closing closing(Eventloop eventloop) {
		return new Closing<>(eventloop);
	}

	public static  ClosingWithError closingWithError(Eventloop eventloop, Exception exception) {
		return new ClosingWithError<>(eventloop, exception);
	}

	/**
	 * Returns {@link ToList} which saves received items in list
	 *
	 * @param eventloop event loop in which will run it
	 * @param list      list with received items
	 * @param        type of item
	 */
	public static  ToList toList(Eventloop eventloop, List list) {
		return new ToList<>(eventloop, list);
	}

	/**
	 * Returns {@link ToList} which saves received items in empty list
	 *
	 * @param eventloop event loop in which will run it
	 * @param        type of item
	 */
	public static  ToList toList(Eventloop eventloop) {
		return toList(eventloop, new ArrayList());
	}

	/**
	 * Returns {@link ToList} which suspends after each receiving data with saving it to list.
	 *
	 * @param eventloop event loop in which will run it
	 * @param list      list with received items
	 * @param        type of item
	 */
	public static  ToList toListOneByOne(Eventloop eventloop, List list) {
		return new ToList(eventloop, list) {
			@Override
			public void onData(T item) {
				super.onData(item);
				upstreamProducer.suspend();
				this.eventloop.post(new Runnable() {
					@Override
					public void run() {
						upstreamProducer.resume();
					}
				});
			}
		};
	}

	/**
	 * Returns {@link ToList} which suspends after each receiving data with saving it to empty list.
	 *
	 * @param eventloop event loop in which will run it
	 * @param        type of item
	 */
	public static  ToList toListOneByOne(Eventloop eventloop) {
		return toListOneByOne(eventloop, new ArrayList());
	}

	/**
	 * Returns {@link ToList} which suspends after some random receiving data with saving it to list from
	 * argument.
	 * 

Useful for unit testing purposes - to make sure upstream producer handles onSuspend and onResume events properly * * @param eventloop event loop in which will run it * @param list list with received items * @param random for generate random values of boolean * @param type of item */ public static ToList toListRandomlySuspending(Eventloop eventloop, List list, final Random random) { return new ToList(eventloop, list) { @Override public void onData(T item) { super.onData(item); if (random.nextBoolean()) { suspendUpstream(); this.eventloop.post(new Runnable() { @Override public void run() { resumeUpstream(); } }); } } }; } /** * Returns {@link ToList} which suspends after default random receiving data with saving it to list * from argument. * * @param eventloop event loop in which will run it * @param list list with received items * @param type of item */ public static ToList toListRandomlySuspending(Eventloop eventloop, List list) { return toListRandomlySuspending(eventloop, list, new Random()); } /** * Returns {@link ToList} which suspends after default random receiving data with saving it to empty list. * * @param eventloop event loop in which will run it * @param type of item */ public static ToList toListRandomlySuspending(Eventloop eventloop) { return toListRandomlySuspending(eventloop, new ArrayList(), new Random()); } public static StreamConsumer asynchronouslyResolving(final Eventloop eventloop, final AsyncGetter> consumerGetter) { final StreamForwarder forwarder = new StreamForwarder<>(eventloop); eventloop.post(new Runnable() { @Override public void run() { consumerGetter.get(new ResultCallback>() { @Override public void onResult(StreamConsumer result) { forwarder.streamTo(result); } @Override public void onException(Exception exception) { forwarder.streamTo(new ClosingWithError(eventloop, exception)); } }); } }); return forwarder; } /** * Represents a simple {@link AbstractStreamConsumer} which with changing producer sets its status as complete. * * @param type of received data */ public static class Closing extends AbstractStreamConsumer implements StreamDataReceiver { public Closing(Eventloop eventloop) { super(eventloop); } /** * With changing producer sets its status as complete. */ @Override public void onConsumerStarted() { upstreamProducer.close(); } @Override public StreamDataReceiver getDataReceiver() { return this; } @Override public void onData(T item) { // do nothing } @Override public void onEndOfStream() { } } public static class ClosingWithError extends AbstractStreamConsumer implements StreamDataReceiver { private final Exception exception; public ClosingWithError(Eventloop eventloop, Exception exception) { super(eventloop); this.exception = exception; } @Override public void onConsumerStarted() { upstreamProducer.closeWithError(exception); } @Override public StreamDataReceiver getDataReceiver() { return this; } @Override public void onData(T item) { // do nothing } @Override public void onEndOfStream() { } } /** * Represents a simple {@link AbstractStreamConsumer} which with changing producer sets its status as complete. * * @param type of received data */ public static class Idle extends AbstractStreamConsumer implements StreamDataReceiver { public Idle(Eventloop eventloop) { super(eventloop); } @Override public StreamDataReceiver getDataReceiver() { return this; } @Override public void onData(T item) { // do nothing } @Override public void onEndOfStream() { upstreamProducer.close(); } } /** * Represents a {@link AbstractStreamConsumer} which adds each item of received data to List. * * @param type of received data */ public static class ToList extends AbstractStreamConsumer implements StreamDataReceiver { private final List list; /** * Creates a new instance of ConsumerToList with empty list and event loop from argument, in which * this customer will run */ public ToList(Eventloop eventloop) { this(eventloop, new ArrayList()); } /** * Creates a new instance of ConsumerToList with * * @param eventloop event loop in which this customer will run * @param list list for adding received items */ public ToList(Eventloop eventloop, List list) { super(eventloop); checkNotNull(list); this.list = list; } /** * Returns list with received items */ public final List getList() { checkState(upstreamProducer.getError() == null, "Upstream error %s: %s", upstreamProducer, upstreamProducer.getError()); checkState(upstreamProducer.getStatus() == StreamProducer.CLOSED, "Upstream %s is not closed", upstreamProducer); return list; } @Override public StreamDataReceiver getDataReceiver() { return this; } /** * Processes received item and adds it to list * * @param item received item */ @Override public void onData(T item) { list.add(item); } /** * Sets the flag complete as true */ @Override public void onEndOfStream() { upstreamProducer.close(); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy