Repository navigation
Expand file tree
/
Copy pathMaybe.java
More file actions
809 lines (759 loc) · 35.5 KB
/
Copy pathMaybe.java
File metadata and controls
809 lines (759 loc) · 35.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
/**
* Copyright 2016 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 io.reactivex;
import java.util.concurrent.Callable;
import io.reactivex.annotations.SchedulerSupport;
import io.reactivex.disposables.Disposable;
import io.reactivex.exceptions.Exceptions;
import io.reactivex.functions.*;
import io.reactivex.internal.functions.*;
import io.reactivex.internal.operators.maybe.*;
import io.reactivex.internal.util.ExceptionHelper;
import io.reactivex.plugins.RxJavaPlugins;
import io.reactivex.subscribers.TestSubscriber;
/**
* Represents a deferred computation and emission of a maybe value or exception.
* <p>
* The main consumer type of Maybe is {@link MaybeObserver} whose methods are called
* in a sequential fashion following this protocol:<br>
* {@code onSubscribe (onSuccess | onError | onComplete)?}.
* <p>
* @param <T> the value type
* @since 2.0
*/
public abstract class Maybe<T> implements MaybeSource<T> {
/**
* Provides an API (via a cold Maybe) that bridges the reactive world with the callback-style world.
* <p>
* Example:
* <pre><code>
* Maybe.<Event>create(emitter -> {
* Callback listener = new Callback() {
* @Override
* public void onEvent(Event e) {
* if (e.isNothing()) {
* emitter.onComplete();
* } else {
* emitter.onSuccess(e);
* }
* }
*
* @Override
* public void onFailure(Exception e) {
* emitter.onError(e);
* }
* };
*
* AutoCloseable c = api.someMethod(listener);
*
* emitter.setCancellable(c::close);
*
* });
* </code></pre>
* <p>
* <dl>
* <dt><b>Scheduler:</b></dt>
* <dd>{@code create} does not operate by default on a particular {@link Scheduler}.</dd>
* </dl>
* @param <T> the value type
* @param onSubscribe the emitter that is called when a MaybeObserver subscribes to the returned {@code Flowable}
* @return the new Maybe instance
* @see MaybeOnSubscribe
* @see Cancellable
*/
public static <T> Maybe<T> create(MaybeOnSubscribe<T> onSubscribe) {
ObjectHelper.requireNonNull(onSubscribe, "onSubscribe is null");
return RxJavaPlugins.onAssembly(new MaybeCreate<T>(onSubscribe));
}
/**
* Calls a Callable for each individual MaybeObserver to return the actual MaybeSource source to
* be subscribe to.
* <dl>
* <dt><b>Scheduler:</b></dt>
* <dd>{@code defer} does not operate by default on a particular {@link Scheduler}.</dd>
* </dl>
* @param <T> the value type
* @param maybeSupplier the Callable that is called for each individual MaybeObserver and
* returns a MaybeSource instance to subscribe to
* @return the new Maybe instance
*/
public static <T> Maybe<T> defer(final Callable<? extends MaybeSource<? extends T>> maybeSupplier) {
ObjectHelper.requireNonNull(maybeSupplier, "maybeSupplier is null");
return RxJavaPlugins.onAssembly(new MaybeDefer<T>(maybeSupplier));
}
/**
* Returns a (singleton) Maybe instance that calls {@link MaybeObserver#onComplete onComplete}
* immediately.
* <p>
* <img width="640" height="190" src="https://raw.github.com/wiki/ReactiveX/RxJava/images/rx-operators/empty.png" alt="">
* <dl>
* <dt><b>Scheduler:</b></dt>
* <dd>{@code empty} does not operate by default on a particular {@link Scheduler}.</dd>
* </dl>
* @param <T> the value type
* @return the new Maybe instance
*/
@SuppressWarnings("unchecked")
public static <T> Maybe<T> empty() {
return RxJavaPlugins.onAssembly((Maybe<T>)MaybeEmpty.INSTANCE);
}
/**
* Returns a Maybe that invokes a subscriber's {@link MaybeObserver#onError onError} method when the
* subscriber subscribes to it.
* <p>
* <img width="640" height="190" src="https://raw.github.com/wiki/ReactiveX/RxJava/images/rx-operators/Single.error.png" alt="">
* <dl>
* <dt><b>Scheduler:</b></dt>
* <dd>{@code error} does not operate by default on a particular {@link Scheduler}.</dd>
* </dl>
*
* @param exception
* the particular Throwable to pass to {@link MaybeObserver#onError onError}
* @param <T>
* the type of the item (ostensibly) emitted by the Maybe
* @return a Maybe that invokes the subscriber's {@link MaybeObserver#onError onError} method when
* the subscriber subscribes to it
* @see <a href="http://reactivex.io/documentation/operators/empty-never-throw.html">ReactiveX operators documentation: Throw</a>
*/
public static <T> Maybe<T> error(Throwable exception) {
ObjectHelper.requireNonNull(exception, "exception is null");
return RxJavaPlugins.onAssembly(new MaybeError<T>(exception));
}
/**
* Returns a Maybe that invokes an {@link Observer}'s {@link MaybeObserver#onError onError} method when the
* Observer subscribes to it.
* <p>
* <img width="640" height="190" src="https://raw.github.com/wiki/ReactiveX/RxJava/images/rx-operators/error.png" alt="">
* <dl>
* <dt><b>Scheduler:</b></dt>
* <dd>{@code error} does not operate by default on a particular {@link Scheduler}.</dd>
* </dl>
*
* @param supplier
* a Callable factory to return a Throwable for each individual Subscriber
* @param <T>
* the type of the items (ostensibly) emitted by the Publisher
* @return a Maybe that invokes the {@link MaybeObserver}'s {@link MaybeObserver#onError onError} method when
* the MaybeObserver subscribes to it
* @see <a href="http://reactivex.io/documentation/operators/empty-never-throw.html">ReactiveX operators documentation: Throw</a>
*/
public static <T> Maybe<T> error(Callable<? extends Throwable> supplier) {
ObjectHelper.requireNonNull(supplier, "errorSupplier is null");
return RxJavaPlugins.onAssembly(new MaybeErrorCallable<T>(supplier));
}
/**
* Returns a Maybe instance that runs the given Action for each subscriber and
* emits either its exception or simply completes.
* <dl>
* <dt><b>Scheduler:</b></dt>
* <dd>{@code fromAction} does not operate by default on a particular {@link Scheduler}.</dd>
* </dl>
* @param <T> the target type
* @param run the runnable to run for each subscriber
* @return the new Maybe instance
* @throws NullPointerException if run is null
*/
@SchedulerSupport(SchedulerSupport.NONE)
public static <T> Maybe<T> fromAction(final Action run) {
ObjectHelper.requireNonNull(run, "run is null");
return RxJavaPlugins.onAssembly(new MaybeFromAction<T>(run));
}
/**
* Returns a {@link Maybe} that invokes passed function and emits its result for each new MaybeObserver that subscribes
* while considering {@code null} value from the callable as indication for valueless completion.
* <p>
* Allows you to defer execution of passed function until MaybeObserver subscribes to the {@link Maybe}.
* It makes passed function "lazy".
* Result of the function invocation will be emitted by the {@link Maybe}.
* <dl>
* <dt><b>Scheduler:</b></dt>
* <dd>{@code fromCallable} does not operate by default on a particular {@link Scheduler}.</dd>
* </dl>
*
* @param callable
* function which execution should be deferred, it will be invoked when MaybeObserver will subscribe to the {@link Maybe}.
* @param <T>
* the type of the item emitted by the {@link Maybe}.
* @return a {@link Maybe} whose {@link MaybeObserver}s' subscriptions trigger an invocation of the given function.
*/
public static <T> Maybe<T> fromCallable(final Callable<? extends T> callable) {
ObjectHelper.requireNonNull(callable, "callable is null");
return RxJavaPlugins.onAssembly(new MaybeFromCallable<T>(callable));
}
/**
* Returns a Maybe instance that runs the given Action for each subscriber and
* emits either its exception or simply completes.
* <dl>
* <dt><b>Scheduler:</b></dt>
* <dd>{@code fromRunnable} does not operate by default on a particular {@link Scheduler}.</dd>
* </dl>
* @param <T> the target type
* @param run the runnable to run for each subscriber
* @return the new Maybe instance
* @throws NullPointerException if run is null
*/
@SchedulerSupport(SchedulerSupport.NONE)
public static <T> Maybe<T> fromRunnable(final Runnable run) {
ObjectHelper.requireNonNull(run, "run is null");
return RxJavaPlugins.onAssembly(new MaybeFromRunnable<T>(run));
}
/**
* Returns a {@code Maybe} that emits a specified item.
* <p>
* <img width="640" height="310" src="https://raw.github.com/wiki/ReactiveX/RxJava/images/rx-operators/Single.just.png" alt="">
* <p>
* To convert any object into a {@code Single} that emits that object, pass that object into the
* {@code just} method.
* <dl>
* <dt><b>Scheduler:</b></dt>
* <dd>{@code just} does not operate by default on a particular {@link Scheduler}.</dd>
* </dl>
*
* @param item
* the item to emit
* @param <T>
* the type of that item
* @return a {@code Maybe} that emits {@code item}
* @see <a href="http://reactivex.io/documentation/operators/just.html">ReactiveX operators documentation: Just</a>
*/
public static <T> Maybe<T> just(T item) {
ObjectHelper.requireNonNull(item, "item is null");
return RxJavaPlugins.onAssembly(new MaybeJust<T>(item));
}
/**
* Returns a Maybe that never sends any items or notifications to an {@link MaybeObserver}.
* <p>
* <img width="640" height="185" src="https://raw.github.com/wiki/ReactiveX/RxJava/images/rx-operators/never.png" alt="">
* <p>
* This Publisher is useful primarily for testing purposes.
* <dl>
* <dt><b>Scheduler:</b></dt>
* <dd>{@code never} does not operate by default on a particular {@link Scheduler}.</dd>
* </dl>
*
* @param <T>
* the type of items (not) emitted by the Publisher
* @return a Maybe that never emits any items or sends any notifications to an {@link MaybeObserver}
* @see <a href="http://reactivex.io/documentation/operators/empty-never-throw.html">ReactiveX operators documentation: Never</a>
*/
@SuppressWarnings("unchecked")
public static <T> Maybe<T> never() {
return RxJavaPlugins.onAssembly((Maybe<T>)MaybeNever.INSTANCE);
}
/**
* <strong>Advanced use only:</strong> creates a Maybe instance without
* any safeguards by using a callback that is called with a MaybeObserver.
* <dl>
* <dt><b>Scheduler:</b></dt>
* <dd>{@code unsafeCreate} does not operate by default on a particular {@link Scheduler}.</dd>
* </dl>
* @param <T> the value type
* @param onSubscribe the function that is called with the subscribing MaybeObserver
* @return the new Maybe instance
*/
public static <T> Maybe<T> unsafeCreate(MaybeSource<T> onSubscribe) {
if (onSubscribe instanceof Maybe) {
throw new IllegalArgumentException("unsafeCreate(Maybe) should be upgraded");
}
ObjectHelper.requireNonNull(onSubscribe, "onSubscribe is null");
return RxJavaPlugins.onAssembly(new MaybeUnsafeCreate<T>(onSubscribe));
}
/**
* Wraps a MaybeSource instance into a new Maybe instance if not already a Maybe
* instance.
* <dl>
* <dt><b>Scheduler:</b></dt>
* <dd>{@code wrap} does not operate by default on a particular {@link Scheduler}.</dd>
* </dl>
* @param <T> the value type
* @param source the source to wrap
* @return the Maybe wrapper or the source cast to Maybe (if possible)
*/
public static <T> Maybe<T> wrap(MaybeSource<T> source) {
if (source instanceof Maybe) {
return RxJavaPlugins.onAssembly((Maybe<T>)source);
}
ObjectHelper.requireNonNull(source, "onSubscribe is null");
return RxJavaPlugins.onAssembly(new MaybeUnsafeCreate<T>(source));
}
// ------------------------------------------------------------------
// Instance methods
// ------------------------------------------------------------------
/**
* Casts the success value of the current Maybe into the target type or signals a
* ClassCastException if not compatible.
* <dl>
* <dt><b>Scheduler:</b></dt>
* <dd>{@code cast} does not operate by default on a particular {@link Scheduler}.</dd>
* </dl>
* @param <U> the target type
* @param clazz the type token to use for casting the success result from the current Maybe
* @return the new Maybe instance
* @since 2.0
*/
public final <U> Maybe<U> cast(final Class<? extends U> clazz) {
ObjectHelper.requireNonNull(clazz, "clazz is null");
return map(Functions.castFunction(clazz));
}
/**
* Transform a Maybe by applying a particular Transformer function to it.
* <p>
* This method operates on the Maybe itself whereas {@link #lift} operates on the Maybe's MaybeObservers.
* <p>
* If the operator you are creating is designed to act on the individual item emitted by a Maybe, use
* {@link #lift}. If your operator is designed to transform the source Maybe as a whole (for instance, by
* applying a particular set of existing RxJava operators to it) use {@code compose}.
* <dl>
* <dt><b>Scheduler:</b></dt>
* <dd>{@code compose} does not operate by default on a particular {@link Scheduler}.</dd>
* </dl>
*
* @param <R> the value type of the Maybe returned by the transformer function
* @param transformer
* implements the function that transforms the source Maybe
* @return a Maybe, transformed by the transformer function
* @see <a href="https://github.com/ReactiveX/RxJava/wiki/Implementing-Your-Own-Operators">RxJava wiki: Implementing Your Own Operators</a>
*/
public final <R> Maybe<R> compose(Function<? super Maybe<T>, ? extends MaybeSource<R>> transformer) {
return wrap(to(transformer));
}
/**
* Registers an {@link Action} to be called when this Maybe invokes either
* {@link MaybeObserver#onComplete onSuccess},
* {@link MaybeObserver#onComplete onComplete} or {@link MaybeObserver#onError onError}.
* <p>
* <img width="640" height="310" src="https://raw.github.com/wiki/ReactiveX/RxJava/images/rx-operators/finallyDo.png" alt="">
* <dl>
* <dt><b>Scheduler:</b></dt>
* <dd>{@code doAfterTerminate} does not operate by default on a particular {@link Scheduler}.</dd>
* </dl>
*
* @param onAfterTerminate
* an {@link Action} to be invoked when the source Publisher finishes
* @return a Maybe that emits the same items as the source Maybe, then invokes the
* {@link Action}
* @see <a href="http://reactivex.io/documentation/operators/do.html">ReactiveX operators documentation: Do</a>
*/
@SchedulerSupport(SchedulerSupport.NONE)
public final Maybe<T> doAfterTerminate(Action onAfterTerminate) {
return RxJavaPlugins.onAssembly(new MaybePeek<T>(this,
Functions.emptyConsumer(), // onSubscribe
Functions.emptyConsumer(), // onSuccess
Functions.emptyConsumer(), // onError
Functions.EMPTY_ACTION, // onComplete
ObjectHelper.requireNonNull(onAfterTerminate, "onAfterTerminate is null"),
Functions.EMPTY_ACTION // dispose
));
}
/**
* Calls the shared runnable if a MaybeObserver subscribed to the current Single
* disposes the common Disposable it received via onSubscribe.
* <dl>
* <dt><b>Scheduler:</b></dt>
* <dd>{@code doOnSubscribe} does not operate by default on a particular {@link Scheduler}.</dd>
* </dl>
* @param onDispose the runnable called when the subscription is cancelled (disposed)
* @return the new Maybe instance
*/
public final Maybe<T> doOnDispose(final Action onDispose) {
return RxJavaPlugins.onAssembly(new MaybePeek<T>(this,
Functions.emptyConsumer(), // onSubscribe
Functions.emptyConsumer(), // onSuccess
Functions.emptyConsumer(), // onError
Functions.EMPTY_ACTION, // onComplete
Functions.EMPTY_ACTION, // (onSuccess | onError | onComplete) after
ObjectHelper.requireNonNull(onDispose, "onDispose is null")
));
}
/**
* Modifies the source Publisher so that it invokes an action when it calls {@code onCompleted}.
* <p>
* <img width="640" height="305" src="https://raw.github.com/wiki/ReactiveX/RxJava/images/rx-operators/doOnComplete.png" alt="">
* <dl>
* <dt><b>Scheduler:</b></dt>
* <dd>{@code doOnComplete} does not operate by default on a particular {@link Scheduler}.</dd>
* </dl>
*
* @param onComplete
* the action to invoke when the source Publisher calls {@code onCompleted}
* @return the new Maybe with the side-effecting behavior applied
* @see <a href="http://reactivex.io/documentation/operators/do.html">ReactiveX operators documentation: Do</a>
*/
@SchedulerSupport(SchedulerSupport.NONE)
public final Maybe<T> doOnComplete(Action onComplete) {
return RxJavaPlugins.onAssembly(new MaybePeek<T>(this,
Functions.emptyConsumer(), // onSubscribe
Functions.emptyConsumer(), // onSuccess
Functions.emptyConsumer(), // onError
ObjectHelper.requireNonNull(onComplete, "onComplete is null"),
Functions.EMPTY_ACTION, // (onSuccess | onError | onComplete)
Functions.EMPTY_ACTION // dispose
));
}
/**
* Calls the shared consumer with the error sent via onError for each
* MaybeObserver that subscribes to the current Single.
* <dl>
* <dt><b>Scheduler:</b></dt>
* <dd>{@code doOnSubscribe} does not operate by default on a particular {@link Scheduler}.</dd>
* </dl>
* @param onError the consumer called with the success value of onError
* @return the new Maybe instance
*/
public final Maybe<T> doOnError(final Consumer<? super Throwable> onError) {
return RxJavaPlugins.onAssembly(new MaybePeek<T>(this,
Functions.emptyConsumer(), // onSubscribe
Functions.emptyConsumer(), // onSuccess
ObjectHelper.requireNonNull(onError, "onError is null"),
Functions.EMPTY_ACTION, // onComplete
Functions.EMPTY_ACTION, // (onSuccess | onError | onComplete)
Functions.EMPTY_ACTION // dispose
));
}
/**
* Calls the shared consumer with the Disposable sent through the onSubscribe for each
* MaybeObserver that subscribes to the current Single.
* <dl>
* <dt><b>Scheduler:</b></dt>
* <dd>{@code doOnSubscribe} does not operate by default on a particular {@link Scheduler}.</dd>
* </dl>
* @param onSubscribe the consumer called with the Disposable sent via onSubscribe
* @return the new Maybe instance
*/
public final Maybe<T> doOnSubscribe(final Consumer<? super Disposable> onSubscribe) {
return RxJavaPlugins.onAssembly(new MaybePeek<T>(this,
ObjectHelper.requireNonNull(onSubscribe, "onSubscribe is null"),
Functions.emptyConsumer(), // onSuccess
Functions.emptyConsumer(), // onError
Functions.EMPTY_ACTION, // onComplete
Functions.EMPTY_ACTION, // (onSuccess | onError | onComplete)
Functions.EMPTY_ACTION // dispose
));
}
/**
* Calls the shared consumer with the success value sent via onSuccess for each
* MaybeObserver that subscribes to the current Single.
* <dl>
* <dt><b>Scheduler:</b></dt>
* <dd>{@code doOnSubscribe} does not operate by default on a particular {@link Scheduler}.</dd>
* </dl>
* @param onSuccess the consumer called with the success value of onSuccess
* @return the new Maybe instance
*/
public final Maybe<T> doOnSuccess(final Consumer<? super T> onSuccess) {
return RxJavaPlugins.onAssembly(new MaybePeek<T>(this,
Functions.emptyConsumer(), // onSubscribe
ObjectHelper.requireNonNull(onSuccess, "onSubscribe is null"),
Functions.emptyConsumer(), // onError
Functions.EMPTY_ACTION, // onComplete
Functions.EMPTY_ACTION, // (onSuccess | onError | onComplete)
Functions.EMPTY_ACTION // dispose
));
}
/**
* Filters the success item of the Maybe via a predicate function and emitting it if the predicate
* returns true, completing otherwise.
* <p>
* <img width="640" height="310" src="https://raw.github.com/wiki/ReactiveX/RxJava/images/rx-operators/filter.png" alt="">
* <dl>
* <dt><b>Scheduler:</b></dt>
* <dd>{@code filter} does not operate by default on a particular {@link Scheduler}.</dd>
* </dl>
*
* @param predicate
* a function that evaluates the item emitted by the source Maybe, returning {@code true}
* if it passes the filter
* @return a Maybe that emit the item emitted by the source Maybe that the filter
* evaluates as {@code true}
* @see <a href="http://reactivex.io/documentation/operators/filter.html">ReactiveX operators documentation: Filter</a>
*/
@SchedulerSupport(SchedulerSupport.NONE)
public final Maybe<T> filter(Predicate<? super T> predicate) {
ObjectHelper.requireNonNull(predicate, "predicate is null");
return RxJavaPlugins.onAssembly(new MaybeFilter<T>(this, predicate));
}
/**
* Returns a Maybe that is based on applying a specified function to the item emitted by the source Single,
* where that function returns a MaybeSource.
* <p>
* <img width="640" height="300" src="https://raw.github.com/wiki/ReactiveX/RxJava/images/rx-operators/Single.flatMap.png" alt="">
* <dl>
* <dt><b>Scheduler:</b></dt>
* <dd>{@code flatMap} does not operate by default on a particular {@link Scheduler}.</dd>
* </dl>
*
* @param <R> the result value type
* @param mapper
* a function that, when applied to the item emitted by the source Maybe, returns a MaybeSource
* @return the Maybe returned from {@code func} when applied to the item emitted by the source Maybe
* @see <a href="http://reactivex.io/documentation/operators/flatmap.html">ReactiveX operators documentation: FlatMap</a>
*/
public final <R> Maybe<R> flatMap(Function<? super T, ? extends MaybeSource<? extends R>> mapper) {
ObjectHelper.requireNonNull(mapper, "mapper is null");
return RxJavaPlugins.onAssembly(new MaybeFlatMap<T, R>(this, mapper));
}
/**
* Maps the onSuccess, onError or onComplete signals of this Maybe into MaybeSource and emits that
* MaybeSource's signals
* <p>
* <img width="640" height="410" src="https://raw.github.com/wiki/ReactiveX/RxJava/images/rx-operators/mergeMap.nce.png" alt="">
* <dl>
* <dt><b>Scheduler:</b></dt>
* <dd>{@code flatMap} does not operate by default on a particular {@link Scheduler}.</dd>
* </dl>
*
* @param <R>
* the result type
* @param onSuccessMapper
* a function that returns a MaybeSource to merge for the success item emitted by this Maybe
* @param onErrorMapper
* a function that returns a MaybeSource to merge for an onError notification from this Maybe
* @param onCompleteSupplier
* a function that returns a MaybeSource to merge for an onCompleted notification this Maybe
* @return the new Maybe instance
* @see <a href="http://reactivex.io/documentation/operators/flatmap.html">ReactiveX operators documentation: FlatMap</a>
*/
@SchedulerSupport(SchedulerSupport.NONE)
public final <R> Maybe<R> flatMap(
Function<? super T, ? extends MaybeSource<? extends R>> onSuccessMapper,
Function<? super Throwable, ? extends MaybeSource<? extends R>> onErrorMapper,
Callable<? extends MaybeSource<? extends R>> onCompleteSupplier) {
ObjectHelper.requireNonNull(onSuccessMapper, "onNextMapper is null");
ObjectHelper.requireNonNull(onErrorMapper, "onErrorMapper is null");
ObjectHelper.requireNonNull(onCompleteSupplier, "onCompleteSupplier is null");
return new MaybeFlatMapNotification<T, R>(this, onSuccessMapper, onErrorMapper, onCompleteSupplier);
}
/**
* Ignores the item emitted by the source Maybe and only calls {@code onCompleted} or {@code onError}.
* <p>
* <img width="640" height="305" src="https://raw.github.com/wiki/ReactiveX/RxJava/images/rx-operators/ignoreElements.png" alt="">
* <dl>
* <dt><b>Scheduler:</b></dt>
* <dd>{@code ignoreElement} does not operate by default on a particular {@link Scheduler}.</dd>
* </dl>
*
* @return an empty Maybe that only calls {@code onComplete} or {@code onError}, based on which one is
* called by the source Publisher
* @see <a href="http://reactivex.io/documentation/operators/ignoreelements.html">ReactiveX operators documentation: IgnoreElements</a>
*/
@SchedulerSupport(SchedulerSupport.NONE)
public final Maybe<T> ignoreElement() {
return RxJavaPlugins.onAssembly(new MaybeIgnoreElement<T>(this));
}
/**
* Lifts a function to the current Maybe and returns a new Maybe that when subscribed to will pass the
* values of the current Maybe through the MaybeOperator function.
* <p>
* In other words, this allows chaining TaskExecutors together on a Maybe for acting on the values within
* the Maybe.
* <p>
* {@code task.map(...).filter(...).lift(new OperatorA()).lift(new OperatorB(...)).subscribe() }
* <p>
* If the operator you are creating is designed to act on the item emitted by a source Maybe, use
* {@code lift}. If your operator is designed to transform the source Maybe as a whole (for instance, by
* applying a particular set of existing RxJava operators to it) use {@link #compose}.
* <dl>
* <dt><b>Scheduler:</b></dt>
* <dd>{@code lift} does not operate by default on a particular {@link Scheduler}.</dd>
* </dl>
*
* @param <R> the downstream's value type (output)
* @param lift
* the MaybeOperator that implements the Maybe-operating function to be applied to the source Maybe
* @return a Maybe that is the result of applying the lifted Operator to the source Maybe
* @see <a href="https://github.com/ReactiveX/RxJava/wiki/Implementing-Your-Own-Operators">RxJava wiki: Implementing Your Own Operators</a>
*/
public final <R> Maybe<R> lift(final MaybeOperator<? extends R, ? super T> lift) {
ObjectHelper.requireNonNull(lift, "onLift is null");
return RxJavaPlugins.onAssembly(new MaybeLift<T, R>(this, lift));
}
/**
* Returns a Maybe that applies a specified function to the item emitted by the source Maybe and
* emits the result of this function application.
* <p>
* <img width="640" height="305" src="https://raw.github.com/wiki/ReactiveX/RxJava/images/rx-operators/Single.map.png" alt="">
* <dl>
* <dt><b>Scheduler:</b></dt>
* <dd>{@code map} does not operate by default on a particular {@link Scheduler}.</dd>
* </dl>
*
* @param <R> the result value type
* @param mapper
* a function to apply to the item emitted by the Maybe
* @return a Maybe that emits the item from the source Maybe, transformed by the specified function
* @see <a href="http://reactivex.io/documentation/operators/map.html">ReactiveX operators documentation: Map</a>
*/
public final <R> Maybe<R> map(Function<? super T, ? extends R> mapper) {
ObjectHelper.requireNonNull(mapper, "mapper is null");
return RxJavaPlugins.onAssembly(new MaybeMap<T, R>(this, mapper));
}
/**
* Wraps a Maybe to emit its item (or notify of its error) on a specified {@link Scheduler},
* asynchronously.
* <p>
* <img width="640" height="305" src="https://raw.github.com/wiki/ReactiveX/RxJava/images/rx-operators/Single.observeOn.png" alt="">
* <dl>
* <dt><b>Scheduler:</b></dt>
* <dd>you specify which {@link Scheduler} this operator will use</dd>
* </dl>
*
* @param scheduler
* the {@link Scheduler} to notify subscribers on
* @return the new Maybe instance that its subscribers are notified on the specified
* {@link Scheduler}
* @see <a href="http://reactivex.io/documentation/operators/observeon.html">ReactiveX operators documentation: ObserveOn</a>
* @see <a href="http://www.grahamlea.com/2014/07/rxjava-threading-examples/">RxJava Threading Examples</a>
* @see #subscribeOn
*/
public final Maybe<T> observeOn(final Scheduler scheduler) {
ObjectHelper.requireNonNull(scheduler, "scheduler is null");
return RxJavaPlugins.onAssembly(new MaybeObserveOn<T>(this, scheduler));
}
/**
* Calls the specified converter function with the current Maybe instance
* during assembly time and returns its result.
* <dl>
* <dt><b>Scheduler:</b></dt>
* <dd>{@code to} does not operate by default on a particular {@link Scheduler}.</dd>
* </dl>
* @param <R> the result type
* @param convert the function that is called with the current Maybe instance during
* assembly time that should return some value to be the result
*
* @return the value returned by the convert function
*/
public final <R> R to(Function<? super Maybe<T>, R> convert) {
try {
return convert.apply(this);
} catch (Throwable ex) {
Exceptions.throwIfFatal(ex);
throw ExceptionHelper.wrapOrThrow(ex);
}
}
/**
* Converts this Maybe into an Completable instance composing cancellation
* through and dropping a success value if emitted.
* <dl>
* <dt><b>Scheduler:</b></dt>
* <dd>{@code create} does not operate by default on a particular {@link Scheduler}.</dd>
* </dl>
* @return the new Completable instance
*/
public final Completable toCompletable() {
return RxJavaPlugins.onAssembly(new MaybeToCompletable<T>(this));
}
/**
* Converts this Maybe into a backpressure-aware Flowable instance composing cancellation
* through.
* <dl>
* <dt><b>Scheduler:</b></dt>
* <dd>{@code create} does not operate by default on a particular {@link Scheduler}.</dd>
* </dl>
* @return the new Flowable instance
*/
public final Flowable<T> toFlowable() {
return RxJavaPlugins.onAssembly(new MaybeToFlowable<T>(this));
}
/**
* Converts this Maybe into an Observable instance composing cancellation
* through.
* <dl>
* <dt><b>Scheduler:</b></dt>
* <dd>{@code create} does not operate by default on a particular {@link Scheduler}.</dd>
* </dl>
* @return the new Observable instance
*/
public final Observable<T> toObservable() {
return RxJavaPlugins.onAssembly(new MaybeToObservable<T>(this));
}
/**
* Converts this Maybe into an Single instance composing cancellation
* through and turing an empty Maybe into a signal of NoSuchElementException.
* <dl>
* <dt><b>Scheduler:</b></dt>
* <dd>{@code create} does not operate by default on a particular {@link Scheduler}.</dd>
* </dl>
* @return the new Single instance
*/
public final Single<T> toSingle() {
return RxJavaPlugins.onAssembly(new MaybeToSingle<T>(this));
}
@Override
public final void subscribe(MaybeObserver<? super T> observer) {
ObjectHelper.requireNonNull(observer, "observer is null");
observer = RxJavaPlugins.onSubscribe(this, observer);
ObjectHelper.requireNonNull(observer, "observer returned by the RxJavaPlugins hook is null");
try {
subscribeActual(observer);
} catch (NullPointerException ex) {
throw ex;
} catch (Throwable ex) {
Exceptions.throwIfFatal(ex);
NullPointerException npe = new NullPointerException("subscribeActual failed");
npe.initCause(ex);
throw npe;
}
}
/**
* Override this method in subclasses to handle the incoming MaybeObservers.
* @param observer the MaybeObserver to handle, not null
*/
protected abstract void subscribeActual(MaybeObserver<? super T> observer);
/**
* Asynchronously subscribes subscribers to this Maybe on the specified {@link Scheduler}.
* <p>
* <img width="640" height="305" src="https://raw.github.com/wiki/ReactiveX/RxJava/images/rx-operators/Single.subscribeOn.png" alt="">
* <dl>
* <dt><b>Scheduler:</b></dt>
* <dd>you specify which {@link Scheduler} this operator will use</dd>
* </dl>
*
* @param scheduler
* the {@link Scheduler} to perform subscription actions on
* @return the new Maybe instance that its subscriptions happen on the specified {@link Scheduler}
* @see <a href="http://reactivex.io/documentation/operators/subscribeon.html">ReactiveX operators documentation: SubscribeOn</a>
* @see <a href="http://www.grahamlea.com/2014/07/rxjava-threading-examples/">RxJava Threading Examples</a>
* @see #observeOn
*/
public final Maybe<T> subscribeOn(Scheduler scheduler) {
ObjectHelper.requireNonNull(scheduler, "scheduler is null");
return RxJavaPlugins.onAssembly(new MaybeSubscribeOn<T>(this, scheduler));
}
// ------------------------------------------------------------------
// Test helper
// ------------------------------------------------------------------
/**
* Creates a TestSubscriber and subscribes
* it to this Maybe.
* @return the new TestSubscriber instance
*/
public final TestSubscriber<T> test() {
TestSubscriber<T> ts = new TestSubscriber<T>();
toFlowable().subscribe(ts);
return ts;
}
/**
* Creates a TestSubscriber optionally in cancelled state, then subscribes it to this Maybe.
* @param cancelled if true, the TestSubscriber will be cancelled before subscribing to this
* Maybe.
* @return the new TestSubscriber instance
*/
public final TestSubscriber<T> test(boolean cancelled) {
TestSubscriber<T> ts = new TestSubscriber<T>();
if (cancelled) {
ts.cancel();
}
toFlowable().subscribe(ts);
return ts;
}
}