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

com.github.davidmoten.rx.RxUtil Maven / Gradle / Ivy

There is a newer version: 0.7.19
Show newest version
package com.github.davidmoten.rx;

import java.util.concurrent.atomic.AtomicLong;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import rx.Observable;
import rx.Observable.OnSubscribe;
import rx.Observable.Operator;
import rx.Observer;
import rx.Subscriber;
import rx.functions.Action1;
import rx.functions.Func1;

/**
 * Utility methods for RxJava.
 */
public final class RxUtil {

	/**
	 * slf4j logger.
	 */
	private static final Logger log = LoggerFactory.getLogger(RxUtil.class);

	private RxUtil() {
		// prevent instantiation
	}

	/**
	 * Returns the concatenation of two {@link Observable}s but the first
	 * sequence will be emitted in its entirety and ignored before o2 starts
	 * emitting.
	 * 
	 * @param 
	 *            the generic type of the second observable
	 * @param o1
	 *            the sequence to ignore
	 * @param o2
	 *            the sequence to emit after o1 ignored
	 * @return observable result of concatenating two observables, ignoring the
	 *         first
	 */
	@SuppressWarnings("unchecked")
	public static  Observable concatButIgnoreFirstSequence(
			Observable o1, Observable o2) {
		return Observable.concat((Observable) o1.ignoreElements(), o2);
	}

	/**
	 * Logs errors and onNext at info level using slf4j {@link Logger}.
	 * 
	 * @param 
	 *            the return generic type
	 * @return a logging {@link Observer}
	 */
	public static  Observer log() {
		return new Observer() {

			@Override
			public void onCompleted() {
				// do nothing
			}

			@Override
			public void onError(Throwable e) {
				log.error(e.getMessage(), e);
			}

			@Override
			public void onNext(T t) {
				log.info(t + "");
			}
		};
	}

	/**
	 * Returns a constant value.
	 * 
	 * @param 
	 *            from type
	 * @param 
	 *            to type
	 * @param s
	 * @return a constant function with value s
	 */
	public static  Func1 constant(final S s) {
		return new Func1() {
			@Override
			public S call(R t1) {
				return s;
			}
		};
	}

	/**
	 * Converts a transformation of an Observable into another Observable into
	 * an {@link Operator} suitable for use with
	 * {@link Observable#lift(Operator)} for instance.
	 * 
	 * @param 
	 *            from generic type
	 * @param 
	 *            to generic type
	 * @param operation
	 * @return an operator form of the given function
	 */
	public static  Operator toOperator(
			Func1, Observable> operation) {
		return OperationToOperator.toOperator(operation);
	}

	/**
	 * Returns an {@link Action1} that increments a counter when the call method
	 * is called.
	 * 
	 * @param 
	 *            generic type of item being counted
	 * @return {@link Action1} to count calls.
	 */
	public static  CountingAction counter() {
		return new CountingAction();
	}

	public static class CountingAction implements Action1 {
		private final AtomicLong count = new AtomicLong(0);

		public Observable count() {
			return Observable.create(new OnSubscribe() {

				@Override
				public void call(Subscriber subscriber) {
					subscriber.onNext(count.get());
					subscriber.onCompleted();
				}
			});
		}

		@Override
		public void call(T t) {
			count.incrementAndGet();
		}
	}

	public static  Func1 greaterThanZero() {
		return new Func1() {

			@Override
			public Boolean call(T t) {
				return t.doubleValue() > 0;
			}
		};
	}

	/**
	 * Returns a {@link Func1} that returns an empty {@link Observable}.
	 * 
	 * @return
	 */
	public static  Func1> toEmpty() {
		return constant(Observable. empty());
	}

	/**
	 * Returns an {@link Operator} that flattens a sequence of
	 * {@link Observable} into a flat sequence of the items from the
	 * Observables. This operator may interleave the items asynchronously. For
	 * synchronous behaviour use {@link RxUtil#concat()}.
	 * 
	 * @return
	 */
	public static  Operator> flatten() {
		return toOperator(new Func1>, Observable>() {

			@Override
			public Observable call(Observable> source) {
				return source.flatMap(RxUtil.> identity());
			}
		});
	}

	public static  Func1 identity() {
		return new Func1() {
			@Override
			public T call(T t) {
				return t;
			}
		};
	}

	public static  Operator> concat() {
		return toOperator(new Func1>, Observable>() {

			@Override
			public Observable call(Observable> source) {
				return Observable.concat(source);
			}
		});
	}

}