hu.akarnokd.rxjava2.Single Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of rxjava2-backport Show documentation
Show all versions of rxjava2-backport Show documentation
rxjava2-backport developed by David Karnok
/**
* Copyright 2015 David Karnok and Netflix, Inc.
*
* 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 hu.akarnokd.rxjava2;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.*;
import org.reactivestreams.*;
import hu.akarnokd.rxjava2.disposables.*;
import hu.akarnokd.rxjava2.exceptions.CompositeException;
import hu.akarnokd.rxjava2.functions.*;
import hu.akarnokd.rxjava2.internal.disposables.EmptyDisposable;
import hu.akarnokd.rxjava2.internal.functions.Functions;
import hu.akarnokd.rxjava2.internal.functions.Objects;
import hu.akarnokd.rxjava2.internal.operators.single.*;
import hu.akarnokd.rxjava2.internal.subscriptions.*;
import hu.akarnokd.rxjava2.internal.util.*;
import hu.akarnokd.rxjava2.plugins.RxJavaPlugins;
import hu.akarnokd.rxjava2.schedulers.Schedulers;
/**
* Represents a deferred computation and emission of a single value or exception.
*
* @param the value type
*/
public class Single {
public interface SingleOnSubscribe extends Consumer> {
}
public interface SingleOperator extends Function, SingleSubscriber super Upstream>> {
}
public interface SingleSubscriber {
void onSubscribe(Disposable d);
void onSuccess(T value);
void onError(Throwable e);
}
public interface SingleTransformer extends Function, Single> {
}
public static Single amb(final Iterable extends Single extends T>> sources) {
Objects.requireNonNull(sources, "sources is null");
return create(new SingleOnSubscribe() {
@Override
public void accept(final SingleSubscriber super T> s) {
final AtomicBoolean once = new AtomicBoolean();
final CompositeDisposable set = new CompositeDisposable();
s.onSubscribe(set);
int c = 0;
Iterator extends Single extends T>> iterator;
try {
iterator = sources.iterator();
} catch (Throwable e) {
s.onError(e);
return;
}
if (iterator == null) {
s.onError(new NullPointerException("The iterator returned is null"));
return;
}
for (;;) {
if (once.get()) {
return;
}
boolean b;
try {
b = iterator.hasNext();
} catch (Throwable e) {
s.onError(e);
return;
}
if (once.get()) {
return;
}
if (!b) {
break;
}
Single extends T> s1;
if (once.get()) {
return;
}
try {
s1 = iterator.next();
} catch (Throwable e) {
set.dispose();
s.onError(e);
return;
}
if (s1 == null) {
set.dispose();
s.onError(new NullPointerException("The single source returned by the iterator is null"));
return;
}
s1.subscribe(new SingleSubscriber() {
@Override
public void onSubscribe(Disposable d) {
set.add(d);
}
@Override
public void onSuccess(T value) {
if (once.compareAndSet(false, true)) {
s.onSuccess(value);
}
}
@Override
public void onError(Throwable e) {
if (once.compareAndSet(false, true)) {
s.onError(e);
} else {
RxJavaPlugins.onError(e);
}
}
});
c++;
}
if (c == 0 && !set.isDisposed()) {
s.onError(new NoSuchElementException());
}
}
});
}
@SuppressWarnings("unchecked")
public static Single amb(final Single extends T>... sources) {
if (sources.length == 0) {
return error(new Supplier() {
@Override
public Throwable get() {
return new NoSuchElementException();
}
});
}
if (sources.length == 1) {
return (Single)sources[0];
}
return create(new SingleOnSubscribe() {
@Override
public void accept(final SingleSubscriber super T> s) {
final AtomicBoolean once = new AtomicBoolean();
final CompositeDisposable set = new CompositeDisposable();
s.onSubscribe(set);
for (Single extends T> s1 : sources) {
if (once.get()) {
return;
}
if (s1 == null) {
set.dispose();
Throwable e = new NullPointerException("One of the sources is null");
if (once.compareAndSet(false, true)) {
s.onError(e);
} else {
RxJavaPlugins.onError(e);
}
return;
}
s1.subscribe(new SingleSubscriber() {
@Override
public void onSubscribe(Disposable d) {
set.add(d);
}
@Override
public void onSuccess(T value) {
if (once.compareAndSet(false, true)) {
s.onSuccess(value);
}
}
@Override
public void onError(Throwable e) {
if (once.compareAndSet(false, true)) {
s.onError(e);
} else {
RxJavaPlugins.onError(e);
}
}
});
}
}
});
}
public static Observable concat(Iterable extends Single extends T>> sources) {
return concat(Observable.fromIterable(sources));
}
public static Observable concat(Observable extends Single extends T>> sources) {
return sources.concatMap(new Function, Publisher extends T>>() {
@Override
public Publisher extends T> apply(Single extends T> v){
return v.toFlowable();
}
});
}
@SuppressWarnings("unchecked")
public static Observable concat(
Single extends T> s1, Single extends T> s2
) {
Objects.requireNonNull(s1, "s1 is null");
Objects.requireNonNull(s2, "s2 is null");
return concat(Observable.fromArray(s1, s2));
}
@SuppressWarnings("unchecked")
public static Observable concat(
Single extends T> s1, Single extends T> s2,
Single extends T> s3
) {
Objects.requireNonNull(s1, "s1 is null");
Objects.requireNonNull(s2, "s2 is null");
Objects.requireNonNull(s3, "s3 is null");
return concat(Observable.fromArray(s1, s2, s3));
}
@SuppressWarnings("unchecked")
public static Observable concat(
Single extends T> s1, Single extends T> s2,
Single extends T> s3, Single extends T> s4
) {
Objects.requireNonNull(s1, "s1 is null");
Objects.requireNonNull(s2, "s2 is null");
Objects.requireNonNull(s3, "s3 is null");
Objects.requireNonNull(s4, "s4 is null");
return concat(Observable.fromArray(s1, s2, s3, s4));
}
@SuppressWarnings("unchecked")
public static Observable concat(
Single extends T> s1, Single extends T> s2,
Single extends T> s3, Single extends T> s4,
Single extends T> s5
) {
Objects.requireNonNull(s1, "s1 is null");
Objects.requireNonNull(s2, "s2 is null");
Objects.requireNonNull(s3, "s3 is null");
Objects.requireNonNull(s4, "s4 is null");
Objects.requireNonNull(s5, "s5 is null");
return concat(Observable.fromArray(s1, s2, s3, s4, s5));
}
@SuppressWarnings("unchecked")
public static Observable concat(
Single extends T> s1, Single extends T> s2,
Single extends T> s3, Single extends T> s4,
Single extends T> s5, Single extends T> s6
) {
Objects.requireNonNull(s1, "s1 is null");
Objects.requireNonNull(s2, "s2 is null");
Objects.requireNonNull(s3, "s3 is null");
Objects.requireNonNull(s4, "s4 is null");
Objects.requireNonNull(s5, "s5 is null");
Objects.requireNonNull(s6, "s6 is null");
return concat(Observable.fromArray(s1, s2, s3, s4, s5, s6));
}
@SuppressWarnings("unchecked")
public static Observable concat(
Single extends T> s1, Single extends T> s2,
Single extends T> s3, Single extends T> s4,
Single extends T> s5, Single extends T> s6,
Single extends T> s7
) {
Objects.requireNonNull(s1, "s1 is null");
Objects.requireNonNull(s2, "s2 is null");
Objects.requireNonNull(s3, "s3 is null");
Objects.requireNonNull(s4, "s4 is null");
Objects.requireNonNull(s5, "s5 is null");
Objects.requireNonNull(s6, "s6 is null");
Objects.requireNonNull(s7, "s7 is null");
return concat(Observable.fromArray(s1, s2, s3, s4, s5, s6, s7));
}
@SuppressWarnings("unchecked")
public static Observable concat(
Single extends T> s1, Single extends T> s2,
Single extends T> s3, Single extends T> s4,
Single extends T> s5, Single extends T> s6,
Single extends T> s7, Single extends T> s8
) {
Objects.requireNonNull(s1, "s1 is null");
Objects.requireNonNull(s2, "s2 is null");
Objects.requireNonNull(s3, "s3 is null");
Objects.requireNonNull(s4, "s4 is null");
Objects.requireNonNull(s5, "s5 is null");
Objects.requireNonNull(s6, "s6 is null");
Objects.requireNonNull(s7, "s7 is null");
Objects.requireNonNull(s8, "s8 is null");
return concat(Observable.fromArray(s1, s2, s3, s4, s5, s6, s7, s8));
}
@SuppressWarnings("unchecked")
public static Observable concat(
Single extends T> s1, Single extends T> s2,
Single extends T> s3, Single extends T> s4,
Single extends T> s5, Single extends T> s6,
Single extends T> s7, Single extends T> s8,
Single extends T> s9
) {
Objects.requireNonNull(s1, "s1 is null");
Objects.requireNonNull(s2, "s2 is null");
Objects.requireNonNull(s3, "s3 is null");
Objects.requireNonNull(s4, "s4 is null");
Objects.requireNonNull(s5, "s5 is null");
Objects.requireNonNull(s6, "s6 is null");
Objects.requireNonNull(s7, "s7 is null");
Objects.requireNonNull(s8, "s8 is null");
Objects.requireNonNull(s9, "s9 is null");
return concat(Observable.fromArray(s1, s2, s3, s4, s5, s6, s7, s8, s9));
}
public static Single create(SingleOnSubscribe onSubscribe) {
Objects.requireNonNull(onSubscribe, "onSubscribe is null");
// TODO plugin wrapper
return new Single(onSubscribe);
}
public static Single defer(final Supplier extends Single extends T>> singleSupplier) {
Objects.requireNonNull(singleSupplier, "singleSupplier is null");
return create(new SingleOnSubscribe() {
@Override
public void accept(SingleSubscriber super T> s) {
Single extends T> next;
try {
next = singleSupplier.get();
} catch (Throwable e) {
s.onSubscribe(EmptyDisposable.INSTANCE);
s.onError(e);
return;
}
if (next == null) {
s.onSubscribe(EmptyDisposable.INSTANCE);
s.onError(new NullPointerException("The Single supplied was null"));
return;
}
next.subscribe(s);
}
});
}
public static Single error(final Supplier extends Throwable> errorSupplier) {
Objects.requireNonNull(errorSupplier, "errorSupplier is null");
return create(new SingleOnSubscribe() {
@Override
public void accept(SingleSubscriber super T> s) {
Throwable error;
try {
error = errorSupplier.get();
} catch (Throwable e) {
error = e;
}
if (error == null) {
error = new NullPointerException();
}
s.onSubscribe(EmptyDisposable.INSTANCE);
s.onError(error);
}
});
}
public static Single error(final Throwable error) {
Objects.requireNonNull(error, "error is null");
return error(new Supplier() {
@Override
public Throwable get() {
return error;
}
});
}
public static Single fromCallable(final Callable extends T> callable) {
Objects.requireNonNull(callable, "callable is null");
return create(new SingleOnSubscribe() {
@Override
public void accept(SingleSubscriber super T> s) {
s.onSubscribe(EmptyDisposable.INSTANCE);
try {
T v = callable.call();
if (v != null) {
s.onSuccess(v);
} else {
s.onError(new NullPointerException());
}
} catch (Throwable e) {
s.onError(e);
}
}
});
}
public static Single fromFuture(Future extends T> future) {
return Observable.fromFuture(future).toSingle();
}
public static Single fromFuture(Future extends T> future, long timeout, TimeUnit unit) {
return Observable.fromFuture(future, timeout, unit).toSingle();
}
public static Single fromFuture(Future extends T> future, long timeout, TimeUnit unit, Scheduler scheduler) {
return Observable.fromFuture(future, timeout, unit, scheduler).toSingle();
}
public static Single fromFuture(Future extends T> future, Scheduler scheduler) {
return Observable.fromFuture(future, scheduler).toSingle();
}
public static Single fromPublisher(final Publisher extends T> publisher) {
Objects.requireNonNull(publisher, "publisher is null");
return create(new SingleOnSubscribe() {
@Override
public void accept(final SingleSubscriber super T> s) {
publisher.subscribe(new Subscriber() {
T value;
@Override
public void onComplete() {
T v = value;
value = null;
if (v != null) {
s.onSuccess(v);
} else {
s.onError(new NoSuchElementException());
}
}
@Override
public void onError(Throwable t) {
value = null;
s.onError(t);
}
@Override
public void onNext(T t) {
value = t;
}
@Override
public void onSubscribe(Subscription inner) {
s.onSubscribe(Disposables.from(inner));
inner.request(Long.MAX_VALUE);
}
});
}
});
}
public static Single just(final T value) {
Objects.requireNonNull(value, "value is null");
return create(new SingleOnSubscribe() {
@Override
public void accept(SingleSubscriber super T> s) {
s.onSubscribe(EmptyDisposable.INSTANCE);
s.onSuccess(value);
}
});
}
public static Observable merge(Iterable extends Single extends T>> sources) {
return merge(Observable.fromIterable(sources));
}
public static Observable merge(Observable extends Single extends T>> sources) {
return sources.flatMap(new Function, Publisher extends T>>() {
@Override
public Publisher extends T> apply(Single extends T> v){
return v.toFlowable();
}
});
}
@SuppressWarnings({ "unchecked", "rawtypes" })
public static Single merge(Single extends Single extends T>> source) {
return source.flatMap((Function)Functions.identity());
}
@SuppressWarnings("unchecked")
public static Observable merge(
Single extends T> s1, Single extends T> s2
) {
Objects.requireNonNull(s1, "s1 is null");
Objects.requireNonNull(s2, "s2 is null");
return merge(Observable.fromArray(s1, s2));
}
@SuppressWarnings("unchecked")
public static Observable merge(
Single extends T> s1, Single extends T> s2,
Single extends T> s3
) {
Objects.requireNonNull(s1, "s1 is null");
Objects.requireNonNull(s2, "s2 is null");
Objects.requireNonNull(s3, "s3 is null");
return merge(Observable.fromArray(s1, s2, s3));
}
@SuppressWarnings("unchecked")
public static Observable merge(
Single extends T> s1, Single extends T> s2,
Single extends T> s3, Single extends T> s4
) {
Objects.requireNonNull(s1, "s1 is null");
Objects.requireNonNull(s2, "s2 is null");
Objects.requireNonNull(s3, "s3 is null");
Objects.requireNonNull(s4, "s4 is null");
return merge(Observable.fromArray(s1, s2, s3, s4));
}
@SuppressWarnings("unchecked")
public static Observable merge(
Single extends T> s1, Single extends T> s2,
Single extends T> s3, Single extends T> s4,
Single extends T> s5
) {
Objects.requireNonNull(s1, "s1 is null");
Objects.requireNonNull(s2, "s2 is null");
Objects.requireNonNull(s3, "s3 is null");
Objects.requireNonNull(s4, "s4 is null");
Objects.requireNonNull(s5, "s5 is null");
return merge(Observable.fromArray(s1, s2, s3, s4, s5));
}
@SuppressWarnings("unchecked")
public static Observable merge(
Single extends T> s1, Single extends T> s2,
Single extends T> s3, Single extends T> s4,
Single extends T> s5, Single extends T> s6
) {
Objects.requireNonNull(s1, "s1 is null");
Objects.requireNonNull(s2, "s2 is null");
Objects.requireNonNull(s3, "s3 is null");
Objects.requireNonNull(s4, "s4 is null");
Objects.requireNonNull(s5, "s5 is null");
Objects.requireNonNull(s6, "s6 is null");
return merge(Observable.fromArray(s1, s2, s3, s4, s5, s6));
}
@SuppressWarnings("unchecked")
public static Observable merge(
Single extends T> s1, Single extends T> s2,
Single extends T> s3, Single extends T> s4,
Single extends T> s5, Single extends T> s6,
Single extends T> s7
) {
Objects.requireNonNull(s1, "s1 is null");
Objects.requireNonNull(s2, "s2 is null");
Objects.requireNonNull(s3, "s3 is null");
Objects.requireNonNull(s4, "s4 is null");
Objects.requireNonNull(s5, "s5 is null");
Objects.requireNonNull(s6, "s6 is null");
Objects.requireNonNull(s7, "s7 is null");
return merge(Observable.fromArray(s1, s2, s3, s4, s5, s6, s7));
}
@SuppressWarnings("unchecked")
public static Observable merge(
Single extends T> s1, Single extends T> s2,
Single extends T> s3, Single extends T> s4,
Single extends T> s5, Single extends T> s6,
Single extends T> s7, Single extends T> s8
) {
Objects.requireNonNull(s1, "s1 is null");
Objects.requireNonNull(s2, "s2 is null");
Objects.requireNonNull(s3, "s3 is null");
Objects.requireNonNull(s4, "s4 is null");
Objects.requireNonNull(s5, "s5 is null");
Objects.requireNonNull(s6, "s6 is null");
Objects.requireNonNull(s7, "s7 is null");
Objects.requireNonNull(s8, "s8 is null");
return merge(Observable.fromArray(s1, s2, s3, s4, s5, s6, s7, s8));
}
@SuppressWarnings("unchecked")
public static Observable merge(
Single extends T> s1, Single extends T> s2,
Single extends T> s3, Single extends T> s4,
Single extends T> s5, Single extends T> s6,
Single extends T> s7, Single extends T> s8,
Single extends T> s9
) {
Objects.requireNonNull(s1, "s1 is null");
Objects.requireNonNull(s2, "s2 is null");
Objects.requireNonNull(s3, "s3 is null");
Objects.requireNonNull(s4, "s4 is null");
Objects.requireNonNull(s5, "s5 is null");
Objects.requireNonNull(s6, "s6 is null");
Objects.requireNonNull(s7, "s7 is null");
Objects.requireNonNull(s8, "s8 is null");
Objects.requireNonNull(s9, "s9 is null");
return merge(Observable.fromArray(s1, s2, s3, s4, s5, s6, s7, s8, s9));
}
static final Single