diff --git a/src/main/java/rx/Single.java b/src/main/java/rx/Single.java new file mode 100644 index 0000000000..d8fcf88b87 --- /dev/null +++ b/src/main/java/rx/Single.java @@ -0,0 +1,1858 @@ +/** + * Copyright 2015 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 rx; + +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +import rx.Observable.Operator; +import rx.annotations.Experimental; +import rx.exceptions.Exceptions; +import rx.exceptions.OnErrorNotImplementedException; +import rx.functions.Action1; +import rx.functions.Func1; +import rx.functions.Func2; +import rx.functions.Func3; +import rx.functions.Func4; +import rx.functions.Func5; +import rx.functions.Func6; +import rx.functions.Func7; +import rx.functions.Func8; +import rx.functions.Func9; +import rx.internal.operators.OnSubscribeToObservableFuture; +import rx.internal.operators.OperatorMap; +import rx.internal.operators.OperatorObserveOn; +import rx.internal.operators.OperatorOnErrorReturn; +import rx.internal.operators.OperatorSubscribeOn; +import rx.internal.operators.OperatorTimeout; +import rx.internal.operators.OperatorZip; +import rx.internal.producers.SingleDelayedProducer; +import rx.observers.SafeSubscriber; +import rx.plugins.RxJavaObservableExecutionHook; +import rx.plugins.RxJavaPlugins; +import rx.schedulers.Schedulers; +import rx.subscriptions.Subscriptions; + +/** + * The Single class that implements the Reactive Pattern for a single value response. See {@link Observable} for a stream or vector of values. + *
+ * This behaves the same as an {@link Observable} except that it can only emit either a single successful value, or an error. + *
+ * Like an {@link Observable} it is lazy, can be either "hot" or "cold", synchronous or asynchronous. + *
+ * The documentation for this class makes use of marble diagrams. The following legend explains these diagrams: + *
+ * + *
+ * For more information see the ReactiveX documentation.
+ *
+ * @param
+ * Note: Use {@link #create(OnExecute)} to create a Single, instead of this constructor,
+ * unless you specifically have a need for inheritance.
+ *
+ * @param f
+ * {@link OnExecute} to be executed when {@link #execute(SingleSubscriber)} or {@link #subscribe(Subscriber)} is called
+ */
+ protected Single(final OnSubscribe
+ *
+ *
+ * Write the function you pass to {@code create} so that it behaves as a Single: It should invoke the
+ * SingleSubscriber {@link SingleSubscriber#onSuccess onSuccess} and {@link SingleSubscriber#onError onError} methods appropriately.
+ *
+ * A well-formed Single must invoke either the SingleSubscriber's {@code onSuccess} method exactly once or
+ * its {@code onError} method exactly once.
+ *
+ *
+ * In other words, this allows chaining TaskExecutors together on a Single for acting on the values within
+ * the Single.
+ * {@code
+ * task.map(...).filter(...).lift(new OperatorA()).lift(new OperatorB(...)).subscribe()
+ * }
+ * If the operator you are creating is designed to act on the item emitted by a source
+ * Single, use {@code lift}. If your operator is designed to transform the source Single as a whole
+ * (for instance, by applying a particular set of existing RxJava operators to it) use {@link #compose}.
+ *
+ * This method operates on the Observable itself whereas {@link #lift} operates on the Observable's
+ * Subscribers or Observers.
+ *
+ * If the operator you are creating is designed to act on the individual items emitted by a source
+ * Observable, use {@link #lift}. If your operator is designed to transform the source Observable as a whole
+ * (for instance, by applying a particular set of existing RxJava operators to it) use {@code compose}.
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ * You can convert any object that supports the {@link Future} interface into an Observable that emits the
+ * return value of the {@link Future#get} method of that object, by passing the object into the {@code from} method.
+ *
+ * Important note: This Observable is blocking; you cannot unsubscribe from it.
+ *
+ *
+ *
+ * You can convert any object that supports the {@link Future} interface into an Observable that emits the
+ * return value of the {@link Future#get} method of that object, by passing the object into the {@code from} method.
+ *
+ * Important note: This Observable is blocking; you cannot unsubscribe from it.
+ *
+ *
+ *
+ * You can convert any object that supports the {@link Future} interface into an Observable that emits the
+ * return value of the {@link Future#get} method of that object, by passing the object into the {@code from} method.
+ *
+ *
+ *
+ * To convert any object into an Observable that emits that object, pass that object into the {@code just} method.
+ *
+ * This is similar to the {@link #from(java.lang.Object[])} method, except that {@code from} will convert
+ * an {@link Iterable} object into an Observable that emits each of the items in the Iterable, one at a
+ * time, while the {@code just} method converts an Iterable into an Observable that emits the entire
+ * Iterable as a single item.
+ *
+ *
+ *
+ *
+ *
+ *
+ * You can combine items emitted by multiple Observables so that they appear as a single Observable, by
+ * using the {@code merge} method.
+ *
+ *
+ *
+ * You can combine items emitted by multiple Observables so that they appear as a single Observable, by
+ * using the {@code merge} method.
+ *
+ *
+ *
+ * You can combine items emitted by multiple Observables so that they appear as a single Observable, by
+ * using the {@code merge} method.
+ *
+ *
+ *
+ * You can combine items emitted by multiple Observables so that they appear as a single Observable, by
+ * using the {@code merge} method.
+ *
+ *
+ *
+ * You can combine items emitted by multiple Observables so that they appear as a single Observable, by
+ * using the {@code merge} method.
+ *
+ *
+ *
+ * You can combine items emitted by multiple Observables so that they appear as a single Observable, by
+ * using the {@code merge} method.
+ *
+ *
+ *
+ * You can combine items emitted by multiple Observables so that they appear as a single Observable, by
+ * using the {@code merge} method.
+ *
+ *
+ *
+ * You can combine items emitted by multiple Observables so that they appear as a single Observable, by
+ * using the {@code merge} method.
+ *
+ *
+ * {@code zip} applies this function in strict sequence, so the first item emitted by the new Observable
+ * will be the result of the function applied to the first item emitted by {@code o1} and the first item
+ * emitted by {@code o2}; the second item emitted by the new Observable will be the result of the function
+ * applied to the second item emitted by {@code o1} and the second item emitted by {@code o2}; and so forth.
+ *
+ * The resulting {@code Observable
+ *
+ * {@code zip} applies this function in strict sequence, so the first item emitted by the new Observable
+ * will be the result of the function applied to the first item emitted by {@code o1}, the first item
+ * emitted by {@code o2}, and the first item emitted by {@code o3}; the second item emitted by the new
+ * Observable will be the result of the function applied to the second item emitted by {@code o1}, the
+ * second item emitted by {@code o2}, and the second item emitted by {@code o3}; and so forth.
+ *
+ * The resulting {@code Observable
+ *
+ * {@code zip} applies this function in strict sequence, so the first item emitted by the new Observable
+ * will be the result of the function applied to the first item emitted by {@code o1}, the first item
+ * emitted by {@code o2}, the first item emitted by {@code o3}, and the first item emitted by {@code 04};
+ * the second item emitted by the new Observable will be the result of the function applied to the second
+ * item emitted by each of those Observables; and so forth.
+ *
+ * The resulting {@code Observable
+ *
+ * {@code zip} applies this function in strict sequence, so the first item emitted by the new Observable
+ * will be the result of the function applied to the first item emitted by {@code o1}, the first item
+ * emitted by {@code o2}, the first item emitted by {@code o3}, the first item emitted by {@code o4}, and
+ * the first item emitted by {@code o5}; the second item emitted by the new Observable will be the result of
+ * the function applied to the second item emitted by each of those Observables; and so forth.
+ *
+ * The resulting {@code Observable
+ *
+ * {@code zip} applies this function in strict sequence, so the first item emitted by the new Observable
+ * will be the result of the function applied to the first item emitted by each source Observable, the
+ * second item emitted by the new Observable will be the result of the function applied to the second item
+ * emitted by each of those Observables, and so forth.
+ *
+ * The resulting {@code Observable
+ *
+ * {@code zip} applies this function in strict sequence, so the first item emitted by the new Observable
+ * will be the result of the function applied to the first item emitted by each source Observable, the
+ * second item emitted by the new Observable will be the result of the function applied to the second item
+ * emitted by each of those Observables, and so forth.
+ *
+ * The resulting {@code Observable
+ *
+ * {@code zip} applies this function in strict sequence, so the first item emitted by the new Observable
+ * will be the result of the function applied to the first item emitted by each source Observable, the
+ * second item emitted by the new Observable will be the result of the function applied to the second item
+ * emitted by each of those Observables, and so forth.
+ *
+ * The resulting {@code Observable
+ *
+ * {@code zip} applies this function in strict sequence, so the first item emitted by the new Observable
+ * will be the result of the function applied to the first item emitted by each source Observable, the
+ * second item emitted by the new Observable will be the result of the function applied to the second item
+ * emitted by each of those Observables, and so forth.
+ *
+ * The resulting {@code Observable
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ * You can combine items emitted by multiple Observables so that they appear as a single Observable, by
+ * using the {@code mergeWith} method.
+ *
+ *
+ *
+ *
+ *
+ * By default, when an Observable encounters an error that prevents it from emitting the expected item to
+ * its {@link Observer}, the Observable invokes its Observer's {@code onError} method, and then quits
+ * without invoking any more of its Observer's methods. The {@code onErrorReturn} method changes this
+ * behavior. If you pass a function ({@code resumeFunction}) to an Observable's {@code onErrorReturn} method, if the original Observable encounters an error, instead of invoking its Observer's
+ * {@code onError} method, it will instead emit the return value of {@code resumeFunction}.
+ *
+ * You can use this to prevent errors from propagating or to supply fallback data should errors be
+ * encountered.
+ *
+ * Use this only for implementing an {@link Operator} that requires nested subscriptions. For other
+ * purposes, use {@link #subscribe(Subscriber)} which ensures the Rx contract and other functionality.
+ *
+ * A typical implementation of {@code subscribe} does the following:
+ *
+ * An {@code Single
+ * For more information see the
+ * ReactiveX documentation.
+ *
+ * A typical implementation of {@code subscribe} does the following:
+ *
+ * An {@code Single
+ * For more information see the
+ * ReactiveX documentation.
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ * After an SingleSubscriber calls an {@link Single}'s {@link Single#subscribe subscribe} method, the
+ * {@code Single} calls the SingleSubscriber's {@link #onSuccess} and {@link #onError} methods to provide notifications.
+ * A well-behaved {@code Single} will call an SingleSubscriber's {@link #onSuccess} method exactly once or
+ * the SingleSubscriber's {@link #onError} method exactly once.
+ *
+ * @see ReactiveX documentation: Observable
+ * @param
+ * The {@link Single} will not call this method if it calls {@link #onError}.
+ */
+ public abstract void onSuccess(T value);
+
+ /**
+ * Notifies the SingleSubscriber that the {@link Single} has experienced an error condition.
+ *
+ * If the {@link Single} calls this method, it will not thereafter call {@link #onSuccess}.
+ *
+ * @param e
+ * the exception encountered by the Single
+ */
+ public abstract void onError(Throwable error);
+
+ /**
+ * Adds a {@link Subscription} to this Subscriber's list of subscriptions if this list is not marked as
+ * unsubscribed. If the list is marked as unsubscribed, {@code add} will indicate this by
+ * explicitly unsubscribing the new {@code Subscription} as well.
+ *
+ * @param s
+ * the {@code Subscription} to add
+ */
+ public final void add(Subscription s) {
+ cs.add(s);
+ }
+
+ @Override
+ public final void unsubscribe() {
+ cs.unsubscribe();
+ }
+
+ /**
+ * Indicates whether this Subscriber has unsubscribed from its list of subscriptions.
+ *
+ * @return {@code true} if this Subscriber has unsubscribed from its subscriptions, {@code false} otherwise
+ */
+ @Override
+ public final boolean isUnsubscribed() {
+ return cs.isUnsubscribed();
+ }
+}
\ No newline at end of file
diff --git a/src/perf/java/rx/PerfBaseline.java b/src/perf/java/rx/ObservablePerfBaseline.java
similarity index 98%
rename from src/perf/java/rx/PerfBaseline.java
rename to src/perf/java/rx/ObservablePerfBaseline.java
index fa3f4bc313..061caf6264 100644
--- a/src/perf/java/rx/PerfBaseline.java
+++ b/src/perf/java/rx/ObservablePerfBaseline.java
@@ -30,7 +30,7 @@
@BenchmarkMode(Mode.Throughput)
@OutputTimeUnit(TimeUnit.SECONDS)
-public class PerfBaseline {
+public class ObservablePerfBaseline {
@State(Scope.Thread)
public static class Input extends InputWithIncrementingInteger {
diff --git a/src/perf/java/rx/SinglePerfBaseline.java b/src/perf/java/rx/SinglePerfBaseline.java
new file mode 100644
index 0000000000..e1a646cef0
--- /dev/null
+++ b/src/perf/java/rx/SinglePerfBaseline.java
@@ -0,0 +1,100 @@
+/**
+ * Copyright 2014 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 rx;
+
+import java.util.concurrent.TimeUnit;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.infra.Blackhole;
+
+import rx.Single.OnSubscribe;
+import rx.jmh.LatchedObserver;
+
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+public class SinglePerfBaseline {
+
+
+ @Benchmark
+ public void singleConsumption(Input input) throws InterruptedException {
+ input.single.subscribe(input.newSubscriber());
+ }
+
+ @Benchmark
+ public void singleConsumptionUnsafe(Input input) throws InterruptedException {
+ input.single.unsafeSubscribe(input.newSubscriber());
+ }
+
+ @Benchmark
+ public void newSingleAndSubscriberEachTime(Input input) throws InterruptedException {
+ input.newSingle().subscribe(input.newSubscriber());
+ }
+
+ @State(Scope.Thread)
+ public static class Input {
+ public Single
+ *
+ *
+ * @param
+ *
+ *
+ * @param lift
+ * the Operator that implements the Single-operating function to be applied to the source Single
+ * @return a Single that is the result of applying the lifted Operator to the source Single
+ * @see RxJava wiki: Implementing Your Own Operators
+ */
+ private final
+ *
+ *
+ * @param transformer
+ * implements the function that transforms the source Observable
+ * @return the source Observable, transformed by the transformer function
+ * @see RxJava wiki: Implementing Your Own Operators
+ */
+ @SuppressWarnings("unchecked")
+ public
+ *
+ *
+ * @return an Observable that emits a single item: the source Observable
+ * @see ReactiveX operators documentation: To
+ */
+ private final Single
+ *
+ *
+ * @param t1
+ * an Single to be concatenated
+ * @param t2
+ * an Single to be concatenated
+ * @return an Observable that emits items emitted by the two source Observables, one after the other,
+ * without interleaving them
+ * @see ReactiveX operators documentation: Concat
+ */
+ public final static
+ *
+ *
+ * @param t1
+ * a Single to be concatenated
+ * @param t2
+ * a Single to be concatenated
+ * @param t3
+ * a Single to be concatenated
+ * @return an Observable that emits items emitted by the three source Observables, one after the other,
+ * without interleaving them
+ * @see ReactiveX operators documentation: Concat
+ */
+ public final static
+ *
+ *
+ * @param t1
+ * a Single to be concatenated
+ * @param t2
+ * a Single to be concatenated
+ * @param t3
+ * a Single to be concatenated
+ * @param t4
+ * a Single to be concatenated
+ * @return an Observable that emits items emitted by the four source Observables, one after the other,
+ * without interleaving them
+ * @see ReactiveX operators documentation: Concat
+ */
+ public final static
+ *
+ *
+ * @param t1
+ * a Single to be concatenated
+ * @param t2
+ * a Single to be concatenated
+ * @param t3
+ * a Single to be concatenated
+ * @param t4
+ * a Single to be concatenated
+ * @param t5
+ * a Single to be concatenated
+ * @return an Observable that emits items emitted by the five source Observables, one after the other,
+ * without interleaving them
+ * @see ReactiveX operators documentation: Concat
+ */
+ public final static
+ *
+ *
+ * @param t1
+ * a Single to be concatenated
+ * @param t2
+ * a Single to be concatenated
+ * @param t3
+ * a Single to be concatenated
+ * @param t4
+ * a Single to be concatenated
+ * @param t5
+ * a Single to be concatenated
+ * @param t6
+ * a Single to be concatenated
+ * @return an Observable that emits items emitted by the six source Observables, one after the other,
+ * without interleaving them
+ * @see ReactiveX operators documentation: Concat
+ */
+ public final static
+ *
+ *
+ * @param t1
+ * a Single to be concatenated
+ * @param t2
+ * a Single to be concatenated
+ * @param t3
+ * a Single to be concatenated
+ * @param t4
+ * a Single to be concatenated
+ * @param t5
+ * a Single to be concatenated
+ * @param t6
+ * a Single to be concatenated
+ * @param t7
+ * a Single to be concatenated
+ * @return an Observable that emits items emitted by the seven source Observables, one after the other,
+ * without interleaving them
+ * @see ReactiveX operators documentation: Concat
+ */
+ public final static
+ *
+ *
+ * @param t1
+ * a Single to be concatenated
+ * @param t2
+ * a Single to be concatenated
+ * @param t3
+ * a Single to be concatenated
+ * @param t4
+ * a Single to be concatenated
+ * @param t5
+ * a Single to be concatenated
+ * @param t6
+ * a Single to be concatenated
+ * @param t7
+ * a Single to be concatenated
+ * @param t8
+ * a Single to be concatenated
+ * @return an Observable that emits items emitted by the eight source Observables, one after the other,
+ * without interleaving them
+ * @see ReactiveX operators documentation: Concat
+ */
+ public final static
+ *
+ *
+ * @param t1
+ * a Single to be concatenated
+ * @param t2
+ * a Single to be concatenated
+ * @param t3
+ * a Single to be concatenated
+ * @param t4
+ * a Single to be concatenated
+ * @param t5
+ * a Single to be concatenated
+ * @param t6
+ * a Single to be concatenated
+ * @param t7
+ * a Single to be concatenated
+ * @param t8
+ * a Single to be concatenated
+ * @param t9
+ * a Single to be concatenated
+ * @return an Observable that emits items emitted by the nine source Observables, one after the other,
+ * without interleaving them
+ * @see ReactiveX operators documentation: Concat
+ */
+ public final static
+ *
+ *
+ * @param exception
+ * the particular Throwable to pass to {@link Observer#onError onError}
+ * @param
+ *
+ *
+ * @param future
+ * the source {@link Future}
+ * @param
+ *
+ *
+ * @param future
+ * the source {@link Future}
+ * @param timeout
+ * the maximum time to wait before calling {@code get}
+ * @param unit
+ * the {@link TimeUnit} of the {@code timeout} argument
+ * @param
+ *
+ *
+ * @param future
+ * the source {@link Future}
+ * @param scheduler
+ * the {@link Scheduler} to wait for the Future on. Use a Scheduler such as {@link Schedulers#io()} that can block and wait on the Future
+ * @param
+ *
+ *
+ * @param value
+ * the item to emit
+ * @param
+ *
+ *
+ * @param source
+ * a Single that emits a Single
+ * @return a Single that emits the item that is the result of flattening the Single emitted by the {@code source} Single
+ * @see ReactiveX operators documentation: Merge
+ */
+ public final static
+ *
+ *
+ * @param t1
+ * a Single to be merged
+ * @param t2
+ * a Single to be merged
+ * @return an Observable that emits all of the items emitted by the source Observables
+ * @see ReactiveX operators documentation: Merge
+ */
+ public final static
+ *
+ *
+ * @param t1
+ * a Single to be merged
+ * @param t2
+ * a Single to be merged
+ * @param t3
+ * a Single to be merged
+ * @return an Observable that emits all of the items emitted by the source Observables
+ * @see ReactiveX operators documentation: Merge
+ */
+ public final static
+ *
+ *
+ * @param t1
+ * a Single to be merged
+ * @param t2
+ * a Single to be merged
+ * @param t3
+ * a Single to be merged
+ * @param t4
+ * a Single to be merged
+ * @return an Observable that emits all of the items emitted by the source Observables
+ * @see ReactiveX operators documentation: Merge
+ */
+ public final static
+ *
+ *
+ * @param t1
+ * a Single to be merged
+ * @param t2
+ * a Single to be merged
+ * @param t3
+ * a Single to be merged
+ * @param t4
+ * a Single to be merged
+ * @param t5
+ * a Single to be merged
+ * @return an Observable that emits all of the items emitted by the source Observables
+ * @see ReactiveX operators documentation: Merge
+ */
+ public final static
+ *
+ *
+ * @param t1
+ * a Single to be merged
+ * @param t2
+ * a Single to be merged
+ * @param t3
+ * a Single to be merged
+ * @param t4
+ * a Single to be merged
+ * @param t5
+ * a Single to be merged
+ * @param t6
+ * a Single to be merged
+ * @return an Observable that emits all of the items emitted by the source Observables
+ * @see ReactiveX operators documentation: Merge
+ */
+ public final static
+ *
+ *
+ * @param t1
+ * a Single to be merged
+ * @param t2
+ * a Single to be merged
+ * @param t3
+ * a Single to be merged
+ * @param t4
+ * a Single to be merged
+ * @param t5
+ * a Single to be merged
+ * @param t6
+ * a Single to be merged
+ * @param t7
+ * a Single to be merged
+ * @return an Observable that emits all of the items emitted by the source Observables
+ * @see ReactiveX operators documentation: Merge
+ */
+ public final static
+ *
+ *
+ * @param t1
+ * a Single to be merged
+ * @param t2
+ * a Single to be merged
+ * @param t3
+ * a Single to be merged
+ * @param t4
+ * a Single to be merged
+ * @param t5
+ * a Single to be merged
+ * @param t6
+ * a Single to be merged
+ * @param t7
+ * a Single to be merged
+ * @param t8
+ * a Single to be merged
+ * @return an Observable that emits all of the items emitted by the source Observables
+ * @see ReactiveX operators documentation: Merge
+ */
+ public final static
+ *
+ *
+ * @param t1
+ * a Single to be merged
+ * @param t2
+ * a Single to be merged
+ * @param t3
+ * a Single to be merged
+ * @param t4
+ * a Single to be merged
+ * @param t5
+ * a Single to be merged
+ * @param t6
+ * a Single to be merged
+ * @param t7
+ * a Single to be merged
+ * @param t8
+ * a Single to be merged
+ * @param t9
+ * a Single to be merged
+ * @return an Observable that emits all of the items emitted by the source Observables
+ * @see ReactiveX operators documentation: Merge
+ */
+ public final static
+ *
+ *
+ * @param o1
+ * the first source Observable
+ * @param o2
+ * a second source Observable
+ * @param zipFunction
+ * a function that, when applied to an item emitted by each of the source Observables, results
+ * in an item that will be emitted by the resulting Observable
+ * @return an Observable that emits the zipped results
+ * @see ReactiveX operators documentation: Zip
+ */
+ public final static
+ *
+ *
+ * @param o1
+ * the first source Observable
+ * @param o2
+ * a second source Observable
+ * @param o3
+ * a third source Observable
+ * @param zipFunction
+ * a function that, when applied to an item emitted by each of the source Observables, results in
+ * an item that will be emitted by the resulting Observable
+ * @return an Observable that emits the zipped results
+ * @see ReactiveX operators documentation: Zip
+ */
+ public final static
+ *
+ *
+ * @param o1
+ * the first source Observable
+ * @param o2
+ * a second source Observable
+ * @param o3
+ * a third source Observable
+ * @param o4
+ * a fourth source Observable
+ * @param zipFunction
+ * a function that, when applied to an item emitted by each of the source Observables, results in
+ * an item that will be emitted by the resulting Observable
+ * @return an Observable that emits the zipped results
+ * @see ReactiveX operators documentation: Zip
+ */
+ public final static
+ *
+ *
+ * @param o1
+ * the first source Observable
+ * @param o2
+ * a second source Observable
+ * @param o3
+ * a third source Observable
+ * @param o4
+ * a fourth source Observable
+ * @param o5
+ * a fifth source Observable
+ * @param zipFunction
+ * a function that, when applied to an item emitted by each of the source Observables, results in
+ * an item that will be emitted by the resulting Observable
+ * @return an Observable that emits the zipped results
+ * @see ReactiveX operators documentation: Zip
+ */
+ public final static
+ *
+ *
+ * @param o1
+ * the first source Observable
+ * @param o2
+ * a second source Observable
+ * @param o3
+ * a third source Observable
+ * @param o4
+ * a fourth source Observable
+ * @param o5
+ * a fifth source Observable
+ * @param o6
+ * a sixth source Observable
+ * @param zipFunction
+ * a function that, when applied to an item emitted by each of the source Observables, results in
+ * an item that will be emitted by the resulting Observable
+ * @return an Observable that emits the zipped results
+ * @see ReactiveX operators documentation: Zip
+ */
+ public final static
+ *
+ *
+ * @param o1
+ * the first source Observable
+ * @param o2
+ * a second source Observable
+ * @param o3
+ * a third source Observable
+ * @param o4
+ * a fourth source Observable
+ * @param o5
+ * a fifth source Observable
+ * @param o6
+ * a sixth source Observable
+ * @param o7
+ * a seventh source Observable
+ * @param zipFunction
+ * a function that, when applied to an item emitted by each of the source Observables, results in
+ * an item that will be emitted by the resulting Observable
+ * @return an Observable that emits the zipped results
+ * @see ReactiveX operators documentation: Zip
+ */
+ public final static
+ *
+ *
+ * @param o1
+ * the first source Observable
+ * @param o2
+ * a second source Observable
+ * @param o3
+ * a third source Observable
+ * @param o4
+ * a fourth source Observable
+ * @param o5
+ * a fifth source Observable
+ * @param o6
+ * a sixth source Observable
+ * @param o7
+ * a seventh source Observable
+ * @param o8
+ * an eighth source Observable
+ * @param zipFunction
+ * a function that, when applied to an item emitted by each of the source Observables, results in
+ * an item that will be emitted by the resulting Observable
+ * @return an Observable that emits the zipped results
+ * @see ReactiveX operators documentation: Zip
+ */
+ public final static
+ *
+ *
+ * @param o1
+ * the first source Observable
+ * @param o2
+ * a second source Observable
+ * @param o3
+ * a third source Observable
+ * @param o4
+ * a fourth source Observable
+ * @param o5
+ * a fifth source Observable
+ * @param o6
+ * a sixth source Observable
+ * @param o7
+ * a seventh source Observable
+ * @param o8
+ * an eighth source Observable
+ * @param o9
+ * a ninth source Observable
+ * @param zipFunction
+ * a function that, when applied to an item emitted by each of the source Observables, results in
+ * an item that will be emitted by the resulting Observable
+ * @return an Observable that emits the zipped results
+ * @see ReactiveX operators documentation: Zip
+ */
+ public final static
+ *
+ *
+ * @param t1
+ * a Single to be concatenated after the current
+ * @return an Observable that emits items emitted by the two source Observables, one after the other,
+ * without interleaving them
+ * @see ReactiveX operators documentation: Concat
+ */
+ public final Observable
+ *
+ *
+ * @param func
+ * a function that, when applied to an item emitted by the source Observable, returns an
+ * Observable
+ * @return an Observable that emits the result of applying the transformation function to each item emitted
+ * by the source Observable and merging the results of the Observables obtained from this
+ * transformation
+ * @see ReactiveX operators documentation: FlatMap
+ */
+ public final
+ *
+ *
+ * @param func
+ * a function that, when applied to an item emitted by the source Observable, returns an
+ * Observable
+ * @return an Observable that emits the result of applying the transformation function to each item emitted
+ * by the source Observable and merging the results of the Observables obtained from this
+ * transformation
+ * @see ReactiveX operators documentation: FlatMap
+ */
+ public final
+ *
+ *
+ * @param func
+ * a function to apply to the item emitted by the Single
+ * @return a Single that emits the item from the source Single, transformed by the specified function
+ * @see ReactiveX operators documentation: Map
+ */
+ public final
+ *
+ *
+ * @param t1
+ * a Single to be merged
+ * @return an Observable that emits all of the items emitted by the source Observables
+ * @see ReactiveX operators documentation: Merge
+ */
+ public final Observable
+ *
+ *
+ * @param scheduler
+ * the {@link Scheduler} to notify {@link Observer}s on
+ * @return the source Observable modified so that its {@link Observer}s are notified on the specified {@link Scheduler}
+ * @see ReactiveX operators documentation: ObserveOn
+ * @see RxJava Threading Examples
+ * @see #subscribeOn
+ */
+ public final Single
+ *
+ *
+ * @param resumeFunction
+ * a function that returns an item that the new Observable will emit if the source Observable
+ * encounters an error
+ * @return the original Observable with appropriately modified behavior
+ * @see ReactiveX operators documentation: Catch
+ */
+ public final Single
+ *
+ *
+ * @return a {@link Subscription} reference can request the {@link Single} stop work.
+ * @throws OnErrorNotImplementedException
+ * if the Observable tries to call {@code onError}
+ * @see ReactiveX operators documentation: Subscribe
+ */
+ public final Subscription subscribe() {
+ return subscribe(new Subscriber
+ *
+ *
+ * @param onNext
+ * the {@code Action1
+ *
+ *
+ * @param onNext
+ * the {@code Action1
+ *
+ *
+ * @param subscriber
+ * the Subscriber that will handle emissions and notifications from the Observable
+ */
+ public final void unsafeSubscribe(Subscriber super T> subscriber) {
+ try {
+ // new Subscriber so onStart it
+ subscriber.onStart();
+ // TODO add back the hook
+ // hook.onSubscribeStart(this, onSubscribe).call(subscriber);
+ onSubscribe.call(subscriber);
+ hook.onSubscribeReturn(subscriber);
+ } catch (Throwable e) {
+ // special handling for certain Throwable/Error/Exception types
+ Exceptions.throwIfFatal(e);
+ // if an unhandled error occurs executing the onSubscribe we will propagate it
+ try {
+ subscriber.onError(hook.onSubscribeError(e));
+ } catch (OnErrorNotImplementedException e2) {
+ // special handling when onError is not implemented ... we just rethrow
+ throw e2;
+ } catch (Throwable e2) {
+ // if this happens it means the onError itself failed (perhaps an invalid function implementation)
+ // so we are unable to propagate the error correctly and will just throw
+ RuntimeException r = new RuntimeException("Error occurred attempting to subscribe [" + e.getMessage() + "] and then again while trying to pass to onError.", e2);
+ // TODO could the hook be the cause of the error in the on error handling.
+ hook.onSubscribeError(r);
+ // TODO why aren't we throwing the hook's return value.
+ throw r;
+ }
+ }
+ }
+
+ /**
+ * Subscribes to an Single and provides a Subscriber that implements functions to handle the item the
+ * Single emits and any error notification it issues.
+ *
+ *
+ *
+ *
+ * @param subscriber
+ * the {@link Subscriber} that will handle emissions and notifications from the Observable
+ * @return a {@link Subscription} reference can request the {@link Single} stop work.
+ * @throws IllegalStateException
+ * if {@code subscribe} is unable to obtain an {@code OnSubscribe<>} function
+ * @throws IllegalArgumentException
+ * if the {@link Subscriber} provided as the argument to {@code subscribe} is {@code null}
+ * @throws OnErrorNotImplementedException
+ * if the {@link Subscriber}'s {@code onError} method is null
+ * @throws RuntimeException
+ * if the {@link Subscriber}'s {@code onError} method itself threw a {@code Throwable}
+ * @see ReactiveX operators documentation: Subscribe
+ */
+ public final Subscription subscribe(Subscriber super T> subscriber) {
+ // validate and proceed
+ if (subscriber == null) {
+ throw new IllegalArgumentException("observer can not be null");
+ }
+ if (onSubscribe == null) {
+ throw new IllegalStateException("onSubscribe function can not be null.");
+ /*
+ * the subscribe function can also be overridden but generally that's not the appropriate approach
+ * so I won't mention that in the exception
+ */
+ }
+
+ // new Subscriber so onStart it
+ subscriber.onStart();
+
+ /*
+ * See https://github.com/ReactiveX/RxJava/issues/216 for discussion on "Guideline 6.4: Protect calls
+ * to user code from within an Observer"
+ */
+ // if not already wrapped
+ if (!(subscriber instanceof SafeSubscriber)) {
+ // assign to `observer` so we return the protected version
+ subscriber = new SafeSubscriber
+ *
+ *
+ *
+ * @param subscriber
+ * the {@link Subscriber} that will handle emissions and notifications from the Observable
+ * @return a {@link Subscription} reference can request the {@link Single} stop work.
+ * @throws IllegalStateException
+ * if {@code subscribe} is unable to obtain an {@code OnSubscribe<>} function
+ * @throws IllegalArgumentException
+ * if the {@link Subscriber} provided as the argument to {@code subscribe} is {@code null}
+ * @throws OnErrorNotImplementedException
+ * if the {@link Subscriber}'s {@code onError} method is null
+ * @throws RuntimeException
+ * if the {@link Subscriber}'s {@code onError} method itself threw a {@code Throwable}
+ * @see ReactiveX operators documentation: Subscribe
+ */
+ public final Subscription subscribe(final SingleSubscriber super T> te) {
+ Subscriber
+ *
+ *
+ * @param scheduler
+ * the {@link Scheduler} to perform subscription actions on
+ * @return the source Observable modified so that its subscriptions happen on the
+ * specified {@link Scheduler}
+ * @see ReactiveX operators documentation: SubscribeOn
+ * @see RxJava Threading Examples
+ * @see #observeOn
+ */
+ public final Single
+ *
+ *
+ * @param timeout
+ * maximum duration between emitted items before a timeout occurs
+ * @param timeUnit
+ * the unit of time that applies to the {@code timeout} argument.
+ * @return the source Observable modified to notify observers of a {@code TimeoutException} in case of a
+ * timeout
+ * @see ReactiveX operators documentation: Timeout
+ */
+ public final Single
+ *
+ *
+ * @param timeout
+ * maximum duration between items before a timeout occurs
+ * @param timeUnit
+ * the unit of time that applies to the {@code timeout} argument
+ * @param scheduler
+ * the Scheduler to run the timeout timers on
+ * @return the source Observable modified to notify observers of a {@code TimeoutException} in case of a
+ * timeout
+ * @see ReactiveX operators documentation: Timeout
+ */
+ public final Single
+ *
+ *
+ * @param timeout
+ * maximum duration between items before a timeout occurs
+ * @param timeUnit
+ * the unit of time that applies to the {@code timeout} argument
+ * @param other
+ * the fallback Observable to use in case of a timeout
+ * @return the source Observable modified to switch to the fallback Observable in case of a timeout
+ * @see ReactiveX operators documentation: Timeout
+ */
+ public final Single
+ *
+ *
+ * @param timeout
+ * maximum duration between items before a timeout occurs
+ * @param timeUnit
+ * the unit of time that applies to the {@code timeout} argument
+ * @param other
+ * the Observable to use as the fallback in case of a timeout
+ * @param scheduler
+ * the {@link Scheduler} to run the timeout timers on
+ * @return the source Observable modified so that it will switch to the fallback Observable in case of a
+ * timeout
+ * @see ReactiveX operators documentation: Timeout
+ */
+ public final Single
+ *
+ *
+ * @param