From 000a174d87a901135f9665d3b11f3627fd2dc4ed Mon Sep 17 00:00:00 2001 From: akarnokd Date: Thu, 4 Feb 2016 13:52:42 +0100 Subject: [PATCH] 2.x: full JDK 6 compatible backport + including bugfixes up to today --- build.gradle | 4 +- .../io/reactivex/BackpressureStrategy.java | 2 +- src/main/java/io/reactivex/Completable.java | 2361 +++++++++++ src/main/java/io/reactivex/NbpObservable.java | 1854 ++++++--- src/main/java/io/reactivex/NbpObserver.java | 2 +- src/main/java/io/reactivex/Notification.java | 8 +- src/main/java/io/reactivex/Observable.java | 1702 +++++--- src/main/java/io/reactivex/Observer.java | 2 +- src/main/java/io/reactivex/Optional.java | 80 + src/main/java/io/reactivex/Scheduler.java | 61 +- src/main/java/io/reactivex/Single.java | 2068 +++++----- src/main/java/io/reactivex/Try.java | 10 +- .../annotations/BackpressureKind.java | 2 +- .../annotations/BackpressureSupport.java | 2 +- .../java/io/reactivex/annotations/Beta.java | 2 +- .../reactivex/annotations/Experimental.java | 2 +- .../reactivex/annotations/SchedulerKind.java | 2 +- .../annotations/SchedulerSupport.java | 2 +- .../disposables/BooleanDisposable.java | 27 +- .../disposables/CompositeDisposable.java | 17 +- .../io/reactivex/disposables/Disposable.java | 2 +- .../io/reactivex/disposables/Disposables.java | 90 +- .../MultipleAssignmentDisposable.java | 6 +- .../disposables/RefCountDisposable.java | 42 +- .../disposables/SerialDisposable.java | 6 +- .../exceptions/CompositeException.java | 312 +- .../MissingBackpressureException.java | 2 +- .../exceptions/OnCompleteFailedException.java | 2 +- .../exceptions/OnErrorFailedException.java | 2 +- .../OnErrorNotImplementedException.java | 2 +- .../UnsubscribeFailedException.java | 2 +- .../io/reactivex/functions/BiConsumer.java | 19 + .../io/reactivex/functions/BiFunction.java | 19 + .../io/reactivex/functions/BiPredicate.java | 19 + .../reactivex/functions/BooleanSupplier.java | 18 + .../java/io/reactivex/functions/Consumer.java | 18 + .../java/io/reactivex/functions/Function.java | 18 + .../io/reactivex/functions/Function3.java | 16 +- .../io/reactivex/functions/Function4.java | 16 +- .../io/reactivex/functions/Function5.java | 16 +- .../io/reactivex/functions/Function6.java | 16 +- .../io/reactivex/functions/Function7.java | 16 +- .../io/reactivex/functions/Function8.java | 16 +- .../io/reactivex/functions/Function9.java | 15 +- .../io/reactivex/functions/IntFunction.java | 17 + .../io/reactivex/functions/LongConsumer.java | 17 + .../io/reactivex/functions/Predicate.java | 18 + .../java/io/reactivex/functions/Supplier.java | 19 + .../disposables/ArrayCompositeResource.java | 4 +- .../disposables/CompositeResource.java | 2 +- .../internal/disposables/EmptyDisposable.java | 2 +- .../disposables/ListCompositeResource.java | 21 +- .../MultipleAssignmentResource.java | 4 +- .../internal/disposables/NbpFullArbiter.java | 21 +- .../internal/disposables/SerialResource.java | 5 +- .../disposables/SetCompositeResource.java | 25 +- .../internal/functions/Functions.java | 253 ++ .../reactivex/internal/functions/Objects.java | 94 + .../operators/BlockingOperatorLatest.java | 19 +- .../operators/BlockingOperatorMostRecent.java | 7 +- .../operators/BlockingOperatorNext.java | 22 +- .../internal/operators/CachedObservable.java | 18 +- .../operators/ObservableScalarSource.java | 39 +- .../internal/operators/OperatorAll.java | 6 +- .../internal/operators/OperatorAny.java | 6 +- .../internal/operators/OperatorBuffer.java | 10 +- .../operators/OperatorBufferBoundary.java | 42 +- .../OperatorBufferBoundarySupplier.java | 37 +- .../OperatorBufferExactBoundary.java | 13 +- .../operators/OperatorBufferTimed.java | 89 +- .../internal/operators/OperatorCollect.java | 13 +- .../internal/operators/OperatorConcatMap.java | 21 +- .../internal/operators/OperatorCount.java | 2 +- .../internal/operators/OperatorDebounce.java | 35 +- .../operators/OperatorDebounceTimed.java | 47 +- .../internal/operators/OperatorDelay.java | 45 +- .../operators/OperatorDematerialize.java | 8 +- .../internal/operators/OperatorDistinct.java | 107 +- .../internal/operators/OperatorDoOnEach.java | 16 +- .../internal/operators/OperatorElementAt.java | 4 +- .../internal/operators/OperatorFilter.java | 10 +- .../internal/operators/OperatorFlatMap.java | 109 +- .../internal/operators/OperatorGroupBy.java | 250 +- .../operators/OperatorIgnoreElements.java | 4 +- .../internal/operators/OperatorMap.java | 10 +- .../operators/OperatorMapNotification.java | 25 +- .../operators/OperatorMaterialize.java | 27 +- .../internal/operators/OperatorObserveOn.java | 21 +- .../OperatorOnBackpressureBuffer.java | 23 +- .../operators/OperatorOnBackpressureDrop.java | 9 +- .../OperatorOnBackpressureLatest.java | 37 +- .../operators/OperatorOnErrorNext.java | 17 +- .../operators/OperatorOnErrorReturn.java | 45 +- .../internal/operators/OperatorPublish.java | 68 +- .../internal/operators/OperatorReplay.java | 148 +- .../operators/OperatorSamplePublisher.java | 34 +- .../operators/OperatorSampleTimed.java | 37 +- .../internal/operators/OperatorScan.java | 7 +- .../internal/operators/OperatorScanSeed.java | 9 +- .../internal/operators/OperatorSingle.java | 6 +- .../internal/operators/OperatorSkip.java | 7 +- .../internal/operators/OperatorSkipLast.java | 4 +- .../operators/OperatorSkipLastTimed.java | 19 +- .../internal/operators/OperatorSkipUntil.java | 8 +- .../internal/operators/OperatorSkipWhile.java | 7 +- .../operators/OperatorSwitchIfEmpty.java | 4 +- .../internal/operators/OperatorSwitchMap.java | 50 +- .../internal/operators/OperatorTake.java | 7 +- .../internal/operators/OperatorTakeLast.java | 24 +- .../operators/OperatorTakeLastOne.java | 4 +- .../operators/OperatorTakeLastTimed.java | 67 +- .../internal/operators/OperatorTakeUntil.java | 11 +- .../operators/OperatorTakeUntilPredicate.java | 10 +- .../internal/operators/OperatorTakeWhile.java | 7 +- .../operators/OperatorThrottleFirstTimed.java | 33 +- .../operators/OperatorTimeInterval.java | 8 +- .../internal/operators/OperatorTimeout.java | 64 +- .../operators/OperatorTimeoutTimed.java | 112 +- .../internal/operators/OperatorToList.java | 13 +- .../operators/OperatorUnsubscribeOn.java | 13 +- .../internal/operators/OperatorWindow.java | 17 +- .../operators/OperatorWindowBoundary.java | 43 +- .../OperatorWindowBoundarySelector.java | 63 +- .../OperatorWindowBoundarySupplier.java | 49 +- .../operators/OperatorWindowTimed.java | 92 +- .../operators/OperatorWithLatestFrom.java | 36 +- .../internal/operators/PublisherAmb.java | 48 +- .../operators/PublisherArraySource.java | 30 +- .../operators/PublisherAutoConnect.java | 4 +- .../operators/PublisherCombineLatest.java | 66 +- .../PublisherCompletableFutureSource.java | 46 - .../internal/operators/PublisherDefer.java | 8 +- .../PublisherDelaySubscriptionOther.java | 107 + .../operators/PublisherEmptySource.java | 2 +- .../operators/PublisherErrorSource.java | 8 +- .../operators/PublisherFutureSource.java | 10 +- .../internal/operators/PublisherGenerate.java | 6 +- .../PublisherIntervalOnceSource.java | 12 +- .../PublisherIntervalRangeSource.java | 19 +- .../operators/PublisherIntervalSource.java | 19 +- .../operators/PublisherIterableSource.java | 7 +- .../internal/operators/PublisherLift.java | 2 +- .../operators/PublisherRangeSource.java | 20 +- .../internal/operators/PublisherRedo.java | 29 +- .../internal/operators/PublisherRefCount.java | 56 +- .../internal/operators/PublisherRepeat.java | 4 +- .../operators/PublisherRepeatUntil.java | 6 +- .../operators/PublisherRetryBiPredicate.java | 10 +- .../operators/PublisherRetryPredicate.java | 10 +- .../operators/PublisherScalarAsyncSource.java | 7 +- .../operators/PublisherSequenceEqual.java | 23 +- .../operators/PublisherStreamSource.java | 133 - .../operators/PublisherSubscribeOn.java | 29 +- .../internal/operators/PublisherUsing.java | 19 +- .../internal/operators/PublisherZip.java | 52 +- .../operators/PublisherZipIterable.java | 6 +- .../operators/SubscriberResourceWrapper.java | 19 +- .../CompletableOnSubscribeConcat.java | 166 + .../CompletableOnSubscribeConcatArray.java | 93 + .../CompletableOnSubscribeConcatIterable.java | 133 + .../CompletableOnSubscribeMerge.java | 238 ++ .../CompletableOnSubscribeMergeArray.java | 88 + ...etableOnSubscribeMergeDelayErrorArray.java | 90 + ...bleOnSubscribeMergeDelayErrorIterable.java | 154 + .../CompletableOnSubscribeMergeIterable.java | 144 + .../CompletableOnSubscribeTimeout.java | 110 + .../nbp/NbpBlockingOperatorLatest.java | 19 +- .../nbp/NbpBlockingOperatorMostRecent.java | 7 +- .../nbp/NbpBlockingOperatorNext.java | 22 +- .../operators/nbp/NbpCachedObservable.java | 16 +- .../nbp/NbpObservableScalarSource.java | 53 +- .../operators/nbp/NbpOnSubscribeAmb.java | 37 +- .../nbp/NbpOnSubscribeArraySource.java | 14 +- .../nbp/NbpOnSubscribeAutoConnect.java | 4 +- .../nbp/NbpOnSubscribeCombineLatest.java | 60 +- ...NbpOnSubscribeCompletableFutureSource.java | 48 - .../operators/nbp/NbpOnSubscribeDefer.java | 8 +- .../NbpOnSubscribeDelaySubscriptionOther.java | 96 + .../nbp/NbpOnSubscribeErrorSource.java | 8 +- .../nbp/NbpOnSubscribeFutureSource.java | 10 +- .../operators/nbp/NbpOnSubscribeGenerate.java | 7 +- .../NbpOnSubscribeIntervalRangeSource.java | 21 +- .../nbp/NbpOnSubscribeIntervalSource.java | 21 +- .../nbp/NbpOnSubscribeIterableSource.java | 5 +- .../operators/nbp/NbpOnSubscribeLift.java | 2 +- .../operators/nbp/NbpOnSubscribeRedo.java | 27 +- .../operators/nbp/NbpOnSubscribeRefCount.java | 60 +- .../operators/nbp/NbpOnSubscribeRepeat.java | 4 +- .../nbp/NbpOnSubscribeRepeatUntil.java | 6 +- .../nbp/NbpOnSubscribeRetryBiPredicate.java | 10 +- .../nbp/NbpOnSubscribeRetryPredicate.java | 10 +- .../nbp/NbpOnSubscribeScalarAsyncSource.java | 13 +- .../nbp/NbpOnSubscribeSequenceEqual.java | 21 +- .../nbp/NbpOnSubscribeStreamSource.java | 101 - .../nbp/NbpOnSubscribeSubscribeOn.java | 11 +- .../nbp/NbpOnSubscribeTimerOnceSource.java | 14 +- .../operators/nbp/NbpOnSubscribeUsing.java | 12 +- .../operators/nbp/NbpOnSubscribeZip.java | 40 +- .../nbp/NbpOnSubscribeZipIterable.java | 6 +- .../operators/nbp/NbpOperatorAll.java | 7 +- .../operators/nbp/NbpOperatorAny.java | 7 +- .../operators/nbp/NbpOperatorBuffer.java | 10 +- .../nbp/NbpOperatorBufferBoundary.java | 42 +- .../NbpOperatorBufferBoundarySupplier.java | 37 +- .../nbp/NbpOperatorBufferExactBoundary.java | 13 +- .../operators/nbp/NbpOperatorBufferTimed.java | 89 +- .../operators/nbp/NbpOperatorCollect.java | 14 +- .../operators/nbp/NbpOperatorConcatMap.java | 19 +- .../operators/nbp/NbpOperatorCount.java | 2 +- .../operators/nbp/NbpOperatorDebounce.java | 35 +- .../nbp/NbpOperatorDebounceTimed.java | 47 +- .../operators/nbp/NbpOperatorDelay.java | 45 +- .../nbp/NbpOperatorDematerialize.java | 8 +- .../operators/nbp/NbpOperatorDistinct.java | 107 +- .../operators/nbp/NbpOperatorDoOnEach.java | 10 +- .../operators/nbp/NbpOperatorElementAt.java | 4 +- .../operators/nbp/NbpOperatorFilter.java | 7 +- .../operators/nbp/NbpOperatorFlatMap.java | 85 +- .../operators/nbp/NbpOperatorGroupBy.java | 55 +- .../nbp/NbpOperatorIgnoreElements.java | 4 +- .../operators/nbp/NbpOperatorMap.java | 10 +- .../nbp/NbpOperatorMapNotification.java | 7 +- .../operators/nbp/NbpOperatorMaterialize.java | 6 +- .../operators/nbp/NbpOperatorObserveOn.java | 8 +- .../operators/nbp/NbpOperatorOnErrorNext.java | 17 +- .../nbp/NbpOperatorOnErrorReturn.java | 18 +- .../operators/nbp/NbpOperatorPublish.java | 69 +- .../operators/nbp/NbpOperatorReplay.java | 121 +- .../operators/nbp/NbpOperatorSampleTimed.java | 26 +- .../nbp/NbpOperatorSampleWithObservable.java | 28 +- .../operators/nbp/NbpOperatorScan.java | 7 +- .../operators/nbp/NbpOperatorScanSeed.java | 7 +- .../operators/nbp/NbpOperatorSingle.java | 6 +- .../operators/nbp/NbpOperatorSkip.java | 7 +- .../operators/nbp/NbpOperatorSkipLast.java | 4 +- .../nbp/NbpOperatorSkipLastTimed.java | 8 +- .../operators/nbp/NbpOperatorSkipUntil.java | 10 +- .../operators/nbp/NbpOperatorSkipWhile.java | 7 +- .../nbp/NbpOperatorSwitchIfEmpty.java | 4 +- .../operators/nbp/NbpOperatorSwitchMap.java | 48 +- .../operators/nbp/NbpOperatorTake.java | 7 +- .../operators/nbp/NbpOperatorTakeLast.java | 4 +- .../operators/nbp/NbpOperatorTakeLastOne.java | 4 +- .../nbp/NbpOperatorTakeLastTimed.java | 8 +- .../operators/nbp/NbpOperatorTakeUntil.java | 13 +- .../nbp/NbpOperatorTakeUntilPredicate.java | 10 +- .../operators/nbp/NbpOperatorTakeWhile.java | 7 +- .../nbp/NbpOperatorThrottleFirstTimed.java | 33 +- .../nbp/NbpOperatorTimeInterval.java | 8 +- .../operators/nbp/NbpOperatorTimeout.java | 64 +- .../nbp/NbpOperatorTimeoutTimed.java | 110 +- .../operators/nbp/NbpOperatorToList.java | 13 +- .../nbp/NbpOperatorUnsubscribeOn.java | 13 +- .../operators/nbp/NbpOperatorWindow.java | 17 +- .../nbp/NbpOperatorWindowBoundary.java | 45 +- .../NbpOperatorWindowBoundarySelector.java | 63 +- .../NbpOperatorWindowBoundarySupplier.java | 49 +- .../operators/nbp/NbpOperatorWindowTimed.java | 93 +- .../nbp/NbpOperatorWithLatestFrom.java | 41 +- .../nbp/NbpSubscriberResourceWrapper.java | 22 +- .../single/SingleOperatorFlatMap.java | 7 +- .../operators/single/SingleOperatorMap.java | 7 +- .../internal/queue/BaseArrayQueue.java | 2 +- .../internal/queue/BaseLinkedQueue.java | 8 +- .../internal/queue/LinkedQueueNode.java | 2 +- .../internal/queue/MpscLinkedQueue.java | 9 +- .../internal/queue/SpscArrayQueue.java | 2 +- .../internal/queue/SpscExactArrayQueue.java | 36 +- .../internal/queue/SpscLinkedArrayQueue.java | 41 +- .../schedulers/ComputationScheduler.java | 12 +- .../schedulers/ExecutorScheduler.java | 52 +- .../internal/schedulers/IOScheduler.java | 21 +- .../schedulers/NewThreadScheduler.java | 2 +- .../internal/schedulers/NewThreadWorker.java | 28 +- .../internal/schedulers/RxThreadFactory.java | 7 +- .../schedulers/ScheduledRunnable.java | 4 +- .../schedulers/SchedulerLifecycle.java | 2 +- .../schedulers/SchedulerPoolFactory.java | 128 + .../internal/schedulers/SingleScheduler.java | 38 +- .../schedulers/TrampolineScheduler.java | 23 +- .../subscribers/BlockingSubscriber.java | 5 +- .../subscribers/CancelledSubscriber.java | 2 +- .../subscribers/ConditionalSubscriber.java | 2 +- .../subscribers/DisposableSubscriber.java | 25 +- .../internal/subscribers/EmptySubscriber.java | 2 +- .../subscribers/FullArbiterSubscriber.java | 2 +- .../subscribers/LambdaSubscriber.java | 6 +- .../subscribers/NbpFullArbiterSubscriber.java | 2 +- .../subscribers/QueueDrainSubscriber.java | 48 +- .../SubscriptionLambdaSubscriber.java | 5 +- .../subscribers/ToNotificationSubscriber.java | 10 +- .../nbp/NbpBlockingSubscriber.java | 9 +- .../nbp/NbpCancelledSubscriber.java | 2 +- .../nbp/NbpConditionalSubscriber.java | 2 +- .../nbp/NbpDisposableSubscriber.java | 22 +- .../subscribers/nbp/NbpEmptySubscriber.java | 2 +- .../subscribers/nbp/NbpLambdaSubscriber.java | 11 +- .../nbp/NbpQueueDrainSubscriber.java | 28 +- .../nbp/NbpSubscriptionLambdaSubscriber.java | 5 +- .../nbp/NbpToNotificationSubscriber.java | 10 +- .../subscriptions/AsyncSubscription.java | 40 +- .../subscriptions/BooleanSubscription.java | 2 +- .../subscriptions/DisposableSubscription.java | 108 + .../subscriptions/EmptySubscription.java | 2 +- .../internal/subscriptions/FullArbiter.java | 27 +- .../ScalarAsyncSubscription.java | 9 +- .../subscriptions/ScalarSubscription.java | 5 +- .../subscriptions/SubscriptionArbiter.java | 135 +- .../subscriptions/SubscriptionHelper.java | 77 +- .../util/AppendOnlyLinkedArrayList.java | 4 +- .../internal/util/BackpressureHelper.java | 23 +- .../reactivex/internal/util/Exceptions.java | 2 +- .../internal/util/LinkedArrayList.java | 14 +- .../internal/util/NbpQueueDrain.java | 85 +- .../internal/util/NotificationLite.java | 15 +- .../reactivex/internal/util/OpenHashSet.java | 8 +- .../java/io/reactivex/internal/util/Pow2.java | 2 +- .../reactivex/internal/util/QueueDrain.java | 146 +- .../internal/util/QueueDrainHelper.java | 329 +- .../internal/util/TerminalAtomicsHelper.java | 184 +- .../observables/BlockingObservable.java | 342 +- .../observables/ConnectableObservable.java | 23 +- .../observables/GroupedObservable.java | 2 +- .../nbp/NbpBlockingObservable.java | 330 +- .../nbp/NbpConnectableObservable.java | 23 +- .../observables/nbp/NbpGroupedObservable.java | 2 +- .../io/reactivex/plugins/RxJavaPlugins.java | 50 +- .../io/reactivex/schedulers/Schedulers.java | 6 +- .../reactivex/schedulers/TestScheduler.java | 23 +- .../java/io/reactivex/schedulers/Timed.java | 7 +- .../io/reactivex/subjects/AsyncSubject.java | 32 +- .../reactivex/subjects/BehaviorSubject.java | 92 +- .../io/reactivex/subjects/PublishSubject.java | 46 +- .../io/reactivex/subjects/ReplaySubject.java | 95 +- .../reactivex/subjects/SerializedSubject.java | 31 +- .../java/io/reactivex/subjects/Subject.java | 6 +- .../io/reactivex/subjects/UnicastSubject.java | 55 +- .../subjects/nbp/NbpAsyncSubject.java | 52 +- .../subjects/nbp/NbpBehaviorSubject.java | 92 +- .../subjects/nbp/NbpPublishSubject.java | 55 +- .../subjects/nbp/NbpReplaySubject.java | 59 +- .../subjects/nbp/NbpSerializedSubject.java | 27 +- .../io/reactivex/subjects/nbp/NbpSubject.java | 4 +- .../subjects/nbp/NbpUnicastSubject.java | 50 +- .../reactivex/subscribers/AsyncObserver.java | 41 +- .../io/reactivex/subscribers/Observers.java | 62 +- .../reactivex/subscribers/SafeSubscriber.java | 44 +- .../subscribers/SerializedSubscriber.java | 18 +- .../io/reactivex/subscribers/Subscribers.java | 70 +- .../reactivex/subscribers/TestSubscriber.java | 106 +- .../CompletableSerializedSubscriber.java | 50 + .../subscribers/nbp/NbpAsyncObserver.java | 31 +- .../subscribers/nbp/NbpObservers.java | 63 +- .../subscribers/nbp/NbpSafeSubscriber.java | 43 +- .../nbp/NbpSerializedSubscriber.java | 21 +- .../subscribers/nbp/NbpSubscribers.java | 63 +- .../subscribers/nbp/NbpTestSubscriber.java | 90 +- .../io/reactivex/EachTypeFlatMapPerf.java | 58 +- .../InputWithIncrementingInteger.java | 7 +- .../java/io/reactivex/LatchedNbpObserver.java | 2 +- .../java/io/reactivex/LatchedObserver.java | 4 +- .../io/reactivex/LatchedSingleObserver.java | 2 +- .../io/reactivex/OperatorFlatMapPerf.java | 29 +- .../java/io/reactivex/OperatorMergePerf.java | 39 +- src/perf/java/io/reactivex/RangePerf.java | 13 +- .../java/io/reactivex/RxVsStreamPerf.java | 75 +- .../java/io/reactivex/BackpressureTests.java | 149 +- .../java/io/reactivex/CombineLatestTests.java | 34 +- .../java/io/reactivex/CompletableTest.java | 3593 +++++++++++++++++ src/test/java/io/reactivex/ConcatTests.java | 18 +- .../java/io/reactivex/CovarianceTest.java | 155 +- .../java/io/reactivex/ErrorHandlingTests.java | 10 +- src/test/java/io/reactivex/EventStream.java | 27 +- src/test/java/io/reactivex/GroupByTests.java | 50 +- src/test/java/io/reactivex/MergeTests.java | 18 +- .../io/reactivex/NbpObservableNullTests.java | 2786 +++++++++++++ .../java/io/reactivex/NbpObservableTest.java | 12 +- .../java/io/reactivex/NotificationTest.java | 4 +- .../reactivex/ObservableConversionTest.java | 107 +- .../java/io/reactivex/ObservableDoOnTest.java | 30 +- .../io/reactivex/ObservableNullTests.java | 2876 +++++++++++++ .../java/io/reactivex/ObservableTests.java | 349 +- .../io/reactivex/ObservableWindowTests.java | 21 +- src/test/java/io/reactivex/ReduceTests.java | 41 +- src/test/java/io/reactivex/ScanTests.java | 21 +- .../java/io/reactivex/SingleNullTests.java | 843 ++++ src/test/java/io/reactivex/SingleTest.java | 292 +- .../java/io/reactivex/StartWithTests.java | 8 +- .../java/io/reactivex/SubscriberTest.java | 266 +- src/test/java/io/reactivex/TestHelper.java | 18 +- .../java/io/reactivex/ThrottleLastTests.java | 2 +- .../reactivex/ThrottleWithTimeoutTests.java | 4 +- src/test/java/io/reactivex/ZipTests.java | 71 +- .../disposables/CompositeDisposableTest.java | 6 +- .../disposables/DisposablesTest.java | 2 +- .../MultipleAssignmentDisposableTest.java | 2 +- .../disposables/RefCountDisposableTest.java | 10 +- .../disposables/SerialDisposableTests.java | 8 +- .../reactivex/exceptions/TestException.java | 2 +- .../operators/BackpressureHelperTest.java | 2 +- .../operators/BlockingOperatorLatestTest.java | 2 +- .../BlockingOperatorMostRecentTest.java | 4 +- .../operators/BlockingOperatorNextTest.java | 3 +- .../BlockingOperatorToIteratorTest.java | 2 +- .../operators/BufferUntilSubscriberTest.java | 42 +- .../operators/CachedObservableTest.java | 55 +- .../operators/NotificationLiteTest.java | 2 +- .../operators/OnSubscribeAmbTest.java | 92 +- .../OnSubscribeCombineLatestTest.java | 104 +- .../operators/OnSubscribeDeferTest.java | 5 +- .../OnSubscribeFromIterableTest.java | 12 +- .../operators/OnSubscribeRangeTest.java | 34 +- .../operators/OnSubscribeRefCountTest.java | 276 +- .../operators/OnSubscribeTimerTest.java | 18 +- .../OnSubscribeToObservableFutureTest.java | 10 +- .../operators/OnSubscribeUsingTest.java | 135 +- .../internal/operators/OperatorAllTest.java | 90 +- .../internal/operators/OperatorAnyTest.java | 95 +- .../operators/OperatorAsObservableTest.java | 2 +- .../operators/OperatorBufferTest.java | 48 +- .../internal/operators/OperatorCastTest.java | 2 +- .../operators/OperatorConcatTest.java | 78 +- .../operators/OperatorDebounceTest.java | 6 +- .../operators/OperatorDefaultIfEmptyTest.java | 8 +- .../internal/operators/OperatorDelayTest.java | 103 +- .../operators/OperatorDematerializeTest.java | 6 +- .../operators/OperatorDistinctTest.java | 5 +- .../OperatorDistinctUntilChangedTest.java | 7 +- .../operators/OperatorDoOnEachTest.java | 4 +- .../operators/OperatorDoOnRequestTest.java | 6 +- .../operators/OperatorDoOnSubscribeTest.java | 40 +- .../OperatorDoOnUnsubscribeTest.java | 79 +- .../operators/OperatorElementAtTest.java | 2 +- .../operators/OperatorFilterTest.java | 7 +- .../operators/OperatorFinallyTest.java | 2 +- .../internal/operators/OperatorFirstTest.java | 46 +- .../operators/OperatorFlatMapTest.java | 57 +- .../operators/OperatorGroupByTest.java | 204 +- .../operators/OperatorIgnoreElementsTest.java | 8 +- .../internal/operators/OperatorLastTest.java | 4 +- .../OperatorMapNotificationTest.java | 7 +- .../internal/operators/OperatorMapTest.java | 13 +- .../operators/OperatorMaterializeTest.java | 23 +- .../OperatorMergeDelayErrorTest.java | 24 +- .../OperatorMergeMaxConcurrentTest.java | 50 +- .../internal/operators/OperatorMergeTest.java | 103 +- .../operators/OperatorMulticastTest.java | 2 +- .../operators/OperatorObserveOnTest.java | 23 +- .../OperatorOnBackpressureBufferTest.java | 8 +- .../OperatorOnBackpressureDropTest.java | 8 +- .../OperatorOnBackpressureLatestTest.java | 10 +- ...ratorOnErrorResumeNextViaFunctionTest.java | 18 +- ...torOnErrorResumeNextViaObservableTest.java | 9 +- .../operators/OperatorOnErrorReturnTest.java | 12 +- ...nExceptionResumeNextViaObservableTest.java | 15 +- .../operators/OperatorPublishTest.java | 34 +- .../operators/OperatorReduceTest.java | 26 +- .../operators/OperatorRepeatTest.java | 10 +- .../operators/OperatorReplayTest.java | 182 +- .../internal/operators/OperatorRetryTest.java | 93 +- .../OperatorRetryWithPredicateTest.java | 24 +- .../operators/OperatorSampleTest.java | 2 +- .../internal/operators/OperatorScanTest.java | 32 +- .../operators/OperatorSequenceEqualTest.java | 5 +- .../operators/OperatorSerializeTest.java | 2 +- .../operators/OperatorSingleTest.java | 40 +- .../operators/OperatorSkipLastTest.java | 4 +- .../operators/OperatorSkipLastTimedTest.java | 2 +- .../internal/operators/OperatorSkipTest.java | 9 +- .../operators/OperatorSkipTimedTest.java | 2 +- .../operators/OperatorSkipUntilTest.java | 2 +- .../operators/OperatorSkipWhileTest.java | 5 +- .../operators/OperatorSubscribeOnTest.java | 14 +- .../operators/OperatorSwitchIfEmptyTest.java | 25 +- .../operators/OperatorSwitchTest.java | 28 +- .../operators/OperatorTakeLastOneTest.java | 16 +- .../operators/OperatorTakeLastTest.java | 23 +- .../operators/OperatorTakeLastTimedTest.java | 41 +- .../internal/operators/OperatorTakeTest.java | 27 +- .../operators/OperatorTakeTimedTest.java | 2 +- .../OperatorTakeUntilPredicateTest.java | 71 +- .../operators/OperatorTakeUntilTest.java | 10 +- .../operators/OperatorTakeWhileTest.java | 11 +- .../operators/OperatorThrottleFirstTest.java | 2 +- .../operators/OperatorTimeIntervalTest.java | 8 +- .../operators/OperatorTimeoutTests.java | 30 +- .../OperatorTimeoutWithSelectorTest.java | 59 +- .../operators/OperatorTimestampTest.java | 14 +- .../internal/operators/OperatorToMapTest.java | 30 +- .../operators/OperatorToMultimapTest.java | 111 +- .../OperatorToObservableListTest.java | 8 +- .../OperatorToObservableSortedListTest.java | 8 +- .../operators/OperatorUnsubscribeOnTest.java | 10 +- .../OperatorWindowWithObservableTest.java | 30 +- .../operators/OperatorWindowWithSizeTest.java | 38 +- ...ratorWindowWithStartEndObservableTest.java | 26 +- .../operators/OperatorWindowWithTimeTest.java | 55 +- .../operators/OperatorWithLatestFromTest.java | 21 +- .../operators/OperatorZipCompletionTest.java | 5 +- .../operators/OperatorZipIterableTest.java | 12 +- .../internal/operators/OperatorZipTest.java | 45 +- .../PublisherDelaySubscriptionOtherTest.java | 243 ++ .../nbp/NbpBlockingOperatorLatestTest.java | 2 +- .../NbpBlockingOperatorMostRecentTest.java | 2 +- .../nbp/NbpBlockingOperatorNextTest.java | 3 +- .../NbpBlockingOperatorToIteratorTest.java | 2 +- .../nbp/NbpBufferUntilSubscriberTest.java | 41 +- .../nbp/NbpCachedObservableTest.java | 53 +- .../operators/nbp/NbpOnSubscribeAmbTest.java | 82 +- .../nbp/NbpOnSubscribeCombineLatestTest.java | 99 +- .../nbp/NbpOnSubscribeDeferTest.java | 5 +- ...OnSubscribeDelaySubscriptionOtherTest.java | 193 + .../nbp/NbpOnSubscribeFromIterableTest.java | 6 +- .../nbp/NbpOnSubscribeRangeTest.java | 16 +- .../nbp/NbpOnSubscribeRefCountTest.java | 268 +- .../nbp/NbpOnSubscribeTimerTest.java | 18 +- .../NbpOnSubscribeToObservableFutureTest.java | 10 +- .../nbp/NbpOnSubscribeUsingTest.java | 135 +- .../operators/nbp/NbpOperatorAllTest.java | 70 +- .../operators/nbp/NbpOperatorAnyTest.java | 75 +- .../nbp/NbpOperatorAsObservableTest.java | 2 +- .../operators/nbp/NbpOperatorBufferTest.java | 36 +- .../operators/nbp/NbpOperatorCastTest.java | 2 +- .../operators/nbp/NbpOperatorConcatTest.java | 81 +- .../nbp/NbpOperatorDebounceTest.java | 6 +- .../nbp/NbpOperatorDefaultIfEmptyTest.java | 4 +- .../operators/nbp/NbpOperatorDelayTest.java | 104 +- .../nbp/NbpOperatorDematerializeTest.java | 6 +- .../nbp/NbpOperatorDistinctTest.java | 5 +- .../NbpOperatorDistinctUntilChangedTest.java | 5 +- .../nbp/NbpOperatorDoOnEachTest.java | 4 +- .../nbp/NbpOperatorDoOnSubscribeTest.java | 41 +- .../nbp/NbpOperatorDoOnUnsubscribeTest.java | 79 +- .../nbp/NbpOperatorElementAtTest.java | 2 +- .../operators/nbp/NbpOperatorFilterTest.java | 5 +- .../operators/nbp/NbpOperatorFinallyTest.java | 2 +- .../operators/nbp/NbpOperatorFirstTest.java | 46 +- .../operators/nbp/NbpOperatorFlatMapTest.java | 54 +- .../operators/nbp/NbpOperatorGroupByTest.java | 91 +- .../nbp/NbpOperatorIgnoreElementsTest.java | 8 +- .../operators/nbp/NbpOperatorLastTest.java | 4 +- .../nbp/NbpOperatorMapNotificationTest.java | 7 +- .../operators/nbp/NbpOperatorMapTest.java | 13 +- .../nbp/NbpOperatorMaterializeTest.java | 9 +- .../nbp/NbpOperatorMergeDelayErrorTest.java | 12 +- .../NbpOperatorMergeMaxConcurrentTest.java | 50 +- .../operators/nbp/NbpOperatorMergeTest.java | 96 +- .../nbp/NbpOperatorMulticastTest.java | 2 +- .../nbp/NbpOperatorObserveOnTest.java | 12 +- ...ratorOnErrorResumeNextViaFunctionTest.java | 18 +- ...torOnErrorResumeNextViaObservableTest.java | 9 +- .../nbp/NbpOperatorOnErrorReturnTest.java | 12 +- ...nExceptionResumeNextViaObservableTest.java | 16 +- .../operators/nbp/NbpOperatorPublishTest.java | 36 +- .../operators/nbp/NbpOperatorReduceTest.java | 26 +- .../operators/nbp/NbpOperatorRepeatTest.java | 10 +- .../operators/nbp/NbpOperatorReplayTest.java | 46 +- .../operators/nbp/NbpOperatorRetryTest.java | 86 +- .../NbpOperatorRetryWithPredicateTest.java | 14 +- .../operators/nbp/NbpOperatorSampleTest.java | 2 +- .../operators/nbp/NbpOperatorScanTest.java | 12 +- .../nbp/NbpOperatorSequenceEqualTest.java | 5 +- .../nbp/NbpOperatorSerializeTest.java | 2 +- .../operators/nbp/NbpOperatorSingleTest.java | 32 +- .../nbp/NbpOperatorSkipLastTest.java | 4 +- .../nbp/NbpOperatorSkipLastTimedTest.java | 2 +- .../operators/nbp/NbpOperatorSkipTest.java | 4 +- .../nbp/NbpOperatorSkipTimedTest.java | 2 +- .../nbp/NbpOperatorSkipUntilTest.java | 2 +- .../nbp/NbpOperatorSkipWhileTest.java | 5 +- .../nbp/NbpOperatorSubscribeOnTest.java | 10 +- .../nbp/NbpOperatorSwitchIfEmptyTest.java | 16 +- .../operators/nbp/NbpOperatorSwitchTest.java | 4 +- .../nbp/NbpOperatorTakeLastOneTest.java | 10 +- .../nbp/NbpOperatorTakeLastTest.java | 15 +- .../nbp/NbpOperatorTakeLastTimedTest.java | 2 +- .../operators/nbp/NbpOperatorTakeTest.java | 21 +- .../nbp/NbpOperatorTakeTimedTest.java | 2 +- .../NbpOperatorTakeUntilPredicateTest.java | 62 +- .../nbp/NbpOperatorTakeUntilTest.java | 8 +- .../nbp/NbpOperatorTakeWhileTest.java | 9 +- .../nbp/NbpOperatorThrottleFirstTest.java | 2 +- .../nbp/NbpOperatorTimeIntervalTest.java | 8 +- .../nbp/NbpOperatorTimeoutTests.java | 30 +- .../NbpOperatorTimeoutWithSelectorTest.java | 59 +- .../nbp/NbpOperatorTimestampTest.java | 14 +- .../operators/nbp/NbpOperatorToMapTest.java | 30 +- .../nbp/NbpOperatorToMultimapTest.java | 111 +- .../nbp/NbpOperatorToObservableListTest.java | 2 +- ...NbpOperatorToObservableSortedListTest.java | 2 +- .../nbp/NbpOperatorUnsubscribeOnTest.java | 10 +- .../NbpOperatorWindowWithObservableTest.java | 22 +- .../nbp/NbpOperatorWindowWithSizeTest.java | 20 +- ...ratorWindowWithStartEndObservableTest.java | 20 +- .../nbp/NbpOperatorWindowWithTimeTest.java | 45 +- .../nbp/NbpOperatorWithLatestFromTest.java | 19 +- .../nbp/NbpOperatorZipCompletionTest.java | 5 +- .../nbp/NbpOperatorZipIterableTest.java | 12 +- .../operators/nbp/NbpOperatorZipTest.java | 33 +- .../subscriptions/AsyncSubscriptionTest.java | 8 +- .../reactivex/nbp/NbpCombineLatestTests.java | 33 +- .../java/io/reactivex/nbp/NbpConcatTests.java | 17 +- .../io/reactivex/nbp/NbpCovarianceTest.java | 152 +- .../reactivex/nbp/NbpErrorHandlingTests.java | 8 +- .../java/io/reactivex/nbp/NbpEventStream.java | 25 +- .../io/reactivex/nbp/NbpGroupByTests.java | 47 +- .../java/io/reactivex/nbp/NbpMergeTests.java | 16 +- .../reactivex/nbp/NbpObservableDoOnTest.java | 28 +- .../io/reactivex/nbp/NbpObservableTest.java | 10 +- .../io/reactivex/nbp/NbpObservableTests.java | 347 +- .../nbp/NbpObservableWindowTests.java | 19 +- .../java/io/reactivex/nbp/NbpReduceTests.java | 40 +- .../java/io/reactivex/nbp/NbpScanTests.java | 21 +- .../io/reactivex/nbp/NbpStartWithTests.java | 6 +- .../io/reactivex/nbp/NbpSubscriberTest.java | 2 +- .../reactivex/nbp/NbpThrottleLastTests.java | 4 +- .../nbp/NbpThrottleWithTimeoutTests.java | 4 +- .../java/io/reactivex/nbp/NbpZipTests.java | 69 +- .../AbstractSchedulerConcurrencyTests.java | 5 +- .../schedulers/AbstractSchedulerTests.java | 16 +- .../schedulers/CachedThreadSchedulerTest.java | 8 +- .../schedulers/ComputationSchedulerTests.java | 9 +- .../schedulers/ExecutorSchedulerTest.java | 26 +- .../schedulers/NewThreadSchedulerTest.java | 5 +- .../schedulers/SchedulerLifecycleTest.java | 9 +- .../reactivex/schedulers/SchedulerTests.java | 4 +- .../schedulers/TestSchedulerTest.java | 7 +- .../schedulers/TrampolineSchedulerTest.java | 29 +- .../reactivex/subjects/AsyncSubjectTest.java | 15 +- .../subjects/BehaviorSubjectTest.java | 11 +- .../subjects/PublishSubjectTest.java | 19 +- .../ReplaySubjectBoundedConcurrencyTest.java | 23 +- .../ReplaySubjectConcurrencyTest.java | 21 +- .../reactivex/subjects/ReplaySubjectTest.java | 102 +- .../subjects/SerializedSubjectTest.java | 6 +- .../subjects/nbp/NbpAsyncSubjectTest.java | 17 +- .../subjects/nbp/NbpBehaviorSubjectTest.java | 11 +- .../subjects/nbp/NbpPublishSubjectTest.java | 17 +- ...bpReplaySubjectBoundedConcurrencyTest.java | 22 +- .../nbp/NbpReplaySubjectConcurrencyTest.java | 20 +- .../subjects/nbp/NbpReplaySubjectTest.java | 15 +- .../nbp/NbpSerializedSubjectTest.java | 6 +- .../reactivex/subscribers/ObserversTest.java | 49 +- .../subscribers/SafeObserverTest.java | 33 +- .../subscribers/SafeSubscriberTest.java | 10 +- .../SafeSubscriberWithPluginTest.java | 44 +- .../subscribers/SerializedObserverTest.java | 59 +- .../subscribers/SubscribersTest.java | 94 +- .../subscribers/TestObserverTest.java | 36 +- .../subscribers/TestSubscriberTest.java | 121 +- 650 files changed, 30213 insertions(+), 10166 deletions(-) create mode 100644 src/main/java/io/reactivex/Completable.java create mode 100644 src/main/java/io/reactivex/Optional.java create mode 100644 src/main/java/io/reactivex/functions/BiConsumer.java create mode 100644 src/main/java/io/reactivex/functions/BiFunction.java create mode 100644 src/main/java/io/reactivex/functions/BiPredicate.java create mode 100644 src/main/java/io/reactivex/functions/BooleanSupplier.java create mode 100644 src/main/java/io/reactivex/functions/Consumer.java create mode 100644 src/main/java/io/reactivex/functions/Function.java create mode 100644 src/main/java/io/reactivex/functions/IntFunction.java create mode 100644 src/main/java/io/reactivex/functions/LongConsumer.java create mode 100644 src/main/java/io/reactivex/functions/Predicate.java create mode 100644 src/main/java/io/reactivex/functions/Supplier.java create mode 100644 src/main/java/io/reactivex/internal/functions/Functions.java create mode 100644 src/main/java/io/reactivex/internal/functions/Objects.java delete mode 100644 src/main/java/io/reactivex/internal/operators/PublisherCompletableFutureSource.java create mode 100644 src/main/java/io/reactivex/internal/operators/PublisherDelaySubscriptionOther.java delete mode 100644 src/main/java/io/reactivex/internal/operators/PublisherStreamSource.java create mode 100644 src/main/java/io/reactivex/internal/operators/completable/CompletableOnSubscribeConcat.java create mode 100644 src/main/java/io/reactivex/internal/operators/completable/CompletableOnSubscribeConcatArray.java create mode 100644 src/main/java/io/reactivex/internal/operators/completable/CompletableOnSubscribeConcatIterable.java create mode 100644 src/main/java/io/reactivex/internal/operators/completable/CompletableOnSubscribeMerge.java create mode 100644 src/main/java/io/reactivex/internal/operators/completable/CompletableOnSubscribeMergeArray.java create mode 100644 src/main/java/io/reactivex/internal/operators/completable/CompletableOnSubscribeMergeDelayErrorArray.java create mode 100644 src/main/java/io/reactivex/internal/operators/completable/CompletableOnSubscribeMergeDelayErrorIterable.java create mode 100644 src/main/java/io/reactivex/internal/operators/completable/CompletableOnSubscribeMergeIterable.java create mode 100644 src/main/java/io/reactivex/internal/operators/completable/CompletableOnSubscribeTimeout.java delete mode 100644 src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeCompletableFutureSource.java create mode 100644 src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeDelaySubscriptionOther.java delete mode 100644 src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeStreamSource.java create mode 100644 src/main/java/io/reactivex/internal/schedulers/SchedulerPoolFactory.java create mode 100644 src/main/java/io/reactivex/internal/subscriptions/DisposableSubscription.java create mode 100644 src/main/java/io/reactivex/subscribers/completable/CompletableSerializedSubscriber.java create mode 100644 src/test/java/io/reactivex/CompletableTest.java create mode 100644 src/test/java/io/reactivex/NbpObservableNullTests.java create mode 100644 src/test/java/io/reactivex/ObservableNullTests.java create mode 100644 src/test/java/io/reactivex/SingleNullTests.java create mode 100644 src/test/java/io/reactivex/internal/operators/PublisherDelaySubscriptionOtherTest.java create mode 100644 src/test/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeDelaySubscriptionOtherTest.java diff --git a/build.gradle b/build.gradle index 9b9f91ab80..715971e5fe 100644 --- a/build.gradle +++ b/build.gradle @@ -8,8 +8,8 @@ description = 'RxJava: Reactive Extensions for the JVM – a library for composi apply plugin: 'rxjava-project' apply plugin: 'java' -sourceCompatibility = JavaVersion.VERSION_1_8 -targetCompatibility = JavaVersion.VERSION_1_8 +sourceCompatibility = JavaVersion.VERSION_1_6 +targetCompatibility = JavaVersion.VERSION_1_6 dependencies { compile 'org.reactivestreams:reactive-streams:1.0.0' diff --git a/src/main/java/io/reactivex/BackpressureStrategy.java b/src/main/java/io/reactivex/BackpressureStrategy.java index 6aab0f679f..b6a27ed739 100644 --- a/src/main/java/io/reactivex/BackpressureStrategy.java +++ b/src/main/java/io/reactivex/BackpressureStrategy.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 diff --git a/src/main/java/io/reactivex/Completable.java b/src/main/java/io/reactivex/Completable.java new file mode 100644 index 0000000000..f769188ae9 --- /dev/null +++ b/src/main/java/io/reactivex/Completable.java @@ -0,0 +1,2361 @@ +/** + * 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.Iterator; +import java.util.concurrent.*; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.reactivestreams.*; + +import io.reactivex.NbpObservable.*; +import io.reactivex.Single.*; +import io.reactivex.annotations.*; +import io.reactivex.disposables.*; +import io.reactivex.exceptions.CompositeException; +import io.reactivex.functions.*; +import io.reactivex.internal.disposables.*; +import io.reactivex.internal.functions.*; +import io.reactivex.internal.operators.completable.*; +import io.reactivex.internal.subscriptions.DisposableSubscription; +import io.reactivex.internal.util.Exceptions; +import io.reactivex.plugins.RxJavaPlugins; +import io.reactivex.schedulers.Schedulers; + +/** + * Represents a deferred computation without any value but only indication for completion or exception. + * + * The class follows a similar event pattern as Reactive-Streams: onSubscribe (onError|onComplete)? + */ +public class Completable { + /** + * Callback used for building deferred computations that takes a CompletableSubscriber. + */ + public interface CompletableOnSubscribe extends Consumer { + + } + + /** + * Convenience interface and callback used by the lift operator that given a child CompletableSubscriber, + * return a parent CompletableSubscriber that does any kind of lifecycle-related transformations. + */ + public interface CompletableOperator extends Function { + + } + + /** + * Represents the subscription API callbacks when subscribing to a Completable instance. + */ + public interface CompletableSubscriber { + /** + * Called once the deferred computation completes normally. + */ + void onComplete(); + + /** + * Called once if the deferred computation 'throws' an exception. + * @param e the exception, not null. + */ + void onError(Throwable e); + + /** + * Called once by the Completable to set a Disposable on this instance which + * then can be used to cancel the subscription at any time. + * @param d the Disposable instance to call dispose on for cancellation, not null + */ + void onSubscribe(Disposable d); + } + + /** + * Convenience interface and callback used by the compose operator to turn a Completable into another + * Completable fluently. + */ + public interface CompletableTransformer extends Function { + + } + + /** Single instance of a complete Completable. */ + static final Completable COMPLETE = create(new CompletableOnSubscribe() { + @Override + public void accept(CompletableSubscriber s) { + s.onSubscribe(EmptyDisposable.INSTANCE); + s.onComplete(); + } + }); + + /** Single instance of a never Completable. */ + static final Completable NEVER = create(new CompletableOnSubscribe() { + @Override + public void accept(CompletableSubscriber s) { + s.onSubscribe(EmptyDisposable.INSTANCE); + } + }); + + /** + * Returns a Completable which terminates as soon as one of the source Completables + * terminates (normally or with an error) and cancels all other Completables. + * @param sources the array of source Completables + * @return the new Completable instance + * @throws NullPointerException if sources is null + */ + @SchedulerSupport(SchedulerKind.NONE) + public static Completable amb(final Completable... sources) { + Objects.requireNonNull(sources, "sources is null"); + if (sources.length == 0) { + return complete(); + } + if (sources.length == 1) { + return sources[0]; + } + + return create(new CompletableOnSubscribe() { + @Override + public void accept(final CompletableSubscriber s) { + final CompositeDisposable set = new CompositeDisposable(); + s.onSubscribe(set); + + final AtomicBoolean once = new AtomicBoolean(); + + CompletableSubscriber inner = new CompletableSubscriber() { + @Override + public void onComplete() { + if (once.compareAndSet(false, true)) { + set.dispose(); + s.onComplete(); + } + } + + @Override + public void onError(Throwable e) { + if (once.compareAndSet(false, true)) { + set.dispose(); + s.onError(e); + } else { + RxJavaPlugins.onError(e); + } + } + + @Override + public void onSubscribe(Disposable d) { + set.add(d); + } + + }; + + for (Completable c : sources) { + if (set.isDisposed()) { + return; + } + if (c == null) { + NullPointerException npe = new NullPointerException("One of the sources is null"); + if (once.compareAndSet(false, true)) { + set.dispose(); + s.onError(npe); + } else { + RxJavaPlugins.onError(npe); + } + return; + } + if (once.get() || set.isDisposed()) { + return; + } + + // no need to have separate subscribers because inner is stateless + c.subscribe(inner); + } + } + }); + } + + /** + * Returns a Completable which terminates as soon as one of the source Completables + * terminates (normally or with an error) and cancels all other Completables. + * @param sources the array of source Completables + * @return the new Completable instance + * @throws NullPointerException if sources is null + */ + @SchedulerSupport(SchedulerKind.NONE) + public static Completable amb(final Iterable sources) { + Objects.requireNonNull(sources, "sources is null"); + + return create(new CompletableOnSubscribe() { + @Override + public void accept(final CompletableSubscriber s) { + final CompositeDisposable set = new CompositeDisposable(); + s.onSubscribe(set); + + final AtomicBoolean once = new AtomicBoolean(); + + CompletableSubscriber inner = new CompletableSubscriber() { + @Override + public void onComplete() { + if (once.compareAndSet(false, true)) { + set.dispose(); + s.onComplete(); + } + } + + @Override + public void onError(Throwable e) { + if (once.compareAndSet(false, true)) { + set.dispose(); + s.onError(e); + } else { + RxJavaPlugins.onError(e); + } + } + + @Override + public void onSubscribe(Disposable d) { + set.add(d); + } + + }; + + Iterator it; + + try { + it = sources.iterator(); + } catch (Throwable e) { + s.onError(e); + return; + } + + if (it == null) { + s.onError(new NullPointerException("The iterator returned is null")); + return; + } + + boolean empty = true; + + for (;;) { + if (once.get() || set.isDisposed()) { + return; + } + + boolean b; + + try { + b = it.hasNext(); + } catch (Throwable e) { + if (once.compareAndSet(false, true)) { + set.dispose(); + s.onError(e); + } else { + RxJavaPlugins.onError(e); + } + return; + } + + if (!b) { + if (empty) { + s.onComplete(); + } + break; + } + + empty = false; + + if (once.get() || set.isDisposed()) { + return; + } + + Completable c; + + try { + c = it.next(); + } catch (Throwable e) { + if (once.compareAndSet(false, true)) { + set.dispose(); + s.onError(e); + } else { + RxJavaPlugins.onError(e); + } + return; + } + + if (c == null) { + NullPointerException npe = new NullPointerException("One of the sources is null"); + if (once.compareAndSet(false, true)) { + set.dispose(); + s.onError(npe); + } else { + RxJavaPlugins.onError(npe); + } + return; + } + + if (once.get() || set.isDisposed()) { + return; + } + + // no need to have separate subscribers because inner is stateless + c.subscribe(inner); + } + } + }); + } + + /** + * Returns a Completable instance that completes immediately when subscribed to. + * @return a Completable instance that completes immediately + */ + @SchedulerSupport(SchedulerKind.NONE) + public static Completable complete() { + return COMPLETE; + } + + /** + * Returns a Completable which completes only when all sources complete, one after another. + * @param sources the sources to concatenate + * @return the Completable instance which completes only when all sources complete + * @throws NullPointerException if sources is null + */ + @SchedulerSupport(SchedulerKind.NONE) + public static Completable concat(Completable... sources) { + Objects.requireNonNull(sources, "sources is null"); + if (sources.length == 0) { + return complete(); + } else + if (sources.length == 1) { + return sources[0]; + } + return create(new CompletableOnSubscribeConcatArray(sources)); + } + + /** + * Returns a Completable which completes only when all sources complete, one after another. + * @param sources the sources to concatenate + * @return the Completable instance which completes only when all sources complete + * @throws NullPointerException if sources is null + */ + @SchedulerSupport(SchedulerKind.NONE) + public static Completable concat(Iterable sources) { + Objects.requireNonNull(sources, "sources is null"); + + return create(new CompletableOnSubscribeConcatIterable(sources)); + } + + /** + * Returns a Completable which completes only when all sources complete, one after another. + * @param sources the sources to concatenate + * @return the Completable instance which completes only when all sources complete + * @throws NullPointerException if sources is null + */ + @SchedulerSupport(SchedulerKind.NONE) + public static Completable concat(Observable sources) { + return concat(sources, 2); + } + + /** + * Returns a Completable which completes only when all sources complete, one after another. + * @param sources the sources to concatenate + * @param prefetch the number of sources to prefetch from the sources + * @return the Completable instance which completes only when all sources complete + * @throws NullPointerException if sources is null + */ + @SchedulerSupport(SchedulerKind.NONE) + public static Completable concat(Observable sources, int prefetch) { + Objects.requireNonNull(sources, "sources is null"); + if (prefetch < 1) { + throw new IllegalArgumentException("prefetch > 0 required but it was " + prefetch); + } + return create(new CompletableOnSubscribeConcat(sources, prefetch)); + } + + /** + * Constructs a Completable instance by wrapping the given onSubscribe callback. + * @param onSubscribe the callback which will receive the CompletableSubscriber instances + * when the Completable is subscribed to. + * @return the created Completable instance + * @throws NullPointerException if onSubscribe is null + */ + @SchedulerSupport(SchedulerKind.NONE) + public static Completable create(CompletableOnSubscribe onSubscribe) { + Objects.requireNonNull(onSubscribe, "onSubscribe is null"); + try { + // TODO plugin wrapping onSubscribe + + return new Completable(onSubscribe); + } catch (NullPointerException ex) { + throw ex; + } catch (Throwable ex) { + RxJavaPlugins.onError(ex); + throw toNpe(ex); + } + } + + /** + * Defers the subscription to a Completable instance returned by a supplier. + * @param completableSupplier the supplier that returns the Completable that will be subscribed to. + * @return the Completable instance + */ + @SchedulerSupport(SchedulerKind.NONE) + public static Completable defer(final Supplier completableSupplier) { + Objects.requireNonNull(completableSupplier, "completableSupplier"); + return create(new CompletableOnSubscribe() { + @Override + public void accept(CompletableSubscriber s) { + Completable c; + + try { + c = completableSupplier.get(); + } catch (Throwable e) { + s.onSubscribe(EmptyDisposable.INSTANCE); + s.onError(e); + return; + } + + if (c == null) { + s.onSubscribe(EmptyDisposable.INSTANCE); + s.onError(new NullPointerException("The completable returned is null")); + return; + } + + c.subscribe(s); + } + }); + } + + /** + * Creates a Completable which calls the given error supplier for each subscriber + * and emits its returned Throwable. + *

+ * If the errorSupplier returns null, the child CompletableSubscribers will receive a + * NullPointerException. + * @param errorSupplier the error supplier, not null + * @return the new Completable instance + * @throws NullPointerException if errorSupplier is null + */ + @SchedulerSupport(SchedulerKind.NONE) + public static Completable error(final Supplier errorSupplier) { + Objects.requireNonNull(errorSupplier, "errorSupplier is null"); + return create(new CompletableOnSubscribe() { + @Override + public void accept(CompletableSubscriber s) { + s.onSubscribe(EmptyDisposable.INSTANCE); + Throwable error; + + try { + error = errorSupplier.get(); + } catch (Throwable e) { + error = e; + } + + if (error == null) { + error = new NullPointerException("The error supplied is null"); + } + s.onError(error); + } + }); + } + + /** + * Creates a Completable instance that emits the given Throwable exception to subscribers. + * @param error the Throwable instance to emit, not null + * @return the new Completable instance + * @throws NullPointerException if error is null + */ + @SchedulerSupport(SchedulerKind.NONE) + public static Completable error(final Throwable error) { + Objects.requireNonNull(error, "error is null"); + return create(new CompletableOnSubscribe() { + @Override + public void accept(CompletableSubscriber s) { + s.onSubscribe(EmptyDisposable.INSTANCE); + s.onError(error); + } + }); + } + + /** + * Returns a Completable which when subscribed, executes the callable function, ignores its + * normal result and emits onError or onCompleted only. + * @param callable the callable instance to execute for each subscriber + * @return the new Completable instance + */ + @SchedulerSupport(SchedulerKind.NONE) + public static Completable fromCallable(final Callable callable) { + Objects.requireNonNull(callable, "callable is null"); + return create(new CompletableOnSubscribe() { + @Override + public void accept(CompletableSubscriber s) { + BooleanDisposable bs = new BooleanDisposable(); + s.onSubscribe(bs); + try { + callable.call(); + } catch (Throwable e) { + if (!bs.isDisposed()) { + s.onError(e); + } + return; + } + if (!bs.isDisposed()) { + s.onComplete(); + } + } + }); + } + + /** + * Returns a Completable instance that subscribes to the given flowable, ignores all values and + * emits only the terminal event. + * + * @param the type of the flowable + * @param flowable the Flowable instance to subscribe to, not null + * @return the new Completable instance + * @throws NullPointerException if flowable is null + */ + @SchedulerSupport(SchedulerKind.NONE) + public static Completable fromFlowable(final Observable flowable) { + Objects.requireNonNull(flowable, "flowable is null"); + return create(new CompletableOnSubscribe() { + @Override + public void accept(final CompletableSubscriber cs) { + flowable.subscribe(new Subscriber() { + + @Override + public void onComplete() { + cs.onComplete(); + } + + @Override + public void onError(Throwable t) { + cs.onError(t); + } + + @Override + public void onNext(T t) { + // ignored + } + + @Override + public void onSubscribe(Subscription s) { + cs.onSubscribe(Disposables.from(s)); + s.request(Long.MAX_VALUE); + } + + }); + } + }); + } + + /** + * Returns a Completable instance that subscribes to the given NbpObservable, ignores all values and + * emits only the terminal event. + * @param the type of the NbpObservable + * @param observable the Observable instance to subscribe to, not null + * @return the new Completable instance + * @throws NullPointerException if flowable is null + */ + @SchedulerSupport(SchedulerKind.NONE) + public static Completable fromNbpObservable(final NbpObservable observable) { + Objects.requireNonNull(observable, "observable is null"); + return create(new CompletableOnSubscribe() { + @Override + public void accept(final CompletableSubscriber s) { + observable.subscribe(new NbpSubscriber() { + + @Override + public void onComplete() { + s.onComplete(); + } + + @Override + public void onError(Throwable e) { + s.onError(e); + } + + @Override + public void onNext(T value) { + // ignored + } + + @Override + public void onSubscribe(Disposable d) { + s.onSubscribe(d); + } + + }); + } + }); + } + + /** + * Returns a Completable instance that runs the given Runnable for each subscriber and + * emits either an unchecked exception or simply completes. + * @param run the runnable to run for each subscriber + * @return the new Completable instance + * @throws NullPointerException if run is null + */ + @SchedulerSupport(SchedulerKind.NONE) + public static Completable fromRunnable(final Runnable run) { + Objects.requireNonNull(run, "run is null"); + return create(new CompletableOnSubscribe() { + @Override + public void accept(CompletableSubscriber s) { + BooleanDisposable bs = new BooleanDisposable(); + s.onSubscribe(bs); + try { + run.run(); + } catch (Throwable e) { + if (!bs.isDisposed()) { + s.onError(e); + } + return; + } + if (!bs.isDisposed()) { + s.onComplete(); + } + } + }); + } + + /** + * Returns a Completable instance that when subscribed to, subscribes to the Single instance and + * emits a completion event if the single emits onSuccess or forwards any onError events. + * @param the value type of the Single + * @param single the Single instance to subscribe to, not null + * @return the new Completable instance + * @throws NullPointerException if single is null + */ + @SchedulerSupport(SchedulerKind.NONE) + public static Completable fromSingle(final Single single) { + Objects.requireNonNull(single, "single is null"); + return create(new CompletableOnSubscribe() { + @Override + public void accept(final CompletableSubscriber s) { + single.subscribe(new SingleSubscriber() { + + @Override + public void onError(Throwable e) { + s.onError(e); + } + + @Override + public void onSubscribe(Disposable d) { + s.onSubscribe(d); + } + + @Override + public void onSuccess(T value) { + s.onComplete(); + } + + }); + } + }); + } + + /** + * Returns a Completable instance that subscribes to all sources at once and + * completes only when all source Completables complete or one of them emits an error. + * @param sources the iterable sequence of sources. + * @return the new Completable instance + * @throws NullPointerException if sources is null + */ + public static Completable merge(Completable... sources) { + Objects.requireNonNull(sources, "sources is null"); + if (sources.length == 0) { + return complete(); + } else + if (sources.length == 1) { + return sources[0]; + } + return create(new CompletableOnSubscribeMergeArray(sources)); + } + + /** + * Returns a Completable instance that subscribes to all sources at once and + * completes only when all source Completables complete or one of them emits an error. + * @param sources the iterable sequence of sources. + * @return the new Completable instance + * @throws NullPointerException if sources is null + */ + @SchedulerSupport(SchedulerKind.NONE) + public static Completable merge(Iterable sources) { + Objects.requireNonNull(sources, "sources is null"); + return create(new CompletableOnSubscribeMergeIterable(sources)); + } + + /** + * Returns a Completable instance that subscribes to all sources at once and + * completes only when all source Completables complete or one of them emits an error. + * @param sources the iterable sequence of sources. + * @return the new Completable instance + * @throws NullPointerException if sources is null + */ + public static Completable merge(Observable sources) { + return merge0(sources, Integer.MAX_VALUE, false); + } + + /** + * Returns a Completable instance that keeps subscriptions to a limited number of sources at once and + * completes only when all source Completables complete or one of them emits an error. + * @param sources the iterable sequence of sources. + * @param maxConcurrency the maximum number of concurrent subscriptions + * @return the new Completable instance + * @throws NullPointerException if sources is null + * @throws IllegalArgumentException if maxConcurrency is less than 1 + */ + public static Completable merge(Observable sources, int maxConcurrency) { + return merge0(sources, maxConcurrency, false); + + } + + /** + * Returns a Completable instance that keeps subscriptions to a limited number of sources at once and + * completes only when all source Completables terminate in one way or another, combining any exceptions + * thrown by either the sources Observable or the inner Completable instances. + * @param sources the iterable sequence of sources. + * @param maxConcurrency the maximum number of concurrent subscriptions + * @param delayErrors delay all errors from the main source and from the inner Completables? + * @return the new Completable instance + * @throws NullPointerException if sources is null + * @throws IllegalArgumentException if maxConcurrency is less than 1 + */ + protected static Completable merge0(Observable sources, int maxConcurrency, boolean delayErrors) { + Objects.requireNonNull(sources, "sources is null"); + if (maxConcurrency < 1) { + throw new IllegalArgumentException("maxConcurrency > 0 required but it was " + maxConcurrency); + } + return create(new CompletableOnSubscribeMerge(sources, maxConcurrency, delayErrors)); + } + + /** + * Returns a Completable that subscribes to all Completables in the source array and delays + * any error emitted by either the sources observable or any of the inner Completables until all of + * them terminate in a way or another. + * @param sources the array of Completables + * @return the new Completable instance + * @throws NullPointerException if sources is null + */ + public static Completable mergeDelayError(Completable... sources) { + Objects.requireNonNull(sources, "sources is null"); + return create(new CompletableOnSubscribeMergeDelayErrorArray(sources)); + } + + /** + * Returns a Completable that subscribes to all Completables in the source sequence and delays + * any error emitted by either the sources observable or any of the inner Completables until all of + * them terminate in a way or another. + * @param sources the sequence of Completables + * @return the new Completable instance + * @throws NullPointerException if sources is null + */ + public static Completable mergeDelayError(Iterable sources) { + Objects.requireNonNull(sources, "sources is null"); + return create(new CompletableOnSubscribeMergeDelayErrorIterable(sources)); + } + + + /** + * Returns a Completable that subscribes to all Completables in the source sequence and delays + * any error emitted by either the sources observable or any of the inner Completables until all of + * them terminate in a way or another. + * @param sources the sequence of Completables + * @return the new Completable instance + * @throws NullPointerException if sources is null + */ + public static Completable mergeDelayError(Observable sources) { + return merge0(sources, Integer.MAX_VALUE, true); + } + + /** + * Returns a Completable that subscribes to a limited number of inner Completables at once in + * the source sequence and delays any error emitted by either the sources + * observable or any of the inner Completables until all of + * them terminate in a way or another. + * @param sources the sequence of Completables + * @param maxConcurrency the maximum number of concurrent subscriptions to Completables + * @return the new Completable instance + * @throws NullPointerException if sources is null + */ + public static Completable mergeDelayError(Observable sources, int maxConcurrency) { + return merge0(sources, maxConcurrency, true); + } + + /** + * Returns a Completable that never calls onError or onComplete. + * @return the singleton instance that never calls onError or onComplete + */ + public static Completable never() { + return NEVER; + } + + /** + * Returns a Completable instance that fires its onComplete event after the given delay ellapsed. + * @param delay the delay time + * @param unit the delay unit + * @return the new Completable instance + */ + @SchedulerSupport(SchedulerKind.COMPUTATION) + public static Completable timer(long delay, TimeUnit unit) { + return timer(delay, unit, Schedulers.computation()); + } + + /** + * Returns a Completable instance that fires its onComplete event after the given delay ellapsed + * by using the supplied scheduler. + * @param delay the delay time + * @param unit the delay unit + * @param scheduler the scheduler where to emit the complete event + * @return the new Completable instance + */ + @SchedulerSupport(SchedulerKind.CUSTOM) + public static Completable timer(final long delay, final TimeUnit unit, final Scheduler scheduler) { + Objects.requireNonNull(unit, "unit is null"); + Objects.requireNonNull(scheduler, "scheduler is null"); + return create(new CompletableOnSubscribe() { + @Override + public void accept(final CompletableSubscriber s) { + MultipleAssignmentDisposable mad = new MultipleAssignmentDisposable(); + s.onSubscribe(mad); + if (!mad.isDisposed()) { + mad.set(scheduler.scheduleDirect(new Runnable() { + @Override + public void run() { + s.onComplete(); + } + }, delay, unit)); + } + } + }); + } + + /** + * Creates a NullPointerException instance and sets the given Throwable as its initial cause. + * @param ex the Throwable instance to use as cause, not null (not verified) + * @return the created NullPointerException + */ + static NullPointerException toNpe(Throwable ex) { + NullPointerException npe = new NullPointerException("Actually not, but can't pass out an exception otherwise..."); + npe.initCause(ex); + return npe; + } + + /** + * Returns a Completable instance which manages a resource along + * with a custom Completable instance while the subscription is active. + *

+ * This overload performs an eager unsubscription before the terminal event is emitted. + * + * @param the resource type + * @param resourceSupplier the supplier that returns a resource to be managed. + * @param completableFunction the function that given a resource returns a Completable instance that will be subscribed to + * @param disposer the consumer that disposes the resource created by the resource supplier + * @return the new Completable instance + */ + public static Completable using(Supplier resourceSupplier, + Function completableFunction, + Consumer disposer) { + return using(resourceSupplier, completableFunction, disposer, true); + } + + /** + * Returns a Completable instance which manages a resource along + * with a custom Completable instance while the subscription is active and performs eager or lazy + * resource disposition. + *

+ * If this overload performs a lazy unsubscription after the terminal event is emitted. + * Exceptions thrown at this time will be delivered to RxJavaPlugins only. + * + * @param the resource type + * @param resourceSupplier the supplier that returns a resource to be managed + * @param completableFunction the function that given a resource returns a non-null + * Completable instance that will be subscribed to + * @param disposer the consumer that disposes the resource created by the resource supplier + * @param eager if true, the resource is disposed before the terminal event is emitted, if false, the + * resource is disposed after the terminal event has been emitted + * @return the new Completable instance + */ + public static Completable using( + final Supplier resourceSupplier, + final Function completableFunction, + final Consumer disposer, + final boolean eager) { + Objects.requireNonNull(resourceSupplier, "resourceSupplier is null"); + Objects.requireNonNull(completableFunction, "completableFunction is null"); + Objects.requireNonNull(disposer, "disposer is null"); + + return create(new CompletableOnSubscribe() { + @Override + public void accept(final CompletableSubscriber s) { + final R resource; + + try { + resource = resourceSupplier.get(); + } catch (Throwable e) { + s.onSubscribe(EmptyDisposable.INSTANCE); + s.onError(e); + return; + } + + Completable cs; + + try { + cs = completableFunction.apply(resource); + } catch (Throwable e) { + s.onSubscribe(EmptyDisposable.INSTANCE); + s.onError(e); + return; + } + + if (cs == null) { + s.onSubscribe(EmptyDisposable.INSTANCE); + s.onError(new NullPointerException("The completable supplied is null")); + return; + } + + final AtomicBoolean once = new AtomicBoolean(); + + cs.subscribe(new CompletableSubscriber() { + Disposable d; + void disposeThis() { + d.dispose(); + if (once.compareAndSet(false, true)) { + try { + disposer.accept(resource); + } catch (Throwable ex) { + RxJavaPlugins.onError(ex); + } + } + } + + @Override + public void onComplete() { + if (eager) { + if (once.compareAndSet(false, true)) { + try { + disposer.accept(resource); + } catch (Throwable ex) { + s.onError(ex); + return; + } + } + } + + s.onComplete(); + + if (!eager) { + disposeThis(); + } + } + + @Override + public void onError(Throwable e) { + if (eager) { + if (once.compareAndSet(false, true)) { + try { + disposer.accept(resource); + } catch (Throwable ex) { + e = new CompositeException(ex, e); + } + } + } + + s.onError(e); + + if (!eager) { + disposeThis(); + } + } + + @Override + public void onSubscribe(Disposable d) { + this.d = d; + s.onSubscribe(new Disposable() { + @Override + public void dispose() { + disposeThis(); + } + }); + } + }); + } + }); + } + + /** The actual subscription action. */ + private final CompletableOnSubscribe onSubscribe; + + /** + * Constructs a Completable instance with the given onSubscribe callback. + * @param onSubscribe the callback that will receive CompletableSubscribers when they subscribe, + * not null (not verified) + */ + protected Completable(CompletableOnSubscribe onSubscribe) { + this.onSubscribe = onSubscribe; + } + + /** + * Returns a Completable that emits the a terminated event of either this Completable + * or the other Completable whichever fires first. + * @param other the other Completable, not null + * @return the new Completable instance + * @throws NullPointerException if other is null + */ + @SchedulerSupport(SchedulerKind.NONE) + public final Completable ambWith(Completable other) { + Objects.requireNonNull(other, "other is null"); + return amb(this, other); + } + + /** + * Subscribes to and awaits the termination of this Completable instance in a blocking manner and + * rethrows any exception emitted. + * @throws RuntimeException wrapping an InterruptedException if the current thread is interrupted + */ + @SchedulerSupport(SchedulerKind.NONE) + public final void await() { + final CountDownLatch cdl = new CountDownLatch(1); + final Throwable[] err = new Throwable[1]; + + subscribe(new CompletableSubscriber() { + + @Override + public void onComplete() { + cdl.countDown(); + } + + @Override + public void onError(Throwable e) { + err[0] = e; + cdl.countDown(); + } + + @Override + public void onSubscribe(Disposable d) { + // ignored + } + + }); + + if (cdl.getCount() == 0) { + if (err[0] != null) { + Exceptions.propagate(err[0]); + } + return; + } + try { + cdl.await(); + } catch (InterruptedException ex) { + throw Exceptions.propagate(ex); + } + if (err[0] != null) { + Exceptions.propagate(err[0]); + } + } + + /** + * Subscribes to and awaits the termination of this Completable instance in a blocking manner + * with a specific timeout and rethrows any exception emitted within the timeout window. + * @param timeout the timeout value + * @param unit the timeout unit + * @return true if the this Completable instance completed normally within the time limit, + * false if the timeout ellapsed before this Completable terminated. + * @throws RuntimeException wrapping an InterruptedException if the current thread is interrupted + */ + @SchedulerSupport(SchedulerKind.NONE) + public final boolean await(long timeout, TimeUnit unit) { + Objects.requireNonNull(unit, "unit is null"); + + final CountDownLatch cdl = new CountDownLatch(1); + final Throwable[] err = new Throwable[1]; + + subscribe(new CompletableSubscriber() { + + @Override + public void onComplete() { + cdl.countDown(); + } + + @Override + public void onError(Throwable e) { + err[0] = e; + cdl.countDown(); + } + + @Override + public void onSubscribe(Disposable d) { + // ignored + } + + }); + + if (cdl.getCount() == 0) { + if (err[0] != null) { + Exceptions.propagate(err[0]); + } + return true; + } + boolean b; + try { + b = cdl.await(timeout, unit); + } catch (InterruptedException ex) { + throw Exceptions.propagate(ex); + } + if (b) { + if (err[0] != null) { + Exceptions.propagate(err[0]); + } + } + return b; + } + + /** + * Calls the given transformer function with this instance and returns the function's resulting + * Completable. + * @param transformer the transformer function, not null + * @return the Completable returned by the function + * @throws NullPointerException if transformer is null + */ + @SchedulerSupport(SchedulerKind.NONE) + public final Completable compose(CompletableTransformer transformer) { + return to(transformer); + } + + /** + * Concatenates this Completable with another Completable. + * @param other the other Completable, not null + * @return the new Completable which subscribes to this and then the other Completable + * @throws NullPointerException if other is null + */ + @SchedulerSupport(SchedulerKind.NONE) + public final Completable concatWith(Completable other) { + Objects.requireNonNull(other, "other is null"); + return concat(this, other); + } + + /** + * Returns a Completable which delays the emission of the completion event by the given time. + * @param delay the delay time + * @param unit the delay unit + * @return the new Completable instance + * @throws NullPointerException if unit is null + */ + @SchedulerSupport(SchedulerKind.COMPUTATION) + public final Completable delay(long delay, TimeUnit unit) { + return delay(delay, unit, Schedulers.computation(), false); + } + + /** + * Returns a Completable which delays the emission of the completion event by the given time while + * running on the specified scheduler. + * @param delay the delay time + * @param unit the delay unit + * @param scheduler the scheduler to run the delayed completion on + * @return the new Completable instance + * @throws NullPointerException if unit or scheduler is null + */ + @SchedulerSupport(SchedulerKind.CUSTOM) + public final Completable delay(long delay, TimeUnit unit, Scheduler scheduler) { + return delay(delay, unit, scheduler, false); + } + + /** + * Returns a Completable which delays the emission of the completion event, and optionally the error as well, by the given time while + * running on the specified scheduler. + * @param delay the delay time + * @param unit the delay unit + * @param scheduler the scheduler to run the delayed completion on + * @param delayError delay the error emission as well? + * @return the new Completable instance + * @throws NullPointerException if unit or scheduler is null + */ + @SchedulerSupport(SchedulerKind.CUSTOM) + public final Completable delay(final long delay, final TimeUnit unit, final Scheduler scheduler, final boolean delayError) { + Objects.requireNonNull(unit, "unit is null"); + Objects.requireNonNull(scheduler, "scheduler is null"); + return create(new CompletableOnSubscribe() { + @Override + public void accept(final CompletableSubscriber s) { + final CompositeDisposable set = new CompositeDisposable(); + + subscribe(new CompletableSubscriber() { + + + @Override + public void onComplete() { + set.add(scheduler.scheduleDirect(new Runnable() { + @Override + public void run() { + s.onComplete(); + } + }, delay, unit)); + } + + @Override + public void onError(final Throwable e) { + if (delayError) { + set.add(scheduler.scheduleDirect(new Runnable() { + @Override + public void run() { + s.onError(e); + } + }, delay, unit)); + } else { + s.onError(e); + } + } + + @Override + public void onSubscribe(Disposable d) { + set.add(d); + s.onSubscribe(set); + } + + }); + } + }); + } + + /** + * Returns a Completable which calls the given onComplete callback if this Completable completes. + * @param onComplete the callback to call when this emits an onComplete event + * @return the new Completable instance + * @throws NullPointerException if onComplete is null + */ + @SchedulerSupport(SchedulerKind.NONE) + public final Completable doOnComplete(Runnable onComplete) { + return doOnLifecycle(Functions.emptyConsumer(), Functions.emptyConsumer(), onComplete, Functions.emptyRunnable(), Functions.emptyRunnable()); + } + + /** + * Returns a Completable which calls the giveon onDispose callback if the child subscriber cancels + * the subscription. + * @param onDispose the callback to call when the child subscriber cancels the subscription + * @return the new Completable instance + * @throws NullPointerException if onDispose is null + */ + @SchedulerSupport(SchedulerKind.NONE) + public final Completable doOnDispose(Runnable onDispose) { + return doOnLifecycle(Functions.emptyConsumer(), Functions.emptyConsumer(), Functions.emptyRunnable(), Functions.emptyRunnable(), onDispose); + } + + /** + * Returns a Completable which calls the given onError callback if this Completable emits an error. + * @param onError the error callback + * @return the new Completable instance + * @throws NullPointerException if onError is null + */ + @SchedulerSupport(SchedulerKind.NONE) + public final Completable doOnError(Consumer onError) { + return doOnLifecycle(Functions.emptyConsumer(), onError, Functions.emptyRunnable(), Functions.emptyRunnable(), Functions.emptyRunnable()); + } + + /** + * Returns a Completable instance that calls the various callbacks on the specific + * lifecycle events. + * @param onSubscribe the consumer called when a CompletableSubscriber subscribes. + * @param onError the consumer called when this emits an onError event + * @param onComplete the runnable called just before when this Completable completes normally + * @param onAfterComplete the runnable called after this Completable completes normally + * @param onDisposed the runnable called when the child cancels the subscription + * @return the new Completable instance + */ + @SchedulerSupport(SchedulerKind.NONE) + protected final Completable doOnLifecycle( + final Consumer onSubscribe, + final Consumer onError, + final Runnable onComplete, + final Runnable onAfterComplete, + final Runnable onDisposed) { + Objects.requireNonNull(onSubscribe, "onSubscribe is null"); + Objects.requireNonNull(onError, "onError is null"); + Objects.requireNonNull(onComplete, "onComplete is null"); + Objects.requireNonNull(onAfterComplete, "onAfterComplete is null"); + Objects.requireNonNull(onDisposed, "onDisposed is null"); + return create(new CompletableOnSubscribe() { + @Override + public void accept(final CompletableSubscriber s) { + subscribe(new CompletableSubscriber() { + + @Override + public void onComplete() { + try { + onComplete.run(); + } catch (Throwable e) { + s.onError(e); + return; + } + + s.onComplete(); + + try { + onAfterComplete.run(); + } catch (Throwable e) { + RxJavaPlugins.onError(e); + } + } + + @Override + public void onError(Throwable e) { + try { + onError.accept(e); + } catch (Throwable ex) { + e = new CompositeException(ex, e); + } + + s.onError(e); + } + + @Override + public void onSubscribe(final Disposable d) { + + try { + onSubscribe.accept(d); + } catch (Throwable ex) { + d.dispose(); + s.onSubscribe(EmptyDisposable.INSTANCE); + s.onError(ex); + return; + } + + s.onSubscribe(new Disposable() { + @Override + public void dispose() { + try { + onDisposed.run(); + } catch (Throwable e) { + RxJavaPlugins.onError(e); + } + d.dispose(); + } + }); + } + + }); + } + }); + } + + /** + * Returns a Completable instance that calls the given onSubscribe callback with the disposable + * that child subscribers receive on subscription. + * @param onSubscribe the callback called when a child subscriber subscribes + * @return the new Completable instance + * @throws NullPointerException if onSubscribe is null + */ + @SchedulerSupport(SchedulerKind.NONE) + public final Completable doOnSubscribe(Consumer onSubscribe) { + return doOnLifecycle(onSubscribe, Functions.emptyConsumer(), Functions.emptyRunnable(), Functions.emptyRunnable(), Functions.emptyRunnable()); + } + + /** + * Returns a Completable instance that calls the given onTerminate callback just before this Completable + * completes normally or with an exception + * @param onTerminate the callback to call just before this Completable terminates + * @return the new Completable instance + */ + @SchedulerSupport(SchedulerKind.NONE) + public final Completable doOnTerminate(final Runnable onTerminate) { + return doOnLifecycle(Functions.emptyConsumer(), new Consumer() { + @Override + public void accept(Throwable e) { + onTerminate.run(); + } + }, onTerminate, Functions.emptyRunnable(), Functions.emptyRunnable()); + } + + /** + * Returns a completable that first runs this Completable + * and then the other completable. + *

+ * This is an alias for {@link #concatWith(Completable)}. + * @param other the other Completable, not null + * @return the new Completable instance + * @throws NullPointerException if other is null + */ + @SchedulerSupport(SchedulerKind.NONE) + public final Completable endWith(Completable other) { + return concatWith(other); + } + /** + * Returns an NbpObservable that first runs this Completable instance and + * resumes with the given next Observable. + * @param the type of the NbpObservable + * @param next the next Observable to continue + * @return the new Observable instance + * @throws NullPointerException if next is null + */ + @SchedulerSupport(SchedulerKind.CUSTOM) + public final NbpObservable endWith(NbpObservable next) { + return next.startWith(this.toNbpObservable()); + } + + /** + * Returns an Observable that first runs this Completable instance and + * resumes with the given next Observable. + * @param the value type of the observable + * @param next the next Observable to continue + * @return the new Observable instance + * @throws NullPointerException if next is null + */ + @SchedulerSupport(SchedulerKind.CUSTOM) + public final Observable endWith(Observable next) { + return next.startWith(this.toFlowable()); + } + + /** + * Returns a Completable instace that calls the given onAfterComplete callback after this + * Completable completes normally. + * @param onAfterComplete the callback to call after this Completable emits an onComplete event. + * @return the new Completable instance + * @throws NullPointerException if onAfterComplete is null + */ + @SchedulerSupport(SchedulerKind.NONE) + public final Completable finallyDo(Runnable onAfterComplete) { + return doOnLifecycle(Functions.emptyConsumer(), Functions.emptyConsumer(), Functions.emptyRunnable(), onAfterComplete, Functions.emptyRunnable()); + } + + /** + * Subscribes to this Completable instance and blocks until it terminates, then returns null or + * the emitted exception if any. + * @return the throwable if this terminated with an error, null otherwise + * @throws RuntimeException that wraps an InterruptedException if the wait is interrupted + */ + @SchedulerSupport(SchedulerKind.NONE) + public final Throwable get() { + final CountDownLatch cdl = new CountDownLatch(1); + final Throwable[] err = new Throwable[1]; + + subscribe(new CompletableSubscriber() { + + @Override + public void onComplete() { + cdl.countDown(); + } + + @Override + public void onError(Throwable e) { + err[0] = e; + cdl.countDown(); + } + + @Override + public void onSubscribe(Disposable d) { + // ignored + } + + }); + + if (cdl.getCount() == 0) { + return err[0]; + } + try { + cdl.await(); + } catch (InterruptedException ex) { + throw Exceptions.propagate(ex); + } + return err[0]; + } + + /** + * Subscribes to this Completable instance and blocks until it terminates or the specified timeout + * ellapses, then returns null for normal termination or the emitted exception if any. + * @param timeout the timeout value + * @param unit the time unit + * @return the throwable if this terminated with an error, null otherwise + * @throws RuntimeException that wraps an InterruptedException if the wait is interrupted or + * TimeoutException if the specified timeout ellapsed before it + */ + @SchedulerSupport(SchedulerKind.NONE) + public final Throwable get(long timeout, TimeUnit unit) { + Objects.requireNonNull(unit, "unit is null"); + + final CountDownLatch cdl = new CountDownLatch(1); + final Throwable[] err = new Throwable[1]; + + subscribe(new CompletableSubscriber() { + + @Override + public void onComplete() { + cdl.countDown(); + } + + @Override + public void onError(Throwable e) { + err[0] = e; + cdl.countDown(); + } + + @Override + public void onSubscribe(Disposable d) { + // ignored + } + + }); + + if (cdl.getCount() == 0) { + return err[0]; + } + boolean b; + try { + b = cdl.await(timeout, unit); + } catch (InterruptedException ex) { + throw Exceptions.propagate(ex); + } + if (b) { + return err[0]; + } + Exceptions.propagate(new TimeoutException()); + return null; + } + + /** + * Lifts a CompletableSubscriber transformation into the chain of Completables. + * @param onLift the lifting function that transforms the child subscriber with a parent subscriber. + * @return the new Completable instance + * @throws NullPointerException if onLift is null + */ + @SchedulerSupport(SchedulerKind.NONE) + public final Completable lift(final CompletableOperator onLift) { + Objects.requireNonNull(onLift, "onLift is null"); + return create(new CompletableOnSubscribe() { + @Override + public void accept(CompletableSubscriber s) { + try { + // TODO plugin wrapping + + CompletableSubscriber sw = onLift.apply(s); + + subscribe(sw); + } catch (NullPointerException ex) { + throw ex; + } catch (Throwable ex) { + throw toNpe(ex); + } + } + }); + } + + /** + * Returns a Completable which subscribes to this and the other Completable and completes + * when both of them complete or one emits an error. + * @param other the other Completable instance + * @return the new Completable instance + * @throws NullPointerException if other is null + */ + @SchedulerSupport(SchedulerKind.NONE) + public final Completable mergeWith(Completable other) { + Objects.requireNonNull(other, "other is null"); + return merge(this, other); + } + + /** + * Returns a Completable which emits the terminal events from the thread of the specified scheduler. + * @param scheduler the scheduler to emit terminal events on + * @return the new Completable instance + * @throws NullPointerException if scheduler is null + */ + @SchedulerSupport(SchedulerKind.CUSTOM) + public final Completable observeOn(final Scheduler scheduler) { + Objects.requireNonNull(scheduler, "scheduler is null"); + return create(new CompletableOnSubscribe() { + @Override + public void accept(final CompletableSubscriber s) { + + final ArrayCompositeResource ad = new ArrayCompositeResource(2, Disposables.consumeAndDispose()); + final Scheduler.Worker w = scheduler.createWorker(); + ad.set(0, w); + + s.onSubscribe(ad); + + subscribe(new CompletableSubscriber() { + + @Override + public void onComplete() { + w.schedule(new Runnable() { + @Override + public void run() { + try { + s.onComplete(); + } finally { + ad.dispose(); + } + } + }); + } + + @Override + public void onError(final Throwable e) { + w.schedule(new Runnable() { + @Override + public void run() { + try { + s.onError(e); + } finally { + ad.dispose(); + } + } + }); + } + + @Override + public void onSubscribe(Disposable d) { + ad.set(1, d); + } + + }); + } + }); + } + + /** + * Returns a Completable instance that if this Completable emits an error, it will emit an onComplete + * and swallow the throwable. + * @return the new Completable instance + */ + @SchedulerSupport(SchedulerKind.NONE) + public final Completable onErrorComplete() { + return onErrorComplete(Functions.alwaysTrue()); + } + + /** + * Returns a Completable instance that if this Completable emits an error and the predicate returns + * true, it will emit an onComplete and swallow the throwable. + * @param predicate the predicate to call when an Throwable is emitted which should return true + * if the Throwable should be swallowed and replaced with an onComplete. + * @return the new Completable instance + */ + @SchedulerSupport(SchedulerKind.NONE) + public final Completable onErrorComplete(final Predicate predicate) { + Objects.requireNonNull(predicate, "predicate is null"); + + return create(new CompletableOnSubscribe() { + @Override + public void accept(final CompletableSubscriber s) { + subscribe(new CompletableSubscriber() { + + @Override + public void onComplete() { + s.onComplete(); + } + + @Override + public void onError(Throwable e) { + boolean b; + + try { + b = predicate.test(e); + } catch (Throwable ex) { + s.onError(new CompositeException(ex, e)); + return; + } + + if (b) { + s.onComplete(); + } else { + s.onError(e); + } + } + + @Override + public void onSubscribe(Disposable d) { + s.onSubscribe(d); + } + + }); + } + }); + } + + /** + * Returns a Completable instance that when encounters an error from this Completable, calls the + * specified mapper function that returns another Completable instance for it and resumes the + * execution with it. + * @param errorMapper the mapper function that takes the error and should return a Completable as + * continuation. + * @return the new Completable instance + */ + @SchedulerSupport(SchedulerKind.NONE) + public final Completable onErrorResumeNext(final Function errorMapper) { + Objects.requireNonNull(errorMapper, "errorMapper is null"); + return create(new CompletableOnSubscribe() { + @Override + public void accept(final CompletableSubscriber s) { + final SerialDisposable sd = new SerialDisposable(); + subscribe(new CompletableSubscriber() { + + @Override + public void onComplete() { + s.onComplete(); + } + + @Override + public void onError(Throwable e) { + Completable c; + + try { + c = errorMapper.apply(e); + } catch (Throwable ex) { + s.onError(new CompositeException(ex, e)); + return; + } + + if (c == null) { + NullPointerException npe = new NullPointerException("The completable returned is null"); + npe.initCause(e); + s.onError(npe); + return; + } + + c.subscribe(new CompletableSubscriber() { + + @Override + public void onComplete() { + s.onComplete(); + } + + @Override + public void onError(Throwable e) { + s.onError(e); + } + + @Override + public void onSubscribe(Disposable d) { + sd.set(d); + } + + }); + } + + @Override + public void onSubscribe(Disposable d) { + sd.set(d); + } + + }); + } + }); + } + + /** + * Returns a Completable that repeatedly subscribes to this Completable until cancelled. + * @return the new Completable instance + */ + @SchedulerSupport(SchedulerKind.NONE) + public final Completable repeat() { + return fromFlowable(toFlowable().repeat()); + } + + /** + * Returns a Completable that subscribes repeatedly at most the given times to this Completable. + * @param times the number of times the resubscription should happen + * @return the new Completable instance + * @throws IllegalArgumentException if times is less than zero + */ + @SchedulerSupport(SchedulerKind.NONE) + public final Completable repeat(long times) { + return fromFlowable(toFlowable().repeat(times)); + } + + /** + * Returns a Completable that repeatedly subscribes to this Completable so long as the given + * stop supplier returns false. + * @param stop the supplier that should return true to stop resubscribing. + * @return the new Completable instance + * @throws NullPointerException if stop is null + */ + @SchedulerSupport(SchedulerKind.NONE) + public final Completable repeatUntil(BooleanSupplier stop) { + return fromFlowable(toFlowable().repeatUntil(stop)); + } + + /** + * Returns a Completable instance that repeats when the Publisher returned by the handler + * emits an item or completes when this Publisher emits a completed event. + * @param handler the function that transforms the stream of values indicating the completion of + * this Completable and returns a Publisher that emits items for repeating or completes to indicate the + * repetition should stop + * @return the new Completable instance + * @throws NullPointerException if stop is null + */ + @SchedulerSupport(SchedulerKind.NONE) + /* + * FIXME the Observable type doesn't make sense here because nulls are not allowed + * FIXME add unit test once the type has been fixed + */ + public final Completable repeatWhen(Function, ? extends Publisher> handler) { + return fromFlowable(toFlowable().repeatWhen(handler)); + } + + /** + * Returns a Completable that retries this Completable as long as it emits an onError event. + * @return the new Completable instance + */ + @SchedulerSupport(SchedulerKind.NONE) + public final Completable retry() { + return fromFlowable(toFlowable().retry()); + } + + /** + * Returns a Completable that retries this Completable in case of an error as long as the predicate + * returns true. + * @param predicate the predicate called when this emits an error with the repeat count and the latest exception + * and should return true to retry. + * @return the new Completable instance + */ + @SchedulerSupport(SchedulerKind.NONE) + public final Completable retry(BiPredicate predicate) { + return fromFlowable(toFlowable().retry(predicate)); + } + + /** + * Returns a Completable that when this Completable emits an error, retries at most the given + * number of times before giving up and emitting the last error. + * @param times the number of times the returned Completable should retry this Completable + * @return the new Completable instance + * @throws IllegalArgumentException if times is negative + */ + @SchedulerSupport(SchedulerKind.NONE) + public final Completable retry(long times) { + return fromFlowable(toFlowable().retry(times)); + } + + /** + * Returns a Completable that when this Completable emits an error, calls the given predicate with + * the latest exception to decide whether to resubscribe to this or not. + * @param predicate the predicate that is called with the latest throwable and should return + * true to indicate the returned Completable should resubscribe to this Completable. + * @return the new Completable instance + * @throws NullPointerException if predicate is null + */ + @SchedulerSupport(SchedulerKind.NONE) + public final Completable retry(Predicate predicate) { + return fromFlowable(toFlowable().retry(predicate)); + } + + /** + * Returns a Completable which given a Publisher and when this Completable emits an error, delivers + * that error through an Observable and the Publisher should return a value indicating a retry in response + * or a terminal event indicating a termination. + * @param handler the handler that receives an Observable delivering Throwables and should return a Publisher that + * emits items to indicate retries or emits terminal events to indicate termination. + * @return the new Completable instance + * @throws NullPointerException if handler is null + */ + @SchedulerSupport(SchedulerKind.NONE) + public final Completable retryWhen(Function, ? extends Publisher> handler) { + return fromFlowable(toFlowable().retryWhen(handler)); + } + + /** + * Returns a Completable which first runs the other Completable + * then this completable if the other completed normally. + * @param other the other completable to run first + * @return the new Completable instance + * @throws NullPointerException if other is null + */ + @SchedulerSupport(SchedulerKind.NONE) + public final Completable startWith(Completable other) { + Objects.requireNonNull(other, "other is null"); + return concat(other, this); + } + + /** + * Returns an NbpObservable which first delivers the events + * of the other NbpObservable then runs this Completable. + * @param the value type + * @param other the other NbpObservable to run first + * @return the new NbpObservable instance + * @throws NullPointerException if other is null + */ + @SchedulerSupport(SchedulerKind.NONE) + public final NbpObservable startWith(NbpObservable other) { + Objects.requireNonNull(other, "other is null"); + return other.endWith(this.toNbpObservable()); + } + /** + * Returns an Observable which first delivers the events + * of the other Observable then runs this Completable. + * @param the value type + * @param other the other Observable to run first + * @return the new Observable instance + * @throws NullPointerException if other is null + */ + @SchedulerSupport(SchedulerKind.NONE) + public final Observable startWith(Observable other) { + Objects.requireNonNull(other, "other is null"); + return other.endWith(this.toFlowable()); + } + + /** + * Subscribes to this Completable and returns a Disposable which can be used to cancel + * the subscription. + * @return the Disposable that allows cancelling the subscription + */ + @SchedulerSupport(SchedulerKind.NONE) + public final Disposable subscribe() { + final MultipleAssignmentDisposable mad = new MultipleAssignmentDisposable(); + subscribe(new CompletableSubscriber() { + @Override + public void onComplete() { + // nothing to do + } + + @Override + public void onError(Throwable e) { + RxJavaPlugins.onError(e); + } + + @Override + public void onSubscribe(Disposable d) { + mad.set(d); + } + }); + + return mad; + } + /** + * Subscribes the given CompletableSubscriber to this Completable instance. + * @param s the CompletableSubscriber, not null + * @throws NullPointerException if s is null + */ + @SchedulerSupport(SchedulerKind.NONE) + public final void subscribe(CompletableSubscriber s) { + Objects.requireNonNull(s, "s is null"); + try { + // TODO plugin wrapping the subscriber + + onSubscribe.accept(s); + } catch (NullPointerException ex) { + throw ex; + } catch (Throwable ex) { + RxJavaPlugins.onError(ex); + throw toNpe(ex); + } + } + + /** + * Subscribes to this Completable and calls back either the onError or onComplete functions. + * + * @param onError the consumer that is called if this Completable emits an error + * @param onComplete the runnable that is called if the Completable completes normally + * @return the Disposable that can be used for cancelling the subscription asynchronously + * @throws NullPointerException if either callback is null + */ + @SchedulerSupport(SchedulerKind.NONE) + public final Disposable subscribe(final Consumer onError, final Runnable onComplete) { + Objects.requireNonNull(onError, "onError is null"); + Objects.requireNonNull(onComplete, "onComplete is null"); + + final MultipleAssignmentDisposable mad = new MultipleAssignmentDisposable(); + subscribe(new CompletableSubscriber() { + @Override + public void onComplete() { + try { + onComplete.run(); + } catch (Throwable e) { + onError(e); + } + } + + @Override + public void onError(Throwable e) { + try { + onError.accept(e); + } catch (Throwable ex) { + RxJavaPlugins.onError(ex); + RxJavaPlugins.onError(e); + } + } + + @Override + public void onSubscribe(Disposable d) { + mad.set(d); + } + }); + + return mad; + } + + /** + * Subscribes a non-backpressure NbpSubscriberto this Completable instance which + * will receive only an onError or onComplete event. + * @param s the NbpSubscriber instance, not null + * @throws NullPointerException if s is null + */ + @SchedulerSupport(SchedulerKind.NONE) + public final void subscribe(final NbpSubscriber s) { + Objects.requireNonNull(s, "s is null"); + try { + // TODO plugin wrapping the subscriber + + subscribe(new CompletableSubscriber() { + @Override + public void onComplete() { + s.onComplete(); + } + + @Override + public void onError(Throwable e) { + s.onError(e); + } + + @Override + public void onSubscribe(Disposable d) { + s.onSubscribe(d); + } + }); + + } catch (NullPointerException ex) { + throw ex; + } catch (Throwable ex) { + RxJavaPlugins.onError(ex); + throw toNpe(ex); + } + } + + /** + * Subscribes to this Completable and calls the given Runnable when this Completable + * completes normally. + *

+ * If this Completable emits an error, it is sent to RxJavaPlugins.onError and gets swallowed. + * @param onComplete the runnable called when this Completable completes normally + * @return the Disposable that allows cancelling the subscription + */ + @SchedulerSupport(SchedulerKind.NONE) + public final Disposable subscribe(final Runnable onComplete) { + Objects.requireNonNull(onComplete, "onComplete is null"); + + final MultipleAssignmentDisposable mad = new MultipleAssignmentDisposable(); + subscribe(new CompletableSubscriber() { + @Override + public void onComplete() { + try { + onComplete.run(); + } catch (Throwable e) { + RxJavaPlugins.onError(e); + } + } + + @Override + public void onError(Throwable e) { + RxJavaPlugins.onError(e); + } + + @Override + public void onSubscribe(Disposable d) { + mad.set(d); + } + }); + + return mad; + } + + /** + * Subscribes a reactive-streams Subscriber to this Completable instance which + * will receive only an onError or onComplete event. + * @param the value type of the subscriber + * @param s the reactive-streams Subscriber, not null + * @throws NullPointerException if s is null + */ + @SchedulerSupport(SchedulerKind.NONE) + public final void subscribe(Subscriber s) { + Objects.requireNonNull(s, "s is null"); + try { + final Subscriber sw = RxJavaPlugins.onSubscribe(s); + + if (sw == null) { + throw new NullPointerException("The RxJavaPlugins.onSubscribe returned a null Subscriber"); + } + + subscribe(new CompletableSubscriber() { + @Override + public void onComplete() { + sw.onComplete(); + } + + @Override + public void onError(Throwable e) { + sw.onError(e); + } + + @Override + public void onSubscribe(Disposable d) { + DisposableSubscription ds = new DisposableSubscription(d); + sw.onSubscribe(ds); + } + }); + + } catch (NullPointerException ex) { + throw ex; + } catch (Throwable ex) { + RxJavaPlugins.onError(ex); + throw toNpe(ex); + } + } + + /** + * Returns a Completable which subscribes the child subscriber on the specified scheduler, making + * sure the subscription side-effects happen on that specific thread of the scheduler. + * @param scheduler the Scheduler to subscribe on + * @return the new Completable instance + * @throws NullPointerException if scheduler is null + */ + @SchedulerSupport(SchedulerKind.CUSTOM) + public final Completable subscribeOn(final Scheduler scheduler) { + Objects.requireNonNull(scheduler, "scheduler is null"); + + return create(new CompletableOnSubscribe() { + @Override + public void accept(final CompletableSubscriber s) { + // FIXME cancellation of this schedule + scheduler.scheduleDirect(new Runnable() { + @Override + public void run() { + subscribe(s); + } + }); + } + }); + } + + /** + * Returns a Completable that runs this Completable and emits a TimeoutException in case + * this Completable doesn't complete within the given time. + * @param timeout the timeout value + * @param unit the timeout unit + * @return the new Completable instance + * @throws NullPointerException if unit is null + */ + @SchedulerSupport(SchedulerKind.COMPUTATION) + public final Completable timeout(long timeout, TimeUnit unit) { + return timeout0(timeout, unit, Schedulers.computation(), null); + } + + /** + * Returns a Completable that runs this Completable and switches to the other Completable + * in case this Completable doesn't complete within the given time. + * @param timeout the timeout value + * @param unit the timeout unit + * @param other the other Completable instance to switch to in case of a timeout + * @return the new Completable instance + * @throws NullPointerException if unit or other is null + */ + @SchedulerSupport(SchedulerKind.COMPUTATION) + public final Completable timeout(long timeout, TimeUnit unit, Completable other) { + Objects.requireNonNull(other, "other is null"); + return timeout0(timeout, unit, Schedulers.computation(), other); + } + + /** + * Returns a Completable that runs this Completable and emits a TimeoutException in case + * this Completable doesn't complete within the given time while "waiting" on the specified + * Scheduler. + * @param timeout the timeout value + * @param unit the timeout unit + * @param scheduler the scheduler to use to wait for completion + * @return the new Completable instance + * @throws NullPointerException if unit or scheduler is null + */ + @SchedulerSupport(SchedulerKind.CUSTOM) + public final Completable timeout(long timeout, TimeUnit unit, Scheduler scheduler) { + return timeout0(timeout, unit, scheduler, null); + } + + /** + * Returns a Completable that runs this Completable and switches to the other Completable + * in case this Completable doesn't complete within the given time while "waiting" on + * the specified scheduler. + * @param timeout the timeout value + * @param unit the timeout unit + * @param scheduler the scheduler to use to wait for completion + * @param other the other Completable instance to switch to in case of a timeout + * @return the new Completable instance + * @throws NullPointerException if unit, scheduler or other is null + */ + @SchedulerSupport(SchedulerKind.CUSTOM) + public final Completable timeout(long timeout, TimeUnit unit, Scheduler scheduler, Completable other) { + Objects.requireNonNull(other, "other is null"); + return timeout0(timeout, unit, scheduler, other); + } + + /** + * Returns a Completable that runs this Completable and optionally switches to the other Completable + * in case this Completable doesn't complete within the given time while "waiting" on + * the specified scheduler. + * @param timeout the timeout value + * @param unit the timeout unit + * @param scheduler the scheduler to use to wait for completion + * @param other the other Completable instance to switch to in case of a timeout, + * if null a TimeoutException is emitted instead + * @return the new Completable instance + * @throws NullPointerException if unit or scheduler + */ + @SchedulerSupport(SchedulerKind.CUSTOM) + public final Completable timeout0(long timeout, TimeUnit unit, Scheduler scheduler, Completable other) { + Objects.requireNonNull(unit, "unit is null"); + Objects.requireNonNull(scheduler, "scheduler is null"); + return create(new CompletableOnSubscribeTimeout(this, timeout, unit, scheduler, other)); + } + + /** + * Allows fluent conversion to another type via a function callback. + * @param the output type + * @param converter the function called with this which should return some other value. + * @return the converted value + * @throws NullPointerException if converter is null + */ + @SchedulerSupport(SchedulerKind.NONE) + public final U to(Function converter) { + return converter.apply(this); + } + + /** + * Returns an Observable which when subscribed to subscribes to this Completable and + * relays the terminal events to the subscriber. + * @param the value type + * @return the new Observable created + */ + @SchedulerSupport(SchedulerKind.NONE) + public final Observable toFlowable() { + return Observable.create(new Publisher() { + @Override + public void subscribe(Subscriber s) { + Completable.this.subscribe(s); + } + }); + } + + /** + * Returns an NbpObservable which when subscribed to subscribes to this Completable and + * relays the terminal events to the subscriber. + * @param the value type + * @return the new NbpObservable created + */ + @SchedulerSupport(SchedulerKind.NONE) + public final NbpObservable toNbpObservable() { + return NbpObservable.create(new NbpOnSubscribe() { + @Override + public void accept(NbpSubscriber s) { + subscribe(s); + } + }); + } + + /** + * Convers this Completable into a Single which when this Completable completes normally, + * calls the given supplier and emits its returned value through onSuccess. + * @param the value type + * @param completionValueSupplier the value supplier called when this Completable completes normally + * @return the new Single instance + * @throws NullPointerException if completionValueSupplier is null + */ + @SchedulerSupport(SchedulerKind.NONE) + public final Single toSingle(final Supplier completionValueSupplier) { + Objects.requireNonNull(completionValueSupplier, "completionValueSupplier is null"); + return Single.create(new SingleOnSubscribe() { + @Override + public void accept(final SingleSubscriber s) { + subscribe(new CompletableSubscriber() { + + @Override + public void onComplete() { + T v; + + try { + v = completionValueSupplier.get(); + } catch (Throwable e) { + s.onError(e); + return; + } + + if (v == null) { + s.onError(new NullPointerException("The value supplied is null")); + } else { + s.onSuccess(v); + } + } + + @Override + public void onError(Throwable e) { + s.onError(e); + } + + @Override + public void onSubscribe(Disposable d) { + s.onSubscribe(d); + } + + }); + } + }); + } + + /** + * Convers this Completable into a Single which when this Completable completes normally, + * emits the given value through onSuccess. + * @param the value type + * @param completionValue the value to emit when this Completable completes normally + * @return the new Single instance + * @throws NullPointerException if completionValue is null + */ + @SchedulerSupport(SchedulerKind.NONE) + public final Single toSingleDefault(final T completionValue) { + Objects.requireNonNull(completionValue, "completionValue is null"); + return toSingle(new Supplier() { + @Override + public T get() { + return completionValue; + } + }); + } + + /** + * Returns a Completable which makes sure when a subscriber cancels the subscription, the + * dispose is called on the specified scheduler + * @param scheduler the target scheduler where to execute the cancellation + * @return the new Completable instance + * @throws NullPointerException if scheduler is null + */ + @SchedulerSupport(SchedulerKind.CUSTOM) + public final Completable unsubscribeOn(final Scheduler scheduler) { + Objects.requireNonNull(scheduler, "scheduler is null"); + return create(new CompletableOnSubscribe() { + @Override + public void accept(final CompletableSubscriber s) { + subscribe(new CompletableSubscriber() { + + @Override + public void onComplete() { + s.onComplete(); + } + + @Override + public void onError(Throwable e) { + s.onError(e); + } + + @Override + public void onSubscribe(final Disposable d) { + s.onSubscribe(new Disposable() { + @Override + public void dispose() { + scheduler.scheduleDirect(new Runnable() { + @Override + public void run() { + d.dispose(); + } + }); + } + }); + } + + }); + } + }); + } +} \ No newline at end of file diff --git a/src/main/java/io/reactivex/NbpObservable.java b/src/main/java/io/reactivex/NbpObservable.java index cdb8a1a0d8..7e865606cc 100644 --- a/src/main/java/io/reactivex/NbpObservable.java +++ b/src/main/java/io/reactivex/NbpObservable.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -16,15 +16,16 @@ import java.util.*; import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicReference; -import java.util.function.*; -import java.util.stream.Stream; import org.reactivestreams.*; +import io.reactivex.Single.*; import io.reactivex.annotations.*; import io.reactivex.disposables.*; import io.reactivex.functions.*; import io.reactivex.internal.disposables.EmptyDisposable; +import io.reactivex.internal.functions.*; +import io.reactivex.internal.functions.Objects; import io.reactivex.internal.operators.nbp.*; import io.reactivex.internal.subscribers.nbp.*; import io.reactivex.internal.util.Exceptions; @@ -64,26 +65,33 @@ public interface NbpTransformer extends Function EMPTY = create(s -> { - s.onSubscribe(EmptyDisposable.INSTANCE); - s.onComplete(); + static final NbpObservable EMPTY = create(new NbpOnSubscribe() { + @Override + public void accept(NbpSubscriber s) { + s.onSubscribe(EmptyDisposable.INSTANCE); + s.onComplete(); + } }); /** A never NbpObservable instance as there is no need to instantiate this more than once. */ - static final NbpObservable NEVER = create(s -> s.onSubscribe(EmptyDisposable.INSTANCE)); + static final NbpObservable NEVER = create(new NbpOnSubscribe() { + @Override + public void accept(NbpSubscriber s) { + s.onSubscribe(EmptyDisposable.INSTANCE); + } + }); static final Object OBJECT = new Object(); public static NbpObservable amb(Iterable> sources) { - Objects.requireNonNull(sources); - return create(new NbpOnSubscribeAmb<>(null, sources)); + Objects.requireNonNull(sources, "sources is null"); + return create(new NbpOnSubscribeAmb(null, sources)); } @SuppressWarnings("unchecked") @SchedulerSupport(SchedulerKind.NONE) - @SafeVarargs public static NbpObservable amb(NbpObservable... sources) { - Objects.requireNonNull(sources); + Objects.requireNonNull(sources, "sources is null"); int len = sources.length; if (len == 0) { return empty(); @@ -91,7 +99,7 @@ public static NbpObservable amb(NbpObservable... sources) { if (len == 1) { return (NbpObservable)sources[0]; } - return create(new NbpOnSubscribeAmb<>(sources, null)); + return create(new NbpOnSubscribeAmb(sources, null)); } /** @@ -103,7 +111,6 @@ static int bufferSize() { } @SchedulerSupport(SchedulerKind.NONE) - @SafeVarargs public static NbpObservable combineLatest(Function combiner, boolean delayError, int bufferSize, NbpObservable... sources) { return combineLatest(sources, combiner, delayError, bufferSize); } @@ -120,13 +127,13 @@ public static NbpObservable combineLatest(Iterable NbpObservable combineLatest(Iterable> sources, Function combiner, boolean delayError, int bufferSize) { - Objects.requireNonNull(sources); - Objects.requireNonNull(combiner); + Objects.requireNonNull(sources, "sources is null"); + Objects.requireNonNull(combiner, "combiner is null"); validateBufferSize(bufferSize); // the queue holds a pair of values so we need to double the capacity int s = bufferSize << 1; - return create(new NbpOnSubscribeCombineLatest<>(null, sources, combiner, s, delayError)); + return create(new NbpOnSubscribeCombineLatest(null, sources, combiner, s, delayError)); } @SchedulerSupport(SchedulerKind.NONE) @@ -142,57 +149,62 @@ public static NbpObservable combineLatest(NbpObservable[] @SchedulerSupport(SchedulerKind.NONE) public static NbpObservable combineLatest(NbpObservable[] sources, Function combiner, boolean delayError, int bufferSize) { validateBufferSize(bufferSize); - Objects.requireNonNull(combiner); + Objects.requireNonNull(combiner, "combiner is null"); if (sources.length == 0) { return empty(); } // the queue holds a pair of values so we need to double the capacity int s = bufferSize << 1; - return create(new NbpOnSubscribeCombineLatest<>(sources, null, combiner, s, delayError)); + return create(new NbpOnSubscribeCombineLatest(sources, null, combiner, s, delayError)); } + @SuppressWarnings("unchecked") @SchedulerSupport(SchedulerKind.NONE) public static NbpObservable combineLatest( NbpObservable p1, NbpObservable p2, BiFunction combiner) { - Function f = toFunction(combiner); - return combineLatest(f, false, bufferSize(), p1, p2); + return combineLatest(Functions.toFunction(combiner), false, bufferSize(), p1, p2); } + @SuppressWarnings("unchecked") @SchedulerSupport(SchedulerKind.NONE) public static NbpObservable combineLatest( NbpObservable p1, NbpObservable p2, NbpObservable p3, Function3 combiner) { - return combineLatest(combiner, false, bufferSize(), p1, p2, p3); + return combineLatest(Functions.toFunction(combiner), false, bufferSize(), p1, p2, p3); } + @SuppressWarnings("unchecked") @SchedulerSupport(SchedulerKind.NONE) public static NbpObservable combineLatest( NbpObservable p1, NbpObservable p2, NbpObservable p3, NbpObservable p4, Function4 combiner) { - return combineLatest(combiner, false, bufferSize(), p1, p2, p3, p4); + return combineLatest(Functions.toFunction(combiner), false, bufferSize(), p1, p2, p3, p4); } + @SuppressWarnings("unchecked") @SchedulerSupport(SchedulerKind.NONE) public static NbpObservable combineLatest( NbpObservable p1, NbpObservable p2, NbpObservable p3, NbpObservable p4, NbpObservable p5, Function5 combiner) { - return combineLatest(combiner, false, bufferSize(), p1, p2, p3, p4, p5); + return combineLatest(Functions.toFunction(combiner), false, bufferSize(), p1, p2, p3, p4, p5); } + @SuppressWarnings("unchecked") @SchedulerSupport(SchedulerKind.NONE) public static NbpObservable combineLatest( NbpObservable p1, NbpObservable p2, NbpObservable p3, NbpObservable p4, NbpObservable p5, NbpObservable p6, Function6 combiner) { - return combineLatest(combiner, false, bufferSize(), p1, p2, p3, p4, p5, p6); + return combineLatest(Functions.toFunction(combiner), false, bufferSize(), p1, p2, p3, p4, p5, p6); } + @SuppressWarnings("unchecked") @SchedulerSupport(SchedulerKind.NONE) public static NbpObservable combineLatest( NbpObservable p1, NbpObservable p2, @@ -200,9 +212,10 @@ public static NbpObservable combineLatest( NbpObservable p5, NbpObservable p6, NbpObservable p7, Function7 combiner) { - return combineLatest(combiner, false, bufferSize(), p1, p2, p3, p4, p5, p6, p7); + return combineLatest(Functions.toFunction(combiner), false, bufferSize(), p1, p2, p3, p4, p5, p6, p7); } + @SuppressWarnings("unchecked") @SchedulerSupport(SchedulerKind.NONE) public static NbpObservable combineLatest( NbpObservable p1, NbpObservable p2, @@ -210,9 +223,10 @@ public static NbpObservable combineLatest NbpObservable p5, NbpObservable p6, NbpObservable p7, NbpObservable p8, Function8 combiner) { - return combineLatest(combiner, false, bufferSize(), p1, p2, p3, p4, p5, p6, p7, p8); + return combineLatest(Functions.toFunction(combiner), false, bufferSize(), p1, p2, p3, p4, p5, p6, p7, p8); } + @SuppressWarnings("unchecked") @SchedulerSupport(SchedulerKind.NONE) public static NbpObservable combineLatest( NbpObservable p1, NbpObservable p2, @@ -221,19 +235,21 @@ public static NbpObservable combineLa NbpObservable p7, NbpObservable p8, NbpObservable p9, Function9 combiner) { - return combineLatest(combiner, false, bufferSize(), p1, p2, p3, p4, p5, p6, p7, p8, p9); + return combineLatest(Functions.toFunction(combiner), false, bufferSize(), p1, p2, p3, p4, p5, p6, p7, p8, p9); } + @SuppressWarnings({ "unchecked", "rawtypes" }) @SchedulerSupport(SchedulerKind.NONE) public static NbpObservable concat(int prefetch, Iterable> sources) { - Objects.requireNonNull(sources); - return fromIterable(sources).concatMap(v -> v, prefetch); + Objects.requireNonNull(sources, "sources is null"); + return fromIterable(sources).concatMap((Function)Functions.identity(), prefetch); } + @SuppressWarnings({ "unchecked", "rawtypes" }) @SchedulerSupport(SchedulerKind.NONE) public static NbpObservable concat(Iterable> sources) { - Objects.requireNonNull(sources); - return fromIterable(sources).concatMap(v -> v); + Objects.requireNonNull(sources, "sources is null"); + return fromIterable(sources).concatMap((Function)Functions.identity()); } @SchedulerSupport(SchedulerKind.NONE) @@ -241,16 +257,19 @@ public static final NbpObservable concat(NbpObservable NbpObservable concat(NbpObservable> sources, int bufferSize) { - return sources.concatMap(v -> v); + return sources.concatMap((Function)Functions.identity()); } + @SuppressWarnings("unchecked") @SchedulerSupport(SchedulerKind.NONE) public static NbpObservable concat(NbpObservable p1, NbpObservable p2) { return concatArray(p1, p2); } + @SuppressWarnings("unchecked") @SchedulerSupport(SchedulerKind.NONE) public static NbpObservable concat( NbpObservable p1, NbpObservable p2, @@ -258,6 +277,7 @@ public static NbpObservable concat( return concatArray(p1, p2, p3); } + @SuppressWarnings("unchecked") @SchedulerSupport(SchedulerKind.NONE) public static NbpObservable concat( NbpObservable p1, NbpObservable p2, @@ -265,6 +285,7 @@ public static NbpObservable concat( return concatArray(p1, p2, p3, p4); } + @SuppressWarnings("unchecked") @SchedulerSupport(SchedulerKind.NONE) public static NbpObservable concat( NbpObservable p1, NbpObservable p2, @@ -274,6 +295,7 @@ public static NbpObservable concat( return concatArray(p1, p2, p3, p4, p5); } + @SuppressWarnings("unchecked") @SchedulerSupport(SchedulerKind.NONE) public static NbpObservable concat( NbpObservable p1, NbpObservable p2, @@ -283,6 +305,7 @@ public static NbpObservable concat( return concatArray(p1, p2, p3, p4, p5, p6); } + @SuppressWarnings("unchecked") @SchedulerSupport(SchedulerKind.NONE) public static NbpObservable concat( NbpObservable p1, NbpObservable p2, @@ -293,6 +316,7 @@ public static NbpObservable concat( return concatArray(p1, p2, p3, p4, p5, p6, p7); } + @SuppressWarnings("unchecked") @SchedulerSupport(SchedulerKind.NONE) public static NbpObservable concat( NbpObservable p1, NbpObservable p2, @@ -303,6 +327,7 @@ public static NbpObservable concat( return concatArray(p1, p2, p3, p4, p5, p6, p7, p8); } + @SuppressWarnings("unchecked") @SchedulerSupport(SchedulerKind.NONE) public static NbpObservable concat( NbpObservable p1, NbpObservable p2, @@ -314,20 +339,24 @@ public static NbpObservable concat( return concatArray(p1, p2, p3, p4, p5, p6, p7, p8, p9); } + @SuppressWarnings({ "unchecked", "rawtypes" }) @SchedulerSupport(SchedulerKind.NONE) - @SafeVarargs public static NbpObservable concatArray(int prefetch, NbpObservable... sources) { - Objects.requireNonNull(sources); - return fromArray(sources).concatMap(v -> v, prefetch); + Objects.requireNonNull(sources, "sources is null"); + return fromArray(sources).concatMap((Function)Functions.identity(), prefetch); } /** - * - * TODO named this way because of overload conflict with concat(NbpObservable<NbpObservable>) + * Concatenates a variable number of NbpObservable sources. + *

+ * Note: named this way because of overload conflict with concat(NbpObservable<NbpObservable>) + * @param sources the array of sources + * @param the common base value type + * @return the new NbpObservable instance + * @throws NullPointerException if sources is null */ - @SuppressWarnings("unchecked") + @SuppressWarnings({ "unchecked", "rawtypes" }) @SchedulerSupport(SchedulerKind.NONE) - @SafeVarargs public static NbpObservable concatArray(NbpObservable... sources) { if (sources.length == 0) { return empty(); @@ -335,18 +364,19 @@ public static NbpObservable concatArray(NbpObservable... sou if (sources.length == 1) { return (NbpObservable)sources[0]; } - return fromArray(sources).concatMap(v -> v); + return fromArray(sources).concatMap((Function)Functions.identity()); } public static NbpObservable create(NbpOnSubscribe onSubscribe) { - Objects.requireNonNull(onSubscribe); + Objects.requireNonNull(onSubscribe, "onSubscribe is null"); // TODO plugin wrapper - return new NbpObservable<>(onSubscribe); + return new NbpObservable(onSubscribe); } @SchedulerSupport(SchedulerKind.NONE) public static NbpObservable defer(Supplier> supplier) { - return create(new NbpOnSubscribeDefer<>(supplier)); + Objects.requireNonNull(supplier, "supplier is null"); + return create(new NbpOnSubscribeDefer(supplier)); } @SchedulerSupport(SchedulerKind.NONE) @@ -357,40 +387,38 @@ public static NbpObservable empty() { @SchedulerSupport(SchedulerKind.NONE) public static NbpObservable error(Supplier errorSupplier) { - Objects.requireNonNull(errorSupplier); - return create(new NbpOnSubscribeErrorSource<>(errorSupplier)); + Objects.requireNonNull(errorSupplier, "errorSupplier is null"); + return create(new NbpOnSubscribeErrorSource(errorSupplier)); } @SchedulerSupport(SchedulerKind.NONE) - public static NbpObservable error(Throwable e) { - Objects.requireNonNull(e); - return error(() -> e); + public static NbpObservable error(final Throwable e) { + Objects.requireNonNull(e, "e is null"); + return error(new Supplier() { + @Override + public Throwable get() { + return e; + } + }); } @SchedulerSupport(SchedulerKind.NONE) - @SafeVarargs public static NbpObservable fromArray(T... values) { - Objects.requireNonNull(values); + Objects.requireNonNull(values, "values is null"); if (values.length == 0) { return empty(); } else if (values.length == 1) { return just(values[0]); } - return create(new NbpOnSubscribeArraySource<>(values)); + return create(new NbpOnSubscribeArraySource(values)); } // TODO match naming with RxJava 1.x @SchedulerSupport(SchedulerKind.NONE) public static NbpObservable fromCallable(Callable supplier) { - Objects.requireNonNull(supplier); - return create(new NbpOnSubscribeScalarAsyncSource<>(supplier)); - } - - @SchedulerSupport(SchedulerKind.NONE) - public static NbpObservable fromFuture(CompletableFuture future) { - Objects.requireNonNull(future); - return create(new NbpOnSubscribeCompletableFutureSource<>(future)); + Objects.requireNonNull(supplier, "supplier is null"); + return create(new NbpOnSubscribeScalarAsyncSource(supplier)); } /* @@ -400,114 +428,121 @@ public static NbpObservable fromFuture(CompletableFuture fut */ @SchedulerSupport(SchedulerKind.NONE) public static NbpObservable fromFuture(Future future) { - if (future instanceof CompletableFuture) { - return fromFuture((CompletableFuture)future); - } - Objects.requireNonNull(future); - return create(new NbpOnSubscribeFutureSource<>(future, 0L, null)); + Objects.requireNonNull(future, "future is null"); + return create(new NbpOnSubscribeFutureSource(future, 0L, null)); } @SchedulerSupport(SchedulerKind.NONE) public static NbpObservable fromFuture(Future future, long timeout, TimeUnit unit) { - Objects.requireNonNull(future); - Objects.requireNonNull(unit); - NbpObservable o = create(new NbpOnSubscribeFutureSource<>(future, timeout, unit)); + Objects.requireNonNull(future, "future is null"); + Objects.requireNonNull(unit, "unit is null"); + NbpObservable o = create(new NbpOnSubscribeFutureSource(future, timeout, unit)); return o; } @SchedulerSupport(SchedulerKind.CUSTOM) public static NbpObservable fromFuture(Future future, long timeout, TimeUnit unit, Scheduler scheduler) { - Objects.requireNonNull(scheduler); + Objects.requireNonNull(scheduler, "scheduler is null"); NbpObservable o = fromFuture(future, timeout, unit); return o.subscribeOn(scheduler); } @SchedulerSupport(SchedulerKind.IO) public static NbpObservable fromFuture(Future future, Scheduler scheduler) { - Objects.requireNonNull(scheduler); + Objects.requireNonNull(scheduler, "scheduler is null"); NbpObservable o = fromFuture(future); return o.subscribeOn(Schedulers.io()); } public static NbpObservable fromIterable(Iterable source) { - Objects.requireNonNull(source); - return create(new NbpOnSubscribeIterableSource<>(source)); + Objects.requireNonNull(source, "source is null"); + return create(new NbpOnSubscribeIterableSource(source)); } - public static NbpObservable fromPublisher(Publisher publisher) { - Objects.requireNonNull(publisher); - return create(s -> { - publisher.subscribe(new Subscriber() { + public static NbpObservable fromPublisher(final Publisher publisher) { + Objects.requireNonNull(publisher, "publisher is null"); + return create(new NbpOnSubscribe() { + @Override + public void accept(final NbpSubscriber s) { + publisher.subscribe(new Subscriber() { - @Override - public void onComplete() { - s.onComplete(); - } + @Override + public void onComplete() { + s.onComplete(); + } - @Override - public void onError(Throwable t) { - s.onError(t); - } + @Override + public void onError(Throwable t) { + s.onError(t); + } - @Override - public void onNext(T t) { - s.onNext(t); - } + @Override + public void onNext(T t) { + s.onNext(t); + } - @Override - public void onSubscribe(Subscription inner) { - s.onSubscribe(inner::cancel); - inner.request(Long.MAX_VALUE); - } - - }); + @Override + public void onSubscribe(Subscription inner) { + s.onSubscribe(Disposables.from(inner)); + inner.request(Long.MAX_VALUE); + } + + }); + } }); } @SchedulerSupport(SchedulerKind.NONE) - public static NbpObservable fromStream(Stream stream) { - Objects.requireNonNull(stream); - return create(new NbpOnSubscribeStreamSource<>(stream)); - } - - @SchedulerSupport(SchedulerKind.NONE) - public static NbpObservable generate(Consumer> generator) { - Objects.requireNonNull(generator); - return generate(() -> null, (s, o) -> { - generator.accept(o); - return s; - }, s -> { }); + public static NbpObservable generate(final Consumer> generator) { + Objects.requireNonNull(generator, "generator is null"); + return generate(Functions.nullSupplier(), + new BiFunction, Object>() { + @Override + public Object apply(Object s, NbpSubscriber o) { + generator.accept(o); + return s; + } + }, Functions.emptyConsumer()); } @SchedulerSupport(SchedulerKind.NONE) - public static NbpObservable generate(Supplier initialState, BiConsumer> generator) { - Objects.requireNonNull(generator); - return generate(initialState, (s, o) -> { - generator.accept(s, o); - return s; - }, s -> { }); + public static NbpObservable generate(Supplier initialState, final BiConsumer> generator) { + Objects.requireNonNull(generator, "generator is null"); + return generate(initialState, new BiFunction, S>() { + @Override + public S apply(S s, NbpSubscriber o) { + generator.accept(s, o); + return s; + } + }, Functions.emptyConsumer()); } @SchedulerSupport(SchedulerKind.NONE) - public static NbpObservable generate(Supplier initialState, BiConsumer> generator, Consumer disposeState) { - Objects.requireNonNull(generator); - return generate(initialState, (s, o) -> { - generator.accept(s, o); - return s; + public static NbpObservable generate( + final Supplier initialState, + final BiConsumer> generator, + Consumer disposeState) { + Objects.requireNonNull(generator, "generator is null"); + return generate(initialState, new BiFunction, S>() { + @Override + public S apply(S s, NbpSubscriber o) { + generator.accept(s, o); + return s; + } }, disposeState); } @SchedulerSupport(SchedulerKind.NONE) public static NbpObservable generate(Supplier initialState, BiFunction, S> generator) { - return generate(initialState, generator, s -> { }); + return generate(initialState, generator, Functions.emptyConsumer()); } @SchedulerSupport(SchedulerKind.NONE) public static NbpObservable generate(Supplier initialState, BiFunction, S> generator, Consumer disposeState) { - Objects.requireNonNull(initialState); - Objects.requireNonNull(generator); - Objects.requireNonNull(disposeState); - return create(new NbpOnSubscribeGenerate<>(initialState, generator, disposeState)); + Objects.requireNonNull(initialState, "initialState is null"); + Objects.requireNonNull(generator, "generator is null"); + Objects.requireNonNull(disposeState, "diposeState is null"); + return create(new NbpOnSubscribeGenerate(initialState, generator, disposeState)); } @SchedulerSupport(SchedulerKind.COMPUTATION) @@ -523,8 +558,8 @@ public static NbpObservable interval(long initialDelay, long period, TimeU if (period < 0) { period = 0L; } - Objects.requireNonNull(unit); - Objects.requireNonNull(scheduler); + Objects.requireNonNull(unit, "unit is null"); + Objects.requireNonNull(scheduler, "scheduler is null"); return create(new NbpOnSubscribeIntervalSource(initialDelay, period, unit, scheduler)); } @@ -558,16 +593,18 @@ public static NbpObservable intervalRange(long start, long count, long ini if (period < 0) { period = 0L; } - Objects.requireNonNull(unit); - Objects.requireNonNull(scheduler); + Objects.requireNonNull(unit, "unit is null"); + Objects.requireNonNull(scheduler, "scheduler is null"); return create(new NbpOnSubscribeIntervalRangeSource(start, end, initialDelay, period, unit, scheduler)); } public static NbpObservable just(T value) { - return new NbpObservableScalarSource<>(value); + Objects.requireNonNull(value, "The value is null"); + return new NbpObservableScalarSource(value); } + @SuppressWarnings("unchecked") @SchedulerSupport(SchedulerKind.NONE) public static final NbpObservable just(T v1, T v2) { Objects.requireNonNull(v1, "The first value is null"); @@ -576,6 +613,7 @@ public static final NbpObservable just(T v1, T v2) { return fromArray(v1, v2); } + @SuppressWarnings("unchecked") @SchedulerSupport(SchedulerKind.NONE) public static final NbpObservable just(T v1, T v2, T v3) { Objects.requireNonNull(v1, "The first value is null"); @@ -585,6 +623,7 @@ public static final NbpObservable just(T v1, T v2, T v3) { return fromArray(v1, v2, v3); } + @SuppressWarnings("unchecked") @SchedulerSupport(SchedulerKind.NONE) public static final NbpObservable just(T v1, T v2, T v3, T v4) { Objects.requireNonNull(v1, "The first value is null"); @@ -595,6 +634,7 @@ public static final NbpObservable just(T v1, T v2, T v3, T v4) { return fromArray(v1, v2, v3, v4); } + @SuppressWarnings("unchecked") @SchedulerSupport(SchedulerKind.NONE) public static final NbpObservable just(T v1, T v2, T v3, T v4, T v5) { Objects.requireNonNull(v1, "The first value is null"); @@ -606,6 +646,7 @@ public static final NbpObservable just(T v1, T v2, T v3, T v4, T v5) { return fromArray(v1, v2, v3, v4, v5); } + @SuppressWarnings("unchecked") @SchedulerSupport(SchedulerKind.NONE) public static final NbpObservable just(T v1, T v2, T v3, T v4, T v5, T v6) { Objects.requireNonNull(v1, "The first value is null"); @@ -613,10 +654,12 @@ public static final NbpObservable just(T v1, T v2, T v3, T v4, T v5, T v6 Objects.requireNonNull(v3, "The third value is null"); Objects.requireNonNull(v4, "The fourth value is null"); Objects.requireNonNull(v5, "The fifth value is null"); + Objects.requireNonNull(v6, "The sixth value is null"); return fromArray(v1, v2, v3, v4, v5, v6); } + @SuppressWarnings("unchecked") @SchedulerSupport(SchedulerKind.NONE) public static final NbpObservable just(T v1, T v2, T v3, T v4, T v5, T v6, T v7) { Objects.requireNonNull(v1, "The first value is null"); @@ -630,6 +673,7 @@ public static final NbpObservable just(T v1, T v2, T v3, T v4, T v5, T v6 return fromArray(v1, v2, v3, v4, v5, v6, v7); } + @SuppressWarnings("unchecked") @SchedulerSupport(SchedulerKind.NONE) public static final NbpObservable just(T v1, T v2, T v3, T v4, T v5, T v6, T v7, T v8) { Objects.requireNonNull(v1, "The first value is null"); @@ -644,6 +688,7 @@ public static final NbpObservable just(T v1, T v2, T v3, T v4, T v5, T v6 return fromArray(v1, v2, v3, v4, v5, v6, v7, v8); } + @SuppressWarnings("unchecked") @SchedulerSupport(SchedulerKind.NONE) public static final NbpObservable just(T v1, T v2, T v3, T v4, T v5, T v6, T v7, T v8, T v9) { Objects.requireNonNull(v1, "The first value is null"); @@ -659,89 +704,163 @@ public static final NbpObservable just(T v1, T v2, T v3, T v4, T v5, T v6 return fromArray(v1, v2, v3, v4, v5, v6, v7, v8, v9); } + @SuppressWarnings({ "unchecked", "rawtypes" }) @SchedulerSupport(SchedulerKind.NONE) public static NbpObservable merge(int maxConcurrency, int bufferSize, Iterable> sources) { - return fromIterable(sources).flatMap(v -> v, false, maxConcurrency, bufferSize); + return fromIterable(sources).flatMap((Function)Functions.identity(), false, maxConcurrency, bufferSize); } + @SuppressWarnings({ "unchecked", "rawtypes" }) @SchedulerSupport(SchedulerKind.NONE) - @SafeVarargs public static NbpObservable merge(int maxConcurrency, int bufferSize, NbpObservable... sources) { - return fromArray(sources).flatMap(v -> v, false, maxConcurrency, bufferSize); + return fromArray(sources).flatMap((Function)Functions.identity(), false, maxConcurrency, bufferSize); } + @SuppressWarnings({ "unchecked", "rawtypes" }) @SchedulerSupport(SchedulerKind.NONE) - @SafeVarargs public static NbpObservable merge(int maxConcurrency, NbpObservable... sources) { - return fromArray(sources).flatMap(v -> v, maxConcurrency); + return fromArray(sources).flatMap((Function)Functions.identity(), maxConcurrency); } + @SuppressWarnings({ "unchecked", "rawtypes" }) @SchedulerSupport(SchedulerKind.NONE) public static NbpObservable merge(Iterable> sources) { - return fromIterable(sources).flatMap(v -> v); + return fromIterable(sources).flatMap((Function)Functions.identity()); } + @SuppressWarnings({ "unchecked", "rawtypes" }) @SchedulerSupport(SchedulerKind.NONE) public static NbpObservable merge(Iterable> sources, int maxConcurrency) { - return fromIterable(sources).flatMap(v -> v, maxConcurrency); + return fromIterable(sources).flatMap((Function)Functions.identity(), maxConcurrency); } + @SuppressWarnings({ "unchecked", "rawtypes" }) public static NbpObservable merge(NbpObservable> sources) { - return sources.flatMap(v -> v); + return sources.flatMap((Function)Functions.identity()); } + @SuppressWarnings({ "unchecked", "rawtypes" }) @SchedulerSupport(SchedulerKind.NONE) public static NbpObservable merge(NbpObservable> sources, int maxConcurrency) { - return sources.flatMap(v -> v, maxConcurrency); + return sources.flatMap((Function)Functions.identity(), maxConcurrency); + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @BackpressureSupport(BackpressureKind.FULL) + @SchedulerSupport(SchedulerKind.NONE) + public static NbpObservable merge(NbpObservable p1, NbpObservable p2) { + Objects.requireNonNull(p1, "p1 is null"); + Objects.requireNonNull(p2, "p2 is null"); + return fromArray(p1, p2).flatMap((Function)Functions.identity(), false, 2); + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @BackpressureSupport(BackpressureKind.FULL) + @SchedulerSupport(SchedulerKind.NONE) + public static NbpObservable merge(NbpObservable p1, NbpObservable p2, NbpObservable p3) { + Objects.requireNonNull(p1, "p1 is null"); + Objects.requireNonNull(p2, "p2 is null"); + Objects.requireNonNull(p3, "p3 is null"); + return fromArray(p1, p2, p3).flatMap((Function)Functions.identity(), false, 3); + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @BackpressureSupport(BackpressureKind.FULL) + @SchedulerSupport(SchedulerKind.NONE) + public static NbpObservable merge( + NbpObservable p1, NbpObservable p2, + NbpObservable p3, NbpObservable p4) { + Objects.requireNonNull(p1, "p1 is null"); + Objects.requireNonNull(p2, "p2 is null"); + Objects.requireNonNull(p3, "p3 is null"); + Objects.requireNonNull(p4, "p4 is null"); + return fromArray(p1, p2, p3, p4).flatMap((Function)Functions.identity(), false, 4); } + @SuppressWarnings({ "unchecked", "rawtypes" }) @SchedulerSupport(SchedulerKind.NONE) - @SafeVarargs public static NbpObservable merge(NbpObservable... sources) { - return fromArray(sources).flatMap(v -> v, sources.length); + return fromArray(sources).flatMap((Function)Functions.identity(), sources.length); } + @SuppressWarnings({ "unchecked", "rawtypes" }) @SchedulerSupport(SchedulerKind.NONE) public static NbpObservable mergeDelayError(boolean delayErrors, Iterable> sources) { - return fromIterable(sources).flatMap(v -> v, true); + return fromIterable(sources).flatMap((Function)Functions.identity(), true); } + @SuppressWarnings({ "unchecked", "rawtypes" }) @SchedulerSupport(SchedulerKind.NONE) public static NbpObservable mergeDelayError(int maxConcurrency, int bufferSize, Iterable> sources) { - return fromIterable(sources).flatMap(v -> v, true, maxConcurrency, bufferSize); + return fromIterable(sources).flatMap((Function)Functions.identity(), true, maxConcurrency, bufferSize); } + @SuppressWarnings({ "unchecked", "rawtypes" }) @SchedulerSupport(SchedulerKind.NONE) - @SafeVarargs public static NbpObservable mergeDelayError(int maxConcurrency, int bufferSize, NbpObservable... sources) { - return fromArray(sources).flatMap(v -> v, true, maxConcurrency, bufferSize); + return fromArray(sources).flatMap((Function)Functions.identity(), true, maxConcurrency, bufferSize); } + @SuppressWarnings({ "unchecked", "rawtypes" }) @SchedulerSupport(SchedulerKind.NONE) public static NbpObservable mergeDelayError(int maxConcurrency, Iterable> sources) { - return fromIterable(sources).flatMap(v -> v, true, maxConcurrency); + return fromIterable(sources).flatMap((Function)Functions.identity(), true, maxConcurrency); } + @SuppressWarnings({ "unchecked", "rawtypes" }) @SchedulerSupport(SchedulerKind.NONE) - @SafeVarargs public static NbpObservable mergeDelayError(int maxConcurrency, NbpObservable... sources) { - return fromArray(sources).flatMap(v -> v, true, maxConcurrency); + return fromArray(sources).flatMap((Function)Functions.identity(), true, maxConcurrency); } + @SuppressWarnings({ "unchecked", "rawtypes" }) public static NbpObservable mergeDelayError(NbpObservable> sources) { - return sources.flatMap(v -> v, true); + return sources.flatMap((Function)Functions.identity(), true); } + @SuppressWarnings({ "unchecked", "rawtypes" }) @SchedulerSupport(SchedulerKind.NONE) public static NbpObservable mergeDelayError(NbpObservable> sources, int maxConcurrency) { - return sources.flatMap(v -> v, true, maxConcurrency); + return sources.flatMap((Function)Functions.identity(), true, maxConcurrency); + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @BackpressureSupport(BackpressureKind.FULL) + @SchedulerSupport(SchedulerKind.NONE) + public static NbpObservable mergeDelayError(NbpObservable p1, NbpObservable p2) { + Objects.requireNonNull(p1, "p1 is null"); + Objects.requireNonNull(p2, "p2 is null"); + return fromArray(p1, p2).flatMap((Function)Functions.identity(), true, 2); } + @SuppressWarnings({ "unchecked", "rawtypes" }) + @BackpressureSupport(BackpressureKind.FULL) + @SchedulerSupport(SchedulerKind.NONE) + public static NbpObservable mergeDelayError(NbpObservable p1, NbpObservable p2, NbpObservable p3) { + Objects.requireNonNull(p1, "p1 is null"); + Objects.requireNonNull(p2, "p2 is null"); + Objects.requireNonNull(p3, "p3 is null"); + return fromArray(p1, p2, p3).flatMap((Function)Functions.identity(), true, 3); + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @BackpressureSupport(BackpressureKind.FULL) + @SchedulerSupport(SchedulerKind.NONE) + public static NbpObservable mergeDelayError( + NbpObservable p1, NbpObservable p2, + NbpObservable p3, NbpObservable p4) { + Objects.requireNonNull(p1, "p1 is null"); + Objects.requireNonNull(p2, "p2 is null"); + Objects.requireNonNull(p3, "p3 is null"); + Objects.requireNonNull(p4, "p4 is null"); + return fromArray(p1, p2, p3, p4).flatMap((Function)Functions.identity(), true, 4); + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) @SchedulerSupport(SchedulerKind.NONE) - @SafeVarargs public static NbpObservable mergeDelayError(NbpObservable... sources) { - return fromArray(sources).flatMap(v -> v, true, sources.length); + return fromArray(sources).flatMap((Function)Functions.identity(), true, sources.length); } @SchedulerSupport(SchedulerKind.NONE) @@ -750,7 +869,8 @@ public static NbpObservable never() { return (NbpObservable)NEVER; } - public static NbpObservable range(int start, int count) { + @SchedulerSupport(SchedulerKind.NONE) + public static NbpObservable range(final int start, final int count) { if (count < 0) { throw new IllegalArgumentException("count >= required but it was " + count); } else @@ -763,33 +883,26 @@ public static NbpObservable range(int start, int count) { if ((long)start + (count - 1) > Integer.MAX_VALUE) { throw new IllegalArgumentException("Integer overflow"); } - return create(s -> { - BooleanDisposable d = new BooleanDisposable(); - s.onSubscribe(d); - - long end = start - 1L + count; - for (long i = start; i <= end && !d.isDisposed(); i++) { - s.onNext((int)i); - } - if (!d.isDisposed()) { - s.onComplete(); + return create(new NbpOnSubscribe() { + @Override + public void accept(NbpSubscriber s) { + BooleanDisposable d = new BooleanDisposable(); + s.onSubscribe(d); + + long end = start - 1L + count; + for (long i = start; i <= end && !d.isDisposed(); i++) { + s.onNext((int)i); + } + if (!d.isDisposed()) { + s.onComplete(); + } } }); } - /** - * - * @deprecated use composition - */ - @SchedulerSupport(SchedulerKind.CUSTOM) - @Deprecated - public static NbpObservable range(int start, int count, Scheduler scheduler) { - return range(start, count).subscribeOn(scheduler); - } - @SchedulerSupport(SchedulerKind.NONE) public static NbpObservable sequenceEqual(NbpObservable p1, NbpObservable p2) { - return sequenceEqual(p1, p2, Objects::equals, bufferSize()); + return sequenceEqual(p1, p2, Objects.equalsPredicate(), bufferSize()); } @SchedulerSupport(SchedulerKind.NONE) @@ -799,27 +912,29 @@ public static NbpObservable sequenceEqual(NbpObservable NbpObservable sequenceEqual(NbpObservable p1, NbpObservable p2, BiPredicate isEqual, int bufferSize) { - Objects.requireNonNull(p1); - Objects.requireNonNull(p2); - Objects.requireNonNull(isEqual); + Objects.requireNonNull(p1, "p1 is null"); + Objects.requireNonNull(p2, "p2 is null"); + Objects.requireNonNull(isEqual, "isEqual is null"); validateBufferSize(bufferSize); - return create(new NbpOnSubscribeSequenceEqual<>(p1, p2, isEqual, bufferSize)); + return create(new NbpOnSubscribeSequenceEqual(p1, p2, isEqual, bufferSize)); } @SchedulerSupport(SchedulerKind.NONE) public static NbpObservable sequenceEqual(NbpObservable p1, NbpObservable p2, int bufferSize) { - return sequenceEqual(p1, p2, Objects::equals, bufferSize); + return sequenceEqual(p1, p2, Objects.equalsPredicate(), bufferSize); } + @SuppressWarnings({ "rawtypes", "unchecked" }) @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static NbpObservable switchOnNext(int bufferSize, NbpObservable> sources) { - return sources.switchMap(v -> v, bufferSize); + return sources.switchMap((Function)Functions.identity(), bufferSize); } + @SuppressWarnings({ "rawtypes", "unchecked" }) @SchedulerSupport(SchedulerKind.NONE) public static NbpObservable switchOnNext(NbpObservable> sources) { - return sources.switchMap(v -> v); + return sources.switchMap((Function)Functions.identity()); } @SchedulerSupport(SchedulerKind.COMPUTATION) @@ -832,23 +947,12 @@ public static NbpObservable timer(long delay, TimeUnit unit, Scheduler sch if (delay < 0) { delay = 0L; } - Objects.requireNonNull(unit); - Objects.requireNonNull(scheduler); + Objects.requireNonNull(unit, "unit is null"); + Objects.requireNonNull(scheduler, "scheduler is null"); return create(new NbpOnSubscribeTimerOnceSource(delay, unit, scheduler)); } - @SuppressWarnings("unchecked") - private static Function toFunction(BiFunction biFunction) { - Objects.requireNonNull(biFunction); - return a -> { - if (a.length != 2) { - throw new IllegalArgumentException("Array of size 2 expected but got " + a.length); - } - return ((BiFunction)biFunction).apply(a[0], a[1]); - }; - } - @SchedulerSupport(SchedulerKind.NONE) public static NbpObservable using(Supplier resourceSupplier, Function> sourceSupplier, Consumer disposer) { return using(resourceSupplier, sourceSupplier, disposer, true); @@ -856,10 +960,10 @@ public static NbpObservable using(Supplier resourceSuppli @SchedulerSupport(SchedulerKind.NONE) public static NbpObservable using(Supplier resourceSupplier, Function> sourceSupplier, Consumer disposer, boolean eager) { - Objects.requireNonNull(resourceSupplier); - Objects.requireNonNull(sourceSupplier); - Objects.requireNonNull(disposer); - return create(new NbpOnSubscribeUsing<>(resourceSupplier, sourceSupplier, disposer, eager)); + Objects.requireNonNull(resourceSupplier, "resourceSupplier is null"); + Objects.requireNonNull(sourceSupplier, "sourceSupplier is null"); + Objects.requireNonNull(disposer, "disposer is null"); + return create(new NbpOnSubscribeUsing(resourceSupplier, sourceSupplier, disposer, eager)); } private static void validateBufferSize(int bufferSize) { @@ -870,117 +974,130 @@ private static void validateBufferSize(int bufferSize) { @SchedulerSupport(SchedulerKind.NONE) public static NbpObservable zip(Iterable> sources, Function zipper) { - Objects.requireNonNull(zipper); - Objects.requireNonNull(sources); - return create(new NbpOnSubscribeZip<>(null, sources, zipper, bufferSize(), false)); + Objects.requireNonNull(zipper, "zipper is null"); + Objects.requireNonNull(sources, "sources is null"); + return create(new NbpOnSubscribeZip(null, sources, zipper, bufferSize(), false)); } @SchedulerSupport(SchedulerKind.NONE) - public static NbpObservable zip(NbpObservable> sources, Function zipper) { - return sources.toList().flatMap(list -> { - return zipIterable(zipper, false, bufferSize(), list); + public static NbpObservable zip(NbpObservable> sources, final Function zipper) { + Objects.requireNonNull(zipper, "zipper is null"); + return sources.toList().flatMap(new Function>, NbpObservable>() { + @Override + public NbpObservable apply(List> list) { + return zipIterable(zipper, false, bufferSize(), list); + } }); } + @SuppressWarnings("unchecked") @SchedulerSupport(SchedulerKind.NONE) public static NbpObservable zip( NbpObservable p1, NbpObservable p2, BiFunction zipper) { - return zipArray(toFunction(zipper), false, bufferSize(), p1, p2); + return zipArray(Functions.toFunction(zipper), false, bufferSize(), p1, p2); } + @SuppressWarnings("unchecked") @SchedulerSupport(SchedulerKind.NONE) public static NbpObservable zip( NbpObservable p1, NbpObservable p2, BiFunction zipper, boolean delayError) { - return zipArray(toFunction(zipper), delayError, bufferSize(), p1, p2); + return zipArray(Functions.toFunction(zipper), delayError, bufferSize(), p1, p2); } + @SuppressWarnings("unchecked") @SchedulerSupport(SchedulerKind.NONE) public static NbpObservable zip( NbpObservable p1, NbpObservable p2, BiFunction zipper, boolean delayError, int bufferSize) { - return zipArray(toFunction(zipper), delayError, bufferSize, p1, p2); + return zipArray(Functions.toFunction(zipper), delayError, bufferSize, p1, p2); } + @SuppressWarnings("unchecked") @SchedulerSupport(SchedulerKind.NONE) public static NbpObservable zip( NbpObservable p1, NbpObservable p2, NbpObservable p3, Function3 zipper) { - return zipArray(zipper, false, bufferSize(), p1, p2, p3); + return zipArray(Functions.toFunction(zipper), false, bufferSize(), p1, p2, p3); } + @SuppressWarnings("unchecked") @SchedulerSupport(SchedulerKind.NONE) public static NbpObservable zip( NbpObservable p1, NbpObservable p2, NbpObservable p3, NbpObservable p4, Function4 zipper) { - return zipArray(zipper, false, bufferSize(), p1, p2, p3, p4); + return zipArray(Functions.toFunction(zipper), false, bufferSize(), p1, p2, p3, p4); } + @SuppressWarnings("unchecked") @SchedulerSupport(SchedulerKind.NONE) public static NbpObservable zip( NbpObservable p1, NbpObservable p2, NbpObservable p3, NbpObservable p4, NbpObservable p5, Function5 zipper) { - return zipArray(zipper, false, bufferSize(), p1, p2, p3, p4, p5); + return zipArray(Functions.toFunction(zipper), false, bufferSize(), p1, p2, p3, p4, p5); } + @SuppressWarnings("unchecked") @SchedulerSupport(SchedulerKind.NONE) public static NbpObservable zip( NbpObservable p1, NbpObservable p2, NbpObservable p3, NbpObservable p4, NbpObservable p5, NbpObservable p6, Function6 zipper) { - return zipArray(zipper, false, bufferSize(), p1, p2, p3, p4, p5, p6); + return zipArray(Functions.toFunction(zipper), false, bufferSize(), p1, p2, p3, p4, p5, p6); } + @SuppressWarnings("unchecked") @SchedulerSupport(SchedulerKind.NONE) public static NbpObservable zip( NbpObservable p1, NbpObservable p2, NbpObservable p3, NbpObservable p4, NbpObservable p5, NbpObservable p6, NbpObservable p7, Function7 zipper) { - return zipArray(zipper, false, bufferSize(), p1, p2, p3, p4, p5, p6, p7); + return zipArray(Functions.toFunction(zipper), false, bufferSize(), p1, p2, p3, p4, p5, p6, p7); } + @SuppressWarnings("unchecked") @SchedulerSupport(SchedulerKind.NONE) public static NbpObservable zip( NbpObservable p1, NbpObservable p2, NbpObservable p3, NbpObservable p4, NbpObservable p5, NbpObservable p6, NbpObservable p7, NbpObservable p8, Function8 zipper) { - return zipArray(zipper, false, bufferSize(), p1, p2, p3, p4, p5, p6, p7, p8); + return zipArray(Functions.toFunction(zipper), false, bufferSize(), p1, p2, p3, p4, p5, p6, p7, p8); } + @SuppressWarnings("unchecked") @SchedulerSupport(SchedulerKind.NONE) public static NbpObservable zip( NbpObservable p1, NbpObservable p2, NbpObservable p3, NbpObservable p4, NbpObservable p5, NbpObservable p6, NbpObservable p7, NbpObservable p8, NbpObservable p9, Function9 zipper) { - return zipArray(zipper, false, bufferSize(), p1, p2, p3, p4, p5, p6, p7, p8, p9); + return zipArray(Functions.toFunction(zipper), false, bufferSize(), p1, p2, p3, p4, p5, p6, p7, p8, p9); } @SchedulerSupport(SchedulerKind.NONE) - @SafeVarargs public static NbpObservable zipArray(Function zipper, boolean delayError, int bufferSize, NbpObservable... sources) { if (sources.length == 0) { return empty(); } - Objects.requireNonNull(zipper); + Objects.requireNonNull(zipper, "zipper is null"); validateBufferSize(bufferSize); - return create(new NbpOnSubscribeZip<>(sources, null, zipper, bufferSize, delayError)); + return create(new NbpOnSubscribeZip(sources, null, zipper, bufferSize, delayError)); } @SchedulerSupport(SchedulerKind.NONE) public static NbpObservable zipIterable(Function zipper, boolean delayError, int bufferSize, Iterable> sources) { - Objects.requireNonNull(zipper); - Objects.requireNonNull(sources); + Objects.requireNonNull(zipper, "zipper is null"); + Objects.requireNonNull(sources, "sources is null"); validateBufferSize(bufferSize); - return create(new NbpOnSubscribeZip<>(null, sources, zipper, bufferSize, delayError)); + return create(new NbpOnSubscribeZip(null, sources, zipper, bufferSize, delayError)); } @@ -992,24 +1109,31 @@ protected NbpObservable(NbpOnSubscribe onSubscribe) { @SchedulerSupport(SchedulerKind.NONE) public final NbpObservable all(Predicate predicate) { - Objects.requireNonNull(predicate); - return lift(new NbpOperatorAll<>(predicate)); + Objects.requireNonNull(predicate, "predicate is null"); + return lift(new NbpOperatorAll(predicate)); } + @SuppressWarnings("unchecked") @SchedulerSupport(SchedulerKind.NONE) public final NbpObservable ambWith(NbpObservable other) { + Objects.requireNonNull(other, "other is null"); return amb(this, other); } @SchedulerSupport(SchedulerKind.NONE) public final NbpObservable any(Predicate predicate) { - Objects.requireNonNull(predicate); - return lift(new NbpOperatorAny<>(predicate)); + Objects.requireNonNull(predicate, "predicate is null"); + return lift(new NbpOperatorAny(predicate)); } @SchedulerSupport(SchedulerKind.NONE) public final NbpObservable asObservable() { - return create(s -> this.subscribe(s)); + return create(new NbpOnSubscribe() { + @Override + public void accept(NbpSubscriber s) { + NbpObservable.this.subscribe(s); + } + }); } @SchedulerSupport(SchedulerKind.NONE) @@ -1019,7 +1143,12 @@ public final NbpObservable> buffer(int count) { @SchedulerSupport(SchedulerKind.NONE) public final NbpObservable> buffer(int count, int skip) { - return buffer(count, skip, ArrayList::new); + return buffer(count, skip, new Supplier>() { + @Override + public List get() { + return new ArrayList(); + } + }); } @SchedulerSupport(SchedulerKind.NONE) @@ -1030,8 +1159,8 @@ public final > NbpObservable buffer(int count if (skip <= 0) { throw new IllegalArgumentException("skip > 0 required but it was " + count); } - Objects.requireNonNull(bufferSupplier); - return lift(new NbpOperatorBuffer<>(count, skip, bufferSupplier)); + Objects.requireNonNull(bufferSupplier, "bufferSupplier is null"); + return lift(new NbpOperatorBuffer(count, skip, bufferSupplier)); } @SchedulerSupport(SchedulerKind.NONE) @@ -1041,20 +1170,30 @@ public final > NbpObservable buffer(int count @SchedulerSupport(SchedulerKind.COMPUTATION) public final NbpObservable> buffer(long timespan, long timeskip, TimeUnit unit) { - return buffer(timespan, timeskip, unit, Schedulers.computation(), ArrayList::new); + return buffer(timespan, timeskip, unit, Schedulers.computation(), new Supplier>() { + @Override + public List get() { + return new ArrayList(); + } + }); } @SchedulerSupport(SchedulerKind.CUSTOM) public final NbpObservable> buffer(long timespan, long timeskip, TimeUnit unit, Scheduler scheduler) { - return buffer(timespan, timeskip, unit, scheduler, ArrayList::new); + return buffer(timespan, timeskip, unit, scheduler, new Supplier>() { + @Override + public List get() { + return new ArrayList(); + } + }); } @SchedulerSupport(SchedulerKind.CUSTOM) public final > NbpObservable buffer(long timespan, long timeskip, TimeUnit unit, Scheduler scheduler, Supplier bufferSupplier) { - Objects.requireNonNull(unit); - Objects.requireNonNull(scheduler); - Objects.requireNonNull(bufferSupplier); - return lift(new NbpOperatorBufferTimed<>(timespan, timeskip, unit, scheduler, bufferSupplier, Integer.MAX_VALUE, false)); + Objects.requireNonNull(unit, "unit is null"); + Objects.requireNonNull(scheduler, "scheduler is null"); + Objects.requireNonNull(bufferSupplier, "bufferSupplier is null"); + return lift(new NbpOperatorBufferTimed(timespan, timeskip, unit, scheduler, bufferSupplier, Integer.MAX_VALUE, false)); } @SchedulerSupport(SchedulerKind.COMPUTATION) @@ -1069,7 +1208,12 @@ public final NbpObservable> buffer(long timespan, TimeUnit unit, int cou @SchedulerSupport(SchedulerKind.CUSTOM) public final NbpObservable> buffer(long timespan, TimeUnit unit, int count, Scheduler scheduler) { - return buffer(timespan, unit, count, scheduler, ArrayList::new, false); + return buffer(timespan, unit, count, scheduler, new Supplier>() { + @Override + public List get() { + return new ArrayList(); + } + }, false); } @SchedulerSupport(SchedulerKind.CUSTOM) @@ -1078,25 +1222,35 @@ public final > NbpObservable buffer( int count, Scheduler scheduler, Supplier bufferSupplier, boolean restartTimerOnMaxSize) { - Objects.requireNonNull(unit); - Objects.requireNonNull(scheduler); - Objects.requireNonNull(bufferSupplier); + Objects.requireNonNull(unit, "unit is null"); + Objects.requireNonNull(scheduler, "scheduler is null"); + Objects.requireNonNull(bufferSupplier, "bufferSupplier is null"); if (count <= 0) { throw new IllegalArgumentException("count > 0 required but it was " + count); } - return lift(new NbpOperatorBufferTimed<>(timespan, timespan, unit, scheduler, bufferSupplier, count, restartTimerOnMaxSize)); + return lift(new NbpOperatorBufferTimed(timespan, timespan, unit, scheduler, bufferSupplier, count, restartTimerOnMaxSize)); } @SchedulerSupport(SchedulerKind.CUSTOM) public final NbpObservable> buffer(long timespan, TimeUnit unit, Scheduler scheduler) { - return buffer(timespan, unit, Integer.MAX_VALUE, scheduler, ArrayList::new, false); + return buffer(timespan, unit, Integer.MAX_VALUE, scheduler, new Supplier>() { + @Override + public List get() { + return new ArrayList(); + } + }, false); } @SchedulerSupport(SchedulerKind.NONE) public final NbpObservable> buffer( NbpObservable bufferOpenings, Function> bufferClosingSelector) { - return buffer(bufferOpenings, bufferClosingSelector, ArrayList::new); + return buffer(bufferOpenings, bufferClosingSelector, new Supplier>() { + @Override + public List get() { + return new ArrayList(); + } + }); } @SchedulerSupport(SchedulerKind.NONE) @@ -1104,10 +1258,10 @@ public final > NbpObservable NbpObservable bufferOpenings, Function> bufferClosingSelector, Supplier bufferSupplier) { - Objects.requireNonNull(bufferOpenings); - Objects.requireNonNull(bufferClosingSelector); - Objects.requireNonNull(bufferSupplier); - return lift(new NbpOperatorBufferBoundary<>(bufferOpenings, bufferClosingSelector, bufferSupplier)); + Objects.requireNonNull(bufferOpenings, "bufferOpenings is null"); + Objects.requireNonNull(bufferClosingSelector, "bufferClosingSelector is null"); + Objects.requireNonNull(bufferSupplier, "bufferSupplier is null"); + return lift(new NbpOperatorBufferBoundary(bufferOpenings, bufferClosingSelector, bufferSupplier)); } @SchedulerSupport(SchedulerKind.NONE) @@ -1115,32 +1269,47 @@ public final NbpObservable> buffer(NbpObservable boundary) { /* * XXX: javac complains if this is not manually cast, Eclipse is fine */ - return buffer(boundary, (Supplier>)ArrayList::new); + return buffer(boundary, new Supplier>() { + @Override + public List get() { + return new ArrayList(); + } + }); } @SchedulerSupport(SchedulerKind.NONE) - public final NbpObservable> buffer(NbpObservable boundary, int initialCapacity) { - return buffer(boundary, () -> new ArrayList<>(initialCapacity)); + public final NbpObservable> buffer(NbpObservable boundary, final int initialCapacity) { + return buffer(boundary, new Supplier>() { + @Override + public List get() { + return new ArrayList(initialCapacity); + } + }); } @SchedulerSupport(SchedulerKind.NONE) public final > NbpObservable buffer(NbpObservable boundary, Supplier bufferSupplier) { - Objects.requireNonNull(boundary); - Objects.requireNonNull(bufferSupplier); - return lift(new NbpOperatorBufferExactBoundary<>(boundary, bufferSupplier)); + Objects.requireNonNull(boundary, "boundary is null"); + Objects.requireNonNull(bufferSupplier, "bufferSupplier is null"); + return lift(new NbpOperatorBufferExactBoundary(boundary, bufferSupplier)); } @SchedulerSupport(SchedulerKind.NONE) public final NbpObservable> buffer(Supplier> boundarySupplier) { - return buffer(boundarySupplier, ArrayList::new); + return buffer(boundarySupplier, new Supplier>() { + @Override + public List get() { + return new ArrayList(); + } + }); } @SchedulerSupport(SchedulerKind.NONE) public final > NbpObservable buffer(Supplier> boundarySupplier, Supplier bufferSupplier) { - Objects.requireNonNull(boundarySupplier); - Objects.requireNonNull(bufferSupplier); - return lift(new NbpOperatorBufferBoundarySupplier<>(boundarySupplier, bufferSupplier)); + Objects.requireNonNull(boundarySupplier, "boundarySupplier is null"); + Objects.requireNonNull(bufferSupplier, "bufferSupplier is null"); + return lift(new NbpOperatorBufferBoundarySupplier(boundarySupplier, bufferSupplier)); } @SchedulerSupport(SchedulerKind.NONE) @@ -1154,20 +1323,32 @@ public final NbpObservable cache(int capacityHint) { } @SchedulerSupport(SchedulerKind.NONE) - public final NbpObservable cast(Class clazz) { - return map(clazz::cast); + public final NbpObservable cast(final Class clazz) { + Objects.requireNonNull(clazz, "clazz is null"); + return map(new Function() { + @Override + public U apply(T v) { + return clazz.cast(v); + } + }); } @SchedulerSupport(SchedulerKind.NONE) public final NbpObservable collect(Supplier initialValueSupplier, BiConsumer collector) { - Objects.requireNonNull(initialValueSupplier); - Objects.requireNonNull(collector); - return lift(new NbpOperatorCollect<>(initialValueSupplier, collector)); + Objects.requireNonNull(initialValueSupplier, "initalValueSupplier is null"); + Objects.requireNonNull(collector, "collector is null"); + return lift(new NbpOperatorCollect(initialValueSupplier, collector)); } @SchedulerSupport(SchedulerKind.NONE) - public final NbpObservable collectInto(U initialValue, BiConsumer collector) { - return collect(() -> initialValue, collector); + public final NbpObservable collectInto(final U initialValue, BiConsumer collector) { + Objects.requireNonNull(initialValue, "initialValue is null"); + return collect(new Supplier() { + @Override + public U get() { + return initialValue; + } + }, collector); } public final NbpObservable compose(Function, ? extends NbpObservable> convert) { @@ -1181,33 +1362,49 @@ public final NbpObservable concatMap(Function NbpObservable concatMap(Function> mapper, int prefetch) { - Objects.requireNonNull(mapper); + Objects.requireNonNull(mapper, "mapper is null"); if (prefetch <= 0) { throw new IllegalArgumentException("prefetch > 0 required but it was " + prefetch); } - return lift(new NbpOperatorConcatMap<>(mapper, prefetch)); + return lift(new NbpOperatorConcatMap(mapper, prefetch)); } @SchedulerSupport(SchedulerKind.NONE) - public final NbpObservable concatMapIterable(Function> mapper) { - return concatMap(v -> fromIterable(mapper.apply(v))); + public final NbpObservable concatMapIterable(final Function> mapper) { + Objects.requireNonNull(mapper, "mapper is null"); + return concatMap(new Function>() { + @Override + public NbpObservable apply(T v) { + return fromIterable(mapper.apply(v)); + } + }); } @SchedulerSupport(SchedulerKind.NONE) - public final NbpObservable concatMapIterable(Function> mapper, int prefetch) { - return concatMap(v -> fromIterable(mapper.apply(v)), prefetch); + public final NbpObservable concatMapIterable(final Function> mapper, int prefetch) { + return concatMap(new Function>() { + @Override + public NbpObservable apply(T v) { + return fromIterable(mapper.apply(v)); + } + }, prefetch); } @SchedulerSupport(SchedulerKind.NONE) public final NbpObservable concatWith(NbpObservable other) { - Objects.requireNonNull(other); + Objects.requireNonNull(other, "other is null"); return concat(this, other); } @SchedulerSupport(SchedulerKind.NONE) - public final NbpObservable contains(Object o) { - Objects.requireNonNull(o); - return any(v -> Objects.equals(v, o)); + public final NbpObservable contains(final Object o) { + Objects.requireNonNull(o, "o is null"); + return any(new Predicate() { + @Override + public boolean test(T v) { + return Objects.equals(v, o); + } + }); } @SchedulerSupport(SchedulerKind.NONE) @@ -1217,8 +1414,8 @@ public final NbpObservable count() { @SchedulerSupport(SchedulerKind.NONE) public final NbpObservable debounce(Function> debounceSelector) { - Objects.requireNonNull(debounceSelector); - return lift(new NbpOperatorDebounce<>(debounceSelector)); + Objects.requireNonNull(debounceSelector, "debounceSelector is null"); + return lift(new NbpOperatorDebounce(debounceSelector)); } @SchedulerSupport(SchedulerKind.COMPUTATION) @@ -1229,22 +1426,32 @@ public final NbpObservable debounce(long timeout, TimeUnit unit) { @BackpressureSupport(BackpressureKind.ERROR) @SchedulerSupport(SchedulerKind.CUSTOM) public final NbpObservable debounce(long timeout, TimeUnit unit, Scheduler scheduler) { - Objects.requireNonNull(unit); - Objects.requireNonNull(scheduler); - return lift(new NbpOperatorDebounceTimed<>(timeout, unit, scheduler)); + Objects.requireNonNull(unit, "unit is null"); + Objects.requireNonNull(scheduler, "scheduler is null"); + return lift(new NbpOperatorDebounceTimed(timeout, unit, scheduler)); } @SchedulerSupport(SchedulerKind.NONE) public final NbpObservable defaultIfEmpty(T value) { - Objects.requireNonNull(value); + Objects.requireNonNull(value, "value is null"); return switchIfEmpty(just(value)); } @SchedulerSupport(SchedulerKind.NONE) // TODO a more efficient implementation if necessary - public final NbpObservable delay(Function> itemDelay) { - Objects.requireNonNull(itemDelay); - return flatMap(v -> itemDelay.apply(v).take(1).map(u -> v).defaultIfEmpty(v)); + public final NbpObservable delay(final Function> itemDelay) { + Objects.requireNonNull(itemDelay, "itemDelay is null"); + return flatMap(new Function>() { + @Override + public NbpObservable apply(final T v) { + return itemDelay.apply(v).take(1).map(new Function() { + @Override + public T apply(U u) { + return v; + } + }).defaultIfEmpty(v); + } + }); } @SchedulerSupport(SchedulerKind.COMPUTATION) @@ -1264,10 +1471,10 @@ public final NbpObservable delay(long delay, TimeUnit unit, Scheduler schedul @SchedulerSupport(SchedulerKind.CUSTOM) public final NbpObservable delay(long delay, TimeUnit unit, Scheduler scheduler, boolean delayError) { - Objects.requireNonNull(unit); - Objects.requireNonNull(scheduler); + Objects.requireNonNull(unit, "unit is null"); + Objects.requireNonNull(scheduler, "scheduler is null"); - return lift(new NbpOperatorDelay<>(delay, unit, scheduler, delayError)); + return lift(new NbpOperatorDelay(delay, unit, scheduler, delayError)); } @SchedulerSupport(SchedulerKind.NONE) @@ -1276,6 +1483,30 @@ public final NbpObservable delay(Supplier> return delaySubscription(delaySupplier).delay(itemDelay); } + /** + * Returns an Observable that delays the subscription to this Observable + * until the other Observable emits an element or completes normally. + *

+ *

+ *
Backpressure:
+ *
The operator forwards the backpressure requests to this Observable once + * the subscription happens and requests Long.MAX_VALUE from the other Observable
+ *
Scheduler:
+ *
This method does not operate by default on a particular {@link Scheduler}.
+ *
+ * + * @param the value type of the other Observable, irrelevant + * @param other the other Observable that should trigger the subscription + * to this Observable. + * @return an Observable that delays the subscription to this Observable + * until the other Observable emits an element or completes normally. + */ + @Experimental + public final NbpObservable delaySubscription(NbpObservable other) { + Objects.requireNonNull(other, "other is null"); + return create(new NbpOnSubscribeDelaySubscriptionOther(this, other)); + } + @SchedulerSupport(SchedulerKind.COMPUTATION) public final NbpObservable delaySubscription(long delay, TimeUnit unit) { return delaySubscription(delay, unit, Schedulers.computation()); @@ -1284,124 +1515,194 @@ public final NbpObservable delaySubscription(long delay, TimeUnit unit) { @SchedulerSupport(SchedulerKind.CUSTOM) // TODO a more efficient implementation if necessary public final NbpObservable delaySubscription(long delay, TimeUnit unit, Scheduler scheduler) { - Objects.requireNonNull(unit); - Objects.requireNonNull(scheduler); + Objects.requireNonNull(unit, "unit is null"); + Objects.requireNonNull(scheduler, "scheduler is null"); - return timer(delay, unit, scheduler).flatMap(v -> this); + return timer(delay, unit, scheduler).flatMap(new Function>() { + @Override + public NbpObservable apply(Long v) { + return NbpObservable.this; + } + }); } + @SuppressWarnings({ "unchecked", "rawtypes" }) @SchedulerSupport(SchedulerKind.NONE) - public final NbpObservable delaySubscription(Supplier> delaySupplier) { - return fromCallable(delaySupplier::get).flatMap(v -> v).take(1).cast(Object.class).defaultIfEmpty(OBJECT).flatMap(v -> this); + public final NbpObservable delaySubscription(final Supplier> delaySupplier) { + Objects.requireNonNull(delaySupplier, "delaySupplier is null"); + return fromCallable(new Callable>() { + @Override + public NbpObservable call() throws Exception { + return delaySupplier.get(); + } + }) + .flatMap((Function)Functions.identity()) + .take(1) + .cast(Object.class) + .defaultIfEmpty(OBJECT) + .flatMap(new Function>() { + @Override + public NbpObservable apply(Object v) { + return NbpObservable.this; + } + }); } @SchedulerSupport(SchedulerKind.NONE) public final NbpObservable dematerialize() { @SuppressWarnings("unchecked") NbpObservable>> m = (NbpObservable>>)this; - return m.lift(NbpOperatorDematerialize.instance()); + return m.lift(NbpOperatorDematerialize.instance()); } + @SuppressWarnings({ "rawtypes", "unchecked" }) @SchedulerSupport(SchedulerKind.NONE) public final NbpObservable distinct() { - return distinct(v -> v, HashSet::new); + return distinct((Function)Functions.identity(), new Supplier>() { + @Override + public Collection get() { + return new HashSet(); + } + }); } @SchedulerSupport(SchedulerKind.NONE) public final NbpObservable distinct(Function keySelector) { - return distinct(keySelector, HashSet::new); + return distinct(keySelector, new Supplier>() { + @Override + public Collection get() { + return new HashSet(); + } + }); } @SchedulerSupport(SchedulerKind.NONE) public final NbpObservable distinct(Function keySelector, Supplier> collectionSupplier) { + Objects.requireNonNull(keySelector, "keySelector is null"); + Objects.requireNonNull(collectionSupplier, "collectionSupplier is null"); return lift(NbpOperatorDistinct.withCollection(keySelector, collectionSupplier)); } @SchedulerSupport(SchedulerKind.NONE) public final NbpObservable distinctUntilChanged() { - return lift(NbpOperatorDistinct.untilChanged()); + return lift(NbpOperatorDistinct.untilChanged()); } @SchedulerSupport(SchedulerKind.NONE) public final NbpObservable distinctUntilChanged(Function keySelector) { + Objects.requireNonNull(keySelector, "keySelector is null"); return lift(NbpOperatorDistinct.untilChanged(keySelector)); } @SchedulerSupport(SchedulerKind.NONE) public final NbpObservable doOnCancel(Runnable onCancel) { - return doOnLifecycle(s -> { }, onCancel); + return doOnLifecycle(Functions.emptyConsumer(), onCancel); } @SchedulerSupport(SchedulerKind.NONE) public final NbpObservable doOnComplete(Runnable onComplete) { - return doOnEach(v -> { }, e -> { }, onComplete, () -> { }); + return doOnEach(Functions.emptyConsumer(), Functions.emptyConsumer(), onComplete, Functions.emptyRunnable()); } @SchedulerSupport(SchedulerKind.NONE) private NbpObservable doOnEach(Consumer onNext, Consumer onError, Runnable onComplete, Runnable onAfterTerminate) { - Objects.requireNonNull(onNext); - Objects.requireNonNull(onError); - Objects.requireNonNull(onComplete); - Objects.requireNonNull(onAfterTerminate); - return lift(new NbpOperatorDoOnEach<>(onNext, onError, onComplete, onAfterTerminate)); + Objects.requireNonNull(onNext, "onNext is null"); + Objects.requireNonNull(onError, "onError is null"); + Objects.requireNonNull(onComplete, "onComplete is null"); + Objects.requireNonNull(onAfterTerminate, "onAfterTerminate is null"); + return lift(new NbpOperatorDoOnEach(onNext, onError, onComplete, onAfterTerminate)); } @SchedulerSupport(SchedulerKind.NONE) - public final NbpObservable doOnEach(Consumer>> consumer) { + public final NbpObservable doOnEach(final Consumer>> consumer) { + Objects.requireNonNull(consumer, "consumer is null"); return doOnEach( - v -> consumer.accept(Try.ofValue(Optional.of(v))), - e -> consumer.accept(Try.ofError(e)), - () -> consumer.accept(Try.ofValue(Optional.empty())), - () -> { } + new Consumer() { + @Override + public void accept(T v) { + consumer.accept(Try.ofValue(Optional.of(v))); + } + }, + new Consumer() { + @Override + public void accept(Throwable e) { + consumer.accept(Try.>ofError(e)); + } + }, + new Runnable() { + @Override + public void run() { + consumer.accept(Try.ofValue(Optional.empty())); + } + }, + Functions.emptyRunnable() ); } @SchedulerSupport(SchedulerKind.NONE) - public final NbpObservable doOnEach(NbpSubscriber observer) { - return doOnEach(observer::onNext, observer::onError, observer::onComplete, () -> { }); + public final NbpObservable doOnEach(final NbpSubscriber observer) { + Objects.requireNonNull(observer, "observer is null"); + return doOnEach(new Consumer() { + @Override + public void accept(T v) { + observer.onNext(v); + } + }, new Consumer() { + @Override + public void accept(Throwable e) { + observer.onError(e); + } + }, new Runnable() { + @Override + public void run() { + observer.onComplete(); + } + }, Functions.emptyRunnable()); } @SchedulerSupport(SchedulerKind.NONE) public final NbpObservable doOnError(Consumer onError) { - return doOnEach(v -> { }, onError, () -> { }, () -> { }); + return doOnEach(Functions.emptyConsumer(), onError, Functions.emptyRunnable(), Functions.emptyRunnable()); } @SchedulerSupport(SchedulerKind.NONE) - public final NbpObservable doOnLifecycle(Consumer onSubscribe, Runnable onCancel) { - return lift(s -> new NbpSubscriptionLambdaSubscriber<>(s, onSubscribe, onCancel)); + public final NbpObservable doOnLifecycle(final Consumer onSubscribe, final Runnable onCancel) { + Objects.requireNonNull(onSubscribe, "onSubscribe is null"); + Objects.requireNonNull(onCancel, "onCancel is null"); + return lift(new NbpOperator() { + @Override + public NbpSubscriber apply(NbpSubscriber s) { + return new NbpSubscriptionLambdaSubscriber(s, onSubscribe, onCancel); + } + }); } @SchedulerSupport(SchedulerKind.NONE) public final NbpObservable doOnNext(Consumer onNext) { - return doOnEach(onNext, e -> { }, () -> { }, () -> { }); + return doOnEach(onNext, Functions.emptyConsumer(), Functions.emptyRunnable(), Functions.emptyRunnable()); } @SchedulerSupport(SchedulerKind.NONE) public final NbpObservable doOnSubscribe(Consumer onSubscribe) { - return doOnLifecycle(onSubscribe, () -> { }); + return doOnLifecycle(onSubscribe, Functions.emptyRunnable()); } @SchedulerSupport(SchedulerKind.NONE) - public final NbpObservable doOnTerminate(Runnable onTerminate) { - return doOnEach(v -> { }, e -> onTerminate.run(), onTerminate, () -> { }); + public final NbpObservable doOnTerminate(final Runnable onTerminate) { + return doOnEach(Functions.emptyConsumer(), new Consumer() { + @Override + public void accept(Throwable e) { + onTerminate.run(); + } + }, onTerminate, Functions.emptyRunnable()); } - /** - * - * @deprecated use {@link #doOnCancel(Runnable)} instead - */ - @SchedulerSupport(SchedulerKind.NONE) - @Deprecated - public final NbpObservable doOnUnsubscribe(Runnable onUnsubscribe) { - return doOnCancel(onUnsubscribe); - } - @SchedulerSupport(SchedulerKind.NONE) public final NbpObservable elementAt(long index) { if (index < 0) { throw new IndexOutOfBoundsException("index >= 0 required but it was " + index); } - return lift(new NbpOperatorElementAt<>(index, null)); + return lift(new NbpOperatorElementAt(index, null)); } @SchedulerSupport(SchedulerKind.NONE) @@ -1409,29 +1710,32 @@ public final NbpObservable elementAt(long index, T defaultValue) { if (index < 0) { throw new IndexOutOfBoundsException("index >= 0 required but it was " + index); } - Objects.requireNonNull(defaultValue); - return lift(new NbpOperatorElementAt<>(index, defaultValue)); + Objects.requireNonNull(defaultValue, "defaultValue is null"); + return lift(new NbpOperatorElementAt(index, defaultValue)); } + @SuppressWarnings("unchecked") @SchedulerSupport(SchedulerKind.NONE) public final NbpObservable endWith(Iterable values) { return concatArray(this, fromIterable(values)); } + @SuppressWarnings("unchecked") @SchedulerSupport(SchedulerKind.NONE) public final NbpObservable endWith(NbpObservable other) { - Objects.requireNonNull(other); + Objects.requireNonNull(other, "other is null"); return concatArray(this, other); } + @SuppressWarnings("unchecked") @SchedulerSupport(SchedulerKind.NONE) public final NbpObservable endWith(T value) { - Objects.requireNonNull(value); + Objects.requireNonNull(value, "value is null"); return concatArray(this, just(value)); } + @SuppressWarnings("unchecked") @SchedulerSupport(SchedulerKind.NONE) - @SafeVarargs public final NbpObservable endWithArray(T... values) { NbpObservable fromArray = fromArray(values); if (fromArray == empty()) { @@ -1440,24 +1744,15 @@ public final NbpObservable endWithArray(T... values) { return concatArray(this, fromArray); } - /** - * @deprecated use {@link #any(Predicate)} - */ - @SchedulerSupport(SchedulerKind.NONE) - @Deprecated - public final NbpObservable exists(Predicate predicate) { - return any(predicate); - } - @SchedulerSupport(SchedulerKind.NONE) public final NbpObservable filter(Predicate predicate) { - Objects.requireNonNull(predicate); - return lift(new NbpOperatorFilter<>(predicate)); + Objects.requireNonNull(predicate, "predicate is null"); + return lift(new NbpOperatorFilter(predicate)); } @SchedulerSupport(SchedulerKind.NONE) public final NbpObservable finallyDo(Runnable onFinally) { - return doOnEach(v -> { }, e -> { }, () -> { }, onFinally); + return doOnEach(Functions.emptyConsumer(), Functions.emptyConsumer(), Functions.emptyRunnable(), onFinally); } @SchedulerSupport(SchedulerKind.NONE) @@ -1487,7 +1782,7 @@ public final NbpObservable flatMap(Function NbpObservable flatMap(Function> mapper, boolean delayErrors, int maxConcurrency, int bufferSize) { - Objects.requireNonNull(mapper); + Objects.requireNonNull(mapper, "mapper is null"); if (maxConcurrency <= 0) { throw new IllegalArgumentException("maxConcurrency > 0 required but it was " + maxConcurrency); } @@ -1496,7 +1791,7 @@ public final NbpObservable flatMap(Function scalar = (NbpObservableScalarSource) this; return create(scalar.scalarFlatMap(mapper)); } - return lift(new NbpOperatorFlatMap<>(mapper, delayErrors, maxConcurrency, bufferSize)); + return lift(new NbpOperatorFlatMap(mapper, delayErrors, maxConcurrency, bufferSize)); } @SchedulerSupport(SchedulerKind.NONE) @@ -1504,7 +1799,10 @@ public final NbpObservable flatMap( Function> onNextMapper, Function> onErrorMapper, Supplier> onCompleteSupplier) { - return merge(lift(new NbpOperatorMapNotification<>(onNextMapper, onErrorMapper, onCompleteSupplier))); + Objects.requireNonNull(onNextMapper, "onNextMapper is null"); + Objects.requireNonNull(onErrorMapper, "onErrorMapper is null"); + Objects.requireNonNull(onCompleteSupplier, "onCompleteSupplier is null"); + return merge(lift(new NbpOperatorMapNotification(onNextMapper, onErrorMapper, onCompleteSupplier))); } @SchedulerSupport(SchedulerKind.NONE) @@ -1513,7 +1811,10 @@ public final NbpObservable flatMap( Function> onErrorMapper, Supplier> onCompleteSupplier, int maxConcurrency) { - return merge(lift(new NbpOperatorMapNotification<>(onNextMapper, onErrorMapper, onCompleteSupplier)), maxConcurrency); + Objects.requireNonNull(onNextMapper, "onNextMapper is null"); + Objects.requireNonNull(onErrorMapper, "onErrorMapper is null"); + Objects.requireNonNull(onCompleteSupplier, "onCompleteSupplier is null"); + return merge(lift(new NbpOperatorMapNotification(onNextMapper, onErrorMapper, onCompleteSupplier)), maxConcurrency); } @SchedulerSupport(SchedulerKind.NONE) @@ -1537,11 +1838,21 @@ public final NbpObservable flatMap(Function NbpObservable flatMap(Function> mapper, BiFunction combiner, boolean delayError, int maxConcurrency, int bufferSize) { - return flatMap(t -> { - @SuppressWarnings("unchecked") - NbpObservable u = (NbpObservable)mapper.apply(t); - return u.map(w -> combiner.apply(t, w)); + public final NbpObservable flatMap(final Function> mapper, final BiFunction combiner, boolean delayError, int maxConcurrency, int bufferSize) { + Objects.requireNonNull(mapper, "mapper is null"); + Objects.requireNonNull(combiner, "combiner is null"); + return flatMap(new Function>() { + @Override + public NbpObservable apply(final T t) { + @SuppressWarnings("unchecked") + NbpObservable u = (NbpObservable)mapper.apply(t); + return u.map(new Function() { + @Override + public R apply(U w) { + return combiner.apply(t, w); + } + }); + } }, delayError, maxConcurrency, bufferSize); } @@ -1551,18 +1862,34 @@ public final NbpObservable flatMap(Function NbpObservable flatMapIterable(Function> mapper) { - return flatMap(v -> fromIterable(mapper.apply(v))); + public final NbpObservable flatMapIterable(final Function> mapper) { + Objects.requireNonNull(mapper, "mapper is null"); + return flatMap(new Function>() { + @Override + public NbpObservable apply(T v) { + return fromIterable(mapper.apply(v)); + } + }); } @SchedulerSupport(SchedulerKind.NONE) - public final NbpObservable flatMapIterable(Function> mapper, BiFunction resultSelector) { - return flatMap(t -> fromIterable(mapper.apply(t)), resultSelector, false, bufferSize(), bufferSize()); + public final NbpObservable flatMapIterable(final Function> mapper, BiFunction resultSelector) { + return flatMap(new Function>() { + @Override + public NbpObservable apply(T t) { + return fromIterable(mapper.apply(t)); + } + }, resultSelector, false, bufferSize(), bufferSize()); } @SchedulerSupport(SchedulerKind.NONE) - public final NbpObservable flatMapIterable(Function> mapper, int bufferSize) { - return flatMap(v -> fromIterable(mapper.apply(v)), false, bufferSize); + public final NbpObservable flatMapIterable(final Function> mapper, int bufferSize) { + return flatMap(new Function>() { + @Override + public NbpObservable apply(T v) { + return fromIterable(mapper.apply(v)); + } + }, false, bufferSize); } @SchedulerSupport(SchedulerKind.NONE) @@ -1572,36 +1899,43 @@ public final Disposable forEach(Consumer onNext) { @SchedulerSupport(SchedulerKind.NONE) public final Disposable forEachWhile(Predicate onNext) { - return forEachWhile(onNext, RxJavaPlugins::onError, () -> { }); + return forEachWhile(onNext, RxJavaPlugins.errorConsumer(), Functions.emptyRunnable()); } @SchedulerSupport(SchedulerKind.NONE) public final Disposable forEachWhile(Predicate onNext, Consumer onError) { - return forEachWhile(onNext, onError, () -> { }); + return forEachWhile(onNext, onError, Functions.emptyRunnable()); } @SchedulerSupport(SchedulerKind.NONE) - public final Disposable forEachWhile(Predicate onNext, Consumer onError, - Runnable onComplete) { - Objects.requireNonNull(onNext); - Objects.requireNonNull(onError); - Objects.requireNonNull(onComplete); - - AtomicReference subscription = new AtomicReference<>(); - return subscribe(v -> { - if (!onNext.test(v)) { - subscription.get().dispose(); - onComplete.run(); - } - }, onError, onComplete, s -> { - subscription.lazySet(s); + public final Disposable forEachWhile(final Predicate onNext, Consumer onError, + final Runnable onComplete) { + Objects.requireNonNull(onNext, "onNext is null"); + Objects.requireNonNull(onError, "onError is null"); + Objects.requireNonNull(onComplete, "onComplete is null"); + + final AtomicReference subscription = new AtomicReference(); + return subscribe(new Consumer() { + @Override + public void accept(T v) { + if (!onNext.test(v)) { + subscription.get().dispose(); + onComplete.run(); + } + } + }, onError, onComplete, new Consumer() { + @Override + public void accept(Disposable s) { + subscription.lazySet(s); + } }); } + @SchedulerSupport(SchedulerKind.NONE) public final List getList() { - List result = new ArrayList<>(); - Throwable[] error = { null }; - CountDownLatch cdl = new CountDownLatch(1); + final List result = new ArrayList(); + final Throwable[] error = { null }; + final CountDownLatch cdl = new CountDownLatch(1); subscribe(new NbpSubscriber() { @Override @@ -1639,14 +1973,16 @@ public void onSubscribe(Disposable d) { return result; } + @SuppressWarnings({ "unchecked", "rawtypes" }) @SchedulerSupport(SchedulerKind.NONE) public final NbpObservable> groupBy(Function keySelector) { - return groupBy(keySelector, v -> v, false, bufferSize()); + return groupBy(keySelector, (Function)Functions.identity(), false, bufferSize()); } + @SuppressWarnings({ "unchecked", "rawtypes" }) @SchedulerSupport(SchedulerKind.NONE) public final NbpObservable> groupBy(Function keySelector, boolean delayError) { - return groupBy(keySelector, v -> v, delayError, bufferSize()); + return groupBy(keySelector, (Function)Functions.identity(), delayError, bufferSize()); } @SchedulerSupport(SchedulerKind.NONE) @@ -1665,21 +2001,26 @@ public final NbpObservable> groupBy(Function NbpObservable> groupBy(Function keySelector, Function valueSelector, boolean delayError, int bufferSize) { - Objects.requireNonNull(keySelector); - Objects.requireNonNull(valueSelector); + Objects.requireNonNull(keySelector, "keySelector is null"); + Objects.requireNonNull(valueSelector, "valueSelector is null"); validateBufferSize(bufferSize); - return lift(new NbpOperatorGroupBy<>(keySelector, valueSelector, bufferSize, delayError)); + return lift(new NbpOperatorGroupBy(keySelector, valueSelector, bufferSize, delayError)); } @SchedulerSupport(SchedulerKind.NONE) public final NbpObservable ignoreElements() { - return lift(NbpOperatorIgnoreElements.instance()); + return lift(NbpOperatorIgnoreElements.instance()); } @SchedulerSupport(SchedulerKind.NONE) public final NbpObservable isEmpty() { - return all(v -> false); + return all(new Predicate() { + @Override + public boolean test(T v) { + return false; + } + }); } @SchedulerSupport(SchedulerKind.NONE) @@ -1693,30 +2034,23 @@ public final NbpObservable last(T defaultValue) { } public final NbpObservable lift(NbpOperator onLift) { - Objects.requireNonNull(onLift); - return create(new NbpOnSubscribeLift<>(this, onLift)); - } - - /** - * @deprecated use {@link #take(long)} instead - */ - @SchedulerSupport(SchedulerKind.NONE) - @Deprecated - public final NbpObservable limit(long n) { - return take(n); + Objects.requireNonNull(onLift, "onLift is null"); + return create(new NbpOnSubscribeLift(this, onLift)); } public final NbpObservable map(Function mapper) { - return lift(new NbpOperatorMap<>(mapper)); + Objects.requireNonNull(mapper, "mapper is null"); + return lift(new NbpOperatorMap(mapper)); } @SchedulerSupport(SchedulerKind.NONE) public final NbpObservable>> materialize() { - return lift(NbpOperatorMaterialize.instance()); + return lift(NbpOperatorMaterialize.instance()); } @SchedulerSupport(SchedulerKind.NONE) public final NbpObservable mergeWith(NbpObservable other) { + Objects.requireNonNull(other, "other is null"); return merge(this, other); } @@ -1738,45 +2072,66 @@ public final NbpObservable observeOn(Scheduler scheduler, boolean delayError) @SchedulerSupport(SchedulerKind.CUSTOM) public final NbpObservable observeOn(Scheduler scheduler, boolean delayError, int bufferSize) { - Objects.requireNonNull(scheduler); + Objects.requireNonNull(scheduler, "scheduler is null"); validateBufferSize(bufferSize); - return lift(new NbpOperatorObserveOn<>(scheduler, delayError, bufferSize)); + return lift(new NbpOperatorObserveOn(scheduler, delayError, bufferSize)); } @SchedulerSupport(SchedulerKind.NONE) - public final NbpObservable ofType(Class clazz) { - return filter(clazz::isInstance).cast(clazz); + public final NbpObservable ofType(final Class clazz) { + Objects.requireNonNull(clazz, "clazz is null"); + return filter(new Predicate() { + @Override + public boolean test(T v) { + return clazz.isInstance(v); + } + }).cast(clazz); } @SchedulerSupport(SchedulerKind.NONE) public final NbpObservable onErrorResumeNext(Function> resumeFunction) { - Objects.requireNonNull(resumeFunction); - return lift(new NbpOperatorOnErrorNext<>(resumeFunction, false)); + Objects.requireNonNull(resumeFunction, "resumeFunction is null"); + return lift(new NbpOperatorOnErrorNext(resumeFunction, false)); } @SchedulerSupport(SchedulerKind.NONE) - public final NbpObservable onErrorResumeNext(NbpObservable next) { - Objects.requireNonNull(next); - return onErrorResumeNext(e -> next); + public final NbpObservable onErrorResumeNext(final NbpObservable next) { + Objects.requireNonNull(next, "next is null"); + return onErrorResumeNext(new Function>() { + @Override + public NbpObservable apply(Throwable e) { + return next; + } + }); } @SchedulerSupport(SchedulerKind.NONE) public final NbpObservable onErrorReturn(Function valueSupplier) { - Objects.requireNonNull(valueSupplier); - return lift(new NbpOperatorOnErrorReturn<>(valueSupplier)); + Objects.requireNonNull(valueSupplier, "valueSupplier is null"); + return lift(new NbpOperatorOnErrorReturn(valueSupplier)); } // TODO would result in ambiguity with onErrorReturn(Function) @SchedulerSupport(SchedulerKind.NONE) - public final NbpObservable onErrorReturnValue(T value) { - Objects.requireNonNull(value); - return onErrorReturn(e -> value); + public final NbpObservable onErrorReturnValue(final T value) { + Objects.requireNonNull(value, "value is null"); + return onErrorReturn(new Function() { + @Override + public T apply(Throwable e) { + return value; + } + }); } @SchedulerSupport(SchedulerKind.NONE) - public final NbpObservable onExceptionResumeNext(NbpObservable next) { - Objects.requireNonNull(next); - return lift(new NbpOperatorOnErrorNext<>(e -> next, true)); + public final NbpObservable onExceptionResumeNext(final NbpObservable next) { + Objects.requireNonNull(next, "next is null"); + return lift(new NbpOperatorOnErrorNext(new Function>() { + @Override + public NbpObservable apply(Throwable e) { + return next; + } + }, true)); } @SchedulerSupport(SchedulerKind.NONE) @@ -1792,7 +2147,7 @@ public final NbpObservable publish(Function, ? e @SchedulerSupport(SchedulerKind.NONE) public final NbpObservable publish(Function, ? extends NbpObservable> selector, int bufferSize) { validateBufferSize(bufferSize); - Objects.requireNonNull(selector); + Objects.requireNonNull(selector, "selector is null"); return NbpOperatorPublish.create(this, selector, bufferSize); } @@ -1831,43 +2186,33 @@ public final NbpObservable repeat(long times) { if (times == 0) { return empty(); } - return create(new NbpOnSubscribeRepeat<>(this, times)); - } - - /** - * - * @deprecated use composition - */ - @Deprecated - @SchedulerSupport(SchedulerKind.CUSTOM) - public final NbpObservable repeat(long times, Scheduler scheduler) { - return repeat(times).subscribeOn(scheduler); - } - - /** - * - * @deprecated use composition - */ - @SchedulerSupport(SchedulerKind.CUSTOM) - @Deprecated - public final NbpObservable repeat(Scheduler scheduler) { - return repeat().subscribeOn(scheduler); + return create(new NbpOnSubscribeRepeat(this, times)); } @SchedulerSupport(SchedulerKind.NONE) public final NbpObservable repeatUntil(BooleanSupplier stop) { - return create(new NbpOnSubscribeRepeatUntil<>(this, stop)); + Objects.requireNonNull(stop, "stop is null"); + return create(new NbpOnSubscribeRepeatUntil(this, stop)); } @SchedulerSupport(SchedulerKind.NONE) - public final NbpObservable repeatWhen(Function, ? extends NbpObservable> handler) { - Objects.requireNonNull(handler); + public final NbpObservable repeatWhen(final Function, ? extends NbpObservable> handler) { + Objects.requireNonNull(handler, "handler is null"); - Function>>, NbpObservable> f = no -> - handler.apply(no.map(v -> null)) + Function>>, NbpObservable> f = new Function>>, NbpObservable>() { + @Override + public NbpObservable apply(NbpObservable>> no) { + return handler.apply(no.map(new Function>, Object>() { + @Override + public Object apply(Try> v) { + return 0; + } + })); + } + } ; - return create(new NbpOnSubscribeRedo<>(this, f)); + return create(new NbpOnSubscribeRedo(this, f)); } @SchedulerSupport(SchedulerKind.NONE) @@ -1877,14 +2222,24 @@ public final NbpConnectableObservable replay() { @SchedulerSupport(SchedulerKind.NONE) public final NbpObservable replay(Function, ? extends NbpObservable> selector) { - Objects.requireNonNull(selector); - return NbpOperatorReplay.multicastSelector(this::replay, selector); + Objects.requireNonNull(selector, "selector is null"); + return NbpOperatorReplay.multicastSelector(new Supplier>() { + @Override + public NbpConnectableObservable get() { + return replay(); + } + }, selector); } @SchedulerSupport(SchedulerKind.NONE) public final NbpObservable replay(Function, ? extends NbpObservable> selector, final int bufferSize) { - Objects.requireNonNull(selector); - return NbpOperatorReplay.multicastSelector(() -> replay(bufferSize), selector); + Objects.requireNonNull(selector, "selector is null"); + return NbpOperatorReplay.multicastSelector(new Supplier>() { + @Override + public NbpConnectableObservable get() { + return replay(bufferSize); + } + }, selector); } @SchedulerSupport(SchedulerKind.COMPUTATION) @@ -1897,14 +2252,29 @@ public final NbpObservable replay(Function, ? ex if (bufferSize < 0) { throw new IllegalArgumentException("bufferSize < 0"); } - Objects.requireNonNull(selector); - return NbpOperatorReplay.multicastSelector(() -> replay(bufferSize, time, unit, scheduler), selector); + Objects.requireNonNull(selector, "selector is null"); + return NbpOperatorReplay.multicastSelector(new Supplier>() { + @Override + public NbpConnectableObservable get() { + return replay(bufferSize, time, unit, scheduler); + } + }, selector); } @SchedulerSupport(SchedulerKind.CUSTOM) public final NbpObservable replay(final Function, ? extends NbpObservable> selector, final int bufferSize, final Scheduler scheduler) { - return NbpOperatorReplay.multicastSelector(() -> replay(bufferSize), - t -> selector.apply(t).observeOn(scheduler)); + return NbpOperatorReplay.multicastSelector(new Supplier>() { + @Override + public NbpConnectableObservable get() { + return replay(bufferSize); + } + }, + new Function, NbpObservable>() { + @Override + public NbpObservable apply(NbpObservable t) { + return selector.apply(t).observeOn(scheduler); + } + }); } @SchedulerSupport(SchedulerKind.COMPUTATION) @@ -1914,13 +2284,33 @@ public final NbpObservable replay(Function, ? ex @SchedulerSupport(SchedulerKind.CUSTOM) public final NbpObservable replay(Function, ? extends NbpObservable> selector, final long time, final TimeUnit unit, final Scheduler scheduler) { - return NbpOperatorReplay.multicastSelector(() -> replay(time, unit, scheduler), selector); + Objects.requireNonNull(selector, "selector is null"); + Objects.requireNonNull(unit, "unit is null"); + Objects.requireNonNull(scheduler, "scheduler is null"); + return NbpOperatorReplay.multicastSelector(new Supplier>() { + @Override + public NbpConnectableObservable get() { + return replay(time, unit, scheduler); + } + }, selector); } @SchedulerSupport(SchedulerKind.CUSTOM) public final NbpObservable replay(final Function, ? extends NbpObservable> selector, final Scheduler scheduler) { - return NbpOperatorReplay.multicastSelector(() -> replay(), - t -> selector.apply(t).observeOn(scheduler)); + Objects.requireNonNull(selector, "selector is null"); + Objects.requireNonNull(scheduler, "scheduler is null"); + return NbpOperatorReplay.multicastSelector(new Supplier>() { + @Override + public NbpConnectableObservable get() { + return replay(); + } + }, + new Function, NbpObservable>() { + @Override + public NbpObservable apply(NbpObservable t) { + return selector.apply(t).observeOn(scheduler); + } + }); } @SchedulerSupport(SchedulerKind.NONE) @@ -1938,6 +2328,8 @@ public final NbpConnectableObservable replay(final int bufferSize, final long if (bufferSize < 0) { throw new IllegalArgumentException("bufferSize < 0"); } + Objects.requireNonNull(unit, "unit is null"); + Objects.requireNonNull(scheduler, "scheduler is null"); return NbpOperatorReplay.create(this, time, unit, scheduler, bufferSize); } @@ -1953,30 +2345,32 @@ public final NbpConnectableObservable replay(long time, TimeUnit unit) { @SchedulerSupport(SchedulerKind.CUSTOM) public final NbpConnectableObservable replay(final long time, final TimeUnit unit, final Scheduler scheduler) { + Objects.requireNonNull(unit, "unit is null"); + Objects.requireNonNull(scheduler, "scheduler is null"); return NbpOperatorReplay.create(this, time, unit, scheduler); } @SchedulerSupport(SchedulerKind.CUSTOM) public final NbpConnectableObservable replay(final Scheduler scheduler) { - Objects.requireNonNull(scheduler); + Objects.requireNonNull(scheduler, "scheduler is null"); return NbpOperatorReplay.observeOn(replay(), scheduler); } @SchedulerSupport(SchedulerKind.NONE) public final NbpObservable retry() { - return retry(Long.MAX_VALUE, e -> true); + return retry(Long.MAX_VALUE, Functions.alwaysTrue()); } @SchedulerSupport(SchedulerKind.NONE) public final NbpObservable retry(BiPredicate predicate) { - Objects.requireNonNull(predicate); + Objects.requireNonNull(predicate, "predicate is null"); - return create(new NbpOnSubscribeRetryBiPredicate<>(this, predicate)); + return create(new NbpOnSubscribeRetryBiPredicate(this, predicate)); } @SchedulerSupport(SchedulerKind.NONE) public final NbpObservable retry(long times) { - return retry(times, e -> true); + return retry(times, Functions.alwaysTrue()); } // Retries at most times or until the predicate returns false, whichever happens first @@ -1985,9 +2379,9 @@ public final NbpObservable retry(long times, Predicate pre if (times < 0) { throw new IllegalArgumentException("times >= 0 required but it was " + times); } - Objects.requireNonNull(predicate); + Objects.requireNonNull(predicate, "predicate is null"); - return create(new NbpOnSubscribeRetryPredicate<>(this, times, predicate)); + return create(new NbpOnSubscribeRetryPredicate(this, times, predicate)); } @SchedulerSupport(SchedulerKind.NONE) @@ -1996,32 +2390,53 @@ public final NbpObservable retry(Predicate predicate) { } @SchedulerSupport(SchedulerKind.NONE) - public final NbpObservable retryUntil(BooleanSupplier stop) { - return retry(Long.MAX_VALUE, e -> !stop.getAsBoolean()); + public final NbpObservable retryUntil(final BooleanSupplier stop) { + Objects.requireNonNull(stop, "stop is null"); + return retry(Long.MAX_VALUE, new Predicate() { + @Override + public boolean test(Throwable e) { + return !stop.getAsBoolean(); + } + }); } @SchedulerSupport(SchedulerKind.NONE) public final NbpObservable retryWhen( - Function, ? extends NbpObservable> handler) { - Objects.requireNonNull(handler); + final Function, ? extends NbpObservable> handler) { + Objects.requireNonNull(handler, "handler is null"); - Function>>, NbpObservable> f = no -> - handler.apply(no.takeWhile(Try::hasError).map(t -> { - return t.error(); - })) + Function>>, NbpObservable> f = new Function>>, NbpObservable>() { + @Override + public NbpObservable apply(NbpObservable>> no) { + return handler.apply(no + .takeWhile(new Predicate>>() { + @Override + public boolean test(Try> e) { + return e.hasError(); + } + }) + .map(new Function>, Throwable>() { + @Override + public Throwable apply(Try> t) { + return t.error(); + } + }) + ); + } + } ; - return create(new NbpOnSubscribeRedo<>(this, f)); + return create(new NbpOnSubscribeRedo(this, f)); } // TODO decide if safe subscription or unsafe should be the default @SchedulerSupport(SchedulerKind.NONE) public final void safeSubscribe(NbpSubscriber s) { - Objects.requireNonNull(s); + Objects.requireNonNull(s, "s is null"); if (s instanceof NbpSafeSubscriber) { subscribe(s); } else { - subscribe(new NbpSafeSubscriber<>(s)); + subscribe(new NbpSafeSubscriber(s)); } } @@ -2032,40 +2447,50 @@ public final NbpObservable sample(long period, TimeUnit unit) { @SchedulerSupport(SchedulerKind.CUSTOM) public final NbpObservable sample(long period, TimeUnit unit, Scheduler scheduler) { - Objects.requireNonNull(unit); - Objects.requireNonNull(scheduler); - return lift(new NbpOperatorSampleTimed<>(period, unit, scheduler)); + Objects.requireNonNull(unit, "unit is null"); + Objects.requireNonNull(scheduler, "scheduler is null"); + return lift(new NbpOperatorSampleTimed(period, unit, scheduler)); } @SchedulerSupport(SchedulerKind.NONE) public final NbpObservable sample(NbpObservable sampler) { - Objects.requireNonNull(sampler); - return lift(new NbpOperatorSampleWithObservable<>(sampler)); + Objects.requireNonNull(sampler, "sampler is null"); + return lift(new NbpOperatorSampleWithObservable(sampler)); } @SchedulerSupport(SchedulerKind.NONE) public final NbpObservable scan(BiFunction accumulator) { - Objects.requireNonNull(accumulator); - return lift(new NbpOperatorScan<>(accumulator)); + Objects.requireNonNull(accumulator, "accumulator is null"); + return lift(new NbpOperatorScan(accumulator)); } @SchedulerSupport(SchedulerKind.NONE) - public final NbpObservable scan(R seed, BiFunction accumulator) { - Objects.requireNonNull(seed); - return scanWith(() -> seed, accumulator); + public final NbpObservable scan(final R seed, BiFunction accumulator) { + Objects.requireNonNull(seed, "seed is null"); + return scanWith(new Supplier() { + @Override + public R get() { + return seed; + } + }, accumulator); } // Naming note, a plain scan would cause ambiguity with the value-seeded version @SchedulerSupport(SchedulerKind.NONE) public final NbpObservable scanWith(Supplier seedSupplier, BiFunction accumulator) { - Objects.requireNonNull(seedSupplier); - Objects.requireNonNull(accumulator); - return lift(new NbpOperatorScanSeed<>(seedSupplier, accumulator)); + Objects.requireNonNull(seedSupplier, "seedSupplier is null"); + Objects.requireNonNull(accumulator, "accumulator is null"); + return lift(new NbpOperatorScanSeed(seedSupplier, accumulator)); } @SchedulerSupport(SchedulerKind.NONE) public final NbpObservable serialize() { - return lift(s -> new NbpSerializedSubscriber<>(s)); + return lift(new NbpOperator() { + @Override + public NbpSubscriber apply(NbpSubscriber s) { + return new NbpSerializedSubscriber(s); + } + }); } @SchedulerSupport(SchedulerKind.NONE) @@ -2075,13 +2500,13 @@ public final NbpObservable share() { @SchedulerSupport(SchedulerKind.NONE) public final NbpObservable single() { - return lift(NbpOperatorSingle.instanceNoDefault()); + return lift(NbpOperatorSingle.instanceNoDefault()); } @SchedulerSupport(SchedulerKind.NONE) public final NbpObservable single(T defaultValue) { - Objects.requireNonNull(defaultValue); - return lift(new NbpOperatorSingle<>(defaultValue)); + Objects.requireNonNull(defaultValue, "defaultValue is null"); + return lift(new NbpOperatorSingle(defaultValue)); } @SchedulerSupport(SchedulerKind.NONE) @@ -2093,7 +2518,7 @@ public final NbpObservable skip(long n) { if (n <= 0) { return this; } - return lift(new NbpOperatorSkip<>(n)); + return lift(new NbpOperatorSkip(n)); } @SchedulerSupport(SchedulerKind.CUSTOM) @@ -2110,7 +2535,7 @@ public final NbpObservable skipLast(int n) { if (n == 0) { return this; } - return lift(new NbpOperatorSkipLast<>(n)); + return lift(new NbpOperatorSkipLast(n)); } @SchedulerSupport(SchedulerKind.TRAMPOLINE) @@ -2135,45 +2560,48 @@ public final NbpObservable skipLast(long time, TimeUnit unit, Scheduler sched @SchedulerSupport(SchedulerKind.CUSTOM) public final NbpObservable skipLast(long time, TimeUnit unit, Scheduler scheduler, boolean delayError, int bufferSize) { - Objects.requireNonNull(unit); - Objects.requireNonNull(scheduler); + Objects.requireNonNull(unit, "unit is null"); + Objects.requireNonNull(scheduler, "scheduler is null"); validateBufferSize(bufferSize); // the internal buffer holds pairs of (timestamp, value) so double the default buffer size int s = bufferSize << 1; - return lift(new NbpOperatorSkipLastTimed<>(time, unit, scheduler, s, delayError)); + return lift(new NbpOperatorSkipLastTimed(time, unit, scheduler, s, delayError)); } @SchedulerSupport(SchedulerKind.NONE) - public final NbpObservable skipUntil(NbpObservable other) { - Objects.requireNonNull(other); - return lift(new NbpOperatorSkipUntil<>(other)); + public final NbpObservable skipUntil(NbpObservable other) { + Objects.requireNonNull(other, "other is null"); + return lift(new NbpOperatorSkipUntil(other)); } @SchedulerSupport(SchedulerKind.NONE) public final NbpObservable skipWhile(Predicate predicate) { - Objects.requireNonNull(predicate); - return lift(new NbpOperatorSkipWhile<>(predicate)); + Objects.requireNonNull(predicate, "predicate is null"); + return lift(new NbpOperatorSkipWhile(predicate)); } + @SuppressWarnings("unchecked") @SchedulerSupport(SchedulerKind.NONE) public final NbpObservable startWith(Iterable values) { return concatArray(fromIterable(values), this); } + @SuppressWarnings("unchecked") @SchedulerSupport(SchedulerKind.NONE) public final NbpObservable startWith(NbpObservable other) { - Objects.requireNonNull(other); + Objects.requireNonNull(other, "other is null"); return concatArray(other, this); } + @SuppressWarnings("unchecked") @SchedulerSupport(SchedulerKind.NONE) public final NbpObservable startWith(T value) { - Objects.requireNonNull(value); + Objects.requireNonNull(value, "value is null"); return concatArray(just(value), this); } + @SuppressWarnings("unchecked") @SchedulerSupport(SchedulerKind.NONE) - @SafeVarargs public final NbpObservable startWithArray(T... values) { NbpObservable fromArray = fromArray(values); if (fromArray == empty()) { @@ -2184,34 +2612,34 @@ public final NbpObservable startWithArray(T... values) { @SchedulerSupport(SchedulerKind.NONE) public final Disposable subscribe() { - return subscribe(v -> { }, RxJavaPlugins::onError, () -> { }, s -> { }); + return subscribe(Functions.emptyConsumer(), RxJavaPlugins.errorConsumer(), Functions.emptyRunnable(), Functions.emptyConsumer()); } @SchedulerSupport(SchedulerKind.NONE) public final Disposable subscribe(Consumer onNext) { - return subscribe(onNext, RxJavaPlugins::onError, () -> { }, s -> { }); + return subscribe(onNext, RxJavaPlugins.errorConsumer(), Functions.emptyRunnable(), Functions.emptyConsumer()); } @SchedulerSupport(SchedulerKind.NONE) public final Disposable subscribe(Consumer onNext, Consumer onError) { - return subscribe(onNext, onError, () -> { }, s -> { }); + return subscribe(onNext, onError, Functions.emptyRunnable(), Functions.emptyConsumer()); } @SchedulerSupport(SchedulerKind.NONE) public final Disposable subscribe(Consumer onNext, Consumer onError, Runnable onComplete) { - return subscribe(onNext, onError, onComplete, s -> { }); + return subscribe(onNext, onError, onComplete, Functions.emptyConsumer()); } @SchedulerSupport(SchedulerKind.NONE) public final Disposable subscribe(Consumer onNext, Consumer onError, Runnable onComplete, Consumer onSubscribe) { - Objects.requireNonNull(onNext); - Objects.requireNonNull(onError); - Objects.requireNonNull(onComplete); - Objects.requireNonNull(onSubscribe); + Objects.requireNonNull(onNext, "onNext is null"); + Objects.requireNonNull(onError, "onError is null"); + Objects.requireNonNull(onComplete, "onComplete is null"); + Objects.requireNonNull(onSubscribe, "onSubscribe is null"); - NbpLambdaSubscriber ls = new NbpLambdaSubscriber<>(onNext, onError, onComplete, onSubscribe); + NbpLambdaSubscriber ls = new NbpLambdaSubscriber(onNext, onError, onComplete, onSubscribe); unsafeSubscribe(ls); @@ -2219,20 +2647,20 @@ public final Disposable subscribe(Consumer onNext, Consumer subscriber) { - Objects.requireNonNull(subscriber); + Objects.requireNonNull(subscriber, "subscriber is null"); onSubscribe.accept(subscriber); } @SchedulerSupport(SchedulerKind.CUSTOM) public final NbpObservable subscribeOn(Scheduler scheduler) { - Objects.requireNonNull(scheduler); - return create(new NbpOnSubscribeSubscribeOn<>(this, scheduler)); + Objects.requireNonNull(scheduler, "scheduler is null"); + return create(new NbpOnSubscribeSubscribeOn(this, scheduler)); } @SchedulerSupport(SchedulerKind.NONE) public final NbpObservable switchIfEmpty(NbpObservable other) { - Objects.requireNonNull(other); - return lift(new NbpOperatorSwitchIfEmpty<>(other)); + Objects.requireNonNull(other, "other is null"); + return lift(new NbpOperatorSwitchIfEmpty(other)); } @SchedulerSupport(SchedulerKind.NONE) @@ -2242,9 +2670,9 @@ public final NbpObservable switchMap(Function NbpObservable switchMap(Function> mapper, int bufferSize) { - Objects.requireNonNull(mapper); + Objects.requireNonNull(mapper, "mapper is null"); validateBufferSize(bufferSize); - return lift(new NbpOperatorSwitchMap<>(mapper, bufferSize)); + return lift(new NbpOperatorSwitchMap(mapper, bufferSize)); } @SchedulerSupport(SchedulerKind.NONE) @@ -2257,7 +2685,7 @@ public final NbpObservable take(long n) { // return lift(s -> CancelledSubscriber.INSTANCE); return empty(); } - return lift(new NbpOperatorTake<>(n)); + return lift(new NbpOperatorTake(n)); } @SchedulerSupport(SchedulerKind.NONE) @@ -2280,9 +2708,9 @@ public final NbpObservable takeLast(int n) { return ignoreElements(); } else if (n == 1) { - return lift(NbpOperatorTakeLastOne.instance()); + return lift(NbpOperatorTakeLastOne.instance()); } - return lift(new NbpOperatorTakeLast<>(n)); + return lift(new NbpOperatorTakeLast(n)); } @SchedulerSupport(SchedulerKind.TRAMPOLINE) @@ -2297,13 +2725,13 @@ public final NbpObservable takeLast(long count, long time, TimeUnit unit, Sch @SchedulerSupport(SchedulerKind.CUSTOM) public final NbpObservable takeLast(long count, long time, TimeUnit unit, Scheduler scheduler, boolean delayError, int bufferSize) { - Objects.requireNonNull(unit); - Objects.requireNonNull(scheduler); + Objects.requireNonNull(unit, "unit is null"); + Objects.requireNonNull(scheduler, "scheduler is null"); validateBufferSize(bufferSize); if (count < 0) { throw new IndexOutOfBoundsException("count >= 0 required but it was " + count); } - return lift(new NbpOperatorTakeLastTimed<>(count, time, unit, scheduler, bufferSize, delayError)); + return lift(new NbpOperatorTakeLastTimed(count, time, unit, scheduler, bufferSize, delayError)); } @SchedulerSupport(SchedulerKind.TRAMPOLINE) @@ -2358,20 +2786,20 @@ public final NbpObservable> takeLastBuffer(long time, TimeUnit unit, Sch @SchedulerSupport(SchedulerKind.NONE) public final NbpObservable takeUntil(NbpObservable other) { - Objects.requireNonNull(other); - return lift(new NbpOperatorTakeUntil<>(other)); + Objects.requireNonNull(other, "other is null"); + return lift(new NbpOperatorTakeUntil(other)); } @SchedulerSupport(SchedulerKind.NONE) public final NbpObservable takeUntil(Predicate predicate) { - Objects.requireNonNull(predicate); - return lift(new NbpOperatorTakeUntilPredicate<>(predicate)); + Objects.requireNonNull(predicate, "predicate is null"); + return lift(new NbpOperatorTakeUntilPredicate(predicate)); } @SchedulerSupport(SchedulerKind.NONE) public final NbpObservable takeWhile(Predicate predicate) { - Objects.requireNonNull(predicate); - return lift(new NbpOperatorTakeWhile<>(predicate)); + Objects.requireNonNull(predicate, "predicate is null"); + return lift(new NbpOperatorTakeWhile(predicate)); } @SchedulerSupport(SchedulerKind.COMPUTATION) @@ -2381,6 +2809,8 @@ public final NbpObservable throttleFirst(long windowDuration, TimeUnit unit) @SchedulerSupport(SchedulerKind.CUSTOM) public final NbpObservable throttleFirst(long skipDuration, TimeUnit unit, Scheduler scheduler) { + Objects.requireNonNull(unit, "unit is null"); + Objects.requireNonNull(scheduler, "scheduler is null"); return lift(new NbpOperatorThrottleFirstTimed(skipDuration, unit, scheduler)); } @@ -2421,7 +2851,9 @@ public final NbpObservable> timeInterval(TimeUnit unit) { @SchedulerSupport(SchedulerKind.CUSTOM) public final NbpObservable> timeInterval(TimeUnit unit, Scheduler scheduler) { - return lift(new NbpOperatorTimeInterval<>(unit, scheduler)); + Objects.requireNonNull(unit, "unit is null"); + Objects.requireNonNull(scheduler, "scheduler is null"); + return lift(new NbpOperatorTimeInterval(unit, scheduler)); } @SchedulerSupport(SchedulerKind.NONE) @@ -2431,7 +2863,7 @@ public final NbpObservable timeout(Function NbpObservable timeout(Function> timeoutSelector, NbpObservable other) { - Objects.requireNonNull(other); + Objects.requireNonNull(other, "other is null"); return timeout0(null, timeoutSelector, other); } @@ -2442,13 +2874,13 @@ public final NbpObservable timeout(long timeout, TimeUnit timeUnit) { @SchedulerSupport(SchedulerKind.COMPUTATION) public final NbpObservable timeout(long timeout, TimeUnit timeUnit, NbpObservable other) { - Objects.requireNonNull(other); + Objects.requireNonNull(other, "other is null"); return timeout0(timeout, timeUnit, other, Schedulers.computation()); } @SchedulerSupport(SchedulerKind.CUSTOM) public final NbpObservable timeout(long timeout, TimeUnit timeUnit, NbpObservable other, Scheduler scheduler) { - Objects.requireNonNull(other); + Objects.requireNonNull(other, "other is null"); return timeout0(timeout, timeUnit, other, scheduler); } @@ -2459,7 +2891,7 @@ public final NbpObservable timeout(long timeout, TimeUnit timeUnit, Scheduler public final NbpObservable timeout(Supplier> firstTimeoutSelector, Function> timeoutSelector) { - Objects.requireNonNull(firstTimeoutSelector); + Objects.requireNonNull(firstTimeoutSelector, "firstTimeoutSelector is null"); return timeout0(firstTimeoutSelector, timeoutSelector, null); } @@ -2468,15 +2900,15 @@ public final NbpObservable timeout( Supplier> firstTimeoutSelector, Function> timeoutSelector, NbpObservable other) { - Objects.requireNonNull(firstTimeoutSelector); - Objects.requireNonNull(other); + Objects.requireNonNull(firstTimeoutSelector, "firstTimeoutSelector is null"); + Objects.requireNonNull(other, "other is null"); return timeout0(firstTimeoutSelector, timeoutSelector, other); } private NbpObservable timeout0(long timeout, TimeUnit timeUnit, NbpObservable other, Scheduler scheduler) { - Objects.requireNonNull(timeUnit); - Objects.requireNonNull(scheduler); + Objects.requireNonNull(timeUnit, "timeUnit is null"); + Objects.requireNonNull(scheduler, "scheduler is null"); return lift(new NbpOperatorTimeoutTimed(timeout, timeUnit, scheduler, other)); } @@ -2484,7 +2916,7 @@ private NbpObservable timeout0( Supplier> firstTimeoutSelector, Function> timeoutSelector, NbpObservable other) { - Objects.requireNonNull(timeoutSelector); + Objects.requireNonNull(timeoutSelector, "timeoutSelector is null"); return lift(new NbpOperatorTimeout(firstTimeoutSelector, timeoutSelector, other)); } @@ -2504,8 +2936,15 @@ public final NbpObservable> timestamp(TimeUnit unit) { } @SchedulerSupport(SchedulerKind.CUSTOM) - public final NbpObservable> timestamp(TimeUnit unit, Scheduler scheduler) { - return map(v -> new Timed<>(v, scheduler.now(unit), unit)); + public final NbpObservable> timestamp(final TimeUnit unit, final Scheduler scheduler) { + Objects.requireNonNull(unit, "unit is null"); + Objects.requireNonNull(scheduler, "scheduler is null"); + return map(new Function>() { + @Override + public Timed apply(T v) { + return new Timed(v, scheduler.now(unit), unit); + } + }); } public final R to(Function, R> convert) { @@ -2519,85 +2958,142 @@ public final NbpBlockingObservable toBlocking() { @SchedulerSupport(SchedulerKind.NONE) public final NbpObservable> toList() { - return lift(NbpOperatorToList.defaultInstance()); + return lift(NbpOperatorToList.defaultInstance()); } @SchedulerSupport(SchedulerKind.NONE) - public final NbpObservable> toList(int capacityHint) { + public final NbpObservable> toList(final int capacityHint) { if (capacityHint <= 0) { throw new IllegalArgumentException("capacityHint > 0 required but it was " + capacityHint); } - return lift(new NbpOperatorToList<>(() -> new ArrayList<>(capacityHint))); + return lift(new NbpOperatorToList>(new Supplier>() { + @Override + public List get() { + return new ArrayList(capacityHint); + } + })); } @SchedulerSupport(SchedulerKind.NONE) public final > NbpObservable toList(Supplier collectionSupplier) { - Objects.requireNonNull(collectionSupplier); - return lift(new NbpOperatorToList<>(collectionSupplier)); + Objects.requireNonNull(collectionSupplier, "collectionSupplier is null"); + return lift(new NbpOperatorToList(collectionSupplier)); } @SchedulerSupport(SchedulerKind.NONE) - public final NbpObservable> toMap(Function keySelector) { - return collect(HashMap::new, (m, t) -> { - K key = keySelector.apply(t); - m.put(key, t); + public final NbpObservable> toMap(final Function keySelector) { + return collect(new Supplier>() { + @Override + public Map get() { + return new HashMap(); + } + }, new BiConsumer, T>() { + @Override + public void accept(Map m, T t) { + K key = keySelector.apply(t); + m.put(key, t); + } }); } @SchedulerSupport(SchedulerKind.NONE) - public final NbpObservable> toMap(Function keySelector, Function valueSelector) { - return collect(HashMap::new, (m, t) -> { - K key = keySelector.apply(t); - V value = valueSelector.apply(t); - m.put(key, value); + public final NbpObservable> toMap( + final Function keySelector, + final Function valueSelector) { + Objects.requireNonNull(keySelector, "keySelector is null"); + Objects.requireNonNull(valueSelector, "valueSelector is null"); + return collect(new Supplier>() { + @Override + public Map get() { + return new HashMap(); + } + }, new BiConsumer, T>() { + @Override + public void accept(Map m, T t) { + K key = keySelector.apply(t); + V value = valueSelector.apply(t); + m.put(key, value); + } }); } @SchedulerSupport(SchedulerKind.NONE) - public final NbpObservable> toMap(Function keySelector, - Function valueSelector, + public final NbpObservable> toMap( + final Function keySelector, + final Function valueSelector, Supplier> mapSupplier) { - return collect(mapSupplier, (m, t) -> { - K key = keySelector.apply(t); - V value = valueSelector.apply(t); - m.put(key, value); + return collect(mapSupplier, new BiConsumer, T>() { + @Override + public void accept(Map m, T t) { + K key = keySelector.apply(t); + V value = valueSelector.apply(t); + m.put(key, value); + } }); } @SchedulerSupport(SchedulerKind.NONE) public final NbpObservable>> toMultimap(Function keySelector) { - Function valueSelector = v -> v; - Supplier>> mapSupplier = HashMap::new; - Function> collectionFactory = k -> new ArrayList<>(); + @SuppressWarnings({ "rawtypes", "unchecked" }) + Function valueSelector = (Function)Functions.identity(); + Supplier>> mapSupplier = new Supplier>>() { + @Override + public Map> get() { + return new HashMap>(); + } + }; + Function> collectionFactory = new Function>() { + @Override + public Collection apply(K k) { + return new ArrayList(); + } + }; return toMultimap(keySelector, valueSelector, mapSupplier, collectionFactory); } @SchedulerSupport(SchedulerKind.NONE) public final NbpObservable>> toMultimap(Function keySelector, Function valueSelector) { - Supplier>> mapSupplier = HashMap::new; - Function> collectionFactory = k -> new ArrayList<>(); + Supplier>> mapSupplier = new Supplier>>() { + @Override + public Map> get() { + return new HashMap>(); + } + }; + Function> collectionFactory = new Function>() { + @Override + public Collection apply(K k) { + return new ArrayList(); + } + }; return toMultimap(keySelector, valueSelector, mapSupplier, collectionFactory); } @SchedulerSupport(SchedulerKind.NONE) @SuppressWarnings("unchecked") public final NbpObservable>> toMultimap( - Function keySelector, - Function valueSelector, - Supplier>> mapSupplier, - Function> collectionFactory) { - return collect(mapSupplier, (m, t) -> { - K key = keySelector.apply(t); + final Function keySelector, + final Function valueSelector, + final Supplier>> mapSupplier, + final Function> collectionFactory) { + Objects.requireNonNull(keySelector, "keySelector is null"); + Objects.requireNonNull(valueSelector, "valueSelector is null"); + Objects.requireNonNull(mapSupplier, "mapSupplier is null"); + Objects.requireNonNull(collectionFactory, "collectionFactory is null"); + return collect(mapSupplier, new BiConsumer>, T>() { + @Override + public void accept(Map> m, T t) { + K key = keySelector.apply(t); - Collection coll = m.get(key); - if (coll == null) { - coll = (Collection)collectionFactory.apply(key); - m.put(key, coll); - } + Collection coll = m.get(key); + if (coll == null) { + coll = (Collection)collectionFactory.apply(key); + m.put(key, coll); + } - V value = valueSelector.apply(t); + V value = valueSelector.apply(t); - coll.add(value); + coll.add(value); + } }); } @@ -2607,46 +3103,54 @@ public final NbpObservable>> toMultimap( Function valueSelector, Supplier>> mapSupplier ) { - return toMultimap(keySelector, valueSelector, mapSupplier, k -> new ArrayList<>()); + return toMultimap(keySelector, valueSelector, mapSupplier, new Function>() { + @Override + public Collection apply(K k) { + return new ArrayList(); + } + }); } public final Observable toObservable(BackpressureStrategy strategy) { - Observable o = Observable.create(s -> { - subscribe(new NbpSubscriber() { - - @Override - public void onComplete() { - s.onComplete(); - } - - @Override - public void onError(Throwable e) { - s.onError(e); - } + Observable o = Observable.create(new Publisher() { + @Override + public void subscribe(final Subscriber s) { + NbpObservable.this.subscribe(new NbpSubscriber() { - @Override - public void onNext(T value) { - s.onNext(value); - } + @Override + public void onComplete() { + s.onComplete(); + } - @Override - public void onSubscribe(Disposable d) { - s.onSubscribe(new Subscription() { + @Override + public void onError(Throwable e) { + s.onError(e); + } - @Override - public void cancel() { - d.dispose(); - } + @Override + public void onNext(T value) { + s.onNext(value); + } - @Override - public void request(long n) { - // no backpressure so nothing we can do about this - } - - }); - } - - }); + @Override + public void onSubscribe(final Disposable d) { + s.onSubscribe(new Subscription() { + + @Override + public void cancel() { + d.dispose(); + } + + @Override + public void request(long n) { + // no backpressure so nothing we can do about this + } + + }); + } + + }); + } }); switch (strategy) { @@ -2663,78 +3167,85 @@ public void request(long n) { @SchedulerSupport(SchedulerKind.NONE) public final Single toSingle() { - return Single.create(s -> { - subscribe(new NbpSubscriber() { - T last; - @Override - public void onSubscribe(Disposable d) { - s.onSubscribe(d); - } - @Override - public void onNext(T value) { - last = value; - } - @Override - public void onError(Throwable e) { - s.onError(e); - } - @Override - public void onComplete() { - T v = last; - last = null; - if (v != null) { - s.onSuccess(v); - } else { - s.onError(new NoSuchElementException()); + return Single.create(new SingleOnSubscribe() { + @Override + public void accept(final SingleSubscriber s) { + NbpObservable.this.subscribe(new NbpSubscriber() { + T last; + @Override + public void onSubscribe(Disposable d) { + s.onSubscribe(d); } - } - - - }); + @Override + public void onNext(T value) { + last = value; + } + @Override + public void onError(Throwable e) { + s.onError(e); + } + @Override + public void onComplete() { + T v = last; + last = null; + if (v != null) { + s.onSuccess(v); + } else { + s.onError(new NoSuchElementException()); + } + } + + + }); + } }); } @SchedulerSupport(SchedulerKind.NONE) - @SuppressWarnings({ "unchecked", "rawtypes"}) public final NbpObservable> toSortedList() { - return toSortedList((Comparator)Comparator.naturalOrder()); + return toSortedList(Functions.naturalOrder()); } @SchedulerSupport(SchedulerKind.NONE) - public final NbpObservable> toSortedList(Comparator comparator) { - Objects.requireNonNull(comparator); - return toList().map(v -> { - Collections.sort(v, comparator); - return v; + public final NbpObservable> toSortedList(final Comparator comparator) { + Objects.requireNonNull(comparator, "comparator is null"); + return toList().map(new Function, List>() { + @Override + public List apply(List v) { + Collections.sort(v, comparator); + return v; + } }); } @SchedulerSupport(SchedulerKind.NONE) - public final NbpObservable> toSortedList(Comparator comparator, int capacityHint) { - Objects.requireNonNull(comparator); - return toList(capacityHint).map(v -> { - Collections.sort(v, comparator); - return v; + public final NbpObservable> toSortedList(final Comparator comparator, int capacityHint) { + Objects.requireNonNull(comparator, "comparator is null"); + return toList(capacityHint).map(new Function, List>() { + @Override + public List apply(List v) { + Collections.sort(v, comparator); + return v; + } }); } @SchedulerSupport(SchedulerKind.NONE) - @SuppressWarnings({ "unchecked", "rawtypes"}) public final NbpObservable> toSortedList(int capacityHint) { - return toSortedList((Comparator)Comparator.naturalOrder(), capacityHint); + return toSortedList(Functions.naturalOrder(), capacityHint); } @SchedulerSupport(SchedulerKind.NONE) // TODO decide if safe subscription or unsafe should be the default public final void unsafeSubscribe(NbpSubscriber s) { - Objects.requireNonNull(s); + Objects.requireNonNull(s, "s is null"); subscribe(s); } @SchedulerSupport(SchedulerKind.CUSTOM) public final NbpObservable unsubscribeOn(Scheduler scheduler) { - Objects.requireNonNull(scheduler); - return lift(new NbpOperatorUnsubscribeOn<>(scheduler)); + Objects.requireNonNull(scheduler, "scheduler is null"); + return lift(new NbpOperatorUnsubscribeOn(scheduler)); } @SchedulerSupport(SchedulerKind.NONE) @@ -2756,7 +3267,7 @@ public final NbpObservable> window(long count, long skip, int b throw new IllegalArgumentException("count > 0 required but it was " + count); } validateBufferSize(bufferSize); - return lift(new NbpOperatorWindow<>(count, skip, bufferSize)); + return lift(new NbpOperatorWindow(count, skip, bufferSize)); } @SchedulerSupport(SchedulerKind.COMPUTATION) @@ -2772,9 +3283,9 @@ public final NbpObservable> window(long timespan, long timeskip @SchedulerSupport(SchedulerKind.CUSTOM) public final NbpObservable> window(long timespan, long timeskip, TimeUnit unit, Scheduler scheduler, int bufferSize) { validateBufferSize(bufferSize); - Objects.requireNonNull(scheduler); - Objects.requireNonNull(unit); - return lift(new NbpOperatorWindowTimed<>(timespan, timeskip, unit, scheduler, Long.MAX_VALUE, bufferSize, false)); + Objects.requireNonNull(scheduler, "scheduler is null"); + Objects.requireNonNull(unit, "unit is null"); + return lift(new NbpOperatorWindowTimed(timespan, timeskip, unit, scheduler, Long.MAX_VALUE, bufferSize, false)); } @SchedulerSupport(SchedulerKind.COMPUTATION) @@ -2817,12 +3328,12 @@ public final NbpObservable> window( long timespan, TimeUnit unit, Scheduler scheduler, long count, boolean restart, int bufferSize) { validateBufferSize(bufferSize); - Objects.requireNonNull(scheduler); - Objects.requireNonNull(unit); + Objects.requireNonNull(scheduler, "scheduler is null"); + Objects.requireNonNull(unit, "unit is null"); if (count <= 0) { throw new IllegalArgumentException("count > 0 required but it was " + count); } - return lift(new NbpOperatorWindowTimed<>(timespan, timespan, unit, scheduler, count, bufferSize, restart)); + return lift(new NbpOperatorWindowTimed(timespan, timespan, unit, scheduler, count, bufferSize, restart)); } @SchedulerSupport(SchedulerKind.NONE) @@ -2832,7 +3343,8 @@ public final NbpObservable> window(NbpObservable boundar @SchedulerSupport(SchedulerKind.NONE) public final NbpObservable> window(NbpObservable boundary, int bufferSize) { - return lift(new NbpOperatorWindowBoundary<>(boundary, bufferSize)); + Objects.requireNonNull(boundary, "boundary is null"); + return lift(new NbpOperatorWindowBoundary(boundary, bufferSize)); } @SchedulerSupport(SchedulerKind.NONE) @@ -2846,7 +3358,9 @@ public final NbpObservable> window( public final NbpObservable> window( NbpObservable windowOpen, Function> windowClose, int bufferSize) { - return lift(new NbpOperatorWindowBoundarySelector<>(windowOpen, windowClose, bufferSize)); + Objects.requireNonNull(windowOpen, "windowOpen is null"); + Objects.requireNonNull(windowClose, "windowClose is null"); + return lift(new NbpOperatorWindowBoundarySelector(windowOpen, windowClose, bufferSize)); } @SchedulerSupport(SchedulerKind.NONE) @@ -2856,24 +3370,28 @@ public final NbpObservable> window(Supplier NbpObservable> window(Supplier> boundary, int bufferSize) { - return lift(new NbpOperatorWindowBoundarySupplier<>(boundary, bufferSize)); + Objects.requireNonNull(boundary, "boundary is null"); + return lift(new NbpOperatorWindowBoundarySupplier(boundary, bufferSize)); } @SchedulerSupport(SchedulerKind.NONE) public final NbpObservable withLatestFrom(NbpObservable other, BiFunction combiner) { - Objects.requireNonNull(other); - Objects.requireNonNull(combiner); + Objects.requireNonNull(other, "other is null"); + Objects.requireNonNull(combiner, "combiner is null"); - return lift(new NbpOperatorWithLatestFrom<>(combiner, other)); + return lift(new NbpOperatorWithLatestFrom(combiner, other)); } @SchedulerSupport(SchedulerKind.NONE) - public final NbpObservable zipWith(Iterable other, BiFunction zipper) { - return create(new NbpOnSubscribeZipIterable<>(this, other, zipper)); + public final NbpObservable zipWith(Iterable other, BiFunction zipper) { + Objects.requireNonNull(other, "other is null"); + Objects.requireNonNull(zipper, "zipper is null"); + return create(new NbpOnSubscribeZipIterable(this, other, zipper)); } @SchedulerSupport(SchedulerKind.NONE) public final NbpObservable zipWith(NbpObservable other, BiFunction zipper) { + Objects.requireNonNull(other, "other is null"); return zip(this, other, zipper); } @@ -2888,4 +3406,4 @@ public final NbpObservable zipWith(NbpObservable other, B } - } + } \ No newline at end of file diff --git a/src/main/java/io/reactivex/NbpObserver.java b/src/main/java/io/reactivex/NbpObserver.java index 4247726b59..1c51f90007 100644 --- a/src/main/java/io/reactivex/NbpObserver.java +++ b/src/main/java/io/reactivex/NbpObserver.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 diff --git a/src/main/java/io/reactivex/Notification.java b/src/main/java/io/reactivex/Notification.java index a04f6c97dc..2a2a1dd871 100644 --- a/src/main/java/io/reactivex/Notification.java +++ b/src/main/java/io/reactivex/Notification.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,7 +13,7 @@ package io.reactivex; -import java.util.*; +import io.reactivex.internal.functions.Objects; /** * Utility class to help construct notification objects. @@ -23,7 +23,7 @@ private Notification() { throw new IllegalStateException(); } - static final Try> COMPLETE = Try.ofValue(Optional.empty()); + static final Try> COMPLETE = Try.ofValue(Optional.empty()); @SuppressWarnings({ "rawtypes", "unchecked" }) public static Try> complete() { @@ -36,7 +36,7 @@ public static Try> error(Throwable e) { } public static Try> next(T value) { - Objects.requireNonNull(value); // TODO this coud instead return an error of NPE + Objects.requireNonNull(value, "value is null"); // TODO this coud instead return an error of NPE return Try.ofValue(Optional.of(value)); } diff --git a/src/main/java/io/reactivex/Observable.java b/src/main/java/io/reactivex/Observable.java index 7164560c28..dee64a7c76 100644 --- a/src/main/java/io/reactivex/Observable.java +++ b/src/main/java/io/reactivex/Observable.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -16,14 +16,14 @@ import java.util.*; import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicReference; -import java.util.function.*; -import java.util.stream.Stream; import org.reactivestreams.*; import io.reactivex.annotations.*; import io.reactivex.disposables.Disposable; import io.reactivex.functions.*; +import io.reactivex.internal.functions.*; +import io.reactivex.internal.functions.Objects; import io.reactivex.internal.operators.*; import io.reactivex.internal.subscribers.*; import io.reactivex.internal.subscriptions.EmptySubscription; @@ -39,7 +39,6 @@ public class Observable implements Publisher { * @param the value type of the downstream * @param the value type of the upstream */ - @FunctionalInterface public interface Operator extends Function, Subscriber> { } @@ -50,7 +49,6 @@ public interface Operator extends Function the upstream value type * @param the downstream value type */ - @FunctionalInterface public interface Transformer extends Function, Publisher> { } @@ -65,18 +63,22 @@ public interface Transformer extends Function, Publisher EMPTY = create(PublisherEmptySource.INSTANCE); /** A never observable instance as there is no need to instantiate this more than once. */ - static final Observable NEVER = create(s -> s.onSubscribe(EmptySubscription.INSTANCE)); + static final Observable NEVER = create(new Publisher() { + @Override + public void subscribe(Subscriber s) { + s.onSubscribe(EmptySubscription.INSTANCE); + } + }); public static Observable amb(Iterable> sources) { - Objects.requireNonNull(sources); - return create(new PublisherAmb<>(null, sources)); + Objects.requireNonNull(sources, "sources is null"); + return create(new PublisherAmb(null, sources)); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) - @SafeVarargs public static Observable amb(Publisher... sources) { - Objects.requireNonNull(sources); + Objects.requireNonNull(sources, "sources is null"); int len = sources.length; if (len == 0) { return empty(); @@ -84,7 +86,7 @@ public static Observable amb(Publisher... sources) { if (len == 1) { return fromPublisher(sources[0]); } - return create(new PublisherAmb<>(sources, null)); + return create(new PublisherAmb(sources, null)); } public static int bufferSize() { @@ -93,7 +95,6 @@ public static int bufferSize() { @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) - @SafeVarargs public static Observable combineLatest(Function combiner, boolean delayError, int bufferSize, Publisher... sources) { return combineLatest(sources, combiner, delayError, bufferSize); } @@ -113,13 +114,13 @@ public static Observable combineLatest(Iterable Observable combineLatest(Iterable> sources, Function combiner, boolean delayError, int bufferSize) { - Objects.requireNonNull(sources); - Objects.requireNonNull(combiner); + Objects.requireNonNull(sources, "sources is null"); + Objects.requireNonNull(combiner, "combiner is null"); validateBufferSize(bufferSize); // the queue holds a pair of values so we need to double the capacity int s = bufferSize << 1; - return create(new PublisherCombineLatest<>(null, sources, combiner, s, delayError)); + return create(new PublisherCombineLatest(null, sources, combiner, s, delayError)); } @BackpressureSupport(BackpressureKind.FULL) @@ -138,42 +139,46 @@ public static Observable combineLatest(Publisher[] source @SchedulerSupport(SchedulerKind.NONE) public static Observable combineLatest(Publisher[] sources, Function combiner, boolean delayError, int bufferSize) { validateBufferSize(bufferSize); - Objects.requireNonNull(combiner); + Objects.requireNonNull(combiner, "combiner is null"); if (sources.length == 0) { return empty(); } // the queue holds a pair of values so we need to double the capacity int s = bufferSize << 1; - return create(new PublisherCombineLatest<>(sources, null, combiner, s, delayError)); + return create(new PublisherCombineLatest(sources, null, combiner, s, delayError)); } + @SuppressWarnings("unchecked") @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable combineLatest( Publisher p1, Publisher p2, BiFunction combiner) { - Function f = toFunction(combiner); + Function f = Functions.toFunction(combiner); return combineLatest(f, false, bufferSize(), p1, p2); } + @SuppressWarnings("unchecked") @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable combineLatest( Publisher p1, Publisher p2, Publisher p3, Function3 combiner) { - return combineLatest(combiner, false, bufferSize(), p1, p2, p3); + return combineLatest(Functions.toFunction(combiner), false, bufferSize(), p1, p2, p3); } + @SuppressWarnings("unchecked") @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable combineLatest( Publisher p1, Publisher p2, Publisher p3, Publisher p4, Function4 combiner) { - return combineLatest(combiner, false, bufferSize(), p1, p2, p3, p4); + return combineLatest(Functions.toFunction(combiner), false, bufferSize(), p1, p2, p3, p4); } + @SuppressWarnings("unchecked") @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable combineLatest( @@ -181,9 +186,10 @@ public static Observable combineLatest( Publisher p3, Publisher p4, Publisher p5, Function5 combiner) { - return combineLatest(combiner, false, bufferSize(), p1, p2, p3, p4, p5); + return combineLatest(Functions.toFunction(combiner), false, bufferSize(), p1, p2, p3, p4, p5); } + @SuppressWarnings("unchecked") @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable combineLatest( @@ -191,9 +197,10 @@ public static Observable combineLatest( Publisher p3, Publisher p4, Publisher p5, Publisher p6, Function6 combiner) { - return combineLatest(combiner, false, bufferSize(), p1, p2, p3, p4, p5, p6); + return combineLatest(Functions.toFunction(combiner), false, bufferSize(), p1, p2, p3, p4, p5, p6); } + @SuppressWarnings("unchecked") @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable combineLatest( @@ -202,9 +209,10 @@ public static Observable combineLatest( Publisher p5, Publisher p6, Publisher p7, Function7 combiner) { - return combineLatest(combiner, false, bufferSize(), p1, p2, p3, p4, p5, p6, p7); + return combineLatest(Functions.toFunction(combiner), false, bufferSize(), p1, p2, p3, p4, p5, p6, p7); } + @SuppressWarnings("unchecked") @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable combineLatest( @@ -213,9 +221,10 @@ public static Observable combineLatest( Publisher p5, Publisher p6, Publisher p7, Publisher p8, Function8 combiner) { - return combineLatest(combiner, false, bufferSize(), p1, p2, p3, p4, p5, p6, p7, p8); + return combineLatest(Functions.toFunction(combiner), false, bufferSize(), p1, p2, p3, p4, p5, p6, p7, p8); } + @SuppressWarnings("unchecked") @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable combineLatest( @@ -225,21 +234,23 @@ public static Observable combineLates Publisher p7, Publisher p8, Publisher p9, Function9 combiner) { - return combineLatest(combiner, false, bufferSize(), p1, p2, p3, p4, p5, p6, p7, p8, p9); + return combineLatest(Functions.toFunction(combiner), false, bufferSize(), p1, p2, p3, p4, p5, p6, p7, p8, p9); } + @SuppressWarnings({ "unchecked", "rawtypes" }) @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable concat(int prefetch, Iterable> sources) { - Objects.requireNonNull(sources); - return fromIterable(sources).concatMap(v -> v, prefetch); + Objects.requireNonNull(sources, "sources is null"); + return fromIterable(sources).concatMap((Function)Functions.identity(), prefetch); } + @SuppressWarnings({ "unchecked", "rawtypes" }) @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable concat(Iterable> sources) { - Objects.requireNonNull(sources); - return fromIterable(sources).concatMap(v -> v); + Objects.requireNonNull(sources, "sources is null"); + return fromIterable(sources).concatMap((Function)Functions.identity()); } @BackpressureSupport(BackpressureKind.FULL) @@ -248,18 +259,21 @@ public static final Observable concat(Publisher Observable concat(Publisher> sources, int bufferSize) { - return fromPublisher(sources).concatMap(v -> v); + return fromPublisher(sources).concatMap((Function)Functions.identity()); } + @SuppressWarnings("unchecked") @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable concat(Publisher p1, Publisher p2) { return concatArray(p1, p2); } + @SuppressWarnings("unchecked") @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable concat( @@ -268,6 +282,7 @@ public static Observable concat( return concatArray(p1, p2, p3); } + @SuppressWarnings("unchecked") @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable concat( @@ -276,6 +291,7 @@ public static Observable concat( return concatArray(p1, p2, p3, p4); } + @SuppressWarnings("unchecked") @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable concat( @@ -286,6 +302,7 @@ public static Observable concat( return concatArray(p1, p2, p3, p4, p5); } + @SuppressWarnings("unchecked") @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable concat( @@ -296,6 +313,7 @@ public static Observable concat( return concatArray(p1, p2, p3, p4, p5, p6); } + @SuppressWarnings("unchecked") @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable concat( @@ -307,6 +325,7 @@ public static Observable concat( return concatArray(p1, p2, p3, p4, p5, p6, p7); } + @SuppressWarnings("unchecked") @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable concat( @@ -318,6 +337,7 @@ public static Observable concat( return concatArray(p1, p2, p3, p4, p5, p6, p7, p8); } + @SuppressWarnings("unchecked") @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable concat( @@ -330,21 +350,26 @@ public static Observable concat( return concatArray(p1, p2, p3, p4, p5, p6, p7, p8, p9); } + @SuppressWarnings({ "unchecked", "rawtypes" }) @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) - @SafeVarargs public static Observable concatArray(int prefetch, Publisher... sources) { - Objects.requireNonNull(sources); - return fromArray(sources).concatMap(v -> v, prefetch); + Objects.requireNonNull(sources, "sources is null"); + return fromArray(sources).concatMap((Function)Functions.identity(), prefetch); } /** - * - * TODO named this way because of overload conflict with concat(Publisher<Publisher>) + * Concatenates a variable number of Observable sources. + *

+ * Note: named this way because of overload conflict with concat(NbpObservable<NbpObservable>) + * @param sources the array of sources + * @param the common base value type + * @return the new NbpObservable instance + * @throws NullPointerException if sources is null */ + @SuppressWarnings({ "unchecked", "rawtypes" }) @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) - @SafeVarargs public static Observable concatArray(Publisher... sources) { if (sources.length == 0) { return empty(); @@ -352,21 +377,22 @@ public static Observable concatArray(Publisher... sources) { if (sources.length == 1) { return fromPublisher(sources[0]); } - return fromArray(sources).concatMap(v -> v); + return fromArray(sources).concatMap((Function)Functions.identity()); } @BackpressureSupport(BackpressureKind.NONE) @SchedulerSupport(SchedulerKind.NONE) public static Observable create(Publisher onSubscribe) { - Objects.requireNonNull(onSubscribe); + Objects.requireNonNull(onSubscribe, "onSubscribe is null"); onSubscribe = RxJavaPlugins.onCreate(onSubscribe); - return new Observable<>(onSubscribe); + return new Observable(onSubscribe); } @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport(SchedulerKind.NONE) public static Observable defer(Supplier> supplier) { - return create(new PublisherDefer<>(supplier)); + Objects.requireNonNull(supplier, "supplier is null"); + return create(new PublisherDefer(supplier)); } @BackpressureSupport(BackpressureKind.PASS_THROUGH) @@ -379,44 +405,41 @@ public static Observable empty() { @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport(SchedulerKind.NONE) public static Observable error(Supplier errorSupplier) { - Objects.requireNonNull(errorSupplier); - return create(new PublisherErrorSource<>(errorSupplier)); + Objects.requireNonNull(errorSupplier, "errorSupplier is null"); + return create(new PublisherErrorSource(errorSupplier)); } @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport(SchedulerKind.NONE) - public static Observable error(Throwable e) { - Objects.requireNonNull(e); - return error(() -> e); + public static Observable error(final Throwable e) { + Objects.requireNonNull(e, "e is null"); + return error(new Supplier() { + @Override + public Throwable get() { + return e; + } + }); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) - @SafeVarargs public static Observable fromArray(T... values) { - Objects.requireNonNull(values); + Objects.requireNonNull(values, "values is null"); if (values.length == 0) { return empty(); } else if (values.length == 1) { return just(values[0]); } - return create(new PublisherArraySource<>(values)); + return create(new PublisherArraySource(values)); } // TODO match naming with RxJava 1.x @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable fromCallable(Callable supplier) { - Objects.requireNonNull(supplier); - return create(new PublisherScalarAsyncSource<>(supplier)); - } - - @BackpressureSupport(BackpressureKind.FULL) - @SchedulerSupport(SchedulerKind.NONE) - public static Observable fromFuture(CompletableFuture future) { - Objects.requireNonNull(future); - return create(new PublisherCompletableFutureSource<>(future)); + Objects.requireNonNull(supplier, "supplier is null"); + return create(new PublisherScalarAsyncSource(supplier)); } /* @@ -427,11 +450,8 @@ public static Observable fromFuture(CompletableFuture future @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable fromFuture(Future future) { - if (future instanceof CompletableFuture) { - return fromFuture((CompletableFuture)future); - } - Objects.requireNonNull(future); - Observable o = create(new PublisherFutureSource<>(future, 0L, null)); + Objects.requireNonNull(future, "future is null"); + Observable o = create(new PublisherFutureSource(future, 0L, null)); return o; } @@ -439,16 +459,16 @@ public static Observable fromFuture(Future future) { @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable fromFuture(Future future, long timeout, TimeUnit unit) { - Objects.requireNonNull(future); - Objects.requireNonNull(unit); - Observable o = create(new PublisherFutureSource<>(future, timeout, unit)); + Objects.requireNonNull(future, "future is null"); + Objects.requireNonNull(unit, "unit is null"); + Observable o = create(new PublisherFutureSource(future, timeout, unit)); return o; } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.CUSTOM) public static Observable fromFuture(Future future, long timeout, TimeUnit unit, Scheduler scheduler) { - Objects.requireNonNull(scheduler); + Objects.requireNonNull(scheduler, "scheduler is null"); Observable o = fromFuture(future, timeout, unit); return o.subscribeOn(scheduler); } @@ -456,7 +476,7 @@ public static Observable fromFuture(Future future, long time @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.IO) public static Observable fromFuture(Future future, Scheduler scheduler) { - Objects.requireNonNull(scheduler); + Objects.requireNonNull(scheduler, "scheduler is null"); Observable o = fromFuture(future); return o.subscribeOn(Schedulers.io()); } @@ -464,72 +484,80 @@ public static Observable fromFuture(Future future, Scheduler @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable fromIterable(Iterable source) { - Objects.requireNonNull(source); - return create(new PublisherIterableSource<>(source)); + Objects.requireNonNull(source, "source is null"); + return create(new PublisherIterableSource(source)); } @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport(SchedulerKind.NONE) @SuppressWarnings("unchecked") - public static Observable fromPublisher(Publisher publisher) { + public static Observable fromPublisher(final Publisher publisher) { if (publisher instanceof Observable) { return (Observable)publisher; } - Objects.requireNonNull(publisher); + Objects.requireNonNull(publisher, "publisher is null"); - return create(s -> publisher.subscribe(s)); // javac fails to compile publisher::subscribe, Eclipse is just fine - } - - @BackpressureSupport(BackpressureKind.FULL) - @SchedulerSupport(SchedulerKind.NONE) - public static Observable fromStream(Stream stream) { - Objects.requireNonNull(stream); - return create(new PublisherStreamSource<>(stream)); + return create(new Publisher() { + @Override + public void subscribe(Subscriber s) { + publisher.subscribe(s); + } + }); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) - public static Observable generate(Consumer> generator) { - Objects.requireNonNull(generator); - return generate(() -> null, (s, o) -> { - generator.accept(o); - return s; - }, s -> { }); + public static Observable generate(final Consumer> generator) { + Objects.requireNonNull(generator, "generator is null"); + return generate(Functions.nullSupplier(), + new BiFunction, Object>() { + @Override + public Object apply(Object s, Subscriber o) { + generator.accept(o); + return s; + } + }, Functions.emptyConsumer()); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) - public static Observable generate(Supplier initialState, BiConsumer> generator) { - Objects.requireNonNull(generator); - return generate(initialState, (s, o) -> { - generator.accept(s, o); - return s; - }, s -> { }); + public static Observable generate(Supplier initialState, final BiConsumer> generator) { + Objects.requireNonNull(generator, "generator is null"); + return generate(initialState, new BiFunction, S>() { + @Override + public S apply(S s, Subscriber o) { + generator.accept(s, o); + return s; + } + }, Functions.emptyConsumer()); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) - public static Observable generate(Supplier initialState, BiConsumer> generator, Consumer disposeState) { - Objects.requireNonNull(generator); - return generate(initialState, (s, o) -> { - generator.accept(s, o); - return s; + public static Observable generate(Supplier initialState, final BiConsumer> generator, Consumer disposeState) { + Objects.requireNonNull(generator, "generator is null"); + return generate(initialState, new BiFunction, S>() { + @Override + public S apply(S s, Subscriber o) { + generator.accept(s, o); + return s; + } }, disposeState); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable generate(Supplier initialState, BiFunction, S> generator) { - return generate(initialState, generator, s -> { }); + return generate(initialState, generator, Functions.emptyConsumer()); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable generate(Supplier initialState, BiFunction, S> generator, Consumer disposeState) { - Objects.requireNonNull(initialState); - Objects.requireNonNull(generator); - Objects.requireNonNull(disposeState); - return create(new PublisherGenerate<>(initialState, generator, disposeState)); + Objects.requireNonNull(initialState, "initialState is null"); + Objects.requireNonNull(generator, "generator is null"); + Objects.requireNonNull(disposeState, "disposeState is null"); + return create(new PublisherGenerate(initialState, generator, disposeState)); } @BackpressureSupport(BackpressureKind.ERROR) @@ -547,8 +575,8 @@ public static Observable interval(long initialDelay, long period, TimeUnit if (period < 0) { period = 0L; } - Objects.requireNonNull(unit); - Objects.requireNonNull(scheduler); + Objects.requireNonNull(unit, "unit is null"); + Objects.requireNonNull(scheduler, "scheduler is null"); return create(new PublisherIntervalSource(initialDelay, period, unit, scheduler)); } @@ -586,8 +614,8 @@ public static Observable intervalRange(long start, long count, long initia if (period < 0) { period = 0L; } - Objects.requireNonNull(unit); - Objects.requireNonNull(scheduler); + Objects.requireNonNull(unit, "unit is null"); + Objects.requireNonNull(scheduler, "scheduler is null"); return create(new PublisherIntervalRangeSource(start, end, initialDelay, period, unit, scheduler)); } @@ -595,10 +623,11 @@ public static Observable intervalRange(long start, long count, long initia @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable just(T value) { - Objects.requireNonNull(value); - return new ObservableScalarSource<>(value); + Objects.requireNonNull(value, "value is null"); + return new ObservableScalarSource(value); } + @SuppressWarnings("unchecked") @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static final Observable just(T v1, T v2) { @@ -609,6 +638,7 @@ public static final Observable just(T v1, T v2) { } + @SuppressWarnings("unchecked") @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static final Observable just(T v1, T v2, T v3) { @@ -619,6 +649,7 @@ public static final Observable just(T v1, T v2, T v3) { return fromArray(v1, v2, v3); } + @SuppressWarnings("unchecked") @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static final Observable just(T v1, T v2, T v3, T v4) { @@ -630,6 +661,7 @@ public static final Observable just(T v1, T v2, T v3, T v4) { return fromArray(v1, v2, v3, v4); } + @SuppressWarnings("unchecked") @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static final Observable just(T v1, T v2, T v3, T v4, T v5) { @@ -642,6 +674,7 @@ public static final Observable just(T v1, T v2, T v3, T v4, T v5) { return fromArray(v1, v2, v3, v4, v5); } + @SuppressWarnings("unchecked") @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static final Observable just(T v1, T v2, T v3, T v4, T v5, T v6) { @@ -650,10 +683,12 @@ public static final Observable just(T v1, T v2, T v3, T v4, T v5, T v6) { Objects.requireNonNull(v3, "The third value is null"); Objects.requireNonNull(v4, "The fourth value is null"); Objects.requireNonNull(v5, "The fifth value is null"); + Objects.requireNonNull(v6, "The sixth value is null"); return fromArray(v1, v2, v3, v4, v5, v6); } + @SuppressWarnings("unchecked") @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static final Observable just(T v1, T v2, T v3, T v4, T v5, T v6, T v7) { @@ -668,6 +703,7 @@ public static final Observable just(T v1, T v2, T v3, T v4, T v5, T v6, T return fromArray(v1, v2, v3, v4, v5, v6, v7); } + @SuppressWarnings("unchecked") @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static final Observable just(T v1, T v2, T v3, T v4, T v5, T v6, T v7, T v8) { @@ -683,6 +719,7 @@ public static final Observable just(T v1, T v2, T v3, T v4, T v5, T v6, T return fromArray(v1, v2, v3, v4, v5, v6, v7, v8); } + @SuppressWarnings("unchecked") @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static final Observable just(T v1, T v2, T v3, T v4, T v5, T v6, T v7, T v8, T v9) { @@ -699,36 +736,39 @@ public static final Observable just(T v1, T v2, T v3, T v4, T v5, T v6, T return fromArray(v1, v2, v3, v4, v5, v6, v7, v8, v9); } + @SuppressWarnings({ "unchecked", "rawtypes" }) @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable merge(int maxConcurrency, int bufferSize, Iterable> sources) { - return fromIterable(sources).flatMap(v -> v, false, maxConcurrency, bufferSize); + return fromIterable(sources).flatMap((Function)Functions.identity(), false, maxConcurrency, bufferSize); } + @SuppressWarnings({ "unchecked", "rawtypes" }) @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) - @SafeVarargs public static Observable merge(int maxConcurrency, int bufferSize, Publisher... sources) { - return fromArray(sources).flatMap(v -> v, false, maxConcurrency, bufferSize); + return fromArray(sources).flatMap((Function)Functions.identity(), false, maxConcurrency, bufferSize); } + @SuppressWarnings({ "unchecked", "rawtypes" }) @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) - @SafeVarargs public static Observable merge(int maxConcurrency, Publisher... sources) { - return fromArray(sources).flatMap(v -> v, maxConcurrency); + return fromArray(sources).flatMap((Function)Functions.identity(), maxConcurrency); } + @SuppressWarnings({ "unchecked", "rawtypes" }) @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable merge(Iterable> sources) { - return fromIterable(sources).flatMap(v -> v); + return fromIterable(sources).flatMap((Function)Functions.identity()); } + @SuppressWarnings({ "unchecked", "rawtypes" }) @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable merge(Iterable> sources, int maxConcurrency) { - return fromIterable(sources).flatMap(v -> v, maxConcurrency); + return fromIterable(sources).flatMap((Function)Functions.identity(), maxConcurrency); } @BackpressureSupport(BackpressureKind.FULL) @@ -737,49 +777,85 @@ public static Observable merge(Publisher return merge(sources, bufferSize()); } + @SuppressWarnings({ "unchecked", "rawtypes" }) @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable merge(Publisher> sources, int maxConcurrency) { - return fromPublisher(sources).flatMap(v -> v, maxConcurrency); + return fromPublisher(sources).flatMap((Function)Functions.identity(), maxConcurrency); } + @SuppressWarnings({ "unchecked", "rawtypes" }) @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) - @SafeVarargs public static Observable merge(Publisher... sources) { - return fromArray(sources).flatMap(v -> v, sources.length); + return fromArray(sources).flatMap((Function)Functions.identity(), sources.length); + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @BackpressureSupport(BackpressureKind.FULL) + @SchedulerSupport(SchedulerKind.NONE) + public static Observable merge(Publisher p1, Publisher p2) { + Objects.requireNonNull(p1, "p1 is null"); + Objects.requireNonNull(p2, "p2 is null"); + return fromArray(p1, p2).flatMap((Function)Functions.identity(), false, 2); } + @SuppressWarnings({ "unchecked", "rawtypes" }) + @BackpressureSupport(BackpressureKind.FULL) + @SchedulerSupport(SchedulerKind.NONE) + public static Observable merge(Publisher p1, Publisher p2, Publisher p3) { + Objects.requireNonNull(p1, "p1 is null"); + Objects.requireNonNull(p2, "p2 is null"); + Objects.requireNonNull(p3, "p3 is null"); + return fromArray(p1, p2, p3).flatMap((Function)Functions.identity(), false, 3); + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @BackpressureSupport(BackpressureKind.FULL) + @SchedulerSupport(SchedulerKind.NONE) + public static Observable merge( + Publisher p1, Publisher p2, + Publisher p3, Publisher p4) { + Objects.requireNonNull(p1, "p1 is null"); + Objects.requireNonNull(p2, "p2 is null"); + Objects.requireNonNull(p3, "p3 is null"); + Objects.requireNonNull(p4, "p4 is null"); + return fromArray(p1, p2, p3, p4).flatMap((Function)Functions.identity(), false, 4); + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable mergeDelayError(boolean delayErrors, Iterable> sources) { - return fromIterable(sources).flatMap(v -> v, true); + return fromIterable(sources).flatMap((Function)Functions.identity(), true); } + @SuppressWarnings({ "unchecked", "rawtypes" }) @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable mergeDelayError(int maxConcurrency, int bufferSize, Iterable> sources) { - return fromIterable(sources).flatMap(v -> v, true, maxConcurrency, bufferSize); + return fromIterable(sources).flatMap((Function)Functions.identity(), true, maxConcurrency, bufferSize); } + @SuppressWarnings({ "unchecked", "rawtypes" }) @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) - @SafeVarargs public static Observable mergeDelayError(int maxConcurrency, int bufferSize, Publisher... sources) { - return fromArray(sources).flatMap(v -> v, true, maxConcurrency, bufferSize); + return fromArray(sources).flatMap((Function)Functions.identity(), true, maxConcurrency, bufferSize); } + @SuppressWarnings({ "unchecked", "rawtypes" }) @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable mergeDelayError(int maxConcurrency, Iterable> sources) { - return fromIterable(sources).flatMap(v -> v, true, maxConcurrency); + return fromIterable(sources).flatMap((Function)Functions.identity(), true, maxConcurrency); } + @SuppressWarnings({ "unchecked", "rawtypes" }) @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) - @SafeVarargs public static Observable mergeDelayError(int maxConcurrency, Publisher... sources) { - return fromArray(sources).flatMap(v -> v, true, maxConcurrency); + return fromArray(sources).flatMap((Function)Functions.identity(), true, maxConcurrency); } @BackpressureSupport(BackpressureKind.FULL) @@ -788,19 +864,53 @@ public static Observable mergeDelayError(Publisher Observable mergeDelayError(Publisher> sources, int maxConcurrency) { - return fromPublisher(sources).flatMap(v -> v, true, maxConcurrency); + return fromPublisher(sources).flatMap((Function)Functions.identity(), true, maxConcurrency); } + @SuppressWarnings({ "unchecked", "rawtypes" }) @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) - @SafeVarargs public static Observable mergeDelayError(Publisher... sources) { - return fromArray(sources).flatMap(v -> v, true, sources.length); + return fromArray(sources).flatMap((Function)Functions.identity(), true, sources.length); + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @BackpressureSupport(BackpressureKind.FULL) + @SchedulerSupport(SchedulerKind.NONE) + public static Observable mergeDelayError(Publisher p1, Publisher p2) { + Objects.requireNonNull(p1, "p1 is null"); + Objects.requireNonNull(p2, "p2 is null"); + return fromArray(p1, p2).flatMap((Function)Functions.identity(), true, 2); + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @BackpressureSupport(BackpressureKind.FULL) + @SchedulerSupport(SchedulerKind.NONE) + public static Observable mergeDelayError(Publisher p1, Publisher p2, Publisher p3) { + Objects.requireNonNull(p1, "p1 is null"); + Objects.requireNonNull(p2, "p2 is null"); + Objects.requireNonNull(p3, "p3 is null"); + return fromArray(p1, p2, p3).flatMap((Function)Functions.identity(), true, 3); + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @BackpressureSupport(BackpressureKind.FULL) + @SchedulerSupport(SchedulerKind.NONE) + public static Observable mergeDelayError( + Publisher p1, Publisher p2, + Publisher p3, Publisher p4) { + Objects.requireNonNull(p1, "p1 is null"); + Objects.requireNonNull(p2, "p2 is null"); + Objects.requireNonNull(p3, "p3 is null"); + Objects.requireNonNull(p4, "p4 is null"); + return fromArray(p1, p2, p3, p4).flatMap((Function)Functions.identity(), true, 4); } + @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport(SchedulerKind.NONE) @SuppressWarnings("unchecked") @@ -826,21 +936,10 @@ public static Observable range(int start, int count) { return create(new PublisherRangeSource(start, count)); } - /** - * - * @deprecated use composition - */ - @BackpressureSupport(BackpressureKind.FULL) - @SchedulerSupport(SchedulerKind.CUSTOM) - @Deprecated - public static Observable range(int start, int count, Scheduler scheduler) { - return range(start, count).subscribeOn(scheduler); - } - @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable sequenceEqual(Publisher p1, Publisher p2) { - return sequenceEqual(p1, p2, Objects::equals, bufferSize()); + return sequenceEqual(p1, p2, Objects.equalsPredicate(), bufferSize()); } @BackpressureSupport(BackpressureKind.FULL) @@ -852,29 +951,31 @@ public static Observable sequenceEqual(Publisher p1, P @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable sequenceEqual(Publisher p1, Publisher p2, BiPredicate isEqual, int bufferSize) { - Objects.requireNonNull(p1); - Objects.requireNonNull(p2); - Objects.requireNonNull(isEqual); + Objects.requireNonNull(p1, "p1 is null"); + Objects.requireNonNull(p2, "p2 is null"); + Objects.requireNonNull(isEqual, "isEqual is null"); validateBufferSize(bufferSize); - return create(new PublisherSequenceEqual<>(p1, p2, isEqual, bufferSize)); + return create(new PublisherSequenceEqual(p1, p2, isEqual, bufferSize)); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable sequenceEqual(Publisher p1, Publisher p2, int bufferSize) { - return sequenceEqual(p1, p2, Objects::equals, bufferSize); + return sequenceEqual(p1, p2, Objects.equalsPredicate(), bufferSize); } + @SuppressWarnings({ "unchecked", "rawtypes" }) @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable switchOnNext(int bufferSize, Publisher> sources) { - return fromPublisher(sources).switchMap(v -> v, bufferSize); + return fromPublisher(sources).switchMap((Function)Functions.identity(), bufferSize); } + @SuppressWarnings({ "unchecked", "rawtypes" }) @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable switchOnNext(Publisher> sources) { - return fromPublisher(sources).switchMap(v -> v); + return fromPublisher(sources).switchMap((Function)Functions.identity()); } @BackpressureSupport(BackpressureKind.ERROR) @@ -889,23 +990,12 @@ public static Observable timer(long delay, TimeUnit unit, Scheduler schedu if (delay < 0) { delay = 0L; } - Objects.requireNonNull(unit); - Objects.requireNonNull(scheduler); + Objects.requireNonNull(unit, "unit is null"); + Objects.requireNonNull(scheduler, "scheduler is null"); return create(new PublisherIntervalOnceSource(delay, unit, scheduler)); } - @SuppressWarnings("unchecked") - private static Function toFunction(BiFunction biFunction) { - Objects.requireNonNull(biFunction); - return a -> { - if (a.length != 2) { - throw new IllegalArgumentException("Array of size 2 expected but got " + a.length); - } - return ((BiFunction)biFunction).apply(a[0], a[1]); - }; - } - @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport(SchedulerKind.NONE) public static Observable using(Supplier resourceSupplier, Function> sourceSupplier, Consumer disposer) { @@ -915,10 +1005,10 @@ public static Observable using(Supplier resourceSupplier, @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport(SchedulerKind.NONE) public static Observable using(Supplier resourceSupplier, Function> sourceSupplier, Consumer disposer, boolean eager) { - Objects.requireNonNull(resourceSupplier); - Objects.requireNonNull(sourceSupplier); - Objects.requireNonNull(disposer); - return create(new PublisherUsing<>(resourceSupplier, sourceSupplier, disposer, eager)); + Objects.requireNonNull(resourceSupplier, "resourceSupplier is null"); + Objects.requireNonNull(sourceSupplier, "sourceSupplier is null"); + Objects.requireNonNull(disposer, "disposer is null"); + return create(new PublisherUsing(resourceSupplier, sourceSupplier, disposer, eager)); } private static void validateBufferSize(int bufferSize) { @@ -930,79 +1020,91 @@ private static void validateBufferSize(int bufferSize) { @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable zip(Iterable> sources, Function zipper) { - Objects.requireNonNull(zipper); - Objects.requireNonNull(sources); - return create(new PublisherZip<>(null, sources, zipper, bufferSize(), false)); + Objects.requireNonNull(zipper, "zipper is null"); + Objects.requireNonNull(sources, "sources is null"); + return create(new PublisherZip(null, sources, zipper, bufferSize(), false)); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) - public static Observable zip(Publisher> sources, Function zipper) { - return fromPublisher(sources).toList().flatMap(list -> { - return zipIterable(zipper, false, bufferSize(), list); + public static Observable zip(Publisher> sources, final Function zipper) { + Objects.requireNonNull(zipper, "zipper is null"); + return fromPublisher(sources).toList().flatMap(new Function>, Publisher>() { + @Override + public Publisher apply(List> list) { + return zipIterable(zipper, false, bufferSize(), list); + } }); } + @SuppressWarnings("unchecked") @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable zip( Publisher p1, Publisher p2, BiFunction zipper) { - return zipArray(toFunction(zipper), false, bufferSize(), p1, p2); + return zipArray(Functions.toFunction(zipper), false, bufferSize(), p1, p2); } + @SuppressWarnings("unchecked") @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable zip( Publisher p1, Publisher p2, BiFunction zipper, boolean delayError) { - return zipArray(toFunction(zipper), delayError, bufferSize(), p1, p2); + return zipArray(Functions.toFunction(zipper), delayError, bufferSize(), p1, p2); } + @SuppressWarnings("unchecked") @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable zip( Publisher p1, Publisher p2, BiFunction zipper, boolean delayError, int bufferSize) { - return zipArray(toFunction(zipper), delayError, bufferSize, p1, p2); + return zipArray(Functions.toFunction(zipper), delayError, bufferSize, p1, p2); } + @SuppressWarnings("unchecked") @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable zip( Publisher p1, Publisher p2, Publisher p3, Function3 zipper) { - return zipArray(zipper, false, bufferSize(), p1, p2, p3); + return zipArray(Functions.toFunction(zipper), false, bufferSize(), p1, p2, p3); } + @SuppressWarnings("unchecked") @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable zip( Publisher p1, Publisher p2, Publisher p3, Publisher p4, Function4 zipper) { - return zipArray(zipper, false, bufferSize(), p1, p2, p3, p4); + return zipArray(Functions.toFunction(zipper), false, bufferSize(), p1, p2, p3, p4); } + @SuppressWarnings("unchecked") @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable zip( Publisher p1, Publisher p2, Publisher p3, Publisher p4, Publisher p5, Function5 zipper) { - return zipArray(zipper, false, bufferSize(), p1, p2, p3, p4, p5); + return zipArray(Functions.toFunction(zipper), false, bufferSize(), p1, p2, p3, p4, p5); } + @SuppressWarnings("unchecked") @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable zip( Publisher p1, Publisher p2, Publisher p3, Publisher p4, Publisher p5, Publisher p6, Function6 zipper) { - return zipArray(zipper, false, bufferSize(), p1, p2, p3, p4, p5, p6); + return zipArray(Functions.toFunction(zipper), false, bufferSize(), p1, p2, p3, p4, p5, p6); } + @SuppressWarnings("unchecked") @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable zip( @@ -1010,9 +1112,10 @@ public static Observable zip( Publisher p4, Publisher p5, Publisher p6, Publisher p7, Function7 zipper) { - return zipArray(zipper, false, bufferSize(), p1, p2, p3, p4, p5, p6, p7); + return zipArray(Functions.toFunction(zipper), false, bufferSize(), p1, p2, p3, p4, p5, p6, p7); } + @SuppressWarnings("unchecked") @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable zip( @@ -1020,9 +1123,10 @@ public static Observable zip( Publisher p4, Publisher p5, Publisher p6, Publisher p7, Publisher p8, Function8 zipper) { - return zipArray(zipper, false, bufferSize(), p1, p2, p3, p4, p5, p6, p7, p8); + return zipArray(Functions.toFunction(zipper), false, bufferSize(), p1, p2, p3, p4, p5, p6, p7, p8); } + @SuppressWarnings("unchecked") @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable zip( @@ -1030,20 +1134,19 @@ public static Observable zip( Publisher p4, Publisher p5, Publisher p6, Publisher p7, Publisher p8, Publisher p9, Function9 zipper) { - return zipArray(zipper, false, bufferSize(), p1, p2, p3, p4, p5, p6, p7, p8, p9); + return zipArray(Functions.toFunction(zipper), false, bufferSize(), p1, p2, p3, p4, p5, p6, p7, p8, p9); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) - @SafeVarargs public static Observable zipArray(Function zipper, boolean delayError, int bufferSize, Publisher... sources) { if (sources.length == 0) { return empty(); } - Objects.requireNonNull(zipper); + Objects.requireNonNull(zipper, "zipper is null"); validateBufferSize(bufferSize); - return create(new PublisherZip<>(sources, null, zipper, bufferSize, delayError)); + return create(new PublisherZip(sources, null, zipper, bufferSize, delayError)); } @BackpressureSupport(BackpressureKind.FULL) @@ -1051,10 +1154,10 @@ public static Observable zipArray(Function Observable zipIterable(Function zipper, boolean delayError, int bufferSize, Iterable> sources) { - Objects.requireNonNull(zipper); - Objects.requireNonNull(sources); + Objects.requireNonNull(zipper, "zipper is null"); + Objects.requireNonNull(sources, "sources is null"); validateBufferSize(bufferSize); - return create(new PublisherZip<>(null, sources, zipper, bufferSize, delayError)); + return create(new PublisherZip(null, sources, zipper, bufferSize, delayError)); } final Publisher onSubscribe; @@ -1066,27 +1169,34 @@ protected Observable(Publisher onSubscribe) { @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerKind.NONE) public final Observable all(Predicate predicate) { - Objects.requireNonNull(predicate); - return lift(new OperatorAll<>(predicate)); + Objects.requireNonNull(predicate, "predicate is null"); + return lift(new OperatorAll(predicate)); } + @SuppressWarnings("unchecked") @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable ambWith(Publisher other) { + Objects.requireNonNull(other, "other is null"); return amb(this, other); } @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerKind.NONE) public final Observable any(Predicate predicate) { - Objects.requireNonNull(predicate); - return lift(new OperatorAny<>(predicate)); + Objects.requireNonNull(predicate, "predicate is null"); + return lift(new OperatorAny(predicate)); } @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport(SchedulerKind.NONE) public final Observable asObservable() { - return create(s -> this.subscribe(s)); + return create(new Publisher() { + @Override + public void subscribe(Subscriber s) { + Observable.this.subscribe(s); + } + }); } @BackpressureSupport(BackpressureKind.FULL) @@ -1098,13 +1208,19 @@ public final Observable> buffer(int count) { @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable> buffer(int count, int skip) { - return buffer(count, skip, ArrayList::new); + return buffer(count, skip, new Supplier>() { + @Override + public List get() { + return new ArrayList(); + } + }); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final > Observable buffer(int count, int skip, Supplier bufferSupplier) { - return lift(new OperatorBuffer<>(count, skip, bufferSupplier)); + Objects.requireNonNull(bufferSupplier, "bufferSupplier is null"); + return lift(new OperatorBuffer(count, skip, bufferSupplier)); } @BackpressureSupport(BackpressureKind.FULL) @@ -1116,22 +1232,32 @@ public final > Observable buffer(int count, S @BackpressureSupport(BackpressureKind.ERROR) @SchedulerSupport(SchedulerKind.COMPUTATION) public final Observable> buffer(long timespan, long timeskip, TimeUnit unit) { - return buffer(timespan, timeskip, unit, Schedulers.computation(), ArrayList::new); + return buffer(timespan, timeskip, unit, Schedulers.computation(), new Supplier>() { + @Override + public List get() { + return new ArrayList(); + } + }); } @BackpressureSupport(BackpressureKind.ERROR) @SchedulerSupport(SchedulerKind.CUSTOM) public final Observable> buffer(long timespan, long timeskip, TimeUnit unit, Scheduler scheduler) { - return buffer(timespan, timeskip, unit, scheduler, ArrayList::new); + return buffer(timespan, timeskip, unit, scheduler, new Supplier>() { + @Override + public List get() { + return new ArrayList(); + } + }); } @BackpressureSupport(BackpressureKind.ERROR) @SchedulerSupport(SchedulerKind.CUSTOM) public final > Observable buffer(long timespan, long timeskip, TimeUnit unit, Scheduler scheduler, Supplier bufferSupplier) { - Objects.requireNonNull(unit); - Objects.requireNonNull(scheduler); - Objects.requireNonNull(bufferSupplier); - return lift(new OperatorBufferTimed<>(timespan, timeskip, unit, scheduler, bufferSupplier, Integer.MAX_VALUE, false)); + Objects.requireNonNull(unit, "unit is null"); + Objects.requireNonNull(scheduler, "scheduler is null"); + Objects.requireNonNull(bufferSupplier, "bufferSupplier is null"); + return lift(new OperatorBufferTimed(timespan, timeskip, unit, scheduler, bufferSupplier, Integer.MAX_VALUE, false)); } @BackpressureSupport(BackpressureKind.ERROR) @@ -1149,7 +1275,12 @@ public final Observable> buffer(long timespan, TimeUnit unit, int count) @BackpressureSupport(BackpressureKind.ERROR) @SchedulerSupport(SchedulerKind.CUSTOM) public final Observable> buffer(long timespan, TimeUnit unit, int count, Scheduler scheduler) { - return buffer(timespan, unit, count, scheduler, ArrayList::new, false); + return buffer(timespan, unit, count, scheduler, new Supplier>() { + @Override + public List get() { + return new ArrayList(); + } + }, false); } @BackpressureSupport(BackpressureKind.ERROR) @@ -1159,19 +1290,24 @@ public final > Observable buffer( int count, Scheduler scheduler, Supplier bufferSupplier, boolean restartTimerOnMaxSize) { - Objects.requireNonNull(unit); - Objects.requireNonNull(scheduler); - Objects.requireNonNull(bufferSupplier); + Objects.requireNonNull(unit, "unit is null"); + Objects.requireNonNull(scheduler, "scheduler is null"); + Objects.requireNonNull(bufferSupplier, "bufferSupplier is null"); if (count <= 0) { throw new IllegalArgumentException("count > 0 required but it was " + count); } - return lift(new OperatorBufferTimed<>(timespan, timespan, unit, scheduler, bufferSupplier, count, restartTimerOnMaxSize)); + return lift(new OperatorBufferTimed(timespan, timespan, unit, scheduler, bufferSupplier, count, restartTimerOnMaxSize)); } @BackpressureSupport(BackpressureKind.ERROR) @SchedulerSupport(SchedulerKind.CUSTOM) public final Observable> buffer(long timespan, TimeUnit unit, Scheduler scheduler) { - return buffer(timespan, unit, Integer.MAX_VALUE, scheduler, ArrayList::new, false); + return buffer(timespan, unit, Integer.MAX_VALUE, scheduler, new Supplier>() { + @Override + public List get() { + return new ArrayList(); + } + }, false); } @BackpressureSupport(BackpressureKind.ERROR) @@ -1179,7 +1315,12 @@ public final Observable> buffer(long timespan, TimeUnit unit, Scheduler public final Observable> buffer( Observable bufferOpenings, Function> bufferClosingSelector) { - return buffer(bufferOpenings, bufferClosingSelector, ArrayList::new); + return buffer(bufferOpenings, bufferClosingSelector, new Supplier>() { + @Override + public List get() { + return new ArrayList(); + } + }); } @BackpressureSupport(BackpressureKind.ERROR) @@ -1188,48 +1329,63 @@ public final > Observable Observable bufferOpenings, Function> bufferClosingSelector, Supplier bufferSupplier) { - Objects.requireNonNull(bufferOpenings); - Objects.requireNonNull(bufferClosingSelector); - Objects.requireNonNull(bufferSupplier); - return lift(new OperatorBufferBoundary<>(bufferOpenings, bufferClosingSelector, bufferSupplier)); + Objects.requireNonNull(bufferOpenings, "bufferOpenings is null"); + Objects.requireNonNull(bufferClosingSelector, "bufferClosingSelector is null"); + Objects.requireNonNull(bufferSupplier, "bufferSupplier is null"); + return lift(new OperatorBufferBoundary(bufferOpenings, bufferClosingSelector, bufferSupplier)); } @BackpressureSupport(BackpressureKind.ERROR) @SchedulerSupport(SchedulerKind.NONE) - public final Observable> buffer(Observable boundary) { + public final Observable> buffer(Publisher boundary) { /* * XXX: javac complains if this is not manually cast, Eclipse is fine */ - return buffer(boundary, (Supplier>)ArrayList::new); + return buffer(boundary, new Supplier>() { + @Override + public List get() { + return new ArrayList(); + } + }); } @BackpressureSupport(BackpressureKind.ERROR) @SchedulerSupport(SchedulerKind.NONE) - public final Observable> buffer(Observable boundary, int initialCapacity) { - return buffer(boundary, () -> new ArrayList<>(initialCapacity)); + public final Observable> buffer(Publisher boundary, final int initialCapacity) { + return buffer(boundary, new Supplier>() { + @Override + public List get() { + return new ArrayList(initialCapacity); + } + }); } @BackpressureSupport(BackpressureKind.ERROR) @SchedulerSupport(SchedulerKind.NONE) - public final > Observable buffer(Observable boundary, Supplier bufferSupplier) { - Objects.requireNonNull(boundary); - Objects.requireNonNull(bufferSupplier); - return lift(new OperatorBufferExactBoundary<>(boundary, bufferSupplier)); + public final > Observable buffer(Publisher boundary, Supplier bufferSupplier) { + Objects.requireNonNull(boundary, "boundary is null"); + Objects.requireNonNull(bufferSupplier, "bufferSupplier is null"); + return lift(new OperatorBufferExactBoundary(boundary, bufferSupplier)); } @BackpressureSupport(BackpressureKind.ERROR) @SchedulerSupport(SchedulerKind.NONE) - public final Observable> buffer(Supplier> boundarySupplier) { - return buffer(boundarySupplier, ArrayList::new); + public final Observable> buffer(Supplier> boundarySupplier) { + return buffer(boundarySupplier, new Supplier>() { + @Override + public List get() { + return new ArrayList(); + } + }); } @BackpressureSupport(BackpressureKind.ERROR) @SchedulerSupport(SchedulerKind.NONE) - public final > Observable buffer(Supplier> boundarySupplier, Supplier bufferSupplier) { - Objects.requireNonNull(boundarySupplier); - Objects.requireNonNull(bufferSupplier); - return lift(new OperatorBufferBoundarySupplier<>(boundarySupplier, bufferSupplier)); + public final > Observable buffer(Supplier> boundarySupplier, Supplier bufferSupplier) { + Objects.requireNonNull(boundarySupplier, "boundarySupplier is null"); + Objects.requireNonNull(bufferSupplier, "bufferSupplier is null"); + return lift(new OperatorBufferBoundarySupplier(boundarySupplier, bufferSupplier)); } @BackpressureSupport(BackpressureKind.FULL) @@ -1241,27 +1397,42 @@ public final Observable cache() { @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable cache(int capacityHint) { + if (capacityHint <= 0) { + throw new IllegalArgumentException("capacityHint > 0 required but it was " + capacityHint); + } return CachedObservable.from(this, capacityHint); } @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport(SchedulerKind.NONE) - public final Observable cast(Class clazz) { - return map(clazz::cast); + public final Observable cast(final Class clazz) { + Objects.requireNonNull(clazz, "clazz is null"); + return map(new Function() { + @Override + public U apply(T v) { + return clazz.cast(v); + } + }); } @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerKind.NONE) public final Observable collect(Supplier initialValueSupplier, BiConsumer collector) { - Objects.requireNonNull(initialValueSupplier); - Objects.requireNonNull(collector); - return lift(new OperatorCollect<>(initialValueSupplier, collector)); + Objects.requireNonNull(initialValueSupplier, "initialValueSupplier is null"); + Objects.requireNonNull(collector, "collectior is null"); + return lift(new OperatorCollect(initialValueSupplier, collector)); } @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerKind.NONE) - public final Observable collectInto(U initialValue, BiConsumer collector) { - return collect(() -> initialValue, collector); + public final Observable collectInto(final U initialValue, BiConsumer collector) { + Objects.requireNonNull(initialValue, "initialValue is null"); + return collect(new Supplier() { + @Override + public U get() { + return initialValue; + } + }, collector); } @BackpressureSupport(BackpressureKind.PASS_THROUGH) @@ -1280,37 +1451,48 @@ public final Observable concatMap(Function Observable concatMap(Function> mapper, int prefetch) { - Objects.requireNonNull(mapper); + Objects.requireNonNull(mapper, "mapper is null"); if (prefetch <= 0) { throw new IllegalArgumentException("prefetch > 0 required but it was " + prefetch); } - return lift(new OperatorConcatMap<>(mapper, prefetch)); + return lift(new OperatorConcatMap(mapper, prefetch)); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable concatMapIterable(Function> mapper) { - return concatMap(v -> new PublisherIterableSource<>(mapper.apply(v))); + return concatMapIterable(mapper, 2); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) - public final Observable concatMapIterable(Function> mapper, int prefetch) { - return concatMap(v -> new PublisherIterableSource<>(mapper.apply(v)), prefetch); + public final Observable concatMapIterable(final Function> mapper, int prefetch) { + Objects.requireNonNull(mapper, "mapper is null"); + return concatMap(new Function>() { + @Override + public Publisher apply(T v) { + return new PublisherIterableSource(mapper.apply(v)); + } + }, prefetch); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable concatWith(Publisher other) { - Objects.requireNonNull(other); + Objects.requireNonNull(other, "other is null"); return concat(this, other); } @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerKind.NONE) - public final Observable contains(Object o) { - Objects.requireNonNull(o); - return any(v -> Objects.equals(v, o)); + public final Observable contains(final Object o) { + Objects.requireNonNull(o, "o is null"); + return any(new Predicate() { + @Override + public boolean test(T v) { + return Objects.equals(v, o); + } + }); } @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @@ -1322,8 +1504,8 @@ public final Observable count() { @BackpressureSupport(BackpressureKind.ERROR) @SchedulerSupport(SchedulerKind.NONE) public final Observable debounce(Function> debounceSelector) { - Objects.requireNonNull(debounceSelector); - return lift(new OperatorDebounce<>(debounceSelector)); + Objects.requireNonNull(debounceSelector, "debounceSelector is null"); + return lift(new OperatorDebounce(debounceSelector)); } @BackpressureSupport(BackpressureKind.ERROR) @@ -1335,24 +1517,34 @@ public final Observable debounce(long timeout, TimeUnit unit) { @BackpressureSupport(BackpressureKind.ERROR) @SchedulerSupport(SchedulerKind.CUSTOM) public final Observable debounce(long timeout, TimeUnit unit, Scheduler scheduler) { - Objects.requireNonNull(unit); - Objects.requireNonNull(scheduler); - return lift(new OperatorDebounceTimed<>(timeout, unit, scheduler)); + Objects.requireNonNull(unit, "unit is null"); + Objects.requireNonNull(scheduler, "scheduler is null"); + return lift(new OperatorDebounceTimed(timeout, unit, scheduler)); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable defaultIfEmpty(T value) { - Objects.requireNonNull(value); + Objects.requireNonNull(value, "value is null"); return switchIfEmpty(just(value)); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) // TODO a more efficient implementation if necessary - public final Observable delay(Function> itemDelay) { - Objects.requireNonNull(itemDelay); - return flatMap(v -> fromPublisher(itemDelay.apply(v)).take(1).map(u -> v).defaultIfEmpty(v)); + public final Observable delay(final Function> itemDelay) { + Objects.requireNonNull(itemDelay, "itemDelay is null"); + return flatMap(new Function>() { + @Override + public Publisher apply(final T v) { + return fromPublisher(itemDelay.apply(v)).take(1).map(new Function() { + @Override + public T apply(U u) { + return v; + } + }).defaultIfEmpty(v); + } + }); } @BackpressureSupport(BackpressureKind.FULL) @@ -1376,10 +1568,10 @@ public final Observable delay(long delay, TimeUnit unit, Scheduler scheduler) @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.CUSTOM) public final Observable delay(long delay, TimeUnit unit, Scheduler scheduler, boolean delayError) { - Objects.requireNonNull(unit); - Objects.requireNonNull(scheduler); + Objects.requireNonNull(unit, "unit is null"); + Objects.requireNonNull(scheduler, "scheduler is null"); - return lift(new OperatorDelay<>(delay, unit, scheduler, delayError)); + return lift(new OperatorDelay(delay, unit, scheduler, delayError)); } @BackpressureSupport(BackpressureKind.FULL) @@ -1388,6 +1580,30 @@ public final Observable delay(Supplier> delaySu Function> itemDelay) { return delaySubscription(delaySupplier).delay(itemDelay); } + + /** + * Returns an Observable that delays the subscription to this Observable + * until the other Observable emits an element or completes normally. + *

+ *

+ *
Backpressure:
+ *
The operator forwards the backpressure requests to this Observable once + * the subscription happens and requests Long.MAX_VALUE from the other Observable
+ *
Scheduler:
+ *
This method does not operate by default on a particular {@link Scheduler}.
+ *
+ * + * @param the value type of the other Observable, irrelevant + * @param other the other Observable that should trigger the subscription + * to this Observable. + * @return an Observable that delays the subscription to this Observable + * until the other Observable emits an element or completes normally. + */ + @Experimental + public final Observable delaySubscription(Publisher other) { + Objects.requireNonNull(other, "other is null"); + return create(new PublisherDelaySubscriptionOther(this, other)); + } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.COMPUTATION) @@ -1399,16 +1615,40 @@ public final Observable delaySubscription(long delay, TimeUnit unit) { @SchedulerSupport(SchedulerKind.CUSTOM) // TODO a more efficient implementation if necessary public final Observable delaySubscription(long delay, TimeUnit unit, Scheduler scheduler) { - Objects.requireNonNull(unit); - Objects.requireNonNull(scheduler); + Objects.requireNonNull(unit, "unit is null"); + Objects.requireNonNull(scheduler, "scheduler is null"); - return timer(delay, unit, scheduler).flatMap(v -> this); + return timer(delay, unit, scheduler).flatMap(new Function>() { + @Override + public Publisher apply(Long v) { + return Observable.this; + } + }); } + private static final Object OBJECT = new Object(); + + @SuppressWarnings({ "rawtypes", "unchecked" }) @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) - public final Observable delaySubscription(Supplier> delaySupplier) { - return fromCallable(delaySupplier::get).take(1).flatMap(v -> this); + public final Observable delaySubscription(final Supplier> delaySupplier) { + Objects.requireNonNull(delaySupplier, "delaySupplier is null"); + return fromCallable(new Callable() { + @Override + public Object call() throws Exception { + return delaySupplier.get(); + } + }) + .flatMap((Function)Functions.identity()) + .take(1) + .cast(Object.class) // need a common supertype, the value is not relevant + .defaultIfEmpty(OBJECT) // in case the publisher is empty + .flatMap(new Function() { + @Override + public Object apply(Object v) { + return Observable.this; + } + }); } @BackpressureSupport(BackpressureKind.FULL) @@ -1416,123 +1656,171 @@ public final Observable delaySubscription(Supplier public final Observable dematerialize() { @SuppressWarnings("unchecked") Observable>> m = (Observable>>)this; - return m.lift(OperatorDematerialize.instance()); + return m.lift(OperatorDematerialize.instance()); } + @SuppressWarnings({ "rawtypes", "unchecked" }) @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable distinct() { - return distinct(v -> v, HashSet::new); + return distinct((Function)Functions.identity(), new Supplier>() { + @Override + public Collection get() { + return new HashSet(); + } + }); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable distinct(Function keySelector) { - return distinct(keySelector, HashSet::new); + return distinct(keySelector, new Supplier>() { + @Override + public Collection get() { + return new HashSet(); + } + }); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable distinct(Function keySelector, Supplier> collectionSupplier) { + Objects.requireNonNull(keySelector, "keySelector is null"); + Objects.requireNonNull(collectionSupplier, "collectionSupplier is null"); return lift(OperatorDistinct.withCollection(keySelector, collectionSupplier)); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable distinctUntilChanged() { - return lift(OperatorDistinct.untilChanged()); + return lift(OperatorDistinct.untilChanged()); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable distinctUntilChanged(Function keySelector) { + Objects.requireNonNull(keySelector, "keySelector is null"); return lift(OperatorDistinct.untilChanged(keySelector)); } @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport(SchedulerKind.NONE) public final Observable doOnCancel(Runnable onCancel) { - return doOnLifecycle(s -> { }, n -> { }, onCancel); + return doOnLifecycle(Functions.emptyConsumer(), Functions.emptyLongConsumer(), onCancel); } @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport(SchedulerKind.NONE) public final Observable doOnComplete(Runnable onComplete) { - return doOnEach(v -> { }, e -> { }, onComplete, () -> { }); + return doOnEach(Functions.emptyConsumer(), Functions.emptyConsumer(), onComplete, Functions.emptyRunnable()); } @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport(SchedulerKind.NONE) private Observable doOnEach(Consumer onNext, Consumer onError, Runnable onComplete, Runnable onAfterTerminate) { - Objects.requireNonNull(onNext); - Objects.requireNonNull(onError); - Objects.requireNonNull(onComplete); - Objects.requireNonNull(onAfterTerminate); - return lift(new OperatorDoOnEach<>(onNext, onError, onComplete, onAfterTerminate)); + Objects.requireNonNull(onNext, "onNext is null"); + Objects.requireNonNull(onError, "onError is null"); + Objects.requireNonNull(onComplete, "onComplete is null"); + Objects.requireNonNull(onAfterTerminate, "onAfterTerminate is null"); + return lift(new OperatorDoOnEach(onNext, onError, onComplete, onAfterTerminate)); } @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport(SchedulerKind.NONE) - public final Observable doOnEach(Consumer>> consumer) { + public final Observable doOnEach(final Consumer>> consumer) { + Objects.requireNonNull(consumer, "consumer is null"); return doOnEach( - v -> consumer.accept(Try.ofValue(Optional.of(v))), - e -> consumer.accept(Try.ofError(e)), - () -> consumer.accept(Try.ofValue(Optional.empty())), - () -> { } + new Consumer() { + @Override + public void accept(T v) { + consumer.accept(Try.ofValue(Optional.of(v))); + } + }, + new Consumer() { + @Override + public void accept(Throwable e) { + consumer.accept(Try.>ofError(e)); + } + }, + new Runnable() { + @Override + public void run() { + consumer.accept(Try.ofValue(Optional.empty())); + } + }, + Functions.emptyRunnable() ); } @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport(SchedulerKind.NONE) - public final Observable doOnEach(Subscriber observer) { - return doOnEach(observer::onNext, observer::onError, observer::onComplete, () -> { }); + public final Observable doOnEach(final Subscriber observer) { + Objects.requireNonNull(observer, "observer is null"); + return doOnEach(new Consumer() { + @Override + public void accept(T v) { + observer.onNext(v); + } + }, new Consumer() { + @Override + public void accept(Throwable e) { + observer.onError(e); + } + }, new Runnable() { + @Override + public void run() { + observer.onComplete(); + } + }, Functions.emptyRunnable()); } @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport(SchedulerKind.NONE) public final Observable doOnError(Consumer onError) { - return doOnEach(v -> { }, onError, () -> { }, () -> { }); + return doOnEach(Functions.emptyConsumer(), onError, Functions.emptyRunnable(), Functions.emptyRunnable()); } @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport(SchedulerKind.NONE) - public final Observable doOnLifecycle(Consumer onSubscribe, LongConsumer onRequest, Runnable onCancel) { - return lift(s -> new SubscriptionLambdaSubscriber<>(s, onSubscribe, onRequest, onCancel)); + public final Observable doOnLifecycle(final Consumer onSubscribe, final LongConsumer onRequest, final Runnable onCancel) { + Objects.requireNonNull(onSubscribe, "onSubscribe is null"); + Objects.requireNonNull(onRequest, "onRequest is null"); + Objects.requireNonNull(onCancel, "onCancel is null"); + return lift(new Operator() { + @Override + public Subscriber apply(Subscriber s) { + return new SubscriptionLambdaSubscriber(s, onSubscribe, onRequest, onCancel); + } + }); } @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport(SchedulerKind.NONE) public final Observable doOnNext(Consumer onNext) { - return doOnEach(onNext, e -> { }, () -> { }, () -> { }); + return doOnEach(onNext, Functions.emptyConsumer(), Functions.emptyRunnable(), Functions.emptyRunnable()); } @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport(SchedulerKind.NONE) public final Observable doOnRequest(LongConsumer onRequest) { - return doOnLifecycle(s -> { }, onRequest, () -> { }); + return doOnLifecycle(Functions.emptyConsumer(), onRequest, Functions.emptyRunnable()); } @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport(SchedulerKind.NONE) public final Observable doOnSubscribe(Consumer onSubscribe) { - return doOnLifecycle(onSubscribe, n -> { }, () -> { }); + return doOnLifecycle(onSubscribe, Functions.emptyLongConsumer(), Functions.emptyRunnable()); } @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport(SchedulerKind.NONE) - public final Observable doOnTerminate(Runnable onTerminate) { - return doOnEach(v -> { }, e -> onTerminate.run(), onTerminate, () -> { }); - } - - /** - * - * @deprecated use {@link #doOnCancel(Runnable)} instead - */ - @BackpressureSupport(BackpressureKind.PASS_THROUGH) - @SchedulerSupport(SchedulerKind.NONE) - @Deprecated - public final Observable doOnUnsubscribe(Runnable onUnsubscribe) { - return doOnCancel(onUnsubscribe); + public final Observable doOnTerminate(final Runnable onTerminate) { + return doOnEach(Functions.emptyConsumer(), new Consumer() { + @Override + public void accept(Throwable e) { + onTerminate.run(); + } + }, onTerminate, Functions.emptyRunnable()); } @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @@ -1541,7 +1829,7 @@ public final Observable elementAt(long index) { if (index < 0) { throw new IndexOutOfBoundsException("index >= 0 required but it was " + index); } - return lift(new OperatorElementAt<>(index, null)); + return lift(new OperatorElementAt(index, null)); } @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @@ -1550,34 +1838,37 @@ public final Observable elementAt(long index, T defaultValue) { if (index < 0) { throw new IndexOutOfBoundsException("index >= 0 required but it was " + index); } - Objects.requireNonNull(defaultValue); - return lift(new OperatorElementAt<>(index, defaultValue)); + Objects.requireNonNull(defaultValue, "defaultValue is null"); + return lift(new OperatorElementAt(index, defaultValue)); } + @SuppressWarnings("unchecked") @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable endWith(Iterable values) { return concatArray(this, fromIterable(values)); } + @SuppressWarnings("unchecked") @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable endWith(Publisher other) { - Objects.requireNonNull(other); + Objects.requireNonNull(other, "other is null"); return concatArray(this, other); } + @SuppressWarnings("unchecked") @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable endWith(T value) { - Objects.requireNonNull(value); + Objects.requireNonNull(value, "value is null"); return concatArray(this, just(value)); } + @SuppressWarnings("unchecked") @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) - @SafeVarargs public final Observable endWithArray(T... values) { Observable fromArray = fromArray(values); if (fromArray == empty()) { @@ -1586,27 +1877,17 @@ public final Observable endWithArray(T... values) { return concatArray(this, fromArray); } - /** - * @deprecated use {@link #any(Predicate)} - */ - @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) - @SchedulerSupport(SchedulerKind.NONE) - @Deprecated - public final Observable exists(Predicate predicate) { - return any(predicate); - } - @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport(SchedulerKind.NONE) public final Observable filter(Predicate predicate) { - Objects.requireNonNull(predicate); - return lift(new OperatorFilter<>(predicate)); + Objects.requireNonNull(predicate, "predicate is null"); + return lift(new OperatorFilter(predicate)); } @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport(SchedulerKind.NONE) public final Observable finallyDo(Runnable onFinally) { - return doOnEach(v -> { }, e -> { }, () -> { }, onFinally); + return doOnEach(Functions.emptyConsumer(), Functions.emptyConsumer(), Functions.emptyRunnable(), onFinally); } @BackpressureSupport(BackpressureKind.SPECIAL) // take may trigger UNBOUNDED_IN @@ -1643,7 +1924,7 @@ public final Observable flatMap(Function Observable flatMap(Function> mapper, boolean delayErrors, int maxConcurrency, int bufferSize) { - Objects.requireNonNull(mapper); + Objects.requireNonNull(mapper, "mapper is null"); if (maxConcurrency <= 0) { throw new IllegalArgumentException("maxConcurrency > 0 required but it was " + maxConcurrency); } @@ -1652,7 +1933,7 @@ public final Observable flatMap(Function scalar = (ObservableScalarSource) this; return create(scalar.scalarFlatMap(mapper)); } - return lift(new OperatorFlatMap<>(mapper, delayErrors, maxConcurrency, bufferSize)); + return lift(new OperatorFlatMap(mapper, delayErrors, maxConcurrency, bufferSize)); } @BackpressureSupport(BackpressureKind.FULL) @@ -1661,7 +1942,10 @@ public final Observable flatMap( Function> onNextMapper, Function> onErrorMapper, Supplier> onCompleteSupplier) { - return merge(lift(new OperatorMapNotification<>(onNextMapper, onErrorMapper, onCompleteSupplier))); + Objects.requireNonNull(onNextMapper, "onNextMapper is null"); + Objects.requireNonNull(onErrorMapper, "onErrorMapper is null"); + Objects.requireNonNull(onCompleteSupplier, "onCompleteSupplier is null"); + return merge(lift(new OperatorMapNotification(onNextMapper, onErrorMapper, onCompleteSupplier))); } @BackpressureSupport(BackpressureKind.FULL) @@ -1671,7 +1955,10 @@ public final Observable flatMap( Function> onErrorMapper, Supplier> onCompleteSupplier, int maxConcurrency) { - return merge(lift(new OperatorMapNotification<>(onNextMapper, onErrorMapper, onCompleteSupplier)), maxConcurrency); + Objects.requireNonNull(onNextMapper, "onNextMapper is null"); + Objects.requireNonNull(onErrorMapper, "onErrorMapper is null"); + Objects.requireNonNull(onCompleteSupplier, "onCompleteSupplier is null"); + return merge(lift(new OperatorMapNotification(onNextMapper, onErrorMapper, onCompleteSupplier)), maxConcurrency); } @BackpressureSupport(BackpressureKind.FULL) @@ -1700,10 +1987,20 @@ public final Observable flatMap(Function Observable flatMap(Function> mapper, BiFunction combiner, boolean delayError, int maxConcurrency, int bufferSize) { - return flatMap(t -> { - Observable u = fromPublisher(mapper.apply(t)); - return u.map(w -> combiner.apply(t, w)); + public final Observable flatMap(final Function> mapper, final BiFunction combiner, boolean delayError, int maxConcurrency, int bufferSize) { + Objects.requireNonNull(mapper, "mapper is null"); + Objects.requireNonNull(combiner, "combiner is null"); + return flatMap(new Function>() { + @Override + public Publisher apply(final T t) { + Observable u = fromPublisher(mapper.apply(t)); + return u.map(new Function() { + @Override + public R apply(U w) { + return combiner.apply(t, w); + } + }); + } }, delayError, maxConcurrency, bufferSize); } @@ -1715,20 +2012,38 @@ public final Observable flatMap(Function Observable flatMapIterable(Function> mapper) { - return flatMap(v -> new PublisherIterableSource<>(mapper.apply(v))); + public final Observable flatMapIterable(final Function> mapper) { + Objects.requireNonNull(mapper, "mapper is null"); + return flatMap(new Function>() { + @Override + public Publisher apply(T v) { + return new PublisherIterableSource(mapper.apply(v)); + } + }); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) - public final Observable flatMapIterable(Function> mapper, BiFunction resultSelector) { - return flatMap(t -> new PublisherIterableSource<>(mapper.apply(t)), resultSelector, false, bufferSize(), bufferSize()); + public final Observable flatMapIterable(final Function> mapper, final BiFunction resultSelector) { + Objects.requireNonNull(mapper, "mapper is null"); + Objects.requireNonNull(resultSelector, "resultSelector is null"); + return flatMap(new Function>() { + @Override + public Publisher apply(T t) { + return new PublisherIterableSource(mapper.apply(t)); + } + }, resultSelector, false, bufferSize(), bufferSize()); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) - public final Observable flatMapIterable(Function> mapper, int bufferSize) { - return flatMap(v -> new PublisherIterableSource<>(mapper.apply(v)), false, bufferSize); + public final Observable flatMapIterable(final Function> mapper, int bufferSize) { + return flatMap(new Function>() { + @Override + public Publisher apply(T v) { + return new PublisherIterableSource(mapper.apply(v)); + } + }, false, bufferSize); } @BackpressureSupport(BackpressureKind.NONE) @@ -1740,45 +2055,51 @@ public final Disposable forEach(Consumer onNext) { @BackpressureSupport(BackpressureKind.NONE) @SchedulerSupport(SchedulerKind.NONE) public final Disposable forEachWhile(Predicate onNext) { - return forEachWhile(onNext, RxJavaPlugins::onError, () -> { }); + return forEachWhile(onNext, RxJavaPlugins.errorConsumer(), Functions.emptyRunnable()); } @BackpressureSupport(BackpressureKind.NONE) @SchedulerSupport(SchedulerKind.NONE) public final Disposable forEachWhile(Predicate onNext, Consumer onError) { - return forEachWhile(onNext, onError, () -> { }); + return forEachWhile(onNext, onError, Functions.emptyRunnable()); } @BackpressureSupport(BackpressureKind.NONE) @SchedulerSupport(SchedulerKind.NONE) - public final Disposable forEachWhile(Predicate onNext, Consumer onError, - Runnable onComplete) { - Objects.requireNonNull(onNext); - Objects.requireNonNull(onError); - Objects.requireNonNull(onComplete); - - AtomicReference subscription = new AtomicReference<>(); - return subscribe(v -> { - if (!onNext.test(v)) { - subscription.get().cancel(); - onComplete.run(); - } - }, onError, onComplete, s -> { - subscription.lazySet(s); - s.request(Long.MAX_VALUE); + public final Disposable forEachWhile(final Predicate onNext, final Consumer onError, + final Runnable onComplete) { + Objects.requireNonNull(onNext, "onNext is null"); + Objects.requireNonNull(onError, "onError is null"); + Objects.requireNonNull(onComplete, "onComplete is null"); + + final AtomicReference subscription = new AtomicReference(); + return subscribe(new Consumer() { + @Override + public void accept(T v) { + if (!onNext.test(v)) { + subscription.get().cancel(); + onComplete.run(); + } + } + }, onError, onComplete, new Consumer() { + @Override + public void accept(Subscription s) { + subscription.lazySet(s); + s.request(Long.MAX_VALUE); + } }); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable> groupBy(Function keySelector) { - return groupBy(keySelector, v -> v, false, bufferSize()); + return groupBy(keySelector, Functions.identity(), false, bufferSize()); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable> groupBy(Function keySelector, boolean delayError) { - return groupBy(keySelector, v -> v, delayError, bufferSize()); + return groupBy(keySelector, Functions.identity(), delayError, bufferSize()); } @BackpressureSupport(BackpressureKind.FULL) @@ -1800,23 +2121,28 @@ public final Observable> groupBy(Function Observable> groupBy(Function keySelector, Function valueSelector, boolean delayError, int bufferSize) { - Objects.requireNonNull(keySelector); - Objects.requireNonNull(valueSelector); + Objects.requireNonNull(keySelector, "keySelector is null"); + Objects.requireNonNull(valueSelector, "valueSelector is null"); validateBufferSize(bufferSize); - return lift(new OperatorGroupBy<>(keySelector, valueSelector, bufferSize, delayError)); + return lift(new OperatorGroupBy(keySelector, valueSelector, bufferSize, delayError)); } @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerKind.NONE) public final Observable ignoreElements() { - return lift(OperatorIgnoreElements.instance()); + return lift(OperatorIgnoreElements.instance()); } @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerKind.NONE) public final Observable isEmpty() { - return all(v -> false); + return all(new Predicate() { + @Override + public boolean test(T v) { + return false; + } + }); } @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @@ -1834,36 +2160,28 @@ public final Observable last(T defaultValue) { @BackpressureSupport(BackpressureKind.SPECIAL) @SchedulerSupport(SchedulerKind.NONE) public final Observable lift(Operator lifter) { - Objects.requireNonNull(lifter); + Objects.requireNonNull(lifter, "lifter is null"); // using onSubscribe so the fusing has access to the underlying raw Publisher - return create(new PublisherLift<>(onSubscribe, lifter)); - } - - /** - * @deprecated use {@link #take(long)} instead - */ - @BackpressureSupport(BackpressureKind.SPECIAL) // take may trigger UNBOUNDED_IN - @SchedulerSupport(SchedulerKind.NONE) - @Deprecated - public final Observable limit(long n) { - return take(n); + return create(new PublisherLift(onSubscribe, lifter)); } @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport(SchedulerKind.NONE) public final Observable map(Function mapper) { - return lift(new OperatorMap<>(mapper)); + Objects.requireNonNull(mapper, "mapper is null"); + return lift(new OperatorMap(mapper)); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable>> materialize() { - return lift(OperatorMaterialize.instance()); + return lift(OperatorMaterialize.instance()); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable mergeWith(Publisher other) { + Objects.requireNonNull(other, "other is null"); return merge(this, other); } @@ -1889,15 +2207,21 @@ public final Observable observeOn(Scheduler scheduler, boolean delayError) { @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.CUSTOM) public final Observable observeOn(Scheduler scheduler, boolean delayError, int bufferSize) { - Objects.requireNonNull(scheduler); + Objects.requireNonNull(scheduler, "scheduler is null"); validateBufferSize(bufferSize); - return lift(new OperatorObserveOn<>(scheduler, delayError, bufferSize)); + return lift(new OperatorObserveOn(scheduler, delayError, bufferSize)); } @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport(SchedulerKind.NONE) - public final Observable ofType(Class clazz) { - return filter(clazz::isInstance).cast(clazz); + public final Observable ofType(final Class clazz) { + Objects.requireNonNull(clazz, "clazz is null"); + return filter(new Predicate() { + @Override + public boolean test(T c) { + return clazz.isInstance(c); + } + }).cast(clazz); } @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @@ -1928,13 +2252,14 @@ public final Observable onBackpressureBuffer(int bufferSize, boolean delayErr @SchedulerSupport(SchedulerKind.NONE) public final Observable onBackpressureBuffer(int bufferSize, boolean delayError, boolean unbounded) { validateBufferSize(bufferSize); - return lift(new OperatorOnBackpressureBuffer<>(bufferSize, unbounded, delayError, () -> { })); + return lift(new OperatorOnBackpressureBuffer(bufferSize, unbounded, delayError, Functions.emptyRunnable())); } @BackpressureSupport(BackpressureKind.SPECIAL) @SchedulerSupport(SchedulerKind.NONE) public final Observable onBackpressureBuffer(int bufferSize, boolean delayError, boolean unbounded, Runnable onOverflow) { - return lift(new OperatorOnBackpressureBuffer<>(bufferSize, unbounded, delayError, onOverflow)); + Objects.requireNonNull(onOverflow, "onOverflow is null"); + return lift(new OperatorOnBackpressureBuffer(bufferSize, unbounded, delayError, onOverflow)); } @BackpressureSupport(BackpressureKind.ERROR) @@ -1946,55 +2271,71 @@ public final Observable onBackpressureBuffer(int bufferSize, Runnable onOverf @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerKind.NONE) public final Observable onBackpressureDrop() { - return lift(OperatorOnBackpressureDrop.instance()); + return lift(OperatorOnBackpressureDrop.instance()); } @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerKind.NONE) public final Observable onBackpressureDrop(Consumer onDrop) { - return lift(new OperatorOnBackpressureDrop<>(onDrop)); + Objects.requireNonNull(onDrop, "onDrop is null"); + return lift(new OperatorOnBackpressureDrop(onDrop)); } @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerKind.NONE) public final Observable onBackpressureLatest() { - return lift(OperatorOnBackpressureLatest.instance()); + return lift(OperatorOnBackpressureLatest.instance()); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable onErrorResumeNext(Function> resumeFunction) { - Objects.requireNonNull(resumeFunction); - return lift(new OperatorOnErrorNext<>(resumeFunction, false)); + Objects.requireNonNull(resumeFunction, "resumeFunction is null"); + return lift(new OperatorOnErrorNext(resumeFunction, false)); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) - public final Observable onErrorResumeNext(Publisher next) { - Objects.requireNonNull(next); - return onErrorResumeNext(e -> next); + public final Observable onErrorResumeNext(final Publisher next) { + Objects.requireNonNull(next, "next is null"); + return onErrorResumeNext(new Function>() { + @Override + public Publisher apply(Throwable e) { + return next; + } + }); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable onErrorReturn(Function valueSupplier) { - Objects.requireNonNull(valueSupplier); - return lift(new OperatorOnErrorReturn<>(valueSupplier)); + Objects.requireNonNull(valueSupplier, "valueSupplier is null"); + return lift(new OperatorOnErrorReturn(valueSupplier)); } // TODO would result in ambiguity with onErrorReturn(Function) @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) - public final Observable onErrorReturnValue(T value) { - Objects.requireNonNull(value); - return onErrorReturn(e -> value); + public final Observable onErrorReturnValue(final T value) { + Objects.requireNonNull(value, "value is null"); + return onErrorReturn(new Function() { + @Override + public T apply(Throwable e) { + return value; + } + }); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) - public final Observable onExceptionResumeNext(Publisher next) { - Objects.requireNonNull(next); - return lift(new OperatorOnErrorNext<>(e -> next, true)); + public final Observable onExceptionResumeNext(final Publisher next) { + Objects.requireNonNull(next, "next is null"); + return lift(new OperatorOnErrorNext(new Function>() { + @Override + public Publisher apply(Throwable e) { + return next; + } + }, true)); } @BackpressureSupport(BackpressureKind.FULL) @@ -2013,7 +2354,7 @@ public final Observable publish(Function, ? extends @SchedulerSupport(SchedulerKind.NONE) public final Observable publish(Function, ? extends Publisher> selector, int bufferSize) { validateBufferSize(bufferSize); - Objects.requireNonNull(selector); + Objects.requireNonNull(selector, "selector is null"); return OperatorPublish.create(this, selector, bufferSize); } @@ -2058,47 +2399,35 @@ public final Observable repeat(long times) { if (times == 0) { return empty(); } - return create(new PublisherRepeat<>(this, times)); - } - - /** - * - * @deprecated use composition - */ - @Deprecated - @BackpressureSupport(BackpressureKind.FULL) - @SchedulerSupport(SchedulerKind.CUSTOM) - public final Observable repeat(long times, Scheduler scheduler) { - return repeat(times).subscribeOn(scheduler); + return create(new PublisherRepeat(this, times)); } - /** - * - * @deprecated use composition - */ - @BackpressureSupport(BackpressureKind.FULL) - @SchedulerSupport(SchedulerKind.CUSTOM) - @Deprecated - public final Observable repeat(Scheduler scheduler) { - return repeat().subscribeOn(scheduler); - } - @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable repeatUntil(BooleanSupplier stop) { - return create(new PublisherRepeatUntil<>(this, stop)); + Objects.requireNonNull(stop, "stop is null"); + return create(new PublisherRepeatUntil(this, stop)); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) - public final Observable repeatWhen(Function, ? extends Publisher> handler) { - Objects.requireNonNull(handler); + public final Observable repeatWhen(final Function, ? extends Publisher> handler) { + Objects.requireNonNull(handler, "handler is null"); - Function>>, Publisher> f = no -> - handler.apply(no.map(v -> null)) + Function>>, Publisher> f = new Function>>, Publisher>() { + @Override + public Publisher apply(Observable>> no) { + return handler.apply(no.map(new Function>, Object>() { + @Override + public Object apply(Try> v) { + return 0; + } + })); + } + } ; - return create(new PublisherRedo<>(this, f)); + return create(new PublisherRedo(this, f)); } @BackpressureSupport(BackpressureKind.FULL) @@ -2110,15 +2439,25 @@ public final ConnectableObservable replay() { @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable replay(Function, ? extends Publisher> selector) { - Objects.requireNonNull(selector); - return OperatorReplay.multicastSelector(this::replay, selector); + Objects.requireNonNull(selector, "selector is null"); + return OperatorReplay.multicastSelector(new Supplier>() { + @Override + public ConnectableObservable get() { + return replay(); + } + }, selector); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable replay(Function, ? extends Publisher> selector, final int bufferSize) { - Objects.requireNonNull(selector); - return OperatorReplay.multicastSelector(() -> replay(bufferSize), selector); + Objects.requireNonNull(selector, "selector is null"); + return OperatorReplay.multicastSelector(new Supplier>() { + @Override + public ConnectableObservable get() { + return replay(bufferSize); + } + }, selector); } @BackpressureSupport(BackpressureKind.FULL) @@ -2133,15 +2472,30 @@ public final Observable replay(Function, ? extends if (bufferSize < 0) { throw new IllegalArgumentException("bufferSize < 0"); } - Objects.requireNonNull(selector); - return OperatorReplay.multicastSelector(() -> replay(bufferSize, time, unit, scheduler), selector); + Objects.requireNonNull(selector, "selector is null"); + return OperatorReplay.multicastSelector(new Supplier>() { + @Override + public ConnectableObservable get() { + return replay(bufferSize, time, unit, scheduler); + } + }, selector); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.CUSTOM) public final Observable replay(final Function, ? extends Publisher> selector, final int bufferSize, final Scheduler scheduler) { - return OperatorReplay.multicastSelector(() -> replay(bufferSize), - t -> fromPublisher(selector.apply(t)).observeOn(scheduler)); + return OperatorReplay.multicastSelector(new Supplier>() { + @Override + public ConnectableObservable get() { + return replay(bufferSize); + } + }, + new Function, Publisher>() { + @Override + public Publisher apply(Observable t) { + return fromPublisher(selector.apply(t)).observeOn(scheduler); + } + }); } @BackpressureSupport(BackpressureKind.FULL) @@ -2153,14 +2507,34 @@ public final Observable replay(Function, ? extends @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.CUSTOM) public final Observable replay(Function, ? extends Publisher> selector, final long time, final TimeUnit unit, final Scheduler scheduler) { - return OperatorReplay.multicastSelector(() -> replay(time, unit, scheduler), selector); + Objects.requireNonNull(selector, "selector is null"); + Objects.requireNonNull(unit, "unit is null"); + Objects.requireNonNull(scheduler, "scheduler is null"); + return OperatorReplay.multicastSelector(new Supplier>() { + @Override + public ConnectableObservable get() { + return replay(time, unit, scheduler); + } + }, selector); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.CUSTOM) public final Observable replay(final Function, ? extends Publisher> selector, final Scheduler scheduler) { - return OperatorReplay.multicastSelector(() -> replay(), - t -> fromPublisher(selector.apply(t)).observeOn(scheduler)); + Objects.requireNonNull(selector, "selector is null"); + Objects.requireNonNull(scheduler, "scheduler is null"); + return OperatorReplay.multicastSelector(new Supplier>() { + @Override + public ConnectableObservable get() { + return replay(); + } + }, + new Function, Publisher>() { + @Override + public Publisher apply(Observable t) { + return fromPublisher(selector.apply(t)).observeOn(scheduler); + } + }); } @BackpressureSupport(BackpressureKind.FULL) @@ -2178,6 +2552,8 @@ public final ConnectableObservable replay(int bufferSize, long time, TimeUnit @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.CUSTOM) public final ConnectableObservable replay(final int bufferSize, final long time, final TimeUnit unit, final Scheduler scheduler) { + Objects.requireNonNull(unit, "unit is null"); + Objects.requireNonNull(scheduler, "scheduler is null"); if (bufferSize < 0) { throw new IllegalArgumentException("bufferSize < 0"); } @@ -2187,6 +2563,7 @@ public final ConnectableObservable replay(final int bufferSize, final long ti @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.CUSTOM) public final ConnectableObservable replay(final int bufferSize, final Scheduler scheduler) { + Objects.requireNonNull(scheduler, "scheduler is null"); return OperatorReplay.observeOn(replay(bufferSize), scheduler); } @@ -2199,34 +2576,36 @@ public final ConnectableObservable replay(long time, TimeUnit unit) { @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.CUSTOM) public final ConnectableObservable replay(final long time, final TimeUnit unit, final Scheduler scheduler) { + Objects.requireNonNull(unit, "unit is null"); + Objects.requireNonNull(scheduler, "scheduler is null"); return OperatorReplay.create(this, time, unit, scheduler); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.CUSTOM) public final ConnectableObservable replay(final Scheduler scheduler) { - Objects.requireNonNull(scheduler); + Objects.requireNonNull(scheduler, "scheduler is null"); return OperatorReplay.observeOn(replay(), scheduler); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable retry() { - return retry(Long.MAX_VALUE, e -> true); + return retry(Long.MAX_VALUE, Functions.alwaysTrue()); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable retry(BiPredicate predicate) { - Objects.requireNonNull(predicate); + Objects.requireNonNull(predicate, "predicate is null"); - return create(new PublisherRetryBiPredicate<>(this, predicate)); + return create(new PublisherRetryBiPredicate(this, predicate)); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable retry(long times) { - return retry(times, e -> true); + return retry(times, Functions.alwaysTrue()); } // Retries at most times or until the predicate returns false, whichever happens first @@ -2236,9 +2615,9 @@ public final Observable retry(long times, Predicate predic if (times < 0) { throw new IllegalArgumentException("times >= 0 required but it was " + times); } - Objects.requireNonNull(predicate); + Objects.requireNonNull(predicate, "predicate is null"); - return create(new PublisherRetryPredicate<>(this, times, predicate)); + return create(new PublisherRetryPredicate(this, times, predicate)); } @BackpressureSupport(BackpressureKind.FULL) @@ -2249,34 +2628,53 @@ public final Observable retry(Predicate predicate) { @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) - public final Observable retryUntil(BooleanSupplier stop) { - return retry(Long.MAX_VALUE, e -> !stop.getAsBoolean()); + public final Observable retryUntil(final BooleanSupplier stop) { + Objects.requireNonNull(stop, "stop is null"); + return retry(Long.MAX_VALUE, new Predicate() { + @Override + public boolean test(Throwable e) { + return !stop.getAsBoolean(); + } + }); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable retryWhen( - Function, ? extends Publisher> handler) { - Objects.requireNonNull(handler); + final Function, ? extends Publisher> handler) { + Objects.requireNonNull(handler, "handler is null"); - Function>>, Publisher> f = no -> - handler.apply(no.takeWhile(Try::hasError).map(t -> { - return t.error(); - })) + Function>>, Publisher> f = new Function>>, Publisher>() { + @Override + public Publisher apply(Observable>> no) { + Observable map = no.takeWhile(new Predicate>>() { + @Override + public boolean test(Try> e) { + return e.hasError(); + } + }).map(new Function>, Throwable>() { + @Override + public Throwable apply(Try> t) { + return t.error(); + } + }); + return handler.apply(map); + } + } ; - return create(new PublisherRedo<>(this, f)); + return create(new PublisherRedo(this, f)); } // TODO decide if safe subscription or unsafe should be the default @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport(SchedulerKind.NONE) public final void safeSubscribe(Subscriber s) { - Objects.requireNonNull(s); + Objects.requireNonNull(s, "s is null"); if (s instanceof SafeSubscriber) { subscribeActual(s); } else { - subscribeActual(new SafeSubscriber<>(s)); + subscribeActual(new SafeSubscriber(s)); } } @@ -2289,45 +2687,55 @@ public final Observable sample(long period, TimeUnit unit) { @BackpressureSupport(BackpressureKind.ERROR) @SchedulerSupport(SchedulerKind.CUSTOM) public final Observable sample(long period, TimeUnit unit, Scheduler scheduler) { - Objects.requireNonNull(unit); - Objects.requireNonNull(scheduler); - return lift(new OperatorSampleTimed<>(period, unit, scheduler)); + Objects.requireNonNull(unit, "unit is null"); + Objects.requireNonNull(scheduler, "scheduler is null"); + return lift(new OperatorSampleTimed(period, unit, scheduler)); } @BackpressureSupport(BackpressureKind.ERROR) @SchedulerSupport(SchedulerKind.NONE) public final Observable sample(Publisher sampler) { - Objects.requireNonNull(sampler); - return lift(new OperatorSamplePublisher<>(sampler)); + Objects.requireNonNull(sampler, "sampler is null"); + return lift(new OperatorSamplePublisher(sampler)); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable scan(BiFunction accumulator) { - Objects.requireNonNull(accumulator); - return lift(new OperatorScan<>(accumulator)); + Objects.requireNonNull(accumulator, "accumulator is null"); + return lift(new OperatorScan(accumulator)); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) - public final Observable scan(R seed, BiFunction accumulator) { - Objects.requireNonNull(seed); - return scanWith(() -> seed, accumulator); + public final Observable scan(final R seed, BiFunction accumulator) { + Objects.requireNonNull(seed, "seed is null"); + return scanWith(new Supplier() { + @Override + public R get() { + return seed; + } + }, accumulator); } // Naming note, a plain scan would cause ambiguity with the value-seeded version @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable scanWith(Supplier seedSupplier, BiFunction accumulator) { - Objects.requireNonNull(seedSupplier); - Objects.requireNonNull(accumulator); - return lift(new OperatorScanSeed<>(seedSupplier, accumulator)); + Objects.requireNonNull(seedSupplier, "seedSupplier is null"); + Objects.requireNonNull(accumulator, "accumulator is null"); + return lift(new OperatorScanSeed(seedSupplier, accumulator)); } @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport(SchedulerKind.NONE) public final Observable serialize() { - return lift(s -> new SerializedSubscriber<>(s)); + return lift(new Operator() { + @Override + public Subscriber apply(Subscriber s) { + return new SerializedSubscriber(s); + } + }); } @BackpressureSupport(BackpressureKind.FULL) @@ -2339,14 +2747,14 @@ public final Observable share() { @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerKind.NONE) public final Observable single() { - return lift(OperatorSingle.instanceNoDefault()); + return lift(OperatorSingle.instanceNoDefault()); } @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerKind.NONE) public final Observable single(T defaultValue) { - Objects.requireNonNull(defaultValue); - return lift(new OperatorSingle<>(defaultValue)); + Objects.requireNonNull(defaultValue, "defaultValue is null"); + return lift(new OperatorSingle(defaultValue)); } @BackpressureSupport(BackpressureKind.FULL) @@ -2359,7 +2767,7 @@ public final Observable skip(long n) { if (n <= 0) { return this; } - return lift(new OperatorSkip<>(n)); + return lift(new OperatorSkip(n)); } @BackpressureSupport(BackpressureKind.FULL) @@ -2378,7 +2786,7 @@ public final Observable skipLast(int n) { if (n == 0) { return this; } - return lift(new OperatorSkipLast<>(n)); + return lift(new OperatorSkipLast(n)); } @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @@ -2408,51 +2816,54 @@ public final Observable skipLast(long time, TimeUnit unit, Scheduler schedule @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerKind.CUSTOM) public final Observable skipLast(long time, TimeUnit unit, Scheduler scheduler, boolean delayError, int bufferSize) { - Objects.requireNonNull(unit); - Objects.requireNonNull(scheduler); + Objects.requireNonNull(unit, "unit is null"); + Objects.requireNonNull(scheduler, "scheduler is null"); validateBufferSize(bufferSize); // the internal buffer holds pairs of (timestamp, value) so double the default buffer size int s = bufferSize << 1; - return lift(new OperatorSkipLastTimed<>(time, unit, scheduler, s, delayError)); + return lift(new OperatorSkipLastTimed(time, unit, scheduler, s, delayError)); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) - public final Observable skipUntil(Publisher other) { - Objects.requireNonNull(other); - return lift(new OperatorSkipUntil<>(other)); + public final Observable skipUntil(Publisher other) { + Objects.requireNonNull(other, "other is null"); + return lift(new OperatorSkipUntil(other)); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable skipWhile(Predicate predicate) { - Objects.requireNonNull(predicate); - return lift(new OperatorSkipWhile<>(predicate)); + Objects.requireNonNull(predicate, "predicate is null"); + return lift(new OperatorSkipWhile(predicate)); } + @SuppressWarnings("unchecked") @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable startWith(Iterable values) { return concatArray(fromIterable(values), this); } + @SuppressWarnings("unchecked") @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable startWith(Publisher other) { - Objects.requireNonNull(other); + Objects.requireNonNull(other, "other is null"); return concatArray(other, this); } + @SuppressWarnings("unchecked") @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable startWith(T value) { - Objects.requireNonNull(value); + Objects.requireNonNull(value, "value is null"); return concatArray(just(value), this); } + @SuppressWarnings("unchecked") @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) - @SafeVarargs public final Observable startWithArray(T... values) { Observable fromArray = fromArray(values); if (fromArray == empty()) { @@ -2464,38 +2875,58 @@ public final Observable startWithArray(T... values) { @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerKind.NONE) public final Disposable subscribe() { - return subscribe(v -> { }, RxJavaPlugins::onError, () -> { }, s -> s.request(Long.MAX_VALUE)); + return subscribe(Functions.emptyConsumer(), RxJavaPlugins.errorConsumer(), Functions.emptyRunnable(), new Consumer() { + @Override + public void accept(Subscription s) { + s.request(Long.MAX_VALUE); + } + }); } @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerKind.NONE) public final Disposable subscribe(Consumer onNext) { - return subscribe(onNext, RxJavaPlugins::onError, () -> { }, s -> s.request(Long.MAX_VALUE)); + return subscribe(onNext, RxJavaPlugins.errorConsumer(), Functions.emptyRunnable(), new Consumer() { + @Override + public void accept(Subscription s) { + s.request(Long.MAX_VALUE); + } + }); } @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerKind.NONE) public final Disposable subscribe(Consumer onNext, Consumer onError) { - return subscribe(onNext, onError, () -> { }, s -> s.request(Long.MAX_VALUE)); + return subscribe(onNext, onError, Functions.emptyRunnable(), new Consumer() { + @Override + public void accept(Subscription s) { + s.request(Long.MAX_VALUE); + } + }); } @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerKind.NONE) public final Disposable subscribe(Consumer onNext, Consumer onError, Runnable onComplete) { - return subscribe(onNext, onError, onComplete, s -> s.request(Long.MAX_VALUE)); + return subscribe(onNext, onError, onComplete, new Consumer() { + @Override + public void accept(Subscription s) { + s.request(Long.MAX_VALUE); + } + }); } @BackpressureSupport(BackpressureKind.SPECIAL) @SchedulerSupport(SchedulerKind.NONE) public final Disposable subscribe(Consumer onNext, Consumer onError, Runnable onComplete, Consumer onSubscribe) { - Objects.requireNonNull(onNext); - Objects.requireNonNull(onError); - Objects.requireNonNull(onComplete); - Objects.requireNonNull(onSubscribe); + Objects.requireNonNull(onNext, "onNext is null"); + Objects.requireNonNull(onError, "onError is null"); + Objects.requireNonNull(onComplete, "onComplete is null"); + Objects.requireNonNull(onSubscribe, "onSubscribe is null"); - LambdaSubscriber ls = new LambdaSubscriber<>(onNext, onError, onComplete, onSubscribe); + LambdaSubscriber ls = new LambdaSubscriber(onNext, onError, onComplete, onSubscribe); unsafeSubscribe(ls); @@ -2507,7 +2938,7 @@ public final Disposable subscribe(Consumer onNext, Consumer s) { - Objects.requireNonNull(s); + Objects.requireNonNull(s, "s is null"); subscribeActual(s); } @@ -2543,15 +2974,15 @@ public final Observable subscribeOn(Scheduler scheduler) { @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport(SchedulerKind.CUSTOM) public final Observable subscribeOn(Scheduler scheduler, boolean requestOn) { - Objects.requireNonNull(scheduler); - return create(new PublisherSubscribeOn<>(this, scheduler, requestOn)); + Objects.requireNonNull(scheduler, "scheduler is null"); + return create(new PublisherSubscribeOn(this, scheduler, requestOn)); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable switchIfEmpty(Publisher other) { - Objects.requireNonNull(other); - return lift(new OperatorSwitchIfEmpty<>(other)); + Objects.requireNonNull(other, "other is null"); + return lift(new OperatorSwitchIfEmpty(other)); } @BackpressureSupport(BackpressureKind.FULL) @@ -2563,9 +2994,9 @@ public final Observable switchMap(Function Observable switchMap(Function> mapper, int bufferSize) { - Objects.requireNonNull(mapper); + Objects.requireNonNull(mapper, "mapper is null"); validateBufferSize(bufferSize); - return lift(new OperatorSwitchMap<>(mapper, bufferSize)); + return lift(new OperatorSwitchMap(mapper, bufferSize)); } @BackpressureSupport(BackpressureKind.SPECIAL) // may trigger UNBOUNDED_IN @@ -2579,7 +3010,7 @@ public final Observable take(long n) { // return lift(s -> CancelledSubscriber.INSTANCE); return empty(); } - return lift(new OperatorTake<>(n)); + return lift(new OperatorTake(n)); } @BackpressureSupport(BackpressureKind.PASS_THROUGH) @@ -2605,9 +3036,9 @@ public final Observable takeLast(int n) { return ignoreElements(); } else if (n == 1) { - return lift(OperatorTakeLastOne.instance()); + return lift(OperatorTakeLastOne.instance()); } - return lift(new OperatorTakeLast<>(n)); + return lift(new OperatorTakeLast(n)); } @BackpressureSupport(BackpressureKind.FULL) @@ -2625,13 +3056,13 @@ public final Observable takeLast(long count, long time, TimeUnit unit, Schedu @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.CUSTOM) public final Observable takeLast(long count, long time, TimeUnit unit, Scheduler scheduler, boolean delayError, int bufferSize) { - Objects.requireNonNull(unit); - Objects.requireNonNull(scheduler); + Objects.requireNonNull(unit, "unit is null"); + Objects.requireNonNull(scheduler, "scheduler is null"); validateBufferSize(bufferSize); if (count < 0) { throw new IndexOutOfBoundsException("count >= 0 required but it was " + count); } - return lift(new OperatorTakeLastTimed<>(count, time, unit, scheduler, bufferSize, delayError)); + return lift(new OperatorTakeLastTimed(count, time, unit, scheduler, bufferSize, delayError)); } @BackpressureSupport(BackpressureKind.FULL) @@ -2697,22 +3128,22 @@ public final Observable> takeLastBuffer(long time, TimeUnit unit, Schedu @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport(SchedulerKind.NONE) public final Observable takeUntil(Predicate predicate) { - Objects.requireNonNull(predicate); - return lift(new OperatorTakeUntilPredicate<>(predicate)); + Objects.requireNonNull(predicate, "predicate is null"); + return lift(new OperatorTakeUntilPredicate(predicate)); } @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport(SchedulerKind.NONE) public final Observable takeUntil(Publisher other) { - Objects.requireNonNull(other); - return lift(new OperatorTakeUntil<>(other)); + Objects.requireNonNull(other, "other is null"); + return lift(new OperatorTakeUntil(other)); } @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport(SchedulerKind.NONE) public final Observable takeWhile(Predicate predicate) { - Objects.requireNonNull(predicate); - return lift(new OperatorTakeWhile<>(predicate)); + Objects.requireNonNull(predicate, "predicate is null"); + return lift(new OperatorTakeWhile(predicate)); } @BackpressureSupport(BackpressureKind.ERROR) @@ -2724,6 +3155,8 @@ public final Observable throttleFirst(long windowDuration, TimeUnit unit) { @BackpressureSupport(BackpressureKind.ERROR) @SchedulerSupport(SchedulerKind.CUSTOM) public final Observable throttleFirst(long skipDuration, TimeUnit unit, Scheduler scheduler) { + Objects.requireNonNull(unit, "unit is null"); + Objects.requireNonNull(scheduler, "scheduler is null"); return lift(new OperatorThrottleFirstTimed(skipDuration, unit, scheduler)); } @@ -2772,7 +3205,9 @@ public final Observable> timeInterval(TimeUnit unit) { @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport(SchedulerKind.CUSTOM) public final Observable> timeInterval(TimeUnit unit, Scheduler scheduler) { - return lift(new OperatorTimeInterval<>(unit, scheduler)); + Objects.requireNonNull(unit, "unit is null"); + Objects.requireNonNull(scheduler, "scheduler is null"); + return lift(new OperatorTimeInterval(unit, scheduler)); } @BackpressureSupport(BackpressureKind.PASS_THROUGH) @@ -2784,7 +3219,7 @@ public final Observable timeout(Function Observable timeout(Function> timeoutSelector, Observable other) { - Objects.requireNonNull(other); + Objects.requireNonNull(other, "other is null"); return timeout0(null, timeoutSelector, other); } @@ -2797,14 +3232,14 @@ public final Observable timeout(long timeout, TimeUnit timeUnit) { @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.COMPUTATION) public final Observable timeout(long timeout, TimeUnit timeUnit, Observable other) { - Objects.requireNonNull(other); + Objects.requireNonNull(other, "other is null"); return timeout0(timeout, timeUnit, other, Schedulers.computation()); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.CUSTOM) public final Observable timeout(long timeout, TimeUnit timeUnit, Observable other, Scheduler scheduler) { - Objects.requireNonNull(other); + Objects.requireNonNull(other, "other is null"); return timeout0(timeout, timeUnit, other, scheduler); } @@ -2816,7 +3251,7 @@ public final Observable timeout(long timeout, TimeUnit timeUnit, Scheduler sc public final Observable timeout(Supplier> firstTimeoutSelector, Function> timeoutSelector) { - Objects.requireNonNull(firstTimeoutSelector); + Objects.requireNonNull(firstTimeoutSelector, "firstTimeoutSelector is null"); return timeout0(firstTimeoutSelector, timeoutSelector, null); } @@ -2826,15 +3261,15 @@ public final Observable timeout( Supplier> firstTimeoutSelector, Function> timeoutSelector, Publisher other) { - Objects.requireNonNull(firstTimeoutSelector); - Objects.requireNonNull(other); + Objects.requireNonNull(firstTimeoutSelector, "firstTimeoutSelector is null"); + Objects.requireNonNull(other, "other is null"); return timeout0(firstTimeoutSelector, timeoutSelector, other); } private Observable timeout0(long timeout, TimeUnit timeUnit, Observable other, Scheduler scheduler) { - Objects.requireNonNull(timeUnit); - Objects.requireNonNull(scheduler); + Objects.requireNonNull(timeUnit, "timeUnit is null"); + Objects.requireNonNull(scheduler, "scheduler is null"); return lift(new OperatorTimeoutTimed(timeout, timeUnit, scheduler, other)); } @@ -2842,7 +3277,7 @@ private Observable timeout0( Supplier> firstTimeoutSelector, Function> timeoutSelector, Publisher other) { - Objects.requireNonNull(timeoutSelector); + Objects.requireNonNull(timeoutSelector, "timeoutSelector is null"); return lift(new OperatorTimeout(firstTimeoutSelector, timeoutSelector, other)); } @@ -2866,8 +3301,15 @@ public final Observable> timestamp(TimeUnit unit) { @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport(SchedulerKind.CUSTOM) - public final Observable> timestamp(TimeUnit unit, Scheduler scheduler) { - return map(v -> new Timed<>(v, scheduler.now(unit), unit)); + public final Observable> timestamp(final TimeUnit unit, final Scheduler scheduler) { + Objects.requireNonNull(unit, "unit is null"); + Objects.requireNonNull(scheduler, "scheduler is null"); + return map(new Function>() { + @Override + public Timed apply(T v) { + return new Timed(v, scheduler.now(unit), unit); + } + }); } // TODO generics @@ -2886,70 +3328,119 @@ public final BlockingObservable toBlocking() { @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerKind.NONE) public final Observable> toList() { - return lift(OperatorToList.defaultInstance()); + return lift(OperatorToList.defaultInstance()); } @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerKind.NONE) - public final Observable> toList(int capacityHint) { + public final Observable> toList(final int capacityHint) { if (capacityHint <= 0) { throw new IllegalArgumentException("capacityHint > 0 required but it was " + capacityHint); } - return lift(new OperatorToList<>(() -> new ArrayList<>(capacityHint))); + return lift(new OperatorToList>(new Supplier>() { + @Override + public List get() { + return new ArrayList(capacityHint); + } + })); } @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerKind.NONE) public final > Observable toList(Supplier collectionSupplier) { - Objects.requireNonNull(collectionSupplier); - return lift(new OperatorToList<>(collectionSupplier)); + Objects.requireNonNull(collectionSupplier, "collectionSupplier is null"); + return lift(new OperatorToList(collectionSupplier)); } @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerKind.NONE) - public final Observable> toMap(Function keySelector) { - return collect(HashMap::new, (m, t) -> { - K key = keySelector.apply(t); - m.put(key, t); + public final Observable> toMap(final Function keySelector) { + Objects.requireNonNull(keySelector, "keySelector is null"); + return collect(new Supplier>() { + @Override + public Map get() { + return new HashMap(); + } + }, new BiConsumer, T>() { + @Override + public void accept(Map m, T t) { + K key = keySelector.apply(t); + m.put(key, t); + } }); } @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerKind.NONE) - public final Observable> toMap(Function keySelector, Function valueSelector) { - return collect(HashMap::new, (m, t) -> { - K key = keySelector.apply(t); - V value = valueSelector.apply(t); - m.put(key, value); + public final Observable> toMap(final Function keySelector, final Function valueSelector) { + Objects.requireNonNull(keySelector, "keySelector is null"); + Objects.requireNonNull(valueSelector, "valueSelector is null"); + return collect(new Supplier>() { + @Override + public Map get() { + return new HashMap(); + } + }, new BiConsumer, T>() { + @Override + public void accept(Map m, T t) { + K key = keySelector.apply(t); + V value = valueSelector.apply(t); + m.put(key, value); + } }); } @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerKind.NONE) - public final Observable> toMap(Function keySelector, - Function valueSelector, - Supplier> mapSupplier) { - return collect(mapSupplier, (m, t) -> { - K key = keySelector.apply(t); - V value = valueSelector.apply(t); - m.put(key, value); + public final Observable> toMap(final Function keySelector, + final Function valueSelector, + final Supplier> mapSupplier) { + Objects.requireNonNull(keySelector, "keySelector is null"); + Objects.requireNonNull(valueSelector, "valueSelector is null"); + return collect(mapSupplier, new BiConsumer, T>() { + @Override + public void accept(Map m, T t) { + K key = keySelector.apply(t); + V value = valueSelector.apply(t); + m.put(key, value); + } }); } @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerKind.NONE) public final Observable>> toMultimap(Function keySelector) { - Function valueSelector = v -> v; - Supplier>> mapSupplier = HashMap::new; - Function> collectionFactory = k -> new ArrayList<>(); + Function valueSelector = Functions.identity(); + Supplier>> mapSupplier = new Supplier>>() { + @Override + public Map> get() { + return new HashMap>(); + } + }; + Function> collectionFactory = new Function>() { + @Override + public Collection apply(K k) { + return new ArrayList(); + } + }; return toMultimap(keySelector, valueSelector, mapSupplier, collectionFactory); } @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerKind.NONE) public final Observable>> toMultimap(Function keySelector, Function valueSelector) { - Supplier>> mapSupplier = HashMap::new; - Function> collectionFactory = k -> new ArrayList<>(); + Supplier>> mapSupplier = new Supplier>>() { + @Override + public Map> get() { + return new HashMap>(); + } + }; + Function> collectionFactory = new Function>() { + @Override + public Collection apply(K k) { + return new ArrayList(); + } + }; return toMultimap(keySelector, valueSelector, mapSupplier, collectionFactory); } @@ -2957,22 +3448,29 @@ public final Observable>> toMultimap(Function Observable>> toMultimap( - Function keySelector, - Function valueSelector, - Supplier>> mapSupplier, - Function> collectionFactory) { - return collect(mapSupplier, (m, t) -> { - K key = keySelector.apply(t); - - Collection coll = m.get(key); - if (coll == null) { - coll = (Collection)collectionFactory.apply(key); - m.put(key, coll); + final Function keySelector, + final Function valueSelector, + final Supplier>> mapSupplier, + final Function> collectionFactory) { + Objects.requireNonNull(keySelector, "keySelector is null"); + Objects.requireNonNull(valueSelector, "valueSelector is null"); + Objects.requireNonNull(mapSupplier, "mapSupplier is null"); + Objects.requireNonNull(collectionFactory, "collectionFactory is null"); + return collect(mapSupplier, new BiConsumer>, T>() { + @Override + public void accept(Map> m, T t) { + K key = keySelector.apply(t); + + Collection coll = m.get(key); + if (coll == null) { + coll = (Collection)collectionFactory.apply(key); + m.put(key, coll); + } + + V value = valueSelector.apply(t); + + coll.add(value); } - - V value = valueSelector.apply(t); - - coll.add(value); }); } @@ -2983,7 +3481,12 @@ public final Observable>> toMultimap( Function valueSelector, Supplier>> mapSupplier ) { - return toMultimap(keySelector, valueSelector, mapSupplier, k -> new ArrayList<>()); + return toMultimap(keySelector, valueSelector, mapSupplier, new Function>() { + @Override + public Collection apply(K k) { + return new ArrayList(); + } + }); } @BackpressureSupport(BackpressureKind.NONE) @@ -3002,26 +3505,37 @@ public final Single toSingle() { @SchedulerSupport(SchedulerKind.NONE) @SuppressWarnings({ "unchecked", "rawtypes"}) public final Observable> toSortedList() { - return toSortedList((Comparator)Comparator.naturalOrder()); + return toSortedList(new Comparator() { + @Override + public int compare(T o1, T o2) { + return ((Comparable)o1).compareTo(o2); + } + }); } @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerKind.NONE) - public final Observable> toSortedList(Comparator comparator) { - Objects.requireNonNull(comparator); - return toList().map(v -> { - Collections.sort(v, comparator); - return v; + public final Observable> toSortedList(final Comparator comparator) { + Objects.requireNonNull(comparator, "comparator is null"); + return toList().map(new Function, List>() { + @Override + public List apply(List v) { + Collections.sort(v, comparator); + return v; + } }); } @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerKind.NONE) - public final Observable> toSortedList(Comparator comparator, int capacityHint) { - Objects.requireNonNull(comparator); - return toList(capacityHint).map(v -> { - Collections.sort(v, comparator); - return v; + public final Observable> toSortedList(final Comparator comparator, int capacityHint) { + Objects.requireNonNull(comparator, "comparator is null"); + return toList(capacityHint).map(new Function, List>() { + @Override + public List apply(List v) { + Collections.sort(v, comparator); + return v; + } }); } @@ -3029,22 +3543,27 @@ public final Observable> toSortedList(Comparator comparator, @SchedulerSupport(SchedulerKind.NONE) @SuppressWarnings({ "unchecked", "rawtypes"}) public final Observable> toSortedList(int capacityHint) { - return toSortedList((Comparator)Comparator.naturalOrder(), capacityHint); + return toSortedList(new Comparator() { + @Override + public int compare(T o1, T o2) { + return ((Comparable)o1).compareTo(o2); + } + }, capacityHint); } @BackpressureSupport(BackpressureKind.SPECIAL) @SchedulerSupport(SchedulerKind.NONE) // TODO decide if safe subscription or unsafe should be the default public final void unsafeSubscribe(Subscriber s) { - Objects.requireNonNull(s); + Objects.requireNonNull(s, "s is null"); subscribeActual(s); } @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport(SchedulerKind.CUSTOM) public final Observable unsubscribeOn(Scheduler scheduler) { - Objects.requireNonNull(scheduler); - return lift(new OperatorUnsubscribeOn<>(scheduler)); + Objects.requireNonNull(scheduler, "scheduler is null"); + return lift(new OperatorUnsubscribeOn(scheduler)); } @BackpressureSupport(BackpressureKind.FULL) @@ -3069,7 +3588,7 @@ public final Observable> window(long count, long skip, int bufferS throw new IllegalArgumentException("count > 0 required but it was " + count); } validateBufferSize(bufferSize); - return lift(new OperatorWindow<>(count, skip, bufferSize)); + return lift(new OperatorWindow(count, skip, bufferSize)); } @BackpressureSupport(BackpressureKind.ERROR) @@ -3088,9 +3607,9 @@ public final Observable> window(long timespan, long timeskip, Time @SchedulerSupport(SchedulerKind.CUSTOM) public final Observable> window(long timespan, long timeskip, TimeUnit unit, Scheduler scheduler, int bufferSize) { validateBufferSize(bufferSize); - Objects.requireNonNull(scheduler); - Objects.requireNonNull(unit); - return lift(new OperatorWindowTimed<>(timespan, timeskip, unit, scheduler, Long.MAX_VALUE, bufferSize, false)); + Objects.requireNonNull(scheduler, "scheduler is null"); + Objects.requireNonNull(unit, "unit is null"); + return lift(new OperatorWindowTimed(timespan, timeskip, unit, scheduler, Long.MAX_VALUE, bufferSize, false)); } @BackpressureSupport(BackpressureKind.ERROR) @@ -3140,12 +3659,12 @@ public final Observable> window( long timespan, TimeUnit unit, Scheduler scheduler, long count, boolean restart, int bufferSize) { validateBufferSize(bufferSize); - Objects.requireNonNull(scheduler); - Objects.requireNonNull(unit); + Objects.requireNonNull(scheduler, "scheduler is null"); + Objects.requireNonNull(unit, "unit is null"); if (count <= 0) { throw new IllegalArgumentException("count > 0 required but it was " + count); } - return lift(new OperatorWindowTimed<>(timespan, timespan, unit, scheduler, count, bufferSize, restart)); + return lift(new OperatorWindowTimed(timespan, timespan, unit, scheduler, count, bufferSize, restart)); } @BackpressureSupport(BackpressureKind.ERROR) @@ -3157,7 +3676,8 @@ public final Observable> window(Publisher boundary) { @BackpressureSupport(BackpressureKind.ERROR) @SchedulerSupport(SchedulerKind.NONE) public final Observable> window(Publisher boundary, int bufferSize) { - return lift(new OperatorWindowBoundary<>(boundary, bufferSize)); + Objects.requireNonNull(boundary, "boundary is null"); + return lift(new OperatorWindowBoundary(boundary, bufferSize)); } @BackpressureSupport(BackpressureKind.ERROR) @@ -3173,7 +3693,9 @@ public final Observable> window( public final Observable> window( Publisher windowOpen, Function> windowClose, int bufferSize) { - return lift(new OperatorWindowBoundarySelector<>(windowOpen, windowClose, bufferSize)); + Objects.requireNonNull(windowOpen, "windowOpen is null"); + Objects.requireNonNull(windowClose, "windowClose is null"); + return lift(new OperatorWindowBoundarySelector(windowOpen, windowClose, bufferSize)); } @BackpressureSupport(BackpressureKind.ERROR) @@ -3185,27 +3707,31 @@ public final Observable> window(Supplier Observable> window(Supplier> boundary, int bufferSize) { - return lift(new OperatorWindowBoundarySupplier<>(boundary, bufferSize)); + Objects.requireNonNull(boundary, "boundary is null"); + return lift(new OperatorWindowBoundarySupplier(boundary, bufferSize)); } @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport(SchedulerKind.NONE) public final Observable withLatestFrom(Publisher other, BiFunction combiner) { - Objects.requireNonNull(other); - Objects.requireNonNull(combiner); + Objects.requireNonNull(other, "other is null"); + Objects.requireNonNull(combiner, "combiner is null"); - return lift(new OperatorWithLatestFrom<>(combiner, other)); + return lift(new OperatorWithLatestFrom(combiner, other)); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) - public final Observable zipWith(Iterable other, BiFunction zipper) { - return create(new PublisherZipIterable<>(this, other, zipper)); + public final Observable zipWith(Iterable other, BiFunction zipper) { + Objects.requireNonNull(other, "other is null"); + Objects.requireNonNull(zipper, "zipper is null"); + return create(new PublisherZipIterable(this, other, zipper)); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable zipWith(Publisher other, BiFunction zipper) { + Objects.requireNonNull(other, "other is null"); return zip(this, other, zipper); } @@ -3221,4 +3747,4 @@ public final Observable zipWith(Publisher other, BiFuncti return zip(this, other, zipper, delayError, bufferSize); } -} +} \ No newline at end of file diff --git a/src/main/java/io/reactivex/Observer.java b/src/main/java/io/reactivex/Observer.java index 2aee8a0781..36bf722a4f 100644 --- a/src/main/java/io/reactivex/Observer.java +++ b/src/main/java/io/reactivex/Observer.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 diff --git a/src/main/java/io/reactivex/Optional.java b/src/main/java/io/reactivex/Optional.java new file mode 100644 index 0000000000..b8d0565bf0 --- /dev/null +++ b/src/main/java/io/reactivex/Optional.java @@ -0,0 +1,80 @@ +/** + * 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 io.reactivex.internal.functions.Objects; + +/** + * Simplified backport of Java 8's Optional type. + * + * @param the value type + */ +public final class Optional { + final T value; + protected Optional(T value) { + this.value = value; + } + + static final Optional EMPTY = new Optional(null); + + @SuppressWarnings("unchecked") + public static Optional empty() { + return (Optional)EMPTY; + } + + public static Optional of(T value) { + Objects.requireNonNull(value, "value is null"); + return new Optional(value); + } + + public boolean isPresent() { + return value != null; + } + + public T get() { + return value; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((value == null) ? 0 : value.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + Optional other = (Optional) obj; + if (value == null) { + if (other.value != null) { + return false; + } + } else if (!value.equals(other.value)) { + return false; + } + return true; + } + + +} diff --git a/src/main/java/io/reactivex/Scheduler.java b/src/main/java/io/reactivex/Scheduler.java index 66eec77b5c..e2af0ef33d 100644 --- a/src/main/java/io/reactivex/Scheduler.java +++ b/src/main/java/io/reactivex/Scheduler.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -15,8 +15,9 @@ import java.util.concurrent.TimeUnit; -import io.reactivex.disposables.Disposable; +import io.reactivex.disposables.*; import io.reactivex.internal.disposables.*; +import io.reactivex.internal.util.Exceptions; import io.reactivex.plugins.RxJavaPlugins; public abstract class Scheduler { @@ -61,21 +62,24 @@ public Disposable scheduleDirect(Runnable run) { *

Override this method to provide an efficient implementation that, * for example, doesn't have extra tracking structures for such one-shot * executions. - * @param run - * @param delay - * @param unit - * @return + * @param run the runnable to schedule + * @param delay the delay time + * @param unit the delay unit + * @return the disposable instance that can cancel the task */ public Disposable scheduleDirect(Runnable run, long delay, TimeUnit unit) { - Worker w = createWorker(); + final Worker w = createWorker(); - Runnable decoratedRun = RxJavaPlugins.onSchedule(run); + final Runnable decoratedRun = RxJavaPlugins.onSchedule(run); - w.schedule(() -> { - try { - decoratedRun.run(); - } finally { - w.dispose(); + w.schedule(new Runnable() { + @Override + public void run() { + try { + decoratedRun.run(); + } finally { + w.dispose(); + } } }, delay, unit); @@ -83,19 +87,22 @@ public Disposable scheduleDirect(Runnable run, long delay, TimeUnit unit) { } public Disposable schedulePeriodicallyDirect(Runnable run, long initialDelay, long period, TimeUnit unit) { - ArrayCompositeResource acr = new ArrayCompositeResource<>(2, Disposable::dispose); - Worker w = createWorker(); + final ArrayCompositeResource acr = new ArrayCompositeResource(2, Disposables.consumeAndDispose()); + final Worker w = createWorker(); acr.lazySet(0, w); - Runnable decoratedRun = RxJavaPlugins.onSchedule(run); + final Runnable decoratedRun = RxJavaPlugins.onSchedule(run); - acr.setResource(1, w.schedulePeriodically(() -> { - try { - decoratedRun.run(); - } catch (final Throwable e) { - // make sure the worker is released if the run crashes - acr.dispose(); - throw e; + acr.setResource(1, w.schedulePeriodically(new Runnable() { + @Override + public void run() { + try { + decoratedRun.run(); + } catch (Throwable e) { + // make sure the worker is released if the run crashes + acr.dispose(); + throw Exceptions.propagate(e); + } } }, initialDelay, period, unit)); @@ -110,12 +117,12 @@ public Disposable schedule(Runnable run) { return schedule(run, 0L, TimeUnit.NANOSECONDS); } - public Disposable schedulePeriodically(Runnable run, long initialDelay, long period, TimeUnit unit) { - MultipleAssignmentResource first = new MultipleAssignmentResource<>(Disposable::dispose); + public Disposable schedulePeriodically(Runnable run, final long initialDelay, final long period, final TimeUnit unit) { + final MultipleAssignmentResource first = new MultipleAssignmentResource(Disposables.consumeAndDispose()); - MultipleAssignmentResource mar = new MultipleAssignmentResource<>(Disposable::dispose, first); + final MultipleAssignmentResource mar = new MultipleAssignmentResource(Disposables.consumeAndDispose(), first); - Runnable decoratedRun = RxJavaPlugins.onSchedule(run); + final Runnable decoratedRun = RxJavaPlugins.onSchedule(run); first.setResource(schedule(new Runnable() { long lastNow = now(unit); diff --git a/src/main/java/io/reactivex/Single.java b/src/main/java/io/reactivex/Single.java index 3f28702146..617d0505ec 100644 --- a/src/main/java/io/reactivex/Single.java +++ b/src/main/java/io/reactivex/Single.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -16,13 +16,15 @@ import java.util.*; import java.util.concurrent.*; import java.util.concurrent.atomic.*; -import java.util.function.*; import org.reactivestreams.*; import io.reactivex.disposables.*; +import io.reactivex.exceptions.CompositeException; import io.reactivex.functions.*; import io.reactivex.internal.disposables.EmptyDisposable; +import io.reactivex.internal.functions.*; +import io.reactivex.internal.functions.Objects; import io.reactivex.internal.operators.single.*; import io.reactivex.internal.subscriptions.*; import io.reactivex.internal.util.*; @@ -58,94 +60,166 @@ public interface SingleTransformer extends Function Single amb(Iterable> sources) { - return create(s -> { - AtomicBoolean once = new AtomicBoolean(); - CompositeDisposable set = new CompositeDisposable(); - s.onSubscribe(set); - - int c = 0; - for (Single s1 : sources) { - if (once.get()) { + public static Single amb(final Iterable> sources) { + Objects.requireNonNull(sources, "sources is null"); + return create(new SingleOnSubscribe() { + @Override + public void accept(final SingleSubscriber s) { + final AtomicBoolean once = new AtomicBoolean(); + final CompositeDisposable set = new CompositeDisposable(); + s.onSubscribe(set); + + int c = 0; + Iterator> iterator; + + try { + iterator = sources.iterator(); + } catch (Throwable e) { + s.onError(e); return; } - s1.subscribe(new SingleSubscriber() { + 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; + } - @Override - public void onSubscribe(Disposable d) { - set.add(d); + if (!b) { + break; } + + Single s1; - @Override - public void onSuccess(T value) { - if (once.compareAndSet(false, true)) { - s.onSuccess(value); - } + if (once.get()) { + return; } - @Override - public void onError(Throwable e) { - if (once.compareAndSet(false, true)) { - s.onError(e); - } else { - RxJavaPlugins.onError(e); - } + try { + s1 = iterator.next(); + } catch (Throwable e) { + set.dispose(); + s.onError(e); + return; } - }); - c++; - } - - if (c == 0 && !set.isDisposed()) { - s.onError(new NoSuchElementException()); + 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()); + } } }); } - @SafeVarargs @SuppressWarnings("unchecked") - public static Single amb(Single... sources) { + public static Single amb(final Single... sources) { if (sources.length == 0) { - return error(() -> new NoSuchElementException()); + return error(new Supplier() { + @Override + public Throwable get() { + return new NoSuchElementException(); + } + }); } if (sources.length == 1) { return (Single)sources[0]; } - return create(s -> { - AtomicBoolean once = new AtomicBoolean(); - CompositeDisposable set = new CompositeDisposable(); - s.onSubscribe(set); - - for (Single s1 : sources) { - if (once.get()) { - return; - } + return create(new SingleOnSubscribe() { + @Override + public void accept(final SingleSubscriber s) { + final AtomicBoolean once = new AtomicBoolean(); + final CompositeDisposable set = new CompositeDisposable(); + s.onSubscribe(set); - 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); - } + for (Single s1 : sources) { + if (once.get()) { + return; } - - @Override - public void onError(Throwable e) { + + 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); + } + } + + }); + } } }); } @@ -155,98 +229,111 @@ public static Observable concat(Iterable> s } public static Observable concat(Observable> sources) { - return sources.concatMap(Single::toFlowable); + return sources.concatMap(new Function, Publisher>() { + @Override + public Publisher apply(Single v){ + return v.toFlowable(); + } + }); } + @SuppressWarnings("unchecked") public static Observable concat( Single s1, Single s2 ) { - Objects.requireNonNull(s1); - Objects.requireNonNull(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 s1, Single s2, Single s3 ) { - Objects.requireNonNull(s1); - Objects.requireNonNull(s2); - Objects.requireNonNull(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 s1, Single s2, Single s3, Single s4 ) { - Objects.requireNonNull(s1); - Objects.requireNonNull(s2); - Objects.requireNonNull(s3); - Objects.requireNonNull(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 s1, Single s2, Single s3, Single s4, Single s5 ) { - Objects.requireNonNull(s1); - Objects.requireNonNull(s2); - Objects.requireNonNull(s3); - Objects.requireNonNull(s4); - Objects.requireNonNull(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 s1, Single s2, Single s3, Single s4, Single s5, Single s6 ) { - Objects.requireNonNull(s1); - Objects.requireNonNull(s2); - Objects.requireNonNull(s3); - Objects.requireNonNull(s4); - Objects.requireNonNull(s5); - Objects.requireNonNull(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 s1, Single s2, Single s3, Single s4, Single s5, Single s6, Single s7 ) { - Objects.requireNonNull(s1); - Objects.requireNonNull(s2); - Objects.requireNonNull(s3); - Objects.requireNonNull(s4); - Objects.requireNonNull(s5); - Objects.requireNonNull(s6); - Objects.requireNonNull(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 s1, Single s2, Single s3, Single s4, Single s5, Single s6, Single s7, Single s8 ) { - Objects.requireNonNull(s1); - Objects.requireNonNull(s2); - Objects.requireNonNull(s3); - Objects.requireNonNull(s4); - Objects.requireNonNull(s5); - Objects.requireNonNull(s6); - Objects.requireNonNull(s7); - Objects.requireNonNull(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 s1, Single s2, Single s3, Single s4, @@ -254,106 +341,100 @@ public static Observable concat( Single s7, Single s8, Single s9 ) { - Objects.requireNonNull(s1); - Objects.requireNonNull(s2); - Objects.requireNonNull(s3); - Objects.requireNonNull(s4); - Objects.requireNonNull(s5); - Objects.requireNonNull(s6); - Objects.requireNonNull(s7); - Objects.requireNonNull(s8); - Objects.requireNonNull(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); + Objects.requireNonNull(onSubscribe, "onSubscribe is null"); // TODO plugin wrapper - return new Single<>(onSubscribe); + return new Single(onSubscribe); } - public static Single defer(Supplier> singleSupplier) { - return create(s -> { - Single 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; + public static Single defer(final Supplier> singleSupplier) { + Objects.requireNonNull(singleSupplier, "singleSupplier is null"); + return create(new SingleOnSubscribe() { + @Override + public void accept(SingleSubscriber s) { + Single 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); } - - next.subscribe(s); }); } - public static Single error(Supplier errorSupplier) { - Objects.requireNonNull(errorSupplier); - return create(s -> { - Throwable error; - - try { - error = errorSupplier.get(); - } catch (Throwable e) { - error = e; - } - - if (error == null) { - error = new NullPointerException(); + public static Single error(final Supplier errorSupplier) { + Objects.requireNonNull(errorSupplier, "errorSupplier is null"); + return create(new SingleOnSubscribe() { + @Override + public void accept(SingleSubscriber 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); } - - s.onSubscribe(EmptyDisposable.INSTANCE); - s.onError(error); }); } - public static Single error(Throwable error) { - Objects.requireNonNull(error); - return error(() -> error); - } - - public static Single fromCallable(Callable callable) { - Objects.requireNonNull(callable); - return create(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 error(final Throwable error) { + Objects.requireNonNull(error, "error is null"); + return error(new Supplier() { + @Override + public Throwable get() { + return error; } }); } - public static Single fromFuture(CompletableFuture future) { - Objects.requireNonNull(future); - return create(s -> { - BooleanDisposable bd = new BooleanDisposable(() -> future.cancel(true)); - s.onSubscribe(bd); - future.whenComplete((v, e) -> { - if (e != null) { - if (!bd.isDisposed()) { - s.onError(e); - } - } else { + public static Single fromCallable(final Callable callable) { + Objects.requireNonNull(callable, "callable is null"); + return create(new SingleOnSubscribe() { + @Override + public void accept(SingleSubscriber 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); } - }); + } }); } @@ -373,48 +454,54 @@ public static Single fromFuture(Future future, Scheduler sch return Observable.fromFuture(future, scheduler).toSingle(); } - public static Single fromPublisher(Publisher publisher) { - Objects.requireNonNull(publisher); - return create(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()); + public static Single fromPublisher(final Publisher publisher) { + Objects.requireNonNull(publisher, "publisher is null"); + return create(new SingleOnSubscribe() { + @Override + public void accept(final SingleSubscriber 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 onError(Throwable t) { + value = null; + s.onError(t); + } - @Override - public void onNext(T t) { - value = t; - } + @Override + public void onNext(T t) { + value = t; + } - @Override - public void onSubscribe(Subscription inner) { - s.onSubscribe(inner::cancel); - inner.request(Long.MAX_VALUE); - } - - }); + @Override + public void onSubscribe(Subscription inner) { + s.onSubscribe(Disposables.from(inner)); + inner.request(Long.MAX_VALUE); + } + + }); + } }); } - public static Single just(T value) { - Objects.requireNonNull(value); - return create(s -> { - s.onSubscribe(EmptyDisposable.INSTANCE); - s.onSuccess(value); + public static Single just(final T value) { + Objects.requireNonNull(value, "value is null"); + return create(new SingleOnSubscribe() { + @Override + public void accept(SingleSubscriber s) { + s.onSubscribe(EmptyDisposable.INSTANCE); + s.onSuccess(value); + } }); } @@ -423,102 +510,116 @@ public static Observable merge(Iterable> so } public static Observable merge(Observable> sources) { - return sources.flatMap(Single::toFlowable); + return sources.flatMap(new Function, Publisher>() { + @Override + public Publisher apply(Single v){ + return v.toFlowable(); + } + }); } + @SuppressWarnings({ "unchecked", "rawtypes" }) public static Single merge(Single> source) { - return source.flatMap(v -> v); + return source.flatMap((Function)Functions.identity()); } + @SuppressWarnings("unchecked") public static Observable merge( Single s1, Single s2 ) { - Objects.requireNonNull(s1); - Objects.requireNonNull(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 s1, Single s2, Single s3 ) { - Objects.requireNonNull(s1); - Objects.requireNonNull(s2); - Objects.requireNonNull(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 s1, Single s2, Single s3, Single s4 ) { - Objects.requireNonNull(s1); - Objects.requireNonNull(s2); - Objects.requireNonNull(s3); - Objects.requireNonNull(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 s1, Single s2, Single s3, Single s4, Single s5 ) { - Objects.requireNonNull(s1); - Objects.requireNonNull(s2); - Objects.requireNonNull(s3); - Objects.requireNonNull(s4); - Objects.requireNonNull(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 s1, Single s2, Single s3, Single s4, Single s5, Single s6 ) { - Objects.requireNonNull(s1); - Objects.requireNonNull(s2); - Objects.requireNonNull(s3); - Objects.requireNonNull(s4); - Objects.requireNonNull(s5); - Objects.requireNonNull(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 s1, Single s2, Single s3, Single s4, Single s5, Single s6, Single s7 ) { - Objects.requireNonNull(s1); - Objects.requireNonNull(s2); - Objects.requireNonNull(s3); - Objects.requireNonNull(s4); - Objects.requireNonNull(s5); - Objects.requireNonNull(s6); - Objects.requireNonNull(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 s1, Single s2, Single s3, Single s4, Single s5, Single s6, Single s7, Single s8 ) { - Objects.requireNonNull(s1); - Objects.requireNonNull(s2); - Objects.requireNonNull(s3); - Objects.requireNonNull(s4); - Objects.requireNonNull(s5); - Objects.requireNonNull(s6); - Objects.requireNonNull(s7); - Objects.requireNonNull(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 s1, Single s2, Single s3, Single s4, @@ -526,321 +627,352 @@ public static Observable merge( Single s7, Single s8, Single s9 ) { - Objects.requireNonNull(s1); - Objects.requireNonNull(s2); - Objects.requireNonNull(s3); - Objects.requireNonNull(s4); - Objects.requireNonNull(s5); - Objects.requireNonNull(s6); - Objects.requireNonNull(s7); - Objects.requireNonNull(s8); - Objects.requireNonNull(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)); } - public static Single never() { - return create(s -> { + static final Single NEVER = create(new SingleOnSubscribe() { + @Override + public void accept(SingleSubscriber s) { s.onSubscribe(EmptyDisposable.INSTANCE); - }); + } + }); + + @SuppressWarnings("unchecked") + public static Single never() { + return (Single)NEVER; } public static Single timer(long delay, TimeUnit unit) { return timer(delay, unit, Schedulers.computation()); } - public static Single timer(long delay, TimeUnit unit, Scheduler scheduler) { - Objects.requireNonNull(unit); - Objects.requireNonNull(scheduler); - return create(s -> { - MultipleAssignmentDisposable mad = new MultipleAssignmentDisposable(); - - s.onSubscribe(mad); - - mad.set(scheduler.scheduleDirect(() -> s.onSuccess(0L), delay, unit)); + public static Single timer(final long delay, final TimeUnit unit, final Scheduler scheduler) { + Objects.requireNonNull(unit, "unit is null"); + Objects.requireNonNull(scheduler, "scheduler is null"); + return create(new SingleOnSubscribe() { + @Override + public void accept(final SingleSubscriber s) { + MultipleAssignmentDisposable mad = new MultipleAssignmentDisposable(); + + s.onSubscribe(mad); + + mad.set(scheduler.scheduleDirect(new Runnable() { + @Override + public void run() { + s.onSuccess(0L); + } + }, delay, unit)); + } }); } - public static Single equals(Single first, Single second) { - Objects.requireNonNull(first); - Objects.requireNonNull(second); - return create(s -> { - AtomicInteger count = new AtomicInteger(); - Object[] values = { null, null }; - - CompositeDisposable set = new CompositeDisposable(); - s.onSubscribe(set); - - class InnerSubscriber implements SingleSubscriber { - final int index; - public InnerSubscriber(int index) { - this.index = index; - } - @Override - public void onSubscribe(Disposable d) { - set.add(d); - } - - @Override - public void onSuccess(T value) { - values[index] = value; - - if (count.incrementAndGet() == 2) { - s.onSuccess(Objects.equals(values[0], values[1])); + public static Single equals(final Single first, final Single second) { + Objects.requireNonNull(first, "first is null"); + Objects.requireNonNull(second, "second is null"); + return create(new SingleOnSubscribe() { + @Override + public void accept(final SingleSubscriber s) { + final AtomicInteger count = new AtomicInteger(); + final Object[] values = { null, null }; + + final CompositeDisposable set = new CompositeDisposable(); + s.onSubscribe(set); + + class InnerSubscriber implements SingleSubscriber { + final int index; + public InnerSubscriber(int index) { + this.index = index; + } + @Override + public void onSubscribe(Disposable d) { + set.add(d); } - } - @Override - public void onError(Throwable e) { - for (;;) { - int state = count.get(); - if (state >= 2) { - RxJavaPlugins.onError(e); - return; + @Override + public void onSuccess(T value) { + values[index] = value; + + if (count.incrementAndGet() == 2) { + s.onSuccess(Objects.equals(values[0], values[1])); } - if (count.compareAndSet(state, 2)) { - s.onError(e); - return; + } + + @Override + public void onError(Throwable e) { + for (;;) { + int state = count.get(); + if (state >= 2) { + RxJavaPlugins.onError(e); + return; + } + if (count.compareAndSet(state, 2)) { + s.onError(e); + return; + } } } + } + first.subscribe(new InnerSubscriber(0)); + second.subscribe(new InnerSubscriber(1)); } - - first.subscribe(new InnerSubscriber(0)); - second.subscribe(new InnerSubscriber(1)); }); } - @SuppressWarnings("unchecked") - private static Function toFunction(BiFunction biFunction) { - Objects.requireNonNull(biFunction); - return a -> { - if (a.length != 2) { - throw new IllegalArgumentException("Array of size 2 expected but got " + a.length); - } - return ((BiFunction)biFunction).apply(a[0], a[1]); - }; - } - public static Single using(Supplier resourceSupplier, Function> singleFunction, Consumer disposer) { - return using(resourceSupplier, singleFunction, disposer); + return using(resourceSupplier, singleFunction, disposer, true); } - public static Single using(Supplier resourceSupplier, - Function> singleFunction, Consumer disposer, boolean eager) { - Objects.requireNonNull(resourceSupplier); - Objects.requireNonNull(singleFunction); - Objects.requireNonNull(disposer); + public static Single using( + final Supplier resourceSupplier, + final Function> singleFunction, + final Consumer disposer, + final boolean eager) { + Objects.requireNonNull(resourceSupplier, "resourceSupplier is null"); + Objects.requireNonNull(singleFunction, "singleFunction is null"); + Objects.requireNonNull(disposer, "disposer is null"); - return create(s -> { - U resource; - - try { - resource = resourceSupplier.get(); - } catch (Throwable ex) { - s.onSubscribe(EmptyDisposable.INSTANCE); - s.onError(ex); - return; - } - - Single s1; - - try { - s1 = singleFunction.apply(resource); - } catch (Throwable ex) { - s.onSubscribe(EmptyDisposable.INSTANCE); - s.onError(ex); - return; - } - - if (s1 == null) { - s.onSubscribe(EmptyDisposable.INSTANCE); - s.onError(new NullPointerException("The Single supplied by the function was null")); - return; - } - - s1.subscribe(new SingleSubscriber() { + return create(new SingleOnSubscribe() { + @Override + public void accept(final SingleSubscriber s) { + final U resource; + + try { + resource = resourceSupplier.get(); + } catch (Throwable ex) { + s.onSubscribe(EmptyDisposable.INSTANCE); + s.onError(ex); + return; + } + + Single s1; + + try { + s1 = singleFunction.apply(resource); + } catch (Throwable ex) { + s.onSubscribe(EmptyDisposable.INSTANCE); + s.onError(ex); + return; + } + + if (s1 == null) { + s.onSubscribe(EmptyDisposable.INSTANCE); + s.onError(new NullPointerException("The Single supplied by the function was null")); + return; + } + + s1.subscribe(new SingleSubscriber() { - @Override - public void onSubscribe(Disposable d) { - if (eager) { - CompositeDisposable set = new CompositeDisposable(); - set.add(d); - set.add(() -> { + @Override + public void onSubscribe(Disposable d) { + if (eager) { + CompositeDisposable set = new CompositeDisposable(); + set.add(d); + set.add(new Disposable() { + @Override + public void dispose() { + try { + disposer.accept(resource); + } catch (Throwable e) { + RxJavaPlugins.onError(e); + } + } + }); + } else { + s.onSubscribe(d); + } + } + + @Override + public void onSuccess(T value) { + if (eager) { try { disposer.accept(resource); } catch (Throwable e) { - RxJavaPlugins.onError(e); + s.onError(e); + return; } - }); - } else { - s.onSubscribe(d); - } - } - - @Override - public void onSuccess(T value) { - if (eager) { - try { - disposer.accept(resource); - } catch (Throwable e) { - s.onError(e); - return; } - } - s.onSuccess(value); - if (!eager) { - try { - disposer.accept(resource); - } catch (Throwable e) { - RxJavaPlugins.onError(e); + s.onSuccess(value); + if (!eager) { + try { + disposer.accept(resource); + } catch (Throwable e) { + RxJavaPlugins.onError(e); + } } } - } - @Override - public void onError(Throwable e) { - if (eager) { - try { - disposer.accept(resource); - } catch (Throwable ex) { - e.addSuppressed(ex); + @Override + public void onError(Throwable e) { + if (eager) { + try { + disposer.accept(resource); + } catch (Throwable ex) { + e = new CompositeException(ex, e); + } } - } - s.onError(e); - if (!eager) { - try { - disposer.accept(resource); - } catch (Throwable ex) { - e.addSuppressed(ex); - RxJavaPlugins.onError(e); + s.onError(e); + if (!eager) { + try { + disposer.accept(resource); + } catch (Throwable ex) { + RxJavaPlugins.onError(ex); + } } } - } - - }); + + }); + } }); } - public static Observable zip(Iterable> sources, Function zipper) { - Iterable> it = () -> { - Iterator> sit = sources.iterator(); - return new Iterator>() { + @SuppressWarnings("unchecked") + public static Single zip(final Iterable> sources, Function zipper) { + Objects.requireNonNull(sources, "sources is null"); + + Iterable> it = new Iterable>() { + @Override + public Iterator> iterator() { + final Iterator> sit = sources.iterator(); + return new Iterator>() { - @Override - public boolean hasNext() { - return sit.hasNext(); - } + @Override + public boolean hasNext() { + return sit.hasNext(); + } - @SuppressWarnings("unchecked") - @Override - public Observable next() { - return ((Observable)sit.next().toFlowable()); - } - - }; + @Override + public Observable next() { + return ((Observable)sit.next().toFlowable()); + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + }; + } }; - return Observable.zipIterable(zipper, false, 1, it); + return Observable.zipIterable(zipper, false, 1, it).toSingle(); } - public static Observable zip( + @SuppressWarnings("unchecked") + public static Single zip( Single s1, Single s2, BiFunction zipper ) { - Objects.requireNonNull(s1); - Objects.requireNonNull(s2); - return zipArray(toFunction(zipper), s1, s2); + Objects.requireNonNull(s1, "s1 is null"); + Objects.requireNonNull(s2, "s2 is null"); + return zipArray(Functions.toFunction(zipper), s1, s2); } - public static Observable zip( + @SuppressWarnings("unchecked") + public static Single zip( Single s1, Single s2, Single s3, Function3 zipper ) { - Objects.requireNonNull(s1); - Objects.requireNonNull(s2); - Objects.requireNonNull(s3); - return zipArray(zipper, s1, s2, s3); + Objects.requireNonNull(s1, "s1 is null"); + Objects.requireNonNull(s2, "s2 is null"); + Objects.requireNonNull(s3, "s3 is null"); + return zipArray(Functions.toFunction(zipper), s1, s2, s3); } - public static Observable zip( + @SuppressWarnings("unchecked") + public static Single zip( Single s1, Single s2, Single s3, Single s4, Function4 zipper ) { - Objects.requireNonNull(s1); - Objects.requireNonNull(s2); - Objects.requireNonNull(s3); - Objects.requireNonNull(s4); - return zipArray(zipper, s1, s2, s3, 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 zipArray(Functions.toFunction(zipper), s1, s2, s3, s4); } - public static Observable zip( + @SuppressWarnings("unchecked") + public static Single zip( Single s1, Single s2, Single s3, Single s4, Single s5, Function5 zipper ) { - Objects.requireNonNull(s1); - Objects.requireNonNull(s2); - Objects.requireNonNull(s3); - Objects.requireNonNull(s4); - Objects.requireNonNull(s5); - return zipArray(zipper, s1, s2, s3, s4, 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 zipArray(Functions.toFunction(zipper), s1, s2, s3, s4, s5); } - public static Observable zip( + @SuppressWarnings("unchecked") + public static Single zip( Single s1, Single s2, Single s3, Single s4, Single s5, Single s6, Function6 zipper ) { - Objects.requireNonNull(s1); - Objects.requireNonNull(s2); - Objects.requireNonNull(s3); - Objects.requireNonNull(s4); - Objects.requireNonNull(s5); - Objects.requireNonNull(s6); - return zipArray(zipper, s1, s2, s3, s4, s5, 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 zipArray(Functions.toFunction(zipper), s1, s2, s3, s4, s5, s6); } - public static Observable zip( + @SuppressWarnings("unchecked") + public static Single zip( Single s1, Single s2, Single s3, Single s4, Single s5, Single s6, Single s7, Function7 zipper ) { - Objects.requireNonNull(s1); - Objects.requireNonNull(s2); - Objects.requireNonNull(s3); - Objects.requireNonNull(s4); - Objects.requireNonNull(s5); - Objects.requireNonNull(s6); - Objects.requireNonNull(s7); - return zipArray(zipper, s1, s2, s3, s4, s5, s6, 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 zipArray(Functions.toFunction(zipper), s1, s2, s3, s4, s5, s6, s7); } - public static Observable zip( + @SuppressWarnings("unchecked") + public static Single zip( Single s1, Single s2, Single s3, Single s4, Single s5, Single s6, Single s7, Single s8, Function8 zipper ) { - Objects.requireNonNull(s1); - Objects.requireNonNull(s2); - Objects.requireNonNull(s3); - Objects.requireNonNull(s4); - Objects.requireNonNull(s5); - Objects.requireNonNull(s6); - Objects.requireNonNull(s7); - Objects.requireNonNull(s8); - return zipArray(zipper, s1, s2, s3, s4, s5, s6, s7, s8); - } - - public static Observable zip( + 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 zipArray(Functions.toFunction(zipper), s1, s2, s3, s4, s5, s6, s7, s8); + } + + @SuppressWarnings("unchecked") + public static Single zip( Single s1, Single s2, Single s3, Single s4, Single s5, Single s6, @@ -848,28 +980,27 @@ public static Observable zip( Single s9, Function9 zipper ) { - Objects.requireNonNull(s1); - Objects.requireNonNull(s2); - Objects.requireNonNull(s3); - Objects.requireNonNull(s4); - Objects.requireNonNull(s5); - Objects.requireNonNull(s6); - Objects.requireNonNull(s7); - Objects.requireNonNull(s8); - Objects.requireNonNull(s9); - return zipArray(zipper, s1, s2, s3, s4, s5, s6, s7, s8, s9); - } - - @SafeVarargs + 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 zipArray(Functions.toFunction(zipper), s1, s2, s3, s4, s5, s6, s7, s8, s9); + } + @SuppressWarnings({"rawtypes", "unchecked"}) - public static Observable zipArray(Function zipper, Single... sources) { + public static Single zipArray(Function zipper, Single... sources) { Publisher[] sourcePublishers = new Publisher[sources.length]; int i = 0; for (Single s : sources) { sourcePublishers[i] = s.toFlowable(); i++; } - return Observable.zipArray(zipper, false, 1, sourcePublishers); + return Observable.zipArray(zipper, false, 1, sourcePublishers).toSingle(); } protected final SingleOnSubscribe onSubscribe; @@ -878,12 +1009,19 @@ protected Single(SingleOnSubscribe onSubscribe) { this.onSubscribe = onSubscribe; } + @SuppressWarnings("unchecked") public final Single ambWith(Single other) { + Objects.requireNonNull(other, "other is null"); return amb(this, other); } public final Single asSingle() { - return create(s -> subscribe(s)); + return create(new SingleOnSubscribe() { + @Override + public void accept(SingleSubscriber s) { + subscribe(s); + } + }); } public final Single compose(Function, ? extends Single> convert) { @@ -891,106 +1029,113 @@ public final Single compose(Function, ? extends Single< } public final Single cache() { - AtomicInteger wip = new AtomicInteger(); - AtomicReference notification = new AtomicReference<>(); - List> subscribers = new ArrayList<>(); + final AtomicInteger wip = new AtomicInteger(); + final AtomicReference notification = new AtomicReference(); + final List> subscribers = new ArrayList>(); - return create(s -> { - Object o = notification.get(); - if (o != null) { - s.onSubscribe(EmptyDisposable.INSTANCE); - if (NotificationLite.isError(o)) { - s.onError(NotificationLite.getError(o)); - } else { - s.onSuccess(NotificationLite.getValue(o)); + return create(new SingleOnSubscribe() { + @Override + public void accept(SingleSubscriber s) { + Object o = notification.get(); + if (o != null) { + s.onSubscribe(EmptyDisposable.INSTANCE); + if (NotificationLite.isError(o)) { + s.onError(NotificationLite.getError(o)); + } else { + s.onSuccess(NotificationLite.getValue(o)); + } + return; } - return; - } - - synchronized (subscribers) { - o = notification.get(); - if (o == null) { - subscribers.add(s); + + synchronized (subscribers) { + o = notification.get(); + if (o == null) { + subscribers.add(s); + } } - } - if (o != null) { - s.onSubscribe(EmptyDisposable.INSTANCE); - if (NotificationLite.isError(o)) { - s.onError(NotificationLite.getError(o)); - } else { - s.onSuccess(NotificationLite.getValue(o)); + if (o != null) { + s.onSubscribe(EmptyDisposable.INSTANCE); + if (NotificationLite.isError(o)) { + s.onError(NotificationLite.getError(o)); + } else { + s.onSuccess(NotificationLite.getValue(o)); + } + return; } - return; - } - - if (wip.getAndIncrement() != 0) { - return; - } - - subscribe(new SingleSubscriber() { - - @Override - public void onSubscribe(Disposable d) { - + + if (wip.getAndIncrement() != 0) { + return; } + + subscribe(new SingleSubscriber() { - @Override - public void onSuccess(T value) { - notification.set(NotificationLite.next(value)); - List> list; - synchronized (subscribers) { - list = new ArrayList<>(subscribers); - subscribers.clear(); - } - for (SingleSubscriber s1 : list) { - s1.onSuccess(value); + @Override + public void onSubscribe(Disposable d) { + } - } - @Override - public void onError(Throwable e) { - notification.set(NotificationLite.error(e)); - List> list; - synchronized (subscribers) { - list = new ArrayList<>(subscribers); - subscribers.clear(); + @Override + public void onSuccess(T value) { + notification.set(NotificationLite.next(value)); + List> list; + synchronized (subscribers) { + list = new ArrayList>(subscribers); + subscribers.clear(); + } + for (SingleSubscriber s1 : list) { + s1.onSuccess(value); + } } - for (SingleSubscriber s1 : list) { - s1.onError(e); + + @Override + public void onError(Throwable e) { + notification.set(NotificationLite.error(e)); + List> list; + synchronized (subscribers) { + list = new ArrayList>(subscribers); + subscribers.clear(); + } + for (SingleSubscriber s1 : list) { + s1.onError(e); + } } - } - - }); + + }); + } }); } - public final Single cast(Class clazz) { - return create(s -> { - subscribe(new SingleSubscriber() { + public final Single cast(final Class clazz) { + Objects.requireNonNull(clazz, "clazz is null"); + return create(new SingleOnSubscribe() { + @Override + public void accept(final SingleSubscriber s) { + subscribe(new SingleSubscriber() { - @Override - public void onSubscribe(Disposable d) { - s.onSubscribe(d); - } + @Override + public void onSubscribe(Disposable d) { + s.onSubscribe(d); + } - @Override - public void onSuccess(T value) { - U v; - try { - v = clazz.cast(value); - } catch (ClassCastException ex) { - s.onError(ex); - return; + @Override + public void onSuccess(T value) { + U v; + try { + v = clazz.cast(value); + } catch (ClassCastException ex) { + s.onError(ex); + return; + } + s.onSuccess(v); } - s.onSuccess(v); - } - @Override - public void onError(Throwable e) { - s.onError(e); - } - - }); + @Override + public void onError(Throwable e) { + s.onError(e); + } + + }); + } }); } @@ -1002,156 +1147,179 @@ public final Single delay(long time, TimeUnit unit) { return delay(time, unit, Schedulers.computation()); } - public final Single delay(long time, TimeUnit unit, Scheduler scheduler) { - Objects.requireNonNull(unit); - Objects.requireNonNull(scheduler); - return create(s -> { - MultipleAssignmentDisposable mad = new MultipleAssignmentDisposable(); - s.onSubscribe(mad); - subscribe(new SingleSubscriber() { - @Override - public void onSubscribe(Disposable d) { - mad.set(d); - } + public final Single delay(final long time, final TimeUnit unit, final Scheduler scheduler) { + Objects.requireNonNull(unit, "unit is null"); + Objects.requireNonNull(scheduler, "scheduler is null"); + return create(new SingleOnSubscribe() { + @Override + public void accept(final SingleSubscriber s) { + final MultipleAssignmentDisposable mad = new MultipleAssignmentDisposable(); + s.onSubscribe(mad); + subscribe(new SingleSubscriber() { + @Override + public void onSubscribe(Disposable d) { + mad.set(d); + } - @Override - public void onSuccess(T value) { - mad.set(scheduler.scheduleDirect(() -> { - s.onSuccess(value); - }, time, unit)); - } + @Override + public void onSuccess(final T value) { + mad.set(scheduler.scheduleDirect(new Runnable() { + @Override + public void run() { + s.onSuccess(value); + } + }, time, unit)); + } - @Override - public void onError(Throwable e) { - s.onError(e); - } - - }); + @Override + public void onError(Throwable e) { + s.onError(e); + } + + }); + } }); } - public final Single doOnSubscribe(Consumer onSubscribe) { - return create(s -> { - subscribe(new SingleSubscriber() { - boolean done; - @Override - public void onSubscribe(Disposable d) { - try { - onSubscribe.accept(d); - } catch (Throwable ex) { - done = true; - d.dispose(); - s.onSubscribe(EmptyDisposable.INSTANCE); - s.onError(ex); - return; + public final Single doOnSubscribe(final Consumer onSubscribe) { + Objects.requireNonNull(onSubscribe, "onSubscribe is null"); + return create(new SingleOnSubscribe() { + @Override + public void accept(final SingleSubscriber s) { + subscribe(new SingleSubscriber() { + boolean done; + @Override + public void onSubscribe(Disposable d) { + try { + onSubscribe.accept(d); + } catch (Throwable ex) { + done = true; + d.dispose(); + s.onSubscribe(EmptyDisposable.INSTANCE); + s.onError(ex); + return; + } + + s.onSubscribe(d); } - - s.onSubscribe(d); - } - @Override - public void onSuccess(T value) { - if (done) { - return; + @Override + public void onSuccess(T value) { + if (done) { + return; + } + s.onSuccess(value); } - s.onSuccess(value); - } - @Override - public void onError(Throwable e) { - if (done) { - RxJavaPlugins.onError(e); - return; + @Override + public void onError(Throwable e) { + if (done) { + RxJavaPlugins.onError(e); + return; + } + s.onError(e); } - s.onError(e); - } - - }); + + }); + } }); } - public final Single doOnSuccess(Consumer onSuccess) { - return create(s -> { - subscribe(new SingleSubscriber() { - @Override - public void onSubscribe(Disposable d) { - s.onSubscribe(d); - } + public final Single doOnSuccess(final Consumer onSuccess) { + Objects.requireNonNull(onSuccess, "onSuccess is null"); + return create(new SingleOnSubscribe() { + @Override + public void accept(final SingleSubscriber s) { + subscribe(new SingleSubscriber() { + @Override + public void onSubscribe(Disposable d) { + s.onSubscribe(d); + } - @Override - public void onSuccess(T value) { - try { - onSuccess.accept(value); - } catch (Throwable ex) { - s.onError(ex); - return; + @Override + public void onSuccess(T value) { + try { + onSuccess.accept(value); + } catch (Throwable ex) { + s.onError(ex); + return; + } + s.onSuccess(value); } - s.onSuccess(value); - } - @Override - public void onError(Throwable e) { - s.onError(e); - } - - }); + @Override + public void onError(Throwable e) { + s.onError(e); + } + + }); + } }); } - public final Single doOnError(Consumer onError) { - return create(s -> { - subscribe(new SingleSubscriber() { - @Override - public void onSubscribe(Disposable d) { - s.onSubscribe(d); - } + public final Single doOnError(final Consumer onError) { + Objects.requireNonNull(onError, "onError is null"); + return create(new SingleOnSubscribe() { + @Override + public void accept(final SingleSubscriber s) { + subscribe(new SingleSubscriber() { + @Override + public void onSubscribe(Disposable d) { + s.onSubscribe(d); + } - @Override - public void onSuccess(T value) { - s.onSuccess(value); - } + @Override + public void onSuccess(T value) { + s.onSuccess(value); + } - @Override - public void onError(Throwable e) { - try { - onError.accept(e); - } catch (Throwable ex) { - e.addSuppressed(ex); + @Override + public void onError(Throwable e) { + try { + onError.accept(e); + } catch (Throwable ex) { + e = new CompositeException(ex, e); + } + s.onError(e); } - s.onError(e); - } - - }); + + }); + } }); } - public final Single doOnCancel(Runnable onCancel) { - return create(s -> { - subscribe(new SingleSubscriber() { - @Override - public void onSubscribe(Disposable d) { - CompositeDisposable set = new CompositeDisposable(); - set.add(onCancel::run); - set.add(d); - s.onSubscribe(set); - } + public final Single doOnCancel(final Runnable onCancel) { + Objects.requireNonNull(onCancel, "onCancel is null"); + return create(new SingleOnSubscribe() { + @Override + public void accept(final SingleSubscriber s) { + subscribe(new SingleSubscriber() { + @Override + public void onSubscribe(Disposable d) { + CompositeDisposable set = new CompositeDisposable(); + set.add(Disposables.from(onCancel)); + set.add(d); + s.onSubscribe(set); + } - @Override - public void onSuccess(T value) { - s.onSuccess(value); - } + @Override + public void onSuccess(T value) { + s.onSuccess(value); + } - @Override - public void onError(Throwable e) { - s.onError(e); - } - - }); + @Override + public void onError(Throwable e) { + s.onError(e); + } + + }); + } }); } public final Single flatMap(Function> mapper) { - return lift(new SingleOperatorFlatMap<>(mapper)); + Objects.requireNonNull(mapper, "mapper is null"); + return lift(new SingleOperatorFlatMap(mapper)); } public final Observable flatMapPublisher(Function> mapper) { @@ -1159,9 +1327,9 @@ public final Observable flatMapPublisher(Function valueRef = new AtomicReference<>(); - AtomicReference errorRef = new AtomicReference<>(); - CountDownLatch cdl = new CountDownLatch(1); + final AtomicReference valueRef = new AtomicReference(); + final AtomicReference errorRef = new AtomicReference(); + final CountDownLatch cdl = new CountDownLatch(1); subscribe(new SingleSubscriber() { @Override @@ -1194,43 +1362,64 @@ public void onSuccess(T value) { return valueRef.get(); } - public final Single lift(SingleOperator onLift) { - Objects.requireNonNull(onLift); - return create(s -> { - SingleSubscriber sr = onLift.apply(s); - // TODO plugin wrapper - onSubscribe.accept(sr); + public final Single lift(final SingleOperator onLift) { + Objects.requireNonNull(onLift, "onLift is null"); + return create(new SingleOnSubscribe() { + @Override + public void accept(SingleSubscriber s) { + try { + SingleSubscriber sr = onLift.apply(s); + + if (sr == null) { + throw new NullPointerException("The onLift returned a null subscriber"); + } + // TODO plugin wrapper + onSubscribe.accept(sr); + } catch (NullPointerException ex) { + throw ex; + } catch (Throwable ex) { + RxJavaPlugins.onError(ex); + NullPointerException npe = new NullPointerException("Not really but can't throw other than NPE"); + npe.initCause(ex); + throw npe; + } + } }); } public final Single map(Function mapper) { - return lift(new SingleOperatorMap<>(mapper)); + return lift(new SingleOperatorMap(mapper)); } public final Single contains(Object value) { - return contains(value, Objects::equals); + return contains(value, Objects.equalsPredicate()); } - public final Single contains(Object value, BiPredicate comparer) { - return create(s -> { - subscribe(new SingleSubscriber() { + public final Single contains(final Object value, final BiPredicate comparer) { + Objects.requireNonNull(value, "value is null"); + Objects.requireNonNull(comparer, "comparer is null"); + return create(new SingleOnSubscribe() { + @Override + public void accept(final SingleSubscriber s) { + subscribe(new SingleSubscriber() { - @Override - public void onSubscribe(Disposable d) { - s.onSubscribe(d); - } + @Override + public void onSubscribe(Disposable d) { + s.onSubscribe(d); + } - @Override - public void onSuccess(T v) { - s.onSuccess(comparer.test(v, value)); - } + @Override + public void onSuccess(T v) { + s.onSuccess(comparer.test(v, value)); + } - @Override - public void onError(Throwable e) { - s.onError(e); - } - - }); + @Override + public void onError(Throwable e) { + s.onError(e); + } + + }); + } }); } @@ -1242,131 +1431,160 @@ public final Single> nest() { return just(this); } - public final Single observeOn(Scheduler scheduler) { - return create(s -> { - CompositeDisposable mad = new CompositeDisposable(); - s.onSubscribe(mad); - - subscribe(new SingleSubscriber() { + public final Single observeOn(final Scheduler scheduler) { + Objects.requireNonNull(scheduler, "scheduler is null"); + return create(new SingleOnSubscribe() { + @Override + public void accept(final SingleSubscriber s) { + final CompositeDisposable mad = new CompositeDisposable(); + s.onSubscribe(mad); + + subscribe(new SingleSubscriber() { - @Override - public void onError(Throwable e) { - mad.add(scheduler.scheduleDirect(() -> s.onError(e))); - } + @Override + public void onError(final Throwable e) { + mad.add(scheduler.scheduleDirect(new Runnable() { + @Override + public void run() { + s.onError(e); + } + })); + } - @Override - public void onSubscribe(Disposable d) { - mad.add(d); - } + @Override + public void onSubscribe(Disposable d) { + mad.add(d); + } - @Override - public void onSuccess(T value) { - mad.add(scheduler.scheduleDirect(() -> s.onSuccess(value))); - } - - }); + @Override + public void onSuccess(final T value) { + mad.add(scheduler.scheduleDirect(new Runnable() { + @Override + public void run() { + s.onSuccess(value); + } + })); + } + + }); + } }); } - public final Single onErrorReturn(Supplier valueSupplier) { - return create(s -> { - subscribe(new SingleSubscriber() { + public final Single onErrorReturn(final Supplier valueSupplier) { + Objects.requireNonNull(valueSupplier, "valueSupplier is null"); + return create(new SingleOnSubscribe() { + @Override + public void accept(final SingleSubscriber s) { + subscribe(new SingleSubscriber() { - @Override - public void onError(Throwable e) { - T v; - - try { - v = valueSupplier.get(); - } catch (Throwable ex) { - e.addSuppressed(ex); - s.onError(e); - return; - } - - if (v == null) { - e.addSuppressed(new NullPointerException("Value supplied was null")); - s.onError(e); - return; + @Override + public void onError(Throwable e) { + T v; + + try { + v = valueSupplier.get(); + } catch (Throwable ex) { + s.onError(new CompositeException(ex, e)); + return; + } + + if (v == null) { + NullPointerException npe = new NullPointerException("Value supplied was null"); + npe.initCause(e); + s.onError(npe); + return; + } + + s.onSuccess(v); } - - s.onSuccess(v); - } - @Override - public void onSubscribe(Disposable d) { - s.onSubscribe(d); - } + @Override + public void onSubscribe(Disposable d) { + s.onSubscribe(d); + } - @Override - public void onSuccess(T value) { - s.onSuccess(value); - } - - }); + @Override + public void onSuccess(T value) { + s.onSuccess(value); + } + + }); + } }); } - public final Single onErrorReturn(T value) { - Objects.requireNonNull(value); - return onErrorReturn(() -> value); + public final Single onErrorReturn(final T value) { + Objects.requireNonNull(value, "value is null"); + return onErrorReturn(new Supplier() { + @Override + public T get() { + return value; + } + }); } - public final Single onErrorResumeNext(Function> nextFunction) { - return create(s -> { - MultipleAssignmentDisposable mad = new MultipleAssignmentDisposable(); - s.onSubscribe(mad); - - subscribe(new SingleSubscriber() { - - @Override - public void onSubscribe(Disposable d) { - mad.set(d); - } - - @Override - public void onSuccess(T value) { - s.onSuccess(value); - } + public final Single onErrorResumeNext( + final Function> nextFunction) { + Objects.requireNonNull(nextFunction, "nextFunction is null"); + return create(new SingleOnSubscribe() { + @Override + public void accept(final SingleSubscriber s) { + final MultipleAssignmentDisposable mad = new MultipleAssignmentDisposable(); + s.onSubscribe(mad); + + subscribe(new SingleSubscriber() { - @Override - public void onError(Throwable e) { - Single next; - - try { - next = nextFunction.apply(e); - } catch (Throwable ex) { - e.addSuppressed(ex); - s.onError(e); - return; - } - - if (next == null) { - s.onError(new NullPointerException("The next Single supplied was null")); - return; + @Override + public void onSubscribe(Disposable d) { + mad.set(d); } - - next.subscribe(new SingleSubscriber() { - @Override - public void onSubscribe(Disposable d) { - mad.set(d); - } + @Override + public void onSuccess(T value) { + s.onSuccess(value); + } - @Override - public void onSuccess(T value) { - s.onSuccess(value); + @Override + public void onError(Throwable e) { + Single next; + + try { + next = nextFunction.apply(e); + } catch (Throwable ex) { + s.onError(new CompositeException(ex, e)); + return; } - - @Override - public void onError(Throwable e) { - s.onError(e); + + if (next == null) { + NullPointerException npe = new NullPointerException("The next Single supplied was null"); + npe.initCause(e); + s.onError(npe); + return; } - }); - } - - }); + next.subscribe(new SingleSubscriber() { + + @Override + public void onSubscribe(Disposable d) { + mad.set(d); + } + + @Override + public void onSuccess(T value) { + s.onSuccess(value); + } + + @Override + public void onError(Throwable e) { + s.onError(e); + } + + }); + } + + }); + } }); } @@ -1378,7 +1596,7 @@ public final Observable repeat(long times) { return toFlowable().repeat(times); } - public final Observable repeatWhen(Function, ? extends Publisher> handler) { + public final Observable repeatWhen(Function, ? extends Publisher> handler) { return toFlowable().repeatWhen(handler); } @@ -1402,7 +1620,7 @@ public final Single retry(Predicate predicate) { return toFlowable().retry(predicate).toSingle(); } - public final Single retryWhen(Function, ? extends Publisher> handler) { + public final Single retryWhen(Function, ? extends Publisher> handler) { return toFlowable().retryWhen(handler).toSingle(); } @@ -1411,13 +1629,13 @@ public final void safeSubscribe(Subscriber s) { } public final Disposable subscribe() { - return subscribe(v -> { }, RxJavaPlugins::onError); + return subscribe(Functions.emptyConsumer(), RxJavaPlugins.errorConsumer()); } - public final Disposable subscribe(BiConsumer onCallback) { - Objects.requireNonNull(onCallback); + public final Disposable subscribe(final BiConsumer onCallback) { + Objects.requireNonNull(onCallback, "onCallback is null"); - MultipleAssignmentDisposable mad = new MultipleAssignmentDisposable(); + final MultipleAssignmentDisposable mad = new MultipleAssignmentDisposable(); subscribe(new SingleSubscriber() { @Override @@ -1440,14 +1658,14 @@ public void onSuccess(T value) { } public final Disposable subscribe(Consumer onSuccess) { - return subscribe(onSuccess, RxJavaPlugins::onError); + return subscribe(onSuccess, RxJavaPlugins.errorConsumer()); } - public final Disposable subscribe(Consumer onSuccess, Consumer onError) { - Objects.requireNonNull(onSuccess); - Objects.requireNonNull(onError); + public final Disposable subscribe(final Consumer onSuccess, final Consumer onError) { + Objects.requireNonNull(onSuccess, "onSuccess is null"); + Objects.requireNonNull(onError, "onError is null"); - MultipleAssignmentDisposable mad = new MultipleAssignmentDisposable(); + final MultipleAssignmentDisposable mad = new MultipleAssignmentDisposable(); subscribe(new SingleSubscriber() { @Override @@ -1470,7 +1688,8 @@ public void onSuccess(T value) { } public final void subscribe(SingleSubscriber subscriber) { - Objects.requireNonNull(subscriber); + Objects.requireNonNull(subscriber, "subscriber is null"); + // TODO plugin wrapper onSubscribe.accept(subscriber); } @@ -1478,103 +1697,111 @@ public final void subscribe(Subscriber s) { toFlowable().subscribe(s); } - public final Single subscribeOn(Scheduler scheduler) { - Objects.requireNonNull(scheduler); - return create(s -> { - scheduler.scheduleDirect(() -> { - subscribe(s); - }); + public final Single subscribeOn(final Scheduler scheduler) { + Objects.requireNonNull(scheduler, "scheduler is null"); + return create(new SingleOnSubscribe() { + @Override + public void accept(final SingleSubscriber s) { + scheduler.scheduleDirect(new Runnable() { + @Override + public void run() { + subscribe(s); + } + }); + } }); } public final Single timeout(long timeout, TimeUnit unit) { - Objects.requireNonNull(unit); return timeout0(timeout, unit, Schedulers.computation(), null); } public final Single timeout(long timeout, TimeUnit unit, Scheduler scheduler) { - Objects.requireNonNull(unit); - Objects.requireNonNull(scheduler); return timeout0(timeout, unit, scheduler, null); } public final Single timeout(long timeout, TimeUnit unit, Scheduler scheduler, Single other) { - Objects.requireNonNull(unit); - Objects.requireNonNull(scheduler); - Objects.requireNonNull(other); + Objects.requireNonNull(other, "other is null"); return timeout0(timeout, unit, scheduler, other); } public final Single timeout(long timeout, TimeUnit unit, Single other) { - Objects.requireNonNull(unit); - Objects.requireNonNull(other); + Objects.requireNonNull(other, "other is null"); return timeout0(timeout, unit, Schedulers.computation(), other); } - private Single timeout0(long timeout, TimeUnit unit, Scheduler scheduler, Single other) { - return create(s -> { - CompositeDisposable set = new CompositeDisposable(); - s.onSubscribe(set); - - AtomicBoolean once = new AtomicBoolean(); - - Disposable timer = scheduler.scheduleDirect(() -> { - if (once.compareAndSet(false, true)) { - if (other != null) { - set.clear(); - other.subscribe(new SingleSubscriber() { - - @Override - public void onError(Throwable e) { - set.dispose(); - s.onError(e); - } - - @Override - public void onSubscribe(Disposable d) { - set.add(d); - } - - @Override - public void onSuccess(T value) { + private Single timeout0(final long timeout, final TimeUnit unit, final Scheduler scheduler, final Single other) { + Objects.requireNonNull(unit, "unit is null"); + Objects.requireNonNull(scheduler, "scheduler is null"); + return create(new SingleOnSubscribe() { + @Override + public void accept(final SingleSubscriber s) { + final CompositeDisposable set = new CompositeDisposable(); + s.onSubscribe(set); + + final AtomicBoolean once = new AtomicBoolean(); + + Disposable timer = scheduler.scheduleDirect(new Runnable() { + @Override + public void run() { + if (once.compareAndSet(false, true)) { + if (other != null) { + set.clear(); + other.subscribe(new SingleSubscriber() { + + @Override + public void onError(Throwable e) { + set.dispose(); + s.onError(e); + } + + @Override + public void onSubscribe(Disposable d) { + set.add(d); + } + + @Override + public void onSuccess(T value) { + set.dispose(); + s.onSuccess(value); + } + + }); + } else { set.dispose(); - s.onSuccess(value); + s.onError(new TimeoutException()); } - - }); - } else { - set.dispose(); - s.onError(new TimeoutException()); + } } - } - }, timeout, unit); - - set.add(timer); - - subscribe(new SingleSubscriber() { + }, timeout, unit); + + set.add(timer); + + subscribe(new SingleSubscriber() { - @Override - public void onError(Throwable e) { - if (once.compareAndSet(false, true)) { - set.dispose(); - s.onError(e); + @Override + public void onError(Throwable e) { + if (once.compareAndSet(false, true)) { + set.dispose(); + s.onError(e); + } } - } - @Override - public void onSubscribe(Disposable d) { - set.add(d); - } + @Override + public void onSubscribe(Disposable d) { + set.add(d); + } - @Override - public void onSuccess(T value) { - if (once.compareAndSet(false, true)) { - set.dispose(); - s.onSuccess(value); + @Override + public void onSuccess(T value) { + if (once.compareAndSet(false, true)) { + set.dispose(); + s.onSuccess(value); + } } - } - - }); + + }); + } }); } @@ -1583,29 +1810,32 @@ public final R to(Function, R> convert) { } public final Observable toFlowable() { - return Observable.create(s -> { - ScalarAsyncSubscription sas = new ScalarAsyncSubscription<>(s); - AsyncSubscription as = new AsyncSubscription(); - as.setSubscription(sas); - s.onSubscribe(as); - - subscribe(new SingleSubscriber() { - @Override - public void onError(Throwable e) { - s.onError(e); - } + return Observable.create(new Publisher() { + @Override + public void subscribe(final Subscriber s) { + final ScalarAsyncSubscription sas = new ScalarAsyncSubscription(s); + final AsyncSubscription as = new AsyncSubscription(); + as.setSubscription(sas); + s.onSubscribe(as); + + Single.this.subscribe(new SingleSubscriber() { + @Override + public void onError(Throwable e) { + s.onError(e); + } - @Override - public void onSubscribe(Disposable d) { - as.setResource(d); - } + @Override + public void onSubscribe(Disposable d) { + as.setResource(d); + } - @Override - public void onSuccess(T value) { - sas.setValue(value); - } - - }); + @Override + public void onSuccess(T value) { + sas.setValue(value); + } + + }); + } }); } @@ -1613,7 +1843,7 @@ public final void unsafeSubscribe(Subscriber s) { toFlowable().unsafeSubscribe(s); } - public final Observable zipWith(Single other, BiFunction zipper) { + public final Single zipWith(Single other, BiFunction zipper) { return zip(this, other, zipper); } -} +} \ No newline at end of file diff --git a/src/main/java/io/reactivex/Try.java b/src/main/java/io/reactivex/Try.java index 249d3bb12d..c069826685 100644 --- a/src/main/java/io/reactivex/Try.java +++ b/src/main/java/io/reactivex/Try.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,7 +13,7 @@ package io.reactivex; -import java.util.Objects; +import io.reactivex.internal.functions.Objects; /** * Container for either a value of type T or a Throwable. @@ -34,12 +34,13 @@ private Try(T value, Throwable error) { /** * Constructs a Try instance by wrapping the given value. * + * @param the value type * @param value the value to wrap * @return the created Try instance */ public static Try ofValue(T value) { // TODO ? Objects.requireNonNull(value); - return new Try<>(value, null); + return new Try(value, null); } /** @@ -47,11 +48,12 @@ public static Try ofValue(T value) { * *

Null Throwables are replaced by NullPointerException instance in this Try. * + * @param the value type * @param e the exception to wrap * @return the new Try instance holding the exception */ public static Try ofError(Throwable e) { - return new Try<>(null, e != null ? e : new NullPointerException()); + return new Try(null, e != null ? e : new NullPointerException()); } /** diff --git a/src/main/java/io/reactivex/annotations/BackpressureKind.java b/src/main/java/io/reactivex/annotations/BackpressureKind.java index b56288eddb..20af7d074c 100644 --- a/src/main/java/io/reactivex/annotations/BackpressureKind.java +++ b/src/main/java/io/reactivex/annotations/BackpressureKind.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 diff --git a/src/main/java/io/reactivex/annotations/BackpressureSupport.java b/src/main/java/io/reactivex/annotations/BackpressureSupport.java index 26d280b7cb..a6a225c53e 100644 --- a/src/main/java/io/reactivex/annotations/BackpressureSupport.java +++ b/src/main/java/io/reactivex/annotations/BackpressureSupport.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 diff --git a/src/main/java/io/reactivex/annotations/Beta.java b/src/main/java/io/reactivex/annotations/Beta.java index 97be083ed9..128070d386 100644 --- a/src/main/java/io/reactivex/annotations/Beta.java +++ b/src/main/java/io/reactivex/annotations/Beta.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 diff --git a/src/main/java/io/reactivex/annotations/Experimental.java b/src/main/java/io/reactivex/annotations/Experimental.java index 43c2d88e97..374fe3c2f6 100644 --- a/src/main/java/io/reactivex/annotations/Experimental.java +++ b/src/main/java/io/reactivex/annotations/Experimental.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 diff --git a/src/main/java/io/reactivex/annotations/SchedulerKind.java b/src/main/java/io/reactivex/annotations/SchedulerKind.java index 6da76ae9b5..246951d7ae 100644 --- a/src/main/java/io/reactivex/annotations/SchedulerKind.java +++ b/src/main/java/io/reactivex/annotations/SchedulerKind.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 diff --git a/src/main/java/io/reactivex/annotations/SchedulerSupport.java b/src/main/java/io/reactivex/annotations/SchedulerSupport.java index 06a085c300..e83c7ae38d 100644 --- a/src/main/java/io/reactivex/annotations/SchedulerSupport.java +++ b/src/main/java/io/reactivex/annotations/SchedulerSupport.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 diff --git a/src/main/java/io/reactivex/disposables/BooleanDisposable.java b/src/main/java/io/reactivex/disposables/BooleanDisposable.java index 5892e3efb0..2593a2b564 100644 --- a/src/main/java/io/reactivex/disposables/BooleanDisposable.java +++ b/src/main/java/io/reactivex/disposables/BooleanDisposable.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,29 +13,32 @@ package io.reactivex.disposables; -import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; +import java.util.concurrent.atomic.AtomicReference; public final class BooleanDisposable implements Disposable { - volatile Runnable run; + final AtomicReference run = new AtomicReference(); - static final AtomicReferenceFieldUpdater RUN = - AtomicReferenceFieldUpdater.newUpdater(BooleanDisposable.class, Runnable.class, "run"); - - static final Runnable DISPOSED = () -> { }; + static final Runnable DISPOSED = new Runnable() { + @Override + public void run() { } + }; public BooleanDisposable() { - this(() -> { }); + this(new Runnable() { + @Override + public void run() { } + }); } public BooleanDisposable(Runnable run) { - RUN.lazySet(this, run); + this.run.lazySet(run); } @Override public void dispose() { - Runnable r = run; + Runnable r = run.get(); if (r != DISPOSED) { - r = RUN.getAndSet(this, DISPOSED); + r = run.getAndSet(DISPOSED); if (r != DISPOSED) { r.run(); } @@ -43,6 +46,6 @@ public void dispose() { } public boolean isDisposed() { - return run == DISPOSED; + return run.get() == DISPOSED; } } diff --git a/src/main/java/io/reactivex/disposables/CompositeDisposable.java b/src/main/java/io/reactivex/disposables/CompositeDisposable.java index 145acadaef..6551b6c85b 100644 --- a/src/main/java/io/reactivex/disposables/CompositeDisposable.java +++ b/src/main/java/io/reactivex/disposables/CompositeDisposable.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -12,9 +12,8 @@ */ package io.reactivex.disposables; -import java.util.Objects; - import io.reactivex.internal.disposables.SetCompositeResource; +import io.reactivex.internal.functions.Objects; /** * A disposable container that can hold onto multiple other disposables. @@ -22,19 +21,19 @@ public final class CompositeDisposable implements Disposable { final SetCompositeResource resources; - + public CompositeDisposable() { - resources = new SetCompositeResource<>(Disposable::dispose); + resources = new SetCompositeResource(Disposables.consumeAndDispose()); } public CompositeDisposable(Disposable... resources) { - Objects.requireNonNull(resources); - this.resources = new SetCompositeResource<>(Disposable::dispose, resources); + Objects.requireNonNull(resources, "resources is null"); + this.resources = new SetCompositeResource(Disposables.consumeAndDispose(), resources); } public CompositeDisposable(Iterable resources) { - Objects.requireNonNull(resources); - this.resources = new SetCompositeResource<>(Disposable::dispose, resources); + Objects.requireNonNull(resources, "resources is null"); + this.resources = new SetCompositeResource(Disposables.consumeAndDispose(), resources); } @Override diff --git a/src/main/java/io/reactivex/disposables/Disposable.java b/src/main/java/io/reactivex/disposables/Disposable.java index 4cf1317fed..12974a31cf 100644 --- a/src/main/java/io/reactivex/disposables/Disposable.java +++ b/src/main/java/io/reactivex/disposables/Disposable.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 diff --git a/src/main/java/io/reactivex/disposables/Disposables.java b/src/main/java/io/reactivex/disposables/Disposables.java index 86ba103980..894d2f745f 100644 --- a/src/main/java/io/reactivex/disposables/Disposables.java +++ b/src/main/java/io/reactivex/disposables/Disposables.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,9 +13,13 @@ package io.reactivex.disposables; -import java.util.Objects; import java.util.concurrent.*; -import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; +import java.util.concurrent.atomic.*; + +import org.reactivestreams.Subscription; + +import io.reactivex.functions.Consumer; +import io.reactivex.internal.functions.Objects; /** * Utility class to help create disposables by wrapping @@ -28,7 +32,7 @@ private Disposables() { } public static Disposable from(Runnable run) { - Objects.requireNonNull(run); + Objects.requireNonNull(run, "run is null"); return new RunnableDisposable(run); } @@ -37,19 +41,35 @@ public static Disposable from(Future future) { return from(future, true); } + public static Disposable from(final Subscription subscription) { + Objects.requireNonNull(subscription, "subscription is null"); + return new Disposable() { + @Override + public void dispose() { + subscription.cancel(); + } + }; + } + public static Disposable from(Future future, boolean allowInterrupt) { - Objects.requireNonNull(future); + Objects.requireNonNull(future, "future is null"); return new FutureDisposable(future, allowInterrupt); } - static final Disposable EMPTY = () -> { }; + static final Disposable EMPTY = new Disposable() { + @Override + public void dispose() { } + }; public static Disposable empty() { return EMPTY; } // TODO there is no way to distinguish a disposed and non-disposed resource - static final Disposable DISPOSED = () -> { }; + static final Disposable DISPOSED = new Disposable() { + @Override + public void dispose() { } + }; public static Disposable disposed() { return DISPOSED; @@ -60,23 +80,27 @@ public static CompositeDisposable from(Disposable... resources) { } /** Wraps a Runnable instance. */ - static final class RunnableDisposable implements Disposable { - volatile Runnable run; - - static final AtomicReferenceFieldUpdater RUN = - AtomicReferenceFieldUpdater.newUpdater(RunnableDisposable.class, Runnable.class, "run"); + static final class RunnableDisposable + extends AtomicReference + implements Disposable { + + /** */ + private static final long serialVersionUID = 4892876354773733738L; - static final Runnable DISPOSED = () -> { }; + static final Runnable DISPOSED = new Runnable() { + @Override + public void run() { } + }; public RunnableDisposable(Runnable run) { - RUN.lazySet(this, run); + super(run); } @Override public void dispose() { - Runnable r = run; + Runnable r = get(); if (r != DISPOSED) { - r = RUN.getAndSet(this, DISPOSED); + r = getAndSet(DISPOSED); if (r != DISPOSED) { r.run(); } @@ -85,25 +109,24 @@ public void dispose() { } /** Wraps a Future instance. */ - static final class FutureDisposable implements Disposable { - volatile Future future; - + static final class FutureDisposable + extends AtomicReference> + implements Disposable { + /** */ + private static final long serialVersionUID = -569898983717900525L; + final boolean allowInterrupt; - @SuppressWarnings("rawtypes") - static final AtomicReferenceFieldUpdater RUN = - AtomicReferenceFieldUpdater.newUpdater(FutureDisposable.class, Future.class, "future"); - public FutureDisposable(Future run, boolean allowInterrupt) { + super(run); this.allowInterrupt = allowInterrupt; - RUN.lazySet(this, run); } @Override public void dispose() { - Future r = future; + Future r = get(); if (r != DisposedFuture.INSTANCE) { - r = RUN.getAndSet(this, DisposedFuture.INSTANCE); + r = getAndSet(DisposedFuture.INSTANCE); if (r != DisposedFuture.INSTANCE) { r.cancel(allowInterrupt); } @@ -141,4 +164,19 @@ public Object get(long timeout, TimeUnit unit) return null; } } + + static final Consumer DISPOSER = new Consumer() { + @Override + public void accept(Disposable d) { + d.dispose(); + } + }; + + /** + * Returns a consumer that calls dispose on the received Disposable. + * @return the consumer that calls dispose on the received Disposable. + */ + public static Consumer consumeAndDispose() { + return DISPOSER; + } } diff --git a/src/main/java/io/reactivex/disposables/MultipleAssignmentDisposable.java b/src/main/java/io/reactivex/disposables/MultipleAssignmentDisposable.java index a462aac6ed..c243901d82 100644 --- a/src/main/java/io/reactivex/disposables/MultipleAssignmentDisposable.java +++ b/src/main/java/io/reactivex/disposables/MultipleAssignmentDisposable.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -19,11 +19,11 @@ public final class MultipleAssignmentDisposable implements Disposable { final MultipleAssignmentResource resource; public MultipleAssignmentDisposable() { - this.resource = new MultipleAssignmentResource<>(Disposable::dispose); + this.resource = new MultipleAssignmentResource(Disposables.consumeAndDispose()); } public MultipleAssignmentDisposable(Disposable initialDisposable) { - this.resource = new MultipleAssignmentResource<>(Disposable::dispose, initialDisposable); + this.resource = new MultipleAssignmentResource(Disposables.consumeAndDispose(), initialDisposable); } public void set(Disposable d) { diff --git a/src/main/java/io/reactivex/disposables/RefCountDisposable.java b/src/main/java/io/reactivex/disposables/RefCountDisposable.java index 863dd1c252..b3fd87daa4 100644 --- a/src/main/java/io/reactivex/disposables/RefCountDisposable.java +++ b/src/main/java/io/reactivex/disposables/RefCountDisposable.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,44 +13,42 @@ package io.reactivex.disposables; -import java.util.Objects; import java.util.concurrent.atomic.*; +import io.reactivex.internal.functions.Objects; + public final class RefCountDisposable implements Disposable { - volatile Disposable resource; - static final AtomicReferenceFieldUpdater RESOURCE = - AtomicReferenceFieldUpdater.newUpdater(RefCountDisposable.class, Disposable.class, "resource"); - - static final Disposable DISPOSED = () -> { }; + final AtomicReference resource = new AtomicReference(); + + static final Disposable DISPOSED = new Disposable() { + @Override + public void dispose() { } + }; - volatile int count; - static final AtomicIntegerFieldUpdater COUNT = - AtomicIntegerFieldUpdater.newUpdater(RefCountDisposable.class, "count"); + final AtomicInteger count = new AtomicInteger(); - volatile int once; - static final AtomicIntegerFieldUpdater ONCE = - AtomicIntegerFieldUpdater.newUpdater(RefCountDisposable.class, "once"); + final AtomicBoolean once = new AtomicBoolean(); public RefCountDisposable(Disposable resource) { - Objects.requireNonNull(resource); - RESOURCE.lazySet(this, resource); - COUNT.lazySet(this, 1); + Objects.requireNonNull(resource, "resource is null"); + this.resource.lazySet(resource); + count.lazySet(1); } @Override public void dispose() { - if (ONCE.compareAndSet(this, 0, 1)) { - if (COUNT.decrementAndGet(this) == 0) { + if (once.compareAndSet(false, true)) { + if (count.decrementAndGet() == 0) { disposeActual(); } } } void disposeActual() { - Disposable d = resource; + Disposable d = resource.get(); if (d != DISPOSED) { - d = RESOURCE.getAndSet(this, DISPOSED); + d = resource.getAndSet(DISPOSED); if (d != DISPOSED && d != null) { d.dispose(); } @@ -58,12 +56,12 @@ void disposeActual() { } public Disposable get() { - COUNT.getAndIncrement(this); + count.getAndIncrement(); return new InnerDisposable(this); } void release() { - if (COUNT.decrementAndGet(this) == 0) { + if (count.decrementAndGet() == 0) { disposeActual(); } } diff --git a/src/main/java/io/reactivex/disposables/SerialDisposable.java b/src/main/java/io/reactivex/disposables/SerialDisposable.java index 49e41b9da1..f7968b84d7 100644 --- a/src/main/java/io/reactivex/disposables/SerialDisposable.java +++ b/src/main/java/io/reactivex/disposables/SerialDisposable.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -19,11 +19,11 @@ public final class SerialDisposable implements Disposable { final SerialResource resource; public SerialDisposable() { - this.resource = new SerialResource<>(Disposable::dispose); + this.resource = new SerialResource(Disposables.consumeAndDispose()); } public SerialDisposable(Disposable initialDisposable) { - this.resource = new SerialResource<>(Disposable::dispose, initialDisposable); + this.resource = new SerialResource(Disposables.consumeAndDispose(), initialDisposable); } diff --git a/src/main/java/io/reactivex/exceptions/CompositeException.java b/src/main/java/io/reactivex/exceptions/CompositeException.java index aa1e020a16..d689797ae7 100644 --- a/src/main/java/io/reactivex/exceptions/CompositeException.java +++ b/src/main/java/io/reactivex/exceptions/CompositeException.java @@ -1,44 +1,308 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 + * 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. + * 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.exceptions; -import java.util.*; +import java.io.PrintStream; +import java.io.PrintWriter; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; +/** + * Represents an exception that is a composite of one or more other exceptions. A {@code CompositeException} + * does not modify the structure of any exception it wraps, but at print-time it iterates through the list of + * Throwables contained in the composite in order to print them all. + * + * Its invariant is to contain an immutable, ordered (by insertion order), unique list of non-composite + * exceptions. You can retrieve individual exceptions in this list with {@link #getExceptions()}. + * + * The {@link #printStackTrace()} implementation handles the StackTrace in a customized way instead of using + * {@code getCause()} so that it can avoid circular references. + * + * If you invoke {@link #getCause()}, it will lazily create the causal chain but will stop if it finds any + * Throwable in the chain that it has already seen. + */ public final class CompositeException extends RuntimeException { - /** */ - private static final long serialVersionUID = 2004635183691362481L; + + private static final long serialVersionUID = 3026362227162912146L; + + private final List exceptions; + private final String message; public CompositeException() { - super(); + this.exceptions = new ArrayList(); + this.message = null; } - public CompositeException(String message) { - super(message); + public CompositeException(Throwable... exceptions) { + this.exceptions = new ArrayList(); + this.message = null; + if (exceptions == null) { + this.exceptions.add(new NullPointerException("exceptions is null")); + } else { + for (Throwable t : exceptions) { + this.exceptions.add(t != null ? t : new NullPointerException("One of the exceptions is null")); + } + } } + + public CompositeException(String messagePrefix, Collection errors) { + Set deDupedExceptions = new LinkedHashSet(); + List _exceptions = new ArrayList(); + if (errors != null) { + for (Throwable ex : errors) { + if (ex instanceof CompositeException) { + deDupedExceptions.addAll(((CompositeException) ex).getExceptions()); + } else + if (ex != null) { + deDupedExceptions.add(ex); + } else { + deDupedExceptions.add(new NullPointerException()); + } + } + } else { + deDupedExceptions.add(new NullPointerException()); + } + + _exceptions.addAll(deDupedExceptions); + this.exceptions = Collections.unmodifiableList(_exceptions); + this.message = exceptions.size() + " exceptions occurred. "; + } + + public CompositeException(Collection errors) { + this(null, errors); + } + + /** + * Retrieves the list of exceptions that make up the {@code CompositeException} + * + * @return the exceptions that make up the {@code CompositeException}, as a {@link List} of {@link Throwable}s + */ public List getExceptions() { - Throwable cause = getCause(); - Throwable[] suppressed = getSuppressed(); - List list = new ArrayList<>(cause != null - ? 1 + suppressed.length : suppressed.length); - if (cause != null) { - list.add(cause); + return exceptions; + } + + @Override + public String getMessage() { + return message; + } + + /** + * Adds a suppressed exception to this composite. + *

The method is named this way to avoid conflicts with Java 7 environments + * and its addSuppressed() method. + * @param e the exception to suppress, nulls are converted to NullPointerExceptions + */ + public void suppress(Throwable e) { + exceptions.add(e != null ? e : new NullPointerException("null exception")); + } + + + private Throwable cause = null; + + @Override + public synchronized Throwable getCause() { + if (cause == null) { + // we lazily generate this causal chain if this is called + CompositeExceptionCausalChain _cause = new CompositeExceptionCausalChain(); + Set seenCauses = new HashSet(); + + Throwable chain = _cause; + for (Throwable e : exceptions) { + if (seenCauses.contains(e)) { + // already seen this outer Throwable so skip + continue; + } + seenCauses.add(e); + + List listOfCauses = getListOfCauses(e); + // check if any of them have been seen before + for(Throwable child : listOfCauses) { + if (seenCauses.contains(child)) { + // already seen this outer Throwable so skip + e = new RuntimeException("Duplicate found in causal chain so cropping to prevent loop ..."); + continue; + } + seenCauses.add(child); + } + + // we now have 'e' as the last in the chain + try { + chain.initCause(e); + } catch (Throwable t) { + // ignore + // the javadocs say that some Throwables (depending on how they're made) will never + // let me call initCause without blowing up even if it returns null + } + chain = chain.getCause(); + } + cause = _cause; + } + return cause; + } + + /** + * All of the following {@code printStackTrace} functionality is derived from JDK {@link Throwable} + * {@code printStackTrace}. In particular, the {@code PrintStreamOrWriter} abstraction is copied wholesale. + * + * Changes from the official JDK implementation:

    + *
  • no infinite loop detection
  • + *
  • smaller critical section holding {@link PrintStream} lock
  • + *
  • explicit knowledge about the exceptions {@link List} that this loops through
  • + *
+ */ + @Override + public void printStackTrace() { + printStackTrace(System.err); + } + + @Override + public void printStackTrace(PrintStream s) { + printStackTrace(new WrappedPrintStream(s)); + } + + @Override + public void printStackTrace(PrintWriter s) { + printStackTrace(new WrappedPrintWriter(s)); + } + + /** + * Special handling for printing out a {@code CompositeException}. + * Loops through all inner exceptions and prints them out. + * + * @param s + * stream to print to + */ + private void printStackTrace(PrintStreamOrWriter s) { + StringBuilder bldr = new StringBuilder(); + bldr.append(this).append("\n"); + for (StackTraceElement myStackElement : getStackTrace()) { + bldr.append("\tat ").append(myStackElement).append("\n"); + } + int i = 1; + for (Throwable ex : exceptions) { + bldr.append(" ComposedException ").append(i).append(" :").append("\n"); + appendStackTrace(bldr, ex, "\t"); + i++; } - for (Throwable t : suppressed) { - list.add(t); + synchronized (s.lock()) { + s.println(bldr.toString()); } - - return list; } -} + + private void appendStackTrace(StringBuilder bldr, Throwable ex, String prefix) { + bldr.append(prefix).append(ex).append("\n"); + for (StackTraceElement stackElement : ex.getStackTrace()) { + bldr.append("\t\tat ").append(stackElement).append("\n"); + } + if (ex.getCause() != null) { + bldr.append("\tCaused by: "); + appendStackTrace(bldr, ex.getCause(), ""); + } + } + + private abstract static class PrintStreamOrWriter { + /** Returns the object to be locked when using this StreamOrWriter */ + abstract Object lock(); + + /** Prints the specified string as a line on this StreamOrWriter */ + abstract void println(Object o); + } + + /** + * Same abstraction and implementation as in JDK to allow PrintStream and PrintWriter to share implementation + */ + private static class WrappedPrintStream extends PrintStreamOrWriter { + private final PrintStream printStream; + + WrappedPrintStream(PrintStream printStream) { + this.printStream = printStream; + } + + @Override + Object lock() { + return printStream; + } + + @Override + void println(Object o) { + printStream.println(o); + } + } + + private static class WrappedPrintWriter extends PrintStreamOrWriter { + private final PrintWriter printWriter; + + WrappedPrintWriter(PrintWriter printWriter) { + this.printWriter = printWriter; + } + + @Override + Object lock() { + return printWriter; + } + + @Override + void println(Object o) { + printWriter.println(o); + } + } + + /* package-private */final static class CompositeExceptionCausalChain extends RuntimeException { + private static final long serialVersionUID = 3875212506787802066L; + /* package-private */static String MESSAGE = "Chain of Causes for CompositeException In Order Received =>"; + + @Override + public String getMessage() { + return MESSAGE; + } + } + + private List getListOfCauses(Throwable ex) { + List list = new ArrayList(); + Throwable root = ex.getCause(); + if (root == null) { + return list; + } else { + while(true) { + list.add(root); + if (root.getCause() == null) { + return list; + } else { + root = root.getCause(); + } + } + } + } + public int size() { + return exceptions.size(); + } + + /** + * Returns true if this CompositeException doesn't have a cause or + * any suppressed exceptions. + * @return true if this CompositeException doesn't have a cause or + * any suppressed exceptions. + */ + public boolean isEmpty() { + return exceptions.isEmpty() && getCause() == null; + } +} \ No newline at end of file diff --git a/src/main/java/io/reactivex/exceptions/MissingBackpressureException.java b/src/main/java/io/reactivex/exceptions/MissingBackpressureException.java index 2251df0551..6f063a876b 100644 --- a/src/main/java/io/reactivex/exceptions/MissingBackpressureException.java +++ b/src/main/java/io/reactivex/exceptions/MissingBackpressureException.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 diff --git a/src/main/java/io/reactivex/exceptions/OnCompleteFailedException.java b/src/main/java/io/reactivex/exceptions/OnCompleteFailedException.java index 09131ea881..b3ae57a9dd 100644 --- a/src/main/java/io/reactivex/exceptions/OnCompleteFailedException.java +++ b/src/main/java/io/reactivex/exceptions/OnCompleteFailedException.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 diff --git a/src/main/java/io/reactivex/exceptions/OnErrorFailedException.java b/src/main/java/io/reactivex/exceptions/OnErrorFailedException.java index 1de2092889..c40e69257e 100644 --- a/src/main/java/io/reactivex/exceptions/OnErrorFailedException.java +++ b/src/main/java/io/reactivex/exceptions/OnErrorFailedException.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 diff --git a/src/main/java/io/reactivex/exceptions/OnErrorNotImplementedException.java b/src/main/java/io/reactivex/exceptions/OnErrorNotImplementedException.java index 0e0040560c..a221354766 100644 --- a/src/main/java/io/reactivex/exceptions/OnErrorNotImplementedException.java +++ b/src/main/java/io/reactivex/exceptions/OnErrorNotImplementedException.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 diff --git a/src/main/java/io/reactivex/exceptions/UnsubscribeFailedException.java b/src/main/java/io/reactivex/exceptions/UnsubscribeFailedException.java index 10549d5db5..bccd01350e 100644 --- a/src/main/java/io/reactivex/exceptions/UnsubscribeFailedException.java +++ b/src/main/java/io/reactivex/exceptions/UnsubscribeFailedException.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 diff --git a/src/main/java/io/reactivex/functions/BiConsumer.java b/src/main/java/io/reactivex/functions/BiConsumer.java new file mode 100644 index 0000000000..90738d4fc5 --- /dev/null +++ b/src/main/java/io/reactivex/functions/BiConsumer.java @@ -0,0 +1,19 @@ +/** + * 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.functions; + +public interface BiConsumer { + + void accept(T1 t1, T2 t2); +} diff --git a/src/main/java/io/reactivex/functions/BiFunction.java b/src/main/java/io/reactivex/functions/BiFunction.java new file mode 100644 index 0000000000..f6e1ec0f1d --- /dev/null +++ b/src/main/java/io/reactivex/functions/BiFunction.java @@ -0,0 +1,19 @@ +/** + * 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.functions; + +public interface BiFunction { + + R apply(T1 t1, T2 t2); +} diff --git a/src/main/java/io/reactivex/functions/BiPredicate.java b/src/main/java/io/reactivex/functions/BiPredicate.java new file mode 100644 index 0000000000..fb48e60db8 --- /dev/null +++ b/src/main/java/io/reactivex/functions/BiPredicate.java @@ -0,0 +1,19 @@ +/** + * 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.functions; + +public interface BiPredicate { + + boolean test(T1 t1, T2 t2); +} diff --git a/src/main/java/io/reactivex/functions/BooleanSupplier.java b/src/main/java/io/reactivex/functions/BooleanSupplier.java new file mode 100644 index 0000000000..dfad42f3bb --- /dev/null +++ b/src/main/java/io/reactivex/functions/BooleanSupplier.java @@ -0,0 +1,18 @@ +/** + * 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.functions; + +public interface BooleanSupplier { + boolean getAsBoolean(); +} diff --git a/src/main/java/io/reactivex/functions/Consumer.java b/src/main/java/io/reactivex/functions/Consumer.java new file mode 100644 index 0000000000..0b072f5580 --- /dev/null +++ b/src/main/java/io/reactivex/functions/Consumer.java @@ -0,0 +1,18 @@ +/** + * 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.functions; + +public interface Consumer { + void accept(T t); +} diff --git a/src/main/java/io/reactivex/functions/Function.java b/src/main/java/io/reactivex/functions/Function.java new file mode 100644 index 0000000000..8ebd5b654b --- /dev/null +++ b/src/main/java/io/reactivex/functions/Function.java @@ -0,0 +1,18 @@ +/** + * 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.functions; + +public interface Function { + R apply(T t); +} diff --git a/src/main/java/io/reactivex/functions/Function3.java b/src/main/java/io/reactivex/functions/Function3.java index 3145d0471a..33df46eff7 100644 --- a/src/main/java/io/reactivex/functions/Function3.java +++ b/src/main/java/io/reactivex/functions/Function3.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,18 +13,6 @@ package io.reactivex.functions; -import java.util.function.Function; - -@FunctionalInterface -public interface Function3 extends Function{ +public interface Function3 { R apply(T1 t1, T2 t2, T3 t3); - - @Override - @SuppressWarnings("unchecked") - default R apply(Object[] a) { - if (a.length != 3) { - throw new IllegalArgumentException("Array of size 3 expected but got " + a.length); - } - return apply((T1)a[0], (T2)a[1], (T3)a[2]); - } } diff --git a/src/main/java/io/reactivex/functions/Function4.java b/src/main/java/io/reactivex/functions/Function4.java index f6dca87c2f..721f121379 100644 --- a/src/main/java/io/reactivex/functions/Function4.java +++ b/src/main/java/io/reactivex/functions/Function4.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,18 +13,6 @@ package io.reactivex.functions; -import java.util.function.Function; - -@FunctionalInterface -public interface Function4 extends Function { +public interface Function4 { R apply(T1 t1, T2 t2, T3 t3, T4 t4); - - @Override - @SuppressWarnings("unchecked") - default R apply(Object[] a) { - if (a.length != 4) { - throw new IllegalArgumentException("Array of size 4 expected but got " + a.length); - } - return apply((T1)a[0], (T2)a[1], (T3)a[2], (T4)a[3]); - } } diff --git a/src/main/java/io/reactivex/functions/Function5.java b/src/main/java/io/reactivex/functions/Function5.java index 72fc9c9ab3..596999b99c 100644 --- a/src/main/java/io/reactivex/functions/Function5.java +++ b/src/main/java/io/reactivex/functions/Function5.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,18 +13,6 @@ package io.reactivex.functions; -import java.util.function.Function; - -@FunctionalInterface -public interface Function5 extends Function { +public interface Function5 { R apply(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5); - - @Override - @SuppressWarnings("unchecked") - default R apply(Object[] a) { - if (a.length != 5) { - throw new IllegalArgumentException("Array of size 5 expected but got " + a.length); - } - return apply((T1)a[0], (T2)a[1], (T3)a[2], (T4)a[3], (T5)a[4]); - } } diff --git a/src/main/java/io/reactivex/functions/Function6.java b/src/main/java/io/reactivex/functions/Function6.java index 12a7877de2..6e97c883f8 100644 --- a/src/main/java/io/reactivex/functions/Function6.java +++ b/src/main/java/io/reactivex/functions/Function6.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,18 +13,6 @@ package io.reactivex.functions; -import java.util.function.Function; - -@FunctionalInterface -public interface Function6 extends Function { +public interface Function6 { R apply(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6); - - @Override - @SuppressWarnings("unchecked") - default R apply(Object[] a) { - if (a.length != 6) { - throw new IllegalArgumentException("Array of size 6 expected but got " + a.length); - } - return apply((T1)a[0], (T2)a[1], (T3)a[2], (T4)a[3], (T5)a[4], (T6)a[5]); - } } diff --git a/src/main/java/io/reactivex/functions/Function7.java b/src/main/java/io/reactivex/functions/Function7.java index 78964c4ae7..d617712323 100644 --- a/src/main/java/io/reactivex/functions/Function7.java +++ b/src/main/java/io/reactivex/functions/Function7.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,18 +13,6 @@ package io.reactivex.functions; -import java.util.function.Function; - -@FunctionalInterface -public interface Function7 extends Function { +public interface Function7 { R apply(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7); - - @Override - @SuppressWarnings("unchecked") - default R apply(Object[] a) { - if (a.length != 7) { - throw new IllegalArgumentException("Array of size 7 expected but got " + a.length); - } - return apply((T1)a[0], (T2)a[1], (T3)a[2], (T4)a[3], (T5)a[4], (T6)a[5], (T7)a[6]); - } } diff --git a/src/main/java/io/reactivex/functions/Function8.java b/src/main/java/io/reactivex/functions/Function8.java index dcdb67590d..8cae766078 100644 --- a/src/main/java/io/reactivex/functions/Function8.java +++ b/src/main/java/io/reactivex/functions/Function8.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,18 +13,6 @@ package io.reactivex.functions; -import java.util.function.Function; - -@FunctionalInterface -public interface Function8 extends Function { +public interface Function8 { R apply(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8); - - @Override - @SuppressWarnings("unchecked") - default R apply(Object[] a) { - if (a.length != 8) { - throw new IllegalArgumentException("Array of size 8 expected but got " + a.length); - } - return apply((T1)a[0], (T2)a[1], (T3)a[2], (T4)a[3], (T5)a[4], (T6)a[5], (T7)a[6], (T8)a[7]); - } } diff --git a/src/main/java/io/reactivex/functions/Function9.java b/src/main/java/io/reactivex/functions/Function9.java index f10c6bfa7c..2c90418f2a 100644 --- a/src/main/java/io/reactivex/functions/Function9.java +++ b/src/main/java/io/reactivex/functions/Function9.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,17 +13,6 @@ package io.reactivex.functions; -import java.util.function.Function; - -@FunctionalInterface -public interface Function9 extends Function{ +public interface Function9 { R apply(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9); - @Override - @SuppressWarnings("unchecked") - default R apply(Object[] a) { - if (a.length != 9) { - throw new IllegalArgumentException("Array of size 9 expected but got " + a.length); - } - return apply((T1)a[0], (T2)a[1], (T3)a[2], (T4)a[3], (T5)a[4], (T6)a[5], (T7)a[6], (T8)a[7], (T9)a[8]); - } } diff --git a/src/main/java/io/reactivex/functions/IntFunction.java b/src/main/java/io/reactivex/functions/IntFunction.java new file mode 100644 index 0000000000..b0b7b03cdc --- /dev/null +++ b/src/main/java/io/reactivex/functions/IntFunction.java @@ -0,0 +1,17 @@ +/** + * 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.functions; + +public interface IntFunction { + T apply(int i); +} diff --git a/src/main/java/io/reactivex/functions/LongConsumer.java b/src/main/java/io/reactivex/functions/LongConsumer.java new file mode 100644 index 0000000000..0eb20f7201 --- /dev/null +++ b/src/main/java/io/reactivex/functions/LongConsumer.java @@ -0,0 +1,17 @@ +/** + * 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.functions; + +public interface LongConsumer { + void accept(long t); +} diff --git a/src/main/java/io/reactivex/functions/Predicate.java b/src/main/java/io/reactivex/functions/Predicate.java new file mode 100644 index 0000000000..c6b464d2db --- /dev/null +++ b/src/main/java/io/reactivex/functions/Predicate.java @@ -0,0 +1,18 @@ +/** + * 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.functions; + +public interface Predicate { + boolean test(T t); +} diff --git a/src/main/java/io/reactivex/functions/Supplier.java b/src/main/java/io/reactivex/functions/Supplier.java new file mode 100644 index 0000000000..46cd78fec4 --- /dev/null +++ b/src/main/java/io/reactivex/functions/Supplier.java @@ -0,0 +1,19 @@ +/** + * 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.functions; + +public interface Supplier { + + T get(); +} diff --git a/src/main/java/io/reactivex/internal/disposables/ArrayCompositeResource.java b/src/main/java/io/reactivex/internal/disposables/ArrayCompositeResource.java index cf4d9e8384..0d963d9fe1 100644 --- a/src/main/java/io/reactivex/internal/disposables/ArrayCompositeResource.java +++ b/src/main/java/io/reactivex/internal/disposables/ArrayCompositeResource.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -14,9 +14,9 @@ package io.reactivex.internal.disposables; import java.util.concurrent.atomic.AtomicReferenceArray; -import java.util.function.Consumer; import io.reactivex.disposables.Disposable; +import io.reactivex.functions.Consumer; /** * A composite resource with a fixed number of slots. diff --git a/src/main/java/io/reactivex/internal/disposables/CompositeResource.java b/src/main/java/io/reactivex/internal/disposables/CompositeResource.java index 0db1fd5ce2..e12d337d10 100644 --- a/src/main/java/io/reactivex/internal/disposables/CompositeResource.java +++ b/src/main/java/io/reactivex/internal/disposables/CompositeResource.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 diff --git a/src/main/java/io/reactivex/internal/disposables/EmptyDisposable.java b/src/main/java/io/reactivex/internal/disposables/EmptyDisposable.java index e6e0202ec8..a9dfd8d4c7 100644 --- a/src/main/java/io/reactivex/internal/disposables/EmptyDisposable.java +++ b/src/main/java/io/reactivex/internal/disposables/EmptyDisposable.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 diff --git a/src/main/java/io/reactivex/internal/disposables/ListCompositeResource.java b/src/main/java/io/reactivex/internal/disposables/ListCompositeResource.java index d1dc1ea591..1b1a28042a 100644 --- a/src/main/java/io/reactivex/internal/disposables/ListCompositeResource.java +++ b/src/main/java/io/reactivex/internal/disposables/ListCompositeResource.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -14,9 +14,9 @@ package io.reactivex.internal.disposables; import java.util.LinkedList; -import java.util.function.Consumer; import io.reactivex.disposables.Disposable; +import io.reactivex.functions.Consumer; /** * A linked-list-based composite resource with custom disposer callback. @@ -36,12 +36,11 @@ public ListCompositeResource(Consumer disposer) { this.disposer = disposer; } - @SafeVarargs public ListCompositeResource(Consumer disposer, T... initialResources) { this(disposer); int n = initialResources.length; if (n != 0) { - list = new LinkedList<>(); + list = new LinkedList(); for (T r : initialResources) { list.add(r); } @@ -50,7 +49,7 @@ public ListCompositeResource(Consumer disposer, T... initialResources public ListCompositeResource(Consumer disposer, Iterable initialResources) { this(disposer); - list = new LinkedList<>(); + list = new LinkedList(); for (T r : initialResources) { list.add(r); } @@ -59,7 +58,7 @@ public ListCompositeResource(Consumer disposer, Iterable /** * Adds a new resource to this composite or disposes it if the composite has been disposed. * @param newResource the new resource to add, not-null (not checked) - * @return + * @return false if the container is disposed */ @Override public boolean add(T newResource) { @@ -68,7 +67,7 @@ public boolean add(T newResource) { if (!disposed) { LinkedList a = list; if (a == null) { - a = new LinkedList<>(); + a = new LinkedList(); list = a; } a.add(newResource); @@ -84,7 +83,7 @@ public boolean add(T newResource) { * Removes the given resource from this composite and calls the disposer if the resource * was indeed in the composite. * @param resource the resource to remove, not-null (not verified) - * @return + * @return false if the resource was not in this container */ @Override public boolean remove(T resource) { @@ -98,7 +97,7 @@ public boolean remove(T resource) { /** * Removes the given resource if contained within this composite but doesn't call the disposer for it. * @param resource the resource to delete, not-null (not verified) - * @return + * @return false if the resource was not in this container */ @Override public boolean delete(T resource) { @@ -131,7 +130,9 @@ public void dispose() { list = null; } if (s != null) { - s.forEach(disposer); + for (T t : s) { + disposer.accept(t); + } } } } diff --git a/src/main/java/io/reactivex/internal/disposables/MultipleAssignmentResource.java b/src/main/java/io/reactivex/internal/disposables/MultipleAssignmentResource.java index 0616860dbb..ff6e567575 100644 --- a/src/main/java/io/reactivex/internal/disposables/MultipleAssignmentResource.java +++ b/src/main/java/io/reactivex/internal/disposables/MultipleAssignmentResource.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -14,9 +14,9 @@ package io.reactivex.internal.disposables; import java.util.concurrent.atomic.AtomicReference; -import java.util.function.Consumer; import io.reactivex.disposables.Disposable; +import io.reactivex.functions.Consumer; import io.reactivex.internal.util.TerminalAtomicsHelper; /** diff --git a/src/main/java/io/reactivex/internal/disposables/NbpFullArbiter.java b/src/main/java/io/reactivex/internal/disposables/NbpFullArbiter.java index 099576780e..f33eb5a59b 100644 --- a/src/main/java/io/reactivex/internal/disposables/NbpFullArbiter.java +++ b/src/main/java/io/reactivex/internal/disposables/NbpFullArbiter.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,7 +13,7 @@ package io.reactivex.internal.disposables; -import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; +import java.util.concurrent.atomic.AtomicInteger; import io.reactivex.NbpObservable.NbpSubscriber; import io.reactivex.disposables.Disposable; @@ -32,7 +32,10 @@ public final class NbpFullArbiter extends FullArbiterPad1 implements Disposab final SpscLinkedArrayQueue queue; volatile Disposable s; - static final Disposable INITIAL = () -> { }; + static final Disposable INITIAL = new Disposable() { + @Override + public void dispose() { } + }; Disposable resource; @@ -42,7 +45,7 @@ public final class NbpFullArbiter extends FullArbiterPad1 implements Disposab public NbpFullArbiter(NbpSubscriber actual, Disposable resource, int capacity) { this.actual = actual; this.resource = resource; - this.queue = new SpscLinkedArrayQueue<>(capacity); + this.queue = new SpscLinkedArrayQueue(capacity); this.s = INITIAL; } @@ -97,7 +100,7 @@ public void onComplete(Disposable s) { } void drain() { - if (WIP.getAndIncrement(this) != 0) { + if (wip.getAndIncrement() != 0) { return; } @@ -149,11 +152,11 @@ void drain() { a.onComplete(); } } else { - a.onNext(NotificationLite.getValue(v)); + a.onNext(NotificationLite.getValue(v)); } } - missed = WIP.addAndGet(this, -missed); + missed = wip.addAndGet(-missed); if (missed == 0) { break; } @@ -169,9 +172,7 @@ class FullArbiterPad0 { /** The work-in-progress counter. */ class FullArbiterWip extends FullArbiterPad0 { - volatile int wip; - static final AtomicIntegerFieldUpdater WIP = - AtomicIntegerFieldUpdater.newUpdater(FullArbiterWip.class, "wip"); + final AtomicInteger wip = new AtomicInteger(); } /** Pads the wip counter away. */ diff --git a/src/main/java/io/reactivex/internal/disposables/SerialResource.java b/src/main/java/io/reactivex/internal/disposables/SerialResource.java index e8d04ced71..c5091870d6 100644 --- a/src/main/java/io/reactivex/internal/disposables/SerialResource.java +++ b/src/main/java/io/reactivex/internal/disposables/SerialResource.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -14,9 +14,9 @@ package io.reactivex.internal.disposables; import java.util.concurrent.atomic.AtomicReference; -import java.util.function.Consumer; import io.reactivex.disposables.Disposable; +import io.reactivex.functions.Consumer; import io.reactivex.internal.util.TerminalAtomicsHelper; /** @@ -62,6 +62,7 @@ public SerialResource(Consumer disposer, T initialResource) { * Atomically replaces the current resource with the new resource but doesn't call the disposer * for it. * @param newResource the new resource to replace the old one + * @return true if the set succeeded, false if the container is disposed */ @SuppressWarnings("unchecked") public boolean setResource(T newResource) { diff --git a/src/main/java/io/reactivex/internal/disposables/SetCompositeResource.java b/src/main/java/io/reactivex/internal/disposables/SetCompositeResource.java index fa190a5bb5..35e07d57ec 100644 --- a/src/main/java/io/reactivex/internal/disposables/SetCompositeResource.java +++ b/src/main/java/io/reactivex/internal/disposables/SetCompositeResource.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,9 +13,8 @@ package io.reactivex.internal.disposables; -import java.util.function.Consumer; - import io.reactivex.disposables.Disposable; +import io.reactivex.functions.Consumer; import io.reactivex.internal.util.*; /** @@ -36,12 +35,11 @@ public SetCompositeResource(Consumer disposer) { this.disposer = disposer; } - @SafeVarargs public SetCompositeResource(Consumer disposer, T... initialResources) { this(disposer); int n = initialResources.length; if (n != 0) { - set = new OpenHashSet<>(n); + set = new OpenHashSet(n); for (T r : initialResources) { set.add(r); } @@ -50,7 +48,7 @@ public SetCompositeResource(Consumer disposer, T... initialResources) public SetCompositeResource(Consumer disposer, Iterable initialResources) { this(disposer); - set = new OpenHashSet<>(); + set = new OpenHashSet(); for (T r : initialResources) { set.add(r); } @@ -59,7 +57,7 @@ public SetCompositeResource(Consumer disposer, Iterable /** * Adds a new resource to this composite or disposes it if the composite has been disposed. * @param newResource the new resource to add, not-null (not checked) - * @return + * @return true if the add succeeded, false if this container was disposed */ @Override public boolean add(T newResource) { @@ -68,7 +66,7 @@ public boolean add(T newResource) { if (!disposed) { OpenHashSet a = set; if (a == null) { - a = new OpenHashSet<>(4); + a = new OpenHashSet(4); set = a; } a.add(newResource); @@ -98,7 +96,7 @@ public boolean remove(T resource) { /** * Removes the given resource if contained within this composite but doesn't call the disposer for it. * @param resource the resource to delete, not-null (not verified) - * @return + * @return true if the delete succeeded, false if this container was disposed */ @Override public boolean delete(T resource) { @@ -124,8 +122,13 @@ public int size() { if (a == null) { return 0; } - int[] c = new int[1]; - a.forEach(v -> c[0]++); + final int[] c = new int[1]; + a.forEach(new Consumer() { + @Override + public void accept(T v) { + c[0]++; + } + }); return c[0]; } } diff --git a/src/main/java/io/reactivex/internal/functions/Functions.java b/src/main/java/io/reactivex/internal/functions/Functions.java new file mode 100644 index 0000000000..2f67b26d74 --- /dev/null +++ b/src/main/java/io/reactivex/internal/functions/Functions.java @@ -0,0 +1,253 @@ +/** + * 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.internal.functions; + +import java.util.Comparator; + +import io.reactivex.functions.*; + +/** + * Utility methods to convert the Function3..Function9 instances to Function of Object array. + */ +public enum Functions { + ; + + @SuppressWarnings("unchecked") + public static Function toFunction(final BiFunction biFunction) { + Objects.requireNonNull(biFunction, "biFunction is null"); + return new Function() { + @Override + public R apply(Object[] a) { + if (a.length != 2) { + throw new IllegalArgumentException("Array of size 2 expected but got " + a.length); + } + return ((BiFunction)biFunction).apply(a[0], a[1]); + } + }; + } + + public static Function toFunction(final Function3 f) { + Objects.requireNonNull(f, "f is null"); + return new Function() { + @SuppressWarnings("unchecked") + @Override + public R apply(Object[] a) { + if (a.length != 3) { + throw new IllegalArgumentException("Array of size 3 expected but got " + a.length); + } + return f.apply((T1)a[0], (T2)a[1], (T3)a[2]); + } + }; + } + + public static Function toFunction(final Function4 f) { + Objects.requireNonNull(f, "f is null"); + return new Function() { + @SuppressWarnings("unchecked") + @Override + public R apply(Object[] a) { + if (a.length != 4) { + throw new IllegalArgumentException("Array of size 4 expected but got " + a.length); + } + return f.apply((T1)a[0], (T2)a[1], (T3)a[2], (T4)a[3]); + } + }; + } + + public static Function toFunction(final Function5 f) { + Objects.requireNonNull(f, "f is null"); + return new Function() { + @SuppressWarnings("unchecked") + @Override + public R apply(Object[] a) { + if (a.length != 5) { + throw new IllegalArgumentException("Array of size 5 expected but got " + a.length); + } + return f.apply((T1)a[0], (T2)a[1], (T3)a[2], (T4)a[3], (T5)a[4]); + } + }; + } + + public static Function toFunction( + final Function6 f) { + Objects.requireNonNull(f, "f is null"); + return new Function() { + @SuppressWarnings("unchecked") + @Override + public R apply(Object[] a) { + if (a.length != 6) { + throw new IllegalArgumentException("Array of size 6 expected but got " + a.length); + } + return f.apply((T1)a[0], (T2)a[1], (T3)a[2], (T4)a[3], (T5)a[4], (T6)a[5]); + } + }; + } + + public static Function toFunction( + final Function7 f) { + Objects.requireNonNull(f, "f is null"); + return new Function() { + @SuppressWarnings("unchecked") + @Override + public R apply(Object[] a) { + if (a.length != 7) { + throw new IllegalArgumentException("Array of size 7 expected but got " + a.length); + } + return f.apply((T1)a[0], (T2)a[1], (T3)a[2], (T4)a[3], (T5)a[4], (T6)a[5], (T7)a[6]); + } + }; + } + + public static Function toFunction( + final Function8 f) { + Objects.requireNonNull(f, "f is null"); + return new Function() { + @SuppressWarnings("unchecked") + @Override + public R apply(Object[] a) { + if (a.length != 8) { + throw new IllegalArgumentException("Array of size 8 expected but got " + a.length); + } + return f.apply((T1)a[0], (T2)a[1], (T3)a[2], (T4)a[3], (T5)a[4], (T6)a[5], (T7)a[6], (T8)a[7]); + } + }; + } + + public static Function toFunction( + final Function9 f) { + Objects.requireNonNull(f, "f is null"); + return new Function() { + @SuppressWarnings("unchecked") + @Override + public R apply(Object[] a) { + if (a.length != 9) { + throw new IllegalArgumentException("Array of size 9 expected but got " + a.length); + } + return f.apply((T1)a[0], (T2)a[1], (T3)a[2], (T4)a[3], (T5)a[4], (T6)a[5], (T7)a[6], (T8)a[7], (T9)a[8]); + } + }; + } + + /** A singleton identity function. */ + static final Function IDENTITY = new Function() { + @Override + public Object apply(Object v) { + return v; + } + }; + + /** + * Returns an identity function that simply returns its argument. + * @param the input and output value type + * @return the identity function + */ + @SuppressWarnings("unchecked") + public static Function identity() { + return (Function)IDENTITY; + } + + static final Runnable EMPTY = new Runnable() { + @Override + public void run() { } + }; + + /** + * Returns an empty runnable that does nothing. + * @return an empty runnable that does nothing + */ + public static Runnable emptyRunnable() { + return EMPTY; + } + + static final Consumer EMPTY_CONSUMER = new Consumer() { + @Override + public void accept(Object v) { } + }; + + /** + * Returns an empty consumer that does nothing. + * @param the consumed value type, the value is ignored + * @return an empty consumer that does nothing. + */ + @SuppressWarnings("unchecked") + public static Consumer emptyConsumer() { + return (Consumer)EMPTY_CONSUMER; + } + + static final LongConsumer EMPTY_LONGCONSUMER = new LongConsumer() { + @Override + public void accept(long v) { } + }; + + /** + * Returns an empty long consumer that does nothing. + * @return an empty long consumer that does nothing. + */ + public static LongConsumer emptyLongConsumer() { + return EMPTY_LONGCONSUMER; + } + + static final Predicate ALWAYS_TRUE = new Predicate() { + @Override + public boolean test(Object o) { + return true; + } + }; + + static final Predicate ALWAYS_FALSE = new Predicate() { + @Override + public boolean test(Object o) { + return true; + } + }; + + static final Supplier NULL_SUPPLIER = new Supplier() { + @Override + public Object get() { + return null; + } + }; + + static final Comparator NATURAL_COMPARATOR = new Comparator() { + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Override + public int compare(Object a, Object b) { + return ((Comparable)a).compareTo(b); + } + }; + + @SuppressWarnings("unchecked") + public static Predicate alwaysTrue() { + return (Predicate)ALWAYS_TRUE; + } + + @SuppressWarnings("unchecked") + public static Predicate alwaysFalse() { + return (Predicate)ALWAYS_FALSE; + } + + @SuppressWarnings("unchecked") + public static Supplier nullSupplier() { + return (Supplier)NULL_SUPPLIER; + } + + /** + * Returns a natural order comparator which casts the parameters to Comparable. + * @param the value type + * @return a natural order comparator which casts the parameters to Comparable + */ + @SuppressWarnings("unchecked") + public static Comparator naturalOrder() { + return (Comparator)NATURAL_COMPARATOR; + } +} diff --git a/src/main/java/io/reactivex/internal/functions/Objects.java b/src/main/java/io/reactivex/internal/functions/Objects.java new file mode 100644 index 0000000000..5f44695420 --- /dev/null +++ b/src/main/java/io/reactivex/internal/functions/Objects.java @@ -0,0 +1,94 @@ +/** + * 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.internal.functions; + +import io.reactivex.functions.BiPredicate; + +/** + * Utility methods containing the backport of Java 7's Objects utility class. + *

Named as such to avoid clash with java.util.Objects. + */ +public enum Objects { + ; + /** + * Verifies if the object is not null and returns it or throws a NullPointerException + * with the given message. + * @param the value type + * @param object the object to verify + * @param message the message to use with the NullPointerException + * @return the object itself + * @throws NullPointerException if object is null + */ + public static final T requireNonNull(T object, String message) { + if (object == null) { + throw new NullPointerException(message); + } + return object; + } + + /** + * Compares two potentially null objects with each other using Object.equals. + * @param o1 the first object + * @param o2 the second object + * @return the comparison result + */ + public static boolean equals(Object o1, Object o2) { + return o1 == o2 || (o1 != null && o1.equals(o2)); + } + + /** + * Returns the hashCode of a non-null object or zero for a null object. + * @param o the object to get the hashCode for. + * @return the hashCode + */ + public static int hashCode(Object o) { + return o != null ? o.hashCode() : 0; + } + + /** + * Compares two integer values similar to Integer.compare. + * @param v1 the first value + * @param v2 the second value + * @return the comparison result + */ + public static int compare(int v1, int v2) { + return v1 < v2 ? -1 : (v1 > v2 ? 1 : 0); + } + + /** + * Compares two integer values similar to Long.compare. + * @param v1 the first value + * @param v2 the second value + * @return the comparison result + */ + public static int compare(long v1, long v2) { + return v1 < v2 ? -1 : (v1 > v2 ? 1 : 0); + } + + static final BiPredicate EQUALS = new BiPredicate() { + @Override + public boolean test(Object o1, Object o2) { + return Objects.equals(o1, o2); + } + }; + + /** + * Returns a BiPredicate that compares its parameters via Objects.equals(). + * @param the value type + * @return the bipredicate + */ + @SuppressWarnings("unchecked") + public static BiPredicate equalsPredicate() { + return (BiPredicate)EQUALS; + } +} diff --git a/src/main/java/io/reactivex/internal/operators/BlockingOperatorLatest.java b/src/main/java/io/reactivex/internal/operators/BlockingOperatorLatest.java index a46c8432e3..28e4265ee9 100644 --- a/src/main/java/io/reactivex/internal/operators/BlockingOperatorLatest.java +++ b/src/main/java/io/reactivex/internal/operators/BlockingOperatorLatest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -15,12 +15,13 @@ import java.util.*; import java.util.concurrent.Semaphore; -import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; +import java.util.concurrent.atomic.AtomicReference; import org.reactivestreams.Publisher; import io.reactivex.*; import io.reactivex.Observable; +import io.reactivex.Optional; import io.reactivex.internal.subscribers.DisposableSubscriber; import io.reactivex.internal.util.Exceptions; @@ -35,6 +36,7 @@ public enum BlockingOperatorLatest { * Returns an {@code Iterable} that blocks until or unless the {@code Observable} emits an item that has not * been returned by the {@code Iterable}, then returns that item * + * @param the value type * @param source * the source {@code Observable} * @return an {@code Iterable} that blocks until or unless the {@code Observable} emits an item that has not @@ -44,7 +46,7 @@ public static Iterable latest(final Publisher source) { return new Iterable() { @Override public Iterator iterator() { - LatestObserverIterator lio = new LatestObserverIterator<>(); + LatestObserverIterator lio = new LatestObserverIterator(); Observable.fromPublisher(source).materialize().subscribe(lio); return lio; } @@ -55,15 +57,11 @@ public Iterator iterator() { static final class LatestObserverIterator extends DisposableSubscriber>> implements Iterator { final Semaphore notify = new Semaphore(0); // observer's notification - volatile Try> value; - /** Updater for the value field. */ - @SuppressWarnings("rawtypes") - static final AtomicReferenceFieldUpdater REFERENCE_UPDATER - = AtomicReferenceFieldUpdater.newUpdater(LatestObserverIterator.class, Try.class, "value"); + final AtomicReference>> value = new AtomicReference>>(); @Override public void onNext(Try> args) { - boolean wasntAvailable = REFERENCE_UPDATER.getAndSet(this, args) == null; + boolean wasntAvailable = value.getAndSet(args) == null; if (wasntAvailable) { notify.release(); } @@ -98,8 +96,7 @@ public boolean hasNext() { throw Exceptions.propagate(ex); } - @SuppressWarnings("unchecked") - Try> n = REFERENCE_UPDATER.getAndSet(this, null); + Try> n = value.getAndSet(null); iNotif = n; if (iNotif.hasError()) { throw Exceptions.propagate(iNotif.error()); diff --git a/src/main/java/io/reactivex/internal/operators/BlockingOperatorMostRecent.java b/src/main/java/io/reactivex/internal/operators/BlockingOperatorMostRecent.java index a425dbf11e..f2164f80ad 100644 --- a/src/main/java/io/reactivex/internal/operators/BlockingOperatorMostRecent.java +++ b/src/main/java/io/reactivex/internal/operators/BlockingOperatorMostRecent.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -31,6 +31,7 @@ public enum BlockingOperatorMostRecent { /** * Returns an {@code Iterable} that always returns the item most recently emitted by the {@code Observable}. * + * @param the value type * @param source * the source {@code Observable} * @param initialValue @@ -43,7 +44,7 @@ public static Iterable mostRecent(final Publisher source, fi return new Iterable() { @Override public Iterator iterator() { - MostRecentObserver mostRecentObserver = new MostRecentObserver<>(initialValue); + MostRecentObserver mostRecentObserver = new MostRecentObserver(initialValue); /** * Subscribe instead of unsafeSubscribe since this is the final subscribe in the chain @@ -81,7 +82,7 @@ public void onNext(T args) { /** * The {@link Iterator} return is not thread safe. In other words don't call {@link Iterator#hasNext()} in one * thread expect {@link Iterator#next()} called from a different thread to work. - * @return + * @return the Iterator */ public Iterator getIterable() { return new Iterator() { diff --git a/src/main/java/io/reactivex/internal/operators/BlockingOperatorNext.java b/src/main/java/io/reactivex/internal/operators/BlockingOperatorNext.java index d44caf71ca..b3bf45c5af 100644 --- a/src/main/java/io/reactivex/internal/operators/BlockingOperatorNext.java +++ b/src/main/java/io/reactivex/internal/operators/BlockingOperatorNext.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -15,11 +15,12 @@ import java.util.*; import java.util.concurrent.*; -import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; +import java.util.concurrent.atomic.AtomicInteger; import org.reactivestreams.Publisher; import io.reactivex.Observable; +import io.reactivex.Optional; import io.reactivex.Try; import io.reactivex.internal.subscribers.DisposableSubscriber; import io.reactivex.internal.util.Exceptions; @@ -35,6 +36,7 @@ public enum BlockingOperatorNext { * Returns an {@code Iterable} that blocks until the {@code Observable} emits another item, then returns * that item. * + * @param the value type * @param items * the {@code Observable} to observe * @return an {@code Iterable} that behaves like a blocking version of {@code items} @@ -43,8 +45,8 @@ public static Iterable next(final Publisher items) { return new Iterable() { @Override public Iterator iterator() { - NextObserver nextObserver = new NextObserver<>(); - return new NextIterator<>(items, nextObserver); + NextObserver nextObserver = new NextObserver(); + return new NextIterator(items, nextObserver); } }; @@ -142,12 +144,8 @@ public void remove() { } private static class NextObserver extends DisposableSubscriber>> { - private final BlockingQueue>> buf = new ArrayBlockingQueue<>(1); - @SuppressWarnings("unused") - volatile int waiting; - @SuppressWarnings("rawtypes") - static final AtomicIntegerFieldUpdater WAITING_UPDATER - = AtomicIntegerFieldUpdater.newUpdater(NextObserver.class, "waiting"); + private final BlockingQueue>> buf = new ArrayBlockingQueue>>(1); + final AtomicInteger waiting = new AtomicInteger(); @Override public void onComplete() { @@ -162,7 +160,7 @@ public void onError(Throwable e) { @Override public void onNext(Try> args) { - if (WAITING_UPDATER.getAndSet(this, 0) == 1 || !isOnNext(args)) { + if (waiting.getAndSet(0) == 1 || !isOnNext(args)) { Try> toOffer = args; while (!buf.offer(toOffer)) { Try> concurrentItem = buf.poll(); @@ -181,7 +179,7 @@ public Try> takeNext() throws InterruptedException { return buf.take(); } void setWaiting(int value) { - waiting = value; + waiting.set(value); } } diff --git a/src/main/java/io/reactivex/internal/operators/CachedObservable.java b/src/main/java/io/reactivex/internal/operators/CachedObservable.java index 2de5bbe59b..88b3824361 100644 --- a/src/main/java/io/reactivex/internal/operators/CachedObservable.java +++ b/src/main/java/io/reactivex/internal/operators/CachedObservable.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -35,6 +35,7 @@ public final class CachedObservable extends Observable { /** * Creates a cached Observable with a default capacity hint of 16. + * @param the value type * @param source the source Observable to cache * @return the CachedObservable instance */ @@ -44,6 +45,7 @@ public static CachedObservable from(Observable source) { /** * Creates a cached Observable with the given capacity hint. + * @param the value type * @param source the source Observable to cache * @param capacityHint the hint for the internal buffer size * @return the CachedObservable instance @@ -52,9 +54,9 @@ public static CachedObservable from(Observable source, int c if (capacityHint < 1) { throw new IllegalArgumentException("capacityHint > 0 required"); } - CacheState state = new CacheState<>(source, capacityHint); - CachedSubscribe onSubscribe = new CachedSubscribe<>(state); - return new CachedObservable<>(onSubscribe, state); + CacheState state = new CacheState(source, capacityHint); + CachedSubscribe onSubscribe = new CachedSubscribe(state); + return new CachedObservable(onSubscribe, state); } /** @@ -119,7 +121,7 @@ public CacheState(Observable source, int capacityHint) { super(capacityHint); this.source = source; this.producers = EMPTY; - this.connection = new SerialResource<>(Subscription::cancel); + this.connection = new SerialResource(SubscriptionHelper.consumeAndCancel()); } /** * Adds a ReplayProducer to the producers array atomically. @@ -235,7 +237,7 @@ public CachedSubscribe(CacheState state) { @Override public void subscribe(Subscriber t) { // we can connect first because we replay everything anyway - ReplaySubscription rp = new ReplaySubscription<>(t, state); + ReplaySubscription rp = new ReplaySubscription(t, state); state.addProducer(rp); t.onSubscribe(rp); @@ -308,8 +310,8 @@ public void request(long n) { } /** * Updates the request count to reflect values have been produced. - * @param n - * @return + * @param n the produced amount + * @return the current requested amount */ public long produced(long n) { return addAndGet(-n); diff --git a/src/main/java/io/reactivex/internal/operators/ObservableScalarSource.java b/src/main/java/io/reactivex/internal/operators/ObservableScalarSource.java index a9980808c1..fbbefc8383 100644 --- a/src/main/java/io/reactivex/internal/operators/ObservableScalarSource.java +++ b/src/main/java/io/reactivex/internal/operators/ObservableScalarSource.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,23 +13,23 @@ package io.reactivex.internal.operators; -import java.util.function.Function; - import org.reactivestreams.*; import io.reactivex.Observable; +import io.reactivex.functions.Function; import io.reactivex.internal.subscriptions.*; /** * Represents a constant scalar value. + * @param the value type */ public final class ObservableScalarSource extends Observable { private final T value; - public ObservableScalarSource(T value) { + public ObservableScalarSource(final T value) { super(new Publisher() { @Override public void subscribe(Subscriber s) { - s.onSubscribe(new ScalarSubscription<>(s, value)); + s.onSubscribe(new ScalarSubscription(s, value)); } }); this.value = value; @@ -39,20 +39,23 @@ public T value() { return value; } - public Publisher scalarFlatMap(Function> mapper) { - return s -> { - Publisher other; - try { - other = mapper.apply(value); - } catch (Throwable e) { - EmptySubscription.error(e, s); - return; - } - if (other == null) { - EmptySubscription.error(new NullPointerException("The publisher returned by the function is null"), s); - return; + public Publisher scalarFlatMap(final Function> mapper) { + return new Publisher() { + @Override + public void subscribe(Subscriber s) { + Publisher other; + try { + other = mapper.apply(value); + } catch (Throwable e) { + EmptySubscription.error(e, s); + return; + } + if (other == null) { + EmptySubscription.error(new NullPointerException("The publisher returned by the function is null"), s); + return; + } + other.subscribe(s); } - other.subscribe(s); }; } } diff --git a/src/main/java/io/reactivex/internal/operators/OperatorAll.java b/src/main/java/io/reactivex/internal/operators/OperatorAll.java index dde291b928..c2ee4e2246 100644 --- a/src/main/java/io/reactivex/internal/operators/OperatorAll.java +++ b/src/main/java/io/reactivex/internal/operators/OperatorAll.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,11 +13,11 @@ package io.reactivex.internal.operators; import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.Predicate; import org.reactivestreams.*; import io.reactivex.Observable.Operator; +import io.reactivex.functions.Predicate; import io.reactivex.internal.subscriptions.SubscriptionHelper; import io.reactivex.plugins.RxJavaPlugins; @@ -29,7 +29,7 @@ public OperatorAll(Predicate predicate) { @Override public Subscriber apply(Subscriber t) { - return new AllSubscriber<>(t, predicate); + return new AllSubscriber(t, predicate); } static final class AllSubscriber extends AtomicInteger implements Subscriber, Subscription { diff --git a/src/main/java/io/reactivex/internal/operators/OperatorAny.java b/src/main/java/io/reactivex/internal/operators/OperatorAny.java index 71fb6ec55a..6f9e309fa1 100644 --- a/src/main/java/io/reactivex/internal/operators/OperatorAny.java +++ b/src/main/java/io/reactivex/internal/operators/OperatorAny.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,11 +13,11 @@ package io.reactivex.internal.operators; import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.Predicate; import org.reactivestreams.*; import io.reactivex.Observable.Operator; +import io.reactivex.functions.Predicate; import io.reactivex.internal.subscriptions.SubscriptionHelper; public final class OperatorAny implements Operator { @@ -28,7 +28,7 @@ public OperatorAny(Predicate predicate) { @Override public Subscriber apply(Subscriber t) { - return new AnySubscriber<>(t, predicate); + return new AnySubscriber(t, predicate); } static final class AnySubscriber extends AtomicInteger implements Subscriber, Subscription { diff --git a/src/main/java/io/reactivex/internal/operators/OperatorBuffer.java b/src/main/java/io/reactivex/internal/operators/OperatorBuffer.java index e0b836297b..ebc699f2cc 100644 --- a/src/main/java/io/reactivex/internal/operators/OperatorBuffer.java +++ b/src/main/java/io/reactivex/internal/operators/OperatorBuffer.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -15,11 +15,11 @@ import java.util.*; import java.util.concurrent.atomic.AtomicBoolean; -import java.util.function.Supplier; import org.reactivestreams.*; import io.reactivex.Observable.Operator; +import io.reactivex.functions.Supplier; import io.reactivex.internal.subscribers.EmptySubscriber; import io.reactivex.internal.subscriptions.*; import io.reactivex.internal.util.BackpressureHelper; @@ -38,13 +38,13 @@ public OperatorBuffer(int count, int skip, Supplier bufferSupplier) { @Override public Subscriber apply(Subscriber t) { if (skip == count) { - BufferExactSubscriber bes = new BufferExactSubscriber<>(t, count, bufferSupplier); + BufferExactSubscriber bes = new BufferExactSubscriber(t, count, bufferSupplier); if (bes.createBuffer()) { return bes; } return EmptySubscriber.INSTANCE; } - return new BufferSkipSubscriber<>(t, count, skip, bufferSupplier); + return new BufferSkipSubscriber(t, count, skip, bufferSupplier); } static final class BufferExactSubscriber> implements Subscriber, Subscription { @@ -169,7 +169,7 @@ public BufferSkipSubscriber(Subscriber actual, int count, int skip, S this.count = count; this.skip = skip; this.bufferSupplier = bufferSupplier; - this.buffers = new ArrayDeque<>(); + this.buffers = new ArrayDeque(); } @Override diff --git a/src/main/java/io/reactivex/internal/operators/OperatorBufferBoundary.java b/src/main/java/io/reactivex/internal/operators/OperatorBufferBoundary.java index deffbb1b56..5fa2658d92 100644 --- a/src/main/java/io/reactivex/internal/operators/OperatorBufferBoundary.java +++ b/src/main/java/io/reactivex/internal/operators/OperatorBufferBoundary.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -14,17 +14,18 @@ package io.reactivex.internal.operators; import java.util.*; -import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; -import java.util.function.*; +import java.util.concurrent.atomic.AtomicInteger; import org.reactivestreams.*; import io.reactivex.Observable.Operator; -import io.reactivex.disposables.Disposable; +import io.reactivex.disposables.*; +import io.reactivex.functions.*; import io.reactivex.internal.disposables.SetCompositeResource; import io.reactivex.internal.queue.MpscLinkedQueue; import io.reactivex.internal.subscribers.*; import io.reactivex.internal.subscriptions.SubscriptionHelper; +import io.reactivex.internal.util.QueueDrainHelper; import io.reactivex.plugins.RxJavaPlugins; import io.reactivex.subscribers.SerializedSubscriber; @@ -42,8 +43,8 @@ public OperatorBufferBoundary(Publisher bufferOpen, @Override public Subscriber apply(Subscriber t) { - return new BufferBoundarySubscriber<>( - new SerializedSubscriber<>(t), + return new BufferBoundarySubscriber( + new SerializedSubscriber(t), bufferOpen, bufferClose, bufferSupplier ); } @@ -59,21 +60,18 @@ static final class BufferBoundarySubscriber, final List buffers; - volatile int windows; - @SuppressWarnings("rawtypes") - static final AtomicIntegerFieldUpdater WINDOWS = - AtomicIntegerFieldUpdater.newUpdater(BufferBoundarySubscriber.class, "windows"); + final AtomicInteger windows = new AtomicInteger(); public BufferBoundarySubscriber(Subscriber actual, Publisher bufferOpen, Function> bufferClose, Supplier bufferSupplier) { - super(actual, new MpscLinkedQueue<>()); + super(actual, new MpscLinkedQueue()); this.bufferOpen = bufferOpen; this.bufferClose = bufferClose; this.bufferSupplier = bufferSupplier; - this.buffers = new LinkedList<>(); - this.resources = new SetCompositeResource<>(Disposable::dispose); + this.buffers = new LinkedList(); + this.resources = new SetCompositeResource(Disposables.consumeAndDispose()); } @Override public void onSubscribe(Subscription s) { @@ -82,12 +80,12 @@ public void onSubscribe(Subscription s) { } this.s = s; - BufferOpenSubscriber bos = new BufferOpenSubscriber<>(this); + BufferOpenSubscriber bos = new BufferOpenSubscriber(this); resources.add(bos); actual.onSubscribe(this); - WINDOWS.lazySet(this, 1); + windows.lazySet(1); bufferOpen.subscribe(bos); s.request(Long.MAX_VALUE); @@ -114,7 +112,7 @@ public void onError(Throwable t) { @Override public void onComplete() { - if (WINDOWS.decrementAndGet(this) == 0) { + if (windows.decrementAndGet() == 0) { complete(); } } @@ -122,7 +120,7 @@ public void onComplete() { void complete() { List list; synchronized (this) { - list = new ArrayList<>(buffers); + list = new ArrayList(buffers); buffers.clear(); } @@ -132,7 +130,7 @@ void complete() { } done = true; if (enter()) { - drainMaxLoop(q, actual, false, this); + QueueDrainHelper.drainMaxLoop(q, actual, false, this, this); } } @@ -204,17 +202,17 @@ void open(Open window) { buffers.add(b); } - BufferCloseSubscriber bcs = new BufferCloseSubscriber<>(b, this); + BufferCloseSubscriber bcs = new BufferCloseSubscriber(b, this); resources.add(bcs); - WINDOWS.getAndIncrement(this); + windows.getAndIncrement(); p.subscribe(bcs); } void openFinished(Disposable d) { if (resources.remove(d)) { - if (WINDOWS.decrementAndGet(this) == 0) { + if (windows.decrementAndGet() == 0) { complete(); } } @@ -232,7 +230,7 @@ void close(U b, Disposable d) { } if (resources.remove(d)) { - if (WINDOWS.decrementAndGet(this) == 0) { + if (windows.decrementAndGet() == 0) { complete(); } } diff --git a/src/main/java/io/reactivex/internal/operators/OperatorBufferBoundarySupplier.java b/src/main/java/io/reactivex/internal/operators/OperatorBufferBoundarySupplier.java index af62f6017b..ecbced3da7 100644 --- a/src/main/java/io/reactivex/internal/operators/OperatorBufferBoundarySupplier.java +++ b/src/main/java/io/reactivex/internal/operators/OperatorBufferBoundarySupplier.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -14,16 +14,17 @@ package io.reactivex.internal.operators; import java.util.Collection; -import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; -import java.util.function.Supplier; +import java.util.concurrent.atomic.*; import org.reactivestreams.*; import io.reactivex.Observable.Operator; import io.reactivex.disposables.Disposable; +import io.reactivex.functions.Supplier; import io.reactivex.internal.queue.MpscLinkedQueue; import io.reactivex.internal.subscribers.*; import io.reactivex.internal.subscriptions.*; +import io.reactivex.internal.util.QueueDrainHelper; import io.reactivex.plugins.RxJavaPlugins; import io.reactivex.subscribers.SerializedSubscriber; @@ -38,7 +39,7 @@ public OperatorBufferBoundarySupplier(Supplier> boundaryS @Override public Subscriber apply(Subscriber t) { - return new BufferBondarySupplierSubscriber<>(new SerializedSubscriber<>(t), bufferSupplier, boundarySupplier); + return new BufferBondarySupplierSubscriber(new SerializedSubscriber(t), bufferSupplier, boundarySupplier); } static final class BufferBondarySupplierSubscriber, B> @@ -49,18 +50,18 @@ static final class BufferBondarySupplierSubscriber OTHER = - AtomicReferenceFieldUpdater.newUpdater(BufferBondarySupplierSubscriber.class, Disposable.class, "other"); + final AtomicReference other = new AtomicReference(); - static final Disposable DISPOSED = () -> { }; + static final Disposable DISPOSED = new Disposable() { + @Override + public void dispose() { } + }; U buffer; public BufferBondarySupplierSubscriber(Subscriber actual, Supplier bufferSupplier, Supplier> boundarySupplier) { - super(actual, new MpscLinkedQueue<>()); + super(actual, new MpscLinkedQueue()); this.bufferSupplier = bufferSupplier; this.boundarySupplier = boundarySupplier; } @@ -111,8 +112,8 @@ public void onSubscribe(Subscription s) { return; } - BufferBoundarySubscriber bs = new BufferBoundarySubscriber<>(this); - other = bs; + BufferBoundarySubscriber bs = new BufferBoundarySubscriber(this); + other.set(bs); actual.onSubscribe(this); @@ -153,7 +154,7 @@ public void onComplete() { queue.offer(b); done = true; if (enter()) { - drainMaxLoop(queue, actual, false, this); + QueueDrainHelper.drainMaxLoop(queue, actual, false, this, this); } } @@ -176,9 +177,9 @@ public void cancel() { } void disposeOther() { - Disposable d = other; + Disposable d = other.get(); if (d != DISPOSED) { - d = OTHER.getAndSet(this, DISPOSED); + d = other.getAndSet(DISPOSED); if (d != DISPOSED && d != null) { d.dispose(); } @@ -187,7 +188,7 @@ void disposeOther() { void next() { - Disposable o = other; + Disposable o = other.get(); U next; @@ -223,9 +224,9 @@ void next() { return; } - BufferBoundarySubscriber bs = new BufferBoundarySubscriber<>(this); + BufferBoundarySubscriber bs = new BufferBoundarySubscriber(this); - if (!OTHER.compareAndSet(this, o, bs)) { + if (!other.compareAndSet(o, bs)) { return; } diff --git a/src/main/java/io/reactivex/internal/operators/OperatorBufferExactBoundary.java b/src/main/java/io/reactivex/internal/operators/OperatorBufferExactBoundary.java index 026d86baa7..aa5761769e 100644 --- a/src/main/java/io/reactivex/internal/operators/OperatorBufferExactBoundary.java +++ b/src/main/java/io/reactivex/internal/operators/OperatorBufferExactBoundary.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -14,15 +14,16 @@ package io.reactivex.internal.operators; import java.util.Collection; -import java.util.function.Supplier; import org.reactivestreams.*; import io.reactivex.Observable.Operator; import io.reactivex.disposables.Disposable; +import io.reactivex.functions.Supplier; import io.reactivex.internal.queue.MpscLinkedQueue; import io.reactivex.internal.subscribers.*; import io.reactivex.internal.subscriptions.*; +import io.reactivex.internal.util.QueueDrainHelper; import io.reactivex.subscribers.SerializedSubscriber; public final class OperatorBufferExactBoundary, B> implements Operator { @@ -36,7 +37,7 @@ public OperatorBufferExactBoundary(Publisher boundary, Supplier bufferSupp @Override public Subscriber apply(Subscriber t) { - return new BufferExactBondarySubscriber<>(new SerializedSubscriber<>(t), bufferSupplier, boundary); + return new BufferExactBondarySubscriber(new SerializedSubscriber(t), bufferSupplier, boundary); } static final class BufferExactBondarySubscriber, B> @@ -53,7 +54,7 @@ static final class BufferExactBondarySubscriber actual, Supplier bufferSupplier, Publisher boundary) { - super(actual, new MpscLinkedQueue<>()); + super(actual, new MpscLinkedQueue()); this.bufferSupplier = bufferSupplier; this.boundary = boundary; } @@ -84,7 +85,7 @@ public void onSubscribe(Subscription s) { } buffer = b; - BufferBoundarySubscriber bs = new BufferBoundarySubscriber<>(this); + BufferBoundarySubscriber bs = new BufferBoundarySubscriber(this); other = bs; actual.onSubscribe(this); @@ -126,7 +127,7 @@ public void onComplete() { queue.offer(b); done = true; if (enter()) { - drainMaxLoop(queue, actual, false, this); + QueueDrainHelper.drainMaxLoop(queue, actual, false, this, this); } } diff --git a/src/main/java/io/reactivex/internal/operators/OperatorBufferTimed.java b/src/main/java/io/reactivex/internal/operators/OperatorBufferTimed.java index 3fc388b6f7..dc1920d31e 100644 --- a/src/main/java/io/reactivex/internal/operators/OperatorBufferTimed.java +++ b/src/main/java/io/reactivex/internal/operators/OperatorBufferTimed.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -15,8 +15,7 @@ import java.util.*; import java.util.concurrent.*; -import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; -import java.util.function.Supplier; +import java.util.concurrent.atomic.AtomicReference; import org.reactivestreams.*; @@ -24,9 +23,11 @@ import io.reactivex.Scheduler; import io.reactivex.Scheduler.Worker; import io.reactivex.disposables.Disposable; +import io.reactivex.functions.Supplier; import io.reactivex.internal.queue.MpscLinkedQueue; import io.reactivex.internal.subscribers.QueueDrainSubscriber; import io.reactivex.internal.subscriptions.*; +import io.reactivex.internal.util.QueueDrainHelper; import io.reactivex.subscribers.SerializedSubscriber; public final class OperatorBufferTimed> implements Operator { @@ -53,23 +54,23 @@ public OperatorBufferTimed(long timespan, long timeskip, TimeUnit unit, Schedule @Override public Subscriber apply(Subscriber t) { if (timespan == timeskip && maxSize == Integer.MAX_VALUE) { - return new BufferExactUnboundedSubscriber<>( - new SerializedSubscriber<>(t), + return new BufferExactUnboundedSubscriber( + new SerializedSubscriber(t), bufferSupplier, timespan, unit, scheduler); } Scheduler.Worker w = scheduler.createWorker(); if (timespan == timeskip) { - return new BufferExactBoundedSubscriber<>( - new SerializedSubscriber<>(t), + return new BufferExactBoundedSubscriber( + new SerializedSubscriber(t), bufferSupplier, timespan, unit, maxSize, restartTimerOnMaxSize, w ); } // Can't use maxSize because what to do if a buffer is full but its // timespan hasn't been elapsed? - return new BufferSkipBoundedSubscriber<>( - new SerializedSubscriber<>(t), + return new BufferSkipBoundedSubscriber( + new SerializedSubscriber(t), bufferSupplier, timespan, timeskip, unit, w); } @@ -86,17 +87,17 @@ static final class BufferExactUnboundedSubscriber TIMER = - AtomicReferenceFieldUpdater.newUpdater(BufferExactUnboundedSubscriber.class, Disposable.class, "timer"); + final AtomicReference timer = new AtomicReference(); - static final Disposable CANCELLED = () -> { }; + static final Disposable CANCELLED = new Disposable() { + @Override + public void dispose() { } + }; public BufferExactUnboundedSubscriber( Subscriber actual, Supplier bufferSupplier, long timespan, TimeUnit unit, Scheduler scheduler) { - super(actual, new MpscLinkedQueue<>()); + super(actual, new MpscLinkedQueue()); this.bufferSupplier = bufferSupplier; this.timespan = timespan; this.unit = unit; @@ -134,7 +135,7 @@ public void onSubscribe(Subscription s) { s.request(Long.MAX_VALUE); Disposable d = scheduler.schedulePeriodicallyDirect(this, timespan, timespan, unit); - if (!TIMER.compareAndSet(this, null, d)) { + if (!timer.compareAndSet(null, d)) { d.dispose(); } } @@ -174,7 +175,7 @@ public void onComplete() { queue.offer(b); done = true; if (enter()) { - drainMaxLoop(queue, actual, false, this); + QueueDrainHelper.drainMaxLoop(queue, actual, false, this, this); } } @@ -191,9 +192,9 @@ public void cancel() { } void disposeTimer() { - Disposable d = timer; + Disposable d = timer.get(); if (d != CANCELLED) { - d = TIMER.getAndSet(this, CANCELLED); + d = timer.getAndSet(CANCELLED); if (d != CANCELLED && d != null) { d.dispose(); } @@ -276,13 +277,13 @@ static final class BufferSkipBoundedSubscriber actual, Supplier bufferSupplier, long timespan, long timeskip, TimeUnit unit, Worker w) { - super(actual, new MpscLinkedQueue<>()); + super(actual, new MpscLinkedQueue()); this.bufferSupplier = bufferSupplier; this.timespan = timespan; this.timeskip = timeskip; this.unit = unit; this.w = w; - this.buffers = new LinkedList<>(); + this.buffers = new LinkedList(); } @Override @@ -292,7 +293,7 @@ public void onSubscribe(Subscription s) { } this.s = s; - U b; + final U b; try { b = bufferSupplier.get(); @@ -318,19 +319,24 @@ public void onSubscribe(Subscription s) { w.schedulePeriodically(this, timeskip, timeskip, unit); - w.schedule(() -> { - synchronized (this) { - buffers.remove(b); + w.schedule(new Runnable() { + @Override + public void run() { + synchronized (BufferSkipBoundedSubscriber.this) { + buffers.remove(b); + } + + fastpathOrderedEmitMax(b, false, w); } - - fastpathOrderedEmitMax(b, false, w); }, timespan, unit); } @Override public void onNext(T t) { synchronized (this) { - buffers.forEach(b -> b.add(t)); + for (U b : buffers) { + b.add(t); + } } } @@ -346,14 +352,16 @@ public void onError(Throwable t) { public void onComplete() { List bs; synchronized (this) { - bs = new ArrayList<>(buffers); + bs = new ArrayList(buffers); buffers.clear(); } - bs.forEach(b -> queue.add(b)); + for (U b : bs) { + queue.add(b); + } done = true; if (enter()) { - drainMaxLoop(queue, actual, false, w); + QueueDrainHelper.drainMaxLoop(queue, actual, false, w, this); } } @@ -380,7 +388,7 @@ public void run() { if (cancelled) { return; } - U b; + final U b; try { b = bufferSupplier.get(); @@ -402,12 +410,15 @@ public void run() { buffers.add(b); } - w.schedule(() -> { - synchronized (this) { - buffers.remove(b); + w.schedule(new Runnable() { + @Override + public void run() { + synchronized (BufferSkipBoundedSubscriber.this) { + buffers.remove(b); + } + + fastpathOrderedEmitMax(b, false, w); } - - fastpathOrderedEmitMax(b, false, w); }, timespan, unit); } @@ -442,7 +453,7 @@ public BufferExactBoundedSubscriber( Supplier bufferSupplier, long timespan, TimeUnit unit, int maxSize, boolean restartOnMaxSize, Worker w) { - super(actual, new MpscLinkedQueue<>()); + super(actual, new MpscLinkedQueue()); this.bufferSupplier = bufferSupplier; this.timespan = timespan; this.unit = unit; @@ -562,7 +573,7 @@ public void onComplete() { queue.offer(b); done = true; if (enter()) { - drainMaxLoop(queue, actual, false, this); + QueueDrainHelper.drainMaxLoop(queue, actual, false, this, this); } } diff --git a/src/main/java/io/reactivex/internal/operators/OperatorCollect.java b/src/main/java/io/reactivex/internal/operators/OperatorCollect.java index 7a200d3ba2..6f28d1a609 100644 --- a/src/main/java/io/reactivex/internal/operators/OperatorCollect.java +++ b/src/main/java/io/reactivex/internal/operators/OperatorCollect.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -12,11 +12,10 @@ */ package io.reactivex.internal.operators; -import java.util.function.*; - import org.reactivestreams.*; import io.reactivex.Observable.Operator; +import io.reactivex.functions.*; import io.reactivex.internal.subscribers.CancelledSubscriber; import io.reactivex.internal.subscriptions.*; @@ -39,8 +38,12 @@ public Subscriber apply(Subscriber t) { EmptySubscription.error(e, t); return CancelledSubscriber.INSTANCE; } + if (u == null) { + EmptySubscription.error(new NullPointerException("The initial value supplied is null"), t); + return CancelledSubscriber.INSTANCE; + } - return new CollectSubscriber<>(t, u, collector); + return new CollectSubscriber(t, u, collector); } static final class CollectSubscriber implements Subscriber, Subscription { @@ -99,4 +102,4 @@ public void cancel() { s.cancel(); } } -} +} \ No newline at end of file diff --git a/src/main/java/io/reactivex/internal/operators/OperatorConcatMap.java b/src/main/java/io/reactivex/internal/operators/OperatorConcatMap.java index 2a4dbd3569..03fe9d2969 100644 --- a/src/main/java/io/reactivex/internal/operators/OperatorConcatMap.java +++ b/src/main/java/io/reactivex/internal/operators/OperatorConcatMap.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -14,11 +14,11 @@ import java.util.Queue; import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.Function; import org.reactivestreams.*; import io.reactivex.Observable.Operator; +import io.reactivex.functions.Function; import io.reactivex.internal.queue.*; import io.reactivex.internal.subscriptions.SubscriptionArbiter; import io.reactivex.internal.util.Pow2; @@ -34,10 +34,10 @@ public OperatorConcatMap(Function> m } @Override public Subscriber apply(Subscriber s) { - SerializedSubscriber ssub = new SerializedSubscriber<>(s); + SerializedSubscriber ssub = new SerializedSubscriber(s); SubscriptionArbiter sa = new SubscriptionArbiter(); ssub.onSubscribe(sa); - return new SourceSubscriber<>(ssub, sa, mapper, bufferSize); + return new SourceSubscriber(ssub, sa, mapper, bufferSize); } static final class SourceSubscriber extends AtomicInteger implements Subscriber { @@ -62,12 +62,12 @@ public SourceSubscriber(Subscriber actual, SubscriptionArbiter sa, this.sa = sa; this.mapper = mapper; this.bufferSize = bufferSize; - this.inner = new InnerSubscriber<>(actual, sa, this); + this.inner = new InnerSubscriber(actual, sa, this); Queue q; if (Pow2.isPowerOfTwo(bufferSize)) { - q = new SpscArrayQueue<>(bufferSize); + q = new SpscArrayQueue(bufferSize); } else { - q = new SpscExactArrayQueue<>(bufferSize); + q = new SpscExactArrayQueue(bufferSize); } this.queue = q; } @@ -150,6 +150,13 @@ void drain() { actual.onError(e); return; } + + if (p == null) { + cancel(); + actual.onError(new NullPointerException("The publisher returned is null")); + return; + } + index++; // this is not RS but since our Subscriber doesn't hold state by itself, // subscribing it to each source is safe and saves allocation diff --git a/src/main/java/io/reactivex/internal/operators/OperatorCount.java b/src/main/java/io/reactivex/internal/operators/OperatorCount.java index bcf700611b..466547b256 100644 --- a/src/main/java/io/reactivex/internal/operators/OperatorCount.java +++ b/src/main/java/io/reactivex/internal/operators/OperatorCount.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 diff --git a/src/main/java/io/reactivex/internal/operators/OperatorDebounce.java b/src/main/java/io/reactivex/internal/operators/OperatorDebounce.java index fe5f8e43aa..2ce4cae388 100644 --- a/src/main/java/io/reactivex/internal/operators/OperatorDebounce.java +++ b/src/main/java/io/reactivex/internal/operators/OperatorDebounce.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -14,12 +14,12 @@ package io.reactivex.internal.operators; import java.util.concurrent.atomic.*; -import java.util.function.Function; import org.reactivestreams.*; import io.reactivex.Observable.Operator; import io.reactivex.disposables.Disposable; +import io.reactivex.functions.Function; import io.reactivex.internal.subscribers.DisposableSubscriber; import io.reactivex.internal.subscriptions.SubscriptionHelper; import io.reactivex.internal.util.BackpressureHelper; @@ -35,7 +35,7 @@ public OperatorDebounce(Function> debounceSele @Override public Subscriber apply(Subscriber t) { - return new DebounceSubscriber<>(new SerializedSubscriber<>(t), debounceSelector); + return new DebounceSubscriber(new SerializedSubscriber(t), debounceSelector); } static final class DebounceSubscriber extends AtomicLong @@ -49,12 +49,12 @@ static final class DebounceSubscriber extends AtomicLong Subscription s; - volatile Disposable debouncer; - @SuppressWarnings("rawtypes") - static final AtomicReferenceFieldUpdater DEBOUNCER = - AtomicReferenceFieldUpdater.newUpdater(DebounceSubscriber.class, Disposable.class, "debouncer"); + final AtomicReference debouncer = new AtomicReference(); - static final Disposable CANCELLED = () -> { }; + static final Disposable CANCELLED = new Disposable() { + @Override + public void dispose() { } + }; volatile long index; @@ -86,7 +86,7 @@ public void onNext(T t) { long idx = index + 1; index = idx; - Disposable d = debouncer; + Disposable d = debouncer.get(); if (d != null) { d.dispose(); } @@ -107,9 +107,9 @@ public void onNext(T t) { return; } - DebounceInnerSubscriber dis = new DebounceInnerSubscriber<>(this, idx, t); + DebounceInnerSubscriber dis = new DebounceInnerSubscriber(this, idx, t); - if (DEBOUNCER.compareAndSet(this, d, dis)) { + if (debouncer.compareAndSet(d, dis)) { p.subscribe(dis); } } @@ -126,7 +126,7 @@ public void onComplete() { return; } done = true; - Disposable d = debouncer; + Disposable d = debouncer.get(); if (d != CANCELLED) { @SuppressWarnings("unchecked") DebounceInnerSubscriber dis = (DebounceInnerSubscriber)d; @@ -152,9 +152,9 @@ public void cancel() { } public void disposeDebouncer() { - Disposable d = debouncer; + Disposable d = debouncer.get(); if (d != CANCELLED) { - d = DEBOUNCER.getAndSet(this, CANCELLED); + d = debouncer.getAndSet(CANCELLED); if (d != CANCELLED && d != null) { d.dispose(); } @@ -183,10 +183,7 @@ static final class DebounceInnerSubscriber extends DisposableSubscriber boolean done; - volatile int once; - @SuppressWarnings("rawtypes") - static final AtomicIntegerFieldUpdater ONCE = - AtomicIntegerFieldUpdater.newUpdater(DebounceInnerSubscriber.class, "once"); + final AtomicBoolean once = new AtomicBoolean(); public DebounceInnerSubscriber(DebounceSubscriber parent, long index, T value) { this.parent = parent; @@ -205,7 +202,7 @@ public void onNext(U t) { } void emit() { - if (ONCE.compareAndSet(this, 0, 1)) { + if (once.compareAndSet(false, true)) { parent.emit(index, value); } } diff --git a/src/main/java/io/reactivex/internal/operators/OperatorDebounceTimed.java b/src/main/java/io/reactivex/internal/operators/OperatorDebounceTimed.java index d849be982f..184c711e65 100644 --- a/src/main/java/io/reactivex/internal/operators/OperatorDebounceTimed.java +++ b/src/main/java/io/reactivex/internal/operators/OperatorDebounceTimed.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -18,8 +18,8 @@ import org.reactivestreams.*; -import io.reactivex.Observable.Operator; import io.reactivex.Scheduler; +import io.reactivex.Observable.Operator; import io.reactivex.Scheduler.Worker; import io.reactivex.disposables.Disposable; import io.reactivex.internal.subscriptions.SubscriptionHelper; @@ -40,8 +40,8 @@ public OperatorDebounceTimed(long timeout, TimeUnit unit, Scheduler scheduler) { @Override public Subscriber apply(Subscriber t) { - return new DebounceTimedSubscriber<>( - new SerializedSubscriber<>(t), + return new DebounceTimedSubscriber( + new SerializedSubscriber(t), timeout, unit, scheduler.createWorker()); } @@ -56,14 +56,17 @@ static final class DebounceTimedSubscriber extends AtomicLong Subscription s; - volatile Disposable timer; - @SuppressWarnings("rawtypes") - static final AtomicReferenceFieldUpdater TIMER = - AtomicReferenceFieldUpdater.newUpdater(DebounceTimedSubscriber.class, Disposable.class, "timer"); + final AtomicReference timer = new AtomicReference(); - static final Disposable CANCELLED = () -> { }; + static final Disposable CANCELLED = new Disposable() { + @Override + public void dispose() { } + }; - static final Disposable NEW_TIMER = () -> { }; + static final Disposable NEW_TIMER = new Disposable() { + @Override + public void dispose() { } + }; volatile long index; @@ -77,9 +80,9 @@ public DebounceTimedSubscriber(Subscriber actual, long timeout, TimeU } public void disposeTimer() { - Disposable d = timer; + Disposable d = timer.get(); if (d != CANCELLED) { - d = TIMER.getAndSet(this, CANCELLED); + d = timer.getAndSet(CANCELLED); if (d != CANCELLED && d != null) { d.dispose(); } @@ -105,13 +108,13 @@ public void onNext(T t) { long idx = index + 1; index = idx; - Disposable d = timer; + Disposable d = timer.get(); if (d != null) { d.dispose(); } - DebounceEmitter de = new DebounceEmitter<>(t, idx, this); - if (!TIMER.compareAndSet(this, d, de)) { + DebounceEmitter de = new DebounceEmitter(t, idx, this); + if (!timer.compareAndSet(d, de)) { return; } @@ -138,7 +141,7 @@ public void onComplete() { } done = true; - Disposable d = timer; + Disposable d = timer.get(); if (d != CANCELLED) { @SuppressWarnings("unchecked") DebounceEmitter de = (DebounceEmitter)d; @@ -186,16 +189,16 @@ static final class DebounceEmitter extends AtomicReference implem /** */ private static final long serialVersionUID = 6812032969491025141L; - static final Disposable DISPOSED = () -> { }; + static final Disposable DISPOSED = new Disposable() { + @Override + public void dispose() { } + }; final T value; final long idx; final DebounceTimedSubscriber parent; - volatile int once; - @SuppressWarnings("rawtypes") - static final AtomicIntegerFieldUpdater ONCE = - AtomicIntegerFieldUpdater.newUpdater(DebounceEmitter.class, "once"); + final AtomicBoolean once = new AtomicBoolean(); public DebounceEmitter(T value, long idx, DebounceTimedSubscriber parent) { @@ -210,7 +213,7 @@ public void run() { } void emit() { - if (ONCE.compareAndSet(this, 0, 1)) { + if (once.compareAndSet(false, true)) { parent.emit(idx, value, this); } } diff --git a/src/main/java/io/reactivex/internal/operators/OperatorDelay.java b/src/main/java/io/reactivex/internal/operators/OperatorDelay.java index 1677eb86c7..0246352f4a 100644 --- a/src/main/java/io/reactivex/internal/operators/OperatorDelay.java +++ b/src/main/java/io/reactivex/internal/operators/OperatorDelay.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -17,8 +17,8 @@ import org.reactivestreams.*; -import io.reactivex.Observable.Operator; import io.reactivex.Scheduler; +import io.reactivex.Observable.Operator; import io.reactivex.Scheduler.Worker; import io.reactivex.internal.subscriptions.SubscriptionHelper; import io.reactivex.subscribers.SerializedSubscriber; @@ -45,12 +45,12 @@ public Subscriber apply(Subscriber t) { if (delayError) { s = (Subscriber)t; } else { - s = new SerializedSubscriber<>(t); + s = new SerializedSubscriber(t); } Scheduler.Worker w = scheduler.createWorker(); - return new DelaySubscriber<>(s, delay, unit, w, delayError); + return new DelaySubscriber(s, delay, unit, w, delayError); } static final class DelaySubscriber implements Subscriber, Subscription { @@ -81,18 +81,26 @@ public void onSubscribe(Subscription s) { } @Override - public void onNext(T t) { - w.schedule(() -> actual.onNext(t), delay, unit); + public void onNext(final T t) { + w.schedule(new Runnable() { + @Override + public void run() { + actual.onNext(t); + } + }, delay, unit); } @Override - public void onError(Throwable t) { + public void onError(final Throwable t) { if (delayError) { - w.schedule(() -> { - try { - actual.onError(t); - } finally { - w.dispose(); + w.schedule(new Runnable() { + @Override + public void run() { + try { + actual.onError(t); + } finally { + w.dispose(); + } } }, delay, unit); } else { @@ -102,11 +110,14 @@ public void onError(Throwable t) { @Override public void onComplete() { - w.schedule(() -> { - try { - actual.onComplete(); - } finally { - w.dispose(); + w.schedule(new Runnable() { + @Override + public void run() { + try { + actual.onComplete(); + } finally { + w.dispose(); + } } }, delay, unit); } diff --git a/src/main/java/io/reactivex/internal/operators/OperatorDematerialize.java b/src/main/java/io/reactivex/internal/operators/OperatorDematerialize.java index 841237e391..9bea9a8df1 100644 --- a/src/main/java/io/reactivex/internal/operators/OperatorDematerialize.java +++ b/src/main/java/io/reactivex/internal/operators/OperatorDematerialize.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,14 +13,12 @@ package io.reactivex.internal.operators; -import java.util.Optional; - import org.reactivestreams.*; +import io.reactivex.*; import io.reactivex.Observable.Operator; import io.reactivex.internal.subscriptions.SubscriptionHelper; import io.reactivex.plugins.RxJavaPlugins; -import io.reactivex.Try; public enum OperatorDematerialize implements Operator>> { INSTANCE; @@ -32,7 +30,7 @@ public static Operator>> instance() { @Override public Subscriber>> apply(Subscriber t) { - return new DematerializeSubscriber<>(t); + return new DematerializeSubscriber(t); } static final class DematerializeSubscriber implements Subscriber>> { diff --git a/src/main/java/io/reactivex/internal/operators/OperatorDistinct.java b/src/main/java/io/reactivex/internal/operators/OperatorDistinct.java index a5274bc82a..f2a218c24a 100644 --- a/src/main/java/io/reactivex/internal/operators/OperatorDistinct.java +++ b/src/main/java/io/reactivex/internal/operators/OperatorDistinct.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,12 +13,14 @@ package io.reactivex.internal.operators; -import java.util.*; -import java.util.function.*; +import java.util.Collection; import org.reactivestreams.*; import io.reactivex.Observable.Operator; +import io.reactivex.exceptions.CompositeException; +import io.reactivex.functions.*; +import io.reactivex.internal.functions.*; import io.reactivex.internal.subscribers.CancelledSubscriber; import io.reactivex.internal.subscriptions.*; @@ -31,38 +33,50 @@ public OperatorDistinct(Function keySelector, Supplier OperatorDistinct withCollection(Function keySelector, Supplier> collectionSupplier) { - Supplier> p = () -> { - Collection coll = collectionSupplier.get(); - - return t -> { - if (t == null) { - coll.clear(); - return true; - } - return coll.add(t); - }; + public static OperatorDistinct withCollection(Function keySelector, final Supplier> collectionSupplier) { + Supplier> p = new Supplier>() { + @Override + public Predicate get() { + final Collection coll = collectionSupplier.get(); + + return new Predicate() { + @Override + public boolean test(K t) { + if (t == null) { + coll.clear(); + return true; + } + return coll.add(t); + } + }; + } }; - return new OperatorDistinct<>(keySelector, p); + return new OperatorDistinct(keySelector, p); } static final OperatorDistinct UNTIL_CHANGED; static { - Supplier> p = () -> { - Object[] last = { null }; - - return t -> { - if (t == null) { - last[0] = null; - return true; - } - Object o = last[0]; - last[0] = t; - return !Objects.equals(o, t); - }; + Supplier> p = new Supplier>() { + @Override + public Predicate get() { + final Object[] last = { null }; + + return new Predicate() { + @Override + public boolean test(Object t) { + if (t == null) { + last[0] = null; + return true; + } + Object o = last[0]; + last[0] = t; + return !Objects.equals(o, t); + } + }; + } }; - UNTIL_CHANGED = new OperatorDistinct<>(v -> v, p); + UNTIL_CHANGED = new OperatorDistinct(Functions.identity(), p); } @SuppressWarnings("unchecked") @@ -71,20 +85,26 @@ public static OperatorDistinct untilChanged() { } public static OperatorDistinct untilChanged(Function keySelector) { - Supplier> p = () -> { - Object[] last = { null }; - - return t -> { - if (t == null) { - last[0] = null; - return true; - } - Object o = last[0]; - last[0] = t; - return !Objects.equals(o, t); - }; + Supplier> p = new Supplier>() { + @Override + public Predicate get() { + final Object[] last = { null }; + + return new Predicate() { + @Override + public boolean test(K t) { + if (t == null) { + last[0] = null; + return true; + } + Object o = last[0]; + last[0] = t; + return !Objects.equals(o, t); + } + }; + } }; - return new OperatorDistinct<>(keySelector, p); + return new OperatorDistinct(keySelector, p); } @@ -103,7 +123,7 @@ public Subscriber apply(Subscriber t) { return CancelledSubscriber.INSTANCE; } - return new DistinctSubscriber<>(t, keySelector, coll); + return new DistinctSubscriber(t, keySelector, coll); } static final class DistinctSubscriber implements Subscriber { @@ -168,8 +188,7 @@ public void onError(Throwable t) { try { predicate.test(null); // special case: poison pill } catch (Throwable e) { - t.addSuppressed(e); - actual.onError(t); + actual.onError(new CompositeException(e, t)); return; } actual.onError(t); diff --git a/src/main/java/io/reactivex/internal/operators/OperatorDoOnEach.java b/src/main/java/io/reactivex/internal/operators/OperatorDoOnEach.java index c60b4c23f8..1d59cbbc21 100644 --- a/src/main/java/io/reactivex/internal/operators/OperatorDoOnEach.java +++ b/src/main/java/io/reactivex/internal/operators/OperatorDoOnEach.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,11 +13,11 @@ package io.reactivex.internal.operators; -import java.util.function.Consumer; - import org.reactivestreams.*; import io.reactivex.Observable.Operator; +import io.reactivex.exceptions.CompositeException; +import io.reactivex.functions.Consumer; import io.reactivex.internal.subscriptions.SubscriptionHelper; import io.reactivex.plugins.RxJavaPlugins; @@ -39,7 +39,7 @@ public OperatorDoOnEach(Consumer onNext, @Override public Subscriber apply(Subscriber t) { - return new DoOnEachSubscriber<>(t, onNext, onError, onComplete, onAfterTerminate); + return new DoOnEachSubscriber(t, onNext, onError, onComplete, onAfterTerminate); } static final class DoOnEachSubscriber implements Subscriber { @@ -98,12 +98,16 @@ public void onError(Throwable t) { return; } done = true; + boolean relay = true; try { onError.accept(t); } catch (Throwable e) { - t.addSuppressed(e); + actual.onError(new CompositeException(e, t)); + relay = false; + } + if (relay) { + actual.onError(t); } - actual.onError(t); try { onAfterTerminate.run(); diff --git a/src/main/java/io/reactivex/internal/operators/OperatorElementAt.java b/src/main/java/io/reactivex/internal/operators/OperatorElementAt.java index 20210da6b6..84d44e5a59 100644 --- a/src/main/java/io/reactivex/internal/operators/OperatorElementAt.java +++ b/src/main/java/io/reactivex/internal/operators/OperatorElementAt.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -27,7 +27,7 @@ public OperatorElementAt(long index, T defaultValue) { } @Override public Subscriber apply(Subscriber t) { - return new ElementAtSubscriber<>(t, index, defaultValue); + return new ElementAtSubscriber(t, index, defaultValue); } static final class ElementAtSubscriber implements Subscriber, Subscription { diff --git a/src/main/java/io/reactivex/internal/operators/OperatorFilter.java b/src/main/java/io/reactivex/internal/operators/OperatorFilter.java index f0c843309b..23a73d5e54 100644 --- a/src/main/java/io/reactivex/internal/operators/OperatorFilter.java +++ b/src/main/java/io/reactivex/internal/operators/OperatorFilter.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,17 +13,13 @@ package io.reactivex.internal.operators; -import java.util.function.Predicate; - import org.reactivestreams.*; import io.reactivex.Observable.Operator; +import io.reactivex.functions.Predicate; import io.reactivex.internal.subscribers.ConditionalSubscriber; import io.reactivex.internal.subscriptions.SubscriptionHelper; -/** - * - */ public final class OperatorFilter implements Operator { final Predicate predicate; public OperatorFilter(Predicate predicate) { @@ -32,7 +28,7 @@ public OperatorFilter(Predicate predicate) { @Override public Subscriber apply(Subscriber s) { - return new FilterSubscriber<>(s, predicate); + return new FilterSubscriber(s, predicate); } static final class FilterSubscriber implements ConditionalSubscriber { diff --git a/src/main/java/io/reactivex/internal/operators/OperatorFlatMap.java b/src/main/java/io/reactivex/internal/operators/OperatorFlatMap.java index dd9fdbacd2..bc9fcb7f15 100644 --- a/src/main/java/io/reactivex/internal/operators/OperatorFlatMap.java +++ b/src/main/java/io/reactivex/internal/operators/OperatorFlatMap.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -15,20 +15,17 @@ import java.util.*; import java.util.concurrent.atomic.*; -import java.util.function.Function; import org.reactivestreams.*; import io.reactivex.Observable.Operator; import io.reactivex.disposables.Disposable; -import io.reactivex.exceptions.MissingBackpressureException; +import io.reactivex.exceptions.*; +import io.reactivex.functions.Function; import io.reactivex.internal.queue.*; import io.reactivex.internal.subscriptions.SubscriptionHelper; import io.reactivex.internal.util.*; -/** - * - */ public final class OperatorFlatMap implements Operator { final Function> mapper; final boolean delayErrors; @@ -46,7 +43,7 @@ public OperatorFlatMap( @Override public Subscriber apply(Subscriber t) { - return new MergeSubscriber<>(t, mapper, delayErrors, maxConcurrency, bufferSize); + return new MergeSubscriber(t, mapper, delayErrors, maxConcurrency, bufferSize); } static final class MergeSubscriber extends AtomicInteger implements Subscription, Subscriber { @@ -63,28 +60,19 @@ static final class MergeSubscriber extends AtomicInteger implements Subscr volatile boolean done; - volatile Queue errors; - @SuppressWarnings("rawtypes") - static final AtomicReferenceFieldUpdater ERRORS = - AtomicReferenceFieldUpdater.newUpdater(MergeSubscriber.class, Queue.class, "errors"); + final AtomicReference> errors = new AtomicReference>(); - static final Queue ERRORS_CLOSED = new RejectingQueue<>(); + static final Queue ERRORS_CLOSED = new RejectingQueue(); volatile boolean cancelled; - volatile InnerSubscriber[] subscribers; - @SuppressWarnings("rawtypes") - static final AtomicReferenceFieldUpdater SUBSCRIBERS = - AtomicReferenceFieldUpdater.newUpdater(MergeSubscriber.class, InnerSubscriber[].class, "subscribers"); + final AtomicReference[]> subscribers = new AtomicReference[]>(); static final InnerSubscriber[] EMPTY = new InnerSubscriber[0]; static final InnerSubscriber[] CANCELLED = new InnerSubscriber[0]; - volatile long requested; - @SuppressWarnings("rawtypes") - static final AtomicLongFieldUpdater REQUESTED = - AtomicLongFieldUpdater.newUpdater(MergeSubscriber.class, "requested"); + final AtomicLong requested = new AtomicLong(); Subscription s; @@ -92,6 +80,9 @@ static final class MergeSubscriber extends AtomicInteger implements Subscr long lastId; int lastIndex; + int scalarEmitted; + final int scalarLimit; + public MergeSubscriber(Subscriber actual, Function> mapper, boolean delayErrors, int maxConcurrency, int bufferSize) { this.actual = actual; @@ -99,7 +90,8 @@ public MergeSubscriber(Subscriber actual, Function> 1); + subscribers.lazySet(EMPTY); } @Override @@ -134,7 +126,7 @@ public void onNext(T t) { if (p instanceof ObservableScalarSource) { tryEmitScalar(((ObservableScalarSource)p).value()); } else { - InnerSubscriber inner = new InnerSubscriber<>(this, uniqueId++); + InnerSubscriber inner = new InnerSubscriber(this, uniqueId++); addInner(inner); p.subscribe(inner); } @@ -142,7 +134,7 @@ public void onNext(T t) { void addInner(InnerSubscriber inner) { for (;;) { - InnerSubscriber[] a = subscribers; + InnerSubscriber[] a = subscribers.get(); if (a == CANCELLED) { inner.dispose(); return; @@ -151,7 +143,7 @@ void addInner(InnerSubscriber inner) { InnerSubscriber[] b = new InnerSubscriber[n + 1]; System.arraycopy(a, 0, b, 0, n); b[n] = inner; - if (SUBSCRIBERS.compareAndSet(this, a, b)) { + if (subscribers.compareAndSet(a, b)) { return; } } @@ -159,7 +151,7 @@ void addInner(InnerSubscriber inner) { void removeInner(InnerSubscriber inner) { for (;;) { - InnerSubscriber[] a = subscribers; + InnerSubscriber[] a = subscribers.get(); if (a == CANCELLED || a == EMPTY) { return; } @@ -182,7 +174,7 @@ void removeInner(InnerSubscriber inner) { System.arraycopy(a, 0, b, 0, j); System.arraycopy(a, j + 1, b, j, n - j - 1); } - if (SUBSCRIBERS.compareAndSet(this, a, b)) { + if (subscribers.compareAndSet(a, b)) { return; } } @@ -192,12 +184,12 @@ Queue getMainQueue() { Queue q = queue; if (q == null) { if (maxConcurrency == Integer.MAX_VALUE) { - q = new SpscLinkedArrayQueue<>(bufferSize); + q = new SpscLinkedArrayQueue(bufferSize); } else { if (Pow2.isPowerOfTwo(maxConcurrency)) { - q = new SpscArrayQueue<>(maxConcurrency); + q = new SpscArrayQueue(maxConcurrency); } else { - q = new SpscExactArrayQueue<>(maxConcurrency); + q = new SpscExactArrayQueue(maxConcurrency); } } queue = q; @@ -207,14 +199,16 @@ Queue getMainQueue() { void tryEmitScalar(U value) { if (get() == 0 && compareAndSet(0, 1)) { - long r = requested; + long r = requested.get(); if (r != 0L) { actual.onNext(value); if (r != Long.MAX_VALUE) { - REQUESTED.decrementAndGet(this); + requested.decrementAndGet(); } - if (maxConcurrency != Integer.MAX_VALUE && !cancelled) { - s.request(1); + if (maxConcurrency != Integer.MAX_VALUE && !cancelled + && ++scalarEmitted == scalarLimit) { + scalarEmitted = 0; + s.request(scalarLimit); } } else { Queue q = getMainQueue(); @@ -242,7 +236,7 @@ void tryEmitScalar(U value) { Queue getInnerQueue(InnerSubscriber inner) { Queue q = inner.queue; if (q == null) { - q = new SpscArrayQueue<>(bufferSize); + q = new SpscArrayQueue(bufferSize); inner.queue = q; } return q; @@ -250,11 +244,11 @@ Queue getInnerQueue(InnerSubscriber inner) { void tryEmit(U value, InnerSubscriber inner) { if (get() == 0 && compareAndSet(0, 1)) { - long r = requested; + long r = requested.get(); if (r != 0L) { actual.onNext(value); if (r != Long.MAX_VALUE) { - REQUESTED.decrementAndGet(this); + requested.decrementAndGet(); } inner.requestMore(1); } else { @@ -270,7 +264,7 @@ void tryEmit(U value, InnerSubscriber inner) { } else { Queue q = inner.queue; if (q == null) { - q = new SpscArrayQueue<>(bufferSize); + q = new SpscArrayQueue(bufferSize); inner.queue = q; } if (!q.offer(value)) { @@ -310,7 +304,7 @@ public void request(long n) { if (SubscriptionHelper.validateRequest(n)) { return; } - BackpressureHelper.add(REQUESTED, this, n); + BackpressureHelper.add(requested, n); drain(); } @@ -340,7 +334,7 @@ void drainLoop() { } Queue svq = queue; - long r = requested; + long r = requested.get(); boolean unbounded = r == Long.MAX_VALUE; long replenishMain = 0; @@ -368,7 +362,7 @@ void drainLoop() { if (unbounded) { r = Long.MAX_VALUE; } else { - r = REQUESTED.addAndGet(this, -scalarEmission); + r = requested.addAndGet(-scalarEmission); } } if (r == 0L || o == null) { @@ -379,11 +373,11 @@ void drainLoop() { boolean d = done; svq = queue; - InnerSubscriber[] inner = subscribers; + InnerSubscriber[] inner = subscribers.get(); int n = inner.length; if (d && (svq == null || svq.isEmpty()) && n == 0) { - Queue e = errors; + Queue e = errors.get(); if (e == null || e.isEmpty()) { child.onComplete(); } else { @@ -447,7 +441,7 @@ void drainLoop() { } if (produced != 0L) { if (!unbounded) { - r = REQUESTED.addAndGet(this, -produced); + r = requested.addAndGet(-produced); } else { r = Long.MAX_VALUE; } @@ -499,7 +493,7 @@ boolean checkTerminate() { unsubscribe(); return true; } - Queue e = errors; + Queue e = errors.get(); if (!delayErrors && (e != null && !e.isEmpty())) { try { reportError(e); @@ -512,6 +506,7 @@ boolean checkTerminate() { } void reportError(Queue q) { + CompositeException composite = null; Throwable ex = null; Throwable t; @@ -520,20 +515,27 @@ void reportError(Queue q) { if (count == 0) { ex = t; } else { - ex.addSuppressed(t); + if (composite == null) { + composite = new CompositeException(ex); + } + composite.suppress(t); } count++; } - actual.onError(ex); + if (composite != null) { + actual.onError(composite); + } else { + actual.onError(ex); + } } void unsubscribe() { - InnerSubscriber[] a = subscribers; + InnerSubscriber[] a = subscribers.get(); if (a != CANCELLED) { - a = SUBSCRIBERS.getAndSet(this, CANCELLED); + a = subscribers.getAndSet(CANCELLED); if (a != CANCELLED) { - ERRORS.getAndSet(this, ERRORS_CLOSED); + errors.getAndSet(ERRORS_CLOSED); for (InnerSubscriber inner : a) { inner.dispose(); } @@ -543,12 +545,12 @@ void unsubscribe() { Queue getErrorQueue() { for (;;) { - Queue q = errors; + Queue q = errors.get(); if (q != null) { return q; } - q = new MpscLinkedQueue<>(); - if (ERRORS.compareAndSet(this, null, q)) { + q = new MpscLinkedQueue(); + if (errors.compareAndSet(null, q)) { return q; } } @@ -657,7 +659,7 @@ public T peek() { @Override public Iterator iterator() { - return Collections.emptyIterator(); + return Collections.emptyList().iterator(); } @Override @@ -666,4 +668,5 @@ public int size() { } } + } diff --git a/src/main/java/io/reactivex/internal/operators/OperatorGroupBy.java b/src/main/java/io/reactivex/internal/operators/OperatorGroupBy.java index 3e3b38bd79..bc7de4582a 100644 --- a/src/main/java/io/reactivex/internal/operators/OperatorGroupBy.java +++ b/src/main/java/io/reactivex/internal/operators/OperatorGroupBy.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -16,15 +16,16 @@ import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.*; -import java.util.function.Function; import org.reactivestreams.*; import io.reactivex.Observable.Operator; +import io.reactivex.functions.Function; import io.reactivex.internal.queue.SpscLinkedArrayQueue; import io.reactivex.internal.subscriptions.*; import io.reactivex.internal.util.BackpressureHelper; import io.reactivex.observables.GroupedObservable; +import io.reactivex.plugins.RxJavaPlugins; public final class OperatorGroupBy implements Operator, T>{ final Function keySelector; @@ -41,10 +42,12 @@ public OperatorGroupBy(Function keySelector, Function apply(Subscriber> t) { - return new GroupBySubscriber<>(t, keySelector, valueSelector, bufferSize, delayError); + return new GroupBySubscriber(t, keySelector, valueSelector, bufferSize, delayError); } - public static final class GroupBySubscriber extends AtomicInteger implements Subscriber, Subscription { + public static final class GroupBySubscriber + extends AtomicInteger + implements Subscriber, Subscription { /** */ private static final long serialVersionUID = -3688291656102519502L; @@ -54,24 +57,29 @@ public static final class GroupBySubscriber extends AtomicInteger imple final int bufferSize; final boolean delayError; final Map> groups; + final Queue> queue; static final Object NULL_KEY = new Object(); Subscription s; - volatile int cancelled; - @SuppressWarnings("rawtypes") - static final AtomicIntegerFieldUpdater CANCELLED = - AtomicIntegerFieldUpdater.newUpdater(GroupBySubscriber.class, "cancelled"); + final AtomicBoolean cancelled = new AtomicBoolean(); + final AtomicLong requested = new AtomicLong(); + + final AtomicInteger groupCount = new AtomicInteger(1); + + Throwable error; + volatile boolean done; + public GroupBySubscriber(Subscriber> actual, Function keySelector, Function valueSelector, int bufferSize, boolean delayError) { this.actual = actual; this.keySelector = keySelector; this.valueSelector = valueSelector; this.bufferSize = bufferSize; this.delayError = delayError; - this.groups = new ConcurrentHashMap<>(); - this.lazySet(1); + this.groups = new ConcurrentHashMap>(); + this.queue = new SpscLinkedArrayQueue>(bufferSize); } @Override @@ -82,16 +90,24 @@ public void onSubscribe(Subscription s) { this.s = s; actual.onSubscribe(this); + s.request(bufferSize); } @Override public void onNext(T t) { + if (done) { + return; + } + + final Queue> q = this.queue; + final Subscriber> a = this.actual; + K key; try { key = keySelector.apply(t); - } catch (Throwable e) { + } catch (Throwable ex) { s.cancel(); - onError(e); + errorAll(a, q, ex); return; } @@ -101,71 +117,80 @@ public void onNext(T t) { if (group == null) { // if the main has been cancelled, stop creating groups // and skip this value - if (cancelled != 0) { - s.request(1); + if (!cancelled.get()) { + group = GroupedUnicast.createWith(key, bufferSize, this, delayError); + groups.put(mapKey, group); + + groupCount.getAndIncrement(); + + notNew = false; + q.offer(group); + drain(); + } else { return; } - notNew = true; - - group = GroupedUnicast.createWith(key, bufferSize, this, delayError); - groups.put(mapKey, group); - - getAndIncrement(); - - actual.onNext(group); } V v; try { v = valueSelector.apply(t); - } catch (Throwable e) { + } catch (Throwable ex) { + s.cancel(); + errorAll(a, q, ex); + return; + } + + if (v == null) { s.cancel(); - onError(e); + errorAll(a, q, new NullPointerException("The valueSelector returned null")); return; } group.onNext(v); - + if (notNew) { - s.request(1); // we spent this t on an existing group, request one more + s.request(1); } } @Override public void onError(Throwable t) { - List> list = new ArrayList<>(groups.values()); - groups.clear(); - - for (GroupedUnicast e : list) { - e.onError(t); + if (done) { + RxJavaPlugins.onError(t); + return; } - - actual.onError(t); + error = t; + done = true; + groupCount.decrementAndGet(); + drain(); } @Override public void onComplete() { - List> list = new ArrayList<>(groups.values()); - groups.clear(); - - for (GroupedUnicast e : list) { - e.onComplete(); + if (done) { + return; } - - actual.onComplete(); + done = true; + groupCount.decrementAndGet(); + drain(); } @Override public void request(long n) { - s.request(n); + if (SubscriptionHelper.validateRequest(n)) { + return; + } + + BackpressureHelper.add(requested, n); + drain(); } @Override public void cancel() { // cancelling the main source means we don't want any more groups // but running groups still require new values - if (CANCELLED.compareAndSet(this, 0, 1)) { - if (decrementAndGet() == 0) { + if (cancelled.compareAndSet(false, true)) { + if (groupCount.decrementAndGet() == 0) { s.cancel(); } } @@ -174,17 +199,107 @@ public void cancel() { public void cancel(K key) { Object mapKey = key != null ? key : NULL_KEY; groups.remove(mapKey); - if (decrementAndGet() == 0) { + if (groupCount.decrementAndGet() == 0) { s.cancel(); } } + + void drain() { + if (getAndIncrement() != 0) { + return; + } + + int missed = 1; + + final Queue> q = this.queue; + final Subscriber> a = this.actual; + + for (;;) { + + if (checkTerminated(done, q.isEmpty(), a, q)) { + return; + } + + long r = requested.get(); + boolean unbounded = r == Long.MAX_VALUE; + long e = 0L; + + while (r != 0) { + boolean d = done; + + GroupedObservable t = q.poll(); + + boolean empty = t == null; + + if (checkTerminated(d, empty, a, q)) { + return; + } + + if (empty) { + break; + } + + a.onNext(t); + + r--; + e--; + } + + if (e != 0L) { + if (!unbounded) { + requested.addAndGet(e); + } + s.request(-e); + } + + missed = addAndGet(-missed); + if (missed == 0) { + break; + } + } + } + + void errorAll(Subscriber> a, Queue q, Throwable ex) { + q.clear(); + List> list = new ArrayList>(groups.values()); + groups.clear(); + + for (GroupedUnicast e : list) { + e.onError(ex); + } + + a.onError(ex); + } + + boolean checkTerminated(boolean d, boolean empty, + Subscriber> a, Queue q) { + if (d) { + Throwable err = error; + if (err != null) { + errorAll(a, q, err); + return true; + } else + if (empty) { + List> list = new ArrayList>(groups.values()); + groups.clear(); + + for (GroupedUnicast e : list) { + e.onComplete(); + } + + actual.onComplete(); + return true; + } + } + return false; + } } static final class GroupedUnicast extends GroupedObservable { public static GroupedUnicast createWith(K key, int bufferSize, GroupBySubscriber parent, boolean delayError) { - State state = new State<>(bufferSize, parent, key, delayError); - return new GroupedUnicast<>(key, state); + State state = new State(bufferSize, parent, key, delayError); + return new GroupedUnicast(key, state); } final State state; @@ -216,26 +331,19 @@ static final class State extends AtomicInteger implements Subscription, Pu final GroupBySubscriber parent; final boolean delayError; - volatile long requested; - @SuppressWarnings("rawtypes") - static final AtomicLongFieldUpdater REQUESTED = - AtomicLongFieldUpdater.newUpdater(State.class, "requested"); + final AtomicLong requested = new AtomicLong(); volatile boolean done; Throwable error; - volatile int cancelled; - @SuppressWarnings("rawtypes") - static final AtomicIntegerFieldUpdater CANCELLED = - AtomicIntegerFieldUpdater.newUpdater(State.class, "cancelled"); - - volatile Subscriber actual; - @SuppressWarnings("rawtypes") - static final AtomicReferenceFieldUpdater ACTUAL = - AtomicReferenceFieldUpdater.newUpdater(State.class, Subscriber.class, "actual"); + final AtomicBoolean cancelled = new AtomicBoolean(); + final AtomicReference> actual = new AtomicReference>(); + + final AtomicBoolean once = new AtomicBoolean(); + public State(int bufferSize, GroupBySubscriber parent, K key, boolean delayError) { - this.queue = new SpscLinkedArrayQueue<>(bufferSize); + this.queue = new SpscLinkedArrayQueue(bufferSize); this.parent = parent; this.key = key; this.delayError = delayError; @@ -246,14 +354,13 @@ public void request(long n) { if (SubscriptionHelper.validateRequest(n)) { return; } - BackpressureHelper.add(REQUESTED, this, n); - parent.request(n); + BackpressureHelper.add(requested, n); drain(); } @Override public void cancel() { - if (CANCELLED.compareAndSet(this, 0, 1)) { + if (cancelled.compareAndSet(false, true)) { if (getAndIncrement() == 0) { parent.cancel(key); } @@ -262,8 +369,10 @@ public void cancel() { @Override public void subscribe(Subscriber s) { - if (ACTUAL.compareAndSet(this, null, s)) { + if (once.compareAndSet(false, true)) { s.onSubscribe(this); + actual.lazySet(s); + drain(); } else { EmptySubscription.error(new IllegalStateException("Only one Subscriber allowed!"), s); } @@ -298,14 +407,14 @@ void drain() { final Queue q = queue; final boolean delayError = this.delayError; - Subscriber a = actual; + Subscriber a = actual.get(); for (;;) { if (a != null) { if (checkTerminated(done, q.isEmpty(), a, delayError)) { return; } - long r = requested; + long r = requested.get(); boolean unbounded = r == Long.MAX_VALUE; long e = 0; @@ -330,8 +439,9 @@ void drain() { if (e != 0L) { if (!unbounded) { - REQUESTED.addAndGet(this, e); + requested.addAndGet(e); } + parent.s.request(-e); } } @@ -340,13 +450,13 @@ void drain() { break; } if (a == null) { - a = actual; + a = actual.get(); } } } boolean checkTerminated(boolean d, boolean empty, Subscriber a, boolean delayError) { - if (cancelled != 0) { + if (cancelled.get()) { queue.clear(); parent.cancel(key); return true; @@ -380,4 +490,4 @@ boolean checkTerminated(boolean d, boolean empty, Subscriber a, boole return false; } } -} +} \ No newline at end of file diff --git a/src/main/java/io/reactivex/internal/operators/OperatorIgnoreElements.java b/src/main/java/io/reactivex/internal/operators/OperatorIgnoreElements.java index 366937283a..04acb4d4de 100644 --- a/src/main/java/io/reactivex/internal/operators/OperatorIgnoreElements.java +++ b/src/main/java/io/reactivex/internal/operators/OperatorIgnoreElements.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -25,7 +25,7 @@ public static Operator instance() { } @Override - public Subscriber apply(Subscriber t) { + public Subscriber apply(final Subscriber t) { return new Subscriber() { @Override public void onSubscribe(Subscription s) { diff --git a/src/main/java/io/reactivex/internal/operators/OperatorMap.java b/src/main/java/io/reactivex/internal/operators/OperatorMap.java index 6b8862621e..a0bbe1dd9a 100644 --- a/src/main/java/io/reactivex/internal/operators/OperatorMap.java +++ b/src/main/java/io/reactivex/internal/operators/OperatorMap.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -14,17 +14,13 @@ package io.reactivex.internal.operators; -import java.util.function.Function; - import org.reactivestreams.*; import io.reactivex.Observable.Operator; +import io.reactivex.functions.Function; import io.reactivex.internal.subscriptions.SubscriptionHelper; import io.reactivex.plugins.RxJavaPlugins; -/** - * - */ public final class OperatorMap implements Operator { final Function function; public OperatorMap(Function function) { @@ -33,7 +29,7 @@ public OperatorMap(Function function) { @Override public Subscriber apply(Subscriber t) { - return new MapperSubscriber<>(t, function); + return new MapperSubscriber(t, function); } static final class MapperSubscriber implements Subscriber { diff --git a/src/main/java/io/reactivex/internal/operators/OperatorMapNotification.java b/src/main/java/io/reactivex/internal/operators/OperatorMapNotification.java index 6460540134..a498636f6a 100644 --- a/src/main/java/io/reactivex/internal/operators/OperatorMapNotification.java +++ b/src/main/java/io/reactivex/internal/operators/OperatorMapNotification.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -14,11 +14,11 @@ package io.reactivex.internal.operators; import java.util.concurrent.atomic.*; -import java.util.function.*; import org.reactivestreams.*; import io.reactivex.Observable.Operator; +import io.reactivex.functions.*; import io.reactivex.internal.subscriptions.SubscriptionHelper; import io.reactivex.internal.util.BackpressureHelper; @@ -38,7 +38,7 @@ public OperatorMapNotification(Function apply(Subscriber> t) { - return new MapNotificationSubscriber<>(t, onNextMapper, onErrorMapper, onCompleteSupplier); + return new MapNotificationSubscriber(t, onNextMapper, onErrorMapper, onCompleteSupplier); } static final class MapNotificationSubscriber @@ -58,10 +58,7 @@ static final class MapNotificationSubscriber volatile boolean done; - volatile int state; - @SuppressWarnings("rawtypes") - static final AtomicIntegerFieldUpdater STATE = - AtomicIntegerFieldUpdater.newUpdater(MapNotificationSubscriber.class, "state"); + final AtomicInteger state = new AtomicInteger(); static final int NO_REQUEST_NO_VALUE = 0; static final int NO_REQUEST_HAS_VALUE = 1; @@ -157,9 +154,9 @@ void tryEmit(Publisher p) { actual.onComplete(); } else { for (;;) { - int s = state; + int s = state.get(); if (s == HAS_REQUEST_NO_VALUE) { - if (STATE.compareAndSet(this, HAS_REQUEST_NO_VALUE, HAS_REQUEST_HAS_VALUE)) { + if (state.compareAndSet(HAS_REQUEST_NO_VALUE, HAS_REQUEST_HAS_VALUE)) { actual.onNext(p); actual.onComplete(); } @@ -168,7 +165,7 @@ void tryEmit(Publisher p) { if (s == NO_REQUEST_NO_VALUE) { value = p; done = true; - if (STATE.compareAndSet(this, NO_REQUEST_NO_VALUE, NO_REQUEST_HAS_VALUE)) { + if (state.compareAndSet(NO_REQUEST_NO_VALUE, NO_REQUEST_HAS_VALUE)) { return; } } else @@ -188,13 +185,13 @@ public void request(long n) { BackpressureHelper.add(this, n); if (done) { for (;;) { - int s = state; + int s = state.get(); if (s == HAS_REQUEST_NO_VALUE || s == HAS_REQUEST_HAS_VALUE) { return; } else if (s == NO_REQUEST_HAS_VALUE) { - if (STATE.compareAndSet(this, NO_REQUEST_HAS_VALUE, HAS_REQUEST_HAS_VALUE)) { + if (state.compareAndSet(NO_REQUEST_HAS_VALUE, HAS_REQUEST_HAS_VALUE)) { Publisher p = value; value = null; actual.onNext(p); @@ -202,7 +199,7 @@ public void request(long n) { } return; } else - if (STATE.compareAndSet(this, NO_REQUEST_NO_VALUE, HAS_REQUEST_NO_VALUE)) { + if (state.compareAndSet(NO_REQUEST_NO_VALUE, HAS_REQUEST_NO_VALUE)) { return; } } @@ -213,7 +210,7 @@ public void request(long n) { @Override public void cancel() { - STATE.lazySet(this, HAS_REQUEST_HAS_VALUE); + state.lazySet(HAS_REQUEST_HAS_VALUE); s.cancel(); } } diff --git a/src/main/java/io/reactivex/internal/operators/OperatorMaterialize.java b/src/main/java/io/reactivex/internal/operators/OperatorMaterialize.java index 2663c55ed1..f9a4ea9e73 100644 --- a/src/main/java/io/reactivex/internal/operators/OperatorMaterialize.java +++ b/src/main/java/io/reactivex/internal/operators/OperatorMaterialize.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,7 +13,6 @@ package io.reactivex.internal.operators; -import java.util.Optional; import java.util.concurrent.atomic.*; import org.reactivestreams.*; @@ -33,7 +32,7 @@ public static Operator>, T> instance() { @Override public Subscriber apply(Subscriber>> t) { - return new MaterializeSubscriber<>(t); + return new MaterializeSubscriber(t); } static final class MaterializeSubscriber extends AtomicLong implements Subscriber, Subscription { @@ -43,10 +42,8 @@ static final class MaterializeSubscriber extends AtomicLong implements Subscr Subscription s; - volatile int state; - @SuppressWarnings("rawtypes") - static final AtomicIntegerFieldUpdater STATE = - AtomicIntegerFieldUpdater.newUpdater(MaterializeSubscriber.class, "state"); + final AtomicInteger state = new AtomicInteger(); + Try> value; volatile boolean done; @@ -80,14 +77,14 @@ public void onNext(T t) { void tryEmit(Try> v) { if (get() != 0L) { - STATE.lazySet(this, HAS_REQUEST_HAS_VALUE); + state.lazySet(HAS_REQUEST_HAS_VALUE); actual.onNext(v); actual.onComplete(); } else { for (;;) { - int s = state; + int s = state.get(); if (s == HAS_REQUEST_NO_VALUE) { - if (STATE.compareAndSet(this, s, HAS_REQUEST_HAS_VALUE)) { + if (state.compareAndSet(s, HAS_REQUEST_HAS_VALUE)) { actual.onNext(v); actual.onComplete(); return; @@ -102,7 +99,7 @@ void tryEmit(Try> v) { } else { value = v; done = true; - if (STATE.compareAndSet(this, s, NO_REQUEST_HAS_VALUE)) { + if (state.compareAndSet(s, NO_REQUEST_HAS_VALUE)) { return; } } @@ -132,9 +129,9 @@ public void request(long n) { BackpressureHelper.add(this, n); if (done) { for (;;) { - int s = state; + int s = state.get(); if (s == NO_REQUEST_HAS_VALUE) { - if (STATE.compareAndSet(this, s, HAS_REQUEST_HAS_VALUE)) { + if (state.compareAndSet(s, HAS_REQUEST_HAS_VALUE)) { Try> v = value; value = null; actual.onNext(v); @@ -145,7 +142,7 @@ public void request(long n) { if (s == HAS_REQUEST_NO_VALUE || s == HAS_REQUEST_HAS_VALUE) { return; } else - if (STATE.compareAndSet(this, s, HAS_REQUEST_NO_VALUE)) { + if (state.compareAndSet(s, HAS_REQUEST_NO_VALUE)) { return; } } @@ -156,7 +153,7 @@ public void request(long n) { @Override public void cancel() { - STATE.lazySet(this, HAS_REQUEST_HAS_VALUE); + state.lazySet(HAS_REQUEST_HAS_VALUE); s.cancel(); } } diff --git a/src/main/java/io/reactivex/internal/operators/OperatorObserveOn.java b/src/main/java/io/reactivex/internal/operators/OperatorObserveOn.java index f8951fd462..e423293546 100644 --- a/src/main/java/io/reactivex/internal/operators/OperatorObserveOn.java +++ b/src/main/java/io/reactivex/internal/operators/OperatorObserveOn.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -18,8 +18,8 @@ import org.reactivestreams.*; -import io.reactivex.Observable.Operator; import io.reactivex.Scheduler; +import io.reactivex.Observable.Operator; import io.reactivex.exceptions.MissingBackpressureException; import io.reactivex.internal.queue.*; import io.reactivex.internal.schedulers.TrampolineScheduler; @@ -45,7 +45,7 @@ public Subscriber apply(Subscriber t) { Scheduler.Worker w = scheduler.createWorker(); - return new ObserveOnSubscriber<>(t, w, delayError, bufferSize); + return new ObserveOnSubscriber(t, w, delayError, bufferSize); } /** @@ -65,10 +65,7 @@ static class Padding1 extends Padding0 { /** */ private static final long serialVersionUID = 7659422588548271214L; - volatile long requested; - static final AtomicLongFieldUpdater REQUESTED = - AtomicLongFieldUpdater.newUpdater(Padding1.class, "requested"); - + final AtomicLong requested = new AtomicLong(); } /** @@ -103,9 +100,9 @@ public ObserveOnSubscriber(Subscriber actual, Scheduler.Worker worker this.bufferSize = bufferSize; Queue q; if (Pow2.isPowerOfTwo(bufferSize)) { - q = new SpscArrayQueue<>(bufferSize); + q = new SpscArrayQueue(bufferSize); } else { - q = new SpscExactArrayQueue<>(bufferSize); + q = new SpscExactArrayQueue(bufferSize); } this.queue = q; } @@ -159,7 +156,7 @@ public void request(long n) { if (SubscriptionHelper.validateRequest(n)) { return; } - BackpressureHelper.add(REQUESTED, this, n); + BackpressureHelper.add(requested, n); schedule(); } @@ -190,7 +187,7 @@ public void run() { return; } - long r = requested; + long r = requested.get(); long e = 0L; boolean unbounded = r == Long.MAX_VALUE; @@ -218,7 +215,7 @@ public void run() { } if (e != 0L) { if (!unbounded) { - REQUESTED.addAndGet(this, -e); + requested.addAndGet(-e); } s.request(e); } diff --git a/src/main/java/io/reactivex/internal/operators/OperatorOnBackpressureBuffer.java b/src/main/java/io/reactivex/internal/operators/OperatorOnBackpressureBuffer.java index 1822840dba..b09c65fc76 100644 --- a/src/main/java/io/reactivex/internal/operators/OperatorOnBackpressureBuffer.java +++ b/src/main/java/io/reactivex/internal/operators/OperatorOnBackpressureBuffer.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -39,7 +39,7 @@ public OperatorOnBackpressureBuffer(int bufferSize, boolean unbounded, boolean d @Override public Subscriber apply(Subscriber t) { - return new BackpressureBufferSubscriber<>(t, bufferSize, unbounded, delayError, onOverflow); + return new BackpressureBufferSubscriber(t, bufferSize, unbounded, delayError, onOverflow); } static final class BackpressureBufferSubscriber extends AtomicInteger implements Subscriber, Subscription { @@ -57,10 +57,7 @@ static final class BackpressureBufferSubscriber extends AtomicInteger impleme volatile boolean done; Throwable error; - volatile long requested; - @SuppressWarnings("rawtypes") - static final AtomicLongFieldUpdater REQUESTED = - AtomicLongFieldUpdater.newUpdater(BackpressureBufferSubscriber.class, "requested"); + final AtomicLong requested = new AtomicLong(); public BackpressureBufferSubscriber(Subscriber actual, int bufferSize, boolean unbounded, boolean delayError, Runnable onOverflow) { @@ -71,12 +68,12 @@ public BackpressureBufferSubscriber(Subscriber actual, int bufferSize Queue q; if (unbounded) { - q = new SpscLinkedArrayQueue<>(bufferSize); + q = new SpscLinkedArrayQueue(bufferSize); } else { if (Pow2.isPowerOfTwo(bufferSize)) { - q = new SpscArrayQueue<>(bufferSize); + q = new SpscArrayQueue(bufferSize); } else { - q = new SpscExactArrayQueue<>(bufferSize); + q = new SpscExactArrayQueue(bufferSize); } } @@ -101,7 +98,7 @@ public void onNext(T t) { try { onOverflow.run(); } catch (Throwable e) { - ex.addSuppressed(e); + ex.initCause(e); } onError(ex); return; @@ -127,7 +124,7 @@ public void request(long n) { if (SubscriptionHelper.validateRequest(n)) { return; } - BackpressureHelper.add(REQUESTED, this, n); + BackpressureHelper.add(requested, n); drain(); } @@ -154,7 +151,7 @@ void drain() { return; } - long r = requested; + long r = requested.get(); boolean unbounded = r == Long.MAX_VALUE; long e = 0L; @@ -180,7 +177,7 @@ void drain() { if (e != 0L) { if (!unbounded) { - REQUESTED.addAndGet(this, e); + requested.addAndGet(e); } } diff --git a/src/main/java/io/reactivex/internal/operators/OperatorOnBackpressureDrop.java b/src/main/java/io/reactivex/internal/operators/OperatorOnBackpressureDrop.java index 190b287f7b..114ea7e2f8 100644 --- a/src/main/java/io/reactivex/internal/operators/OperatorOnBackpressureDrop.java +++ b/src/main/java/io/reactivex/internal/operators/OperatorOnBackpressureDrop.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -14,18 +14,19 @@ package io.reactivex.internal.operators; import java.util.concurrent.atomic.AtomicLong; -import java.util.function.Consumer; import org.reactivestreams.*; import io.reactivex.Observable.Operator; +import io.reactivex.functions.Consumer; +import io.reactivex.internal.functions.Functions; import io.reactivex.internal.subscriptions.SubscriptionHelper; import io.reactivex.internal.util.BackpressureHelper; public final class OperatorOnBackpressureDrop implements Operator { private static final OperatorOnBackpressureDrop DEFAULT = - new OperatorOnBackpressureDrop<>(v -> { }); + new OperatorOnBackpressureDrop(Functions.emptyConsumer()); @SuppressWarnings("unchecked") public static OperatorOnBackpressureDrop instance() { @@ -40,7 +41,7 @@ public OperatorOnBackpressureDrop(Consumer onDrop) { @Override public Subscriber apply(Subscriber t) { - return new BackpressureDropSubscriber<>(t, onDrop); + return new BackpressureDropSubscriber(t, onDrop); } static final class BackpressureDropSubscriber extends AtomicLong implements Subscriber, Subscription { diff --git a/src/main/java/io/reactivex/internal/operators/OperatorOnBackpressureLatest.java b/src/main/java/io/reactivex/internal/operators/OperatorOnBackpressureLatest.java index 54eadc1193..60633e6509 100644 --- a/src/main/java/io/reactivex/internal/operators/OperatorOnBackpressureLatest.java +++ b/src/main/java/io/reactivex/internal/operators/OperatorOnBackpressureLatest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -47,15 +47,9 @@ static final class BackpressureLatestSubscriber extends AtomicInteger implements volatile boolean cancelled; - // TODO contended padding? - volatile long requested; - static final AtomicLongFieldUpdater REQUESTED = - AtomicLongFieldUpdater.newUpdater(BackpressureLatestSubscriber.class, "requested"); + final AtomicLong requested = new AtomicLong(); - // TODO contended padding? - volatile Object current; - static final AtomicReferenceFieldUpdater CURRENT = - AtomicReferenceFieldUpdater.newUpdater(BackpressureLatestSubscriber.class, Object.class, "current"); + final AtomicReference current = new AtomicReference(); public BackpressureLatestSubscriber(Subscriber actual) { this.actual = actual; @@ -75,7 +69,7 @@ public void onSubscribe(Subscription s) { @Override public void onNext(Object t) { - CURRENT.lazySet(this, t); + current.lazySet(t); drain(); } @@ -98,7 +92,7 @@ public void request(long n) { RxJavaPlugins.onError(new IllegalArgumentException("n > required but it was " + n)); return; } - BackpressureHelper.add(REQUESTED, this, n); + BackpressureHelper.add(requested, n); drain(); } @@ -108,7 +102,7 @@ public void cancel() { cancelled = true; if (getAndIncrement() == 0) { - CURRENT.lazySet(this, null); + current.lazySet(null); s.cancel(); } } @@ -122,15 +116,15 @@ void drain() { int missed = 1; for (;;) { - if (checkTerminated(done, current == null, a)) { + if (checkTerminated(done, current.get() == null, a)) { return; } - long r = requested; + long r = requested.get(); while (r != 0L) { boolean d = done; - Object v = CURRENT.getAndSet(this, null); + Object v = current.getAndSet(null); boolean empty = v == null; if (checkTerminated(d, empty, a)) { @@ -144,10 +138,15 @@ void drain() { a.onNext(v); if (r != Long.MAX_VALUE) { - REQUESTED.decrementAndGet(this); + r--; + requested.decrementAndGet(); } } - + + if (checkTerminated(done, current.get() == null, a)) { + return; + } + missed = addAndGet(-missed); if (missed == 0) { break; @@ -157,7 +156,7 @@ void drain() { boolean checkTerminated(boolean d, boolean empty, Subscriber a) { if (cancelled) { - CURRENT.lazySet(this, null); + current.lazySet(null); s.cancel(); return true; } @@ -165,7 +164,7 @@ boolean checkTerminated(boolean d, boolean empty, Subscriber a) if (d) { Throwable e = error; if (e != null) { - CURRENT.lazySet(this, null); + current.lazySet(null); a.onError(e); return true; } else diff --git a/src/main/java/io/reactivex/internal/operators/OperatorOnErrorNext.java b/src/main/java/io/reactivex/internal/operators/OperatorOnErrorNext.java index ec83f6e28a..f57ea7ca33 100644 --- a/src/main/java/io/reactivex/internal/operators/OperatorOnErrorNext.java +++ b/src/main/java/io/reactivex/internal/operators/OperatorOnErrorNext.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,11 +13,11 @@ package io.reactivex.internal.operators; -import java.util.function.*; - import org.reactivestreams.*; import io.reactivex.Observable.Operator; +import io.reactivex.exceptions.CompositeException; +import io.reactivex.functions.Function; import io.reactivex.internal.subscriptions.SubscriptionArbiter; import io.reactivex.plugins.RxJavaPlugins; @@ -32,7 +32,7 @@ public OperatorOnErrorNext(Function apply(Subscriber t) { - OnErrorNextSubscriber parent = new OnErrorNextSubscriber<>(t, nextSupplier, allowFatal); + OnErrorNextSubscriber parent = new OnErrorNextSubscriber(t, nextSupplier, allowFatal); t.onSubscribe(parent.arbiter); return parent; } @@ -92,15 +92,14 @@ public void onError(Throwable t) { try { p = nextSupplier.apply(t); } catch (Throwable e) { - t.addSuppressed(e); - actual.onError(t); + actual.onError(new CompositeException(e, t)); return; } if (p == null) { NullPointerException npe = new NullPointerException("Publisher is null"); - t.addSuppressed(npe); - actual.onError(t); + npe.initCause(t); + actual.onError(npe); return; } @@ -117,4 +116,4 @@ public void onComplete() { actual.onComplete(); } } -} +} \ No newline at end of file diff --git a/src/main/java/io/reactivex/internal/operators/OperatorOnErrorReturn.java b/src/main/java/io/reactivex/internal/operators/OperatorOnErrorReturn.java index 907deb8701..cf65874227 100644 --- a/src/main/java/io/reactivex/internal/operators/OperatorOnErrorReturn.java +++ b/src/main/java/io/reactivex/internal/operators/OperatorOnErrorReturn.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -14,11 +14,12 @@ package io.reactivex.internal.operators; import java.util.concurrent.atomic.*; -import java.util.function.Function; import org.reactivestreams.*; import io.reactivex.Observable.Operator; +import io.reactivex.exceptions.CompositeException; +import io.reactivex.functions.Function; import io.reactivex.internal.subscriptions.SubscriptionHelper; import io.reactivex.internal.util.BackpressureHelper; @@ -30,7 +31,7 @@ public OperatorOnErrorReturn(Function valueSuppl @Override public Subscriber apply(Subscriber t) { - return new OnErrorReturnSubscriber<>(t, valueSupplier); + return new OnErrorReturnSubscriber(t, valueSupplier); } static final class OnErrorReturnSubscriber extends AtomicLong implements Subscriber, Subscription { @@ -41,10 +42,8 @@ static final class OnErrorReturnSubscriber extends AtomicLong implements Subs Subscription s; - volatile int state; - @SuppressWarnings("rawtypes") - static final AtomicIntegerFieldUpdater STATE = - AtomicIntegerFieldUpdater.newUpdater(OnErrorReturnSubscriber.class, "state"); + final AtomicInteger state = new AtomicInteger(); + T value; volatile boolean done; @@ -84,28 +83,28 @@ public void onError(Throwable t) { try { v = valueSupplier.apply(t); } catch (Throwable e) { - STATE.lazySet(this, HAS_REQUEST_HAS_VALUE); - t.addSuppressed(e); - actual.onError(t); + state.lazySet(HAS_REQUEST_HAS_VALUE); + actual.onError(new CompositeException(e, t)); return; } if (v == null) { - STATE.lazySet(this, HAS_REQUEST_HAS_VALUE); - t.addSuppressed(new NullPointerException("The supplied value is null")); - actual.onError(t); + state.lazySet(HAS_REQUEST_HAS_VALUE); + NullPointerException npe = new NullPointerException("The supplied value is null"); + npe.initCause(t); + actual.onError(npe); return; } if (get() != 0L) { - STATE.lazySet(this, HAS_REQUEST_HAS_VALUE); + state.lazySet(HAS_REQUEST_HAS_VALUE); actual.onNext(v); actual.onComplete(); } else { for (;;) { - int s = state; + int s = state.get(); if (s == HAS_REQUEST_NO_VALUE) { - if (STATE.compareAndSet(this, s, HAS_REQUEST_HAS_VALUE)) { + if (state.compareAndSet(s, HAS_REQUEST_HAS_VALUE)) { actual.onNext(v); actual.onComplete(); return; @@ -119,7 +118,7 @@ public void onError(Throwable t) { return; } else { value = v; - if (STATE.compareAndSet(this, s, NO_REQUEST_HAS_VALUE)) { + if (state.compareAndSet(s, NO_REQUEST_HAS_VALUE)) { return; } } @@ -129,7 +128,7 @@ public void onError(Throwable t) { @Override public void onComplete() { - STATE.lazySet(this, HAS_REQUEST_HAS_VALUE); + state.lazySet(HAS_REQUEST_HAS_VALUE); actual.onComplete(); } @@ -141,9 +140,9 @@ public void request(long n) { BackpressureHelper.add(this, n); if (done) { for (;;) { - int s = state; + int s = state.get(); if (s == NO_REQUEST_HAS_VALUE) { - if (STATE.compareAndSet(this, s, HAS_REQUEST_HAS_VALUE)) { + if (state.compareAndSet(s, HAS_REQUEST_HAS_VALUE)) { T v = value; value = null; actual.onNext(v); @@ -154,7 +153,7 @@ public void request(long n) { if (s == HAS_REQUEST_NO_VALUE || s == HAS_REQUEST_HAS_VALUE) { return; } else - if (STATE.compareAndSet(this, s, HAS_REQUEST_NO_VALUE)) { + if (state.compareAndSet(s, HAS_REQUEST_NO_VALUE)) { return; } } @@ -165,8 +164,8 @@ public void request(long n) { @Override public void cancel() { - STATE.lazySet(this, HAS_REQUEST_HAS_VALUE); + state.lazySet(HAS_REQUEST_HAS_VALUE); s.cancel(); } } -} +} \ No newline at end of file diff --git a/src/main/java/io/reactivex/internal/operators/OperatorPublish.java b/src/main/java/io/reactivex/internal/operators/OperatorPublish.java index cbc0c22e3f..faf5645ec8 100644 --- a/src/main/java/io/reactivex/internal/operators/OperatorPublish.java +++ b/src/main/java/io/reactivex/internal/operators/OperatorPublish.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -15,12 +15,12 @@ import java.util.Queue; import java.util.concurrent.atomic.*; -import java.util.function.*; import org.reactivestreams.*; import io.reactivex.Observable; -import io.reactivex.disposables.Disposable; +import io.reactivex.disposables.*; +import io.reactivex.functions.*; import io.reactivex.internal.queue.SpscArrayQueue; import io.reactivex.internal.subscriptions.SubscriptionHelper; import io.reactivex.internal.util.NotificationLite; @@ -43,12 +43,14 @@ public final class OperatorPublish extends ConnectableObservable { /** * Creates a OperatorPublish instance to publish values of the given source observable. + * @param the source value type * @param source the source observable + * @param bufferSize the size of the prefetch buffer * @return the connectable observable */ - public static ConnectableObservable create(Observable source, int bufferSize) { + public static ConnectableObservable create(Observable source, final int bufferSize) { // the current connection to source needs to be shared between the operator and its onSubscribe call - final AtomicReference> curr = new AtomicReference<>(); + final AtomicReference> curr = new AtomicReference>(); Publisher onSubscribe = new Publisher() { @Override public void subscribe(Subscriber child) { @@ -60,7 +62,7 @@ public void subscribe(Subscriber child) { // if there isn't one or it is unsubscribed if (r == null || r.isDisposed()) { // create a new subscriber to source - PublishSubscriber u = new PublishSubscriber<>(curr, bufferSize); + PublishSubscriber u = new PublishSubscriber(curr, bufferSize); // let's try setting it as the current subscriber-to-source if (!curr.compareAndSet(r, u)) { // didn't work, maybe someone else did it or the current subscriber @@ -72,7 +74,7 @@ public void subscribe(Subscriber child) { } // create the backpressure-managing producer for this child - InnerProducer inner = new InnerProducer<>(r, child); + InnerProducer inner = new InnerProducer(r, child); /* * Try adding it to the current subscriber-to-source, add is atomic in respect * to other adds and the termination of the subscriber-to-source. @@ -113,19 +115,27 @@ public void subscribe(Subscriber child) { } } }; - return new OperatorPublish<>(onSubscribe, source, curr, bufferSize); + return new OperatorPublish(onSubscribe, source, curr, bufferSize); } public static Observable create(final Observable source, - final Function, ? extends Publisher> selector, int bufferSize) { - return create(sr -> { - ConnectableObservable op = create(source, bufferSize); - - SubscriberResourceWrapper srw = new SubscriberResourceWrapper<>(sr, Disposable::dispose); - - selector.apply(op).subscribe(srw); - - op.connect(srw::setResource); + final Function, ? extends Publisher> selector, final int bufferSize) { + return create(new Publisher() { + @Override + public void subscribe(Subscriber sr) { + ConnectableObservable op = create(source, bufferSize); + + final SubscriberResourceWrapper srw = new SubscriberResourceWrapper(sr, Disposables.consumeAndDispose()); + + selector.apply(op).subscribe(srw); + + op.connect(new Consumer() { + @Override + public void accept(Disposable r) { + srw.setResource(r); + } + }); + } }); } @@ -148,7 +158,7 @@ public void connect(Consumer connection) { // if there is none yet or the current has unsubscribed if (ps == null || ps.isDisposed()) { // create a new subscriber-to-source - PublishSubscriber u = new PublishSubscriber<>(current, bufferSize); + PublishSubscriber u = new PublishSubscriber(current, bufferSize); // try setting it as the current subscriber-to-source if (!current.compareAndSet(ps, u)) { // did not work, perhaps a new subscriber arrived @@ -210,9 +220,7 @@ static final class PublishSubscriber implements Subscriber, Disposable { /** Guarded by this. */ boolean missed; - volatile Subscription s; - static final AtomicReferenceFieldUpdater S = - AtomicReferenceFieldUpdater.newUpdater(PublishSubscriber.class, Subscription.class, "s"); + final AtomicReference s = new AtomicReference(); static final Subscription CANCELLED = new Subscription() { @Override @@ -227,9 +235,9 @@ public void cancel() { }; public PublishSubscriber(AtomicReference> current, int bufferSize) { - this.queue = new SpscArrayQueue<>(bufferSize); + this.queue = new SpscArrayQueue(bufferSize); - this.producers = new AtomicReference<>(EMPTY); + this.producers = new AtomicReference(EMPTY); this.current = current; this.shouldConnect = new AtomicBoolean(); this.bufferSize = bufferSize; @@ -242,9 +250,9 @@ public void dispose() { if (ps != TERMINATED) { current.compareAndSet(PublishSubscriber.this, null); - Subscription a = s; + Subscription a = s.get(); if (a != CANCELLED) { - a = S.getAndSet(this, CANCELLED); + a = s.getAndSet(CANCELLED); if (a != CANCELLED && a != null) { a.cancel(); } @@ -259,9 +267,9 @@ public boolean isDisposed() { @Override public void onSubscribe(Subscription s) { - if (!S.compareAndSet(this, null, s)) { + if (!this.s.compareAndSet(null, s)) { s.cancel(); - if (this.s != CANCELLED) { + if (this.s.get() != CANCELLED) { SubscriptionHelper.reportSubscriptionSet(); } return; @@ -549,7 +557,7 @@ void dispatch() { return; } // otherwise, just ask for a new value - s.request(1); + s.get().request(1); // and retry emitting to potential new child-subscribers continue; } @@ -597,7 +605,7 @@ void dispatch() { // if we did emit at least one element, request more to replenish the queue if (d > 0) { - s.request(d); + s.get().request(d); } // if we have requests but not an empty queue after emission // let's try again to see if more requests/child-subscribers are @@ -638,8 +646,6 @@ void dispatch() { /** * A Producer and Subscription that manages the request and unsubscription state of a * child subscriber in thread-safe manner. - * We use AtomicLong as a base class to save on extra allocation of an AtomicLong and also - * save the overhead of the AtomicIntegerFieldUpdater. * @param the value type */ static final class InnerProducer extends AtomicLong implements Subscription, Disposable { diff --git a/src/main/java/io/reactivex/internal/operators/OperatorReplay.java b/src/main/java/io/reactivex/internal/operators/OperatorReplay.java index d8724d360c..372bd90017 100644 --- a/src/main/java/io/reactivex/internal/operators/OperatorReplay.java +++ b/src/main/java/io/reactivex/internal/operators/OperatorReplay.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -16,13 +16,13 @@ import java.util.*; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.*; -import java.util.function.*; import org.reactivestreams.*; import io.reactivex.Observable; -import io.reactivex.Scheduler; -import io.reactivex.disposables.Disposable; +import io.reactivex.*; +import io.reactivex.disposables.*; +import io.reactivex.functions.*; import io.reactivex.internal.subscriptions.*; import io.reactivex.internal.util.*; import io.reactivex.observables.ConnectableObservable; @@ -38,43 +38,73 @@ public final class OperatorReplay extends ConnectableObservable { final Supplier> bufferFactory; @SuppressWarnings("rawtypes") - static final Supplier DEFAULT_UNBOUNDED_FACTORY = () -> new UnboundedReplayBuffer<>(16); + static final Supplier DEFAULT_UNBOUNDED_FACTORY = new Supplier() { + @Override + public Object get() { + return new UnboundedReplayBuffer(16); + } + }; /** * Given a connectable observable factory, it multicasts over the generated * ConnectableObservable via a selector function. + * @param the connectable observable type + * @param the result type * @param connectableFactory * @param selector - * @return + * @return the new Observable instance */ - public static Observable multicastSelector( + public static Observable multicastSelector( final Supplier> connectableFactory, final Function, ? extends Publisher> selector) { - return Observable.create(child -> { - ConnectableObservable co; - Publisher observable; - try { - co = connectableFactory.get(); - observable = selector.apply(co); - } catch (Throwable e) { - EmptySubscription.error(e, child); - return; + return Observable.create(new Publisher() { + @Override + public void subscribe(Subscriber child) { + ConnectableObservable co; + Publisher observable; + try { + co = connectableFactory.get(); + } catch (Throwable e) { + EmptySubscription.error(e, child); + return; + } + if (co == null) { + EmptySubscription.error(new NullPointerException("The connectableFactory returned null"), child); + return; + } + + try { + observable = selector.apply(co); + } catch (Throwable e) { + EmptySubscription.error(e, child); + return; + } + if (observable == null) { + EmptySubscription.error(new NullPointerException("The selector returned a null Publisher"), child); + return; + } + + final SubscriberResourceWrapper srw = new SubscriberResourceWrapper(child, Disposables.consumeAndDispose()); + + observable.subscribe(srw); + + co.connect(new Consumer() { + @Override + public void accept(Disposable r) { + srw.setResource(r); + } + }); } - - SubscriberResourceWrapper srw = new SubscriberResourceWrapper<>(child, Disposable::dispose); - - observable.subscribe(srw); - - co.connect(srw::setResource); }); } /** * Child Subscribers will observe the events of the ConnectableObservable on the * specified scheduler. + * @param the value type * @param co * @param scheduler - * @return + * @return the new ConnectableObservable instance */ public static ConnectableObservable observeOn(final ConnectableObservable co, final Scheduler scheduler) { final Observable observable = co.observeOn(scheduler); @@ -88,10 +118,10 @@ public void connect(Consumer connection) { /** * Creates a replaying ConnectableObservable with an unbounded buffer. + * @param the value type * @param source - * @return + * @return the new ConnectableObservable instance */ - // TODO javac 1.8 fails with ambiguity error if this method is called create(), works properly @SuppressWarnings("unchecked") public static ConnectableObservable createFrom(Observable source) { return create(source, DEFAULT_UNBOUNDED_FACTORY); @@ -99,25 +129,32 @@ public static ConnectableObservable createFrom(Observable so /** * Creates a replaying ConnectableObservable with a size bound buffer. + * @param the value type * @param source * @param bufferSize - * @return + * @return the new ConnectableObservable instance */ public static ConnectableObservable create(Observable source, final int bufferSize) { if (bufferSize == Integer.MAX_VALUE) { return createFrom(source); } - return create(source, () -> new SizeBoundReplayBuffer<>(bufferSize)); + return create(source, new Supplier>() { + @Override + public ReplayBuffer get() { + return new SizeBoundReplayBuffer(bufferSize); + } + }); } /** * Creates a replaying ConnectableObservable with a time bound buffer. + * @param the value type * @param source * @param maxAge * @param unit * @param scheduler - * @return + * @return the new ConnectableObservable instance */ public static ConnectableObservable create(Observable source, long maxAge, TimeUnit unit, Scheduler scheduler) { @@ -126,16 +163,22 @@ public static ConnectableObservable create(Observable source /** * Creates a replaying ConnectableObservable with a size and time bound buffer. + * @param the value type * @param source * @param maxAge * @param unit * @param scheduler * @param bufferSize - * @return + * @return the new NbpConnectableObservable instance */ public static ConnectableObservable create(Observable source, - long maxAge, TimeUnit unit, final Scheduler scheduler, final int bufferSize) { - return create(source, () -> new SizeAndTimeBoundReplayBuffer<>(bufferSize, maxAge, unit, scheduler)); + final long maxAge, final TimeUnit unit, final Scheduler scheduler, final int bufferSize) { + return create(source, new Supplier>() { + @Override + public ReplayBuffer get() { + return new SizeAndTimeBoundReplayBuffer(bufferSize, maxAge, unit, scheduler); + } + }); } /** @@ -147,7 +190,7 @@ public static ConnectableObservable create(Observable source static ConnectableObservable create(Observable source, final Supplier> bufferFactory) { // the current connection to source needs to be shared between the operator and its onSubscribe call - final AtomicReference> curr = new AtomicReference<>(); + final AtomicReference> curr = new AtomicReference>(); Publisher onSubscribe = new Publisher() { @Override public void subscribe(Subscriber child) { @@ -159,7 +202,7 @@ public void subscribe(Subscriber child) { // if there isn't one if (r == null) { // create a new subscriber to source - ReplaySubscriber u = new ReplaySubscriber<>(curr, bufferFactory.get()); + ReplaySubscriber u = new ReplaySubscriber(curr, bufferFactory.get()); // let's try setting it as the current subscriber-to-source if (!curr.compareAndSet(r, u)) { // didn't work, maybe someone else did it or the current subscriber @@ -171,11 +214,13 @@ public void subscribe(Subscriber child) { } // create the backpressure-managing producer for this child - InnerSubscription inner = new InnerSubscription<>(r, child); + InnerSubscription inner = new InnerSubscription(r, child); // we try to add it to the array of producers // if it fails, no worries because we will still have its buffer // so it is going to replay it for us r.add(inner); + // trigger the capturing of the current node and total requested + r.buffer.replay(inner); // the producer has been registered with the current subscriber-to-source so // at least it will receive the next terminal event // setting the producer will trigger the first request to be considered by @@ -185,7 +230,7 @@ public void subscribe(Subscriber child) { } } }; - return new OperatorReplay<>(onSubscribe, source, curr, bufferFactory); + return new OperatorReplay(onSubscribe, source, curr, bufferFactory); } private OperatorReplay(Publisher onSubscribe, Observable source, final AtomicReference> current, @@ -207,7 +252,7 @@ public void connect(Consumer connection) { // if there is none yet or the current has unsubscribed if (ps == null || ps.isDisposed()) { // create a new subscriber-to-source - ReplaySubscriber u = new ReplaySubscriber<>(current, bufferFactory.get()); + ReplaySubscriber u = new ReplaySubscriber(current, bufferFactory.get()); // try setting it as the current subscriber-to-source if (!current.compareAndSet(ps, u)) { // did not work, perhaps a new subscriber arrived @@ -280,7 +325,7 @@ public ReplaySubscriber(AtomicReference> current, ReplayBuffer buffer) { this.buffer = buffer; - this.producers = new AtomicReference<>(EMPTY); + this.producers = new AtomicReference(EMPTY); this.shouldConnect = new AtomicBoolean(); } @@ -514,8 +559,6 @@ void replay() { /** * A Producer and Subscription that manages the request and unsubscription state of a * child subscriber in thread-safe manner. - * We use AtomicLong as a base class to save on extra allocation of an AtomicLong and also - * save the overhead of the AtomicIntegerFieldUpdater. * @param the value type */ static final class InnerSubscription extends AtomicLong implements Subscription, Disposable { @@ -790,15 +833,15 @@ public void replay(InnerSubscription output) { /** * Represents a node in a bounded replay buffer's linked list. - * - * @param the contained value type */ static final class Node extends AtomicReference { /** */ private static final long serialVersionUID = 245354315435971818L; final Object value; - public Node(Object value) { + final long index; + public Node(Object value, long index) { this.value = value; + this.index = index; } } @@ -815,8 +858,10 @@ static class BoundedReplayBuffer extends AtomicReference implements Rep Node tail; int size; + long index; + public BoundedReplayBuffer() { - Node n = new Node(null); + Node n = new Node(null, 0); tail = n; set(n); } @@ -865,7 +910,7 @@ final void setFirst(Node n) { @Override public final void next(T value) { Object o = enterTransform(NotificationLite.next(value)); - Node n = new Node(o); + Node n = new Node(o, ++index); addLast(n); truncate(); } @@ -873,7 +918,7 @@ public final void next(T value) { @Override public final void error(Throwable e) { Object o = enterTransform(NotificationLite.error(e)); - Node n = new Node(o); + Node n = new Node(o, ++index); addLast(n); truncateFinal(); } @@ -881,7 +926,7 @@ public final void error(Throwable e) { @Override public final void complete() { Object o = enterTransform(NotificationLite.complete()); - Node n = new Node(o); + Node n = new Node(o, ++index); addLast(n); truncateFinal(); } @@ -901,13 +946,15 @@ public final void replay(InnerSubscription output) { } long r = output.get(); - long r0 = r; + boolean unbounded = r == Long.MAX_VALUE; long e = 0L; Node node = output.index(); if (node == null) { node = get(); output.index = node; + + BackpressureHelper.add(output.totalRequested, node.index); } while (r != 0) { @@ -928,6 +975,7 @@ public final void replay(InnerSubscription output) { return; } e++; + r--; node = v; } else { break; @@ -939,7 +987,7 @@ public final void replay(InnerSubscription output) { if (e != 0L) { output.index = node; - if (r0 != Long.MAX_VALUE) { + if (!unbounded) { output.produced(e); } } @@ -997,7 +1045,7 @@ void truncateFinal() { if (NotificationLite.isComplete(v) || NotificationLite.isError(v)) { break; } - output.add(NotificationLite.getValue(v)); + output.add(NotificationLite.getValue(v)); n = next; } else { break; @@ -1058,7 +1106,7 @@ public SizeAndTimeBoundReplayBuffer(int limit, long maxAge, TimeUnit unit, Sched @Override Object enterTransform(Object value) { - return new Timed<>(value, scheduler.now(unit), unit); + return new Timed(value, scheduler.now(unit), unit); } @Override diff --git a/src/main/java/io/reactivex/internal/operators/OperatorSamplePublisher.java b/src/main/java/io/reactivex/internal/operators/OperatorSamplePublisher.java index bdd7ae9dc1..00d4426865 100644 --- a/src/main/java/io/reactivex/internal/operators/OperatorSamplePublisher.java +++ b/src/main/java/io/reactivex/internal/operators/OperatorSamplePublisher.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -32,8 +32,8 @@ public OperatorSamplePublisher(Publisher other) { @Override public Subscriber apply(Subscriber t) { - SerializedSubscriber serial = new SerializedSubscriber<>(t); - return new SamplePublisherSubscriber<>(serial, other); + SerializedSubscriber serial = new SerializedSubscriber(t); + return new SamplePublisherSubscriber(serial, other); } static final class SamplePublisherSubscriber extends AtomicReference implements Subscriber, Subscription { @@ -43,15 +43,9 @@ static final class SamplePublisherSubscriber extends AtomicReference imple final Subscriber actual; final Publisher sampler; - volatile long requested; - @SuppressWarnings("rawtypes") - static final AtomicLongFieldUpdater REQUESTED = - AtomicLongFieldUpdater.newUpdater(SamplePublisherSubscriber.class, "requested"); + final AtomicLong requested = new AtomicLong(); - volatile Subscription other; - @SuppressWarnings("rawtypes") - static final AtomicReferenceFieldUpdater OTHER = - AtomicReferenceFieldUpdater.newUpdater(SamplePublisherSubscriber.class, Subscription.class, "other"); + final AtomicReference other = new AtomicReference(); static final Subscription CANCELLED = new Subscription() { @Override @@ -80,8 +74,8 @@ public void onSubscribe(Subscription s) { this.s = s; actual.onSubscribe(this); - if (other == null) { - sampler.subscribe(new SamplerSubscriber<>(this)); + if (other.get() == null) { + sampler.subscribe(new SamplerSubscriber(this)); s.request(Long.MAX_VALUE); } @@ -105,9 +99,9 @@ public void onComplete() { } void cancelOther() { - Subscription o = other; + Subscription o = other.get(); if (o != CANCELLED) { - o = OTHER.getAndSet(this, CANCELLED); + o = other.getAndSet(CANCELLED); if (o != CANCELLED && o != null) { o.cancel(); } @@ -115,8 +109,8 @@ void cancelOther() { } boolean setOther(Subscription o) { - if (other == null) { - if (OTHER.compareAndSet(this, null, o)) { + if (other.get() == null) { + if (other.compareAndSet(null, o)) { return true; } o.cancel(); @@ -130,7 +124,7 @@ public void request(long n) { return; } - BackpressureHelper.add(REQUESTED, this, n); + BackpressureHelper.add(requested, n); } @Override @@ -152,11 +146,11 @@ public void complete() { public void emit() { T value = getAndSet(null); if (value != null) { - long r = requested; + long r = requested.get(); if (r != 0L) { actual.onNext(value); if (r != Long.MAX_VALUE) { - REQUESTED.decrementAndGet(this); + requested.decrementAndGet(); } } else { cancel(); diff --git a/src/main/java/io/reactivex/internal/operators/OperatorSampleTimed.java b/src/main/java/io/reactivex/internal/operators/OperatorSampleTimed.java index 38fa3af31f..fb6a21e73f 100644 --- a/src/main/java/io/reactivex/internal/operators/OperatorSampleTimed.java +++ b/src/main/java/io/reactivex/internal/operators/OperatorSampleTimed.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -18,8 +18,8 @@ import org.reactivestreams.*; -import io.reactivex.Observable.Operator; import io.reactivex.Scheduler; +import io.reactivex.Observable.Operator; import io.reactivex.disposables.Disposable; import io.reactivex.internal.subscriptions.SubscriptionHelper; import io.reactivex.internal.util.BackpressureHelper; @@ -39,8 +39,8 @@ public OperatorSampleTimed(long period, TimeUnit unit, Scheduler scheduler) { @Override public Subscriber apply(Subscriber t) { - SerializedSubscriber serial = new SerializedSubscriber<>(t); - return new SampleTimedSubscriber<>(serial, period, unit, scheduler); + SerializedSubscriber serial = new SerializedSubscriber(t); + return new SampleTimedSubscriber(serial, period, unit, scheduler); } static final class SampleTimedSubscriber extends AtomicReference implements Subscriber, Subscription, Runnable { @@ -52,17 +52,14 @@ static final class SampleTimedSubscriber extends AtomicReference implement final TimeUnit unit; final Scheduler scheduler; - volatile long requested; - @SuppressWarnings("rawtypes") - static final AtomicLongFieldUpdater REQUESTED = - AtomicLongFieldUpdater.newUpdater(SampleTimedSubscriber.class, "requested"); + final AtomicLong requested = new AtomicLong(); - volatile Disposable timer; - @SuppressWarnings("rawtypes") - static final AtomicReferenceFieldUpdater TIMER = - AtomicReferenceFieldUpdater.newUpdater(SampleTimedSubscriber.class, Disposable.class, "timer"); + final AtomicReference timer = new AtomicReference(); - static final Disposable DISPOSED = () -> { }; + static final Disposable DISPOSED = new Disposable() { + @Override + public void dispose() { } + }; Subscription s; @@ -81,9 +78,9 @@ public void onSubscribe(Subscription s) { this.s = s; actual.onSubscribe(this); - if (timer == null) { + if (timer.get() == null) { Disposable d = scheduler.schedulePeriodicallyDirect(this, period, period, unit); - if (!TIMER.compareAndSet(this, null, d)) { + if (!timer.compareAndSet(null, d)) { d.dispose(); return; } @@ -109,9 +106,9 @@ public void onComplete() { } void cancelTimer() { - Disposable d = timer; + Disposable d = timer.get(); if (d != DISPOSED) { - d = TIMER.getAndSet(this, DISPOSED); + d = timer.getAndSet(DISPOSED); if (d != DISPOSED && d != null) { d.dispose(); } @@ -124,7 +121,7 @@ public void request(long n) { return; } - BackpressureHelper.add(REQUESTED, this, n); + BackpressureHelper.add(requested, n); } @Override @@ -137,11 +134,11 @@ public void cancel() { public void run() { T value = getAndSet(null); if (value != null) { - long r = requested; + long r = requested.get(); if (r != 0L) { actual.onNext(value); if (r != Long.MAX_VALUE) { - REQUESTED.decrementAndGet(this); + requested.decrementAndGet(); } } else { cancel(); diff --git a/src/main/java/io/reactivex/internal/operators/OperatorScan.java b/src/main/java/io/reactivex/internal/operators/OperatorScan.java index d1bf204080..17b5877455 100644 --- a/src/main/java/io/reactivex/internal/operators/OperatorScan.java +++ b/src/main/java/io/reactivex/internal/operators/OperatorScan.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,11 +13,10 @@ package io.reactivex.internal.operators; -import java.util.function.BiFunction; - import org.reactivestreams.*; import io.reactivex.Observable.Operator; +import io.reactivex.functions.BiFunction; import io.reactivex.internal.subscriptions.SubscriptionHelper; public final class OperatorScan implements Operator { @@ -28,7 +27,7 @@ public OperatorScan(BiFunction accumulator) { @Override public Subscriber apply(Subscriber t) { - return new ScanSubscriber<>(t, accumulator); + return new ScanSubscriber(t, accumulator); } static final class ScanSubscriber implements Subscriber { diff --git a/src/main/java/io/reactivex/internal/operators/OperatorScanSeed.java b/src/main/java/io/reactivex/internal/operators/OperatorScanSeed.java index a7a8be0557..b505b0ea4d 100644 --- a/src/main/java/io/reactivex/internal/operators/OperatorScanSeed.java +++ b/src/main/java/io/reactivex/internal/operators/OperatorScanSeed.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -12,11 +12,10 @@ */ package io.reactivex.internal.operators; -import java.util.function.*; - import org.reactivestreams.*; import io.reactivex.Observable.Operator; +import io.reactivex.functions.*; import io.reactivex.internal.queue.SpscArrayQueue; import io.reactivex.internal.subscribers.*; import io.reactivex.internal.subscriptions.*; @@ -47,7 +46,7 @@ public Subscriber apply(Subscriber t) { return EmptySubscriber.INSTANCE; } - return new ScanSeedSubscriber<>(t, accumulator, r); + return new ScanSeedSubscriber(t, accumulator, r); } static final class ScanSeedSubscriber extends QueueDrainSubscriber implements Subscription { @@ -58,7 +57,7 @@ static final class ScanSeedSubscriber extends QueueDrainSubscriber actual, BiFunction accumulator, R value) { - super(actual, new SpscArrayQueue<>(2)); + super(actual, new SpscArrayQueue(2)); this.accumulator = accumulator; this.value = value; queue.offer(value); diff --git a/src/main/java/io/reactivex/internal/operators/OperatorSingle.java b/src/main/java/io/reactivex/internal/operators/OperatorSingle.java index dc54a5ad29..840dd4fdad 100644 --- a/src/main/java/io/reactivex/internal/operators/OperatorSingle.java +++ b/src/main/java/io/reactivex/internal/operators/OperatorSingle.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -23,7 +23,7 @@ public final class OperatorSingle implements Operator { - static final OperatorSingle NO_DEFAULT = new OperatorSingle<>(null); + static final OperatorSingle NO_DEFAULT = new OperatorSingle(null); @SuppressWarnings("unchecked") public static OperatorSingle instanceNoDefault() { @@ -36,7 +36,7 @@ public OperatorSingle(T defaultValue) { } @Override public Subscriber apply(Subscriber t) { - return new SingleElementSubscriber<>(t, defaultValue); + return new SingleElementSubscriber(t, defaultValue); } static final class SingleElementSubscriber implements Subscriber, Subscription { diff --git a/src/main/java/io/reactivex/internal/operators/OperatorSkip.java b/src/main/java/io/reactivex/internal/operators/OperatorSkip.java index 338b7a3f91..84435b8296 100644 --- a/src/main/java/io/reactivex/internal/operators/OperatorSkip.java +++ b/src/main/java/io/reactivex/internal/operators/OperatorSkip.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -17,9 +17,6 @@ import io.reactivex.Observable.Operator; -/** - * - */ public final class OperatorSkip implements Operator { final long n; public OperatorSkip(long n) { @@ -28,7 +25,7 @@ public OperatorSkip(long n) { @Override public Subscriber apply(Subscriber s) { - return new SkipSubscriber<>(s, n); + return new SkipSubscriber(s, n); } static final class SkipSubscriber implements Subscriber { diff --git a/src/main/java/io/reactivex/internal/operators/OperatorSkipLast.java b/src/main/java/io/reactivex/internal/operators/OperatorSkipLast.java index 7c70d23ae2..40a6e03c2b 100644 --- a/src/main/java/io/reactivex/internal/operators/OperatorSkipLast.java +++ b/src/main/java/io/reactivex/internal/operators/OperatorSkipLast.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -29,7 +29,7 @@ public OperatorSkipLast(int skip) { @Override public Subscriber apply(Subscriber s) { - return new SkipLastSubscriber<>(s, skip); + return new SkipLastSubscriber(s, skip); } static final class SkipLastSubscriber extends ArrayDeque implements Subscriber { diff --git a/src/main/java/io/reactivex/internal/operators/OperatorSkipLastTimed.java b/src/main/java/io/reactivex/internal/operators/OperatorSkipLastTimed.java index 59198306e5..28491301e2 100644 --- a/src/main/java/io/reactivex/internal/operators/OperatorSkipLastTimed.java +++ b/src/main/java/io/reactivex/internal/operators/OperatorSkipLastTimed.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -18,8 +18,8 @@ import org.reactivestreams.*; -import io.reactivex.Observable.Operator; import io.reactivex.Scheduler; +import io.reactivex.Observable.Operator; import io.reactivex.internal.queue.SpscLinkedArrayQueue; import io.reactivex.internal.subscriptions.SubscriptionHelper; import io.reactivex.internal.util.BackpressureHelper; @@ -41,7 +41,7 @@ public OperatorSkipLastTimed(long time, TimeUnit unit, Scheduler scheduler, int @Override public Subscriber apply(Subscriber t) { - return new SkipLastTimedSubscriber<>(t, time, unit, scheduler, bufferSize, delayError); + return new SkipLastTimedSubscriber(t, time, unit, scheduler, bufferSize, delayError); } static final class SkipLastTimedSubscriber extends AtomicInteger implements Subscriber, Subscription { @@ -56,10 +56,7 @@ static final class SkipLastTimedSubscriber extends AtomicInteger implements S Subscription s; - volatile long requested; - @SuppressWarnings("rawtypes") - static final AtomicLongFieldUpdater REQUESTED = - AtomicLongFieldUpdater.newUpdater(SkipLastTimedSubscriber.class, "requested"); + final AtomicLong requested = new AtomicLong(); volatile boolean cancelled; @@ -71,7 +68,7 @@ public SkipLastTimedSubscriber(Subscriber actual, long time, TimeUnit this.time = time; this.unit = unit; this.scheduler = scheduler; - this.queue = new SpscLinkedArrayQueue<>(bufferSize); + this.queue = new SpscLinkedArrayQueue(bufferSize); this.delayError = delayError; } @@ -114,7 +111,7 @@ public void request(long n) { if (SubscriptionHelper.validateRequest(n)) { return; } - BackpressureHelper.add(REQUESTED, this, n); + BackpressureHelper.add(requested, n); drain(); } @@ -150,7 +147,7 @@ void drain() { return; } - long r = requested; + long r = requested.get(); boolean unbounded = r == Long.MAX_VALUE; long e = 0L; @@ -199,7 +196,7 @@ void drain() { if (e != 0L) { if (!unbounded) { - REQUESTED.addAndGet(this, e); + requested.addAndGet(e); } } diff --git a/src/main/java/io/reactivex/internal/operators/OperatorSkipUntil.java b/src/main/java/io/reactivex/internal/operators/OperatorSkipUntil.java index ce35605311..10bb231a24 100644 --- a/src/main/java/io/reactivex/internal/operators/OperatorSkipUntil.java +++ b/src/main/java/io/reactivex/internal/operators/OperatorSkipUntil.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -31,11 +31,11 @@ public OperatorSkipUntil(Publisher other) { @Override public Subscriber apply(Subscriber child) { - SerializedSubscriber serial = new SerializedSubscriber<>(child); + final SerializedSubscriber serial = new SerializedSubscriber(child); - ArrayCompositeResource frc = new ArrayCompositeResource<>(2, Subscription::cancel); + final ArrayCompositeResource frc = new ArrayCompositeResource(2, SubscriptionHelper.consumeAndCancel()); - SkipUntilSubscriber sus = new SkipUntilSubscriber<>(serial, frc); + final SkipUntilSubscriber sus = new SkipUntilSubscriber(serial, frc); other.subscribe(new Subscriber() { Subscription s; diff --git a/src/main/java/io/reactivex/internal/operators/OperatorSkipWhile.java b/src/main/java/io/reactivex/internal/operators/OperatorSkipWhile.java index c6659051d6..ced080f964 100644 --- a/src/main/java/io/reactivex/internal/operators/OperatorSkipWhile.java +++ b/src/main/java/io/reactivex/internal/operators/OperatorSkipWhile.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,11 +13,10 @@ package io.reactivex.internal.operators; -import java.util.function.Predicate; - import org.reactivestreams.*; import io.reactivex.Observable.Operator; +import io.reactivex.functions.Predicate; import io.reactivex.plugins.RxJavaPlugins; public final class OperatorSkipWhile implements Operator { @@ -28,7 +27,7 @@ public OperatorSkipWhile(Predicate predicate) { @Override public Subscriber apply(Subscriber s) { - return new SkipWhileSubscriber<>(s, predicate); + return new SkipWhileSubscriber(s, predicate); } static final class SkipWhileSubscriber implements Subscriber { diff --git a/src/main/java/io/reactivex/internal/operators/OperatorSwitchIfEmpty.java b/src/main/java/io/reactivex/internal/operators/OperatorSwitchIfEmpty.java index 3468dae07a..68ff82853f 100644 --- a/src/main/java/io/reactivex/internal/operators/OperatorSwitchIfEmpty.java +++ b/src/main/java/io/reactivex/internal/operators/OperatorSwitchIfEmpty.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -27,7 +27,7 @@ public OperatorSwitchIfEmpty(Publisher other) { @Override public Subscriber apply(Subscriber t) { // TODO Auto-generated method stub - SwitchIfEmptySubscriber parent = new SwitchIfEmptySubscriber<>(t, other); + SwitchIfEmptySubscriber parent = new SwitchIfEmptySubscriber(t, other); t.onSubscribe(parent.arbiter); return parent; } diff --git a/src/main/java/io/reactivex/internal/operators/OperatorSwitchMap.java b/src/main/java/io/reactivex/internal/operators/OperatorSwitchMap.java index 9862d950fe..aa360465d7 100644 --- a/src/main/java/io/reactivex/internal/operators/OperatorSwitchMap.java +++ b/src/main/java/io/reactivex/internal/operators/OperatorSwitchMap.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -15,11 +15,11 @@ import java.util.Queue; import java.util.concurrent.atomic.*; -import java.util.function.Function; import org.reactivestreams.*; import io.reactivex.Observable.Operator; +import io.reactivex.functions.Function; import io.reactivex.internal.queue.*; import io.reactivex.internal.subscriptions.SubscriptionHelper; import io.reactivex.internal.util.*; @@ -36,7 +36,7 @@ public OperatorSwitchMap(Function> m @Override public Subscriber apply(Subscriber t) { - return new SwitchMapSubscriber<>(t, mapper, bufferSize); + return new SwitchMapSubscriber(t, mapper, bufferSize); } static final class SwitchMapSubscriber extends AtomicInteger implements Subscriber, Subscription { @@ -54,19 +54,13 @@ static final class SwitchMapSubscriber extends AtomicInteger implements Su Subscription s; - volatile SwitchMapInnerSubscriber active; - @SuppressWarnings("rawtypes") - static final AtomicReferenceFieldUpdater ACTIVE = - AtomicReferenceFieldUpdater.newUpdater(SwitchMapSubscriber.class, SwitchMapInnerSubscriber.class, "active"); + final AtomicReference> active = new AtomicReference>(); - volatile long requested; - @SuppressWarnings("rawtypes") - static final AtomicLongFieldUpdater REQUESTED = - AtomicLongFieldUpdater.newUpdater(SwitchMapSubscriber.class, "requested"); + final AtomicLong requested = new AtomicLong(); static final SwitchMapInnerSubscriber CANCELLED; static { - CANCELLED = new SwitchMapInnerSubscriber<>(null, -1L, 1); + CANCELLED = new SwitchMapInnerSubscriber(null, -1L, 1); CANCELLED.cancel(); } @@ -92,7 +86,7 @@ public void onNext(T t) { long c = unique + 1; unique = c; - SwitchMapInnerSubscriber inner = active; + SwitchMapInnerSubscriber inner = active.get(); if (inner != null) { inner.cancel(); } @@ -112,14 +106,14 @@ public void onNext(T t) { return; } - SwitchMapInnerSubscriber nextInner = new SwitchMapInnerSubscriber<>(this, c, bufferSize); + SwitchMapInnerSubscriber nextInner = new SwitchMapInnerSubscriber(this, c, bufferSize); for (;;) { - inner = active; + inner = active.get(); if (inner == CANCELLED) { break; } - if (ACTIVE.compareAndSet(this, inner, nextInner)) { + if (active.compareAndSet(inner, nextInner)) { p.subscribe(nextInner); break; } @@ -151,7 +145,7 @@ public void request(long n) { if (SubscriptionHelper.validateRequest(n)) { return; } - BackpressureHelper.add(REQUESTED, this, n); + BackpressureHelper.add(requested, n); if (unique == 0L) { s.request(Long.MAX_VALUE); } else { @@ -170,9 +164,9 @@ public void cancel() { @SuppressWarnings("unchecked") void disposeInner() { - SwitchMapInnerSubscriber a = active; + SwitchMapInnerSubscriber a = active.get(); if (a != CANCELLED) { - a = ACTIVE.getAndSet(this, CANCELLED); + a = active.getAndSet((SwitchMapInnerSubscriber)CANCELLED); if (a != CANCELLED && a != null) { s.cancel(); } @@ -202,13 +196,13 @@ void drain() { a.onError(err); return; } else - if (active == null) { + if (active.get() == null) { a.onComplete(); return; } } - SwitchMapInnerSubscriber inner = active; + SwitchMapInnerSubscriber inner = active.get(); if (inner != null) { Queue q = inner.queue; @@ -222,12 +216,12 @@ void drain() { return; } else if (q.isEmpty()) { - ACTIVE.compareAndSet(this, inner, null); + active.compareAndSet(inner, null); continue; } } - long r = requested; + long r = requested.get(); boolean unbounded = r == Long.MAX_VALUE; long e = 0L; boolean retry = false; @@ -240,7 +234,7 @@ void drain() { if (cancelled) { return; } - if (inner != active) { + if (inner != active.get()) { retry = true; break; } @@ -253,7 +247,7 @@ void drain() { return; } else if (empty) { - ACTIVE.compareAndSet(this, inner, null); + active.compareAndSet(inner, null); retry = true; break; } @@ -272,7 +266,7 @@ void drain() { if (e != 0L) { if (!cancelled) { if (!unbounded) { - REQUESTED.addAndGet(this, e); + requested.addAndGet(e); } inner.get().request(-e); } @@ -342,9 +336,9 @@ public SwitchMapInnerSubscriber(SwitchMapSubscriber parent, long index, in this.bufferSize = bufferSize; Queue q; if (Pow2.isPowerOfTwo(bufferSize)) { - q = new SpscArrayQueue<>(bufferSize); + q = new SpscArrayQueue(bufferSize); } else { - q = new SpscExactArrayQueue<>(bufferSize); + q = new SpscExactArrayQueue(bufferSize); } this.queue = q; } diff --git a/src/main/java/io/reactivex/internal/operators/OperatorTake.java b/src/main/java/io/reactivex/internal/operators/OperatorTake.java index e31ef36f38..d1c02a1aa4 100644 --- a/src/main/java/io/reactivex/internal/operators/OperatorTake.java +++ b/src/main/java/io/reactivex/internal/operators/OperatorTake.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -22,9 +22,6 @@ import io.reactivex.internal.util.BackpressureHelper; import io.reactivex.plugins.RxJavaPlugins; -/** - * - */ public final class OperatorTake implements Operator { final long limit; public OperatorTake(long limit) { @@ -33,7 +30,7 @@ public OperatorTake(long limit) { @Override public Subscriber apply(Subscriber t) { - return new TakeSubscriber<>(t, limit); + return new TakeSubscriber(t, limit); } static final class TakeSubscriber extends AtomicLong implements Subscriber, Subscription { diff --git a/src/main/java/io/reactivex/internal/operators/OperatorTakeLast.java b/src/main/java/io/reactivex/internal/operators/OperatorTakeLast.java index e423e5b836..dfea2844e2 100644 --- a/src/main/java/io/reactivex/internal/operators/OperatorTakeLast.java +++ b/src/main/java/io/reactivex/internal/operators/OperatorTakeLast.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -32,7 +32,7 @@ public OperatorTakeLast(int count) { @Override public Subscriber apply(Subscriber t) { - return new TakeLastSubscriber<>(t, count); + return new TakeLastSubscriber(t, count); } static final class TakeLastSubscriber extends ArrayDeque implements Subscriber, Subscription { @@ -45,15 +45,9 @@ static final class TakeLastSubscriber extends ArrayDeque implements Subscr volatile boolean done; volatile boolean cancelled; - volatile long requested; - @SuppressWarnings("rawtypes") - static final AtomicLongFieldUpdater REQUESTED = - AtomicLongFieldUpdater.newUpdater(TakeLastSubscriber.class, "requested"); + final AtomicLong requested = new AtomicLong(); - volatile int wip; - @SuppressWarnings("rawtypes") - static final AtomicIntegerFieldUpdater WIP = - AtomicIntegerFieldUpdater.newUpdater(TakeLastSubscriber.class, "wip"); + final AtomicInteger wip = new AtomicInteger(); public TakeLastSubscriber(Subscriber actual, int count) { this.actual = actual; @@ -96,7 +90,7 @@ public void request(long n) { if (SubscriptionHelper.validateRequest(n)) { return; } - BackpressureHelper.add(REQUESTED, this, n); + BackpressureHelper.add(requested, n); drain(); } @@ -107,9 +101,9 @@ public void cancel() { } void drain() { - if (WIP.getAndIncrement(this) == 0) { + if (wip.getAndIncrement() == 0) { Subscriber a = actual; - long r = requested; + long r = requested.get(); do { if (cancelled) { return; @@ -132,10 +126,10 @@ void drain() { e++; } if (!unbounded && e != 0L) { - r = REQUESTED.addAndGet(this, -e); + r = requested.addAndGet(-e); } } - } while (WIP.decrementAndGet(this) != 0); + } while (wip.decrementAndGet() != 0); } } } diff --git a/src/main/java/io/reactivex/internal/operators/OperatorTakeLastOne.java b/src/main/java/io/reactivex/internal/operators/OperatorTakeLastOne.java index c1678fe99f..d064cd5d35 100644 --- a/src/main/java/io/reactivex/internal/operators/OperatorTakeLastOne.java +++ b/src/main/java/io/reactivex/internal/operators/OperatorTakeLastOne.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -30,7 +30,7 @@ public static Operator instance() { @Override public Subscriber apply(Subscriber s) { - return new TakeLastOneSubscriber<>(s); + return new TakeLastOneSubscriber(s); } static final class TakeLastOneSubscriber extends AtomicInteger implements Subscriber, Subscription { diff --git a/src/main/java/io/reactivex/internal/operators/OperatorTakeLastTimed.java b/src/main/java/io/reactivex/internal/operators/OperatorTakeLastTimed.java index 63b0d71138..7109236aed 100644 --- a/src/main/java/io/reactivex/internal/operators/OperatorTakeLastTimed.java +++ b/src/main/java/io/reactivex/internal/operators/OperatorTakeLastTimed.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -19,11 +19,11 @@ import org.reactivestreams.*; +import io.reactivex.Scheduler; import io.reactivex.Observable.Operator; import io.reactivex.internal.queue.SpscLinkedArrayQueue; import io.reactivex.internal.subscriptions.SubscriptionHelper; import io.reactivex.internal.util.BackpressureHelper; -import io.reactivex.Scheduler; public final class OperatorTakeLastTimed implements Operator { final long count; @@ -44,7 +44,7 @@ public OperatorTakeLastTimed(long count, long time, TimeUnit unit, Scheduler sch @Override public Subscriber apply(Subscriber t) { - return new TakeLastTimedSubscriber<>(t, count, time, unit, scheduler, bufferSize, delayError); + return new TakeLastTimedSubscriber(t, count, time, unit, scheduler, bufferSize, delayError); } static final class TakeLastTimedSubscriber extends AtomicInteger implements Subscriber, Subscription { @@ -60,11 +60,8 @@ static final class TakeLastTimedSubscriber extends AtomicInteger implements S Subscription s; - volatile long requested; - @SuppressWarnings("rawtypes") - static final AtomicLongFieldUpdater REQUESTED = - AtomicLongFieldUpdater.newUpdater(TakeLastTimedSubscriber.class, "requested"); - + final AtomicLong requested = new AtomicLong(); + volatile boolean cancelled; volatile boolean done; @@ -76,7 +73,7 @@ public TakeLastTimedSubscriber(Subscriber actual, long count, long ti this.time = time; this.unit = unit; this.scheduler = scheduler; - this.queue = new SpscLinkedArrayQueue<>(bufferSize); + this.queue = new SpscLinkedArrayQueue(bufferSize); this.delayError = delayError; } @@ -95,26 +92,18 @@ public void onNext(T t) { final Queue q = queue; long now = scheduler.now(unit); - long time = this.time; - long c = count; - boolean unbounded = c == Long.MAX_VALUE; - + q.offer(now); q.offer(t); - while (!q.isEmpty()) { - long ts = (Long)q.peek(); - if (ts <= now - time || (!unbounded && (q.size() >> 1) > c)) { - q.poll(); - q.poll(); - } else { - break; - } - } + trim(now, q); } @Override public void onError(Throwable t) { + if (delayError) { + trim(scheduler.now(unit), queue); + } error = t; done = true; drain(); @@ -122,16 +111,33 @@ public void onError(Throwable t) { @Override public void onComplete() { + trim(scheduler.now(unit), queue); done = true; drain(); } + void trim(long now, Queue q) { + long time = this.time; + long c = count; + boolean unbounded = c == Long.MAX_VALUE; + + while (!q.isEmpty()) { + long ts = (Long)q.peek(); + if (ts < now - time || (!unbounded && (q.size() >> 1) > c)) { + q.poll(); + q.poll(); + } else { + break; + } + } + } + @Override public void request(long n) { if (SubscriptionHelper.validateRequest(n)) { return; } - BackpressureHelper.add(REQUESTED, this, n); + BackpressureHelper.add(requested, n); drain(); } @@ -167,22 +173,23 @@ void drain() { return; } - long r = requested; + long r = requested.get(); boolean unbounded = r == Long.MAX_VALUE; long e = 0L; - while (r != 0) { - Object ts = q.poll(); // the timestamp long + for (;;) { + Object ts = q.peek(); // the timestamp long empty = ts == null; if (checkTerminated(empty, a, delayError)) { return; } - if (empty) { + if (empty || r == 0L) { break; } + q.poll(); @SuppressWarnings("unchecked") T o = (T)q.poll(); if (o == null) { @@ -191,10 +198,6 @@ void drain() { return; } - if ((Long)ts < scheduler.now(unit) - time) { - continue; - } - a.onNext(o); r--; @@ -203,7 +206,7 @@ void drain() { if (e != 0L) { if (!unbounded) { - REQUESTED.addAndGet(this, e); + requested.addAndGet(e); } } } diff --git a/src/main/java/io/reactivex/internal/operators/OperatorTakeUntil.java b/src/main/java/io/reactivex/internal/operators/OperatorTakeUntil.java index e0be0d0e14..7d3d444c8c 100644 --- a/src/main/java/io/reactivex/internal/operators/OperatorTakeUntil.java +++ b/src/main/java/io/reactivex/internal/operators/OperatorTakeUntil.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -22,9 +22,6 @@ import io.reactivex.internal.subscriptions.*; import io.reactivex.subscribers.SerializedSubscriber; -/** - * - */ public final class OperatorTakeUntil implements Operator { final Publisher other; public OperatorTakeUntil(Publisher other) { @@ -32,11 +29,11 @@ public OperatorTakeUntil(Publisher other) { } @Override public Subscriber apply(Subscriber child) { - SerializedSubscriber serial = new SerializedSubscriber<>(child); + final SerializedSubscriber serial = new SerializedSubscriber(child); - ArrayCompositeResource frc = new ArrayCompositeResource<>(2, Subscription::cancel); + final ArrayCompositeResource frc = new ArrayCompositeResource(2, SubscriptionHelper.consumeAndCancel()); - TakeUntilSubscriber tus = new TakeUntilSubscriber<>(serial, frc); + final TakeUntilSubscriber tus = new TakeUntilSubscriber(serial, frc); other.subscribe(new Subscriber() { @Override diff --git a/src/main/java/io/reactivex/internal/operators/OperatorTakeUntilPredicate.java b/src/main/java/io/reactivex/internal/operators/OperatorTakeUntilPredicate.java index 37f9876e4f..4ad84b0dd2 100644 --- a/src/main/java/io/reactivex/internal/operators/OperatorTakeUntilPredicate.java +++ b/src/main/java/io/reactivex/internal/operators/OperatorTakeUntilPredicate.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,16 +13,12 @@ package io.reactivex.internal.operators; -import java.util.function.Predicate; - import org.reactivestreams.*; import io.reactivex.Observable.Operator; +import io.reactivex.functions.Predicate; import io.reactivex.plugins.RxJavaPlugins; -/** - * - */ public final class OperatorTakeUntilPredicate implements Operator { final Predicate predicate; public OperatorTakeUntilPredicate(Predicate predicate) { @@ -31,7 +27,7 @@ public OperatorTakeUntilPredicate(Predicate predicate) { @Override public Subscriber apply(Subscriber s) { - return new InnerSubscriber<>(s, predicate); + return new InnerSubscriber(s, predicate); } static final class InnerSubscriber implements Subscriber { diff --git a/src/main/java/io/reactivex/internal/operators/OperatorTakeWhile.java b/src/main/java/io/reactivex/internal/operators/OperatorTakeWhile.java index f8773e9a14..ea180f438d 100644 --- a/src/main/java/io/reactivex/internal/operators/OperatorTakeWhile.java +++ b/src/main/java/io/reactivex/internal/operators/OperatorTakeWhile.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,11 +13,10 @@ package io.reactivex.internal.operators; -import java.util.function.Predicate; - import org.reactivestreams.*; import io.reactivex.Observable.Operator; +import io.reactivex.functions.Predicate; import io.reactivex.internal.subscriptions.SubscriptionHelper; public final class OperatorTakeWhile implements Operator { @@ -28,7 +27,7 @@ public OperatorTakeWhile(Predicate predicate) { @Override public Subscriber apply(Subscriber t) { - return new TakeWhileSubscriber<>(t, predicate); + return new TakeWhileSubscriber(t, predicate); } static final class TakeWhileSubscriber implements Subscriber { diff --git a/src/main/java/io/reactivex/internal/operators/OperatorThrottleFirstTimed.java b/src/main/java/io/reactivex/internal/operators/OperatorThrottleFirstTimed.java index 35d38bb314..602f7b3e93 100644 --- a/src/main/java/io/reactivex/internal/operators/OperatorThrottleFirstTimed.java +++ b/src/main/java/io/reactivex/internal/operators/OperatorThrottleFirstTimed.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -18,8 +18,8 @@ import org.reactivestreams.*; -import io.reactivex.Observable.Operator; import io.reactivex.Scheduler; +import io.reactivex.Observable.Operator; import io.reactivex.Scheduler.Worker; import io.reactivex.disposables.Disposable; import io.reactivex.internal.subscriptions.SubscriptionHelper; @@ -40,8 +40,8 @@ public OperatorThrottleFirstTimed(long timeout, TimeUnit unit, Scheduler schedul @Override public Subscriber apply(Subscriber t) { - return new DebounceTimedSubscriber<>( - new SerializedSubscriber<>(t), + return new DebounceTimedSubscriber( + new SerializedSubscriber(t), timeout, unit, scheduler.createWorker()); } @@ -57,14 +57,17 @@ static final class DebounceTimedSubscriber Subscription s; - volatile Disposable timer; - @SuppressWarnings("rawtypes") - static final AtomicReferenceFieldUpdater TIMER = - AtomicReferenceFieldUpdater.newUpdater(DebounceTimedSubscriber.class, Disposable.class, "timer"); + final AtomicReference timer = new AtomicReference(); - static final Disposable CANCELLED = () -> { }; + static final Disposable CANCELLED = new Disposable() { + @Override + public void dispose() { } + }; - static final Disposable NEW_TIMER = () -> { }; + static final Disposable NEW_TIMER = new Disposable() { + @Override + public void dispose() { } + }; volatile boolean gate; @@ -78,9 +81,9 @@ public DebounceTimedSubscriber(Subscriber actual, long timeout, TimeU } public void disposeTimer() { - Disposable d = timer; + Disposable d = timer.get(); if (d != CANCELLED) { - d = TIMER.getAndSet(this, CANCELLED); + d = timer.getAndSet(CANCELLED); if (d != CANCELLED && d != null) { d.dispose(); } @@ -119,14 +122,14 @@ public void onNext(T t) { } // FIXME should this be a periodic blocking or a value-relative blocking? - Disposable d = timer; + Disposable d = timer.get(); if (d != null) { d.dispose(); } - if (TIMER.compareAndSet(this, d, NEW_TIMER)) { + if (timer.compareAndSet(d, NEW_TIMER)) { d = worker.schedule(this, timeout, unit); - if (!TIMER.compareAndSet(this, NEW_TIMER, d)) { + if (!timer.compareAndSet(NEW_TIMER, d)) { d.dispose(); } } diff --git a/src/main/java/io/reactivex/internal/operators/OperatorTimeInterval.java b/src/main/java/io/reactivex/internal/operators/OperatorTimeInterval.java index f0aba3a577..b8d4e98767 100644 --- a/src/main/java/io/reactivex/internal/operators/OperatorTimeInterval.java +++ b/src/main/java/io/reactivex/internal/operators/OperatorTimeInterval.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -17,8 +17,8 @@ import org.reactivestreams.*; -import io.reactivex.Observable.Operator; import io.reactivex.Scheduler; +import io.reactivex.Observable.Operator; import io.reactivex.schedulers.Timed; public final class OperatorTimeInterval implements Operator, T> { @@ -32,7 +32,7 @@ public OperatorTimeInterval(TimeUnit unit, Scheduler scheduler) { @Override public Subscriber apply(Subscriber> t) { - return new TimeIntervalSubscriber<>(t, unit, scheduler); + return new TimeIntervalSubscriber(t, unit, scheduler); } static final class TimeIntervalSubscriber implements Subscriber { @@ -60,7 +60,7 @@ public void onNext(T t) { long last = lastTime; lastTime = now; long delta = now - last; - actual.onNext(new Timed<>(t, delta, unit)); + actual.onNext(new Timed(t, delta, unit)); } @Override diff --git a/src/main/java/io/reactivex/internal/operators/OperatorTimeout.java b/src/main/java/io/reactivex/internal/operators/OperatorTimeout.java index 419942c525..8ff92adcec 100644 --- a/src/main/java/io/reactivex/internal/operators/OperatorTimeout.java +++ b/src/main/java/io/reactivex/internal/operators/OperatorTimeout.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -14,13 +14,13 @@ package io.reactivex.internal.operators; import java.util.concurrent.TimeoutException; -import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; -import java.util.function.*; +import java.util.concurrent.atomic.*; import org.reactivestreams.*; import io.reactivex.Observable.Operator; import io.reactivex.disposables.Disposable; +import io.reactivex.functions.*; import io.reactivex.internal.subscribers.*; import io.reactivex.internal.subscriptions.*; import io.reactivex.plugins.RxJavaPlugins; @@ -41,11 +41,11 @@ public OperatorTimeout(Supplier> firstTimeoutSelector, @Override public Subscriber apply(Subscriber t) { if (other == null) { - return new TimeoutSubscriber<>( - new SerializedSubscriber<>(t), + return new TimeoutSubscriber( + new SerializedSubscriber(t), firstTimeoutSelector, timeoutSelector); } - return new TimeoutOtherSubscriber<>(t, firstTimeoutSelector, timeoutSelector, other); + return new TimeoutOtherSubscriber(t, firstTimeoutSelector, timeoutSelector, other); } static final class TimeoutSubscriber implements Subscriber, Subscription, OnTimeout { @@ -59,12 +59,12 @@ static final class TimeoutSubscriber implements Subscriber, Subscrip volatile long index; - volatile Disposable timeout; - @SuppressWarnings("rawtypes") - static final AtomicReferenceFieldUpdater TIMEOUT = - AtomicReferenceFieldUpdater.newUpdater(TimeoutSubscriber.class, Disposable.class, "timeout"); + final AtomicReference timeout = new AtomicReference(); - static final Disposable CANCELLED = () -> { }; + static final Disposable CANCELLED = new Disposable() { + @Override + public void dispose() { } + }; public TimeoutSubscriber(Subscriber actual, Supplier> firstTimeoutSelector, @@ -104,9 +104,9 @@ public void onSubscribe(Subscription s) { return; } - TimeoutInnerSubscriber tis = new TimeoutInnerSubscriber<>(this, 0); + TimeoutInnerSubscriber tis = new TimeoutInnerSubscriber(this, 0); - if (TIMEOUT.compareAndSet(this, null, tis)) { + if (timeout.compareAndSet(null, tis)) { a.onSubscribe(s); p.subscribe(tis); } @@ -122,7 +122,7 @@ public void onNext(T t) { actual.onNext(t); - Disposable d = timeout; + Disposable d = timeout.get(); if (d != null) { d.dispose(); } @@ -143,9 +143,9 @@ public void onNext(T t) { return; } - TimeoutInnerSubscriber tis = new TimeoutInnerSubscriber<>(this, idx); + TimeoutInnerSubscriber tis = new TimeoutInnerSubscriber(this, idx); - if (TIMEOUT.compareAndSet(this, d, tis)) { + if (timeout.compareAndSet(d, tis)) { p.subscribe(tis); } } @@ -172,9 +172,9 @@ public void cancel() { cancelled = true; s.cancel(); - Disposable d = timeout; + Disposable d = timeout.get(); if (d != CANCELLED) { - d = TIMEOUT.getAndSet(this, CANCELLED); + d = timeout.getAndSet(CANCELLED); if (d != CANCELLED && d != null) { d.dispose(); } @@ -247,12 +247,12 @@ static final class TimeoutOtherSubscriber implements Subscriber, Dis volatile long index; - volatile Disposable timeout; - @SuppressWarnings("rawtypes") - static final AtomicReferenceFieldUpdater TIMEOUT = - AtomicReferenceFieldUpdater.newUpdater(TimeoutOtherSubscriber.class, Disposable.class, "timeout"); + final AtomicReference timeout = new AtomicReference(); - static final Disposable CANCELLED = () -> { }; + static final Disposable CANCELLED = new Disposable() { + @Override + public void dispose() { } + }; public TimeoutOtherSubscriber(Subscriber actual, Supplier> firstTimeoutSelector, @@ -261,7 +261,7 @@ public TimeoutOtherSubscriber(Subscriber actual, this.firstTimeoutSelector = firstTimeoutSelector; this.timeoutSelector = timeoutSelector; this.other = other; - this.arbiter = new FullArbiter<>(actual, this, 8); + this.arbiter = new FullArbiter(actual, this, 8); } @Override @@ -293,9 +293,9 @@ public void onSubscribe(Subscription s) { return; } - TimeoutInnerSubscriber tis = new TimeoutInnerSubscriber<>(this, 0); + TimeoutInnerSubscriber tis = new TimeoutInnerSubscriber(this, 0); - if (TIMEOUT.compareAndSet(this, null, tis)) { + if (timeout.compareAndSet(null, tis)) { a.onSubscribe(arbiter); p.subscribe(tis); } @@ -316,7 +316,7 @@ public void onNext(T t) { return; } - Disposable d = timeout; + Disposable d = timeout.get(); if (d != null) { d.dispose(); } @@ -335,9 +335,9 @@ public void onNext(T t) { return; } - TimeoutInnerSubscriber tis = new TimeoutInnerSubscriber<>(this, idx); + TimeoutInnerSubscriber tis = new TimeoutInnerSubscriber(this, idx); - if (TIMEOUT.compareAndSet(this, d, tis)) { + if (timeout.compareAndSet(d, tis)) { p.subscribe(tis); } } @@ -368,9 +368,9 @@ public void dispose() { cancelled = true; s.cancel(); - Disposable d = timeout; + Disposable d = timeout.get(); if (d != CANCELLED) { - d = TIMEOUT.getAndSet(this, CANCELLED); + d = timeout.getAndSet(CANCELLED); if (d != CANCELLED && d != null) { d.dispose(); } @@ -381,7 +381,7 @@ public void dispose() { public void timeout(long idx) { if (idx == index) { dispose(); - other.subscribe(new FullArbiterSubscriber<>(arbiter)); + other.subscribe(new FullArbiterSubscriber(arbiter)); } } } diff --git a/src/main/java/io/reactivex/internal/operators/OperatorTimeoutTimed.java b/src/main/java/io/reactivex/internal/operators/OperatorTimeoutTimed.java index bfc60ca7bd..54cc3eebd7 100644 --- a/src/main/java/io/reactivex/internal/operators/OperatorTimeoutTimed.java +++ b/src/main/java/io/reactivex/internal/operators/OperatorTimeoutTimed.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -14,12 +14,12 @@ package io.reactivex.internal.operators; import java.util.concurrent.*; -import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; +import java.util.concurrent.atomic.*; import org.reactivestreams.*; -import io.reactivex.Observable.Operator; import io.reactivex.Scheduler; +import io.reactivex.Observable.Operator; import io.reactivex.Scheduler.Worker; import io.reactivex.disposables.Disposable; import io.reactivex.internal.subscribers.FullArbiterSubscriber; @@ -43,11 +43,11 @@ public OperatorTimeoutTimed(long timeout, TimeUnit unit, Scheduler scheduler, Pu @Override public Subscriber apply(Subscriber t) { if (other == null) { - return new TimeoutTimedSubscriber<>( - new SerializedSubscriber<>(t), // because errors can race + return new TimeoutTimedSubscriber( + new SerializedSubscriber(t), // because errors can race timeout, unit, scheduler.createWorker()); } - return new TimeoutTimedOtherSubscriber<>( + return new TimeoutTimedOtherSubscriber( t, // the FullArbiter serializes timeout, unit, scheduler.createWorker(), other); } @@ -63,14 +63,17 @@ static final class TimeoutTimedOtherSubscriber implements Subscriber, Disp final FullArbiter arbiter; - volatile Disposable timer; - @SuppressWarnings("rawtypes") - static final AtomicReferenceFieldUpdater TIMER = - AtomicReferenceFieldUpdater.newUpdater(TimeoutTimedOtherSubscriber.class, Disposable.class, "timer"); + final AtomicReference timer = new AtomicReference(); - static final Disposable CANCELLED = () -> { }; + static final Disposable CANCELLED = new Disposable() { + @Override + public void dispose() { } + }; - static final Disposable NEW_TIMER = () -> { }; + static final Disposable NEW_TIMER = new Disposable() { + @Override + public void dispose() { } + }; volatile long index; @@ -83,7 +86,7 @@ public TimeoutTimedOtherSubscriber(Subscriber actual, long timeout, T this.unit = unit; this.worker = worker; this.other = other; - this.arbiter = new FullArbiter<>(actual, this, 8); + this.arbiter = new FullArbiter(actual, this, 8); } @Override @@ -113,36 +116,39 @@ public void onNext(T t) { } } - void scheduleTimeout(long idx) { - Disposable d = timer; + void scheduleTimeout(final long idx) { + Disposable d = timer.get(); if (d != null) { d.dispose(); } - if (TIMER.compareAndSet(this, d, NEW_TIMER)) { - d = worker.schedule(() -> { - if (idx == index) { - done = true; - s.cancel(); - disposeTimer(); - worker.dispose(); - - if (other == null) { - actual.onError(new TimeoutException()); - } else { - subscribeNext(); + if (timer.compareAndSet(d, NEW_TIMER)) { + d = worker.schedule(new Runnable() { + @Override + public void run() { + if (idx == index) { + done = true; + s.cancel(); + disposeTimer(); + worker.dispose(); + + if (other == null) { + actual.onError(new TimeoutException()); + } else { + subscribeNext(); + } } } }, timeout, unit); - if (!TIMER.compareAndSet(this, NEW_TIMER, d)) { + if (!timer.compareAndSet(NEW_TIMER, d)) { d.dispose(); } } } void subscribeNext() { - other.subscribe(new FullArbiterSubscriber<>(arbiter)); + other.subscribe(new FullArbiterSubscriber(arbiter)); } @Override @@ -175,9 +181,9 @@ public void dispose() { } public void disposeTimer() { - Disposable d = timer; + Disposable d = timer.get(); if (d != CANCELLED) { - d = TIMER.getAndSet(this, CANCELLED); + d = timer.getAndSet(CANCELLED); if (d != CANCELLED && d != null) { d.dispose(); } @@ -193,14 +199,17 @@ static final class TimeoutTimedSubscriber implements Subscriber, Disposabl Subscription s; - volatile Disposable timer; - @SuppressWarnings("rawtypes") - static final AtomicReferenceFieldUpdater TIMER = - AtomicReferenceFieldUpdater.newUpdater(TimeoutTimedSubscriber.class, Disposable.class, "timer"); + final AtomicReference timer = new AtomicReference(); - static final Disposable CANCELLED = () -> { }; + static final Disposable CANCELLED = new Disposable() { + @Override + public void dispose() { } + }; - static final Disposable NEW_TIMER = () -> { }; + static final Disposable NEW_TIMER = new Disposable() { + @Override + public void dispose() { } + }; volatile long index; @@ -237,24 +246,27 @@ public void onNext(T t) { scheduleTimeout(idx); } - void scheduleTimeout(long idx) { - Disposable d = timer; + void scheduleTimeout(final long idx) { + Disposable d = timer.get(); if (d != null) { d.dispose(); } - if (TIMER.compareAndSet(this, d, NEW_TIMER)) { - d = worker.schedule(() -> { - if (idx == index) { - done = true; - s.cancel(); - dispose(); - - actual.onError(new TimeoutException()); + if (timer.compareAndSet(d, NEW_TIMER)) { + d = worker.schedule(new Runnable() { + @Override + public void run() { + if (idx == index) { + done = true; + s.cancel(); + dispose(); + + actual.onError(new TimeoutException()); + } } }, timeout, unit); - if (!TIMER.compareAndSet(this, NEW_TIMER, d)) { + if (!timer.compareAndSet(NEW_TIMER, d)) { d.dispose(); } } @@ -290,9 +302,9 @@ public void dispose() { } public void disposeTimer() { - Disposable d = timer; + Disposable d = timer.get(); if (d != CANCELLED) { - d = TIMER.getAndSet(this, CANCELLED); + d = timer.getAndSet(CANCELLED); if (d != CANCELLED && d != null) { d.dispose(); } diff --git a/src/main/java/io/reactivex/internal/operators/OperatorToList.java b/src/main/java/io/reactivex/internal/operators/OperatorToList.java index afcb1a2f48..c40f04fb22 100644 --- a/src/main/java/io/reactivex/internal/operators/OperatorToList.java +++ b/src/main/java/io/reactivex/internal/operators/OperatorToList.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -14,11 +14,11 @@ package io.reactivex.internal.operators; import java.util.*; -import java.util.function.Supplier; import org.reactivestreams.*; import io.reactivex.Observable.Operator; +import io.reactivex.functions.Supplier; import io.reactivex.internal.subscribers.CancelledSubscriber; import io.reactivex.internal.subscriptions.EmptySubscription; import io.reactivex.plugins.RxJavaPlugins; @@ -26,7 +26,12 @@ public final class OperatorToList> implements Operator { @SuppressWarnings({"rawtypes", "unchecked"}) - static final OperatorToList DEFAULT = new OperatorToList(ArrayList::new); + static final OperatorToList DEFAULT = new OperatorToList(new Supplier() { + @Override + public Object get() { + return new ArrayList(); + } + }); @SuppressWarnings("unchecked") public static OperatorToList> defaultInstance() { @@ -48,7 +53,7 @@ public Subscriber apply(Subscriber t) { EmptySubscription.error(e, t); return CancelledSubscriber.INSTANCE; } - return new ToListSubscriber<>(t, coll); + return new ToListSubscriber(t, coll); } static final class ToListSubscriber> implements Subscriber, Subscription { diff --git a/src/main/java/io/reactivex/internal/operators/OperatorUnsubscribeOn.java b/src/main/java/io/reactivex/internal/operators/OperatorUnsubscribeOn.java index ead0237857..82334ebe12 100644 --- a/src/main/java/io/reactivex/internal/operators/OperatorUnsubscribeOn.java +++ b/src/main/java/io/reactivex/internal/operators/OperatorUnsubscribeOn.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -17,8 +17,8 @@ import org.reactivestreams.*; -import io.reactivex.Observable.Operator; import io.reactivex.Scheduler; +import io.reactivex.Observable.Operator; import io.reactivex.internal.subscriptions.SubscriptionHelper; public final class OperatorUnsubscribeOn implements Operator { @@ -29,7 +29,7 @@ public OperatorUnsubscribeOn(Scheduler scheduler) { @Override public Subscriber apply(Subscriber t) { - return new UnsubscribeSubscriber<>(t, scheduler); + return new UnsubscribeSubscriber(t, scheduler); } static final class UnsubscribeSubscriber extends AtomicBoolean implements Subscriber, Subscription { @@ -78,8 +78,11 @@ public void request(long n) { @Override public void cancel() { if (compareAndSet(false, true)) { - scheduler.scheduleDirect(() -> { - s.cancel(); + scheduler.scheduleDirect(new Runnable() { + @Override + public void run() { + s.cancel(); + } }); } } diff --git a/src/main/java/io/reactivex/internal/operators/OperatorWindow.java b/src/main/java/io/reactivex/internal/operators/OperatorWindow.java index a7f1319e56..777f99de3e 100644 --- a/src/main/java/io/reactivex/internal/operators/OperatorWindow.java +++ b/src/main/java/io/reactivex/internal/operators/OperatorWindow.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -38,9 +38,9 @@ public OperatorWindow(long count, long skip, int capacityHint) { @Override public Subscriber apply(Subscriber> t) { if (count == skip) { - return new WindowExactSubscriber<>(t, count, capacityHint); + return new WindowExactSubscriber(t, count, capacityHint); } - return new WindowSkipSubscriber<>(t, count, skip, capacityHint); + return new WindowSkipSubscriber(t, count, skip, capacityHint); } static final class WindowExactSubscriber @@ -159,17 +159,14 @@ static final class WindowSkipSubscriber extends AtomicBoolean Subscription s; - volatile int wip; - @SuppressWarnings("rawtypes") - static final AtomicIntegerFieldUpdater WIP = - AtomicIntegerFieldUpdater.newUpdater(WindowSkipSubscriber.class, "wip"); + final AtomicInteger wip = new AtomicInteger(); public WindowSkipSubscriber(Subscriber> actual, long count, long skip, int capacityHint) { this.actual = actual; this.count = count; this.skip = skip; this.capacityHint = capacityHint; - this.windows = new ArrayDeque<>(); + this.windows = new ArrayDeque>(); } @Override @@ -192,7 +189,7 @@ public void onNext(T t) { long s = skip; if (i % s == 0 && !cancelled) { - WIP.getAndIncrement(this); + wip.getAndIncrement(); UnicastSubject w = UnicastSubject.create(capacityHint, this); ws.offer(w); actual.onNext(w); @@ -276,7 +273,7 @@ public void cancel() { @Override public void run() { - if (WIP.decrementAndGet(this) == 0) { + if (wip.decrementAndGet() == 0) { if (cancelled) { s.cancel(); } diff --git a/src/main/java/io/reactivex/internal/operators/OperatorWindowBoundary.java b/src/main/java/io/reactivex/internal/operators/OperatorWindowBoundary.java index 3eb0c494a9..e556db61a9 100644 --- a/src/main/java/io/reactivex/internal/operators/OperatorWindowBoundary.java +++ b/src/main/java/io/reactivex/internal/operators/OperatorWindowBoundary.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -40,7 +40,7 @@ public OperatorWindowBoundary(Publisher other, int bufferSize) { @Override public Subscriber apply(Subscriber> t) { - return new WindowBoundaryMainSubscriber<>(new SerializedSubscriber<>(t), other, bufferSize); + return new WindowBoundaryMainSubscriber(new SerializedSubscriber>(t), other, bufferSize); } static final class WindowBoundaryMainSubscriber @@ -52,28 +52,25 @@ static final class WindowBoundaryMainSubscriber Subscription s; - volatile Disposable boundary; - @SuppressWarnings("rawtypes") - static final AtomicReferenceFieldUpdater BOUNDARY = - AtomicReferenceFieldUpdater.newUpdater(WindowBoundaryMainSubscriber.class, Disposable.class, "boundary"); + final AtomicReference boundary = new AtomicReference(); - static final Disposable CANCELLED = () -> { }; + static final Disposable CANCELLED = new Disposable() { + @Override + public void dispose() { } + }; UnicastSubject window; static final Object NEXT = new Object(); - volatile long windows; - @SuppressWarnings("rawtypes") - static final AtomicLongFieldUpdater WINDOWS = - AtomicLongFieldUpdater.newUpdater(WindowBoundaryMainSubscriber.class, "windows"); + final AtomicLong windows = new AtomicLong(); public WindowBoundaryMainSubscriber(Subscriber> actual, Publisher other, int bufferSize) { - super(actual, new MpscLinkedQueue<>()); + super(actual, new MpscLinkedQueue()); this.other = other; this.bufferSize = bufferSize; - WINDOWS.lazySet(this, 1); + windows.lazySet(1); } @Override @@ -105,10 +102,10 @@ public void onSubscribe(Subscription s) { window = w; - WindowBoundaryInnerSubscriber inner = new WindowBoundaryInnerSubscriber<>(this); + WindowBoundaryInnerSubscriber inner = new WindowBoundaryInnerSubscriber(this); - if (BOUNDARY.compareAndSet(this, null, inner)) { - WINDOWS.getAndIncrement(this); + if (boundary.compareAndSet(null, inner)) { + windows.getAndIncrement(); s.request(Long.MAX_VALUE); other.subscribe(inner); } @@ -145,7 +142,7 @@ public void onError(Throwable t) { drainLoop(); } - if (WINDOWS.decrementAndGet(this) == 0) { + if (windows.decrementAndGet() == 0) { dispose(); } @@ -162,7 +159,7 @@ public void onComplete() { drainLoop(); } - if (WINDOWS.decrementAndGet(this) == 0) { + if (windows.decrementAndGet() == 0) { dispose(); } @@ -183,9 +180,9 @@ public void cancel() { } void dispose() { - Disposable d = boundary; + Disposable d = boundary.get(); if (d != CANCELLED) { - d = BOUNDARY.getAndSet(this, CANCELLED); + d = boundary.getAndSet(CANCELLED); if (d != CANCELLED && d != null) { d.dispose(); } @@ -224,7 +221,7 @@ void drainLoop() { if (o == NEXT) { w.onComplete(); - if (WINDOWS.decrementAndGet(this) == 0) { + if (windows.decrementAndGet() == 0) { dispose(); return; } @@ -237,7 +234,7 @@ void drainLoop() { long r = requested(); if (r != 0L) { - WINDOWS.getAndIncrement(this); + windows.getAndIncrement(); a.onNext(w); if (r != Long.MAX_VALUE) { @@ -254,7 +251,7 @@ void drainLoop() { continue; } - w.onNext(NotificationLite.getValue(o)); + w.onNext(NotificationLite.getValue(o)); } missed = leave(-missed); diff --git a/src/main/java/io/reactivex/internal/operators/OperatorWindowBoundarySelector.java b/src/main/java/io/reactivex/internal/operators/OperatorWindowBoundarySelector.java index 834c95ae7a..9669ba3e26 100644 --- a/src/main/java/io/reactivex/internal/operators/OperatorWindowBoundarySelector.java +++ b/src/main/java/io/reactivex/internal/operators/OperatorWindowBoundarySelector.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -15,13 +15,13 @@ import java.util.*; import java.util.concurrent.atomic.*; -import java.util.function.Function; import org.reactivestreams.*; import io.reactivex.Observable; import io.reactivex.Observable.Operator; -import io.reactivex.disposables.Disposable; +import io.reactivex.disposables.*; +import io.reactivex.functions.Function; import io.reactivex.internal.disposables.SetCompositeResource; import io.reactivex.internal.queue.MpscLinkedQueue; import io.reactivex.internal.subscribers.*; @@ -45,8 +45,8 @@ public OperatorWindowBoundarySelector(Publisher open, Function apply(Subscriber> t) { - return new WindowBoundaryMainSubscriber<>( - new SerializedSubscriber<>(t), + return new WindowBoundaryMainSubscriber( + new SerializedSubscriber>(t), open, close, bufferSize); } @@ -60,29 +60,26 @@ static final class WindowBoundaryMainSubscriber Subscription s; - volatile Disposable boundary; - @SuppressWarnings("rawtypes") - static final AtomicReferenceFieldUpdater BOUNDARY = - AtomicReferenceFieldUpdater.newUpdater(WindowBoundaryMainSubscriber.class, Disposable.class, "boundary"); + final AtomicReference boundary = new AtomicReference(); - static final Disposable CANCELLED = () -> { }; + static final Disposable CANCELLED = new Disposable() { + @Override + public void dispose() { } + }; final List> ws; - volatile long windows; - @SuppressWarnings("rawtypes") - static final AtomicLongFieldUpdater WINDOWS = - AtomicLongFieldUpdater.newUpdater(WindowBoundaryMainSubscriber.class, "windows"); + final AtomicLong windows = new AtomicLong(); public WindowBoundaryMainSubscriber(Subscriber> actual, Publisher open, Function> close, int bufferSize) { - super(actual, new MpscLinkedQueue<>()); + super(actual, new MpscLinkedQueue()); this.open = open; this.close = close; this.bufferSize = bufferSize; - this.resources = new SetCompositeResource<>(Disposable::dispose); - this.ws = new ArrayList<>(); - WINDOWS.lazySet(this, 1); + this.resources = new SetCompositeResource(Disposables.consumeAndDispose()); + this.ws = new ArrayList>(); + windows.lazySet(1); } @Override @@ -99,10 +96,10 @@ public void onSubscribe(Subscription s) { return; } - OperatorWindowBoundaryOpenSubscriber os = new OperatorWindowBoundaryOpenSubscriber<>(this); + OperatorWindowBoundaryOpenSubscriber os = new OperatorWindowBoundaryOpenSubscriber(this); - if (BOUNDARY.compareAndSet(this, null, os)) { - WINDOWS.getAndIncrement(this); + if (boundary.compareAndSet(null, os)) { + windows.getAndIncrement(); s.request(Long.MAX_VALUE); open.subscribe(os); } @@ -140,7 +137,7 @@ public void onError(Throwable t) { drainLoop(); } - if (WINDOWS.decrementAndGet(this) == 0) { + if (windows.decrementAndGet() == 0) { resources.dispose(); } @@ -158,7 +155,7 @@ public void onComplete() { drainLoop(); } - if (WINDOWS.decrementAndGet(this) == 0) { + if (windows.decrementAndGet() == 0) { resources.dispose(); } @@ -168,7 +165,7 @@ public void onComplete() { void complete() { - if (WINDOWS.decrementAndGet(this) == 0) { + if (windows.decrementAndGet() == 0) { s.cancel(); resources.dispose(); } @@ -177,7 +174,7 @@ void complete() { } void error(Throwable t) { - if (WINDOWS.decrementAndGet(this) == 0) { + if (windows.decrementAndGet() == 0) { s.cancel(); resources.dispose(); } @@ -199,9 +196,9 @@ public void cancel() { void dispose() { resources.dispose(); - Disposable d = boundary; + Disposable d = boundary.get(); if (d != CANCELLED) { - d = BOUNDARY.getAndSet(this, CANCELLED); + d = boundary.getAndSet(CANCELLED); if (d != CANCELLED && d != null) { d.dispose(); } @@ -251,7 +248,7 @@ void drainLoop() { if (ws.remove(wo.w)) { wo.w.onComplete(); - if (WINDOWS.decrementAndGet(this) == 0) { + if (windows.decrementAndGet() == 0) { dispose(); return; } @@ -295,10 +292,10 @@ void drainLoop() { continue; } - OperatorWindowBoundaryCloseSubscriber cl = new OperatorWindowBoundaryCloseSubscriber<>(this, w); + OperatorWindowBoundaryCloseSubscriber cl = new OperatorWindowBoundaryCloseSubscriber(this, w); if (resources.add(cl)) { - WINDOWS.getAndIncrement(this); + windows.getAndIncrement(); p.subscribe(cl); } @@ -307,7 +304,7 @@ void drainLoop() { } for (UnicastSubject w : ws) { - w.onNext(NotificationLite.getValue(o)); + w.onNext(NotificationLite.getValue(o)); } } @@ -325,7 +322,7 @@ public boolean accept(Subscriber> a, Object v) { } void open(B b) { - queue.offer(new WindowOperation<>(null, b)); + queue.offer(new WindowOperation(null, b)); if (enter()) { drainLoop(); } @@ -333,7 +330,7 @@ void open(B b) { void close(OperatorWindowBoundaryCloseSubscriber w) { resources.delete(w); - queue.offer(new WindowOperation<>(w.w, null)); + queue.offer(new WindowOperation(w.w, null)); if (enter()) { drainLoop(); } diff --git a/src/main/java/io/reactivex/internal/operators/OperatorWindowBoundarySupplier.java b/src/main/java/io/reactivex/internal/operators/OperatorWindowBoundarySupplier.java index f556dded11..39ab3c51ab 100644 --- a/src/main/java/io/reactivex/internal/operators/OperatorWindowBoundarySupplier.java +++ b/src/main/java/io/reactivex/internal/operators/OperatorWindowBoundarySupplier.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -15,13 +15,13 @@ import java.util.Queue; import java.util.concurrent.atomic.*; -import java.util.function.Supplier; import org.reactivestreams.*; import io.reactivex.Observable; import io.reactivex.Observable.Operator; import io.reactivex.disposables.Disposable; +import io.reactivex.functions.Supplier; import io.reactivex.internal.queue.MpscLinkedQueue; import io.reactivex.internal.subscribers.*; import io.reactivex.internal.subscriptions.SubscriptionHelper; @@ -41,7 +41,7 @@ public OperatorWindowBoundarySupplier(Supplier> other, in @Override public Subscriber apply(Subscriber> t) { - return new WindowBoundaryMainSubscriber<>(new SerializedSubscriber<>(t), other, bufferSize); + return new WindowBoundaryMainSubscriber(new SerializedSubscriber>(t), other, bufferSize); } static final class WindowBoundaryMainSubscriber @@ -53,28 +53,25 @@ static final class WindowBoundaryMainSubscriber Subscription s; - volatile Disposable boundary; - @SuppressWarnings("rawtypes") - static final AtomicReferenceFieldUpdater BOUNDARY = - AtomicReferenceFieldUpdater.newUpdater(WindowBoundaryMainSubscriber.class, Disposable.class, "boundary"); + final AtomicReference boundary = new AtomicReference(); - static final Disposable CANCELLED = () -> { }; + static final Disposable CANCELLED = new Disposable() { + @Override + public void dispose() { } + }; UnicastSubject window; static final Object NEXT = new Object(); - volatile long windows; - @SuppressWarnings("rawtypes") - static final AtomicLongFieldUpdater WINDOWS = - AtomicLongFieldUpdater.newUpdater(WindowBoundaryMainSubscriber.class, "windows"); + final AtomicLong windows = new AtomicLong(); public WindowBoundaryMainSubscriber(Subscriber> actual, Supplier> other, int bufferSize) { - super(actual, new MpscLinkedQueue<>()); + super(actual, new MpscLinkedQueue()); this.other = other; this.bufferSize = bufferSize; - WINDOWS.lazySet(this, 1); + windows.lazySet(1); } @Override @@ -123,10 +120,10 @@ public void onSubscribe(Subscription s) { window = w; - WindowBoundaryInnerSubscriber inner = new WindowBoundaryInnerSubscriber<>(this); + WindowBoundaryInnerSubscriber inner = new WindowBoundaryInnerSubscriber(this); - if (BOUNDARY.compareAndSet(this, null, inner)) { - WINDOWS.getAndIncrement(this); + if (boundary.compareAndSet(null, inner)) { + windows.getAndIncrement(); s.request(Long.MAX_VALUE); p.subscribe(inner); return; @@ -164,7 +161,7 @@ public void onError(Throwable t) { drainLoop(); } - if (WINDOWS.decrementAndGet(this) == 0) { + if (windows.decrementAndGet() == 0) { dispose(); } @@ -181,7 +178,7 @@ public void onComplete() { drainLoop(); } - if (WINDOWS.decrementAndGet(this) == 0) { + if (windows.decrementAndGet() == 0) { dispose(); } @@ -202,9 +199,9 @@ public void cancel() { } void dispose() { - Disposable d = boundary; + Disposable d = boundary.get(); if (d != CANCELLED) { - d = BOUNDARY.getAndSet(this, CANCELLED); + d = boundary.getAndSet(CANCELLED); if (d != CANCELLED && d != null) { d.dispose(); } @@ -242,7 +239,7 @@ void drainLoop() { if (o == NEXT) { w.onComplete(); - if (WINDOWS.decrementAndGet(this) == 0) { + if (windows.decrementAndGet() == 0) { dispose(); return; } @@ -271,7 +268,7 @@ void drainLoop() { long r = requested(); if (r != 0L) { - WINDOWS.getAndIncrement(this); + windows.getAndIncrement(); a.onNext(w); if (r != Long.MAX_VALUE) { @@ -286,16 +283,16 @@ void drainLoop() { window = w; - WindowBoundaryInnerSubscriber b = new WindowBoundaryInnerSubscriber<>(this); + WindowBoundaryInnerSubscriber b = new WindowBoundaryInnerSubscriber(this); - if (BOUNDARY.compareAndSet(this, boundary, b)) { + if (boundary.compareAndSet(boundary.get(), b)) { p.subscribe(b); } continue; } - w.onNext(NotificationLite.getValue(o)); + w.onNext(NotificationLite.getValue(o)); } missed = leave(-missed); diff --git a/src/main/java/io/reactivex/internal/operators/OperatorWindowTimed.java b/src/main/java/io/reactivex/internal/operators/OperatorWindowTimed.java index d6c384e2b3..d82811e63e 100644 --- a/src/main/java/io/reactivex/internal/operators/OperatorWindowTimed.java +++ b/src/main/java/io/reactivex/internal/operators/OperatorWindowTimed.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -16,7 +16,7 @@ import java.nio.channels.CancelledKeyException; import java.util.*; import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; +import java.util.concurrent.atomic.*; import org.reactivestreams.*; @@ -54,20 +54,20 @@ public OperatorWindowTimed(long timespan, long timeskip, TimeUnit unit, Schedule @Override public Subscriber apply(Subscriber> t) { - SerializedSubscriber> actual = new SerializedSubscriber<>(t); + SerializedSubscriber> actual = new SerializedSubscriber>(t); if (timespan == timeskip) { if (maxSize == Long.MAX_VALUE) { - return new WindowExactUnboundedSubscriber<>( + return new WindowExactUnboundedSubscriber( actual, timespan, unit, scheduler, bufferSize); } - return new WindowExactBoundedSubscriber<>( + return new WindowExactBoundedSubscriber( actual, timespan, unit, scheduler, bufferSize, maxSize, restartTimerOnMaxSize); } - return new WindowSkipSubscriber<>(actual, + return new WindowSkipSubscriber(actual, timespan, timeskip, unit, scheduler.createWorker(), bufferSize); } @@ -85,12 +85,12 @@ static final class WindowExactUnboundedSubscriber UnicastSubject window; - volatile Disposable timer; - @SuppressWarnings("rawtypes") - static final AtomicReferenceFieldUpdater TIMER = - AtomicReferenceFieldUpdater.newUpdater(WindowExactUnboundedSubscriber.class, Disposable.class, "timer"); + final AtomicReference timer = new AtomicReference(); - static final Disposable CANCELLED = () -> { }; + static final Disposable CANCELLED = new Disposable() { + @Override + public void dispose() { } + }; static final Object NEXT = new Object(); @@ -98,7 +98,7 @@ static final class WindowExactUnboundedSubscriber public WindowExactUnboundedSubscriber(Subscriber> actual, long timespan, TimeUnit unit, Scheduler scheduler, int bufferSize) { - super(actual, new MpscLinkedQueue<>()); + super(actual, new MpscLinkedQueue()); this.timespan = timespan; this.unit = unit; this.scheduler = scheduler; @@ -132,7 +132,7 @@ public void onSubscribe(Subscription s) { if (!cancelled) { Disposable d = scheduler.schedulePeriodicallyDirect(this, timespan, timespan, unit); - if (!TIMER.compareAndSet(this, null, d)) { + if (!timer.compareAndSet(null, d)) { d.dispose(); return; } @@ -196,9 +196,9 @@ public void cancel() { @Override public void dispose() { selfCancel = true; - Disposable d = timer; + Disposable d = timer.get(); if (d != CANCELLED) { - d = TIMER.getAndSet(this, CANCELLED); + d = timer.getAndSet(CANCELLED); if (d != CANCELLED && d != null) { d.dispose(); } @@ -282,7 +282,7 @@ void drainLoop() { continue; } - w.onNext(NotificationLite.getValue(o)); + w.onNext(NotificationLite.getValue(o)); } missed = leave(-missed); @@ -323,18 +323,18 @@ static final class WindowExactBoundedSubscriber volatile boolean terminated; - volatile Disposable timer; - @SuppressWarnings("rawtypes") - static final AtomicReferenceFieldUpdater TIMER = - AtomicReferenceFieldUpdater.newUpdater(WindowExactBoundedSubscriber.class, Disposable.class, "timer"); + final AtomicReference timer = new AtomicReference(); - static final Disposable CANCELLED = () -> { }; + static final Disposable CANCELLED = new Disposable() { + @Override + public void dispose() { } + }; public WindowExactBoundedSubscriber( Subscriber> actual, long timespan, TimeUnit unit, Scheduler scheduler, int bufferSize, long maxSize, boolean restartTimerOnMaxSize) { - super(actual, new MpscLinkedQueue<>()); + super(actual, new MpscLinkedQueue()); this.timespan = timespan; this.unit = unit; this.scheduler = scheduler; @@ -385,7 +385,7 @@ public void onSubscribe(Subscription s) { d = scheduler.schedulePeriodicallyDirect(consumerIndexHolder, timespan, timespan, unit); } - if (!TIMER.compareAndSet(this, null, d)) { + if (!timer.compareAndSet(null, d)) { d.dispose(); return; } @@ -420,12 +420,12 @@ public void onNext(T t) { produced(1); } if (restartTimerOnMaxSize) { - timer.dispose(); + Disposable tm = timer.get(); - Disposable tm = timer; + tm.dispose(); Disposable task = worker.schedulePeriodically( new ConsumerIndexHolder(producerIndex, this), timespan, timespan, unit); - if (!TIMER.compareAndSet(this, tm, task)) { + if (!timer.compareAndSet(tm, task)) { task.dispose(); } } @@ -490,9 +490,9 @@ public void cancel() { @Override public void dispose() { selfCancel = true; - Disposable d = timer; + Disposable d = timer.get(); if (d != CANCELLED) { - d = TIMER.getAndSet(this, CANCELLED); + d = timer.getAndSet(CANCELLED); if (d != CANCELLED && d != null) { d.dispose(); } @@ -569,7 +569,7 @@ void drainLoop() { continue; } - w.onNext(NotificationLite.getValue(o)); + w.onNext(NotificationLite.getValue(o)); long c = count + 1; if (c >= maxSize) { @@ -589,12 +589,12 @@ void drainLoop() { } if (restartTimerOnMaxSize) { - timer.dispose(); + Disposable tm = timer.get(); + tm.dispose(); - Disposable tm = timer; Disposable task = worker.schedulePeriodically( new ConsumerIndexHolder(producerIndex, this), timespan, timespan, unit); - if (!TIMER.compareAndSet(this, tm, task)) { + if (!timer.compareAndSet(tm, task)) { task.dispose(); } } @@ -664,13 +664,13 @@ static final class WindowSkipSubscriber public WindowSkipSubscriber(Subscriber> actual, long timespan, long timeskip, TimeUnit unit, Worker worker, int bufferSize) { - super(actual, new MpscLinkedQueue<>()); + super(actual, new MpscLinkedQueue()); this.timespan = timespan; this.timeskip = timeskip; this.unit = unit; this.worker = worker; this.bufferSize = bufferSize; - this.windows = new LinkedList<>(); + this.windows = new LinkedList>(); } @Override @@ -689,15 +689,18 @@ public void onSubscribe(Subscription s) { long r = requested(); if (r != 0L) { - UnicastSubject w = UnicastSubject.create(bufferSize); + final UnicastSubject w = UnicastSubject.create(bufferSize); windows.add(w); actual.onNext(w); if (r != Long.MAX_VALUE) { produced(1); } - worker.schedule(() -> { - complete(w); + worker.schedule(new Runnable() { + @Override + public void run() { + complete(w); + } }, timespan, unit); worker.schedulePeriodically(this, timeskip, timeskip, unit); @@ -776,7 +779,7 @@ public boolean accept(Subscriber> a, Object v) { } void complete(UnicastSubject w) { - queue.offer(new SubjectWork<>(w, false)); + queue.offer(new SubjectWork(w, false)); if (enter()) { drainLoop(); } @@ -839,15 +842,18 @@ void drainLoop() { long r = requested(); if (r != 0L) { - UnicastSubject w = UnicastSubject.create(bufferSize); + final UnicastSubject w = UnicastSubject.create(bufferSize); ws.add(w); a.onNext(w); if (r != Long.MAX_VALUE) { produced(1); } - worker.schedule(() -> { - complete(w); + worker.schedule(new Runnable() { + @Override + public void run() { + complete(w); + } }, timespan, unit); } else { a.onError(new IllegalStateException("Can't emit window due to lack of requests")); @@ -864,7 +870,7 @@ void drainLoop() { } for (UnicastSubject w : ws) { - w.onNext(NotificationLite.getValue(v)); + w.onNext(NotificationLite.getValue(v)); } } @@ -880,7 +886,7 @@ public void run() { UnicastSubject w = UnicastSubject.create(bufferSize); - SubjectWork sw = new SubjectWork<>(w, true); + SubjectWork sw = new SubjectWork(w, true); if (!cancelled) { queue.offer(sw); } diff --git a/src/main/java/io/reactivex/internal/operators/OperatorWithLatestFrom.java b/src/main/java/io/reactivex/internal/operators/OperatorWithLatestFrom.java index 3654c74e93..01f9cfbdcd 100644 --- a/src/main/java/io/reactivex/internal/operators/OperatorWithLatestFrom.java +++ b/src/main/java/io/reactivex/internal/operators/OperatorWithLatestFrom.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -14,11 +14,11 @@ package io.reactivex.internal.operators; import java.util.concurrent.atomic.*; -import java.util.function.BiFunction; import org.reactivestreams.*; import io.reactivex.Observable.Operator; +import io.reactivex.functions.BiFunction; import io.reactivex.internal.subscriptions.*; import io.reactivex.plugins.RxJavaPlugins; import io.reactivex.subscribers.SerializedSubscriber; @@ -33,8 +33,8 @@ public OperatorWithLatestFrom(BiFunction comb @Override public Subscriber apply(Subscriber t) { - SerializedSubscriber serial = new SerializedSubscriber<>(t); - WithLatestFromSubscriber wlf = new WithLatestFromSubscriber<>(serial, combiner); + final SerializedSubscriber serial = new SerializedSubscriber(t); + final WithLatestFromSubscriber wlf = new WithLatestFromSubscriber(serial, combiner); other.subscribe(new Subscriber() { @Override @@ -70,15 +70,9 @@ static final class WithLatestFromSubscriber extends AtomicReference final Subscriber actual; final BiFunction combiner; - volatile Subscription s; - @SuppressWarnings("rawtypes") - static final AtomicReferenceFieldUpdater S = - AtomicReferenceFieldUpdater.newUpdater(WithLatestFromSubscriber.class, Subscription.class, "s"); + final AtomicReference s = new AtomicReference(); - volatile Subscription other; - @SuppressWarnings("rawtypes") - static final AtomicReferenceFieldUpdater OTHER = - AtomicReferenceFieldUpdater.newUpdater(WithLatestFromSubscriber.class, Subscription.class, "other"); + final AtomicReference other = new AtomicReference(); static final Subscription CANCELLED = new Subscription() { @Override @@ -98,11 +92,11 @@ public WithLatestFromSubscriber(Subscriber actual, BiFunction s) { return; } - AmbCoordinator ac = new AmbCoordinator<>(s, count); + AmbCoordinator ac = new AmbCoordinator(s, count); ac.subscribe(sources); } @@ -66,10 +66,7 @@ static final class AmbCoordinator implements Subscription { final Subscriber actual; final AmbInnerSubscriber[] subscribers; - volatile int winner; - @SuppressWarnings("rawtypes") - static final AtomicIntegerFieldUpdater WINNER = - AtomicIntegerFieldUpdater.newUpdater(AmbCoordinator.class, "winner"); + final AtomicInteger winner = new AtomicInteger(); @SuppressWarnings("unchecked") public AmbCoordinator(Subscriber actual, int count) { @@ -81,13 +78,13 @@ public void subscribe(Publisher[] sources) { AmbInnerSubscriber[] as = subscribers; int len = as.length; for (int i = 0; i < len; i++) { - as[i] = new AmbInnerSubscriber<>(this, i + 1, actual); + as[i] = new AmbInnerSubscriber(this, i + 1, actual); } - WINNER.lazySet(this, 0); // release the contents of 'as' + winner.lazySet(0); // release the contents of 'as' actual.onSubscribe(this); for (int i = 0; i < len; i++) { - if (winner != 0) { + if (winner.get() != 0) { return; } @@ -101,7 +98,7 @@ public void request(long n) { return; } - int w = winner; + int w = winner.get(); if (w > 0) { subscribers[w - 1].request(n); } else @@ -113,9 +110,16 @@ public void request(long n) { } public boolean win(int index) { - int w = winner; + int w = winner.get(); if (w == 0) { - if (WINNER.compareAndSet(this, 0, index)) { + if (winner.compareAndSet(0, index)) { + AmbInnerSubscriber[] a = subscribers; + int n = a.length; + for (int i = 0; i < n; i++) { + if (i + 1 != index) { + a[i].cancel(); + } + } return true; } return false; @@ -125,8 +129,8 @@ public boolean win(int index) { @Override public void cancel() { - if (winner != -1) { - WINNER.lazySet(this, -1); + if (winner.get() != -1) { + winner.lazySet(-1); for (AmbInnerSubscriber a : subscribers) { a.cancel(); @@ -144,10 +148,7 @@ static final class AmbInnerSubscriber extends AtomicReference i boolean won; - volatile long missedRequested; - @SuppressWarnings("rawtypes") - static final AtomicLongFieldUpdater MISSED_REQUESTED = - AtomicLongFieldUpdater.newUpdater(AmbInnerSubscriber.class, "missedRequested"); + final AtomicLong missedRequested = new AtomicLong(); static final Subscription CANCELLED = new Subscription() { @Override @@ -177,7 +178,7 @@ public void onSubscribe(Subscription s) { return; } - long r = MISSED_REQUESTED.getAndSet(this, 0L); + long r = missedRequested.getAndSet(0L); if (r != 0L) { s.request(r); } @@ -189,10 +190,13 @@ public void request(long n) { if (s != null) { s.request(n); } else { - BackpressureHelper.add(MISSED_REQUESTED, this, n); + if (SubscriptionHelper.validateRequest(n)) { + return; + } + BackpressureHelper.add(missedRequested, n); s = get(); if (s != null && s != CANCELLED) { - long r = MISSED_REQUESTED.getAndSet(this, 0L); + long r = missedRequested.getAndSet(0L); if (r != 0L) { s.request(r); } @@ -255,4 +259,4 @@ public void cancel() { } } -} +} \ No newline at end of file diff --git a/src/main/java/io/reactivex/internal/operators/PublisherArraySource.java b/src/main/java/io/reactivex/internal/operators/PublisherArraySource.java index da2412defa..535b5c09be 100644 --- a/src/main/java/io/reactivex/internal/operators/PublisherArraySource.java +++ b/src/main/java/io/reactivex/internal/operators/PublisherArraySource.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -21,9 +21,6 @@ import io.reactivex.internal.subscriptions.SubscriptionHelper; import io.reactivex.internal.util.BackpressureHelper; -/** - * - */ public final class PublisherArraySource implements Publisher { final T[] array; public PublisherArraySource(T[] array) { @@ -36,9 +33,9 @@ public T[] array() { public void subscribe(Subscriber s) { if (s instanceof ConditionalSubscriber) { ConditionalSubscriber cs = (ConditionalSubscriber) s; - s.onSubscribe(new ConditionalArraySourceSubscription<>(array, cs)); + s.onSubscribe(new ConditionalArraySourceSubscription(array, cs)); } else { - s.onSubscribe(new ArraySourceSubscription<>(array, s)); + s.onSubscribe(new ArraySourceSubscription(array, s)); } } @@ -74,7 +71,12 @@ public void request(long n) { return; } for (int j = i; j < len; j++) { - s.onNext(a[j]); + T t = a[j]; + if (t == null) { + s.onError(new NullPointerException("The " + j + "th array element is null")); + return; + } + s.onNext(t); if (cancelled) { return; } @@ -87,7 +89,12 @@ public void request(long n) { return; } while (r != 0 && i < len) { - s.onNext(a[i]); + T t = a[i]; + if (t == null) { + s.onError(new NullPointerException("The " + i + "th array element is null")); + return; + } + s.onNext(t); if (cancelled) { return; } @@ -144,7 +151,12 @@ public void request(long n) { return; } for (int j = i; j < len; j++) { - s.onNext(a[j]); + T t = a[j]; + if (t == null) { + s.onError(new NullPointerException("The " + j + "th array element is null")); + return; + } + s.onNext(t); if (cancelled) { return; } diff --git a/src/main/java/io/reactivex/internal/operators/PublisherAutoConnect.java b/src/main/java/io/reactivex/internal/operators/PublisherAutoConnect.java index ffff7eb306..8ae4f9bb16 100644 --- a/src/main/java/io/reactivex/internal/operators/PublisherAutoConnect.java +++ b/src/main/java/io/reactivex/internal/operators/PublisherAutoConnect.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -14,11 +14,11 @@ package io.reactivex.internal.operators; import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.Consumer; import org.reactivestreams.*; import io.reactivex.disposables.Disposable; +import io.reactivex.functions.Consumer; import io.reactivex.observables.ConnectableObservable; /** diff --git a/src/main/java/io/reactivex/internal/operators/PublisherCombineLatest.java b/src/main/java/io/reactivex/internal/operators/PublisherCombineLatest.java index 36718e2843..73915ad5c1 100644 --- a/src/main/java/io/reactivex/internal/operators/PublisherCombineLatest.java +++ b/src/main/java/io/reactivex/internal/operators/PublisherCombineLatest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -15,10 +15,11 @@ import java.util.*; import java.util.concurrent.atomic.*; -import java.util.function.Function; import org.reactivestreams.*; +import io.reactivex.exceptions.CompositeException; +import io.reactivex.functions.Function; import io.reactivex.internal.queue.SpscLinkedArrayQueue; import io.reactivex.internal.subscriptions.*; import io.reactivex.internal.util.BackpressureHelper; @@ -67,7 +68,7 @@ public void subscribe(Subscriber s) { return; } - LatestCoordinator lc = new LatestCoordinator<>(s, combiner, count, bufferSize, delayError); + LatestCoordinator lc = new LatestCoordinator(s, combiner, count, bufferSize, delayError); lc.subscribe(sources); } @@ -87,16 +88,9 @@ static final class LatestCoordinator extends AtomicInteger implements Subs volatile boolean done; - volatile long requested; - @SuppressWarnings("rawtypes") - static final AtomicLongFieldUpdater REQUESTED = - AtomicLongFieldUpdater.newUpdater(LatestCoordinator.class, "requested"); + final AtomicLong requested = new AtomicLong(); - volatile Throwable error; - @SuppressWarnings("rawtypes") - static final AtomicReferenceFieldUpdater ERROR = - AtomicReferenceFieldUpdater.newUpdater(LatestCoordinator.class, Throwable.class, "error"); - + final AtomicReference error = new AtomicReference(); int active; int complete; @@ -112,14 +106,14 @@ public LatestCoordinator(Subscriber actual, this.delayError = delayError; this.latest = new Object[count]; this.subscribers = new CombinerSubscriber[count]; - this.queue = new SpscLinkedArrayQueue<>(bufferSize); + this.queue = new SpscLinkedArrayQueue(bufferSize); } public void subscribe(Publisher[] sources) { Subscriber[] as = subscribers; int len = as.length; for (int i = 0; i < len; i++) { - as[i] = new CombinerSubscriber<>(this, i); + as[i] = new CombinerSubscriber(this, i); } lazySet(0); // release array contents actual.onSubscribe(this); @@ -136,7 +130,7 @@ public void request(long n) { if (SubscriptionHelper.validateRequest(n)) { return; } - BackpressureHelper.add(REQUESTED, this, n); + BackpressureHelper.add(requested, n); drain(); } @@ -197,7 +191,7 @@ void combine(T value, int index) { if (value != null && f) { queue.offer(cs, latest.clone()); } else - if (value == null && error != null) { + if (value == null && error.get() != null) { done = true; // if this source completed without a value } } else { @@ -226,7 +220,7 @@ void drain() { return; } - long r = requested; + long r = requested.get(); boolean unbounded = r == Long.MAX_VALUE; long e = 0L; @@ -265,6 +259,13 @@ void drain() { return; } + if (v == null) { + cancelled = true; + cancel(q); + a.onError(new NullPointerException("The combiner returned a null")); + return; + } + a.onNext(v); cs.request(1); @@ -275,7 +276,7 @@ void drain() { if (e != 0L) { if (!unbounded) { - REQUESTED.addAndGet(this, e); + requested.addAndGet(e); } } @@ -296,7 +297,7 @@ boolean checkTerminated(boolean d, boolean empty, Subscriber a, Queue q, b if (delayError) { if (empty) { clear(queue); - Throwable e = error; + Throwable e = error.get(); if (e != null) { a.onError(e); } else { @@ -305,7 +306,7 @@ boolean checkTerminated(boolean d, boolean empty, Subscriber a, Queue q, b return true; } } else { - Throwable e = error; + Throwable e = error.get(); if (e != null) { cancel(q); a.onError(e); @@ -323,12 +324,14 @@ boolean checkTerminated(boolean d, boolean empty, Subscriber a, Queue q, b void onError(Throwable e) { for (;;) { - Throwable curr = error; + Throwable curr = error.get(); if (curr != null) { - e.addSuppressed(curr); + CompositeException ex = new CompositeException(); + ex.suppress(curr); + e = ex; } Throwable next = e; - if (ERROR.compareAndSet(this, curr, next)) { + if (error.compareAndSet(curr, next)) { return; } } @@ -341,10 +344,7 @@ static final class CombinerSubscriber implements Subscriber, Subscripti boolean done; - volatile Subscription s; - @SuppressWarnings("rawtypes") - static final AtomicReferenceFieldUpdater S = - AtomicReferenceFieldUpdater.newUpdater(CombinerSubscriber.class, Subscription.class, "s"); + final AtomicReference s = new AtomicReference(); static final Subscription CANCELLED = new Subscription() { @Override @@ -365,9 +365,9 @@ public CombinerSubscriber(LatestCoordinator parent, int index) { @Override public void onSubscribe(Subscription s) { - if (!S.compareAndSet(this, null, s)) { + if (!this.s.compareAndSet(null, s)) { s.cancel(); - if (s != CANCELLED) { + if (this.s.get() != CANCELLED) { SubscriptionHelper.reportSubscriptionSet(); } return; @@ -405,18 +405,18 @@ public void onComplete() { @Override public void request(long n) { - s.request(n); + s.get().request(n); } @Override public void cancel() { - Subscription a = s; + Subscription a = s.get(); if (a != CANCELLED) { - a = S.getAndSet(this, CANCELLED); + a = s.getAndSet(CANCELLED); if (a != CANCELLED && a != null) { a.cancel(); } } } } -} +} \ No newline at end of file diff --git a/src/main/java/io/reactivex/internal/operators/PublisherCompletableFutureSource.java b/src/main/java/io/reactivex/internal/operators/PublisherCompletableFutureSource.java deleted file mode 100644 index e3891ff018..0000000000 --- a/src/main/java/io/reactivex/internal/operators/PublisherCompletableFutureSource.java +++ /dev/null @@ -1,46 +0,0 @@ -/** - * 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 io.reactivex.internal.operators; - -import java.util.concurrent.CompletableFuture; - -import org.reactivestreams.*; - -import io.reactivex.internal.subscriptions.ScalarAsyncSubscription; - -/** - * - */ -public final class PublisherCompletableFutureSource implements Publisher { - final CompletableFuture future; - public PublisherCompletableFutureSource(CompletableFuture future) { - this.future = future; - } - @Override - public void subscribe(Subscriber s) { - ScalarAsyncSubscription sub = new ScalarAsyncSubscription<>(s); - s.onSubscribe(sub); - - future.whenComplete((v, e) -> { - if (e != null) { - s.onError(e); - } else - if (v == null) { - s.onError(new NullPointerException()); - } else { - sub.setValue(v); - } - }); - } -} diff --git a/src/main/java/io/reactivex/internal/operators/PublisherDefer.java b/src/main/java/io/reactivex/internal/operators/PublisherDefer.java index 5734e12638..527bbca205 100644 --- a/src/main/java/io/reactivex/internal/operators/PublisherDefer.java +++ b/src/main/java/io/reactivex/internal/operators/PublisherDefer.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,15 +13,11 @@ package io.reactivex.internal.operators; -import java.util.function.Supplier; - import org.reactivestreams.*; +import io.reactivex.functions.Supplier; import io.reactivex.internal.subscriptions.EmptySubscription; -/** - * - */ public final class PublisherDefer implements Publisher { final Supplier> supplier; public PublisherDefer(Supplier> supplier) { diff --git a/src/main/java/io/reactivex/internal/operators/PublisherDelaySubscriptionOther.java b/src/main/java/io/reactivex/internal/operators/PublisherDelaySubscriptionOther.java new file mode 100644 index 0000000000..9f3c8203e9 --- /dev/null +++ b/src/main/java/io/reactivex/internal/operators/PublisherDelaySubscriptionOther.java @@ -0,0 +1,107 @@ +/** + * 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.internal.operators; + +import org.reactivestreams.*; + +import io.reactivex.internal.subscriptions.SubscriptionArbiter; +import io.reactivex.plugins.RxJavaPlugins; + +/** + * Delays the subscription to the main source until the other + * observable fires an event or completes. + * @param the main type + * @param the other value type, ignored + */ +public final class PublisherDelaySubscriptionOther implements Publisher { + final Publisher main; + final Publisher other; + + public PublisherDelaySubscriptionOther(Publisher main, Publisher other) { + this.main = main; + this.other = other; + } + + @Override + public void subscribe(final Subscriber child) { + final SubscriptionArbiter serial = new SubscriptionArbiter(); + child.onSubscribe(serial); + + Subscriber otherSubscriber = new Subscriber() { + boolean done; + + @Override + public void onSubscribe(final Subscription s) { + serial.setSubscription(new Subscription() { + @Override + public void request(long n) { + // ignored + } + + @Override + public void cancel() { + s.cancel(); + } + }); + s.request(Long.MAX_VALUE); + } + + @Override + public void onNext(U t) { + onComplete(); + } + + @Override + public void onError(Throwable e) { + if (done) { + RxJavaPlugins.onError(e); + return; + } + done = true; + child.onError(e); + } + + @Override + public void onComplete() { + if (done) { + return; + } + done = true; + + main.subscribe(new Subscriber() { + @Override + public void onSubscribe(Subscription s) { + serial.setSubscription(s); + } + + @Override + public void onNext(T t) { + child.onNext(t); + } + + @Override + public void onError(Throwable t) { + child.onError(t); + } + + @Override + public void onComplete() { + child.onComplete(); + } + }); + } + }; + + other.subscribe(otherSubscriber); + } +} \ No newline at end of file diff --git a/src/main/java/io/reactivex/internal/operators/PublisherEmptySource.java b/src/main/java/io/reactivex/internal/operators/PublisherEmptySource.java index dd9d60194c..23d910135d 100644 --- a/src/main/java/io/reactivex/internal/operators/PublisherEmptySource.java +++ b/src/main/java/io/reactivex/internal/operators/PublisherEmptySource.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 diff --git a/src/main/java/io/reactivex/internal/operators/PublisherErrorSource.java b/src/main/java/io/reactivex/internal/operators/PublisherErrorSource.java index 9470fc4afd..9806afd4c2 100644 --- a/src/main/java/io/reactivex/internal/operators/PublisherErrorSource.java +++ b/src/main/java/io/reactivex/internal/operators/PublisherErrorSource.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,15 +13,11 @@ package io.reactivex.internal.operators; -import java.util.function.Supplier; - import org.reactivestreams.*; +import io.reactivex.functions.Supplier; import io.reactivex.internal.subscriptions.EmptySubscription; -/** - * - */ public final class PublisherErrorSource implements Publisher { final Supplier errorSupplier; public PublisherErrorSource(Supplier errorSupplier) { diff --git a/src/main/java/io/reactivex/internal/operators/PublisherFutureSource.java b/src/main/java/io/reactivex/internal/operators/PublisherFutureSource.java index 58478ab7e4..2ba1e90765 100644 --- a/src/main/java/io/reactivex/internal/operators/PublisherFutureSource.java +++ b/src/main/java/io/reactivex/internal/operators/PublisherFutureSource.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -32,7 +32,7 @@ public PublisherFutureSource(Future future, long timeout, TimeUnit @Override public void subscribe(Subscriber s) { - ScalarAsyncSubscription sas = new ScalarAsyncSubscription<>(s); + ScalarAsyncSubscription sas = new ScalarAsyncSubscription(s); s.onSubscribe(sas); if (!sas.isComplete()) { T v; @@ -46,7 +46,11 @@ public void subscribe(Subscriber s) { } finally { future.cancel(true); // TODO ?? not sure about this } - sas.setValue(v); + if (v == null) { + s.onError(new NullPointerException("The future returned null")); + } else { + sas.setValue(v); + } } } } diff --git a/src/main/java/io/reactivex/internal/operators/PublisherGenerate.java b/src/main/java/io/reactivex/internal/operators/PublisherGenerate.java index 3ee31f9c90..5c2beba60c 100644 --- a/src/main/java/io/reactivex/internal/operators/PublisherGenerate.java +++ b/src/main/java/io/reactivex/internal/operators/PublisherGenerate.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -14,10 +14,10 @@ package io.reactivex.internal.operators; import java.util.concurrent.atomic.AtomicLong; -import java.util.function.*; import org.reactivestreams.*; +import io.reactivex.functions.*; import io.reactivex.internal.subscriptions.*; import io.reactivex.internal.util.BackpressureHelper; import io.reactivex.plugins.RxJavaPlugins; @@ -45,7 +45,7 @@ public void subscribe(Subscriber s) { return; } - s.onSubscribe(new GeneratorSubscription<>(s, generator, disposeState, state)); + s.onSubscribe(new GeneratorSubscription(s, generator, disposeState, state)); } static final class GeneratorSubscription diff --git a/src/main/java/io/reactivex/internal/operators/PublisherIntervalOnceSource.java b/src/main/java/io/reactivex/internal/operators/PublisherIntervalOnceSource.java index c73d8d339b..381b7a4cf8 100644 --- a/src/main/java/io/reactivex/internal/operators/PublisherIntervalOnceSource.java +++ b/src/main/java/io/reactivex/internal/operators/PublisherIntervalOnceSource.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -49,10 +49,16 @@ static final class IntervalOnceSubscriber extends AtomicReference final Subscriber actual; - static final Disposable DISPOSED = () -> { }; + static final Disposable DISPOSED = new Disposable() { + @Override + public void dispose() { } + }; /** This state tells the setResource not to call dispose since the run is finishing anyway. */ - static final Disposable DONE = () -> { }; + static final Disposable DONE = new Disposable() { + @Override + public void dispose() { } + }; volatile boolean requested; diff --git a/src/main/java/io/reactivex/internal/operators/PublisherIntervalRangeSource.java b/src/main/java/io/reactivex/internal/operators/PublisherIntervalRangeSource.java index fa1a7682dd..55feb17261 100644 --- a/src/main/java/io/reactivex/internal/operators/PublisherIntervalRangeSource.java +++ b/src/main/java/io/reactivex/internal/operators/PublisherIntervalRangeSource.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -62,11 +62,12 @@ static final class IntervalRangeSubscriber extends AtomicLong volatile boolean cancelled; - static final Disposable DISPOSED = () -> { }; + static final Disposable DISPOSED = new Disposable() { + @Override + public void dispose() { } + }; - volatile Disposable resource; - static final AtomicReferenceFieldUpdater RESOURCE = - AtomicReferenceFieldUpdater.newUpdater(IntervalRangeSubscriber.class, Disposable.class, "resource"); + final AtomicReference resource = new AtomicReference(); public IntervalRangeSubscriber(Subscriber actual, long start, long end) { this.actual = actual; @@ -93,9 +94,9 @@ public void cancel() { } void disposeResource() { - Disposable d = resource; + Disposable d = resource.get(); if (d != DISPOSED) { - d = RESOURCE.getAndSet(this, DISPOSED); + d = resource.getAndSet(DISPOSED); if (d != DISPOSED && d != null) { d.dispose(); } @@ -139,7 +140,7 @@ public void run() { public void setResource(Disposable d) { for (;;) { - Disposable current = resource; + Disposable current = resource.get(); if (current == DISPOSED) { d.dispose(); return; @@ -148,7 +149,7 @@ public void setResource(Disposable d) { RxJavaPlugins.onError(new IllegalStateException("Resource already set!")); return; } - if (RESOURCE.compareAndSet(this, null, d)) { + if (resource.compareAndSet(null, d)) { return; } } diff --git a/src/main/java/io/reactivex/internal/operators/PublisherIntervalSource.java b/src/main/java/io/reactivex/internal/operators/PublisherIntervalSource.java index 10ae982d3e..37dee8c2e8 100644 --- a/src/main/java/io/reactivex/internal/operators/PublisherIntervalSource.java +++ b/src/main/java/io/reactivex/internal/operators/PublisherIntervalSource.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -59,11 +59,12 @@ static final class IntervalSubscriber extends AtomicLong volatile boolean cancelled; - static final Disposable DISPOSED = () -> { }; + static final Disposable DISPOSED = new Disposable() { + @Override + public void dispose() { } + }; - volatile Disposable resource; - static final AtomicReferenceFieldUpdater RESOURCE = - AtomicReferenceFieldUpdater.newUpdater(IntervalSubscriber.class, Disposable.class, "resource"); + final AtomicReference resource = new AtomicReference(); public IntervalSubscriber(Subscriber actual) { this.actual = actual; @@ -87,9 +88,9 @@ public void cancel() { } void disposeResource() { - Disposable d = resource; + Disposable d = resource.get(); if (d != DISPOSED) { - d = RESOURCE.getAndSet(this, DISPOSED); + d = resource.getAndSet(DISPOSED); if (d != DISPOSED && d != null) { d.dispose(); } @@ -119,7 +120,7 @@ public void run() { public void setResource(Disposable d) { for (;;) { - Disposable current = resource; + Disposable current = resource.get(); if (current == DISPOSED) { d.dispose(); return; @@ -128,7 +129,7 @@ public void setResource(Disposable d) { RxJavaPlugins.onError(new IllegalStateException("Resource already set!")); return; } - if (RESOURCE.compareAndSet(this, null, d)) { + if (resource.compareAndSet(null, d)) { return; } } diff --git a/src/main/java/io/reactivex/internal/operators/PublisherIterableSource.java b/src/main/java/io/reactivex/internal/operators/PublisherIterableSource.java index f591ae3add..fa7af841f9 100644 --- a/src/main/java/io/reactivex/internal/operators/PublisherIterableSource.java +++ b/src/main/java/io/reactivex/internal/operators/PublisherIterableSource.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -21,9 +21,6 @@ import io.reactivex.internal.subscriptions.*; import io.reactivex.internal.util.BackpressureHelper; -/** - * - */ public final class PublisherIterableSource extends AtomicBoolean implements Publisher { /** */ private static final long serialVersionUID = 9051303031779816842L; @@ -53,7 +50,7 @@ public void subscribe(Subscriber s) { EmptySubscription.complete(s); return; } - s.onSubscribe(new IteratorSourceSubscription<>(it, s)); + s.onSubscribe(new IteratorSourceSubscription(it, s)); } static final class IteratorSourceSubscription extends AtomicLong implements Subscription { diff --git a/src/main/java/io/reactivex/internal/operators/PublisherLift.java b/src/main/java/io/reactivex/internal/operators/PublisherLift.java index cbc34705eb..04f868dfa3 100644 --- a/src/main/java/io/reactivex/internal/operators/PublisherLift.java +++ b/src/main/java/io/reactivex/internal/operators/PublisherLift.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 diff --git a/src/main/java/io/reactivex/internal/operators/PublisherRangeSource.java b/src/main/java/io/reactivex/internal/operators/PublisherRangeSource.java index 35cdd1e9e8..5430378ea6 100644 --- a/src/main/java/io/reactivex/internal/operators/PublisherRangeSource.java +++ b/src/main/java/io/reactivex/internal/operators/PublisherRangeSource.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -80,12 +80,13 @@ void fastpath() { void slowpath(long r) { long idx = index; + long e = 0L; + for (;;) { long fs = end - idx + 1; - long e = Math.min(fs, r); final boolean complete = fs <= r; - fs = e + idx; + fs = Math.min(fs, r) + idx; final Subscriber o = this.actual; for (long i = idx; i != fs; i++) { @@ -102,12 +103,19 @@ void slowpath(long r) { return; } + e -= fs - idx; + idx = fs; - index = fs; + + r = get() + e; - r = addAndGet(-r); if (r == 0L) { - return; + index = fs; + r = addAndGet(e); + if (r == 0L) { + return; + } + e = 0L; } } } diff --git a/src/main/java/io/reactivex/internal/operators/PublisherRedo.java b/src/main/java/io/reactivex/internal/operators/PublisherRedo.java index a0e539e038..93a2a78309 100644 --- a/src/main/java/io/reactivex/internal/operators/PublisherRedo.java +++ b/src/main/java/io/reactivex/internal/operators/PublisherRedo.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,16 +13,15 @@ package io.reactivex.internal.operators; -import java.util.Optional; import java.util.concurrent.atomic.*; -import java.util.function.Function; import org.reactivestreams.*; import io.reactivex.*; +import io.reactivex.functions.*; import io.reactivex.internal.subscribers.ToNotificationSubscriber; import io.reactivex.internal.subscriptions.SubscriptionArbiter; -import io.reactivex.subjects.*; +import io.reactivex.subjects.BehaviorSubject; public final class PublisherRedo implements Publisher { final Publisher source; @@ -40,16 +39,21 @@ public void subscribe(Subscriber s) { // FIXE use BehaviorSubject? (once available) BehaviorSubject>> subject = BehaviorSubject.create(); - RedoSubscriber parent = new RedoSubscriber<>(s, subject, source); + final RedoSubscriber parent = new RedoSubscriber(s, subject, source); s.onSubscribe(parent.arbiter); Publisher action = manager.apply(subject); - action.subscribe(new ToNotificationSubscriber<>(parent::handle)); + action.subscribe(new ToNotificationSubscriber(new Consumer>>() { + @Override + public void accept(Try> v) { + parent.handle(v); + } + })); // trigger first subscription - parent.handle(Notification.next(0)); + parent.handle(Notification.next((Object)0)); } static final class RedoSubscriber extends AtomicBoolean implements Subscriber { @@ -60,10 +64,7 @@ static final class RedoSubscriber extends AtomicBoolean implements Subscriber final Publisher source; final SubscriptionArbiter arbiter; - volatile int wip; - @SuppressWarnings("rawtypes") - static final AtomicIntegerFieldUpdater WIP = - AtomicIntegerFieldUpdater.newUpdater(RedoSubscriber.class, "wip"); + final AtomicInteger wip = new AtomicInteger(); public RedoSubscriber(Subscriber actual, BehaviorSubject>> subject, Publisher source) { this.actual = actual; @@ -87,7 +88,7 @@ public void onNext(T t) { @Override public void onError(Throwable t) { if (compareAndSet(false, true)) { - subject.onNext(Try.ofError(t)); + subject.onNext(Try.>ofError(t)); } } @@ -108,7 +109,7 @@ void handle(Try> notification) { if (o.isPresent()) { - if (WIP.getAndIncrement(this) == 0) { + if (wip.getAndIncrement() == 0) { int missed = 1; for (;;) { if (arbiter.isCancelled()) { @@ -116,7 +117,7 @@ void handle(Try> notification) { } source.subscribe(this); - missed = WIP.addAndGet(this, -missed); + missed = wip.addAndGet(-missed); if (missed == 0) { break; } diff --git a/src/main/java/io/reactivex/internal/operators/PublisherRefCount.java b/src/main/java/io/reactivex/internal/operators/PublisherRefCount.java index f3e6eae4d3..e0c10a4191 100644 --- a/src/main/java/io/reactivex/internal/operators/PublisherRefCount.java +++ b/src/main/java/io/reactivex/internal/operators/PublisherRefCount.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -15,11 +15,11 @@ import java.util.concurrent.atomic.*; import java.util.concurrent.locks.ReentrantLock; -import java.util.function.Consumer; import org.reactivestreams.*; -import io.reactivex.disposables.Disposable; +import io.reactivex.disposables.*; +import io.reactivex.functions.Consumer; import io.reactivex.internal.disposables.SetCompositeResource; import io.reactivex.internal.subscriptions.SubscriptionHelper; import io.reactivex.observables.ConnectableObservable; @@ -91,7 +91,7 @@ void cleanup() { try { if (baseSubscription == currentBase) { baseSubscription.dispose(); - baseSubscription = new SetCompositeResource<>(Disposable::dispose); + baseSubscription = new SetCompositeResource(Disposables.consumeAndDispose()); subscriptionCount.set(0); } } finally { @@ -101,7 +101,7 @@ void cleanup() { } final ConnectableObservable source; - volatile SetCompositeResource baseSubscription = new SetCompositeResource<>(Disposable::dispose); + volatile SetCompositeResource baseSubscription = new SetCompositeResource(Disposables.consumeAndDispose()); final AtomicInteger subscriptionCount = new AtomicInteger(0); /** @@ -155,15 +155,18 @@ public void subscribe(final Subscriber subscriber) { private Consumer onSubscribe(final Subscriber subscriber, final AtomicBoolean writeLocked) { - return subscription -> { - try { - baseSubscription.add(subscription); - // ready to subscribe to source so do it - doSubscribe(subscriber, baseSubscription); - } finally { - // release the write lock - lock.unlock(); - writeLocked.set(false); + return new Consumer() { + @Override + public void accept(Disposable subscription) { + try { + baseSubscription.add(subscription); + // ready to subscribe to source so do it + doSubscribe(subscriber, baseSubscription); + } finally { + // release the write lock + lock.unlock(); + writeLocked.set(false); + } } }; } @@ -178,19 +181,22 @@ void doSubscribe(final Subscriber subscriber, final SetCompositeResou } private Disposable disconnect(final SetCompositeResource current) { - return () -> { - lock.lock(); - try { - if (baseSubscription == current) { - if (subscriptionCount.decrementAndGet() == 0) { - baseSubscription.dispose(); - // need a new baseSubscription because once - // unsubscribed stays that way - baseSubscription = new SetCompositeResource<>(Disposable::dispose); + return new Disposable() { + @Override + public void dispose() { + lock.lock(); + try { + if (baseSubscription == current) { + if (subscriptionCount.decrementAndGet() == 0) { + baseSubscription.dispose(); + // need a new baseSubscription because once + // unsubscribed stays that way + baseSubscription = new SetCompositeResource(Disposables.consumeAndDispose()); + } } + } finally { + lock.unlock(); } - } finally { - lock.unlock(); } }; } diff --git a/src/main/java/io/reactivex/internal/operators/PublisherRepeat.java b/src/main/java/io/reactivex/internal/operators/PublisherRepeat.java index 9cd58353db..78b3904167 100644 --- a/src/main/java/io/reactivex/internal/operators/PublisherRepeat.java +++ b/src/main/java/io/reactivex/internal/operators/PublisherRepeat.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -32,7 +32,7 @@ public void subscribe(Subscriber s) { SubscriptionArbiter sa = new SubscriptionArbiter(); s.onSubscribe(sa); - RepeatSubscriber rs = new RepeatSubscriber<>(s, count != Long.MAX_VALUE ? count - 1 : Long.MAX_VALUE, sa, source); + RepeatSubscriber rs = new RepeatSubscriber(s, count != Long.MAX_VALUE ? count - 1 : Long.MAX_VALUE, sa, source); rs.subscribeNext(); } diff --git a/src/main/java/io/reactivex/internal/operators/PublisherRepeatUntil.java b/src/main/java/io/reactivex/internal/operators/PublisherRepeatUntil.java index 322140e525..17eff72e61 100644 --- a/src/main/java/io/reactivex/internal/operators/PublisherRepeatUntil.java +++ b/src/main/java/io/reactivex/internal/operators/PublisherRepeatUntil.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -14,10 +14,10 @@ package io.reactivex.internal.operators; import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.BooleanSupplier; import org.reactivestreams.*; +import io.reactivex.functions.BooleanSupplier; import io.reactivex.internal.subscriptions.SubscriptionArbiter; public final class PublisherRepeatUntil implements Publisher { @@ -33,7 +33,7 @@ public void subscribe(Subscriber s) { SubscriptionArbiter sa = new SubscriptionArbiter(); s.onSubscribe(sa); - RepeatSubscriber rs = new RepeatSubscriber<>(s, until, sa, source); + RepeatSubscriber rs = new RepeatSubscriber(s, until, sa, source); rs.subscribeNext(); } diff --git a/src/main/java/io/reactivex/internal/operators/PublisherRetryBiPredicate.java b/src/main/java/io/reactivex/internal/operators/PublisherRetryBiPredicate.java index a612dbb467..25ffd9f26c 100644 --- a/src/main/java/io/reactivex/internal/operators/PublisherRetryBiPredicate.java +++ b/src/main/java/io/reactivex/internal/operators/PublisherRetryBiPredicate.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -14,10 +14,11 @@ package io.reactivex.internal.operators; import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.*; import org.reactivestreams.*; +import io.reactivex.exceptions.CompositeException; +import io.reactivex.functions.BiPredicate; import io.reactivex.internal.subscriptions.SubscriptionArbiter; public final class PublisherRetryBiPredicate implements Publisher { @@ -35,7 +36,7 @@ public void subscribe(Subscriber s) { SubscriptionArbiter sa = new SubscriptionArbiter(); s.onSubscribe(sa); - RetryBiSubscriber rs = new RetryBiSubscriber<>(s, predicate, sa, source); + RetryBiSubscriber rs = new RetryBiSubscriber(s, predicate, sa, source); rs.subscribeNext(); } @@ -72,8 +73,7 @@ public void onError(Throwable t) { try { b = predicate.test(++retries, t); } catch (Throwable e) { - e.addSuppressed(t); - actual.onError(e); + actual.onError(new CompositeException(e, t)); return; } if (!b) { diff --git a/src/main/java/io/reactivex/internal/operators/PublisherRetryPredicate.java b/src/main/java/io/reactivex/internal/operators/PublisherRetryPredicate.java index 874a14c827..a3a1a08c32 100644 --- a/src/main/java/io/reactivex/internal/operators/PublisherRetryPredicate.java +++ b/src/main/java/io/reactivex/internal/operators/PublisherRetryPredicate.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -14,10 +14,11 @@ package io.reactivex.internal.operators; import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.Predicate; import org.reactivestreams.*; +import io.reactivex.exceptions.CompositeException; +import io.reactivex.functions.Predicate; import io.reactivex.internal.subscriptions.SubscriptionArbiter; public final class PublisherRetryPredicate implements Publisher { @@ -37,7 +38,7 @@ public void subscribe(Subscriber s) { SubscriptionArbiter sa = new SubscriptionArbiter(); s.onSubscribe(sa); - RepeatSubscriber rs = new RepeatSubscriber<>(s, count, predicate, sa, source); + RepeatSubscriber rs = new RepeatSubscriber(s, count, predicate, sa, source); rs.subscribeNext(); } @@ -82,8 +83,7 @@ public void onError(Throwable t) { try { b = predicate.test(t); } catch (Throwable e) { - e.addSuppressed(t); - actual.onError(e); + actual.onError(new CompositeException(e, t)); return; } if (!b) { diff --git a/src/main/java/io/reactivex/internal/operators/PublisherScalarAsyncSource.java b/src/main/java/io/reactivex/internal/operators/PublisherScalarAsyncSource.java index 567f7ee13c..2f7a2b8895 100644 --- a/src/main/java/io/reactivex/internal/operators/PublisherScalarAsyncSource.java +++ b/src/main/java/io/reactivex/internal/operators/PublisherScalarAsyncSource.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -19,9 +19,6 @@ import io.reactivex.internal.subscriptions.ScalarAsyncSubscription; -/** - * - */ public final class PublisherScalarAsyncSource implements Publisher { final Callable callable; public PublisherScalarAsyncSource(Callable callable) { @@ -29,7 +26,7 @@ public PublisherScalarAsyncSource(Callable callable) { } @Override public void subscribe(Subscriber s) { - ScalarAsyncSubscription sub = new ScalarAsyncSubscription<>(s); + ScalarAsyncSubscription sub = new ScalarAsyncSubscription(s); s.onSubscribe(sub); if (sub.isComplete()) { return; diff --git a/src/main/java/io/reactivex/internal/operators/PublisherSequenceEqual.java b/src/main/java/io/reactivex/internal/operators/PublisherSequenceEqual.java index 7d67c91608..d0cc62befb 100644 --- a/src/main/java/io/reactivex/internal/operators/PublisherSequenceEqual.java +++ b/src/main/java/io/reactivex/internal/operators/PublisherSequenceEqual.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -15,10 +15,10 @@ import java.util.Queue; import java.util.concurrent.atomic.*; -import java.util.function.BiPredicate; import org.reactivestreams.*; +import io.reactivex.functions.BiPredicate; import io.reactivex.internal.disposables.ArrayCompositeResource; import io.reactivex.internal.queue.*; import io.reactivex.internal.subscriptions.SubscriptionHelper; @@ -40,7 +40,7 @@ public PublisherSequenceEqual(Publisher first, Publisher s) { - EqualCoordinator ec = new EqualCoordinator<>(s, bufferSize, first, second, comparer); + EqualCoordinator ec = new EqualCoordinator(s, bufferSize, first, second, comparer); ec.subscribe(); } @@ -56,10 +56,7 @@ static final class EqualCoordinator extends AtomicInteger implements Subscrip volatile boolean cancelled; - volatile int once; - @SuppressWarnings("rawtypes") - static final AtomicIntegerFieldUpdater ONCE = - AtomicIntegerFieldUpdater.newUpdater(EqualCoordinator.class, "once"); + final AtomicBoolean once = new AtomicBoolean(); public EqualCoordinator(Subscriber actual, int bufferSize, Publisher first, Publisher second, @@ -71,9 +68,9 @@ public EqualCoordinator(Subscriber actual, int bufferSize, @SuppressWarnings("unchecked") EqualSubscriber[] as = new EqualSubscriber[2]; this.subscribers = as; - as[0] = new EqualSubscriber<>(this, 0, bufferSize); - as[1] = new EqualSubscriber<>(this, 1, bufferSize); - this.resources = new ArrayCompositeResource<>(2, Subscription::cancel); + as[0] = new EqualSubscriber(this, 0, bufferSize); + as[1] = new EqualSubscriber(this, 1, bufferSize); + this.resources = new ArrayCompositeResource(2, SubscriptionHelper.consumeAndCancel()); } boolean setSubscription(Subscription s, int index) { @@ -91,7 +88,7 @@ public void request(long n) { if (SubscriptionHelper.validateRequest(n)) { return; } - if (ONCE.compareAndSet(this, 0, 1)) { + if (once.compareAndSet(false, true)) { EqualSubscriber[] as = subscribers; first.subscribe(as[0]); second.subscribe(as[1]); @@ -242,9 +239,9 @@ public EqualSubscriber(EqualCoordinator parent, int index, int bufferSize) { this.index = index; Queue q; if (Pow2.isPowerOfTwo(bufferSize)) { - q = new SpscArrayQueue<>(bufferSize); + q = new SpscArrayQueue(bufferSize); } else { - q = new SpscExactArrayQueue<>(bufferSize); + q = new SpscExactArrayQueue(bufferSize); } this.queue = q; } diff --git a/src/main/java/io/reactivex/internal/operators/PublisherStreamSource.java b/src/main/java/io/reactivex/internal/operators/PublisherStreamSource.java deleted file mode 100644 index 01c68e5ac8..0000000000 --- a/src/main/java/io/reactivex/internal/operators/PublisherStreamSource.java +++ /dev/null @@ -1,133 +0,0 @@ -/** - * 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 io.reactivex.internal.operators; - -import java.util.Iterator; -import java.util.concurrent.atomic.*; -import java.util.stream.Stream; - -import org.reactivestreams.*; - -import io.reactivex.internal.subscriptions.EmptySubscription; -import io.reactivex.internal.util.BackpressureHelper; -import io.reactivex.plugins.RxJavaPlugins; - -/** - * - */ -public final class PublisherStreamSource extends AtomicBoolean implements Publisher { - /** */ - private static final long serialVersionUID = 9051303031779816842L; - - final Stream stream; - public PublisherStreamSource(Stream stream) { - this.stream = stream; - } - @Override - public void subscribe(Subscriber s) { - if (compareAndSet(false, true)) { - Iterator it; - try { - it = stream.iterator(); - } catch (Throwable e) { - EmptySubscription.error(e, s); - return; - } - s.onSubscribe(new StreamSourceSubscription<>(stream, it, s)); - return; - } - EmptySubscription.error(new IllegalStateException("Contents already consumed"), s); - } - - static final class StreamSourceSubscription extends AtomicLong implements Subscription { - /** */ - private static final long serialVersionUID = 8931425802102883003L; - final Iterator it; - final Stream stream; - final Subscriber subscriber; - - volatile boolean cancelled; - - volatile int wip; - @SuppressWarnings("rawtypes") - static final AtomicIntegerFieldUpdater WIP = - AtomicIntegerFieldUpdater.newUpdater(StreamSourceSubscription.class, "wip"); - - public StreamSourceSubscription(Stream stream, Iterator it, Subscriber subscriber) { - this.stream = stream; - this.it = it; - this.subscriber = subscriber; - } - @Override - public void request(long n) { - if (n <= 0) { - RxJavaPlugins.onError(new IllegalArgumentException("n > 0 required but it was " + n)); - return; - } - BackpressureHelper.add(this, n); - drain(); - } - @Override - public void cancel() { - if (!cancelled) { - cancelled = true; - if (WIP.getAndIncrement(this) != 0) { - return; - } - stream.close(); - } - } - - void drain() { - if (WIP.getAndIncrement(this) != 0) { - return; - } - long r = get(); - long r0 = r; - do { - if (cancelled) { - stream.close(); - return; - } - long e = 0L; - - if (!it.hasNext()) { - subscriber.onComplete(); - return; - } - while (r != 0L) { - T v = it.next(); - subscriber.onNext(v); - if (cancelled) { - stream.close(); - return; - } - if (!it.hasNext()) { - subscriber.onComplete(); - return; - } - r--; - e--; - } - if (e != 0L) { - if (r0 != Long.MAX_VALUE) { - r = addAndGet(e); - } else { - r = Long.MAX_VALUE; - } - } - } while (WIP.decrementAndGet(this) != 0); - } - } -} diff --git a/src/main/java/io/reactivex/internal/operators/PublisherSubscribeOn.java b/src/main/java/io/reactivex/internal/operators/PublisherSubscribeOn.java index 855aa11466..c9b515657a 100644 --- a/src/main/java/io/reactivex/internal/operators/PublisherSubscribeOn.java +++ b/src/main/java/io/reactivex/internal/operators/PublisherSubscribeOn.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -32,7 +32,7 @@ public PublisherSubscribeOn(Publisher source, Scheduler scheduler, } @Override - public void subscribe(Subscriber s) { + public void subscribe(final Subscriber s) { /* * TODO can't use the returned disposable because to dispose it, * one must set a Subscription on s on the current thread, but @@ -40,13 +40,19 @@ public void subscribe(Subscriber s) { */ if (requestOn) { Scheduler.Worker w = scheduler.createWorker(); - SubscribeOnSubscriber sos = new SubscribeOnSubscriber<>(s, w); - w.schedule(() -> { - source.subscribe(sos); + final SubscribeOnSubscriber sos = new SubscribeOnSubscriber(s, w); + w.schedule(new Runnable() { + @Override + public void run() { + source.subscribe(sos); + } }); } else { - scheduler.scheduleDirect(() -> { - source.subscribe(s); + scheduler.scheduleDirect(new Runnable() { + @Override + public void run() { + source.subscribe(s); + } }); } } @@ -98,15 +104,18 @@ public void onComplete() { } @Override - public void request(long n) { + public void request(final long n) { if (SubscriptionHelper.validateRequest(n)) { return; } if (Thread.currentThread() == get()) { s.request(n); } else { - worker.schedule(() -> { - s.request(n); + worker.schedule(new Runnable() { + @Override + public void run() { + s.request(n); + } }); } } diff --git a/src/main/java/io/reactivex/internal/operators/PublisherUsing.java b/src/main/java/io/reactivex/internal/operators/PublisherUsing.java index 8f49f18d6b..2753bf3ad9 100644 --- a/src/main/java/io/reactivex/internal/operators/PublisherUsing.java +++ b/src/main/java/io/reactivex/internal/operators/PublisherUsing.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -14,10 +14,11 @@ package io.reactivex.internal.operators; import java.util.concurrent.atomic.AtomicBoolean; -import java.util.function.*; import org.reactivestreams.*; +import io.reactivex.exceptions.CompositeException; +import io.reactivex.functions.*; import io.reactivex.internal.subscriptions.*; import io.reactivex.plugins.RxJavaPlugins; @@ -55,13 +56,14 @@ public void subscribe(Subscriber s) { try { disposer.accept(resource); } catch (Throwable ex) { - e.addSuppressed(ex); + EmptySubscription.error(new CompositeException(ex, e), s); + return; } EmptySubscription.error(e, s); return; } - UsingSubscriber us = new UsingSubscriber<>(s, resource, disposer, eager); + UsingSubscriber us = new UsingSubscriber(s, resource, disposer, eager); source.subscribe(us); } @@ -101,16 +103,21 @@ public void onNext(T t) { @Override public void onError(Throwable t) { if (eager) { + Throwable innerError = null; if (compareAndSet(false, true)) { try { disposer.accept(resource); } catch (Throwable e) { - t.addSuppressed(e); + innerError = e; } } s.cancel(); - actual.onError(t); + if (innerError != null) { + actual.onError(new CompositeException(innerError, t)); + } else { + actual.onError(t); + } } else { actual.onError(t); s.cancel(); diff --git a/src/main/java/io/reactivex/internal/operators/PublisherZip.java b/src/main/java/io/reactivex/internal/operators/PublisherZip.java index 4bc48761ef..9fa0e9c986 100644 --- a/src/main/java/io/reactivex/internal/operators/PublisherZip.java +++ b/src/main/java/io/reactivex/internal/operators/PublisherZip.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -15,10 +15,10 @@ import java.util.Queue; import java.util.concurrent.atomic.*; -import java.util.function.Function; import org.reactivestreams.*; +import io.reactivex.functions.Function; import io.reactivex.internal.queue.*; import io.reactivex.internal.subscriptions.EmptySubscription; import io.reactivex.internal.util.*; @@ -68,7 +68,7 @@ public void subscribe(Subscriber s) { return; } - ZipCoordinator zc = new ZipCoordinator<>(s, zipper, count, delayError); + ZipCoordinator zc = new ZipCoordinator(s, zipper, count, delayError); zc.subscribe(sources, bufferSize); } @@ -81,10 +81,7 @@ static final class ZipCoordinator extends AtomicInteger implements Subscri final Object[] row; final boolean delayError; - volatile long requested; - @SuppressWarnings("rawtypes") - static final AtomicLongFieldUpdater REQUESTED = - AtomicLongFieldUpdater.newUpdater(ZipCoordinator.class, "requested"); + final AtomicLong requested = new AtomicLong(); volatile boolean cancelled; @@ -103,10 +100,10 @@ public void subscribe(Publisher[] sources, int bufferSize) { ZipSubscriber[] s = subscribers; int len = s.length; for (int i = 0; i < len; i++) { - s[i] = new ZipSubscriber<>(this, bufferSize); + s[i] = new ZipSubscriber(this, bufferSize); } // this makes sure the contents of the subscribers array is visible - REQUESTED.lazySet(this, 0); + requested.lazySet(0); actual.onSubscribe(this); for (int i = 0; i < len; i++) { if (cancelled) { @@ -122,7 +119,7 @@ public void request(long n) { RxJavaPlugins.onError(new IllegalArgumentException("n > required but it was " + n)); return; } - BackpressureHelper.add(REQUESTED, this, n); + BackpressureHelper.add(requested, n); drain(); } @@ -157,7 +154,7 @@ public void drain() { for (;;) { - long r = requested; + long r = requested.get(); boolean unbounded = r == Long.MAX_VALUE; long e = 0; @@ -199,6 +196,12 @@ public void drain() { return; } + if (v == null) { + clear(); + a.onError(new NullPointerException("The zipper returned null")); + return; + } + a.onNext(v); r--; @@ -207,7 +210,7 @@ public void drain() { if (e != 0) { if (!unbounded) { - REQUESTED.addAndGet(this, -e); + requested.addAndGet(-e); } for (ZipSubscriber z : zs) { z.request(e); @@ -269,10 +272,7 @@ static final class ZipSubscriber extends AtomicLong implements Subscriber< volatile boolean done; Throwable error; - volatile Subscription s; - @SuppressWarnings("rawtypes") - static final AtomicReferenceFieldUpdater S = - AtomicReferenceFieldUpdater.newUpdater(ZipSubscriber.class, Subscription.class, "s"); + final AtomicReference s = new AtomicReference(); Subscription cachedS; @@ -293,9 +293,9 @@ public ZipSubscriber(ZipCoordinator parent, int bufferSize) { this.bufferSize = bufferSize; Queue q; if (Pow2.isPowerOfTwo(bufferSize)) { - q = new SpscArrayQueue<>(bufferSize); + q = new SpscArrayQueue(bufferSize); } else { - q = new SpscExactArrayQueue<>(bufferSize); + q = new SpscExactArrayQueue(bufferSize); } this.queue = q; } @@ -303,7 +303,7 @@ public ZipSubscriber(ZipCoordinator parent, int bufferSize) { public void onSubscribe(Subscription s) { for (;;) { - Subscription current = this.s; + Subscription current = this.s.get(); if (current == CANCELLED) { s.cancel(); return; @@ -313,7 +313,7 @@ public void onSubscribe(Subscription s) { RxJavaPlugins.onError(new IllegalStateException("Subscription already set!")); return; } - if (S.compareAndSet(this, null, s)) { + if (this.s.compareAndSet(null, s)) { lazySet(bufferSize); s.request(bufferSize); return; @@ -327,12 +327,12 @@ public void onSubscribe(Subscription s) { @Override public void onNext(T t) { if (t == null) { - s.cancel(); + s.get().cancel(); onError(new NullPointerException()); return; } if (!queue.offer(t)) { - s.cancel(); + s.get().cancel(); onError(new IllegalStateException("Queue full?!")); return; } @@ -357,16 +357,16 @@ public void request(long n) { lazySet(BackpressureHelper.addCap(get(), n)); // this method is only called if s is no longer null; if (cachedS == null) { - cachedS = s; + cachedS = s.get(); } cachedS.request(n); } @Override public void cancel() { - Subscription s = this.s; + Subscription s = this.s.get(); if (s != CANCELLED) { - s = S.getAndSet(this, CANCELLED); + s = this.s.getAndSet(CANCELLED); if (s != CANCELLED && s != null) { s.cancel(); } @@ -382,4 +382,4 @@ public void produced(long n) { lazySet(v); } } -} +} \ No newline at end of file diff --git a/src/main/java/io/reactivex/internal/operators/PublisherZipIterable.java b/src/main/java/io/reactivex/internal/operators/PublisherZipIterable.java index 348d03bd04..937d7df8dc 100644 --- a/src/main/java/io/reactivex/internal/operators/PublisherZipIterable.java +++ b/src/main/java/io/reactivex/internal/operators/PublisherZipIterable.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -14,10 +14,10 @@ package io.reactivex.internal.operators; import java.util.Iterator; -import java.util.function.BiFunction; import org.reactivestreams.*; +import io.reactivex.functions.BiFunction; import io.reactivex.internal.subscriptions.*; import io.reactivex.plugins.RxJavaPlugins; @@ -64,7 +64,7 @@ public void subscribe(Subscriber t) { return; } - source.subscribe(new ZipIterableSubscriber<>(t, it, zipper)); + source.subscribe(new ZipIterableSubscriber(t, it, zipper)); } static final class ZipIterableSubscriber implements Subscriber { diff --git a/src/main/java/io/reactivex/internal/operators/SubscriberResourceWrapper.java b/src/main/java/io/reactivex/internal/operators/SubscriberResourceWrapper.java index adea443002..d68770a206 100644 --- a/src/main/java/io/reactivex/internal/operators/SubscriberResourceWrapper.java +++ b/src/main/java/io/reactivex/internal/operators/SubscriberResourceWrapper.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -14,11 +14,11 @@ package io.reactivex.internal.operators; import java.util.concurrent.atomic.*; -import java.util.function.Consumer; import org.reactivestreams.*; import io.reactivex.disposables.Disposable; +import io.reactivex.functions.Consumer; import io.reactivex.internal.subscriptions.SubscriptionHelper; import io.reactivex.plugins.RxJavaPlugins; @@ -29,10 +29,7 @@ public final class SubscriberResourceWrapper extends AtomicReference actual; final Consumer disposer; - volatile Subscription subscription; - @SuppressWarnings("rawtypes") - static final AtomicReferenceFieldUpdater SUBSCRIPTION = - AtomicReferenceFieldUpdater.newUpdater(SubscriberResourceWrapper.class, Subscription.class, "subscription"); + final AtomicReference subscription = new AtomicReference(); static final Subscription TERMINATED = new Subscription() { @Override @@ -56,7 +53,7 @@ public SubscriberResourceWrapper(Subscriber actual, Consumer sources; + final int prefetch; + + public CompletableOnSubscribeConcat(Observable sources, int prefetch) { + this.sources = sources; + this.prefetch = prefetch; + } + + @Override + public void accept(CompletableSubscriber s) { + CompletableConcatSubscriber parent = new CompletableConcatSubscriber(s, prefetch); + sources.subscribe(parent); + } + + static final class CompletableConcatSubscriber + extends AtomicInteger + implements Subscriber, Disposable { + /** */ + private static final long serialVersionUID = 7412667182931235013L; + final CompletableSubscriber actual; + final int prefetch; + final SerialResource sr; + + final SpscArrayQueue queue; + + Subscription s; + + volatile boolean done; + + final AtomicBoolean once = new AtomicBoolean(); + + final ConcatInnerSubscriber inner; + + public CompletableConcatSubscriber(CompletableSubscriber actual, int prefetch) { + this.actual = actual; + this.prefetch = prefetch; + this.queue = new SpscArrayQueue(prefetch); + this.sr = new SerialResource(Disposables.consumeAndDispose()); + this.inner = new ConcatInnerSubscriber(); + } + + @Override + public void onSubscribe(Subscription s) { + if (SubscriptionHelper.validateSubscription(this.s, s)) { + return; + } + this.s = s; + actual.onSubscribe(this); + s.request(prefetch); + } + + @Override + public void onNext(Completable t) { + if (!queue.offer(t)) { + onError(new MissingBackpressureException()); + return; + } + if (getAndIncrement() == 0) { + next(); + } + } + + @Override + public void onError(Throwable t) { + if (once.compareAndSet(false, true)) { + actual.onError(t); + return; + } + RxJavaPlugins.onError(t); + } + + @Override + public void onComplete() { + if (done) { + return; + } + done = true; + if (getAndIncrement() == 0) { + next(); + } + } + + void innerError(Throwable e) { + s.cancel(); + onError(e); + } + + void innerComplete() { + if (decrementAndGet() != 0) { + next(); + } + if (!done) { + s.request(1); + } + } + + @Override + public void dispose() { + s.cancel(); + sr.dispose(); + } + + void next() { + boolean d = done; + Completable c = queue.poll(); + if (c == null) { + if (d) { + if (once.compareAndSet(false, true)) { + actual.onComplete(); + } + return; + } + RxJavaPlugins.onError(new IllegalStateException("Queue is empty?!")); + return; + } + + c.subscribe(inner); + } + + final class ConcatInnerSubscriber implements CompletableSubscriber { + @Override + public void onSubscribe(Disposable d) { + sr.set(d); + } + + @Override + public void onError(Throwable e) { + innerError(e); + } + + @Override + public void onComplete() { + innerComplete(); + } + } + } +} \ No newline at end of file diff --git a/src/main/java/io/reactivex/internal/operators/completable/CompletableOnSubscribeConcatArray.java b/src/main/java/io/reactivex/internal/operators/completable/CompletableOnSubscribeConcatArray.java new file mode 100644 index 0000000000..f4393769e0 --- /dev/null +++ b/src/main/java/io/reactivex/internal/operators/completable/CompletableOnSubscribeConcatArray.java @@ -0,0 +1,93 @@ +/** + * 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.internal.operators.completable; + +import java.util.concurrent.atomic.AtomicInteger; + +import io.reactivex.Completable; +import io.reactivex.Completable.*; +import io.reactivex.disposables.*; + +public final class CompletableOnSubscribeConcatArray implements CompletableOnSubscribe { + final Completable[] sources; + + public CompletableOnSubscribeConcatArray(Completable[] sources) { + this.sources = sources; + } + + @Override + public void accept(CompletableSubscriber s) { + ConcatInnerSubscriber inner = new ConcatInnerSubscriber(s, sources); + s.onSubscribe(inner.sd); + inner.next(); + } + + static final class ConcatInnerSubscriber extends AtomicInteger implements CompletableSubscriber { + /** */ + private static final long serialVersionUID = -7965400327305809232L; + + final CompletableSubscriber actual; + final Completable[] sources; + + int index; + + final SerialDisposable sd; + + public ConcatInnerSubscriber(CompletableSubscriber actual, Completable[] sources) { + this.actual = actual; + this.sources = sources; + this.sd = new SerialDisposable(); + } + + @Override + public void onSubscribe(Disposable d) { + sd.set(d); + } + + @Override + public void onError(Throwable e) { + actual.onError(e); + } + + @Override + public void onComplete() { + next(); + } + + void next() { + if (sd.isDisposed()) { + return; + } + + if (getAndIncrement() != 0) { + return; + } + + Completable[] a = sources; + do { + if (sd.isDisposed()) { + return; + } + + int idx = index++; + if (idx == a.length) { + actual.onComplete(); + return; + } + + a[idx].subscribe(this); + } while (decrementAndGet() != 0); + } + } +} \ No newline at end of file diff --git a/src/main/java/io/reactivex/internal/operators/completable/CompletableOnSubscribeConcatIterable.java b/src/main/java/io/reactivex/internal/operators/completable/CompletableOnSubscribeConcatIterable.java new file mode 100644 index 0000000000..8f4bb3cb74 --- /dev/null +++ b/src/main/java/io/reactivex/internal/operators/completable/CompletableOnSubscribeConcatIterable.java @@ -0,0 +1,133 @@ +/** + * 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.internal.operators.completable; + +import java.util.Iterator; +import java.util.concurrent.atomic.AtomicInteger; + +import io.reactivex.Completable; +import io.reactivex.Completable.*; +import io.reactivex.disposables.*; +import io.reactivex.internal.disposables.EmptyDisposable; + +public final class CompletableOnSubscribeConcatIterable implements CompletableOnSubscribe { + final Iterable sources; + + public CompletableOnSubscribeConcatIterable(Iterable sources) { + this.sources = sources; + } + + @Override + public void accept(CompletableSubscriber s) { + + Iterator it; + + try { + it = sources.iterator(); + } catch (Throwable e) { + s.onSubscribe(EmptyDisposable.INSTANCE); + s.onError(e); + return; + } + + if (it == null) { + s.onSubscribe(EmptyDisposable.INSTANCE); + s.onError(new NullPointerException("The iterator returned is null")); + return; + } + + ConcatInnerSubscriber inner = new ConcatInnerSubscriber(s, it); + s.onSubscribe(inner.sd); + inner.next(); + } + + static final class ConcatInnerSubscriber extends AtomicInteger implements CompletableSubscriber { + /** */ + private static final long serialVersionUID = -7965400327305809232L; + + final CompletableSubscriber actual; + final Iterator sources; + + int index; + + final SerialDisposable sd; + + public ConcatInnerSubscriber(CompletableSubscriber actual, Iterator sources) { + this.actual = actual; + this.sources = sources; + this.sd = new SerialDisposable(); + } + + @Override + public void onSubscribe(Disposable d) { + sd.set(d); + } + + @Override + public void onError(Throwable e) { + actual.onError(e); + } + + @Override + public void onComplete() { + next(); + } + + void next() { + if (sd.isDisposed()) { + return; + } + + if (getAndIncrement() != 0) { + return; + } + + Iterator a = sources; + do { + if (sd.isDisposed()) { + return; + } + + boolean b; + try { + b = a.hasNext(); + } catch (Throwable ex) { + actual.onError(ex); + return; + } + + if (!b) { + actual.onComplete(); + return; + } + + Completable c; + + try { + c = a.next(); + } catch (Throwable ex) { + actual.onError(ex); + return; + } + + if (c == null) { + actual.onError(new NullPointerException("The completable returned is null")); + return; + } + + c.subscribe(this); + } while (decrementAndGet() != 0); + } + } +} \ No newline at end of file diff --git a/src/main/java/io/reactivex/internal/operators/completable/CompletableOnSubscribeMerge.java b/src/main/java/io/reactivex/internal/operators/completable/CompletableOnSubscribeMerge.java new file mode 100644 index 0000000000..09319ccce2 --- /dev/null +++ b/src/main/java/io/reactivex/internal/operators/completable/CompletableOnSubscribeMerge.java @@ -0,0 +1,238 @@ +/** + * 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.internal.operators.completable; + +import java.util.Queue; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.atomic.*; + +import org.reactivestreams.*; + +import io.reactivex.*; +import io.reactivex.Completable.*; +import io.reactivex.disposables.*; +import io.reactivex.exceptions.CompositeException; +import io.reactivex.internal.disposables.SetCompositeResource; +import io.reactivex.internal.subscriptions.SubscriptionHelper; +import io.reactivex.plugins.RxJavaPlugins; + +public final class CompletableOnSubscribeMerge implements CompletableOnSubscribe { + final Observable source; + final int maxConcurrency; + final boolean delayErrors; + + public CompletableOnSubscribeMerge(Observable source, int maxConcurrency, boolean delayErrors) { + this.source = source; + this.maxConcurrency = maxConcurrency; + this.delayErrors = delayErrors; + } + + @Override + public void accept(CompletableSubscriber s) { + CompletableMergeSubscriber parent = new CompletableMergeSubscriber(s, maxConcurrency, delayErrors); + source.subscribe(parent); + } + + static final class CompletableMergeSubscriber + extends AtomicInteger + implements Subscriber, Disposable { + /** */ + private static final long serialVersionUID = -2108443387387077490L; + + final CompletableSubscriber actual; + final SetCompositeResource set; + final int maxConcurrency; + final boolean delayErrors; + + Subscription s; + + volatile boolean done; + + final AtomicReference> errors = new AtomicReference>(); + + final AtomicBoolean once = new AtomicBoolean(); + + public CompletableMergeSubscriber(CompletableSubscriber actual, int maxConcurrency, boolean delayErrors) { + this.actual = actual; + this.maxConcurrency = maxConcurrency; + this.delayErrors = delayErrors; + this.set = new SetCompositeResource(Disposables.consumeAndDispose()); + lazySet(1); + } + + @Override + public void dispose() { + s.cancel(); + set.dispose(); + } + + @Override + public void onSubscribe(Subscription s) { + if (SubscriptionHelper.validateSubscription(this.s, s)) { + return; + } + this.s = s; + set.add(Disposables.from(s)); + actual.onSubscribe(this); + if (maxConcurrency == Integer.MAX_VALUE) { + s.request(Long.MAX_VALUE); + } else { + s.request(maxConcurrency); + } + } + + Queue getOrCreateErrors() { + Queue q = errors.get(); + + if (q != null) { + return q; + } + + q = new ConcurrentLinkedQueue(); + if (errors.compareAndSet(null, q)) { + return q; + } + return errors.get(); + } + + @Override + public void onNext(Completable t) { + if (done) { + return; + } + + getAndIncrement(); + + t.subscribe(new CompletableSubscriber() { + Disposable d; + boolean innerDone; + @Override + public void onSubscribe(Disposable d) { + this.d = d; + set.add(d); + } + + @Override + public void onError(Throwable e) { + if (innerDone) { + RxJavaPlugins.onError(e); + return; + } + innerDone = true; + set.remove(d); + + getOrCreateErrors().offer(e); + + terminate(); + + if (delayErrors && !done) { + s.request(1); + } + } + + @Override + public void onComplete() { + if (innerDone) { + return; + } + innerDone = true; + set.remove(d); + + terminate(); + + if (!done) { + s.request(1); + } + } + }); + } + + @Override + public void onError(Throwable t) { + if (done) { + RxJavaPlugins.onError(t); + return; + } + getOrCreateErrors().offer(t); + done = true; + terminate(); + } + + @Override + public void onComplete() { + if (done) { + return; + } + done = true; + terminate(); + } + + void terminate() { + if (decrementAndGet() == 0) { + Queue q = errors.get(); + if (q == null || q.isEmpty()) { + actual.onComplete(); + } else { + Throwable e = collectErrors(q); + if (once.compareAndSet(false, true)) { + actual.onError(e); + } else { + RxJavaPlugins.onError(e); + } + } + } else + if (!delayErrors) { + Queue q = errors.get(); + if (q != null && !q.isEmpty()) { + Throwable e = collectErrors(q); + if (once.compareAndSet(false, true)) { + actual.onError(e); + } else { + RxJavaPlugins.onError(e); + } + } + } + } + } + + /** + * Collects the Throwables from the queue, adding subsequent Throwables as suppressed to + * the first Throwable and returns it. + * @param q the queue to drain + * @return the Throwable containing all other Throwables as suppressed + */ + public static Throwable collectErrors(Queue q) { + CompositeException composite = null; + Throwable first = null; + + Throwable t; + int count = 0; + while ((t = q.poll()) != null) { + if (count == 0) { + first = t; + } else { + if (composite == null) { + composite = new CompositeException(first); + } + composite.suppress(t); + } + + count++; + } + if (composite != null) { + return composite; + } + return first; + } +} \ No newline at end of file diff --git a/src/main/java/io/reactivex/internal/operators/completable/CompletableOnSubscribeMergeArray.java b/src/main/java/io/reactivex/internal/operators/completable/CompletableOnSubscribeMergeArray.java new file mode 100644 index 0000000000..7fb965c00b --- /dev/null +++ b/src/main/java/io/reactivex/internal/operators/completable/CompletableOnSubscribeMergeArray.java @@ -0,0 +1,88 @@ +/** + * 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.internal.operators.completable; + +import java.util.concurrent.atomic.*; + +import io.reactivex.Completable; +import io.reactivex.Completable.*; +import io.reactivex.disposables.*; +import io.reactivex.plugins.RxJavaPlugins; + +public final class CompletableOnSubscribeMergeArray implements CompletableOnSubscribe { + final Completable[] sources; + + public CompletableOnSubscribeMergeArray(Completable[] sources) { + this.sources = sources; + } + + @Override + public void accept(final CompletableSubscriber s) { + final CompositeDisposable set = new CompositeDisposable(); + final AtomicInteger wip = new AtomicInteger(sources.length + 1); + final AtomicBoolean once = new AtomicBoolean(); + + s.onSubscribe(set); + + for (Completable c : sources) { + if (set.isDisposed()) { + return; + } + + if (c == null) { + set.dispose(); + NullPointerException npe = new NullPointerException("A completable source is null"); + if (once.compareAndSet(false, true)) { + s.onError(npe); + return; + } else { + RxJavaPlugins.onError(npe); + } + } + + c.subscribe(new CompletableSubscriber() { + @Override + public void onSubscribe(Disposable d) { + set.add(d); + } + + @Override + public void onError(Throwable e) { + set.dispose(); + if (once.compareAndSet(false, true)) { + s.onError(e); + } else { + RxJavaPlugins.onError(e); + } + } + + @Override + public void onComplete() { + if (wip.decrementAndGet() == 0) { + if (once.compareAndSet(false, true)) { + s.onComplete(); + } + } + } + + }); + } + + if (wip.decrementAndGet() == 0) { + if (once.compareAndSet(false, true)) { + s.onComplete(); + } + } + } +} \ No newline at end of file diff --git a/src/main/java/io/reactivex/internal/operators/completable/CompletableOnSubscribeMergeDelayErrorArray.java b/src/main/java/io/reactivex/internal/operators/completable/CompletableOnSubscribeMergeDelayErrorArray.java new file mode 100644 index 0000000000..a877523fc1 --- /dev/null +++ b/src/main/java/io/reactivex/internal/operators/completable/CompletableOnSubscribeMergeDelayErrorArray.java @@ -0,0 +1,90 @@ +/** + * 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.internal.operators.completable; + +import java.util.Queue; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.atomic.AtomicInteger; + +import io.reactivex.Completable; +import io.reactivex.Completable.*; +import io.reactivex.disposables.*; + +public final class CompletableOnSubscribeMergeDelayErrorArray implements CompletableOnSubscribe { + final Completable[] sources; + + public CompletableOnSubscribeMergeDelayErrorArray(Completable[] sources) { + this.sources = sources; + } + + @Override + public void accept(final CompletableSubscriber s) { + final CompositeDisposable set = new CompositeDisposable(); + final AtomicInteger wip = new AtomicInteger(sources.length + 1); + + final Queue q = new ConcurrentLinkedQueue(); + + s.onSubscribe(set); + + for (Completable c : sources) { + if (set.isDisposed()) { + return; + } + + if (c == null) { + q.offer(new NullPointerException("A completable source is null")); + wip.decrementAndGet(); + continue; + } + + c.subscribe(new CompletableSubscriber() { + @Override + public void onSubscribe(Disposable d) { + set.add(d); + } + + @Override + public void onError(Throwable e) { + q.offer(e); + tryTerminate(); + } + + @Override + public void onComplete() { + tryTerminate(); + } + + void tryTerminate() { + if (wip.decrementAndGet() == 0) { + if (q.isEmpty()) { + s.onComplete(); + } else { + s.onError(CompletableOnSubscribeMerge.collectErrors(q)); + } + } + } + + }); + } + + if (wip.decrementAndGet() == 0) { + if (q.isEmpty()) { + s.onComplete(); + } else { + s.onError(CompletableOnSubscribeMerge.collectErrors(q)); + } + } + + } +} \ No newline at end of file diff --git a/src/main/java/io/reactivex/internal/operators/completable/CompletableOnSubscribeMergeDelayErrorIterable.java b/src/main/java/io/reactivex/internal/operators/completable/CompletableOnSubscribeMergeDelayErrorIterable.java new file mode 100644 index 0000000000..c2d36219ce --- /dev/null +++ b/src/main/java/io/reactivex/internal/operators/completable/CompletableOnSubscribeMergeDelayErrorIterable.java @@ -0,0 +1,154 @@ +/** + * 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.internal.operators.completable; + +import java.util.*; +import java.util.concurrent.atomic.AtomicInteger; + +import io.reactivex.Completable; +import io.reactivex.Completable.*; +import io.reactivex.disposables.*; +import io.reactivex.internal.queue.MpscLinkedQueue; + +public final class CompletableOnSubscribeMergeDelayErrorIterable implements CompletableOnSubscribe { + final Iterable sources; + + public CompletableOnSubscribeMergeDelayErrorIterable(Iterable sources) { + this.sources = sources; + } + + @Override + public void accept(final CompletableSubscriber s) { + final CompositeDisposable set = new CompositeDisposable(); + final AtomicInteger wip = new AtomicInteger(1); + + final Queue queue = new MpscLinkedQueue(); + + s.onSubscribe(set); + + Iterator iterator; + + try { + iterator = sources.iterator(); + } catch (Throwable e) { + s.onError(e); + return; + } + + if (iterator == null) { + s.onError(new NullPointerException("The source iterator returned is null")); + return; + } + + for (;;) { + if (set.isDisposed()) { + return; + } + + boolean b; + try { + b = iterator.hasNext(); + } catch (Throwable e) { + queue.offer(e); + if (wip.decrementAndGet() == 0) { + if (queue.isEmpty()) { + s.onComplete(); + } else { + s.onError(CompletableOnSubscribeMerge.collectErrors(queue)); + } + } + return; + } + + if (!b) { + break; + } + + if (set.isDisposed()) { + return; + } + + Completable c; + + try { + c = iterator.next(); + } catch (Throwable e) { + queue.offer(e); + if (wip.decrementAndGet() == 0) { + if (queue.isEmpty()) { + s.onComplete(); + } else { + s.onError(CompletableOnSubscribeMerge.collectErrors(queue)); + } + } + return; + } + + if (set.isDisposed()) { + return; + } + + if (c == null) { + NullPointerException e = new NullPointerException("A completable source is null"); + queue.offer(e); + if (wip.decrementAndGet() == 0) { + if (queue.isEmpty()) { + s.onComplete(); + } else { + s.onError(CompletableOnSubscribeMerge.collectErrors(queue)); + } + } + return; + } + + wip.getAndIncrement(); + + c.subscribe(new CompletableSubscriber() { + @Override + public void onSubscribe(Disposable d) { + set.add(d); + } + + @Override + public void onError(Throwable e) { + queue.offer(e); + tryTerminate(); + } + + @Override + public void onComplete() { + tryTerminate(); + } + + void tryTerminate() { + if (wip.decrementAndGet() == 0) { + if (queue.isEmpty()) { + s.onComplete(); + } else { + s.onError(CompletableOnSubscribeMerge.collectErrors(queue)); + } + } + } + }); + } + + if (wip.decrementAndGet() == 0) { + if (queue.isEmpty()) { + s.onComplete(); + } else { + s.onError(CompletableOnSubscribeMerge.collectErrors(queue)); + } + } + } +} \ No newline at end of file diff --git a/src/main/java/io/reactivex/internal/operators/completable/CompletableOnSubscribeMergeIterable.java b/src/main/java/io/reactivex/internal/operators/completable/CompletableOnSubscribeMergeIterable.java new file mode 100644 index 0000000000..76987e50b1 --- /dev/null +++ b/src/main/java/io/reactivex/internal/operators/completable/CompletableOnSubscribeMergeIterable.java @@ -0,0 +1,144 @@ +/** + * 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.internal.operators.completable; + +import java.util.Iterator; +import java.util.concurrent.atomic.*; + +import io.reactivex.Completable; +import io.reactivex.Completable.*; +import io.reactivex.disposables.*; +import io.reactivex.plugins.RxJavaPlugins; + +public final class CompletableOnSubscribeMergeIterable implements CompletableOnSubscribe { + final Iterable sources; + + public CompletableOnSubscribeMergeIterable(Iterable sources) { + this.sources = sources; + } + + @Override + public void accept(final CompletableSubscriber s) { + final CompositeDisposable set = new CompositeDisposable(); + final AtomicInteger wip = new AtomicInteger(1); + final AtomicBoolean once = new AtomicBoolean(); + + s.onSubscribe(set); + + Iterator iterator; + + try { + iterator = sources.iterator(); + } catch (Throwable e) { + s.onError(e); + return; + } + + if (iterator == null) { + s.onError(new NullPointerException("The source iterator returned is null")); + return; + } + + for (;;) { + if (set.isDisposed()) { + return; + } + + boolean b; + try { + b = iterator.hasNext(); + } catch (Throwable e) { + set.dispose(); + if (once.compareAndSet(false, true)) { + s.onError(e); + } else { + RxJavaPlugins.onError(e); + } + return; + } + + if (!b) { + break; + } + + if (set.isDisposed()) { + return; + } + + Completable c; + + try { + c = iterator.next(); + } catch (Throwable e) { + set.dispose(); + if (once.compareAndSet(false, true)) { + s.onError(e); + } else { + RxJavaPlugins.onError(e); + } + return; + } + + if (set.isDisposed()) { + return; + } + + if (c == null) { + set.dispose(); + NullPointerException npe = new NullPointerException("A completable source is null"); + if (once.compareAndSet(false, true)) { + s.onError(npe); + } else { + RxJavaPlugins.onError(npe); + } + return; + } + + wip.getAndIncrement(); + + c.subscribe(new CompletableSubscriber() { + @Override + public void onSubscribe(Disposable d) { + set.add(d); + } + + @Override + public void onError(Throwable e) { + set.dispose(); + if (once.compareAndSet(false, true)) { + s.onError(e); + } else { + RxJavaPlugins.onError(e); + } + } + + @Override + public void onComplete() { + if (wip.decrementAndGet() == 0) { + if (once.compareAndSet(false, true)) { + s.onComplete(); + } + } + } + + }); + } + + if (wip.decrementAndGet() == 0) { + if (once.compareAndSet(false, true)) { + s.onComplete(); + } + } + } +} \ No newline at end of file diff --git a/src/main/java/io/reactivex/internal/operators/completable/CompletableOnSubscribeTimeout.java b/src/main/java/io/reactivex/internal/operators/completable/CompletableOnSubscribeTimeout.java new file mode 100644 index 0000000000..479e2d0004 --- /dev/null +++ b/src/main/java/io/reactivex/internal/operators/completable/CompletableOnSubscribeTimeout.java @@ -0,0 +1,110 @@ +/** + * 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.internal.operators.completable; + +import java.util.concurrent.*; +import java.util.concurrent.atomic.AtomicBoolean; + +import io.reactivex.*; +import io.reactivex.Completable.*; +import io.reactivex.disposables.*; +import io.reactivex.plugins.RxJavaPlugins; + +public final class CompletableOnSubscribeTimeout implements CompletableOnSubscribe { + + final Completable source; + final long timeout; + final TimeUnit unit; + final Scheduler scheduler; + final Completable other; + + public CompletableOnSubscribeTimeout(Completable source, long timeout, + TimeUnit unit, Scheduler scheduler, Completable other) { + this.source = source; + this.timeout = timeout; + this.unit = unit; + this.scheduler = scheduler; + this.other = other; + } + + @Override + public void accept(final CompletableSubscriber s) { + final CompositeDisposable set = new CompositeDisposable(); + s.onSubscribe(set); + + final AtomicBoolean once = new AtomicBoolean(); + + Disposable timer = scheduler.scheduleDirect(new Runnable() { + @Override + public void run() { + if (once.compareAndSet(false, true)) { + set.clear(); + if (other == null) { + s.onError(new TimeoutException()); + } else { + other.subscribe(new CompletableSubscriber() { + + @Override + public void onSubscribe(Disposable d) { + set.add(d); + } + + @Override + public void onError(Throwable e) { + set.dispose(); + s.onError(e); + } + + @Override + public void onComplete() { + set.dispose(); + s.onComplete(); + } + + }); + } + } + } + }, timeout, unit); + + set.add(timer); + + source.subscribe(new CompletableSubscriber() { + + @Override + public void onSubscribe(Disposable d) { + set.add(d); + } + + @Override + public void onError(Throwable e) { + if (once.compareAndSet(false, true)) { + set.dispose(); + s.onError(e); + } else { + RxJavaPlugins.onError(e); + } + } + + @Override + public void onComplete() { + if (once.compareAndSet(false, true)) { + set.dispose(); + s.onComplete(); + } + } + + }); + } +} \ No newline at end of file diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpBlockingOperatorLatest.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpBlockingOperatorLatest.java index a88f32db60..22613c4cf3 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpBlockingOperatorLatest.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpBlockingOperatorLatest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -15,9 +15,10 @@ import java.util.*; import java.util.concurrent.Semaphore; -import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; +import java.util.concurrent.atomic.*; import io.reactivex.*; +import io.reactivex.Optional; import io.reactivex.internal.subscribers.nbp.NbpDisposableSubscriber; import io.reactivex.internal.util.Exceptions; @@ -32,6 +33,7 @@ public enum NbpBlockingOperatorLatest { * Returns an {@code Iterable} that blocks until or unless the {@code Observable} emits an item that has not * been returned by the {@code Iterable}, then returns that item * + * @param the value type * @param source * the source {@code Observable} * @return an {@code Iterable} that blocks until or unless the {@code Observable} emits an item that has not @@ -41,7 +43,7 @@ public static Iterable latest(final NbpObservable source) { return new Iterable() { @Override public Iterator iterator() { - NbpLatestObserverIterator lio = new NbpLatestObserverIterator<>(); + NbpLatestObserverIterator lio = new NbpLatestObserverIterator(); @SuppressWarnings("unchecked") NbpObservable>> materialized = ((NbpObservable)source).materialize(); @@ -56,15 +58,11 @@ public Iterator iterator() { static final class NbpLatestObserverIterator extends NbpDisposableSubscriber>> implements Iterator { final Semaphore notify = new Semaphore(0); // observer's notification - volatile Try> value; - /** Updater for the value field. */ - @SuppressWarnings("rawtypes") - static final AtomicReferenceFieldUpdater REFERENCE_UPDATER - = AtomicReferenceFieldUpdater.newUpdater(NbpLatestObserverIterator.class, Try.class, "value"); + final AtomicReference>> value = new AtomicReference>>(); @Override public void onNext(Try> args) { - boolean wasntAvailable = REFERENCE_UPDATER.getAndSet(this, args) == null; + boolean wasntAvailable = value.getAndSet(args) == null; if (wasntAvailable) { notify.release(); } @@ -99,8 +97,7 @@ public boolean hasNext() { throw Exceptions.propagate(ex); } - @SuppressWarnings("unchecked") - Try> n = REFERENCE_UPDATER.getAndSet(this, null); + Try> n = value.getAndSet(null); iNotif = n; if (iNotif.hasError()) { throw Exceptions.propagate(iNotif.error()); diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpBlockingOperatorMostRecent.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpBlockingOperatorMostRecent.java index 672d8facc1..eff82c060f 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpBlockingOperatorMostRecent.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpBlockingOperatorMostRecent.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -29,6 +29,7 @@ public enum NbpBlockingOperatorMostRecent { /** * Returns an {@code Iterable} that always returns the item most recently emitted by the {@code Observable}. * + * @param the value type * @param source * the source {@code Observable} * @param initialValue @@ -41,7 +42,7 @@ public static Iterable mostRecent(final NbpObservable source return new Iterable() { @Override public Iterator iterator() { - NbpMostRecentObserver mostRecentObserver = new NbpMostRecentObserver<>(initialValue); + NbpMostRecentObserver mostRecentObserver = new NbpMostRecentObserver(initialValue); /** * Subscribe instead of unsafeSubscribe since this is the final subscribe in the chain @@ -79,7 +80,7 @@ public void onNext(T args) { /** * The {@link Iterator} return is not thread safe. In other words don't call {@link Iterator#hasNext()} in one * thread expect {@link Iterator#next()} called from a different thread to work. - * @return + * @return the Iterator */ public Iterator getIterable() { return new Iterator() { diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpBlockingOperatorNext.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpBlockingOperatorNext.java index 559ec979f4..293567d2f6 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpBlockingOperatorNext.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpBlockingOperatorNext.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -15,9 +15,10 @@ import java.util.*; import java.util.concurrent.*; -import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; +import java.util.concurrent.atomic.AtomicInteger; import io.reactivex.*; +import io.reactivex.Optional; import io.reactivex.internal.subscribers.nbp.NbpDisposableSubscriber; import io.reactivex.internal.util.Exceptions; @@ -32,6 +33,7 @@ public enum NbpBlockingOperatorNext { * Returns an {@code Iterable} that blocks until the {@code Observable} emits another item, then returns * that item. * + * @param the value type * @param items * the {@code Observable} to observe * @return an {@code Iterable} that behaves like a blocking version of {@code items} @@ -40,8 +42,8 @@ public static Iterable next(final NbpObservable items) { return new Iterable() { @Override public Iterator iterator() { - NbpNextObserver nextObserver = new NbpNextObserver<>(); - return new NextIterator<>(items, nextObserver); + NbpNextObserver nextObserver = new NbpNextObserver(); + return new NextIterator(items, nextObserver); } }; @@ -140,12 +142,8 @@ public void remove() { } private static class NbpNextObserver extends NbpDisposableSubscriber>> { - private final BlockingQueue>> buf = new ArrayBlockingQueue<>(1); - @SuppressWarnings("unused") - volatile int waiting; - @SuppressWarnings("rawtypes") - static final AtomicIntegerFieldUpdater WAITING_UPDATER - = AtomicIntegerFieldUpdater.newUpdater(NbpNextObserver.class, "waiting"); + private final BlockingQueue>> buf = new ArrayBlockingQueue>>(1); + final AtomicInteger waiting = new AtomicInteger(); @Override public void onComplete() { @@ -160,7 +158,7 @@ public void onError(Throwable e) { @Override public void onNext(Try> args) { - if (WAITING_UPDATER.getAndSet(this, 0) == 1 || !isOnNext(args)) { + if (waiting.getAndSet(0) == 1 || !isOnNext(args)) { Try> toOffer = args; while (!buf.offer(toOffer)) { Try> concurrentItem = buf.poll(); @@ -179,7 +177,7 @@ public Try> takeNext() throws InterruptedException { return buf.take(); } void setWaiting(int value) { - waiting = value; + waiting.set(value); } } diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpCachedObservable.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpCachedObservable.java index 92a5453703..3d3113a720 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpCachedObservable.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpCachedObservable.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -16,7 +16,7 @@ import java.util.concurrent.atomic.AtomicBoolean; import io.reactivex.NbpObservable; -import io.reactivex.disposables.Disposable; +import io.reactivex.disposables.*; import io.reactivex.internal.disposables.SerialResource; import io.reactivex.internal.util.*; @@ -32,6 +32,7 @@ public final class NbpCachedObservable extends NbpObservable { /** * Creates a cached Observable with a default capacity hint of 16. + * @param the value type * @param source the source Observable to cache * @return the CachedObservable instance */ @@ -41,6 +42,7 @@ public static NbpCachedObservable from(NbpObservable source) /** * Creates a cached Observable with the given capacity hint. + * @param the value type * @param source the source Observable to cache * @param capacityHint the hint for the internal buffer size * @return the CachedObservable instance @@ -49,9 +51,9 @@ public static NbpCachedObservable from(NbpObservable source, if (capacityHint < 1) { throw new IllegalArgumentException("capacityHint > 0 required"); } - CacheState state = new CacheState<>(source, capacityHint); - CachedSubscribe onSubscribe = new CachedSubscribe<>(state); - return new NbpCachedObservable<>(onSubscribe, state); + CacheState state = new CacheState(source, capacityHint); + CachedSubscribe onSubscribe = new CachedSubscribe(state); + return new NbpCachedObservable(onSubscribe, state); } /** @@ -116,7 +118,7 @@ public CacheState(NbpObservable source, int capacityHint) { super(capacityHint); this.source = source; this.producers = EMPTY; - this.connection = new SerialResource<>(Disposable::dispose); + this.connection = new SerialResource(Disposables.consumeAndDispose()); } /** * Adds a ReplayProducer to the producers array atomically. @@ -230,7 +232,7 @@ public CachedSubscribe(CacheState state) { @Override public void accept(NbpSubscriber t) { // we can connect first because we replay everything anyway - ReplaySubscription rp = new ReplaySubscription<>(t, state); + ReplaySubscription rp = new ReplaySubscription(t, state); state.addProducer(rp); t.onSubscribe(rp); diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpObservableScalarSource.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpObservableScalarSource.java index 64140eba78..eb009abbde 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpObservableScalarSource.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpObservableScalarSource.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,17 +13,17 @@ package io.reactivex.internal.operators.nbp; -import java.util.function.Function; - import io.reactivex.NbpObservable; +import io.reactivex.functions.Function; import io.reactivex.internal.disposables.EmptyDisposable; /** * Represents a constant scalar value. + * @param the value type */ public final class NbpObservableScalarSource extends NbpObservable { private final T value; - public NbpObservableScalarSource(T value) { + public NbpObservableScalarSource(final T value) { super(new NbpOnSubscribe() { @Override public void accept(NbpSubscriber s) { @@ -39,27 +39,30 @@ public T value() { return value; } - public NbpOnSubscribe scalarFlatMap(Function> mapper) { - return s -> { - NbpObservable other; - try { - other = mapper.apply(value); - } catch (Throwable e) { - EmptyDisposable.error(e, s); - return; - } - if (other == null) { - EmptyDisposable.error(new NullPointerException("The publisher returned by the function is null"), s); - return; - } - if (other instanceof NbpObservableScalarSource) { - @SuppressWarnings("unchecked") - NbpObservableScalarSource o = (NbpObservableScalarSource)other; - s.onSubscribe(EmptyDisposable.INSTANCE); - s.onNext(o.value); - s.onComplete(); - } else { - other.subscribe(s); + public NbpOnSubscribe scalarFlatMap(final Function> mapper) { + return new NbpOnSubscribe() { + @Override + public void accept(NbpSubscriber s) { + NbpObservable other; + try { + other = mapper.apply(value); + } catch (Throwable e) { + EmptyDisposable.error(e, s); + return; + } + if (other == null) { + EmptyDisposable.error(new NullPointerException("The publisher returned by the function is null"), s); + return; + } + if (other instanceof NbpObservableScalarSource) { + @SuppressWarnings("unchecked") + NbpObservableScalarSource o = (NbpObservableScalarSource)other; + s.onSubscribe(EmptyDisposable.INSTANCE); + s.onNext(o.value); + s.onComplete(); + } else { + other.subscribe(s); + } } }; } diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeAmb.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeAmb.java index 50187efb19..498ff6432d 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeAmb.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeAmb.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -59,7 +59,7 @@ public void accept(NbpSubscriber s) { return; } - AmbCoordinator ac = new AmbCoordinator<>(s, count); + AmbCoordinator ac = new AmbCoordinator(s, count); ac.subscribe(sources); } @@ -67,10 +67,7 @@ static final class AmbCoordinator implements Disposable { final NbpSubscriber actual; final AmbInnerSubscriber[] subscribers; - volatile int winner; - @SuppressWarnings("rawtypes") - static final AtomicIntegerFieldUpdater WINNER = - AtomicIntegerFieldUpdater.newUpdater(AmbCoordinator.class, "winner"); + final AtomicInteger winner = new AtomicInteger(); @SuppressWarnings("unchecked") public AmbCoordinator(NbpSubscriber actual, int count) { @@ -82,13 +79,13 @@ public void subscribe(NbpObservable[] sources) { AmbInnerSubscriber[] as = subscribers; int len = as.length; for (int i = 0; i < len; i++) { - as[i] = new AmbInnerSubscriber<>(this, i + 1, actual); + as[i] = new AmbInnerSubscriber(this, i + 1, actual); } - WINNER.lazySet(this, 0); // release the contents of 'as' + winner.lazySet(0); // release the contents of 'as' actual.onSubscribe(this); for (int i = 0; i < len; i++) { - if (winner != 0) { + if (winner.get() != 0) { return; } @@ -97,9 +94,16 @@ public void subscribe(NbpObservable[] sources) { } public boolean win(int index) { - int w = winner; + int w = winner.get(); if (w == 0) { - if (WINNER.compareAndSet(this, 0, index)) { + if (winner.compareAndSet(0, index)) { + AmbInnerSubscriber[] a = subscribers; + int n = a.length; + for (int i = 0; i < n; i++) { + if (i + 1 != index) { + a[i].dispose(); + } + } return true; } return false; @@ -109,8 +113,8 @@ public boolean win(int index) { @Override public void dispose() { - if (winner != -1) { - WINNER.lazySet(this, -1); + if (winner.get() != -1) { + winner.lazySet(-1); for (AmbInnerSubscriber a : subscribers) { a.dispose(); @@ -128,7 +132,10 @@ static final class AmbInnerSubscriber extends AtomicReference imp boolean won; - static final Disposable CANCELLED = () -> { }; + static final Disposable CANCELLED = new Disposable() { + @Override + public void dispose() { } + }; public AmbInnerSubscriber(AmbCoordinator parent, int index, NbpSubscriber actual) { this.parent = parent; @@ -202,4 +209,4 @@ public void dispose() { } } -} +} \ No newline at end of file diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeArraySource.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeArraySource.java index be62d188f5..52682f32ca 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeArraySource.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeArraySource.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -16,9 +16,6 @@ import io.reactivex.NbpObservable.*; import io.reactivex.disposables.BooleanDisposable; -/** - * - */ public final class NbpOnSubscribeArraySource implements NbpOnSubscribe { final T[] array; public NbpOnSubscribeArraySource(T[] array) { @@ -37,10 +34,15 @@ public void accept(NbpSubscriber s) { int n = a.length; for (int i = 0; i < n && !bd.isDisposed(); i++) { - s.onNext(a[i]); + T value = a[i]; + if (value == null) { + s.onError(new NullPointerException("The " + i + "th element is null")); + return; + } + s.onNext(value); } if (!bd.isDisposed()) { s.onComplete(); } } -} +} \ No newline at end of file diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeAutoConnect.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeAutoConnect.java index 70cbcfd615..a150e00264 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeAutoConnect.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeAutoConnect.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -14,10 +14,10 @@ package io.reactivex.internal.operators.nbp; import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.Consumer; import io.reactivex.NbpObservable.*; import io.reactivex.disposables.Disposable; +import io.reactivex.functions.Consumer; import io.reactivex.observables.nbp.NbpConnectableObservable; /** diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeCombineLatest.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeCombineLatest.java index 9934078716..976fe206c8 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeCombineLatest.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeCombineLatest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -15,11 +15,12 @@ import java.util.*; import java.util.concurrent.atomic.*; -import java.util.function.Function; import io.reactivex.NbpObservable; import io.reactivex.NbpObservable.*; import io.reactivex.disposables.Disposable; +import io.reactivex.exceptions.CompositeException; +import io.reactivex.functions.Function; import io.reactivex.internal.disposables.EmptyDisposable; import io.reactivex.internal.queue.SpscLinkedArrayQueue; import io.reactivex.internal.subscriptions.SubscriptionHelper; @@ -68,7 +69,7 @@ public void accept(NbpSubscriber s) { return; } - LatestCoordinator lc = new LatestCoordinator<>(s, combiner, count, bufferSize, delayError); + LatestCoordinator lc = new LatestCoordinator(s, combiner, count, bufferSize, delayError); lc.subscribe(sources); } @@ -88,11 +89,7 @@ static final class LatestCoordinator extends AtomicInteger implements Disp volatile boolean done; - volatile Throwable error; - @SuppressWarnings("rawtypes") - static final AtomicReferenceFieldUpdater ERROR = - AtomicReferenceFieldUpdater.newUpdater(LatestCoordinator.class, Throwable.class, "error"); - + final AtomicReference error = new AtomicReference(); int active; int complete; @@ -108,14 +105,14 @@ public LatestCoordinator(NbpSubscriber actual, this.delayError = delayError; this.latest = new Object[count]; this.subscribers = new CombinerSubscriber[count]; - this.queue = new SpscLinkedArrayQueue<>(bufferSize); + this.queue = new SpscLinkedArrayQueue(bufferSize); } public void subscribe(NbpObservable[] sources) { NbpSubscriber[] as = subscribers; int len = as.length; for (int i = 0; i < len; i++) { - as[i] = new CombinerSubscriber<>(this, i); + as[i] = new CombinerSubscriber(this, i); } lazySet(0); // release array contents actual.onSubscribe(this); @@ -184,7 +181,7 @@ void combine(T value, int index) { if (value != null && f) { queue.offer(cs, latest.clone()); } else - if (value == null && error != null) { + if (value == null && error.get() != null) { done = true; // if this source completed without a value } } else { @@ -247,6 +244,13 @@ void drain() { return; } + if (v == null) { + cancelled = true; + cancel(q); + a.onError(new NullPointerException("The combiner returned a null")); + return; + } + a.onNext(v); } @@ -267,7 +271,7 @@ boolean checkTerminated(boolean d, boolean empty, NbpSubscriber a, Queue q if (delayError) { if (empty) { clear(queue); - Throwable e = error; + Throwable e = error.get(); if (e != null) { a.onError(e); } else { @@ -276,7 +280,7 @@ boolean checkTerminated(boolean d, boolean empty, NbpSubscriber a, Queue q return true; } } else { - Throwable e = error; + Throwable e = error.get(); if (e != null) { cancel(q); a.onError(e); @@ -294,12 +298,14 @@ boolean checkTerminated(boolean d, boolean empty, NbpSubscriber a, Queue q void onError(Throwable e) { for (;;) { - Throwable curr = error; - if (curr != null) { - e.addSuppressed(curr); + Throwable curr = error.get(); + if (curr instanceof CompositeException) { + CompositeException ce = new CompositeException((CompositeException)curr); + ce.suppress(e); + e = ce; } Throwable next = e; - if (ERROR.compareAndSet(this, curr, next)) { + if (error.compareAndSet(curr, next)) { return; } } @@ -312,12 +318,12 @@ static final class CombinerSubscriber implements NbpSubscriber, Disposa boolean done; - volatile Disposable s; - @SuppressWarnings("rawtypes") - static final AtomicReferenceFieldUpdater S = - AtomicReferenceFieldUpdater.newUpdater(CombinerSubscriber.class, Disposable.class, "s"); + final AtomicReference s = new AtomicReference(); - static final Disposable CANCELLED = () -> { }; + static final Disposable CANCELLED = new Disposable() { + @Override + public void dispose() { } + }; public CombinerSubscriber(LatestCoordinator parent, int index) { this.parent = parent; @@ -326,9 +332,9 @@ public CombinerSubscriber(LatestCoordinator parent, int index) { @Override public void onSubscribe(Disposable s) { - if (!S.compareAndSet(this, null, s)) { + if (!this.s.compareAndSet(null, s)) { s.dispose(); - if (s != CANCELLED) { + if (this.s.get() != CANCELLED) { SubscriptionHelper.reportDisposableSet(); } return; @@ -365,13 +371,13 @@ public void onComplete() { @Override public void dispose() { - Disposable a = s; + Disposable a = s.get(); if (a != CANCELLED) { - a = S.getAndSet(this, CANCELLED); + a = s.getAndSet(CANCELLED); if (a != CANCELLED && a != null) { a.dispose(); } } } } -} +} \ No newline at end of file diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeCompletableFutureSource.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeCompletableFutureSource.java deleted file mode 100644 index 206696c9ac..0000000000 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeCompletableFutureSource.java +++ /dev/null @@ -1,48 +0,0 @@ -/** - * 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 io.reactivex.internal.operators.nbp; - -import java.util.concurrent.CompletableFuture; - -import io.reactivex.NbpObservable.*; -import io.reactivex.disposables.BooleanDisposable; - -/** - * - */ -public final class NbpOnSubscribeCompletableFutureSource implements NbpOnSubscribe { - final CompletableFuture future; - public NbpOnSubscribeCompletableFutureSource(CompletableFuture future) { - this.future = future; - } - @Override - public void accept(NbpSubscriber s) { - BooleanDisposable bd = new BooleanDisposable(); - s.onSubscribe(bd); - - future.whenComplete((v, e) -> { - if (!bd.isDisposed()) { - if (e != null) { - s.onError(e); - } else - if (v == null) { - s.onError(new NullPointerException()); - } else { - s.onNext(v); - s.onComplete(); - } - } - }); - } -} diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeDefer.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeDefer.java index a0b8ccc1d2..9cc3408f9c 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeDefer.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeDefer.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,15 +13,11 @@ package io.reactivex.internal.operators.nbp; -import java.util.function.Supplier; - import io.reactivex.NbpObservable; import io.reactivex.NbpObservable.*; +import io.reactivex.functions.Supplier; import io.reactivex.internal.disposables.EmptyDisposable; -/** - * - */ public final class NbpOnSubscribeDefer implements NbpOnSubscribe { final Supplier> supplier; public NbpOnSubscribeDefer(Supplier> supplier) { diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeDelaySubscriptionOther.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeDelaySubscriptionOther.java new file mode 100644 index 0000000000..c31e15a1dd --- /dev/null +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeDelaySubscriptionOther.java @@ -0,0 +1,96 @@ +/** + * 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.internal.operators.nbp; + +import io.reactivex.NbpObservable; +import io.reactivex.NbpObservable.*; +import io.reactivex.disposables.*; +import io.reactivex.plugins.RxJavaPlugins; + +/** + * Delays the subscription to the main source until the other + * observable fires an event or completes. + * @param the main type + * @param the other value type, ignored + */ +public final class NbpOnSubscribeDelaySubscriptionOther implements NbpOnSubscribe { + final NbpObservable main; + final NbpObservable other; + + public NbpOnSubscribeDelaySubscriptionOther(NbpObservable main, NbpObservable other) { + this.main = main; + this.other = other; + } + + @Override + public void accept(final NbpSubscriber child) { + final SerialDisposable serial = new SerialDisposable(); + child.onSubscribe(serial); + + NbpSubscriber otherSubscriber = new NbpSubscriber() { + boolean done; + @Override + public void onSubscribe(Disposable d) { + serial.set(d); + } + + @Override + public void onNext(U t) { + onComplete(); + } + + @Override + public void onError(Throwable e) { + if (done) { + RxJavaPlugins.onError(e); + return; + } + done = true; + child.onError(e); + } + + @Override + public void onComplete() { + if (done) { + return; + } + done = true; + + main.unsafeSubscribe(new NbpSubscriber() { + @Override + public void onSubscribe(Disposable d) { + serial.set(d); + } + + @Override + public void onNext(T value) { + child.onNext(value); + } + + @Override + public void onError(Throwable e) { + child.onError(e); + } + + @Override + public void onComplete() { + child.onComplete(); + } + }); + } + }; + + other.unsafeSubscribe(otherSubscriber); + } +} \ No newline at end of file diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeErrorSource.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeErrorSource.java index 9acca7a503..bad1f2de89 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeErrorSource.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeErrorSource.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,14 +13,10 @@ package io.reactivex.internal.operators.nbp; -import java.util.function.Supplier; - import io.reactivex.NbpObservable.*; +import io.reactivex.functions.Supplier; import io.reactivex.internal.disposables.EmptyDisposable; -/** - * - */ public final class NbpOnSubscribeErrorSource implements NbpOnSubscribe { final Supplier errorSupplier; public NbpOnSubscribeErrorSource(Supplier errorSupplier) { diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeFutureSource.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeFutureSource.java index 3215bb2a86..8ff4dce10c 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeFutureSource.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeFutureSource.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -46,8 +46,12 @@ public void accept(NbpSubscriber s) { future.cancel(true); // TODO ?? not sure about this } if (!bd.isDisposed()) { - s.onNext(v); - s.onComplete(); + if (v != null) { + s.onNext(v); + s.onComplete(); + } else { + s.onError(new NullPointerException("Future returned null")); + } } } } diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeGenerate.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeGenerate.java index 3a5357624b..4c825c2d7d 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeGenerate.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeGenerate.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,10 +13,9 @@ package io.reactivex.internal.operators.nbp; -import java.util.function.*; - import io.reactivex.NbpObservable.*; import io.reactivex.disposables.Disposable; +import io.reactivex.functions.*; import io.reactivex.internal.disposables.EmptyDisposable; import io.reactivex.plugins.RxJavaPlugins; @@ -43,7 +42,7 @@ public void accept(NbpSubscriber s) { return; } - GeneratorDisposable gd = new GeneratorDisposable<>(s, generator, disposeState, state); + GeneratorDisposable gd = new GeneratorDisposable(s, generator, disposeState, state); s.onSubscribe(gd); gd.run(); } diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeIntervalRangeSource.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeIntervalRangeSource.java index 33a62a6516..4e5336741d 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeIntervalRangeSource.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeIntervalRangeSource.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -14,7 +14,7 @@ package io.reactivex.internal.operators.nbp; import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; +import java.util.concurrent.atomic.AtomicReference; import io.reactivex.NbpObservable.*; import io.reactivex.Scheduler; @@ -58,11 +58,12 @@ static final class IntervalRangeSubscriber volatile boolean cancelled; - static final Disposable DISPOSED = () -> { }; + static final Disposable DISPOSED = new Disposable() { + @Override + public void dispose() { } + }; - volatile Disposable resource; - static final AtomicReferenceFieldUpdater RESOURCE = - AtomicReferenceFieldUpdater.newUpdater(IntervalRangeSubscriber.class, Disposable.class, "resource"); + final AtomicReference resource = new AtomicReference(); public IntervalRangeSubscriber(NbpSubscriber actual, long start, long end) { this.actual = actual; @@ -79,9 +80,9 @@ public void dispose() { } void disposeResource() { - Disposable d = resource; + Disposable d = resource.get(); if (d != DISPOSED) { - d = RESOURCE.getAndSet(this, DISPOSED); + d = resource.getAndSet(DISPOSED); if (d != DISPOSED && d != null) { d.dispose(); } @@ -111,7 +112,7 @@ public void run() { public void setResource(Disposable d) { for (;;) { - Disposable current = resource; + Disposable current = resource.get(); if (current == DISPOSED) { d.dispose(); return; @@ -120,7 +121,7 @@ public void setResource(Disposable d) { RxJavaPlugins.onError(new IllegalStateException("Resource already set!")); return; } - if (RESOURCE.compareAndSet(this, null, d)) { + if (resource.compareAndSet(null, d)) { return; } } diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeIntervalSource.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeIntervalSource.java index 2e0380adeb..a81a0183ed 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeIntervalSource.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeIntervalSource.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -14,7 +14,7 @@ package io.reactivex.internal.operators.nbp; import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; +import java.util.concurrent.atomic.*; import io.reactivex.NbpObservable.*; import io.reactivex.Scheduler; @@ -53,11 +53,12 @@ static final class IntervalSubscriber volatile boolean cancelled; - static final Disposable DISPOSED = () -> { }; + static final Disposable DISPOSED = new Disposable() { + @Override + public void dispose() { } + }; - volatile Disposable resource; - static final AtomicReferenceFieldUpdater RESOURCE = - AtomicReferenceFieldUpdater.newUpdater(IntervalSubscriber.class, Disposable.class, "resource"); + final AtomicReference resource = new AtomicReference(); public IntervalSubscriber(NbpSubscriber actual) { this.actual = actual; @@ -72,9 +73,9 @@ public void dispose() { } void disposeResource() { - Disposable d = resource; + Disposable d = resource.get(); if (d != DISPOSED) { - d = RESOURCE.getAndSet(this, DISPOSED); + d = resource.getAndSet(DISPOSED); if (d != DISPOSED && d != null) { d.dispose(); } @@ -90,7 +91,7 @@ public void run() { public void setResource(Disposable d) { for (;;) { - Disposable current = resource; + Disposable current = resource.get(); if (current == DISPOSED) { d.dispose(); return; @@ -99,7 +100,7 @@ public void setResource(Disposable d) { RxJavaPlugins.onError(new IllegalStateException("Resource already set!")); return; } - if (RESOURCE.compareAndSet(this, null, d)) { + if (resource.compareAndSet(null, d)) { return; } } diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeIterableSource.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeIterableSource.java index 204aa5d54b..1555555713 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeIterableSource.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeIterableSource.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -19,9 +19,6 @@ import io.reactivex.disposables.BooleanDisposable; import io.reactivex.internal.disposables.EmptyDisposable; -/** - * - */ public final class NbpOnSubscribeIterableSource implements NbpOnSubscribe { final Iterable source; public NbpOnSubscribeIterableSource(Iterable source) { diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeLift.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeLift.java index d79092892f..0259a30e9d 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeLift.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeLift.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeRedo.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeRedo.java index b2d41090c5..aff97aece6 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeRedo.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeRedo.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,13 +13,12 @@ package io.reactivex.internal.operators.nbp; -import java.util.Optional; import java.util.concurrent.atomic.*; -import java.util.function.Function; import io.reactivex.*; import io.reactivex.NbpObservable.*; import io.reactivex.disposables.*; +import io.reactivex.functions.*; import io.reactivex.internal.subscribers.nbp.NbpToNotificationSubscriber; import io.reactivex.subjects.nbp.NbpBehaviorSubject; @@ -39,16 +38,21 @@ public void accept(NbpSubscriber s) { // FIXE use BehaviorSubject? (once available) NbpBehaviorSubject>> subject = NbpBehaviorSubject.create(); - RedoSubscriber parent = new RedoSubscriber<>(s, subject, source); + final RedoSubscriber parent = new RedoSubscriber(s, subject, source); s.onSubscribe(parent.arbiter); NbpObservable action = manager.apply(subject); - action.subscribe(new NbpToNotificationSubscriber<>(parent::handle)); + action.subscribe(new NbpToNotificationSubscriber(new Consumer>>() { + @Override + public void accept(Try> o) { + parent.handle(o); + } + })); // trigger first subscription - parent.handle(Notification.next(0)); + parent.handle(Notification.next(0)); } static final class RedoSubscriber extends AtomicBoolean implements NbpSubscriber { @@ -59,10 +63,7 @@ static final class RedoSubscriber extends AtomicBoolean implements NbpSubscri final NbpObservable source; final MultipleAssignmentDisposable arbiter; - volatile int wip; - @SuppressWarnings("rawtypes") - static final AtomicIntegerFieldUpdater WIP = - AtomicIntegerFieldUpdater.newUpdater(RedoSubscriber.class, "wip"); + final AtomicInteger wip = new AtomicInteger(); public RedoSubscriber(NbpSubscriber actual, NbpBehaviorSubject>> subject, NbpObservable source) { this.actual = actual; @@ -85,7 +86,7 @@ public void onNext(T t) { @Override public void onError(Throwable t) { if (compareAndSet(false, true)) { - subject.onNext(Try.ofError(t)); + subject.onNext(Try.>ofError(t)); } } @@ -106,7 +107,7 @@ void handle(Try> notification) { if (o.isPresent()) { - if (WIP.getAndIncrement(this) == 0) { + if (wip.getAndIncrement() == 0) { int missed = 1; for (;;) { if (arbiter.isDisposed()) { @@ -114,7 +115,7 @@ void handle(Try> notification) { } source.subscribe(this); - missed = WIP.addAndGet(this, -missed); + missed = wip.addAndGet(-missed); if (missed == 0) { break; } diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeRefCount.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeRefCount.java index 1ea4b18dbb..596309bb52 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeRefCount.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeRefCount.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -15,10 +15,10 @@ import java.util.concurrent.atomic.*; import java.util.concurrent.locks.ReentrantLock; -import java.util.function.Consumer; import io.reactivex.NbpObservable.*; -import io.reactivex.disposables.Disposable; +import io.reactivex.disposables.*; +import io.reactivex.functions.Consumer; import io.reactivex.internal.disposables.SetCompositeResource; import io.reactivex.internal.subscriptions.SubscriptionHelper; import io.reactivex.observables.nbp.NbpConnectableObservable; @@ -85,7 +85,7 @@ void cleanup() { try { if (baseSubscription == currentBase) { baseSubscription.dispose(); - baseSubscription = new SetCompositeResource<>(Disposable::dispose); + baseSubscription = new SetCompositeResource(Disposables.consumeAndDispose()); subscriptionCount.set(0); } } finally { @@ -95,8 +95,10 @@ void cleanup() { } final NbpConnectableObservable source; - volatile SetCompositeResource baseSubscription = new SetCompositeResource<>(Disposable::dispose); - final AtomicInteger subscriptionCount = new AtomicInteger(0); + + volatile SetCompositeResource baseSubscription = new SetCompositeResource(Disposables.consumeAndDispose()); + + final AtomicInteger subscriptionCount = new AtomicInteger(); /** * Use this lock for every subscription and disconnect action. @@ -149,15 +151,18 @@ public void accept(final NbpSubscriber subscriber) { private Consumer onSubscribe(final NbpSubscriber subscriber, final AtomicBoolean writeLocked) { - return subscription -> { - try { - baseSubscription.add(subscription); - // ready to subscribe to source so do it - doSubscribe(subscriber, baseSubscription); - } finally { - // release the write lock - lock.unlock(); - writeLocked.set(false); + return new Consumer() { + @Override + public void accept(Disposable subscription) { + try { + baseSubscription.add(subscription); + // ready to subscribe to source so do it + doSubscribe(subscriber, baseSubscription); + } finally { + // release the write lock + lock.unlock(); + writeLocked.set(false); + } } }; } @@ -172,19 +177,22 @@ void doSubscribe(final NbpSubscriber subscriber, final SetCompositeRe } private Disposable disconnect(final SetCompositeResource current) { - return () -> { - lock.lock(); - try { - if (baseSubscription == current) { - if (subscriptionCount.decrementAndGet() == 0) { - baseSubscription.dispose(); - // need a new baseSubscription because once - // unsubscribed stays that way - baseSubscription = new SetCompositeResource<>(Disposable::dispose); + return new Disposable() { + @Override + public void dispose() { + lock.lock(); + try { + if (baseSubscription == current) { + if (subscriptionCount.decrementAndGet() == 0) { + baseSubscription.dispose(); + // need a new baseSubscription because once + // unsubscribed stays that way + baseSubscription = new SetCompositeResource(Disposables.consumeAndDispose()); + } } + } finally { + lock.unlock(); } - } finally { - lock.unlock(); } }; } diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeRepeat.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeRepeat.java index 9d1566d30a..d1c87ee84e 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeRepeat.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeRepeat.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -32,7 +32,7 @@ public void accept(NbpSubscriber s) { MultipleAssignmentDisposable mad = new MultipleAssignmentDisposable(); s.onSubscribe(mad); - RepeatSubscriber rs = new RepeatSubscriber<>(s, count != Long.MAX_VALUE ? count - 1 : Long.MAX_VALUE, mad, source); + RepeatSubscriber rs = new RepeatSubscriber(s, count != Long.MAX_VALUE ? count - 1 : Long.MAX_VALUE, mad, source); rs.subscribeNext(); } diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeRepeatUntil.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeRepeatUntil.java index 9d928c904a..deec32b34c 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeRepeatUntil.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeRepeatUntil.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -14,11 +14,11 @@ package io.reactivex.internal.operators.nbp; import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.BooleanSupplier; import io.reactivex.NbpObservable; import io.reactivex.NbpObservable.*; import io.reactivex.disposables.*; +import io.reactivex.functions.BooleanSupplier; public final class NbpOnSubscribeRepeatUntil implements NbpOnSubscribe { final NbpObservable source; @@ -33,7 +33,7 @@ public void accept(NbpSubscriber s) { MultipleAssignmentDisposable sa = new MultipleAssignmentDisposable(); s.onSubscribe(sa); - RepeatSubscriber rs = new RepeatSubscriber<>(s, until, sa, source); + RepeatSubscriber rs = new RepeatSubscriber(s, until, sa, source); rs.subscribeNext(); } diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeRetryBiPredicate.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeRetryBiPredicate.java index 5dd451b7b3..0ba5868da4 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeRetryBiPredicate.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeRetryBiPredicate.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -14,11 +14,12 @@ package io.reactivex.internal.operators.nbp; import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.BiPredicate; import io.reactivex.NbpObservable; import io.reactivex.NbpObservable.*; import io.reactivex.disposables.*; +import io.reactivex.exceptions.CompositeException; +import io.reactivex.functions.BiPredicate; public final class NbpOnSubscribeRetryBiPredicate implements NbpOnSubscribe { final NbpObservable source; @@ -35,7 +36,7 @@ public void accept(NbpSubscriber s) { SerialDisposable sa = new SerialDisposable(); s.onSubscribe(sa); - RetryBiSubscriber rs = new RetryBiSubscriber<>(s, predicate, sa, source); + RetryBiSubscriber rs = new RetryBiSubscriber(s, predicate, sa, source); rs.subscribeNext(); } @@ -71,8 +72,7 @@ public void onError(Throwable t) { try { b = predicate.test(++retries, t); } catch (Throwable e) { - e.addSuppressed(t); - actual.onError(e); + actual.onError(new CompositeException(e, t)); return; } if (!b) { diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeRetryPredicate.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeRetryPredicate.java index 5ffed4f51a..3b4516317f 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeRetryPredicate.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeRetryPredicate.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -14,11 +14,12 @@ package io.reactivex.internal.operators.nbp; import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.Predicate; import io.reactivex.NbpObservable; import io.reactivex.NbpObservable.*; import io.reactivex.disposables.*; +import io.reactivex.exceptions.CompositeException; +import io.reactivex.functions.Predicate; public final class NbpOnSubscribeRetryPredicate implements NbpOnSubscribe { final NbpObservable source; @@ -37,7 +38,7 @@ public void accept(NbpSubscriber s) { SerialDisposable sa = new SerialDisposable(); s.onSubscribe(sa); - RepeatSubscriber rs = new RepeatSubscriber<>(s, count, predicate, sa, source); + RepeatSubscriber rs = new RepeatSubscriber(s, count, predicate, sa, source); rs.subscribeNext(); } @@ -81,8 +82,7 @@ public void onError(Throwable t) { try { b = predicate.test(t); } catch (Throwable e) { - e.addSuppressed(t); - actual.onError(e); + actual.onError(new CompositeException(e, t)); return; } if (!b) { diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeScalarAsyncSource.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeScalarAsyncSource.java index e2cd61c9d3..76356117d1 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeScalarAsyncSource.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeScalarAsyncSource.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -18,9 +18,6 @@ import io.reactivex.NbpObservable.*; import io.reactivex.disposables.BooleanDisposable; -/** - * - */ public final class NbpOnSubscribeScalarAsyncSource implements NbpOnSubscribe { final Callable callable; public NbpOnSubscribeScalarAsyncSource(Callable callable) { @@ -45,7 +42,11 @@ public void accept(NbpSubscriber s) { if (bd.isDisposed()) { return; } - s.onNext(value); - s.onComplete(); + if (value != null) { + s.onNext(value); + s.onComplete(); + } else { + s.onError(new NullPointerException("Callable returned null")); + } } } diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeSequenceEqual.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeSequenceEqual.java index 28f3912209..ec2866be4f 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeSequenceEqual.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeSequenceEqual.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -15,11 +15,11 @@ import java.util.Queue; import java.util.concurrent.atomic.*; -import java.util.function.BiPredicate; import io.reactivex.NbpObservable; import io.reactivex.NbpObservable.*; -import io.reactivex.disposables.Disposable; +import io.reactivex.disposables.*; +import io.reactivex.functions.BiPredicate; import io.reactivex.internal.disposables.ArrayCompositeResource; import io.reactivex.internal.queue.SpscLinkedArrayQueue; @@ -39,7 +39,7 @@ public NbpOnSubscribeSequenceEqual(NbpObservable first, NbpObservab @Override public void accept(NbpSubscriber s) { - EqualCoordinator ec = new EqualCoordinator<>(s, bufferSize, first, second, comparer); + EqualCoordinator ec = new EqualCoordinator(s, bufferSize, first, second, comparer); ec.subscribe(); } @@ -55,11 +55,6 @@ static final class EqualCoordinator extends AtomicInteger implements Disposab volatile boolean cancelled; - volatile int once; - @SuppressWarnings("rawtypes") - static final AtomicIntegerFieldUpdater ONCE = - AtomicIntegerFieldUpdater.newUpdater(EqualCoordinator.class, "once"); - public EqualCoordinator(NbpSubscriber actual, int bufferSize, NbpObservable first, NbpObservable second, BiPredicate comparer) { @@ -70,9 +65,9 @@ public EqualCoordinator(NbpSubscriber actual, int bufferSize, @SuppressWarnings("unchecked") EqualSubscriber[] as = new EqualSubscriber[2]; this.subscribers = as; - as[0] = new EqualSubscriber<>(this, 0, bufferSize); - as[1] = new EqualSubscriber<>(this, 1, bufferSize); - this.resources = new ArrayCompositeResource<>(2, Disposable::dispose); + as[0] = new EqualSubscriber(this, 0, bufferSize); + as[1] = new EqualSubscriber(this, 1, bufferSize); + this.resources = new ArrayCompositeResource(2, Disposables.consumeAndDispose()); } boolean setSubscription(Disposable s, int index) { @@ -217,7 +212,7 @@ static final class EqualSubscriber implements NbpSubscriber { public EqualSubscriber(EqualCoordinator parent, int index, int bufferSize) { this.parent = parent; this.index = index; - this.queue = new SpscLinkedArrayQueue<>(bufferSize); + this.queue = new SpscLinkedArrayQueue(bufferSize); } @Override diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeStreamSource.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeStreamSource.java deleted file mode 100644 index fa2cf5d9f8..0000000000 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeStreamSource.java +++ /dev/null @@ -1,101 +0,0 @@ -/** - * 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 io.reactivex.internal.operators.nbp; - -import java.util.Iterator; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.stream.Stream; - -import io.reactivex.NbpObservable.*; -import io.reactivex.disposables.BooleanDisposable; -import io.reactivex.internal.disposables.EmptyDisposable; - -/** - * - */ -public final class NbpOnSubscribeStreamSource extends AtomicBoolean implements NbpOnSubscribe { - /** */ - private static final long serialVersionUID = 9051303031779816842L; - - final Stream stream; - public NbpOnSubscribeStreamSource(Stream stream) { - this.stream = stream; - } - @Override - public void accept(NbpSubscriber s) { - if (compareAndSet(false, true)) { - Iterator it; - try { - it = stream.iterator(); - } catch (Throwable e) { - EmptyDisposable.error(e, s); - return; - } - - BooleanDisposable bd = new BooleanDisposable(); - - s.onSubscribe(bd); - if (bd.isDisposed()) { - return; - } - - boolean hasNext; - - try { - hasNext = it.hasNext(); - } catch (Throwable e) { - s.onError(e); - return; - } - - - do { - T v; - - try { - v = it.next(); - } catch (Throwable e) { - s.onError(e); - return; - } - - if (v == null) { - s.onError(new NullPointerException("The stream returned a null value")); - return; - } - - if (bd.isDisposed()) { - return; - } - - try { - hasNext = it.hasNext(); - } catch (Throwable e) { - s.onError(e); - return; - } - - if (bd.isDisposed()) { - return; - } - } while (hasNext); - if (bd.isDisposed()) { - return; - } - s.onComplete(); - return; - } - EmptyDisposable.error(new IllegalStateException("Contents already consumed"), s); - } -} diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeSubscribeOn.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeSubscribeOn.java index bc70a72099..5c263ac0cd 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeSubscribeOn.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeSubscribeOn.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -30,14 +30,17 @@ public NbpOnSubscribeSubscribeOn(NbpObservable source, Scheduler sc } @Override - public void accept(NbpSubscriber s) { + public void accept(final NbpSubscriber s) { /* * TODO can't use the returned disposable because to dispose it, * one must set a Subscription on s on the current thread, but * it is expected that onSubscribe is run on the target scheduler. */ - scheduler.scheduleDirect(() -> { - source.subscribe(s); + scheduler.scheduleDirect(new Runnable() { + @Override + public void run() { + source.subscribe(s); + } }); } diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeTimerOnceSource.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeTimerOnceSource.java index 6fc2fa1e0c..41420a9d10 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeTimerOnceSource.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeTimerOnceSource.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -16,8 +16,8 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; -import io.reactivex.NbpObservable.*; import io.reactivex.Scheduler; +import io.reactivex.NbpObservable.*; import io.reactivex.disposables.Disposable; import io.reactivex.plugins.RxJavaPlugins; @@ -48,10 +48,16 @@ static final class IntervalOnceSubscriber extends AtomicReference final NbpSubscriber actual; - static final Disposable DISPOSED = () -> { }; + static final Disposable DISPOSED = new Disposable() { + @Override + public void dispose() { } + }; /** This state tells the setResource not to call dispose since the run is finishing anyway. */ - static final Disposable DONE = () -> { }; + static final Disposable DONE = new Disposable() { + @Override + public void dispose() { } + }; volatile boolean cancelled; diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeUsing.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeUsing.java index 04a75df88e..218dc20e6e 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeUsing.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeUsing.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -14,11 +14,12 @@ package io.reactivex.internal.operators.nbp; import java.util.concurrent.atomic.AtomicBoolean; -import java.util.function.*; import io.reactivex.NbpObservable; import io.reactivex.NbpObservable.*; import io.reactivex.disposables.Disposable; +import io.reactivex.exceptions.CompositeException; +import io.reactivex.functions.*; import io.reactivex.internal.disposables.EmptyDisposable; import io.reactivex.internal.subscriptions.SubscriptionHelper; import io.reactivex.plugins.RxJavaPlugins; @@ -57,13 +58,14 @@ public void accept(NbpSubscriber s) { try { disposer.accept(resource); } catch (Throwable ex) { - e.addSuppressed(ex); + EmptyDisposable.error(new CompositeException(ex, e), s); + return; } EmptyDisposable.error(e, s); return; } - UsingSubscriber us = new UsingSubscriber<>(s, resource, disposer, eager); + UsingSubscriber us = new UsingSubscriber(s, resource, disposer, eager); source.subscribe(us); } @@ -107,7 +109,7 @@ public void onError(Throwable t) { try { disposer.accept(resource); } catch (Throwable e) { - t.addSuppressed(e); + t = new CompositeException(e, t); } } diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeZip.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeZip.java index cc5cd6356e..cdf8ec9486 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeZip.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeZip.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -15,11 +15,11 @@ import java.util.Queue; import java.util.concurrent.atomic.*; -import java.util.function.Function; import io.reactivex.NbpObservable; import io.reactivex.NbpObservable.*; import io.reactivex.disposables.Disposable; +import io.reactivex.functions.Function; import io.reactivex.internal.disposables.EmptyDisposable; import io.reactivex.internal.queue.SpscLinkedArrayQueue; import io.reactivex.plugins.RxJavaPlugins; @@ -68,7 +68,7 @@ public void accept(NbpSubscriber s) { return; } - ZipCoordinator zc = new ZipCoordinator<>(s, zipper, count, delayError); + ZipCoordinator zc = new ZipCoordinator(s, zipper, count, delayError); zc.subscribe(sources, bufferSize); } @@ -98,7 +98,7 @@ public void subscribe(NbpObservable[] sources, int bufferSize) { ZipSubscriber[] s = subscribers; int len = s.length; for (int i = 0; i < len; i++) { - s[i] = new ZipSubscriber<>(this, bufferSize); + s[i] = new ZipSubscriber(this, bufferSize); } // this makes sure the contents of the subscribers array is visible this.lazySet(0); @@ -180,6 +180,12 @@ public void drain() { return; } + if (v == null) { + clear(); + a.onError(new NullPointerException("The zipper returned a null value")); + return; + } + a.onNext(v); } @@ -235,22 +241,22 @@ static final class ZipSubscriber implements NbpSubscriber, Disposable { volatile boolean done; Throwable error; - volatile Disposable s; - @SuppressWarnings("rawtypes") - static final AtomicReferenceFieldUpdater S = - AtomicReferenceFieldUpdater.newUpdater(ZipSubscriber.class, Disposable.class, "s"); + final AtomicReference s = new AtomicReference(); - static final Disposable CANCELLED = () -> { }; + static final Disposable CANCELLED = new Disposable() { + @Override + public void dispose() { } + }; public ZipSubscriber(ZipCoordinator parent, int bufferSize) { this.parent = parent; - this.queue = new SpscLinkedArrayQueue<>(bufferSize); + this.queue = new SpscLinkedArrayQueue(bufferSize); } @Override public void onSubscribe(Disposable s) { for (;;) { - Disposable current = this.s; + Disposable current = this.s.get(); if (current == CANCELLED) { s.dispose(); return; @@ -260,7 +266,7 @@ public void onSubscribe(Disposable s) { RxJavaPlugins.onError(new IllegalStateException("Subscription already set!")); return; } - if (S.compareAndSet(this, null, s)) { + if (this.s.compareAndSet(null, s)) { return; } else { s.dispose(); @@ -272,12 +278,12 @@ public void onSubscribe(Disposable s) { @Override public void onNext(T t) { if (t == null) { - s.dispose(); + s.get().dispose(); onError(new NullPointerException()); return; } if (!queue.offer(t)) { - s.dispose(); + s.get().dispose(); onError(new IllegalStateException("Queue full?!")); return; } @@ -299,13 +305,13 @@ public void onComplete() { @Override public void dispose() { - Disposable s = this.s; + Disposable s = this.s.get(); if (s != CANCELLED) { - s = S.getAndSet(this, CANCELLED); + s = this.s.getAndSet(CANCELLED); if (s != CANCELLED && s != null) { s.dispose(); } } } } -} +} \ No newline at end of file diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeZipIterable.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeZipIterable.java index 2bca5452a1..5c562484ff 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeZipIterable.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeZipIterable.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -14,11 +14,11 @@ package io.reactivex.internal.operators.nbp; import java.util.Iterator; -import java.util.function.BiFunction; import io.reactivex.NbpObservable; import io.reactivex.NbpObservable.*; import io.reactivex.disposables.Disposable; +import io.reactivex.functions.BiFunction; import io.reactivex.internal.disposables.EmptyDisposable; import io.reactivex.internal.subscriptions.SubscriptionHelper; import io.reactivex.plugins.RxJavaPlugins; @@ -66,7 +66,7 @@ public void accept(NbpSubscriber t) { return; } - source.subscribe(new ZipIterableSubscriber<>(t, it, zipper)); + source.subscribe(new ZipIterableSubscriber(t, it, zipper)); } static final class ZipIterableSubscriber implements NbpSubscriber { diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorAll.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorAll.java index 715b28e987..59ce08e8b1 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorAll.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorAll.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -12,10 +12,9 @@ */ package io.reactivex.internal.operators.nbp; -import java.util.function.Predicate; - import io.reactivex.NbpObservable.*; import io.reactivex.disposables.Disposable; +import io.reactivex.functions.Predicate; import io.reactivex.internal.subscriptions.SubscriptionHelper; import io.reactivex.plugins.RxJavaPlugins; @@ -27,7 +26,7 @@ public NbpOperatorAll(Predicate predicate) { @Override public NbpSubscriber apply(NbpSubscriber t) { - return new AllSubscriber<>(t, predicate); + return new AllSubscriber(t, predicate); } static final class AllSubscriber implements NbpSubscriber { diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorAny.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorAny.java index 28e0b7fb8a..6d1c75f985 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorAny.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorAny.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -12,10 +12,9 @@ */ package io.reactivex.internal.operators.nbp; -import java.util.function.Predicate; - import io.reactivex.NbpObservable.*; import io.reactivex.disposables.Disposable; +import io.reactivex.functions.Predicate; import io.reactivex.internal.subscriptions.SubscriptionHelper; public final class NbpOperatorAny implements NbpOperator { @@ -26,7 +25,7 @@ public NbpOperatorAny(Predicate predicate) { @Override public NbpSubscriber apply(NbpSubscriber t) { - return new AnySubscriber<>(t, predicate); + return new AnySubscriber(t, predicate); } static final class AnySubscriber implements NbpSubscriber { diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorBuffer.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorBuffer.java index a7255bde99..e4764febd0 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorBuffer.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorBuffer.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -15,10 +15,10 @@ import java.util.*; import java.util.concurrent.atomic.AtomicBoolean; -import java.util.function.Supplier; import io.reactivex.NbpObservable.*; import io.reactivex.disposables.Disposable; +import io.reactivex.functions.Supplier; import io.reactivex.internal.disposables.EmptyDisposable; import io.reactivex.internal.subscribers.nbp.NbpEmptySubscriber; import io.reactivex.internal.subscriptions.SubscriptionHelper; @@ -37,13 +37,13 @@ public NbpOperatorBuffer(int count, int skip, Supplier bufferSupplier) { @Override public NbpSubscriber apply(NbpSubscriber t) { if (skip == count) { - BufferExactSubscriber bes = new BufferExactSubscriber<>(t, count, bufferSupplier); + BufferExactSubscriber bes = new BufferExactSubscriber(t, count, bufferSupplier); if (bes.createBuffer()) { return bes; } return NbpEmptySubscriber.INSTANCE; } - return new BufferSkipSubscriber<>(t, count, skip, bufferSupplier); + return new BufferSkipSubscriber(t, count, skip, bufferSupplier); } static final class BufferExactSubscriber> implements NbpSubscriber { @@ -155,7 +155,7 @@ public BufferSkipSubscriber(NbpSubscriber actual, int count, int skip this.count = count; this.skip = skip; this.bufferSupplier = bufferSupplier; - this.buffers = new ArrayDeque<>(); + this.buffers = new ArrayDeque(); } @Override diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorBufferBoundary.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorBufferBoundary.java index f93233c133..6e287f7e8c 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorBufferBoundary.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorBufferBoundary.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -14,16 +14,17 @@ package io.reactivex.internal.operators.nbp; import java.util.*; -import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; -import java.util.function.*; +import java.util.concurrent.atomic.AtomicInteger; import io.reactivex.NbpObservable; import io.reactivex.NbpObservable.*; -import io.reactivex.disposables.Disposable; +import io.reactivex.disposables.*; +import io.reactivex.functions.*; import io.reactivex.internal.disposables.SetCompositeResource; import io.reactivex.internal.queue.MpscLinkedQueue; import io.reactivex.internal.subscribers.nbp.*; import io.reactivex.internal.subscriptions.SubscriptionHelper; +import io.reactivex.internal.util.QueueDrainHelper; import io.reactivex.plugins.RxJavaPlugins; import io.reactivex.subscribers.nbp.NbpSerializedSubscriber; @@ -41,8 +42,8 @@ public NbpOperatorBufferBoundary(NbpObservable bufferOpen, @Override public NbpSubscriber apply(NbpSubscriber t) { - return new BufferBoundarySubscriber<>( - new NbpSerializedSubscriber<>(t), + return new BufferBoundarySubscriber( + new NbpSerializedSubscriber(t), bufferOpen, bufferClose, bufferSupplier ); } @@ -58,21 +59,18 @@ static final class BufferBoundarySubscriber, final List buffers; - volatile int windows; - @SuppressWarnings("rawtypes") - static final AtomicIntegerFieldUpdater WINDOWS = - AtomicIntegerFieldUpdater.newUpdater(BufferBoundarySubscriber.class, "windows"); + final AtomicInteger windows = new AtomicInteger(); public BufferBoundarySubscriber(NbpSubscriber actual, NbpObservable bufferOpen, Function> bufferClose, Supplier bufferSupplier) { - super(actual, new MpscLinkedQueue<>()); + super(actual, new MpscLinkedQueue()); this.bufferOpen = bufferOpen; this.bufferClose = bufferClose; this.bufferSupplier = bufferSupplier; - this.buffers = new LinkedList<>(); - this.resources = new SetCompositeResource<>(Disposable::dispose); + this.buffers = new LinkedList(); + this.resources = new SetCompositeResource(Disposables.consumeAndDispose()); } @Override public void onSubscribe(Disposable s) { @@ -81,12 +79,12 @@ public void onSubscribe(Disposable s) { } this.s = s; - BufferOpenSubscriber bos = new BufferOpenSubscriber<>(this); + BufferOpenSubscriber bos = new BufferOpenSubscriber(this); resources.add(bos); actual.onSubscribe(this); - WINDOWS.lazySet(this, 1); + windows.lazySet(1); bufferOpen.subscribe(bos); } @@ -111,7 +109,7 @@ public void onError(Throwable t) { @Override public void onComplete() { - if (WINDOWS.decrementAndGet(this) == 0) { + if (windows.decrementAndGet() == 0) { complete(); } } @@ -119,7 +117,7 @@ public void onComplete() { void complete() { List list; synchronized (this) { - list = new ArrayList<>(buffers); + list = new ArrayList(buffers); buffers.clear(); } @@ -129,7 +127,7 @@ void complete() { } done = true; if (enter()) { - drainLoop(q, actual, false, this); + QueueDrainHelper.drainLoop(q, actual, false, this, this); } } @@ -190,17 +188,17 @@ void open(Open window) { buffers.add(b); } - BufferCloseSubscriber bcs = new BufferCloseSubscriber<>(b, this); + BufferCloseSubscriber bcs = new BufferCloseSubscriber(b, this); resources.add(bcs); - WINDOWS.getAndIncrement(this); + windows.getAndIncrement(); p.subscribe(bcs); } void openFinished(Disposable d) { if (resources.remove(d)) { - if (WINDOWS.decrementAndGet(this) == 0) { + if (windows.decrementAndGet() == 0) { complete(); } } @@ -218,7 +216,7 @@ void close(U b, Disposable d) { } if (resources.remove(d)) { - if (WINDOWS.decrementAndGet(this) == 0) { + if (windows.decrementAndGet() == 0) { complete(); } } diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorBufferBoundarySupplier.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorBufferBoundarySupplier.java index 3e3d97f5a0..f4fc1d9392 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorBufferBoundarySupplier.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorBufferBoundarySupplier.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -14,16 +14,17 @@ package io.reactivex.internal.operators.nbp; import java.util.Collection; -import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; -import java.util.function.Supplier; +import java.util.concurrent.atomic.AtomicReference; import io.reactivex.NbpObservable; import io.reactivex.NbpObservable.*; import io.reactivex.disposables.Disposable; +import io.reactivex.functions.Supplier; import io.reactivex.internal.disposables.EmptyDisposable; import io.reactivex.internal.queue.MpscLinkedQueue; import io.reactivex.internal.subscribers.nbp.*; import io.reactivex.internal.subscriptions.SubscriptionHelper; +import io.reactivex.internal.util.QueueDrainHelper; import io.reactivex.plugins.RxJavaPlugins; import io.reactivex.subscribers.nbp.NbpSerializedSubscriber; @@ -38,7 +39,7 @@ public NbpOperatorBufferBoundarySupplier(Supplier> bo @Override public NbpSubscriber apply(NbpSubscriber t) { - return new BufferBondarySupplierSubscriber<>(new NbpSerializedSubscriber<>(t), bufferSupplier, boundarySupplier); + return new BufferBondarySupplierSubscriber(new NbpSerializedSubscriber(t), bufferSupplier, boundarySupplier); } static final class BufferBondarySupplierSubscriber, B> @@ -49,18 +50,18 @@ static final class BufferBondarySupplierSubscriber OTHER = - AtomicReferenceFieldUpdater.newUpdater(BufferBondarySupplierSubscriber.class, Disposable.class, "other"); + final AtomicReference other = new AtomicReference(); - static final Disposable DISPOSED = () -> { }; + static final Disposable DISPOSED = new Disposable() { + @Override + public void dispose() { } + }; U buffer; public BufferBondarySupplierSubscriber(NbpSubscriber actual, Supplier bufferSupplier, Supplier> boundarySupplier) { - super(actual, new MpscLinkedQueue<>()); + super(actual, new MpscLinkedQueue()); this.bufferSupplier = bufferSupplier; this.boundarySupplier = boundarySupplier; } @@ -111,8 +112,8 @@ public void onSubscribe(Disposable s) { return; } - BufferBoundarySubscriber bs = new BufferBoundarySubscriber<>(this); - other = bs; + BufferBoundarySubscriber bs = new BufferBoundarySubscriber(this); + other.set(bs); actual.onSubscribe(this); @@ -151,7 +152,7 @@ public void onComplete() { queue.offer(b); done = true; if (enter()) { - drainLoop(queue, actual, false, this); + QueueDrainHelper.drainLoop(queue, actual, false, this, this); } } @@ -169,9 +170,9 @@ public void dispose() { } void disposeOther() { - Disposable d = other; + Disposable d = other.get(); if (d != DISPOSED) { - d = OTHER.getAndSet(this, DISPOSED); + d = other.getAndSet(DISPOSED); if (d != DISPOSED && d != null) { d.dispose(); } @@ -180,7 +181,7 @@ void disposeOther() { void next() { - Disposable o = other; + Disposable o = other.get(); U next; @@ -216,9 +217,9 @@ void next() { return; } - BufferBoundarySubscriber bs = new BufferBoundarySubscriber<>(this); + BufferBoundarySubscriber bs = new BufferBoundarySubscriber(this); - if (!OTHER.compareAndSet(this, o, bs)) { + if (!other.compareAndSet(o, bs)) { return; } diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorBufferExactBoundary.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorBufferExactBoundary.java index 88567cbd83..be5b4fa3eb 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorBufferExactBoundary.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorBufferExactBoundary.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -14,15 +14,16 @@ package io.reactivex.internal.operators.nbp; import java.util.Collection; -import java.util.function.Supplier; import io.reactivex.NbpObservable; import io.reactivex.NbpObservable.*; import io.reactivex.disposables.Disposable; +import io.reactivex.functions.Supplier; import io.reactivex.internal.disposables.EmptyDisposable; import io.reactivex.internal.queue.MpscLinkedQueue; import io.reactivex.internal.subscribers.nbp.*; import io.reactivex.internal.subscriptions.SubscriptionHelper; +import io.reactivex.internal.util.QueueDrainHelper; import io.reactivex.subscribers.nbp.NbpSerializedSubscriber; public final class NbpOperatorBufferExactBoundary, B> implements NbpOperator { @@ -36,7 +37,7 @@ public NbpOperatorBufferExactBoundary(NbpObservable boundary, Supplier buf @Override public NbpSubscriber apply(NbpSubscriber t) { - return new BufferExactBondarySubscriber<>(new NbpSerializedSubscriber<>(t), bufferSupplier, boundary); + return new BufferExactBondarySubscriber(new NbpSerializedSubscriber(t), bufferSupplier, boundary); } static final class BufferExactBondarySubscriber, B> @@ -53,7 +54,7 @@ static final class BufferExactBondarySubscriber actual, Supplier bufferSupplier, NbpObservable boundary) { - super(actual, new MpscLinkedQueue<>()); + super(actual, new MpscLinkedQueue()); this.bufferSupplier = bufferSupplier; this.boundary = boundary; } @@ -84,7 +85,7 @@ public void onSubscribe(Disposable s) { } buffer = b; - BufferBoundarySubscriber bs = new BufferBoundarySubscriber<>(this); + BufferBoundarySubscriber bs = new BufferBoundarySubscriber(this); other = bs; actual.onSubscribe(this); @@ -124,7 +125,7 @@ public void onComplete() { queue.offer(b); done = true; if (enter()) { - drainLoop(queue, actual, false, this); + QueueDrainHelper.drainLoop(queue, actual, false, this, this); } } diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorBufferTimed.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorBufferTimed.java index 8b52b278aa..1529afe21a 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorBufferTimed.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorBufferTimed.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -15,17 +15,18 @@ import java.util.*; import java.util.concurrent.*; -import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; -import java.util.function.Supplier; +import java.util.concurrent.atomic.*; import io.reactivex.NbpObservable.*; import io.reactivex.Scheduler; import io.reactivex.Scheduler.Worker; import io.reactivex.disposables.Disposable; +import io.reactivex.functions.Supplier; import io.reactivex.internal.disposables.EmptyDisposable; import io.reactivex.internal.queue.MpscLinkedQueue; import io.reactivex.internal.subscribers.nbp.NbpQueueDrainSubscriber; import io.reactivex.internal.subscriptions.SubscriptionHelper; +import io.reactivex.internal.util.QueueDrainHelper; import io.reactivex.subscribers.nbp.NbpSerializedSubscriber; public final class NbpOperatorBufferTimed> implements NbpOperator { @@ -52,23 +53,23 @@ public NbpOperatorBufferTimed(long timespan, long timeskip, TimeUnit unit, Sched @Override public NbpSubscriber apply(NbpSubscriber t) { if (timespan == timeskip && maxSize == Integer.MAX_VALUE) { - return new BufferExactUnboundedSubscriber<>( - new NbpSerializedSubscriber<>(t), + return new BufferExactUnboundedSubscriber( + new NbpSerializedSubscriber(t), bufferSupplier, timespan, unit, scheduler); } Scheduler.Worker w = scheduler.createWorker(); if (timespan == timeskip) { - return new BufferExactBoundedSubscriber<>( - new NbpSerializedSubscriber<>(t), + return new BufferExactBoundedSubscriber( + new NbpSerializedSubscriber(t), bufferSupplier, timespan, unit, maxSize, restartTimerOnMaxSize, w ); } // Can't use maxSize because what to do if a buffer is full but its // timespan hasn't been elapsed? - return new BufferSkipBoundedSubscriber<>( - new NbpSerializedSubscriber<>(t), + return new BufferSkipBoundedSubscriber( + new NbpSerializedSubscriber(t), bufferSupplier, timespan, timeskip, unit, w); } @@ -85,17 +86,17 @@ static final class BufferExactUnboundedSubscriber TIMER = - AtomicReferenceFieldUpdater.newUpdater(BufferExactUnboundedSubscriber.class, Disposable.class, "timer"); + final AtomicReference timer = new AtomicReference(); - static final Disposable CANCELLED = () -> { }; + static final Disposable CANCELLED = new Disposable() { + @Override + public void dispose() { } + }; public BufferExactUnboundedSubscriber( NbpSubscriber actual, Supplier bufferSupplier, long timespan, TimeUnit unit, Scheduler scheduler) { - super(actual, new MpscLinkedQueue<>()); + super(actual, new MpscLinkedQueue()); this.bufferSupplier = bufferSupplier; this.timespan = timespan; this.unit = unit; @@ -131,7 +132,7 @@ public void onSubscribe(Disposable s) { if (!cancelled) { Disposable d = scheduler.schedulePeriodicallyDirect(this, timespan, timespan, unit); - if (!TIMER.compareAndSet(this, null, d)) { + if (!timer.compareAndSet(null, d)) { d.dispose(); } } @@ -171,7 +172,7 @@ public void onComplete() { queue.offer(b); done = true; if (enter()) { - drainLoop(queue, actual, false, this); + QueueDrainHelper.drainLoop(queue, actual, false, this, this); } } @@ -182,9 +183,9 @@ public void dispose() { } void disposeTimer() { - Disposable d = timer; + Disposable d = timer.get(); if (d != CANCELLED) { - d = TIMER.getAndSet(this, CANCELLED); + d = timer.getAndSet(CANCELLED); if (d != CANCELLED && d != null) { d.dispose(); } @@ -260,13 +261,13 @@ static final class BufferSkipBoundedSubscriber actual, Supplier bufferSupplier, long timespan, long timeskip, TimeUnit unit, Worker w) { - super(actual, new MpscLinkedQueue<>()); + super(actual, new MpscLinkedQueue()); this.bufferSupplier = bufferSupplier; this.timespan = timespan; this.timeskip = timeskip; this.unit = unit; this.w = w; - this.buffers = new LinkedList<>(); + this.buffers = new LinkedList(); } @Override @@ -276,7 +277,7 @@ public void onSubscribe(Disposable s) { } this.s = s; - U b; + final U b; try { b = bufferSupplier.get(); @@ -300,19 +301,24 @@ public void onSubscribe(Disposable s) { w.schedulePeriodically(this, timeskip, timeskip, unit); - w.schedule(() -> { - synchronized (this) { - buffers.remove(b); + w.schedule(new Runnable() { + @Override + public void run() { + synchronized (BufferSkipBoundedSubscriber.this) { + buffers.remove(b); + } + + fastpathOrderedEmit(b, false, w); } - - fastpathOrderedEmit(b, false, w); }, timespan, unit); } @Override public void onNext(T t) { synchronized (this) { - buffers.forEach(b -> b.add(t)); + for (U b : buffers) { + b.add(t); + } } } @@ -328,14 +334,16 @@ public void onError(Throwable t) { public void onComplete() { List bs; synchronized (this) { - bs = new ArrayList<>(buffers); + bs = new ArrayList(buffers); buffers.clear(); } - bs.forEach(b -> queue.add(b)); + for (U b : bs) { + queue.add(b); + } done = true; if (enter()) { - drainLoop(queue, actual, false, w); + QueueDrainHelper.drainLoop(queue, actual, false, w, this); } } @@ -360,7 +368,7 @@ public void run() { if (cancelled) { return; } - U b; + final U b; try { b = bufferSupplier.get(); @@ -382,12 +390,15 @@ public void run() { buffers.add(b); } - w.schedule(() -> { - synchronized (this) { - buffers.remove(b); + w.schedule(new Runnable() { + @Override + public void run() { + synchronized (BufferSkipBoundedSubscriber.this) { + buffers.remove(b); + } + + fastpathOrderedEmit(b, false, w); } - - fastpathOrderedEmit(b, false, w); }, timespan, unit); } @@ -421,7 +432,7 @@ public BufferExactBoundedSubscriber( Supplier bufferSupplier, long timespan, TimeUnit unit, int maxSize, boolean restartOnMaxSize, Worker w) { - super(actual, new MpscLinkedQueue<>()); + super(actual, new MpscLinkedQueue()); this.bufferSupplier = bufferSupplier; this.timespan = timespan; this.unit = unit; @@ -539,7 +550,7 @@ public void onComplete() { queue.offer(b); done = true; if (enter()) { - drainLoop(queue, actual, false, this); + QueueDrainHelper.drainLoop(queue, actual, false, this, this); } } diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorCollect.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorCollect.java index 601c286a84..aa90efef3e 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorCollect.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorCollect.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -12,10 +12,9 @@ */ package io.reactivex.internal.operators.nbp; -import java.util.function.*; - import io.reactivex.NbpObservable.*; import io.reactivex.disposables.Disposable; +import io.reactivex.functions.*; import io.reactivex.internal.disposables.EmptyDisposable; import io.reactivex.internal.subscribers.nbp.NbpCancelledSubscriber; import io.reactivex.internal.subscriptions.SubscriptionHelper; @@ -40,7 +39,12 @@ public NbpSubscriber apply(NbpSubscriber t) { return NbpCancelledSubscriber.INSTANCE; } - return new CollectSubscriber<>(t, u, collector); + if (u == null) { + EmptyDisposable.error(new NullPointerException("The inital supplier returned a null value"), t); + return NbpCancelledSubscriber.INSTANCE; + } + + return new CollectSubscriber(t, u, collector); } static final class CollectSubscriber implements NbpSubscriber { @@ -86,4 +90,4 @@ public void onComplete() { actual.onComplete(); } } -} +} \ No newline at end of file diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorConcatMap.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorConcatMap.java index 632515f1bc..84c11cc5c6 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorConcatMap.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorConcatMap.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -14,11 +14,11 @@ import java.util.Queue; import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.Function; import io.reactivex.NbpObservable; import io.reactivex.NbpObservable.*; import io.reactivex.disposables.*; +import io.reactivex.functions.Function; import io.reactivex.internal.queue.SpscLinkedArrayQueue; import io.reactivex.internal.subscriptions.SubscriptionHelper; import io.reactivex.plugins.RxJavaPlugins; @@ -33,10 +33,10 @@ public NbpOperatorConcatMap(Function apply(NbpSubscriber s) { - NbpSerializedSubscriber ssub = new NbpSerializedSubscriber<>(s); + NbpSerializedSubscriber ssub = new NbpSerializedSubscriber(s); SerialDisposable sa = new SerialDisposable(); ssub.onSubscribe(sa); - return new SourceSubscriber<>(ssub, sa, mapper, bufferSize); + return new SourceSubscriber(ssub, sa, mapper, bufferSize); } static final class SourceSubscriber extends AtomicInteger implements NbpSubscriber { @@ -61,8 +61,8 @@ public SourceSubscriber(NbpSubscriber actual, SerialDisposable sa, this.sa = sa; this.mapper = mapper; this.bufferSize = bufferSize; - this.inner = new InnerSubscriber<>(actual, sa, this); - this.queue = new SpscLinkedArrayQueue<>(bufferSize); + this.inner = new InnerSubscriber(actual, sa, this); + this.queue = new SpscLinkedArrayQueue(bufferSize); } @Override public void onSubscribe(Disposable s) { @@ -137,6 +137,13 @@ void drain() { actual.onError(e); return; } + + if (p == null) { + cancel(); + actual.onError(new NullPointerException("The NbpObservable returned is null")); + return; + } + index++; // this is not RS but since our Subscriber doesn't hold state by itself, // subscribing it to each source is safe and saves allocation diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorCount.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorCount.java index e8fbc409d1..2c610944db 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorCount.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorCount.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorDebounce.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorDebounce.java index d10ea52059..771b652d55 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorDebounce.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorDebounce.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -14,11 +14,11 @@ package io.reactivex.internal.operators.nbp; import java.util.concurrent.atomic.*; -import java.util.function.Function; import io.reactivex.NbpObservable; import io.reactivex.NbpObservable.*; import io.reactivex.disposables.Disposable; +import io.reactivex.functions.Function; import io.reactivex.internal.subscribers.nbp.NbpDisposableSubscriber; import io.reactivex.internal.subscriptions.SubscriptionHelper; import io.reactivex.plugins.RxJavaPlugins; @@ -33,7 +33,7 @@ public NbpOperatorDebounce(Function> debou @Override public NbpSubscriber apply(NbpSubscriber t) { - return new DebounceSubscriber<>(new NbpSerializedSubscriber<>(t), debounceSelector); + return new DebounceSubscriber(new NbpSerializedSubscriber(t), debounceSelector); } static final class DebounceSubscriber @@ -45,12 +45,12 @@ static final class DebounceSubscriber Disposable s; - volatile Disposable debouncer; - @SuppressWarnings("rawtypes") - static final AtomicReferenceFieldUpdater DEBOUNCER = - AtomicReferenceFieldUpdater.newUpdater(DebounceSubscriber.class, Disposable.class, "debouncer"); + final AtomicReference debouncer = new AtomicReference(); - static final Disposable CANCELLED = () -> { }; + static final Disposable CANCELLED = new Disposable() { + @Override + public void dispose() { } + }; volatile long index; @@ -81,7 +81,7 @@ public void onNext(T t) { long idx = index + 1; index = idx; - Disposable d = debouncer; + Disposable d = debouncer.get(); if (d != null) { d.dispose(); } @@ -102,9 +102,9 @@ public void onNext(T t) { return; } - DebounceInnerSubscriber dis = new DebounceInnerSubscriber<>(this, idx, t); + DebounceInnerSubscriber dis = new DebounceInnerSubscriber(this, idx, t); - if (DEBOUNCER.compareAndSet(this, d, dis)) { + if (debouncer.compareAndSet(d, dis)) { p.subscribe(dis); } } @@ -121,7 +121,7 @@ public void onComplete() { return; } done = true; - Disposable d = debouncer; + Disposable d = debouncer.get(); if (d != CANCELLED) { @SuppressWarnings("unchecked") DebounceInnerSubscriber dis = (DebounceInnerSubscriber)d; @@ -138,9 +138,9 @@ public void dispose() { } public void disposeDebouncer() { - Disposable d = debouncer; + Disposable d = debouncer.get(); if (d != CANCELLED) { - d = DEBOUNCER.getAndSet(this, CANCELLED); + d = debouncer.getAndSet(CANCELLED); if (d != CANCELLED && d != null) { d.dispose(); } @@ -160,10 +160,7 @@ static final class DebounceInnerSubscriber extends NbpDisposableSubscriber boolean done; - volatile int once; - @SuppressWarnings("rawtypes") - static final AtomicIntegerFieldUpdater ONCE = - AtomicIntegerFieldUpdater.newUpdater(DebounceInnerSubscriber.class, "once"); + final AtomicBoolean once = new AtomicBoolean(); public DebounceInnerSubscriber(DebounceSubscriber parent, long index, T value) { this.parent = parent; @@ -182,7 +179,7 @@ public void onNext(U t) { } void emit() { - if (ONCE.compareAndSet(this, 0, 1)) { + if (once.compareAndSet(false, true)) { parent.emit(index, value); } } diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorDebounceTimed.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorDebounceTimed.java index 0d82336469..86193be821 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorDebounceTimed.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorDebounceTimed.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -16,8 +16,8 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.*; -import io.reactivex.NbpObservable.*; import io.reactivex.Scheduler; +import io.reactivex.NbpObservable.*; import io.reactivex.Scheduler.Worker; import io.reactivex.disposables.Disposable; import io.reactivex.internal.subscriptions.SubscriptionHelper; @@ -37,8 +37,8 @@ public NbpOperatorDebounceTimed(long timeout, TimeUnit unit, Scheduler scheduler @Override public NbpSubscriber apply(NbpSubscriber t) { - return new DebounceTimedSubscriber<>( - new NbpSerializedSubscriber<>(t), + return new DebounceTimedSubscriber( + new NbpSerializedSubscriber(t), timeout, unit, scheduler.createWorker()); } @@ -51,14 +51,17 @@ static final class DebounceTimedSubscriber Disposable s; - volatile Disposable timer; - @SuppressWarnings("rawtypes") - static final AtomicReferenceFieldUpdater TIMER = - AtomicReferenceFieldUpdater.newUpdater(DebounceTimedSubscriber.class, Disposable.class, "timer"); + final AtomicReference timer = new AtomicReference(); - static final Disposable CANCELLED = () -> { }; + static final Disposable CANCELLED = new Disposable() { + @Override + public void dispose() { } + }; - static final Disposable NEW_TIMER = () -> { }; + static final Disposable NEW_TIMER = new Disposable() { + @Override + public void dispose() { } + }; volatile long index; @@ -72,9 +75,9 @@ public DebounceTimedSubscriber(NbpSubscriber actual, long timeout, Ti } public void disposeTimer() { - Disposable d = timer; + Disposable d = timer.get(); if (d != CANCELLED) { - d = TIMER.getAndSet(this, CANCELLED); + d = timer.getAndSet(CANCELLED); if (d != CANCELLED && d != null) { d.dispose(); } @@ -99,13 +102,13 @@ public void onNext(T t) { long idx = index + 1; index = idx; - Disposable d = timer; + Disposable d = timer.get(); if (d != null) { d.dispose(); } - DebounceEmitter de = new DebounceEmitter<>(t, idx, this); - if (!TIMER.compareAndSet(this, d, de)) { + DebounceEmitter de = new DebounceEmitter(t, idx, this); + if (!timer.compareAndSet(d, de)) { return; } @@ -132,7 +135,7 @@ public void onComplete() { } done = true; - Disposable d = timer; + Disposable d = timer.get(); if (d != CANCELLED) { @SuppressWarnings("unchecked") DebounceEmitter de = (DebounceEmitter)d; @@ -162,16 +165,16 @@ static final class DebounceEmitter extends AtomicReference implem /** */ private static final long serialVersionUID = 6812032969491025141L; - static final Disposable DISPOSED = () -> { }; + static final Disposable DISPOSED = new Disposable() { + @Override + public void dispose() { } + }; final T value; final long idx; final DebounceTimedSubscriber parent; - volatile int once; - @SuppressWarnings("rawtypes") - static final AtomicIntegerFieldUpdater ONCE = - AtomicIntegerFieldUpdater.newUpdater(DebounceEmitter.class, "once"); + final AtomicBoolean once = new AtomicBoolean(); public DebounceEmitter(T value, long idx, DebounceTimedSubscriber parent) { @@ -186,7 +189,7 @@ public void run() { } void emit() { - if (ONCE.compareAndSet(this, 0, 1)) { + if (once.compareAndSet(false, true)) { parent.emit(idx, value, this); } } diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorDelay.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorDelay.java index 075769d4be..15f909848f 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorDelay.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorDelay.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -15,8 +15,8 @@ import java.util.concurrent.TimeUnit; -import io.reactivex.NbpObservable.*; import io.reactivex.Scheduler; +import io.reactivex.NbpObservable.*; import io.reactivex.Scheduler.Worker; import io.reactivex.disposables.Disposable; import io.reactivex.internal.subscriptions.SubscriptionHelper; @@ -44,12 +44,12 @@ public NbpSubscriber apply(NbpSubscriber t) { if (delayError) { s = (NbpSubscriber)t; } else { - s = new NbpSerializedSubscriber<>(t); + s = new NbpSerializedSubscriber(t); } Scheduler.Worker w = scheduler.createWorker(); - return new DelaySubscriber<>(s, delay, unit, w, delayError); + return new DelaySubscriber(s, delay, unit, w, delayError); } static final class DelaySubscriber implements NbpSubscriber, Disposable { @@ -80,18 +80,26 @@ public void onSubscribe(Disposable s) { } @Override - public void onNext(T t) { - w.schedule(() -> actual.onNext(t), delay, unit); + public void onNext(final T t) { + w.schedule(new Runnable() { + @Override + public void run() { + actual.onNext(t); + } + }, delay, unit); } @Override - public void onError(Throwable t) { + public void onError(final Throwable t) { if (delayError) { - w.schedule(() -> { - try { - actual.onError(t); - } finally { - w.dispose(); + w.schedule(new Runnable() { + @Override + public void run() { + try { + actual.onError(t); + } finally { + w.dispose(); + } } }, delay, unit); } else { @@ -101,11 +109,14 @@ public void onError(Throwable t) { @Override public void onComplete() { - w.schedule(() -> { - try { - actual.onComplete(); - } finally { - w.dispose(); + w.schedule(new Runnable() { + @Override + public void run() { + try { + actual.onComplete(); + } finally { + w.dispose(); + } } }, delay, unit); } diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorDematerialize.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorDematerialize.java index 402556361d..51d11dd8ad 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorDematerialize.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorDematerialize.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,10 +13,8 @@ package io.reactivex.internal.operators.nbp; -import java.util.Optional; - +import io.reactivex.*; import io.reactivex.NbpObservable.*; -import io.reactivex.Try; import io.reactivex.disposables.Disposable; import io.reactivex.internal.subscriptions.SubscriptionHelper; import io.reactivex.plugins.RxJavaPlugins; @@ -31,7 +29,7 @@ public static NbpOperator>> instance() { @Override public NbpSubscriber>> apply(NbpSubscriber t) { - return new DematerializeSubscriber<>(t); + return new DematerializeSubscriber(t); } static final class DematerializeSubscriber implements NbpSubscriber>> { diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorDistinct.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorDistinct.java index b47d5073aa..c75cac9c0b 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorDistinct.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorDistinct.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,12 +13,14 @@ package io.reactivex.internal.operators.nbp; -import java.util.*; -import java.util.function.*; +import java.util.Collection; import io.reactivex.NbpObservable.*; import io.reactivex.disposables.Disposable; +import io.reactivex.exceptions.CompositeException; +import io.reactivex.functions.*; import io.reactivex.internal.disposables.EmptyDisposable; +import io.reactivex.internal.functions.*; import io.reactivex.internal.subscribers.nbp.NbpCancelledSubscriber; import io.reactivex.internal.subscriptions.SubscriptionHelper; @@ -31,38 +33,50 @@ public NbpOperatorDistinct(Function keySelector, Supplier NbpOperatorDistinct withCollection(Function keySelector, Supplier> collectionSupplier) { - Supplier> p = () -> { - Collection coll = collectionSupplier.get(); - - return t -> { - if (t == null) { - coll.clear(); - return true; - } - return coll.add(t); - }; + public static NbpOperatorDistinct withCollection(final Function keySelector, final Supplier> collectionSupplier) { + Supplier> p = new Supplier>() { + @Override + public Predicate get() { + final Collection coll = collectionSupplier.get(); + + return new Predicate() { + @Override + public boolean test(K t) { + if (t == null) { + coll.clear(); + return true; + } + return coll.add(t); + } + }; + } }; - return new NbpOperatorDistinct<>(keySelector, p); + return new NbpOperatorDistinct(keySelector, p); } static final NbpOperatorDistinct UNTIL_CHANGED; static { - Supplier> p = () -> { - Object[] last = { null }; - - return t -> { - if (t == null) { - last[0] = null; - return true; - } - Object o = last[0]; - last[0] = t; - return !Objects.equals(o, t); - }; + Supplier> p = new Supplier>() { + @Override + public Predicate get() { + final Object[] last = { null }; + + return new Predicate() { + @Override + public boolean test(Object t) { + if (t == null) { + last[0] = null; + return true; + } + Object o = last[0]; + last[0] = t; + return !Objects.equals(o, t); + } + }; + } }; - UNTIL_CHANGED = new NbpOperatorDistinct<>(v -> v, p); + UNTIL_CHANGED = new NbpOperatorDistinct(Functions.identity(), p); } @SuppressWarnings("unchecked") @@ -71,20 +85,26 @@ public static NbpOperatorDistinct untilChanged() { } public static NbpOperatorDistinct untilChanged(Function keySelector) { - Supplier> p = () -> { - Object[] last = { null }; - - return t -> { - if (t == null) { - last[0] = null; - return true; - } - Object o = last[0]; - last[0] = t; - return !Objects.equals(o, t); - }; + Supplier> p = new Supplier>() { + @Override + public Predicate get() { + final Object[] last = { null }; + + return new Predicate() { + @Override + public boolean test(K t) { + if (t == null) { + last[0] = null; + return true; + } + Object o = last[0]; + last[0] = t; + return !Objects.equals(o, t); + } + }; + } }; - return new NbpOperatorDistinct<>(keySelector, p); + return new NbpOperatorDistinct(keySelector, p); } @@ -103,7 +123,7 @@ public NbpSubscriber apply(NbpSubscriber t) { return NbpCancelledSubscriber.INSTANCE; } - return new DistinctSubscriber<>(t, keySelector, coll); + return new DistinctSubscriber(t, keySelector, coll); } static final class DistinctSubscriber implements NbpSubscriber { @@ -166,8 +186,7 @@ public void onError(Throwable t) { try { predicate.test(null); // special case: poison pill } catch (Throwable e) { - t.addSuppressed(e); - actual.onError(t); + actual.onError(new CompositeException(e, t)); return; } actual.onError(t); diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorDoOnEach.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorDoOnEach.java index 6dbb8e28df..4893c95262 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorDoOnEach.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorDoOnEach.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,10 +13,10 @@ package io.reactivex.internal.operators.nbp; -import java.util.function.Consumer; - import io.reactivex.NbpObservable.*; import io.reactivex.disposables.Disposable; +import io.reactivex.exceptions.CompositeException; +import io.reactivex.functions.Consumer; import io.reactivex.internal.subscriptions.SubscriptionHelper; import io.reactivex.plugins.RxJavaPlugins; @@ -38,7 +38,7 @@ public NbpOperatorDoOnEach(Consumer onNext, @Override public NbpSubscriber apply(NbpSubscriber t) { - return new DoOnEachSubscriber<>(t, onNext, onError, onComplete, onAfterTerminate); + return new DoOnEachSubscriber(t, onNext, onError, onComplete, onAfterTerminate); } static final class DoOnEachSubscriber implements NbpSubscriber { @@ -100,7 +100,7 @@ public void onError(Throwable t) { try { onError.accept(t); } catch (Throwable e) { - t.addSuppressed(e); + t = new CompositeException(e, t); } actual.onError(t); diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorElementAt.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorElementAt.java index f12013f9af..59f38865f9 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorElementAt.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorElementAt.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -26,7 +26,7 @@ public NbpOperatorElementAt(long index, T defaultValue) { } @Override public NbpSubscriber apply(NbpSubscriber t) { - return new ElementAtSubscriber<>(t, index, defaultValue); + return new ElementAtSubscriber(t, index, defaultValue); } static final class ElementAtSubscriber implements NbpSubscriber { diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorFilter.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorFilter.java index 622005c16f..452e45e700 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorFilter.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorFilter.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,10 +13,9 @@ package io.reactivex.internal.operators.nbp; -import java.util.function.Predicate; - import io.reactivex.NbpObservable.*; import io.reactivex.disposables.Disposable; +import io.reactivex.functions.Predicate; import io.reactivex.internal.subscriptions.SubscriptionHelper; public final class NbpOperatorFilter implements NbpOperator { @@ -27,7 +26,7 @@ public NbpOperatorFilter(Predicate predicate) { @Override public NbpSubscriber apply(NbpSubscriber s) { - return new FilterSubscriber<>(s, predicate); + return new FilterSubscriber(s, predicate); } static final class FilterSubscriber implements NbpSubscriber { diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorFlatMap.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorFlatMap.java index c542998dc8..2070d922c3 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorFlatMap.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorFlatMap.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -15,19 +15,16 @@ import java.util.*; import java.util.concurrent.atomic.*; -import java.util.function.Function; import io.reactivex.NbpObservable; import io.reactivex.NbpObservable.*; import io.reactivex.disposables.Disposable; -import io.reactivex.exceptions.MissingBackpressureException; +import io.reactivex.exceptions.*; +import io.reactivex.functions.Function; import io.reactivex.internal.queue.*; import io.reactivex.internal.subscriptions.SubscriptionHelper; import io.reactivex.internal.util.Pow2; -/** - * FIXME handle maxConcurrency case - */ public final class NbpOperatorFlatMap implements NbpOperator { final Function> mapper; final boolean delayErrors; @@ -45,7 +42,7 @@ public NbpOperatorFlatMap( @Override public NbpSubscriber apply(NbpSubscriber t) { - return new MergeSubscriber<>(t, mapper, delayErrors, maxConcurrency, bufferSize); + return new MergeSubscriber(t, mapper, delayErrors, maxConcurrency, bufferSize); } static final class MergeSubscriber extends AtomicInteger implements Disposable, NbpSubscriber { @@ -62,19 +59,13 @@ static final class MergeSubscriber extends AtomicInteger implements Dispos volatile boolean done; - volatile Queue errors; - @SuppressWarnings("rawtypes") - static final AtomicReferenceFieldUpdater ERRORS = - AtomicReferenceFieldUpdater.newUpdater(MergeSubscriber.class, Queue.class, "errors"); + final AtomicReference> errors = new AtomicReference>(); - static final Queue ERRORS_CLOSED = new RejectingQueue<>(); + static final Queue ERRORS_CLOSED = new RejectingQueue(); volatile boolean cancelled; - volatile InnerSubscriber[] subscribers; - @SuppressWarnings("rawtypes") - static final AtomicReferenceFieldUpdater SUBSCRIBERS = - AtomicReferenceFieldUpdater.newUpdater(MergeSubscriber.class, InnerSubscriber[].class, "subscribers"); + final AtomicReference[]> subscribers; static final InnerSubscriber[] EMPTY = new InnerSubscriber[0]; @@ -98,9 +89,9 @@ public MergeSubscriber(NbpSubscriber actual, Function(maxConcurrency); + sources = new ArrayDeque>(maxConcurrency); } - SUBSCRIBERS.lazySet(this, EMPTY); + this.subscribers = new AtomicReference[]>(EMPTY); } @Override @@ -144,14 +135,14 @@ public void onNext(T t) { } void subscribeInner(NbpObservable p) { - InnerSubscriber inner = new InnerSubscriber<>(this, uniqueId++); + InnerSubscriber inner = new InnerSubscriber(this, uniqueId++); addInner(inner); p.subscribe(inner); } void addInner(InnerSubscriber inner) { for (;;) { - InnerSubscriber[] a = subscribers; + InnerSubscriber[] a = subscribers.get(); if (a == CANCELLED) { inner.dispose(); return; @@ -160,7 +151,7 @@ void addInner(InnerSubscriber inner) { InnerSubscriber[] b = new InnerSubscriber[n + 1]; System.arraycopy(a, 0, b, 0, n); b[n] = inner; - if (SUBSCRIBERS.compareAndSet(this, a, b)) { + if (subscribers.compareAndSet(a, b)) { return; } } @@ -168,7 +159,7 @@ void addInner(InnerSubscriber inner) { void removeInner(InnerSubscriber inner) { for (;;) { - InnerSubscriber[] a = subscribers; + InnerSubscriber[] a = subscribers.get(); if (a == CANCELLED || a == EMPTY) { return; } @@ -191,7 +182,7 @@ void removeInner(InnerSubscriber inner) { System.arraycopy(a, 0, b, 0, j); System.arraycopy(a, j + 1, b, j, n - j - 1); } - if (SUBSCRIBERS.compareAndSet(this, a, b)) { + if (subscribers.compareAndSet(a, b)) { return; } } @@ -201,12 +192,12 @@ Queue getMainQueue() { Queue q = queue; if (q == null) { if (maxConcurrency == Integer.MAX_VALUE) { - q = new SpscLinkedArrayQueue<>(bufferSize); + q = new SpscLinkedArrayQueue(bufferSize); } else { if (Pow2.isPowerOfTwo(maxConcurrency)) { - q = new SpscArrayQueue<>(maxConcurrency); + q = new SpscArrayQueue(maxConcurrency); } else { - q = new SpscExactArrayQueue<>(maxConcurrency); + q = new SpscExactArrayQueue(maxConcurrency); } } queue = q; @@ -236,7 +227,7 @@ void tryEmitScalar(U value) { Queue getInnerQueue(InnerSubscriber inner) { Queue q = inner.queue; if (q == null) { - q = new SpscArrayQueue<>(bufferSize); + q = new SpscArrayQueue(bufferSize); inner.queue = q; } return q; @@ -251,7 +242,7 @@ void tryEmit(U value, InnerSubscriber inner) { } else { Queue q = inner.queue; if (q == null) { - q = new SpscLinkedArrayQueue<>(bufferSize); + q = new SpscLinkedArrayQueue(bufferSize); inner.queue = q; } if (!q.offer(value)) { @@ -334,11 +325,11 @@ void drainLoop() { boolean d = done; svq = queue; - InnerSubscriber[] inner = subscribers; + InnerSubscriber[] inner = subscribers.get(); int n = inner.length; if (d && (svq == null || svq.isEmpty()) && n == 0) { - Queue e = errors; + Queue e = errors.get(); if (e == null || e.isEmpty()) { child.onComplete(); } else { @@ -420,7 +411,6 @@ void drainLoop() { } if (innerCompleted) { - // TODO if (maxConcurrency != Integer.MAX_VALUE) { NbpObservable p; synchronized (this) { @@ -447,7 +437,7 @@ boolean checkTerminate() { unsubscribe(); return true; } - Queue e = errors; + Queue e = errors.get(); if (!delayErrors && (e != null && !e.isEmpty())) { try { reportError(e); @@ -460,6 +450,7 @@ boolean checkTerminate() { } void reportError(Queue q) { + CompositeException composite = null; Throwable ex = null; Throwable t; @@ -468,20 +459,27 @@ void reportError(Queue q) { if (count == 0) { ex = t; } else { - ex.addSuppressed(t); + if (composite == null) { + composite = new CompositeException(ex); + } + composite.suppress(t); } count++; } - actual.onError(ex); + if (composite != null) { + actual.onError(composite); + } else { + actual.onError(ex); + } } void unsubscribe() { - InnerSubscriber[] a = subscribers; + InnerSubscriber[] a = subscribers.get(); if (a != CANCELLED) { - a = SUBSCRIBERS.getAndSet(this, CANCELLED); + a = subscribers.getAndSet(CANCELLED); if (a != CANCELLED) { - ERRORS.getAndSet(this, ERRORS_CLOSED); + errors.getAndSet(ERRORS_CLOSED); for (InnerSubscriber inner : a) { inner.dispose(); } @@ -491,12 +489,12 @@ void unsubscribe() { Queue getErrorQueue() { for (;;) { - Queue q = errors; + Queue q = errors.get(); if (q != null) { return q; } - q = new MpscLinkedQueue<>(); - if (ERRORS.compareAndSet(this, null, q)) { + q = new MpscLinkedQueue(); + if (errors.compareAndSet(null, q)) { return q; } } @@ -513,7 +511,10 @@ static final class InnerSubscriber extends AtomicReference volatile boolean done; volatile Queue queue; - static final Disposable CANCELLED = () -> { }; + static final Disposable CANCELLED = new Disposable() { + @Override + public void dispose() { } + }; public InnerSubscriber(MergeSubscriber parent, long id) { this.id = id; @@ -575,7 +576,7 @@ public T peek() { @Override public Iterator iterator() { - return Collections.emptyIterator(); + return Collections.emptyList().iterator(); } @Override diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorGroupBy.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorGroupBy.java index 8b0c045bee..ef83b95ec5 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorGroupBy.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorGroupBy.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -16,10 +16,10 @@ import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.*; -import java.util.function.Function; import io.reactivex.NbpObservable.*; import io.reactivex.disposables.Disposable; +import io.reactivex.functions.Function; import io.reactivex.internal.disposables.EmptyDisposable; import io.reactivex.internal.queue.SpscLinkedArrayQueue; import io.reactivex.internal.subscriptions.SubscriptionHelper; @@ -40,7 +40,7 @@ public NbpOperatorGroupBy(Function keySelector, Function @Override public NbpSubscriber apply(NbpSubscriber> t) { - return new GroupBySubscriber<>(t, keySelector, valueSelector, bufferSize, delayError); + return new GroupBySubscriber(t, keySelector, valueSelector, bufferSize, delayError); } public static final class GroupBySubscriber extends AtomicInteger implements NbpSubscriber, Disposable { @@ -58,10 +58,7 @@ public static final class GroupBySubscriber extends AtomicInteger imple Disposable s; - volatile int cancelled; - @SuppressWarnings("rawtypes") - static final AtomicIntegerFieldUpdater CANCELLED = - AtomicIntegerFieldUpdater.newUpdater(GroupBySubscriber.class, "cancelled"); + final AtomicBoolean cancelled = new AtomicBoolean(); public GroupBySubscriber(NbpSubscriber> actual, Function keySelector, Function valueSelector, int bufferSize, boolean delayError) { this.actual = actual; @@ -69,7 +66,7 @@ public GroupBySubscriber(NbpSubscriber> actua this.valueSelector = valueSelector; this.bufferSize = bufferSize; this.delayError = delayError; - this.groups = new ConcurrentHashMap<>(); + this.groups = new ConcurrentHashMap>(); this.lazySet(1); } @@ -99,7 +96,7 @@ public void onNext(T t) { if (group == null) { // if the main has been cancelled, stop creating groups // and skip this value - if (cancelled != 0) { + if (cancelled.get()) { return; } @@ -119,13 +116,19 @@ public void onNext(T t) { onError(e); return; } + + if (v == null) { + s.dispose(); + onError(new NullPointerException("The value supplied is null")); + return; + } group.onNext(v); } @Override public void onError(Throwable t) { - List> list = new ArrayList<>(groups.values()); + List> list = new ArrayList>(groups.values()); groups.clear(); for (GroupedUnicast e : list) { @@ -137,7 +140,7 @@ public void onError(Throwable t) { @Override public void onComplete() { - List> list = new ArrayList<>(groups.values()); + List> list = new ArrayList>(groups.values()); groups.clear(); for (GroupedUnicast e : list) { @@ -151,7 +154,7 @@ public void onComplete() { public void dispose() { // cancelling the main source means we don't want any more groups // but running groups still require new values - if (CANCELLED.compareAndSet(this, 0, 1)) { + if (cancelled.compareAndSet(false, true)) { if (decrementAndGet() == 0) { s.dispose(); } @@ -170,8 +173,8 @@ public void cancel(K key) { static final class GroupedUnicast extends NbpGroupedObservable { public static GroupedUnicast createWith(K key, int bufferSize, GroupBySubscriber parent, boolean delayError) { - State state = new State<>(bufferSize, parent, key, delayError); - return new GroupedUnicast<>(key, state); + State state = new State(bufferSize, parent, key, delayError); + return new GroupedUnicast(key, state); } final State state; @@ -206,18 +209,12 @@ static final class State extends AtomicInteger implements Disposable, NbpO volatile boolean done; Throwable error; - volatile int cancelled; - @SuppressWarnings("rawtypes") - static final AtomicIntegerFieldUpdater CANCELLED = - AtomicIntegerFieldUpdater.newUpdater(State.class, "cancelled"); + final AtomicBoolean cancelled = new AtomicBoolean(); - volatile NbpSubscriber actual; - @SuppressWarnings("rawtypes") - static final AtomicReferenceFieldUpdater ACTUAL = - AtomicReferenceFieldUpdater.newUpdater(State.class, NbpSubscriber.class, "actual"); + final AtomicReference> actual = new AtomicReference>(); public State(int bufferSize, GroupBySubscriber parent, K key, boolean delayError) { - this.queue = new SpscLinkedArrayQueue<>(bufferSize); + this.queue = new SpscLinkedArrayQueue(bufferSize); this.parent = parent; this.key = key; this.delayError = delayError; @@ -225,7 +222,7 @@ public State(int bufferSize, GroupBySubscriber parent, K key, boolean d @Override public void dispose() { - if (CANCELLED.compareAndSet(this, 0, 1)) { + if (cancelled.compareAndSet(false, true)) { if (getAndIncrement() == 0) { parent.cancel(key); } @@ -234,7 +231,7 @@ public void dispose() { @Override public void accept(NbpSubscriber s) { - if (ACTUAL.compareAndSet(this, null, s)) { + if (actual.compareAndSet(null, s)) { s.onSubscribe(this); drain(); } else { @@ -271,7 +268,7 @@ void drain() { final Queue q = queue; final boolean delayError = this.delayError; - NbpSubscriber a = actual; + NbpSubscriber a = actual.get(); for (;;) { if (a != null) { if (checkTerminated(done, q.isEmpty(), a, delayError)) { @@ -300,13 +297,13 @@ void drain() { break; } if (a == null) { - a = actual; + a = actual.get(); } } } boolean checkTerminated(boolean d, boolean empty, NbpSubscriber a, boolean delayError) { - if (cancelled != 0) { + if (cancelled.get()) { queue.clear(); parent.cancel(key); return true; @@ -340,4 +337,4 @@ boolean checkTerminated(boolean d, boolean empty, NbpSubscriber a, bo return false; } } -} +} \ No newline at end of file diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorIgnoreElements.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorIgnoreElements.java index 521c83963e..449973c32b 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorIgnoreElements.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorIgnoreElements.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -25,7 +25,7 @@ public static NbpOperator instance() { } @Override - public NbpSubscriber apply(NbpSubscriber t) { + public NbpSubscriber apply(final NbpSubscriber t) { return new NbpSubscriber() { @Override public void onSubscribe(Disposable s) { diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorMap.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorMap.java index fad8205742..184920affe 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorMap.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorMap.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -14,16 +14,12 @@ package io.reactivex.internal.operators.nbp; -import java.util.function.Function; - import io.reactivex.NbpObservable.*; import io.reactivex.disposables.Disposable; +import io.reactivex.functions.Function; import io.reactivex.internal.subscriptions.SubscriptionHelper; import io.reactivex.plugins.RxJavaPlugins; -/** - * - */ public final class NbpOperatorMap implements NbpOperator { final Function function; @@ -33,7 +29,7 @@ public NbpOperatorMap(Function function) { @Override public NbpSubscriber apply(NbpSubscriber t) { - return new MapperSubscriber<>(t, function); + return new MapperSubscriber(t, function); } static final class MapperSubscriber implements NbpSubscriber { diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorMapNotification.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorMapNotification.java index 33189ac8fe..b9597c033e 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorMapNotification.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorMapNotification.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,11 +13,10 @@ package io.reactivex.internal.operators.nbp; -import java.util.function.*; - import io.reactivex.NbpObservable; import io.reactivex.NbpObservable.*; import io.reactivex.disposables.Disposable; +import io.reactivex.functions.*; import io.reactivex.internal.subscriptions.SubscriptionHelper; public final class NbpOperatorMapNotification implements NbpOperator, T>{ @@ -36,7 +35,7 @@ public NbpOperatorMapNotification(Function apply(NbpSubscriber> t) { - return new MapNotificationSubscriber<>(t, onNextMapper, onErrorMapper, onCompleteSupplier); + return new MapNotificationSubscriber(t, onNextMapper, onErrorMapper, onCompleteSupplier); } static final class MapNotificationSubscriber diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorMaterialize.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorMaterialize.java index 9fcd4cfd7c..94087b7ae8 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorMaterialize.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorMaterialize.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,8 +13,6 @@ package io.reactivex.internal.operators.nbp; -import java.util.Optional; - import io.reactivex.*; import io.reactivex.NbpObservable.*; import io.reactivex.disposables.Disposable; @@ -30,7 +28,7 @@ public static NbpOperator>, T> instance() { @Override public NbpSubscriber apply(NbpSubscriber>> t) { - return new MaterializeSubscriber<>(t); + return new MaterializeSubscriber(t); } static final class MaterializeSubscriber implements NbpSubscriber { diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorObserveOn.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorObserveOn.java index d98ead4fe8..aa3892f991 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorObserveOn.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorObserveOn.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -16,8 +16,8 @@ import java.util.Queue; import java.util.concurrent.atomic.AtomicInteger; -import io.reactivex.NbpObservable.*; import io.reactivex.Scheduler; +import io.reactivex.NbpObservable.*; import io.reactivex.disposables.Disposable; import io.reactivex.exceptions.MissingBackpressureException; import io.reactivex.internal.queue.SpscLinkedArrayQueue; @@ -43,7 +43,7 @@ public NbpSubscriber apply(NbpSubscriber t) { Scheduler.Worker w = scheduler.createWorker(); - return new ObserveOnSubscriber<>(t, w, delayError, bufferSize); + return new ObserveOnSubscriber(t, w, delayError, bufferSize); } /** @@ -78,7 +78,7 @@ public ObserveOnSubscriber(NbpSubscriber actual, Scheduler.Worker wor this.worker = worker; this.delayError = delayError; this.bufferSize = bufferSize; - this.queue = new SpscLinkedArrayQueue<>(bufferSize); + this.queue = new SpscLinkedArrayQueue(bufferSize); } @Override diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorOnErrorNext.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorOnErrorNext.java index 42630ab88b..3a28e0de91 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorOnErrorNext.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorOnErrorNext.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,11 +13,11 @@ package io.reactivex.internal.operators.nbp; -import java.util.function.Function; - import io.reactivex.NbpObservable; import io.reactivex.NbpObservable.*; import io.reactivex.disposables.*; +import io.reactivex.exceptions.CompositeException; +import io.reactivex.functions.Function; import io.reactivex.plugins.RxJavaPlugins; public final class NbpOperatorOnErrorNext implements NbpOperator { @@ -31,7 +31,7 @@ public NbpOperatorOnErrorNext(Function apply(NbpSubscriber t) { - OnErrorNextSubscriber parent = new OnErrorNextSubscriber<>(t, nextSupplier, allowFatal); + OnErrorNextSubscriber parent = new OnErrorNextSubscriber(t, nextSupplier, allowFatal); t.onSubscribe(parent.arbiter); return parent; } @@ -88,15 +88,14 @@ public void onError(Throwable t) { try { p = nextSupplier.apply(t); } catch (Throwable e) { - t.addSuppressed(e); - actual.onError(t); + actual.onError(new CompositeException(e, t)); return; } if (p == null) { NullPointerException npe = new NullPointerException("Observable is null"); - t.addSuppressed(npe); - actual.onError(t); + npe.initCause(t); + actual.onError(npe); return; } @@ -113,4 +112,4 @@ public void onComplete() { actual.onComplete(); } } -} +} \ No newline at end of file diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorOnErrorReturn.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorOnErrorReturn.java index 3977e9f6f9..5b98d1c494 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorOnErrorReturn.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorOnErrorReturn.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,10 +13,10 @@ package io.reactivex.internal.operators.nbp; -import java.util.function.Function; - import io.reactivex.NbpObservable.*; import io.reactivex.disposables.Disposable; +import io.reactivex.exceptions.CompositeException; +import io.reactivex.functions.Function; import io.reactivex.internal.subscriptions.SubscriptionHelper; public final class NbpOperatorOnErrorReturn implements NbpOperator { @@ -27,7 +27,7 @@ public NbpOperatorOnErrorReturn(Function valueSu @Override public NbpSubscriber apply(NbpSubscriber t) { - return new OnErrorReturnSubscriber<>(t, valueSupplier); + return new OnErrorReturnSubscriber(t, valueSupplier); } static final class OnErrorReturnSubscriber implements NbpSubscriber { @@ -64,14 +64,14 @@ public void onError(Throwable t) { try { v = valueSupplier.apply(t); } catch (Throwable e) { - t.addSuppressed(e); - actual.onError(t); + actual.onError(new CompositeException(e, t)); return; } if (v == null) { - t.addSuppressed(new NullPointerException("The supplied value is null")); - actual.onError(t); + NullPointerException e = new NullPointerException("The supplied value is null"); + e.initCause(t); + actual.onError(e); return; } @@ -84,4 +84,4 @@ public void onComplete() { actual.onComplete(); } } -} +} \ No newline at end of file diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorPublish.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorPublish.java index 062414ce95..3dd15f15b0 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorPublish.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorPublish.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -15,10 +15,10 @@ import java.util.Queue; import java.util.concurrent.atomic.*; -import java.util.function.*; import io.reactivex.NbpObservable; -import io.reactivex.disposables.Disposable; +import io.reactivex.disposables.*; +import io.reactivex.functions.*; import io.reactivex.internal.queue.SpscArrayQueue; import io.reactivex.internal.subscriptions.SubscriptionHelper; import io.reactivex.internal.util.NotificationLite; @@ -40,12 +40,14 @@ public final class NbpOperatorPublish extends NbpConnectableObservable { /** * Creates a OperatorPublish instance to publish values of the given source observable. + * @param the source value type * @param source the source observable + * @param bufferSize the size of the prefetch buffer * @return the connectable observable */ - public static NbpConnectableObservable create(NbpObservable source, int bufferSize) { + public static NbpConnectableObservable create(NbpObservable source, final int bufferSize) { // the current connection to source needs to be shared between the operator and its onSubscribe call - final AtomicReference> curr = new AtomicReference<>(); + final AtomicReference> curr = new AtomicReference>(); NbpOnSubscribe onSubscribe = new NbpOnSubscribe() { @Override public void accept(NbpSubscriber child) { @@ -57,7 +59,7 @@ public void accept(NbpSubscriber child) { // if there isn't one or it is unsubscribed if (r == null || r.isDisposed()) { // create a new subscriber to source - PublishSubscriber u = new PublishSubscriber<>(curr, bufferSize); + PublishSubscriber u = new PublishSubscriber(curr, bufferSize); // let's try setting it as the current subscriber-to-source if (!curr.compareAndSet(r, u)) { // didn't work, maybe someone else did it or the current subscriber @@ -69,7 +71,7 @@ public void accept(NbpSubscriber child) { } // create the backpressure-managing producer for this child - InnerProducer inner = new InnerProducer<>(r, child); + InnerProducer inner = new InnerProducer(r, child); /* * Try adding it to the current subscriber-to-source, add is atomic in respect * to other adds and the termination of the subscriber-to-source. @@ -110,19 +112,27 @@ public void accept(NbpSubscriber child) { } } }; - return new NbpOperatorPublish<>(onSubscribe, source, curr, bufferSize); + return new NbpOperatorPublish(onSubscribe, source, curr, bufferSize); } public static NbpObservable create(final NbpObservable source, - final Function, ? extends NbpObservable> selector, int bufferSize) { - return create(sr -> { - NbpConnectableObservable op = create(source, bufferSize); - - NbpSubscriberResourceWrapper srw = new NbpSubscriberResourceWrapper<>(sr, Disposable::dispose); - - selector.apply(op).subscribe(srw); - - op.connect(srw::setResource); + final Function, ? extends NbpObservable> selector, final int bufferSize) { + return create(new NbpOnSubscribe() { + @Override + public void accept(NbpSubscriber sr) { + NbpConnectableObservable op = create(source, bufferSize); + + final NbpSubscriberResourceWrapper srw = new NbpSubscriberResourceWrapper(sr, Disposables.consumeAndDispose()); + + selector.apply(op).subscribe(srw); + + op.connect(new Consumer() { + @Override + public void accept(Disposable r) { + srw.setResource(r); + } + }); + } }); } @@ -145,7 +155,7 @@ public void connect(Consumer connection) { // if there is none yet or the current has unsubscribed if (ps == null || ps.isDisposed()) { // create a new subscriber-to-source - PublishSubscriber u = new PublishSubscriber<>(current, bufferSize); + PublishSubscriber u = new PublishSubscriber(current, bufferSize); // try setting it as the current subscriber-to-source if (!current.compareAndSet(ps, u)) { // did not work, perhaps a new subscriber arrived @@ -207,16 +217,17 @@ static final class PublishSubscriber implements NbpSubscriber, Disposable /** Guarded by this. */ boolean missed; - volatile Disposable s; - static final AtomicReferenceFieldUpdater S = - AtomicReferenceFieldUpdater.newUpdater(PublishSubscriber.class, Disposable.class, "s"); + final AtomicReference s = new AtomicReference(); - static final Disposable CANCELLED = () -> { }; + static final Disposable CANCELLED = new Disposable() { + @Override + public void dispose() { } + }; public PublishSubscriber(AtomicReference> current, int bufferSize) { - this.queue = new SpscArrayQueue<>(bufferSize); + this.queue = new SpscArrayQueue(bufferSize); - this.producers = new AtomicReference<>(EMPTY); + this.producers = new AtomicReference(EMPTY); this.current = current; this.shouldConnect = new AtomicBoolean(); this.bufferSize = bufferSize; @@ -229,9 +240,9 @@ public void dispose() { if (ps != TERMINATED) { current.compareAndSet(PublishSubscriber.this, null); - Disposable a = s; + Disposable a = s.get(); if (a != CANCELLED) { - a = S.getAndSet(this, CANCELLED); + a = s.getAndSet(CANCELLED); if (a != CANCELLED && a != null) { a.dispose(); } @@ -246,9 +257,9 @@ public boolean isDisposed() { @Override public void onSubscribe(Disposable s) { - if (!S.compareAndSet(this, null, s)) { + if (!this.s.compareAndSet(null, s)) { s.dispose(); - if (this.s != CANCELLED) { + if (this.s.get() != CANCELLED) { SubscriptionHelper.reportSubscriptionSet(); } return; @@ -604,8 +615,6 @@ void dispatch() { /** * A Producer and Subscription that manages the request and unsubscription state of a * child subscriber in thread-safe manner. - * We use AtomicLong as a base class to save on extra allocation of an AtomicLong and also - * save the overhead of the AtomicIntegerFieldUpdater. * @param the value type */ static final class InnerProducer implements Disposable { diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorReplay.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorReplay.java index 8d657004c9..9957bda3e2 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorReplay.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorReplay.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -16,10 +16,10 @@ import java.util.*; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.*; -import java.util.function.*; import io.reactivex.*; -import io.reactivex.disposables.Disposable; +import io.reactivex.disposables.*; +import io.reactivex.functions.*; import io.reactivex.internal.disposables.EmptyDisposable; import io.reactivex.internal.subscriptions.SubscriptionHelper; import io.reactivex.internal.util.NotificationLite; @@ -35,47 +35,68 @@ public final class NbpOperatorReplay extends NbpConnectableObservable { final Supplier> bufferFactory; @SuppressWarnings("rawtypes") - static final Supplier DEFAULT_UNBOUNDED_FACTORY = () -> new UnboundedReplayBuffer<>(16); + static final Supplier DEFAULT_UNBOUNDED_FACTORY = new Supplier() { + @Override + public Object get() { + return new UnboundedReplayBuffer(16); + } + }; /** * Given a connectable observable factory, it multicasts over the generated * ConnectableObservable via a selector function. + * @param the value type of the NbpConnectableObservable + * @param the result value type * @param connectableFactory * @param selector - * @return + * @return the new NbpObservable instance */ - public static NbpObservable multicastSelector( + public static NbpObservable multicastSelector( final Supplier> connectableFactory, final Function, ? extends NbpObservable> selector) { - return NbpObservable.create(child -> { - NbpConnectableObservable co; - NbpObservable observable; - try { - co = connectableFactory.get(); - observable = selector.apply(co); - } catch (Throwable e) { - EmptyDisposable.error(e, child); - return; + return NbpObservable.create(new NbpOnSubscribe() { + @Override + public void accept(NbpSubscriber child) { + NbpConnectableObservable co; + NbpObservable observable; + try { + co = connectableFactory.get(); + observable = selector.apply(co); + } catch (Throwable e) { + EmptyDisposable.error(e, child); + return; + } + + final NbpSubscriberResourceWrapper srw = new NbpSubscriberResourceWrapper(child, Disposables.consumeAndDispose()); + + observable.subscribe(srw); + + co.connect(new Consumer() { + @Override + public void accept(Disposable r) { + srw.setResource(r); + } + }); } - - NbpSubscriberResourceWrapper srw = new NbpSubscriberResourceWrapper<>(child, Disposable::dispose); - - observable.subscribe(srw); - - co.connect(srw::setResource); }); } /** * Child Subscribers will observe the events of the ConnectableObservable on the * specified scheduler. - * @param co - * @param scheduler - * @return + * @param the value type + * @param co the connectable observable instance + * @param scheduler the target scheduler + * @return the new NbpConnectableObservable instance */ public static NbpConnectableObservable observeOn(final NbpConnectableObservable co, final Scheduler scheduler) { final NbpObservable observable = co.observeOn(scheduler); - return new NbpConnectableObservable(s -> observable.subscribe(s)) { + return new NbpConnectableObservable(new NbpOnSubscribe() { + @Override + public void accept(NbpSubscriber s) { + observable.subscribe(s); + } + }) { @Override public void connect(Consumer connection) { co.connect(connection); @@ -85,8 +106,9 @@ public void connect(Consumer connection) { /** * Creates a replaying ConnectableObservable with an unbounded buffer. - * @param source - * @return + * @param the value type + * @param source the source observable + * @return the new NbpConnectableObservable instance */ @SuppressWarnings("unchecked") public static NbpConnectableObservable createFrom(NbpObservable source) { @@ -95,25 +117,32 @@ public static NbpConnectableObservable createFrom(NbpObservable the value type * @param source * @param bufferSize - * @return + * @return the new NbpConnectableObservable instance */ public static NbpConnectableObservable create(NbpObservable source, final int bufferSize) { if (bufferSize == Integer.MAX_VALUE) { return createFrom(source); } - return create(source, () -> new SizeBoundReplayBuffer<>(bufferSize)); + return create(source, new Supplier>() { + @Override + public ReplayBuffer get() { + return new SizeBoundReplayBuffer(bufferSize); + } + }); } /** * Creates a replaying ConnectableObservable with a time bound buffer. + * @param the value type * @param source * @param maxAge * @param unit * @param scheduler - * @return + * @return the new NbpConnectableObservable instance */ public static NbpConnectableObservable create(NbpObservable source, long maxAge, TimeUnit unit, Scheduler scheduler) { @@ -122,16 +151,22 @@ public static NbpConnectableObservable create(NbpObservable /** * Creates a replaying ConnectableObservable with a size and time bound buffer. + * @param the value type * @param source * @param maxAge * @param unit * @param scheduler * @param bufferSize - * @return + * @return the new NbpConnectableObservable instance */ public static NbpConnectableObservable create(NbpObservable source, - long maxAge, TimeUnit unit, final Scheduler scheduler, final int bufferSize) { - return create(source, () -> new SizeAndTimeBoundReplayBuffer<>(bufferSize, maxAge, unit, scheduler)); + final long maxAge, final TimeUnit unit, final Scheduler scheduler, final int bufferSize) { + return create(source, new Supplier>() { + @Override + public ReplayBuffer get() { + return new SizeAndTimeBoundReplayBuffer(bufferSize, maxAge, unit, scheduler); + } + }); } /** @@ -143,7 +178,7 @@ public static NbpConnectableObservable create(NbpObservable static NbpConnectableObservable create(NbpObservable source, final Supplier> bufferFactory) { // the current connection to source needs to be shared between the operator and its onSubscribe call - final AtomicReference> curr = new AtomicReference<>(); + final AtomicReference> curr = new AtomicReference>(); NbpOnSubscribe onSubscribe = new NbpOnSubscribe() { @Override public void accept(NbpSubscriber child) { @@ -155,7 +190,7 @@ public void accept(NbpSubscriber child) { // if there isn't one if (r == null) { // create a new subscriber to source - ReplaySubscriber u = new ReplaySubscriber<>(curr, bufferFactory.get()); + ReplaySubscriber u = new ReplaySubscriber(curr, bufferFactory.get()); // let's try setting it as the current subscriber-to-source if (!curr.compareAndSet(r, u)) { // didn't work, maybe someone else did it or the current subscriber @@ -167,7 +202,7 @@ public void accept(NbpSubscriber child) { } // create the backpressure-managing producer for this child - InnerSubscription inner = new InnerSubscription<>(r, child); + InnerSubscription inner = new InnerSubscription(r, child); // we try to add it to the array of producers // if it fails, no worries because we will still have its buffer // so it is going to replay it for us @@ -185,7 +220,7 @@ public void accept(NbpSubscriber child) { } } }; - return new NbpOperatorReplay<>(onSubscribe, source, curr, bufferFactory); + return new NbpOperatorReplay(onSubscribe, source, curr, bufferFactory); } private NbpOperatorReplay(NbpOnSubscribe onSubscribe, NbpObservable source, final AtomicReference> current, @@ -207,7 +242,7 @@ public void connect(Consumer connection) { // if there is none yet or the current has unsubscribed if (ps == null || ps.isDisposed()) { // create a new subscriber-to-source - ReplaySubscriber u = new ReplaySubscriber<>(current, bufferFactory.get()); + ReplaySubscriber u = new ReplaySubscriber(current, bufferFactory.get()); // try setting it as the current subscriber-to-source if (!current.compareAndSet(ps, u)) { // did not work, perhaps a new subscriber arrived @@ -276,7 +311,7 @@ public ReplaySubscriber(AtomicReference> current, ReplayBuffer buffer) { this.buffer = buffer; - this.producers = new AtomicReference<>(EMPTY); + this.producers = new AtomicReference(EMPTY); this.shouldConnect = new AtomicBoolean(); } @@ -437,8 +472,6 @@ void replay() { /** * A Producer and Subscription that manages the request and unsubscription state of a * child subscriber in thread-safe manner. - * We use AtomicLong as a base class to save on extra allocation of an AtomicLong and also - * save the overhead of the AtomicIntegerFieldUpdater. * @param the value type */ static final class InnerSubscription implements Disposable { @@ -603,8 +636,6 @@ public void replay(InnerSubscription output) { /** * Represents a node in a bounded replay buffer's linked list. - * - * @param the contained value type */ static final class Node extends AtomicReference { /** */ @@ -800,7 +831,7 @@ void truncateFinal() { if (NotificationLite.isComplete(v) || NotificationLite.isError(v)) { break; } - output.add(NotificationLite.getValue(v)); + output.add(NotificationLite.getValue(v)); n = next; } else { break; @@ -861,7 +892,7 @@ public SizeAndTimeBoundReplayBuffer(int limit, long maxAge, TimeUnit unit, Sched @Override Object enterTransform(Object value) { - return new Timed<>(value, scheduler.now(unit), unit); + return new Timed(value, scheduler.now(unit), unit); } @Override diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorSampleTimed.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorSampleTimed.java index 9f0d96d0a0..57c2d0f026 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorSampleTimed.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorSampleTimed.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -16,8 +16,8 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.*; -import io.reactivex.NbpObservable.*; import io.reactivex.Scheduler; +import io.reactivex.NbpObservable.*; import io.reactivex.disposables.Disposable; import io.reactivex.internal.subscriptions.SubscriptionHelper; import io.reactivex.subscribers.nbp.NbpSerializedSubscriber; @@ -36,8 +36,8 @@ public NbpOperatorSampleTimed(long period, TimeUnit unit, Scheduler scheduler) { @Override public NbpSubscriber apply(NbpSubscriber t) { - NbpSerializedSubscriber serial = new NbpSerializedSubscriber<>(t); - return new SampleTimedSubscriber<>(serial, period, unit, scheduler); + NbpSerializedSubscriber serial = new NbpSerializedSubscriber(t); + return new SampleTimedSubscriber(serial, period, unit, scheduler); } static final class SampleTimedSubscriber extends AtomicReference implements NbpSubscriber, Disposable, Runnable { @@ -49,12 +49,12 @@ static final class SampleTimedSubscriber extends AtomicReference implement final TimeUnit unit; final Scheduler scheduler; - volatile Disposable timer; - @SuppressWarnings("rawtypes") - static final AtomicReferenceFieldUpdater TIMER = - AtomicReferenceFieldUpdater.newUpdater(SampleTimedSubscriber.class, Disposable.class, "timer"); + final AtomicReference timer = new AtomicReference(); - static final Disposable DISPOSED = () -> { }; + static final Disposable DISPOSED = new Disposable() { + @Override + public void dispose() { } + }; Disposable s; @@ -73,9 +73,9 @@ public void onSubscribe(Disposable s) { this.s = s; actual.onSubscribe(this); - if (timer == null) { + if (timer.get() == null) { Disposable d = scheduler.schedulePeriodicallyDirect(this, period, period, unit); - if (!TIMER.compareAndSet(this, null, d)) { + if (!timer.compareAndSet(null, d)) { d.dispose(); return; } @@ -100,9 +100,9 @@ public void onComplete() { } void cancelTimer() { - Disposable d = timer; + Disposable d = timer.get(); if (d != DISPOSED) { - d = TIMER.getAndSet(this, DISPOSED); + d = timer.getAndSet(DISPOSED); if (d != DISPOSED && d != null) { d.dispose(); } diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorSampleWithObservable.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorSampleWithObservable.java index e14faa9507..5f7f6d2b7a 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorSampleWithObservable.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorSampleWithObservable.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -30,8 +30,8 @@ public NbpOperatorSampleWithObservable(NbpObservable other) { @Override public NbpSubscriber apply(NbpSubscriber t) { - NbpSerializedSubscriber serial = new NbpSerializedSubscriber<>(t); - return new SamplePublisherSubscriber<>(serial, other); + NbpSerializedSubscriber serial = new NbpSerializedSubscriber(t); + return new SamplePublisherSubscriber(serial, other); } static final class SamplePublisherSubscriber extends AtomicReference @@ -42,12 +42,12 @@ static final class SamplePublisherSubscriber extends AtomicReference final NbpSubscriber actual; final NbpObservable sampler; - volatile Disposable other; - @SuppressWarnings("rawtypes") - static final AtomicReferenceFieldUpdater OTHER = - AtomicReferenceFieldUpdater.newUpdater(SamplePublisherSubscriber.class, Disposable.class, "other"); + final AtomicReference other = new AtomicReference(); - static final Disposable CANCELLED = () -> { }; + static final Disposable CANCELLED = new Disposable() { + @Override + public void dispose() { } + }; Disposable s; @@ -64,8 +64,8 @@ public void onSubscribe(Disposable s) { this.s = s; actual.onSubscribe(this); - if (other == null) { - sampler.subscribe(new SamplerSubscriber<>(this)); + if (other.get() == null) { + sampler.subscribe(new SamplerSubscriber(this)); } } @@ -88,9 +88,9 @@ public void onComplete() { } void cancelOther() { - Disposable o = other; + Disposable o = other.get(); if (o != CANCELLED) { - o = OTHER.getAndSet(this, CANCELLED); + o = other.getAndSet(CANCELLED); if (o != CANCELLED && o != null) { o.dispose(); } @@ -98,8 +98,8 @@ void cancelOther() { } boolean setOther(Disposable o) { - if (other == null) { - if (OTHER.compareAndSet(this, null, o)) { + if (other.get() == null) { + if (other.compareAndSet(null, o)) { return true; } o.dispose(); diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorScan.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorScan.java index 839b140ee0..5924b01b8c 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorScan.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorScan.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,10 +13,9 @@ package io.reactivex.internal.operators.nbp; -import java.util.function.BiFunction; - import io.reactivex.NbpObservable.*; import io.reactivex.disposables.Disposable; +import io.reactivex.functions.BiFunction; import io.reactivex.internal.subscriptions.SubscriptionHelper; public final class NbpOperatorScan implements NbpOperator { @@ -27,7 +26,7 @@ public NbpOperatorScan(BiFunction accumulator) { @Override public NbpSubscriber apply(NbpSubscriber t) { - return new ScanSubscriber<>(t, accumulator); + return new ScanSubscriber(t, accumulator); } static final class ScanSubscriber implements NbpSubscriber { diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorScanSeed.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorScanSeed.java index 9dd2283414..2fadf90762 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorScanSeed.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorScanSeed.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -12,10 +12,9 @@ */ package io.reactivex.internal.operators.nbp; -import java.util.function.*; - import io.reactivex.NbpObservable.*; import io.reactivex.disposables.Disposable; +import io.reactivex.functions.*; import io.reactivex.internal.disposables.EmptyDisposable; import io.reactivex.internal.subscribers.nbp.NbpEmptySubscriber; import io.reactivex.internal.subscriptions.SubscriptionHelper; @@ -46,7 +45,7 @@ public NbpSubscriber apply(NbpSubscriber t) { return NbpEmptySubscriber.INSTANCE; } - return new ScanSeedSubscriber<>(t, accumulator, r); + return new ScanSeedSubscriber(t, accumulator, r); } static final class ScanSeedSubscriber implements NbpSubscriber { diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorSingle.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorSingle.java index e586d94dec..eae65a92db 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorSingle.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorSingle.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -21,7 +21,7 @@ public final class NbpOperatorSingle implements NbpOperator { - static final NbpOperatorSingle NO_DEFAULT = new NbpOperatorSingle<>(null); + static final NbpOperatorSingle NO_DEFAULT = new NbpOperatorSingle(null); @SuppressWarnings("unchecked") public static NbpOperatorSingle instanceNoDefault() { @@ -34,7 +34,7 @@ public NbpOperatorSingle(T defaultValue) { } @Override public NbpSubscriber apply(NbpSubscriber t) { - return new SingleElementSubscriber<>(t, defaultValue); + return new SingleElementSubscriber(t, defaultValue); } static final class SingleElementSubscriber implements NbpSubscriber { diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorSkip.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorSkip.java index c504376300..d6efda8e92 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorSkip.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorSkip.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -16,9 +16,6 @@ import io.reactivex.NbpObservable.*; import io.reactivex.disposables.Disposable; -/** - * - */ public final class NbpOperatorSkip implements NbpOperator { final long n; public NbpOperatorSkip(long n) { @@ -27,7 +24,7 @@ public NbpOperatorSkip(long n) { @Override public NbpSubscriber apply(NbpSubscriber s) { - return new SkipSubscriber<>(s, n); + return new SkipSubscriber(s, n); } static final class SkipSubscriber implements NbpSubscriber { diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorSkipLast.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorSkipLast.java index f070566823..6676d83bec 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorSkipLast.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorSkipLast.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -27,7 +27,7 @@ public NbpOperatorSkipLast(int skip) { @Override public NbpSubscriber apply(NbpSubscriber s) { - return new SkipLastSubscriber<>(s, skip); + return new SkipLastSubscriber(s, skip); } static final class SkipLastSubscriber extends ArrayDeque implements NbpSubscriber { diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorSkipLastTimed.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorSkipLastTimed.java index aa28541348..77c9975f91 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorSkipLastTimed.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorSkipLastTimed.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -16,8 +16,8 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; -import io.reactivex.NbpObservable.*; import io.reactivex.Scheduler; +import io.reactivex.NbpObservable.*; import io.reactivex.disposables.Disposable; import io.reactivex.internal.queue.SpscLinkedArrayQueue; import io.reactivex.internal.subscriptions.SubscriptionHelper; @@ -39,7 +39,7 @@ public NbpOperatorSkipLastTimed(long time, TimeUnit unit, Scheduler scheduler, i @Override public NbpSubscriber apply(NbpSubscriber t) { - return new SkipLastTimedSubscriber<>(t, time, unit, scheduler, bufferSize, delayError); + return new SkipLastTimedSubscriber(t, time, unit, scheduler, bufferSize, delayError); } static final class SkipLastTimedSubscriber extends AtomicInteger implements NbpSubscriber, Disposable { @@ -64,7 +64,7 @@ public SkipLastTimedSubscriber(NbpSubscriber actual, long time, TimeU this.time = time; this.unit = unit; this.scheduler = scheduler; - this.queue = new SpscLinkedArrayQueue<>(bufferSize); + this.queue = new SpscLinkedArrayQueue(bufferSize); this.delayError = delayError; } diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorSkipUntil.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorSkipUntil.java index 3c1fe22c6d..95315678e6 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorSkipUntil.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorSkipUntil.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -17,7 +17,7 @@ import io.reactivex.NbpObservable; import io.reactivex.NbpObservable.*; -import io.reactivex.disposables.Disposable; +import io.reactivex.disposables.*; import io.reactivex.internal.disposables.*; import io.reactivex.internal.subscriptions.SubscriptionHelper; import io.reactivex.subscribers.nbp.NbpSerializedSubscriber; @@ -31,11 +31,11 @@ public NbpOperatorSkipUntil(NbpObservable other) { @Override public NbpSubscriber apply(NbpSubscriber child) { - NbpSerializedSubscriber serial = new NbpSerializedSubscriber<>(child); + final NbpSerializedSubscriber serial = new NbpSerializedSubscriber(child); - ArrayCompositeResource frc = new ArrayCompositeResource<>(2, Disposable::dispose); + final ArrayCompositeResource frc = new ArrayCompositeResource(2, Disposables.consumeAndDispose()); - SkipUntilSubscriber sus = new SkipUntilSubscriber<>(serial, frc); + final SkipUntilSubscriber sus = new SkipUntilSubscriber(serial, frc); other.subscribe(new NbpSubscriber() { Disposable s; diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorSkipWhile.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorSkipWhile.java index 56c4bb3125..8798fc58eb 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorSkipWhile.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorSkipWhile.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,10 +13,9 @@ package io.reactivex.internal.operators.nbp; -import java.util.function.Predicate; - import io.reactivex.NbpObservable.*; import io.reactivex.disposables.Disposable; +import io.reactivex.functions.Predicate; import io.reactivex.internal.subscriptions.SubscriptionHelper; public final class NbpOperatorSkipWhile implements NbpOperator { @@ -27,7 +26,7 @@ public NbpOperatorSkipWhile(Predicate predicate) { @Override public NbpSubscriber apply(NbpSubscriber s) { - return new SkipWhileSubscriber<>(s, predicate); + return new SkipWhileSubscriber(s, predicate); } static final class SkipWhileSubscriber implements NbpSubscriber { diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorSwitchIfEmpty.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorSwitchIfEmpty.java index 5cda41ad91..82dddbdd4e 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorSwitchIfEmpty.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorSwitchIfEmpty.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -25,7 +25,7 @@ public NbpOperatorSwitchIfEmpty(NbpObservable other) { @Override public NbpSubscriber apply(NbpSubscriber t) { - SwitchIfEmptySubscriber parent = new SwitchIfEmptySubscriber<>(t, other); + SwitchIfEmptySubscriber parent = new SwitchIfEmptySubscriber(t, other); t.onSubscribe(parent.arbiter); return parent; } diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorSwitchMap.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorSwitchMap.java index cd09e3e424..a339640271 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorSwitchMap.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorSwitchMap.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -15,16 +15,16 @@ import java.util.Queue; import java.util.concurrent.atomic.*; -import java.util.function.Function; -import org.reactivestreams.*; +import org.reactivestreams.Subscriber; import io.reactivex.NbpObservable; import io.reactivex.NbpObservable.*; import io.reactivex.disposables.Disposable; +import io.reactivex.functions.Function; import io.reactivex.internal.queue.*; import io.reactivex.internal.subscriptions.SubscriptionHelper; -import io.reactivex.internal.util.*; +import io.reactivex.internal.util.Pow2; import io.reactivex.plugins.RxJavaPlugins; public final class NbpOperatorSwitchMap implements NbpOperator { @@ -38,7 +38,7 @@ public NbpOperatorSwitchMap(Function apply(NbpSubscriber t) { - return new SwitchMapSubscriber<>(t, mapper, bufferSize); + return new SwitchMapSubscriber(t, mapper, bufferSize); } static final class SwitchMapSubscriber extends AtomicInteger implements NbpSubscriber, Disposable { @@ -56,14 +56,11 @@ static final class SwitchMapSubscriber extends AtomicInteger implements Nb Disposable s; - volatile SwitchMapInnerSubscriber active; - @SuppressWarnings("rawtypes") - static final AtomicReferenceFieldUpdater ACTIVE = - AtomicReferenceFieldUpdater.newUpdater(SwitchMapSubscriber.class, SwitchMapInnerSubscriber.class, "active"); + final AtomicReference> active = new AtomicReference>(); static final SwitchMapInnerSubscriber CANCELLED; static { - CANCELLED = new SwitchMapInnerSubscriber<>(null, -1L, 1); + CANCELLED = new SwitchMapInnerSubscriber(null, -1L, 1); CANCELLED.cancel(); } @@ -89,7 +86,7 @@ public void onNext(T t) { long c = unique + 1; unique = c; - SwitchMapInnerSubscriber inner = active; + SwitchMapInnerSubscriber inner = active.get(); if (inner != null) { inner.cancel(); } @@ -109,14 +106,14 @@ public void onNext(T t) { return; } - SwitchMapInnerSubscriber nextInner = new SwitchMapInnerSubscriber<>(this, c, bufferSize); + SwitchMapInnerSubscriber nextInner = new SwitchMapInnerSubscriber(this, c, bufferSize); for (;;) { - inner = active; + inner = active.get(); if (inner == CANCELLED) { break; } - if (ACTIVE.compareAndSet(this, inner, nextInner)) { + if (active.compareAndSet(inner, nextInner)) { p.subscribe(nextInner); break; } @@ -154,9 +151,9 @@ public void dispose() { @SuppressWarnings("unchecked") void disposeInner() { - SwitchMapInnerSubscriber a = active; + SwitchMapInnerSubscriber a = active.get(); if (a != CANCELLED) { - a = ACTIVE.getAndSet(this, CANCELLED); + a = active.getAndSet((SwitchMapInnerSubscriber)CANCELLED); if (a != CANCELLED && a != null) { s.dispose(); } @@ -186,13 +183,13 @@ void drain() { a.onError(err); return; } else - if (active == null) { + if (active.get() == null) { a.onComplete(); return; } } - SwitchMapInnerSubscriber inner = active; + SwitchMapInnerSubscriber inner = active.get(); if (inner != null) { Queue q = inner.queue; @@ -206,7 +203,7 @@ void drain() { return; } else if (q.isEmpty()) { - ACTIVE.compareAndSet(this, inner, null); + active.compareAndSet(inner, null); continue; } } @@ -221,7 +218,7 @@ void drain() { if (cancelled) { return; } - if (inner != active) { + if (inner != active.get()) { retry = true; break; } @@ -234,7 +231,7 @@ void drain() { return; } else if (empty) { - ACTIVE.compareAndSet(this, inner, null); + active.compareAndSet(inner, null); retry = true; break; } @@ -293,7 +290,10 @@ static final class SwitchMapInnerSubscriber extends AtomicReference { }; + static final Disposable CANCELLED = new Disposable() { + @Override + public void dispose() { } + }; public SwitchMapInnerSubscriber(SwitchMapSubscriber parent, long index, int bufferSize) { this.parent = parent; @@ -301,9 +301,9 @@ public SwitchMapInnerSubscriber(SwitchMapSubscriber parent, long index, in this.bufferSize = bufferSize; Queue q; if (Pow2.isPowerOfTwo(bufferSize)) { - q = new SpscArrayQueue<>(bufferSize); + q = new SpscArrayQueue(bufferSize); } else { - q = new SpscExactArrayQueue<>(bufferSize); + q = new SpscExactArrayQueue(bufferSize); } this.queue = q; } diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorTake.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorTake.java index 023ad4d222..f12cce772c 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorTake.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorTake.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -17,9 +17,6 @@ import io.reactivex.disposables.Disposable; import io.reactivex.internal.subscriptions.SubscriptionHelper; -/** - * - */ public final class NbpOperatorTake implements NbpOperator { final long limit; public NbpOperatorTake(long limit) { @@ -28,7 +25,7 @@ public NbpOperatorTake(long limit) { @Override public NbpSubscriber apply(NbpSubscriber t) { - return new TakeSubscriber<>(t, limit); + return new TakeSubscriber(t, limit); } static final class TakeSubscriber implements NbpSubscriber { diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorTakeLast.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorTakeLast.java index 06827367a7..91802515c6 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorTakeLast.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorTakeLast.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -28,7 +28,7 @@ public NbpOperatorTakeLast(int count) { @Override public NbpSubscriber apply(NbpSubscriber t) { - return new TakeLastSubscriber<>(t, count); + return new TakeLastSubscriber(t, count); } static final class TakeLastSubscriber extends ArrayDeque implements NbpSubscriber, Disposable { diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorTakeLastOne.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorTakeLastOne.java index 70a566e790..587ec0f84e 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorTakeLastOne.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorTakeLastOne.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -27,7 +27,7 @@ public static NbpOperator instance() { @Override public NbpSubscriber apply(NbpSubscriber s) { - return new TakeLastOneSubscriber<>(s); + return new TakeLastOneSubscriber(s); } static final class TakeLastOneSubscriber implements NbpSubscriber, Disposable { diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorTakeLastTimed.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorTakeLastTimed.java index 15131d14c8..404de39b66 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorTakeLastTimed.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorTakeLastTimed.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -17,8 +17,8 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; -import io.reactivex.NbpObservable.*; import io.reactivex.Scheduler; +import io.reactivex.NbpObservable.*; import io.reactivex.disposables.Disposable; import io.reactivex.internal.queue.SpscLinkedArrayQueue; import io.reactivex.internal.subscriptions.SubscriptionHelper; @@ -42,7 +42,7 @@ public NbpOperatorTakeLastTimed(long count, long time, TimeUnit unit, Scheduler @Override public NbpSubscriber apply(NbpSubscriber t) { - return new TakeLastTimedSubscriber<>(t, count, time, unit, scheduler, bufferSize, delayError); + return new TakeLastTimedSubscriber(t, count, time, unit, scheduler, bufferSize, delayError); } static final class TakeLastTimedSubscriber extends AtomicInteger implements NbpSubscriber, Disposable { @@ -69,7 +69,7 @@ public TakeLastTimedSubscriber(NbpSubscriber actual, long count, long this.time = time; this.unit = unit; this.scheduler = scheduler; - this.queue = new SpscLinkedArrayQueue<>(bufferSize); + this.queue = new SpscLinkedArrayQueue(bufferSize); this.delayError = delayError; } diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorTakeUntil.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorTakeUntil.java index 21c213441d..fc9e998a22 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorTakeUntil.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorTakeUntil.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -17,14 +17,11 @@ import io.reactivex.NbpObservable; import io.reactivex.NbpObservable.*; -import io.reactivex.disposables.Disposable; +import io.reactivex.disposables.*; import io.reactivex.internal.disposables.*; import io.reactivex.internal.subscriptions.SubscriptionHelper; import io.reactivex.subscribers.nbp.NbpSerializedSubscriber; -/** - * - */ public final class NbpOperatorTakeUntil implements NbpOperator { final NbpObservable other; public NbpOperatorTakeUntil(NbpObservable other) { @@ -32,11 +29,11 @@ public NbpOperatorTakeUntil(NbpObservable other) { } @Override public NbpSubscriber apply(NbpSubscriber child) { - NbpSerializedSubscriber serial = new NbpSerializedSubscriber<>(child); + final NbpSerializedSubscriber serial = new NbpSerializedSubscriber(child); - ArrayCompositeResource frc = new ArrayCompositeResource<>(2, Disposable::dispose); + final ArrayCompositeResource frc = new ArrayCompositeResource(2, Disposables.consumeAndDispose()); - TakeUntilSubscriber tus = new TakeUntilSubscriber<>(serial, frc); + final TakeUntilSubscriber tus = new TakeUntilSubscriber(serial, frc); other.subscribe(new NbpSubscriber() { @Override diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorTakeUntilPredicate.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorTakeUntilPredicate.java index 4609b662b3..090554a076 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorTakeUntilPredicate.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorTakeUntilPredicate.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,15 +13,11 @@ package io.reactivex.internal.operators.nbp; -import java.util.function.Predicate; - import io.reactivex.NbpObservable.*; import io.reactivex.disposables.Disposable; +import io.reactivex.functions.Predicate; import io.reactivex.internal.subscriptions.SubscriptionHelper; -/** - * - */ public final class NbpOperatorTakeUntilPredicate implements NbpOperator { final Predicate predicate; public NbpOperatorTakeUntilPredicate(Predicate predicate) { @@ -30,7 +26,7 @@ public NbpOperatorTakeUntilPredicate(Predicate predicate) { @Override public NbpSubscriber apply(NbpSubscriber s) { - return new InnerSubscriber<>(s, predicate); + return new InnerSubscriber(s, predicate); } static final class InnerSubscriber implements NbpSubscriber { diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorTakeWhile.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorTakeWhile.java index 97bff42a7d..474edae06f 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorTakeWhile.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorTakeWhile.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,10 +13,9 @@ package io.reactivex.internal.operators.nbp; -import java.util.function.Predicate; - import io.reactivex.NbpObservable.*; import io.reactivex.disposables.Disposable; +import io.reactivex.functions.Predicate; import io.reactivex.internal.subscriptions.SubscriptionHelper; public final class NbpOperatorTakeWhile implements NbpOperator { @@ -27,7 +26,7 @@ public NbpOperatorTakeWhile(Predicate predicate) { @Override public NbpSubscriber apply(NbpSubscriber t) { - return new TakeWhileSubscriber<>(t, predicate); + return new TakeWhileSubscriber(t, predicate); } static final class TakeWhileSubscriber implements NbpSubscriber { diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorThrottleFirstTimed.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorThrottleFirstTimed.java index 5f689a305b..609b5b5786 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorThrottleFirstTimed.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorThrottleFirstTimed.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -14,7 +14,7 @@ package io.reactivex.internal.operators.nbp; import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; +import java.util.concurrent.atomic.AtomicReference; import io.reactivex.NbpObservable.*; import io.reactivex.Scheduler; @@ -37,8 +37,8 @@ public NbpOperatorThrottleFirstTimed(long timeout, TimeUnit unit, Scheduler sche @Override public NbpSubscriber apply(NbpSubscriber t) { - return new DebounceTimedSubscriber<>( - new NbpSerializedSubscriber<>(t), + return new DebounceTimedSubscriber( + new NbpSerializedSubscriber(t), timeout, unit, scheduler.createWorker()); } @@ -51,14 +51,17 @@ static final class DebounceTimedSubscriber Disposable s; - volatile Disposable timer; - @SuppressWarnings("rawtypes") - static final AtomicReferenceFieldUpdater TIMER = - AtomicReferenceFieldUpdater.newUpdater(DebounceTimedSubscriber.class, Disposable.class, "timer"); + final AtomicReference timer = new AtomicReference(); - static final Disposable CANCELLED = () -> { }; + static final Disposable CANCELLED = new Disposable() { + @Override + public void dispose() { } + }; - static final Disposable NEW_TIMER = () -> { }; + static final Disposable NEW_TIMER = new Disposable() { + @Override + public void dispose() { } + }; volatile boolean gate; @@ -72,9 +75,9 @@ public DebounceTimedSubscriber(NbpSubscriber actual, long timeout, Ti } public void disposeTimer() { - Disposable d = timer; + Disposable d = timer.get(); if (d != CANCELLED) { - d = TIMER.getAndSet(this, CANCELLED); + d = timer.getAndSet(CANCELLED); if (d != CANCELLED && d != null) { d.dispose(); } @@ -102,14 +105,14 @@ public void onNext(T t) { actual.onNext(t); // FIXME should this be a periodic blocking or a value-relative blocking? - Disposable d = timer; + Disposable d = timer.get(); if (d != null) { d.dispose(); } - if (TIMER.compareAndSet(this, d, NEW_TIMER)) { + if (timer.compareAndSet(d, NEW_TIMER)) { d = worker.schedule(this, timeout, unit); - if (!TIMER.compareAndSet(this, NEW_TIMER, d)) { + if (!timer.compareAndSet(NEW_TIMER, d)) { d.dispose(); } } diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorTimeInterval.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorTimeInterval.java index 6a07423cc4..82b30836b2 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorTimeInterval.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorTimeInterval.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -15,8 +15,8 @@ import java.util.concurrent.TimeUnit; -import io.reactivex.NbpObservable.*; import io.reactivex.Scheduler; +import io.reactivex.NbpObservable.*; import io.reactivex.disposables.Disposable; import io.reactivex.schedulers.Timed; @@ -31,7 +31,7 @@ public NbpOperatorTimeInterval(TimeUnit unit, Scheduler scheduler) { @Override public NbpSubscriber apply(NbpSubscriber> t) { - return new TimeIntervalSubscriber<>(t, unit, scheduler); + return new TimeIntervalSubscriber(t, unit, scheduler); } static final class TimeIntervalSubscriber implements NbpSubscriber { @@ -59,7 +59,7 @@ public void onNext(T t) { long last = lastTime; lastTime = now; long delta = now - last; - actual.onNext(new Timed<>(t, delta, unit)); + actual.onNext(new Timed(t, delta, unit)); } @Override diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorTimeout.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorTimeout.java index 47579af198..a6b0d136f2 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorTimeout.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorTimeout.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -14,12 +14,12 @@ package io.reactivex.internal.operators.nbp; import java.util.concurrent.TimeoutException; -import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; -import java.util.function.*; +import java.util.concurrent.atomic.AtomicReference; import io.reactivex.NbpObservable; import io.reactivex.NbpObservable.*; import io.reactivex.disposables.Disposable; +import io.reactivex.functions.*; import io.reactivex.internal.disposables.*; import io.reactivex.internal.subscribers.NbpFullArbiterSubscriber; import io.reactivex.internal.subscribers.nbp.NbpDisposableSubscriber; @@ -42,11 +42,11 @@ public NbpOperatorTimeout(Supplier> firstTimeoutSelec @Override public NbpSubscriber apply(NbpSubscriber t) { if (other == null) { - return new TimeoutSubscriber<>( - new NbpSerializedSubscriber<>(t), + return new TimeoutSubscriber( + new NbpSerializedSubscriber(t), firstTimeoutSelector, timeoutSelector); } - return new TimeoutOtherSubscriber<>(t, firstTimeoutSelector, timeoutSelector, other); + return new TimeoutOtherSubscriber(t, firstTimeoutSelector, timeoutSelector, other); } static final class TimeoutSubscriber implements NbpSubscriber, Disposable, OnTimeout { @@ -60,12 +60,12 @@ static final class TimeoutSubscriber implements NbpSubscriber, Dispo volatile long index; - volatile Disposable timeout; - @SuppressWarnings("rawtypes") - static final AtomicReferenceFieldUpdater TIMEOUT = - AtomicReferenceFieldUpdater.newUpdater(TimeoutSubscriber.class, Disposable.class, "timeout"); + final AtomicReference timeout = new AtomicReference(); - static final Disposable CANCELLED = () -> { }; + static final Disposable CANCELLED = new Disposable() { + @Override + public void dispose() { } + }; public TimeoutSubscriber(NbpSubscriber actual, Supplier> firstTimeoutSelector, @@ -101,9 +101,9 @@ public void onSubscribe(Disposable s) { return; } - TimeoutInnerSubscriber tis = new TimeoutInnerSubscriber<>(this, 0); + TimeoutInnerSubscriber tis = new TimeoutInnerSubscriber(this, 0); - if (TIMEOUT.compareAndSet(this, null, tis)) { + if (timeout.compareAndSet(null, tis)) { a.onSubscribe(s); p.subscribe(tis); } @@ -119,7 +119,7 @@ public void onNext(T t) { actual.onNext(t); - Disposable d = timeout; + Disposable d = timeout.get(); if (d != null) { d.dispose(); } @@ -140,9 +140,9 @@ public void onNext(T t) { return; } - TimeoutInnerSubscriber tis = new TimeoutInnerSubscriber<>(this, idx); + TimeoutInnerSubscriber tis = new TimeoutInnerSubscriber(this, idx); - if (TIMEOUT.compareAndSet(this, d, tis)) { + if (timeout.compareAndSet(d, tis)) { p.subscribe(tis); } } @@ -165,9 +165,9 @@ public void dispose() { cancelled = true; s.dispose(); - Disposable d = timeout; + Disposable d = timeout.get(); if (d != CANCELLED) { - d = TIMEOUT.getAndSet(this, CANCELLED); + d = timeout.getAndSet(CANCELLED); if (d != CANCELLED && d != null) { d.dispose(); } @@ -241,12 +241,12 @@ static final class TimeoutOtherSubscriber implements NbpSubscriber, volatile long index; - volatile Disposable timeout; - @SuppressWarnings("rawtypes") - static final AtomicReferenceFieldUpdater TIMEOUT = - AtomicReferenceFieldUpdater.newUpdater(TimeoutOtherSubscriber.class, Disposable.class, "timeout"); + final AtomicReference timeout = new AtomicReference(); - static final Disposable CANCELLED = () -> { }; + static final Disposable CANCELLED = new Disposable() { + @Override + public void dispose() { } + }; public TimeoutOtherSubscriber(NbpSubscriber actual, Supplier> firstTimeoutSelector, @@ -255,7 +255,7 @@ public TimeoutOtherSubscriber(NbpSubscriber actual, this.firstTimeoutSelector = firstTimeoutSelector; this.timeoutSelector = timeoutSelector; this.other = other; - this.arbiter = new NbpFullArbiter<>(actual, this, 8); + this.arbiter = new NbpFullArbiter(actual, this, 8); } @Override @@ -287,9 +287,9 @@ public void onSubscribe(Disposable s) { return; } - TimeoutInnerSubscriber tis = new TimeoutInnerSubscriber<>(this, 0); + TimeoutInnerSubscriber tis = new TimeoutInnerSubscriber(this, 0); - if (TIMEOUT.compareAndSet(this, null, tis)) { + if (timeout.compareAndSet(null, tis)) { a.onSubscribe(arbiter); p.subscribe(tis); } @@ -310,7 +310,7 @@ public void onNext(T t) { return; } - Disposable d = timeout; + Disposable d = timeout.get(); if (d != null) { d.dispose(); } @@ -329,9 +329,9 @@ public void onNext(T t) { return; } - TimeoutInnerSubscriber tis = new TimeoutInnerSubscriber<>(this, idx); + TimeoutInnerSubscriber tis = new TimeoutInnerSubscriber(this, idx); - if (TIMEOUT.compareAndSet(this, d, tis)) { + if (timeout.compareAndSet(d, tis)) { p.subscribe(tis); } } @@ -363,9 +363,9 @@ public void dispose() { cancelled = true; s.dispose(); - Disposable d = timeout; + Disposable d = timeout.get(); if (d != CANCELLED) { - d = TIMEOUT.getAndSet(this, CANCELLED); + d = timeout.getAndSet(CANCELLED); if (d != CANCELLED && d != null) { d.dispose(); } @@ -377,7 +377,7 @@ public void dispose() { public void timeout(long idx) { if (idx == index) { dispose(); - other.subscribe(new NbpFullArbiterSubscriber<>(arbiter)); + other.subscribe(new NbpFullArbiterSubscriber(arbiter)); } } } diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorTimeoutTimed.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorTimeoutTimed.java index e70b431d4b..c068678318 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorTimeoutTimed.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorTimeoutTimed.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -14,7 +14,7 @@ package io.reactivex.internal.operators.nbp; import java.util.concurrent.*; -import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; +import java.util.concurrent.atomic.*; import io.reactivex.*; import io.reactivex.NbpObservable.*; @@ -42,11 +42,11 @@ public NbpOperatorTimeoutTimed(long timeout, TimeUnit unit, Scheduler scheduler, @Override public NbpSubscriber apply(NbpSubscriber t) { if (other == null) { - return new TimeoutTimedSubscriber<>( - new NbpSerializedSubscriber<>(t), // because errors can race + return new TimeoutTimedSubscriber( + new NbpSerializedSubscriber(t), // because errors can race timeout, unit, scheduler.createWorker()); } - return new TimeoutTimedOtherSubscriber<>( + return new TimeoutTimedOtherSubscriber( t, // the FullArbiter serializes timeout, unit, scheduler.createWorker(), other); } @@ -62,14 +62,17 @@ static final class TimeoutTimedOtherSubscriber implements NbpSubscriber, D final NbpFullArbiter arbiter; - volatile Disposable timer; - @SuppressWarnings("rawtypes") - static final AtomicReferenceFieldUpdater TIMER = - AtomicReferenceFieldUpdater.newUpdater(TimeoutTimedOtherSubscriber.class, Disposable.class, "timer"); + final AtomicReference timer = new AtomicReference(); - static final Disposable CANCELLED = () -> { }; + static final Disposable CANCELLED = new Disposable() { + @Override + public void dispose() { } + }; - static final Disposable NEW_TIMER = () -> { }; + static final Disposable NEW_TIMER = new Disposable() { + @Override + public void dispose() { } + }; volatile long index; @@ -82,7 +85,7 @@ public TimeoutTimedOtherSubscriber(NbpSubscriber actual, long timeout this.unit = unit; this.worker = worker; this.other = other; - this.arbiter = new NbpFullArbiter<>(actual, this, 8); + this.arbiter = new NbpFullArbiter(actual, this, 8); } @Override @@ -112,36 +115,39 @@ public void onNext(T t) { } } - void scheduleTimeout(long idx) { - Disposable d = timer; + void scheduleTimeout(final long idx) { + Disposable d = timer.get(); if (d != null) { d.dispose(); } - if (TIMER.compareAndSet(this, d, NEW_TIMER)) { - d = worker.schedule(() -> { - if (idx == index) { - done = true; - s.dispose(); - disposeTimer(); - worker.dispose(); - - if (other == null) { - actual.onError(new TimeoutException()); - } else { - subscribeNext(); + if (timer.compareAndSet(d, NEW_TIMER)) { + d = worker.schedule(new Runnable() { + @Override + public void run() { + if (idx == index) { + done = true; + s.dispose(); + disposeTimer(); + worker.dispose(); + + if (other == null) { + actual.onError(new TimeoutException()); + } else { + subscribeNext(); + } } } }, timeout, unit); - if (!TIMER.compareAndSet(this, NEW_TIMER, d)) { + if (!timer.compareAndSet(NEW_TIMER, d)) { d.dispose(); } } } void subscribeNext() { - other.subscribe(new NbpFullArbiterSubscriber<>(arbiter)); + other.subscribe(new NbpFullArbiterSubscriber(arbiter)); } @Override @@ -174,9 +180,9 @@ public void dispose() { } public void disposeTimer() { - Disposable d = timer; + Disposable d = timer.get(); if (d != CANCELLED) { - d = TIMER.getAndSet(this, CANCELLED); + d = timer.getAndSet(CANCELLED); if (d != CANCELLED && d != null) { d.dispose(); } @@ -192,14 +198,17 @@ static final class TimeoutTimedSubscriber implements NbpSubscriber, Dispos Disposable s; - volatile Disposable timer; - @SuppressWarnings("rawtypes") - static final AtomicReferenceFieldUpdater TIMER = - AtomicReferenceFieldUpdater.newUpdater(TimeoutTimedSubscriber.class, Disposable.class, "timer"); + final AtomicReference timer = new AtomicReference(); - static final Disposable CANCELLED = () -> { }; + static final Disposable CANCELLED = new Disposable() { + @Override + public void dispose() { } + }; - static final Disposable NEW_TIMER = () -> { }; + static final Disposable NEW_TIMER = new Disposable() { + @Override + public void dispose() { } + }; volatile long index; @@ -236,24 +245,27 @@ public void onNext(T t) { scheduleTimeout(idx); } - void scheduleTimeout(long idx) { - Disposable d = timer; + void scheduleTimeout(final long idx) { + Disposable d = timer.get(); if (d != null) { d.dispose(); } - if (TIMER.compareAndSet(this, d, NEW_TIMER)) { - d = worker.schedule(() -> { - if (idx == index) { - done = true; - s.dispose(); - dispose(); - - actual.onError(new TimeoutException()); + if (timer.compareAndSet(d, NEW_TIMER)) { + d = worker.schedule(new Runnable() { + @Override + public void run() { + if (idx == index) { + done = true; + s.dispose(); + dispose(); + + actual.onError(new TimeoutException()); + } } }, timeout, unit); - if (!TIMER.compareAndSet(this, NEW_TIMER, d)) { + if (!timer.compareAndSet(NEW_TIMER, d)) { d.dispose(); } } @@ -289,9 +301,9 @@ public void dispose() { } public void disposeTimer() { - Disposable d = timer; + Disposable d = timer.get(); if (d != CANCELLED) { - d = TIMER.getAndSet(this, CANCELLED); + d = timer.getAndSet(CANCELLED); if (d != CANCELLED && d != null) { d.dispose(); } diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorToList.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorToList.java index c1a738f546..79d86caa46 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorToList.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorToList.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -14,10 +14,10 @@ package io.reactivex.internal.operators.nbp; import java.util.*; -import java.util.function.Supplier; import io.reactivex.NbpObservable.*; import io.reactivex.disposables.Disposable; +import io.reactivex.functions.Supplier; import io.reactivex.internal.disposables.EmptyDisposable; import io.reactivex.internal.subscribers.nbp.NbpCancelledSubscriber; import io.reactivex.internal.subscriptions.SubscriptionHelper; @@ -26,7 +26,12 @@ public final class NbpOperatorToList> implements NbpOperator { @SuppressWarnings({"rawtypes", "unchecked"}) - static final NbpOperatorToList DEFAULT = new NbpOperatorToList(ArrayList::new); + static final NbpOperatorToList DEFAULT = new NbpOperatorToList(new Supplier() { + @Override + public Object get() { + return new ArrayList(); + } + }); @SuppressWarnings("unchecked") public static NbpOperatorToList> defaultInstance() { @@ -48,7 +53,7 @@ public NbpSubscriber apply(NbpSubscriber t) { EmptyDisposable.error(e, t); return NbpCancelledSubscriber.INSTANCE; } - return new ToListSubscriber<>(t, coll); + return new ToListSubscriber(t, coll); } static final class ToListSubscriber> implements NbpSubscriber { diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorUnsubscribeOn.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorUnsubscribeOn.java index a318a9874b..6a41b27e33 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorUnsubscribeOn.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorUnsubscribeOn.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -15,8 +15,8 @@ import java.util.concurrent.atomic.AtomicBoolean; -import io.reactivex.NbpObservable.*; import io.reactivex.Scheduler; +import io.reactivex.NbpObservable.*; import io.reactivex.disposables.Disposable; import io.reactivex.internal.subscriptions.SubscriptionHelper; @@ -28,7 +28,7 @@ public NbpOperatorUnsubscribeOn(Scheduler scheduler) { @Override public NbpSubscriber apply(NbpSubscriber t) { - return new UnsubscribeSubscriber<>(t, scheduler); + return new UnsubscribeSubscriber(t, scheduler); } static final class UnsubscribeSubscriber extends AtomicBoolean implements NbpSubscriber, Disposable { @@ -72,8 +72,11 @@ public void onComplete() { @Override public void dispose() { if (compareAndSet(false, true)) { - scheduler.scheduleDirect(() -> { - s.dispose(); + scheduler.scheduleDirect(new Runnable() { + @Override + public void run() { + s.dispose(); + } }); } } diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorWindow.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorWindow.java index c3e6b58eea..60bdb543a4 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorWindow.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorWindow.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -36,9 +36,9 @@ public NbpOperatorWindow(long count, long skip, int capacityHint) { @Override public NbpSubscriber apply(NbpSubscriber> t) { if (count == skip) { - return new WindowExactSubscriber<>(t, count, capacityHint); + return new WindowExactSubscriber(t, count, capacityHint); } - return new WindowSkipSubscriber<>(t, count, skip, capacityHint); + return new WindowSkipSubscriber(t, count, skip, capacityHint); } static final class WindowExactSubscriber @@ -147,17 +147,14 @@ static final class WindowSkipSubscriber extends AtomicBoolean Disposable s; - volatile int wip; - @SuppressWarnings("rawtypes") - static final AtomicIntegerFieldUpdater WIP = - AtomicIntegerFieldUpdater.newUpdater(WindowSkipSubscriber.class, "wip"); + final AtomicInteger wip = new AtomicInteger(); public WindowSkipSubscriber(NbpSubscriber> actual, long count, long skip, int capacityHint) { this.actual = actual; this.count = count; this.skip = skip; this.capacityHint = capacityHint; - this.windows = new ArrayDeque<>(); + this.windows = new ArrayDeque>(); } @Override @@ -180,7 +177,7 @@ public void onNext(T t) { long s = skip; if (i % s == 0 && !cancelled) { - WIP.getAndIncrement(this); + wip.getAndIncrement(); NbpUnicastSubject w = NbpUnicastSubject.create(capacityHint, this); ws.offer(w); actual.onNext(w); @@ -231,7 +228,7 @@ public void dispose() { @Override public void run() { - if (WIP.decrementAndGet(this) == 0) { + if (wip.decrementAndGet() == 0) { if (cancelled) { s.dispose(); } diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorWindowBoundary.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorWindowBoundary.java index a1df651f3d..43b29a8588 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorWindowBoundary.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorWindowBoundary.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -16,7 +16,7 @@ import java.util.Queue; import java.util.concurrent.atomic.*; -import io.reactivex.*; +import io.reactivex.NbpObservable; import io.reactivex.NbpObservable.*; import io.reactivex.disposables.Disposable; import io.reactivex.internal.queue.MpscLinkedQueue; @@ -38,7 +38,7 @@ public NbpOperatorWindowBoundary(NbpObservable other, int bufferSize) { @Override public NbpSubscriber apply(NbpSubscriber> t) { - return new WindowBoundaryMainSubscriber<>(new NbpSerializedSubscriber<>(t), other, bufferSize); + return new WindowBoundaryMainSubscriber(new NbpSerializedSubscriber>(t), other, bufferSize); } static final class WindowBoundaryMainSubscriber @@ -50,28 +50,25 @@ static final class WindowBoundaryMainSubscriber Disposable s; - volatile Disposable boundary; - @SuppressWarnings("rawtypes") - static final AtomicReferenceFieldUpdater BOUNDARY = - AtomicReferenceFieldUpdater.newUpdater(WindowBoundaryMainSubscriber.class, Disposable.class, "boundary"); + final AtomicReference boundary = new AtomicReference(); - static final Disposable CANCELLED = () -> { }; + static final Disposable CANCELLED = new Disposable() { + @Override + public void dispose() { } + }; NbpUnicastSubject window; static final Object NEXT = new Object(); - volatile long windows; - @SuppressWarnings("rawtypes") - static final AtomicLongFieldUpdater WINDOWS = - AtomicLongFieldUpdater.newUpdater(WindowBoundaryMainSubscriber.class, "windows"); + final AtomicLong windows = new AtomicLong(); public WindowBoundaryMainSubscriber(NbpSubscriber> actual, NbpObservable other, int bufferSize) { - super(actual, new MpscLinkedQueue<>()); + super(actual, new MpscLinkedQueue()); this.other = other; this.bufferSize = bufferSize; - WINDOWS.lazySet(this, 1); + windows.lazySet(1); } @Override @@ -94,10 +91,10 @@ public void onSubscribe(Disposable s) { a.onNext(w); - WindowBoundaryInnerSubscriber inner = new WindowBoundaryInnerSubscriber<>(this); + WindowBoundaryInnerSubscriber inner = new WindowBoundaryInnerSubscriber(this); - if (BOUNDARY.compareAndSet(this, null, inner)) { - WINDOWS.getAndIncrement(this); + if (boundary.compareAndSet(null, inner)) { + windows.getAndIncrement(); other.subscribe(inner); } } @@ -133,7 +130,7 @@ public void onError(Throwable t) { drainLoop(); } - if (WINDOWS.decrementAndGet(this) == 0) { + if (windows.decrementAndGet() == 0) { disposeBoundary(); } @@ -150,7 +147,7 @@ public void onComplete() { drainLoop(); } - if (WINDOWS.decrementAndGet(this) == 0) { + if (windows.decrementAndGet() == 0) { disposeBoundary(); } @@ -166,9 +163,9 @@ public void dispose() { } void disposeBoundary() { - Disposable d = boundary; + Disposable d = boundary.get(); if (d != CANCELLED) { - d = BOUNDARY.getAndSet(this, CANCELLED); + d = boundary.getAndSet(CANCELLED); if (d != CANCELLED && d != null) { d.dispose(); } @@ -207,7 +204,7 @@ void drainLoop() { if (o == NEXT) { w.onComplete(); - if (WINDOWS.decrementAndGet(this) == 0) { + if (windows.decrementAndGet() == 0) { disposeBoundary(); return; } @@ -218,7 +215,7 @@ void drainLoop() { w = NbpUnicastSubject.create(bufferSize); - WINDOWS.getAndIncrement(this); + windows.getAndIncrement(); window = w; @@ -227,7 +224,7 @@ void drainLoop() { continue; } - w.onNext(NotificationLite.getValue(o)); + w.onNext(NotificationLite.getValue(o)); } missed = leave(-missed); diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorWindowBoundarySelector.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorWindowBoundarySelector.java index 801f09bec1..b37e59ab08 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorWindowBoundarySelector.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorWindowBoundarySelector.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -15,11 +15,11 @@ import java.util.*; import java.util.concurrent.atomic.*; -import java.util.function.Function; import io.reactivex.NbpObservable; import io.reactivex.NbpObservable.*; -import io.reactivex.disposables.Disposable; +import io.reactivex.disposables.*; +import io.reactivex.functions.Function; import io.reactivex.internal.disposables.SetCompositeResource; import io.reactivex.internal.queue.MpscLinkedQueue; import io.reactivex.internal.subscribers.nbp.*; @@ -43,8 +43,8 @@ public NbpOperatorWindowBoundarySelector(NbpObservable open, Function apply(NbpSubscriber> t) { - return new WindowBoundaryMainSubscriber<>( - new NbpSerializedSubscriber<>(t), + return new WindowBoundaryMainSubscriber( + new NbpSerializedSubscriber>(t), open, close, bufferSize); } @@ -58,29 +58,26 @@ static final class WindowBoundaryMainSubscriber Disposable s; - volatile Disposable boundary; - @SuppressWarnings("rawtypes") - static final AtomicReferenceFieldUpdater BOUNDARY = - AtomicReferenceFieldUpdater.newUpdater(WindowBoundaryMainSubscriber.class, Disposable.class, "boundary"); + final AtomicReference boundary = new AtomicReference(); - static final Disposable CANCELLED = () -> { }; + static final Disposable CANCELLED = new Disposable() { + @Override + public void dispose() { } + }; final List> ws; - volatile long windows; - @SuppressWarnings("rawtypes") - static final AtomicLongFieldUpdater WINDOWS = - AtomicLongFieldUpdater.newUpdater(WindowBoundaryMainSubscriber.class, "windows"); + final AtomicLong windows = new AtomicLong(); public WindowBoundaryMainSubscriber(NbpSubscriber> actual, NbpObservable open, Function> close, int bufferSize) { - super(actual, new MpscLinkedQueue<>()); + super(actual, new MpscLinkedQueue()); this.open = open; this.close = close; this.bufferSize = bufferSize; - this.resources = new SetCompositeResource<>(Disposable::dispose); - this.ws = new ArrayList<>(); - WINDOWS.lazySet(this, 1); + this.resources = new SetCompositeResource(Disposables.consumeAndDispose()); + this.ws = new ArrayList>(); + windows.lazySet(1); } @Override @@ -97,10 +94,10 @@ public void onSubscribe(Disposable s) { return; } - OperatorWindowBoundaryOpenSubscriber os = new OperatorWindowBoundaryOpenSubscriber<>(this); + OperatorWindowBoundaryOpenSubscriber os = new OperatorWindowBoundaryOpenSubscriber(this); - if (BOUNDARY.compareAndSet(this, null, os)) { - WINDOWS.getAndIncrement(this); + if (boundary.compareAndSet(null, os)) { + windows.getAndIncrement(); open.subscribe(os); } @@ -137,7 +134,7 @@ public void onError(Throwable t) { drainLoop(); } - if (WINDOWS.decrementAndGet(this) == 0) { + if (windows.decrementAndGet() == 0) { resources.dispose(); } @@ -155,7 +152,7 @@ public void onComplete() { drainLoop(); } - if (WINDOWS.decrementAndGet(this) == 0) { + if (windows.decrementAndGet() == 0) { resources.dispose(); } @@ -165,7 +162,7 @@ public void onComplete() { void complete() { - if (WINDOWS.decrementAndGet(this) == 0) { + if (windows.decrementAndGet() == 0) { s.dispose(); resources.dispose(); } @@ -174,7 +171,7 @@ void complete() { } void error(Throwable t) { - if (WINDOWS.decrementAndGet(this) == 0) { + if (windows.decrementAndGet() == 0) { s.dispose(); resources.dispose(); } @@ -191,9 +188,9 @@ public void dispose() { void disposeBoundary() { resources.dispose(); - Disposable d = boundary; + Disposable d = boundary.get(); if (d != CANCELLED) { - d = BOUNDARY.getAndSet(this, CANCELLED); + d = boundary.getAndSet(CANCELLED); if (d != CANCELLED && d != null) { d.dispose(); } @@ -243,7 +240,7 @@ void drainLoop() { if (ws.remove(wo.w)) { wo.w.onComplete(); - if (WINDOWS.decrementAndGet(this) == 0) { + if (windows.decrementAndGet() == 0) { disposeBoundary(); return; } @@ -277,10 +274,10 @@ void drainLoop() { continue; } - OperatorWindowBoundaryCloseSubscriber cl = new OperatorWindowBoundaryCloseSubscriber<>(this, w); + OperatorWindowBoundaryCloseSubscriber cl = new OperatorWindowBoundaryCloseSubscriber(this, w); if (resources.add(cl)) { - WINDOWS.getAndIncrement(this); + windows.getAndIncrement(); p.subscribe(cl); } @@ -289,7 +286,7 @@ void drainLoop() { } for (NbpUnicastSubject w : ws) { - w.onNext(NotificationLite.getValue(o)); + w.onNext(NotificationLite.getValue(o)); } } @@ -305,7 +302,7 @@ public void accept(NbpSubscriber> a, Object v) { } void open(B b) { - queue.offer(new WindowOperation<>(null, b)); + queue.offer(new WindowOperation(null, b)); if (enter()) { drainLoop(); } @@ -313,7 +310,7 @@ void open(B b) { void close(OperatorWindowBoundaryCloseSubscriber w) { resources.delete(w); - queue.offer(new WindowOperation<>(w.w, null)); + queue.offer(new WindowOperation(w.w, null)); if (enter()) { drainLoop(); } diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorWindowBoundarySupplier.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorWindowBoundarySupplier.java index e20b5c946d..4a6c6420f3 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorWindowBoundarySupplier.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorWindowBoundarySupplier.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -15,11 +15,11 @@ import java.util.Queue; import java.util.concurrent.atomic.*; -import java.util.function.Supplier; import io.reactivex.NbpObservable; import io.reactivex.NbpObservable.*; import io.reactivex.disposables.Disposable; +import io.reactivex.functions.Supplier; import io.reactivex.internal.queue.MpscLinkedQueue; import io.reactivex.internal.subscribers.nbp.*; import io.reactivex.internal.subscriptions.SubscriptionHelper; @@ -39,7 +39,7 @@ public NbpOperatorWindowBoundarySupplier(Supplier> ot @Override public NbpSubscriber apply(NbpSubscriber> t) { - return new WindowBoundaryMainSubscriber<>(new NbpSerializedSubscriber<>(t), other, bufferSize); + return new WindowBoundaryMainSubscriber(new NbpSerializedSubscriber>(t), other, bufferSize); } static final class WindowBoundaryMainSubscriber @@ -51,28 +51,25 @@ static final class WindowBoundaryMainSubscriber Disposable s; - volatile Disposable boundary; - @SuppressWarnings("rawtypes") - static final AtomicReferenceFieldUpdater BOUNDARY = - AtomicReferenceFieldUpdater.newUpdater(WindowBoundaryMainSubscriber.class, Disposable.class, "boundary"); + final AtomicReference boundary = new AtomicReference(); - static final Disposable CANCELLED = () -> { }; + static final Disposable CANCELLED = new Disposable() { + @Override + public void dispose() { } + }; NbpUnicastSubject window; static final Object NEXT = new Object(); - volatile long windows; - @SuppressWarnings("rawtypes") - static final AtomicLongFieldUpdater WINDOWS = - AtomicLongFieldUpdater.newUpdater(WindowBoundaryMainSubscriber.class, "windows"); + final AtomicLong windows = new AtomicLong(); public WindowBoundaryMainSubscriber(NbpSubscriber> actual, Supplier> other, int bufferSize) { - super(actual, new MpscLinkedQueue<>()); + super(actual, new MpscLinkedQueue()); this.other = other; this.bufferSize = bufferSize; - WINDOWS.lazySet(this, 1); + windows.lazySet(1); } @Override @@ -111,10 +108,10 @@ public void onSubscribe(Disposable s) { a.onNext(w); - WindowBoundaryInnerSubscriber inner = new WindowBoundaryInnerSubscriber<>(this); + WindowBoundaryInnerSubscriber inner = new WindowBoundaryInnerSubscriber(this); - if (BOUNDARY.compareAndSet(this, null, inner)) { - WINDOWS.getAndIncrement(this); + if (boundary.compareAndSet(null, inner)) { + windows.getAndIncrement(); p.subscribe(inner); return; } @@ -151,7 +148,7 @@ public void onError(Throwable t) { drainLoop(); } - if (WINDOWS.decrementAndGet(this) == 0) { + if (windows.decrementAndGet() == 0) { disposeBoundary(); } @@ -168,7 +165,7 @@ public void onComplete() { drainLoop(); } - if (WINDOWS.decrementAndGet(this) == 0) { + if (windows.decrementAndGet() == 0) { disposeBoundary(); } @@ -184,9 +181,9 @@ public void dispose() { } void disposeBoundary() { - Disposable d = boundary; + Disposable d = boundary.get(); if (d != CANCELLED) { - d = BOUNDARY.getAndSet(this, CANCELLED); + d = boundary.getAndSet(CANCELLED); if (d != CANCELLED && d != null) { d.dispose(); } @@ -224,7 +221,7 @@ void drainLoop() { if (o == NEXT) { w.onComplete(); - if (WINDOWS.decrementAndGet(this) == 0) { + if (windows.decrementAndGet() == 0) { disposeBoundary(); return; } @@ -251,22 +248,22 @@ void drainLoop() { w = NbpUnicastSubject.create(bufferSize); - WINDOWS.getAndIncrement(this); + windows.getAndIncrement(); window = w; a.onNext(w); - WindowBoundaryInnerSubscriber b = new WindowBoundaryInnerSubscriber<>(this); + WindowBoundaryInnerSubscriber b = new WindowBoundaryInnerSubscriber(this); - if (BOUNDARY.compareAndSet(this, boundary, b)) { + if (boundary.compareAndSet(boundary.get(), b)) { p.subscribe(b); } continue; } - w.onNext(NotificationLite.getValue(o)); + w.onNext(NotificationLite.getValue(o)); } missed = leave(-missed); diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorWindowTimed.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorWindowTimed.java index 4c604d35c5..101006106b 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorWindowTimed.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorWindowTimed.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -16,7 +16,7 @@ import java.nio.channels.CancelledKeyException; import java.util.*; import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; +import java.util.concurrent.atomic.*; import io.reactivex.*; import io.reactivex.NbpObservable.*; @@ -51,20 +51,20 @@ public NbpOperatorWindowTimed(long timespan, long timeskip, TimeUnit unit, Sched @Override public NbpSubscriber apply(NbpSubscriber> t) { - NbpSerializedSubscriber> actual = new NbpSerializedSubscriber<>(t); + NbpSerializedSubscriber> actual = new NbpSerializedSubscriber>(t); if (timespan == timeskip) { if (maxSize == Long.MAX_VALUE) { - return new WindowExactUnboundedSubscriber<>( + return new WindowExactUnboundedSubscriber( actual, timespan, unit, scheduler, bufferSize); } - return new WindowExactBoundedSubscriber<>( + return new WindowExactBoundedSubscriber( actual, timespan, unit, scheduler, bufferSize, maxSize, restartTimerOnMaxSize); } - return new WindowSkipSubscriber<>(actual, + return new WindowSkipSubscriber(actual, timespan, timeskip, unit, scheduler.createWorker(), bufferSize); } @@ -82,12 +82,12 @@ static final class WindowExactUnboundedSubscriber NbpUnicastSubject window; - volatile Disposable timer; - @SuppressWarnings("rawtypes") - static final AtomicReferenceFieldUpdater TIMER = - AtomicReferenceFieldUpdater.newUpdater(WindowExactUnboundedSubscriber.class, Disposable.class, "timer"); + final AtomicReference timer = new AtomicReference(); - static final Disposable CANCELLED = () -> { }; + static final Disposable CANCELLED = new Disposable() { + @Override + public void dispose() { } + }; static final Object NEXT = new Object(); @@ -95,7 +95,7 @@ static final class WindowExactUnboundedSubscriber public WindowExactUnboundedSubscriber(NbpSubscriber> actual, long timespan, TimeUnit unit, Scheduler scheduler, int bufferSize) { - super(actual, new MpscLinkedQueue<>()); + super(actual, new MpscLinkedQueue()); this.timespan = timespan; this.unit = unit; this.scheduler = scheduler; @@ -118,7 +118,7 @@ public void onSubscribe(Disposable s) { if (!cancelled) { Disposable d = scheduler.schedulePeriodicallyDirect(this, timespan, timespan, unit); - if (!TIMER.compareAndSet(this, null, d)) { + if (!timer.compareAndSet(null, d)) { d.dispose(); return; } @@ -175,9 +175,9 @@ public void dispose() { void disposeTimer() { selfCancel = true; - Disposable d = timer; + Disposable d = timer.get(); if (d != CANCELLED) { - d = TIMER.getAndSet(this, CANCELLED); + d = timer.getAndSet(CANCELLED); if (d != CANCELLED && d != null) { d.dispose(); } @@ -248,7 +248,7 @@ void drainLoop() { continue; } - w.onNext(NotificationLite.getValue(o)); + w.onNext(NotificationLite.getValue(o)); } missed = leave(-missed); @@ -288,18 +288,18 @@ static final class WindowExactBoundedSubscriber volatile boolean terminated; - volatile Disposable timer; - @SuppressWarnings("rawtypes") - static final AtomicReferenceFieldUpdater TIMER = - AtomicReferenceFieldUpdater.newUpdater(WindowExactBoundedSubscriber.class, Disposable.class, "timer"); + final AtomicReference timer = new AtomicReference(); - static final Disposable CANCELLED = () -> { }; + static final Disposable CANCELLED = new Disposable() { + @Override + public void dispose() { } + }; public WindowExactBoundedSubscriber( NbpSubscriber> actual, long timespan, TimeUnit unit, Scheduler scheduler, int bufferSize, long maxSize, boolean restartTimerOnMaxSize) { - super(actual, new MpscLinkedQueue<>()); + super(actual, new MpscLinkedQueue()); this.timespan = timespan; this.unit = unit; this.scheduler = scheduler; @@ -339,7 +339,7 @@ public void onSubscribe(Disposable s) { d = scheduler.schedulePeriodicallyDirect(consumerIndexHolder, timespan, timespan, unit); } - if (!TIMER.compareAndSet(this, null, d)) { + if (!timer.compareAndSet(null, d)) { d.dispose(); return; } @@ -367,12 +367,11 @@ public void onNext(T t) { window = w; actual.onNext(w); if (restartTimerOnMaxSize) { - timer.dispose(); - - Disposable tm = timer; + Disposable tm = timer.get(); + tm.dispose(); Disposable task = worker.schedulePeriodically( new ConsumerIndexHolder(producerIndex, this), timespan, timespan, unit); - if (!TIMER.compareAndSet(this, tm, task)) { + if (!timer.compareAndSet(tm, task)) { task.dispose(); } } @@ -424,9 +423,9 @@ public void dispose() { void disposeTimer() { selfCancel = true; - Disposable d = timer; + Disposable d = timer.get(); if (d != CANCELLED) { - d = TIMER.getAndSet(this, CANCELLED); + d = timer.getAndSet(CANCELLED); if (d != CANCELLED && d != null) { d.dispose(); } @@ -489,7 +488,7 @@ void drainLoop() { continue; } - w.onNext(NotificationLite.getValue(o)); + w.onNext(NotificationLite.getValue(o)); long c = count + 1; if (c >= maxSize) { @@ -503,12 +502,12 @@ void drainLoop() { actual.onNext(w); if (restartTimerOnMaxSize) { - timer.dispose(); + Disposable tm = timer.get(); + tm.dispose(); - Disposable tm = timer; Disposable task = worker.schedulePeriodically( new ConsumerIndexHolder(producerIndex, this), timespan, timespan, unit); - if (!TIMER.compareAndSet(this, tm, task)) { + if (!timer.compareAndSet(tm, task)) { task.dispose(); } } @@ -571,13 +570,13 @@ static final class WindowSkipSubscriber public WindowSkipSubscriber(NbpSubscriber> actual, long timespan, long timeskip, TimeUnit unit, Worker worker, int bufferSize) { - super(actual, new MpscLinkedQueue<>()); + super(actual, new MpscLinkedQueue()); this.timespan = timespan; this.timeskip = timeskip; this.unit = unit; this.worker = worker; this.bufferSize = bufferSize; - this.windows = new LinkedList<>(); + this.windows = new LinkedList>(); } @Override @@ -594,12 +593,15 @@ public void onSubscribe(Disposable s) { return; } - NbpUnicastSubject w = NbpUnicastSubject.create(bufferSize); + final NbpUnicastSubject w = NbpUnicastSubject.create(bufferSize); windows.add(w); actual.onNext(w); - worker.schedule(() -> { - complete(w); + worker.schedule(new Runnable() { + @Override + public void run() { + complete(w); + } }, timespan, unit); worker.schedulePeriodically(this, timeskip, timeskip, unit); @@ -663,7 +665,7 @@ public void accept(NbpSubscriber> a, Object v) { } void complete(NbpUnicastSubject w) { - queue.offer(new SubjectWork<>(w, false)); + queue.offer(new SubjectWork(w, false)); if (enter()) { drainLoop(); } @@ -724,12 +726,15 @@ void drainLoop() { continue; } - NbpUnicastSubject w = NbpUnicastSubject.create(bufferSize); + final NbpUnicastSubject w = NbpUnicastSubject.create(bufferSize); ws.add(w); a.onNext(w); - worker.schedule(() -> { - complete(w); + worker.schedule(new Runnable() { + @Override + public void run() { + complete(w); + } }, timespan, unit); } else { ws.remove(work.w); @@ -742,7 +747,7 @@ void drainLoop() { } for (NbpUnicastSubject w : ws) { - w.onNext(NotificationLite.getValue(v)); + w.onNext(NotificationLite.getValue(v)); } } @@ -758,7 +763,7 @@ public void run() { NbpUnicastSubject w = NbpUnicastSubject.create(bufferSize); - SubjectWork sw = new SubjectWork<>(w, true); + SubjectWork sw = new SubjectWork(w, true); if (!cancelled) { queue.offer(sw); } diff --git a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorWithLatestFrom.java b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorWithLatestFrom.java index 87d81f02d0..7a9b8bc25d 100644 --- a/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorWithLatestFrom.java +++ b/src/main/java/io/reactivex/internal/operators/nbp/NbpOperatorWithLatestFrom.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -14,11 +14,11 @@ package io.reactivex.internal.operators.nbp; import java.util.concurrent.atomic.*; -import java.util.function.BiFunction; import io.reactivex.NbpObservable; import io.reactivex.NbpObservable.*; import io.reactivex.disposables.Disposable; +import io.reactivex.functions.BiFunction; import io.reactivex.internal.disposables.EmptyDisposable; import io.reactivex.internal.subscriptions.SubscriptionHelper; import io.reactivex.plugins.RxJavaPlugins; @@ -34,8 +34,8 @@ public NbpOperatorWithLatestFrom(BiFunction c @Override public NbpSubscriber apply(NbpSubscriber t) { - NbpSerializedSubscriber serial = new NbpSerializedSubscriber<>(t); - WithLatestFromSubscriber wlf = new WithLatestFromSubscriber<>(serial, combiner); + final NbpSerializedSubscriber serial = new NbpSerializedSubscriber(t); + final WithLatestFromSubscriber wlf = new WithLatestFromSubscriber(serial, combiner); other.subscribe(new NbpSubscriber() { @Override @@ -69,17 +69,14 @@ static final class WithLatestFromSubscriber extends AtomicReference final NbpSubscriber actual; final BiFunction combiner; - volatile Disposable s; - @SuppressWarnings("rawtypes") - static final AtomicReferenceFieldUpdater S = - AtomicReferenceFieldUpdater.newUpdater(WithLatestFromSubscriber.class, Disposable.class, "s"); + final AtomicReference s = new AtomicReference(); - volatile Disposable other; - @SuppressWarnings("rawtypes") - static final AtomicReferenceFieldUpdater OTHER = - AtomicReferenceFieldUpdater.newUpdater(WithLatestFromSubscriber.class, Disposable.class, "other"); + final AtomicReference other = new AtomicReference(); - static final Disposable CANCELLED = () -> { }; + static final Disposable CANCELLED = new Disposable() { + @Override + public void dispose() { } + }; public WithLatestFromSubscriber(NbpSubscriber actual, BiFunction combiner) { this.actual = actual; @@ -87,11 +84,11 @@ public WithLatestFromSubscriber(NbpSubscriber actual, BiFunction extends AtomicReference implements NbpSubscriber, Disposable { @@ -27,12 +27,12 @@ public final class NbpSubscriberResourceWrapper extends AtomicReference actual; final Consumer disposer; - volatile Disposable subscription; - @SuppressWarnings("rawtypes") - static final AtomicReferenceFieldUpdater SUBSCRIPTION = - AtomicReferenceFieldUpdater.newUpdater(NbpSubscriberResourceWrapper.class, Disposable.class, "subscription"); + final AtomicReference subscription = new AtomicReference(); - static final Disposable TERMINATED = () -> { }; + static final Disposable TERMINATED = new Disposable() { + @Override + public void dispose() { } + }; public NbpSubscriberResourceWrapper(NbpSubscriber actual, Consumer disposer) { this.actual = actual; @@ -42,7 +42,7 @@ public NbpSubscriberResourceWrapper(NbpSubscriber actual, Consumer implements SingleOperator { final Function> mapper; @@ -28,7 +27,7 @@ public SingleOperatorFlatMap(Function> @Override public SingleSubscriber apply(SingleSubscriber t) { - return new SingleFlatMapCallback<>(t, mapper); + return new SingleFlatMapCallback(t, mapper); } static final class SingleFlatMapCallback implements SingleSubscriber { diff --git a/src/main/java/io/reactivex/internal/operators/single/SingleOperatorMap.java b/src/main/java/io/reactivex/internal/operators/single/SingleOperatorMap.java index 3e569758e4..7b6f875324 100644 --- a/src/main/java/io/reactivex/internal/operators/single/SingleOperatorMap.java +++ b/src/main/java/io/reactivex/internal/operators/single/SingleOperatorMap.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,10 +13,9 @@ package io.reactivex.internal.operators.single; -import java.util.function.Function; - import io.reactivex.Single.*; import io.reactivex.disposables.Disposable; +import io.reactivex.functions.Function; public final class SingleOperatorMap implements SingleOperator { final Function mapper; @@ -26,7 +25,7 @@ public SingleOperatorMap(Function mapper) { } @Override - public SingleSubscriber apply(SingleSubscriber t) { + public SingleSubscriber apply(final SingleSubscriber t) { return new SingleSubscriber() { @Override public void onSubscribe(Disposable d) { diff --git a/src/main/java/io/reactivex/internal/queue/BaseArrayQueue.java b/src/main/java/io/reactivex/internal/queue/BaseArrayQueue.java index e7e01c7bdc..c681037c17 100644 --- a/src/main/java/io/reactivex/internal/queue/BaseArrayQueue.java +++ b/src/main/java/io/reactivex/internal/queue/BaseArrayQueue.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 diff --git a/src/main/java/io/reactivex/internal/queue/BaseLinkedQueue.java b/src/main/java/io/reactivex/internal/queue/BaseLinkedQueue.java index ccd94f748b..5c14019956 100644 --- a/src/main/java/io/reactivex/internal/queue/BaseLinkedQueue.java +++ b/src/main/java/io/reactivex/internal/queue/BaseLinkedQueue.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -25,8 +25,8 @@ abstract class BaseLinkedQueue extends AbstractQueue { private final AtomicReference> producerNode; private final AtomicReference> consumerNode; public BaseLinkedQueue() { - producerNode = new AtomicReference<>(); - consumerNode = new AtomicReference<>(); + producerNode = new AtomicReference>(); + consumerNode = new AtomicReference>(); } protected final LinkedQueueNode lvProducerNode() { return producerNode.get(); @@ -84,8 +84,6 @@ public final int size() { * Queue is empty when producerNode is the same as consumerNode. An alternative implementation would be to observe * the producerNode.value is null, which also means an empty queue because only the consumerNode.value is allowed to * be null. - * - * @see MessagePassingQueue#isEmpty() */ @Override public final boolean isEmpty() { diff --git a/src/main/java/io/reactivex/internal/queue/LinkedQueueNode.java b/src/main/java/io/reactivex/internal/queue/LinkedQueueNode.java index 3b849fb52a..b72c5bb299 100644 --- a/src/main/java/io/reactivex/internal/queue/LinkedQueueNode.java +++ b/src/main/java/io/reactivex/internal/queue/LinkedQueueNode.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 diff --git a/src/main/java/io/reactivex/internal/queue/MpscLinkedQueue.java b/src/main/java/io/reactivex/internal/queue/MpscLinkedQueue.java index d9b7fb5408..439c9ea9fd 100644 --- a/src/main/java/io/reactivex/internal/queue/MpscLinkedQueue.java +++ b/src/main/java/io/reactivex/internal/queue/MpscLinkedQueue.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -20,12 +20,13 @@ /** * A multi-producer single consumer unbounded queue. + * @param the contained value type */ public final class MpscLinkedQueue extends BaseLinkedQueue { public MpscLinkedQueue() { super(); - LinkedQueueNode node = new LinkedQueueNode<>(); + LinkedQueueNode node = new LinkedQueueNode(); spConsumerNode(node); xchgProducerNode(node);// this ensures correct construction: StoreLoad } @@ -42,12 +43,11 @@ public MpscLinkedQueue() { * This works because each producer is guaranteed to 'plant' a new node and link the old node. No 2 producers can * get the same producer node as part of XCHG guarantee. * - * @see MessagePassingQueue#offer(Object) * @see java.util.Queue#offer(java.lang.Object) */ @Override public final boolean offer(final T nextValue) { - final LinkedQueueNode nextNode = new LinkedQueueNode<>(nextValue); + final LinkedQueueNode nextNode = new LinkedQueueNode(nextValue); final LinkedQueueNode prevProducerNode = xchgProducerNode(nextNode); // Should a producer thread get interrupted here the chain WILL be broken until that thread is resumed // and completes the store in prev.next. @@ -68,7 +68,6 @@ public final boolean offer(final T nextValue) { * This means the consumerNode.value is always null, which is also the starting point for the queue. Because null * values are not allowed to be offered this is the only node with it's value set to null at any one time. * - * @see MessagePassingQueue#poll() * @see java.util.Queue#poll() */ @Override diff --git a/src/main/java/io/reactivex/internal/queue/SpscArrayQueue.java b/src/main/java/io/reactivex/internal/queue/SpscArrayQueue.java index 9e5e839587..3c00d3f253 100644 --- a/src/main/java/io/reactivex/internal/queue/SpscArrayQueue.java +++ b/src/main/java/io/reactivex/internal/queue/SpscArrayQueue.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 diff --git a/src/main/java/io/reactivex/internal/queue/SpscExactArrayQueue.java b/src/main/java/io/reactivex/internal/queue/SpscExactArrayQueue.java index b764bf7084..60a721c0ee 100644 --- a/src/main/java/io/reactivex/internal/queue/SpscExactArrayQueue.java +++ b/src/main/java/io/reactivex/internal/queue/SpscExactArrayQueue.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -21,25 +21,21 @@ import java.util.*; import java.util.concurrent.atomic.*; +import io.reactivex.internal.functions.Objects; import io.reactivex.internal.util.Pow2; /** * A single-producer single-consumer array-backed queue with exact, non power-of-2 logical capacity. + * @param the contained value type */ public final class SpscExactArrayQueue extends AtomicReferenceArray implements Queue { /** */ private static final long serialVersionUID = 6210984603741293445L; final int mask; final int capacitySkip; - volatile long producerIndex; - volatile long consumerIndex; - - @SuppressWarnings("rawtypes") - static final AtomicLongFieldUpdater PRODUCER_INDEX = - AtomicLongFieldUpdater.newUpdater(SpscExactArrayQueue.class, "producerIndex"); - @SuppressWarnings("rawtypes") - static final AtomicLongFieldUpdater CONSUMER_INDEX = - AtomicLongFieldUpdater.newUpdater(SpscExactArrayQueue.class, "consumerIndex"); + + final AtomicLong producerIndex = new AtomicLong(); + final AtomicLong consumerIndex = new AtomicLong(); public SpscExactArrayQueue(int capacity) { super(Pow2.roundToPowerOfTwo(capacity)); @@ -51,9 +47,9 @@ public SpscExactArrayQueue(int capacity) { @Override public boolean offer(T value) { - Objects.requireNonNull(value); + Objects.requireNonNull(value, "value is null"); - long pi = producerIndex; + long pi = producerIndex.get(); int m = mask; int fullCheck = (int)(pi + capacitySkip) & m; @@ -61,25 +57,25 @@ public boolean offer(T value) { return false; } int offset = (int)pi & m; - PRODUCER_INDEX.lazySet(this, pi + 1); + producerIndex.lazySet(pi + 1); lazySet(offset, value); return true; } @Override public T poll() { - long ci = consumerIndex; + long ci = consumerIndex.get(); int offset = (int)ci & mask; T value = get(offset); if (value == null) { return null; } - CONSUMER_INDEX.lazySet(this, ci + 1); + consumerIndex.lazySet(ci + 1); lazySet(offset, null); return value; } @Override public T peek() { - return get((int)consumerIndex & mask); + return get((int)consumerIndex.get() & mask); } @Override public void clear() { @@ -87,15 +83,15 @@ public void clear() { } @Override public boolean isEmpty() { - return producerIndex == consumerIndex; + return producerIndex.get() == consumerIndex.get(); } @Override public int size() { - long ci = consumerIndex; + long ci = consumerIndex.get(); for (;;) { - long pi = producerIndex; - long ci2 = consumerIndex; + long pi = producerIndex.get(); + long ci2 = consumerIndex.get(); if (ci == ci2) { return (int)(pi - ci2); } diff --git a/src/main/java/io/reactivex/internal/queue/SpscLinkedArrayQueue.java b/src/main/java/io/reactivex/internal/queue/SpscLinkedArrayQueue.java index 8bc8f05eb8..2e7ea6593f 100644 --- a/src/main/java/io/reactivex/internal/queue/SpscLinkedArrayQueue.java +++ b/src/main/java/io/reactivex/internal/queue/SpscLinkedArrayQueue.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -26,29 +26,26 @@ /** * A single-producer single-consumer array-backed queue which can allocate new arrays in case the consumer is slower * than the producer. + * @param the contained value type */ public final class SpscLinkedArrayQueue implements Queue { static final int MAX_LOOK_AHEAD_STEP = Integer.getInteger("jctools.spsc.max.lookahead.step", 4096); - protected volatile long producerIndex; - @SuppressWarnings("rawtypes") - static final AtomicLongFieldUpdater PRODUCER_INDEX = - AtomicLongFieldUpdater.newUpdater(SpscLinkedArrayQueue.class, "producerIndex"); + protected final AtomicLong producerIndex = new AtomicLong(); + protected int producerLookAheadStep; protected long producerLookAhead; protected int producerMask; protected AtomicReferenceArray producerBuffer; protected int consumerMask; protected AtomicReferenceArray consumerBuffer; - protected volatile long consumerIndex; - @SuppressWarnings("rawtypes") - static final AtomicLongFieldUpdater CONSUMER_INDEX = - AtomicLongFieldUpdater.newUpdater(SpscLinkedArrayQueue.class, "consumerIndex"); + protected final AtomicLong consumerIndex = new AtomicLong(); + private static final Object HAS_NEXT = new Object(); public SpscLinkedArrayQueue(final int bufferSize) { int p2capacity = Pow2.roundToPowerOfTwo(bufferSize); int mask = p2capacity - 1; - AtomicReferenceArray buffer = new AtomicReferenceArray<>(p2capacity + 1); + AtomicReferenceArray buffer = new AtomicReferenceArray(p2capacity + 1); producerBuffer = buffer; producerMask = mask; adjustLookAheadStep(p2capacity); @@ -97,7 +94,7 @@ private boolean writeToQueue(final AtomicReferenceArray buffer, final T private void resize(final AtomicReferenceArray oldBuffer, final long currIndex, final int offset, final T e, final long mask) { final int capacity = oldBuffer.length(); - final AtomicReferenceArray newBuffer = new AtomicReferenceArray<>(capacity); + final AtomicReferenceArray newBuffer = new AtomicReferenceArray(capacity); producerBuffer = newBuffer; producerLookAhead = currIndex + mask - 1; soProducerIndex(currIndex + 1);// this ensures correctness on 32bit platforms @@ -215,27 +212,27 @@ private void adjustLookAheadStep(int capacity) { } private long lvProducerIndex() { - return producerIndex; + return producerIndex.get(); } private long lvConsumerIndex() { - return consumerIndex; + return consumerIndex.get(); } private long lpProducerIndex() { - return producerIndex; + return producerIndex.get(); } private long lpConsumerIndex() { - return consumerIndex; + return consumerIndex.get(); } private void soProducerIndex(long v) { - PRODUCER_INDEX.lazySet(this, v); + producerIndex.lazySet(v); } private void soConsumerIndex(long v) { - CONSUMER_INDEX.lazySet(this, v); + consumerIndex.lazySet(v); } private static final int calcWrappedOffset(long index, int mask) { @@ -315,13 +312,13 @@ public T element() { /** * Offer two elements at the same time. *

Don't use the regular offer() with this at all! - * @param first - * @param second - * @return + * @param first the first value, not null + * @param second the second value, not null + * @return true if the queue accepted the two new values */ public boolean offer(T first, T second) { final AtomicReferenceArray buffer = producerBuffer; - final long p = producerIndex; + final long p = lvProducerIndex(); final int m = producerMask; int pi = calcWrappedOffset(p + 2, m); @@ -333,7 +330,7 @@ public boolean offer(T first, T second) { soElement(buffer, pi, first); } else { final int capacity = buffer.length(); - final AtomicReferenceArray newBuffer = new AtomicReferenceArray<>(capacity); + final AtomicReferenceArray newBuffer = new AtomicReferenceArray(capacity); producerBuffer = newBuffer; pi = calcWrappedOffset(p, m); diff --git a/src/main/java/io/reactivex/internal/schedulers/ComputationScheduler.java b/src/main/java/io/reactivex/internal/schedulers/ComputationScheduler.java index 3397de7ea1..2fcb8c2b8f 100644 --- a/src/main/java/io/reactivex/internal/schedulers/ComputationScheduler.java +++ b/src/main/java/io/reactivex/internal/schedulers/ComputationScheduler.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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. @@ -19,7 +19,7 @@ import java.util.concurrent.atomic.AtomicReference; import io.reactivex.Scheduler; -import io.reactivex.disposables.Disposable; +import io.reactivex.disposables.*; import io.reactivex.internal.disposables.*; /** @@ -95,7 +95,7 @@ public void shutdown() { * count and using least-recent worker selection policy. */ public ComputationScheduler() { - this.pool = new AtomicReference<>(NONE); + this.pool = new AtomicReference(NONE); start(); } @@ -149,9 +149,9 @@ private static class EventLoopWorker extends Scheduler.Worker { EventLoopWorker(PoolWorker poolWorker) { this.poolWorker = poolWorker; - this.serial = new ListCompositeResource<>(Disposable::dispose); - this.timed = new SetCompositeResource<>(Disposable::dispose); - this.both = new ArrayCompositeResource<>(2, Disposable::dispose); + this.serial = new ListCompositeResource(Disposables.consumeAndDispose()); + this.timed = new SetCompositeResource(Disposables.consumeAndDispose()); + this.both = new ArrayCompositeResource(2, Disposables.consumeAndDispose()); this.both.lazySet(0, serial); this.both.lazySet(1, timed); } diff --git a/src/main/java/io/reactivex/internal/schedulers/ExecutorScheduler.java b/src/main/java/io/reactivex/internal/schedulers/ExecutorScheduler.java index 4b03f311e3..222fb4b823 100644 --- a/src/main/java/io/reactivex/internal/schedulers/ExecutorScheduler.java +++ b/src/main/java/io/reactivex/internal/schedulers/ExecutorScheduler.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -18,7 +18,7 @@ import java.util.concurrent.atomic.*; import io.reactivex.Scheduler; -import io.reactivex.disposables.Disposable; +import io.reactivex.disposables.*; import io.reactivex.internal.disposables.*; import io.reactivex.internal.queue.MpscLinkedQueue; import io.reactivex.internal.schedulers.ExecutorScheduler.ExecutorWorker.BooleanRunnable; @@ -46,7 +46,7 @@ public Disposable scheduleDirect(Runnable run) { try { if (executor instanceof ExecutorService) { Future f = ((ExecutorService)executor).submit(decoratedRun); - return () -> f.cancel(true); + return Disposables.from(f); } BooleanRunnable br = new BooleanRunnable(decoratedRun); @@ -60,22 +60,25 @@ public Disposable scheduleDirect(Runnable run) { @Override public Disposable scheduleDirect(Runnable run, long delay, TimeUnit unit) { - Runnable decoratedRun = RxJavaPlugins.onSchedule(run); + final Runnable decoratedRun = RxJavaPlugins.onSchedule(run); if (executor instanceof ScheduledExecutorService) { try { Future f = ((ScheduledExecutorService)executor).schedule(decoratedRun, delay, unit); - return () -> f.cancel(true); + return Disposables.from(f); } catch (RejectedExecutionException ex) { RxJavaPlugins.onError(ex); return EmptyDisposable.INSTANCE; } } - MultipleAssignmentResource first = new MultipleAssignmentResource<>(Disposable::dispose); + MultipleAssignmentResource first = new MultipleAssignmentResource(Disposables.consumeAndDispose()); - MultipleAssignmentResource mar = new MultipleAssignmentResource<>(Disposable::dispose, first); + final MultipleAssignmentResource mar = new MultipleAssignmentResource(Disposables.consumeAndDispose(), first); - Disposable delayed = HELPER.scheduleDirect(() -> { - mar.setResource(scheduleDirect(decoratedRun)); + Disposable delayed = HELPER.scheduleDirect(new Runnable() { + @Override + public void run() { + mar.setResource(scheduleDirect(decoratedRun)); + } }, delay, unit); first.setResource(delayed); @@ -89,7 +92,7 @@ public Disposable schedulePeriodicallyDirect(Runnable run, long initialDelay, lo Runnable decoratedRun = RxJavaPlugins.onSchedule(run); try { Future f = ((ScheduledExecutorService)executor).scheduleAtFixedRate(decoratedRun, initialDelay, period, unit); - return () -> f.cancel(true); + return Disposables.from(f); } catch (RejectedExecutionException ex) { RxJavaPlugins.onError(ex); return EmptyDisposable.INSTANCE; @@ -105,15 +108,13 @@ public static final class ExecutorWorker extends Scheduler.Worker implements Run volatile boolean disposed; - volatile int wip; - static final AtomicIntegerFieldUpdater WIP = - AtomicIntegerFieldUpdater.newUpdater(ExecutorWorker.class, "wip"); + final AtomicInteger wip = new AtomicInteger(); - final SetCompositeResource tasks = new SetCompositeResource<>(Disposable::dispose); + final SetCompositeResource tasks = new SetCompositeResource(Disposables.consumeAndDispose()); public ExecutorWorker(Executor executor) { this.executor = executor; - this.queue = new MpscLinkedQueue<>(); + this.queue = new MpscLinkedQueue(); } @Override @@ -127,7 +128,7 @@ public Disposable schedule(Runnable run) { queue.offer(br); - if (WIP.getAndIncrement(this) == 0) { + if (wip.getAndIncrement() == 0) { try { executor.execute(this); } catch (RejectedExecutionException ex) { @@ -151,14 +152,17 @@ public Disposable schedule(Runnable run, long delay, TimeUnit unit) { } - MultipleAssignmentResource first = new MultipleAssignmentResource<>(Disposable::dispose); + MultipleAssignmentResource first = new MultipleAssignmentResource(Disposables.consumeAndDispose()); - MultipleAssignmentResource mar = new MultipleAssignmentResource<>(Disposable::dispose, first); + final MultipleAssignmentResource mar = new MultipleAssignmentResource(Disposables.consumeAndDispose(), first); - Runnable decoratedRun = RxJavaPlugins.onSchedule(run); + final Runnable decoratedRun = RxJavaPlugins.onSchedule(run); - ScheduledRunnable sr = new ScheduledRunnable(() -> { - mar.setResource(schedule(decoratedRun)); + ScheduledRunnable sr = new ScheduledRunnable(new Runnable() { + @Override + public void run() { + mar.setResource(schedule(decoratedRun)); + } }, tasks); tasks.add(sr); @@ -172,7 +176,7 @@ public Disposable schedule(Runnable run, long delay, TimeUnit unit) { return EmptyDisposable.INSTANCE; } } else { - Disposable d = HELPER.scheduleDirect(sr, delay, unit); + final Disposable d = HELPER.scheduleDirect(sr, delay, unit); sr.setFuture(new Future() { @Override public boolean cancel(boolean mayInterruptIfRunning) { @@ -214,7 +218,7 @@ public void dispose() { if (!disposed) { disposed = true; tasks.dispose(); - if (WIP.getAndIncrement(this) == 0) { + if (wip.getAndIncrement() == 0) { queue.clear(); } } @@ -249,7 +253,7 @@ public void run() { return; } - missed = WIP.addAndGet(this, -missed); + missed = wip.addAndGet(-missed); if (missed == 0) { break; } diff --git a/src/main/java/io/reactivex/internal/schedulers/IOScheduler.java b/src/main/java/io/reactivex/internal/schedulers/IOScheduler.java index 72541f1c03..0e69100360 100644 --- a/src/main/java/io/reactivex/internal/schedulers/IOScheduler.java +++ b/src/main/java/io/reactivex/internal/schedulers/IOScheduler.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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. @@ -20,7 +20,7 @@ import java.util.concurrent.atomic.*; import io.reactivex.Scheduler; -import io.reactivex.disposables.Disposable; +import io.reactivex.disposables.*; import io.reactivex.internal.disposables.*; import io.reactivex.plugins.RxJavaPlugins; @@ -54,14 +54,13 @@ private static final class CachedWorkerPool { CachedWorkerPool(long keepAliveTime, TimeUnit unit) { this.keepAliveTime = unit != null ? unit.toNanos(keepAliveTime) : 0L; - this.expiringWorkerQueue = new ConcurrentLinkedQueue<>(); - this.allWorkers = new SetCompositeResource<>(Disposable::dispose); + this.expiringWorkerQueue = new ConcurrentLinkedQueue(); + this.allWorkers = new SetCompositeResource(Disposables.consumeAndDispose()); ScheduledExecutorService evictor = null; Future task = null; if (unit != null) { evictor = Executors.newScheduledThreadPool(1, EVICTOR_THREAD_FACTORY); - ((ScheduledThreadPoolExecutor)evictor).setRemoveOnCancelPolicy(true); try { task = evictor.scheduleWithFixedDelay( new Runnable() { @@ -148,7 +147,7 @@ void shutdown() { } public IOScheduler() { - this.pool = new AtomicReference<>(NONE); + this.pool = new AtomicReference(NONE); start(); } @@ -186,20 +185,18 @@ private static final class EventLoopWorker extends Scheduler.Worker { private final SetCompositeResource tasks; private final CachedWorkerPool pool; private final ThreadWorker threadWorker; - @SuppressWarnings("unused") - volatile int once; - static final AtomicIntegerFieldUpdater ONCE_UPDATER - = AtomicIntegerFieldUpdater.newUpdater(EventLoopWorker.class, "once"); + + final AtomicBoolean once = new AtomicBoolean(); EventLoopWorker(CachedWorkerPool pool) { this.pool = pool; - this.tasks = new SetCompositeResource<>(Disposable::dispose); + this.tasks = new SetCompositeResource(Disposables.consumeAndDispose()); this.threadWorker = pool.get(); } @Override public void dispose() { - if (ONCE_UPDATER.compareAndSet(this, 0, 1)) { + if (once.compareAndSet(false, true)) { tasks.dispose(); // releasing the pool should be the last action diff --git a/src/main/java/io/reactivex/internal/schedulers/NewThreadScheduler.java b/src/main/java/io/reactivex/internal/schedulers/NewThreadScheduler.java index fc1742ba4f..9f34fe88ba 100644 --- a/src/main/java/io/reactivex/internal/schedulers/NewThreadScheduler.java +++ b/src/main/java/io/reactivex/internal/schedulers/NewThreadScheduler.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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. diff --git a/src/main/java/io/reactivex/internal/schedulers/NewThreadWorker.java b/src/main/java/io/reactivex/internal/schedulers/NewThreadWorker.java index 8f032748b6..dbf5b38d1b 100644 --- a/src/main/java/io/reactivex/internal/schedulers/NewThreadWorker.java +++ b/src/main/java/io/reactivex/internal/schedulers/NewThreadWorker.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -16,7 +16,7 @@ import java.util.concurrent.*; import io.reactivex.Scheduler; -import io.reactivex.disposables.Disposable; +import io.reactivex.disposables.*; import io.reactivex.internal.disposables.*; import io.reactivex.plugins.RxJavaPlugins; @@ -30,13 +30,8 @@ public class NewThreadWorker extends Scheduler.Worker implements Disposable { volatile boolean disposed; - /* package */ public NewThreadWorker(ThreadFactory threadFactory) { - ScheduledExecutorService exec = Executors.newScheduledThreadPool(1, threadFactory); - // Java 7+: cancelled future tasks can be removed from the executor thus avoiding memory leak - if (exec instanceof ScheduledThreadPoolExecutor) { - ((ScheduledThreadPoolExecutor)exec).setRemoveOnCancelPolicy(true); - } + ScheduledExecutorService exec = SchedulerPoolFactory.create(threadFactory); executor = exec; } @@ -59,7 +54,7 @@ public Disposable schedule(final Runnable action, long delayTime, TimeUnit unit) * @param run * @param delayTime * @param unit - * @return + * @return the ScheduledRunnable instance */ public Disposable scheduleDirect(final Runnable run, long delayTime, TimeUnit unit) { Runnable decoratedRun = RxJavaPlugins.onSchedule(run); @@ -70,7 +65,7 @@ public Disposable scheduleDirect(final Runnable run, long delayTime, TimeUnit un } else { f = executor.schedule(decoratedRun, delayTime, unit); } - return () -> f.cancel(true); + return Disposables.from(f); } catch (RejectedExecutionException ex) { RxJavaPlugins.onError(ex); return EmptyDisposable.INSTANCE; @@ -84,13 +79,13 @@ public Disposable scheduleDirect(final Runnable run, long delayTime, TimeUnit un * @param initialDelay * @param period * @param unit - * @return + * @return the ScheduledRunnable instance */ public Disposable schedulePeriodicallyDirect(final Runnable run, long initialDelay, long period, TimeUnit unit) { Runnable decoratedRun = RxJavaPlugins.onSchedule(run); try { Future f = executor.scheduleAtFixedRate(decoratedRun, initialDelay, period, unit); - return () -> f.cancel(true); + return Disposables.from(f); } catch (RejectedExecutionException ex) { RxJavaPlugins.onError(ex); return EmptyDisposable.INSTANCE; @@ -103,10 +98,11 @@ public Disposable schedulePeriodicallyDirect(final Runnable run, long initialDel * on the underlying ScheduledExecutorService. *

If the schedule has been rejected, the ScheduledRunnable.wasScheduled will return * false. - * @param action - * @param delayTime - * @param unit - * @return + * @param run the runnable instance + * @param delayTime the time to delay the execution + * @param unit the time unit + * @param parent the optional tracker parent to add the created ScheduledRunnable instance to before it gets scheduled + * @return the ScheduledRunnable instance */ public ScheduledRunnable scheduleActual(final Runnable run, long delayTime, TimeUnit unit, CompositeResource parent) { Runnable decoratedRun = RxJavaPlugins.onSchedule(run); diff --git a/src/main/java/io/reactivex/internal/schedulers/RxThreadFactory.java b/src/main/java/io/reactivex/internal/schedulers/RxThreadFactory.java index 1173d2388a..d6a20b2541 100644 --- a/src/main/java/io/reactivex/internal/schedulers/RxThreadFactory.java +++ b/src/main/java/io/reactivex/internal/schedulers/RxThreadFactory.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -32,4 +32,9 @@ public Thread newThread(Runnable r) { t.setDaemon(true); return t; } + + @Override + public String toString() { + return "RxThreadFactory[" + prefix + "]"; + } } diff --git a/src/main/java/io/reactivex/internal/schedulers/ScheduledRunnable.java b/src/main/java/io/reactivex/internal/schedulers/ScheduledRunnable.java index 423378b1e0..426d6fc76c 100644 --- a/src/main/java/io/reactivex/internal/schedulers/ScheduledRunnable.java +++ b/src/main/java/io/reactivex/internal/schedulers/ScheduledRunnable.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -17,7 +17,7 @@ import java.util.concurrent.atomic.AtomicReferenceArray; import io.reactivex.disposables.Disposable; -import io.reactivex.internal.disposables.*; +import io.reactivex.internal.disposables.CompositeResource; import io.reactivex.plugins.RxJavaPlugins; public final class ScheduledRunnable extends AtomicReferenceArray implements Runnable, Disposable { diff --git a/src/main/java/io/reactivex/internal/schedulers/SchedulerLifecycle.java b/src/main/java/io/reactivex/internal/schedulers/SchedulerLifecycle.java index 9e022c339a..e83959cb9e 100644 --- a/src/main/java/io/reactivex/internal/schedulers/SchedulerLifecycle.java +++ b/src/main/java/io/reactivex/internal/schedulers/SchedulerLifecycle.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 diff --git a/src/main/java/io/reactivex/internal/schedulers/SchedulerPoolFactory.java b/src/main/java/io/reactivex/internal/schedulers/SchedulerPoolFactory.java new file mode 100644 index 0000000000..c0650603eb --- /dev/null +++ b/src/main/java/io/reactivex/internal/schedulers/SchedulerPoolFactory.java @@ -0,0 +1,128 @@ +/** + * 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.internal.schedulers; + +import java.util.*; +import java.util.concurrent.*; +import java.util.concurrent.atomic.AtomicReference; + +import io.reactivex.plugins.RxJavaPlugins; + +/** + * Manages the creating of ScheduledExecutorServices and sets up purging + */ +public enum SchedulerPoolFactory { + ; + + static final String PURGE_ENABLED_KEY = "rx2.purge-enabled"; + + /** + * Indicates the periodic purging of the ScheduledExecutorService is enabled. + */ + public static final boolean PURGE_ENABLED; + + static final String PURGE_PERIOD_SECONDS_KEY = "rx2.purge-period-seconds"; + + /** + * Indicates the purge period of the ScheduledExecutorServices created by create(). + */ + public static final int PURGE_PERIOD_SECONDS; + + static final AtomicReference PURGE_THREAD = + new AtomicReference(); + + static final ConcurrentHashMap POOLS = + new ConcurrentHashMap(); + + /** + * Starts the purge thread if not already started. + */ + public static void start() { + for (;;) { + ScheduledExecutorService curr = PURGE_THREAD.get(); + if (curr != null && !curr.isShutdown()) { + return; + } + ScheduledExecutorService next = Executors.newScheduledThreadPool(1, new RxThreadFactory("RxSchedulerPurge-")); + if (PURGE_THREAD.compareAndSet(curr, next)) { + + next.scheduleAtFixedRate(new Runnable() { + @Override + public void run() { + try { + for (ScheduledThreadPoolExecutor e : new ArrayList(POOLS.keySet())) { + if (e.isShutdown()) { + POOLS.remove(e); + } else { + e.purge(); + } + } + } catch (Throwable e) { + RxJavaPlugins.onError(e); + } + } + }, PURGE_PERIOD_SECONDS, PURGE_PERIOD_SECONDS, TimeUnit.SECONDS); + + return; + } else { + next.shutdownNow(); + } + } + } + + /** + * Stops the purge thread. + */ + public static void shutdown() { + PURGE_THREAD.get().shutdownNow(); + POOLS.clear(); + } + + static { + boolean purgeEnable = true; + int purgePeriod = 1; + + Properties properties = System.getProperties(); + + if (properties.containsKey(PURGE_ENABLED_KEY)) { + purgeEnable = Boolean.getBoolean(PURGE_ENABLED_KEY); + + if (purgeEnable && properties.containsKey(PURGE_PERIOD_SECONDS_KEY)) { + purgePeriod = Integer.getInteger(PURGE_PERIOD_SECONDS_KEY, purgePeriod); + } + } + + PURGE_ENABLED = purgeEnable; + PURGE_PERIOD_SECONDS = purgePeriod; + + start(); + } + + /** + * Creates a ScheduledExecutorService with the given factory. + * @param factory the thread factory + * @return the ScheduledExecutorService + */ + public static ScheduledExecutorService create(ThreadFactory factory) { + final ScheduledExecutorService exec = Executors.newScheduledThreadPool(1, factory); + if (exec instanceof ScheduledThreadPoolExecutor) { + ScheduledThreadPoolExecutor e = (ScheduledThreadPoolExecutor) exec; + POOLS.put(e, exec); + } + return exec; + } +} diff --git a/src/main/java/io/reactivex/internal/schedulers/SingleScheduler.java b/src/main/java/io/reactivex/internal/schedulers/SingleScheduler.java index 26af80ce93..2d7252889b 100644 --- a/src/main/java/io/reactivex/internal/schedulers/SingleScheduler.java +++ b/src/main/java/io/reactivex/internal/schedulers/SingleScheduler.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,19 +13,16 @@ package io.reactivex.internal.schedulers; import java.util.concurrent.*; -import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; +import java.util.concurrent.atomic.AtomicReference; import io.reactivex.Scheduler; -import io.reactivex.disposables.Disposable; +import io.reactivex.disposables.*; import io.reactivex.internal.disposables.*; import io.reactivex.plugins.RxJavaPlugins; public final class SingleScheduler extends Scheduler { - volatile ScheduledExecutorService executor; - - static final AtomicReferenceFieldUpdater EXECUTOR = - AtomicReferenceFieldUpdater.newUpdater(SingleScheduler.class, ScheduledExecutorService.class, "executor"); + final AtomicReference executor = new AtomicReference(); static final ScheduledExecutorService SHUTDOWN; static { @@ -34,12 +31,11 @@ public final class SingleScheduler extends Scheduler { } public SingleScheduler() { - executor = createExecutor(); + executor.lazySet(createExecutor()); } static ScheduledExecutorService createExecutor() { - ScheduledExecutorService exec = Executors.newScheduledThreadPool(1, new RxThreadFactory("RxSingleScheduler-")); - ((ScheduledThreadPoolExecutor)exec).setRemoveOnCancelPolicy(true); + ScheduledExecutorService exec = SchedulerPoolFactory.create(new RxThreadFactory("RxSingleScheduler-")); return exec; } @@ -47,7 +43,7 @@ static ScheduledExecutorService createExecutor() { public void start() { ScheduledExecutorService next = null; for (;;) { - ScheduledExecutorService current = executor; + ScheduledExecutorService current = executor.get(); if (current != SHUTDOWN) { if (next != null) { next.shutdown(); @@ -57,7 +53,7 @@ public void start() { if (next == null) { next = createExecutor(); } - if (EXECUTOR.compareAndSet(this, current, next)) { + if (executor.compareAndSet(current, next)) { return; } @@ -66,9 +62,9 @@ public void start() { @Override public void shutdown() { - ScheduledExecutorService current = executor; + ScheduledExecutorService current = executor.get(); if (current != SHUTDOWN) { - current = EXECUTOR.getAndSet(this, SHUTDOWN); + current = executor.getAndSet(SHUTDOWN); if (current != SHUTDOWN) { current.shutdownNow(); } @@ -77,7 +73,7 @@ public void shutdown() { @Override public Worker createWorker() { - return new ScheduledWorker(executor); + return new ScheduledWorker(executor.get()); } @Override @@ -86,11 +82,11 @@ public Disposable scheduleDirect(Runnable run, long delay, TimeUnit unit) { try { Future f; if (delay <= 0L) { - f = executor.submit(decoratedRun); + f = executor.get().submit(decoratedRun); } else { - f = executor.schedule(decoratedRun, delay, unit); + f = executor.get().schedule(decoratedRun, delay, unit); } - return () -> f.cancel(true); + return Disposables.from(f); } catch (RejectedExecutionException ex) { RxJavaPlugins.onError(ex); return EmptyDisposable.INSTANCE; @@ -101,8 +97,8 @@ public Disposable scheduleDirect(Runnable run, long delay, TimeUnit unit) { public Disposable schedulePeriodicallyDirect(Runnable run, long initialDelay, long period, TimeUnit unit) { Runnable decoratedRun = RxJavaPlugins.onSchedule(run); try { - Future f = executor.scheduleAtFixedRate(decoratedRun, initialDelay, period, unit); - return () -> f.cancel(true); + Future f = executor.get().scheduleAtFixedRate(decoratedRun, initialDelay, period, unit); + return Disposables.from(f); } catch (RejectedExecutionException ex) { RxJavaPlugins.onError(ex); return EmptyDisposable.INSTANCE; @@ -119,7 +115,7 @@ static final class ScheduledWorker extends Scheduler.Worker { public ScheduledWorker(ScheduledExecutorService executor) { this.executor = executor; - this.tasks = new SetCompositeResource<>(Disposable::dispose); + this.tasks = new SetCompositeResource(Disposables.consumeAndDispose()); } @Override diff --git a/src/main/java/io/reactivex/internal/schedulers/TrampolineScheduler.java b/src/main/java/io/reactivex/internal/schedulers/TrampolineScheduler.java index c5f7ac4754..944c2618e7 100644 --- a/src/main/java/io/reactivex/internal/schedulers/TrampolineScheduler.java +++ b/src/main/java/io/reactivex/internal/schedulers/TrampolineScheduler.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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. @@ -22,6 +22,7 @@ import io.reactivex.Scheduler; import io.reactivex.disposables.Disposable; import io.reactivex.internal.disposables.EmptyDisposable; +import io.reactivex.internal.functions.Objects; import io.reactivex.plugins.RxJavaPlugins; /** @@ -61,12 +62,11 @@ public Disposable scheduleDirect(Runnable run, long delay, TimeUnit unit) { } static final class TrampolineWorker extends Scheduler.Worker implements Disposable { - private final PriorityBlockingQueue queue = new PriorityBlockingQueue<>(); + private final PriorityBlockingQueue queue = new PriorityBlockingQueue(); private final AtomicInteger wip = new AtomicInteger(); - volatile int counter; - private static final AtomicIntegerFieldUpdater COUNTER_UPDATER = AtomicIntegerFieldUpdater.newUpdater(TrampolineWorker.class, "counter"); + final AtomicInteger counter = new AtomicInteger(); volatile boolean disposed; @@ -86,7 +86,7 @@ private Disposable enqueue(Runnable action, long execTime) { if (disposed) { return EmptyDisposable.INSTANCE; } - final TimedRunnable timedRunnable = new TimedRunnable(action, execTime, COUNTER_UPDATER.incrementAndGet(this)); + final TimedRunnable timedRunnable = new TimedRunnable(action, execTime, counter.incrementAndGet()); queue.add(timedRunnable); if (wip.getAndIncrement() == 0) { @@ -110,9 +110,12 @@ private Disposable enqueue(Runnable action, long execTime) { return EmptyDisposable.INSTANCE; } else { // queue wasn't empty, a parent is already processing so we just add to the end of the queue - return () -> { - timedRunnable.disposed = true; - queue.remove(timedRunnable); + return new Disposable() { + @Override + public void dispose() { + timedRunnable.disposed = true; + queue.remove(timedRunnable); + } }; } } @@ -138,9 +141,9 @@ private TimedRunnable(Runnable run, Long execTime, int count) { @Override public int compareTo(TimedRunnable that) { - int result = Long.compare(execTime, that.execTime); + int result = Objects.compare(execTime, that.execTime); if (result == 0) { - return Integer.compare(count, that.count); + return Objects.compare(count, that.count); } return result; } diff --git a/src/main/java/io/reactivex/internal/subscribers/BlockingSubscriber.java b/src/main/java/io/reactivex/internal/subscribers/BlockingSubscriber.java index 1ab9a47667..4c62f5ef3c 100644 --- a/src/main/java/io/reactivex/internal/subscribers/BlockingSubscriber.java +++ b/src/main/java/io/reactivex/internal/subscribers/BlockingSubscriber.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -18,7 +18,6 @@ import org.reactivestreams.*; -import io.reactivex.Notification; import io.reactivex.internal.util.NotificationLite; public final class BlockingSubscriber extends AtomicReference implements Subscriber, Subscription { @@ -69,7 +68,7 @@ public void onError(Throwable t) { @Override public void onComplete() { - queue.offer(Notification.complete()); + queue.offer(NotificationLite.complete()); } @Override diff --git a/src/main/java/io/reactivex/internal/subscribers/CancelledSubscriber.java b/src/main/java/io/reactivex/internal/subscribers/CancelledSubscriber.java index b85f0054e4..63cd11ff60 100644 --- a/src/main/java/io/reactivex/internal/subscribers/CancelledSubscriber.java +++ b/src/main/java/io/reactivex/internal/subscribers/CancelledSubscriber.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 diff --git a/src/main/java/io/reactivex/internal/subscribers/ConditionalSubscriber.java b/src/main/java/io/reactivex/internal/subscribers/ConditionalSubscriber.java index 976966310d..dcfc37fd19 100644 --- a/src/main/java/io/reactivex/internal/subscribers/ConditionalSubscriber.java +++ b/src/main/java/io/reactivex/internal/subscribers/ConditionalSubscriber.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 diff --git a/src/main/java/io/reactivex/internal/subscribers/DisposableSubscriber.java b/src/main/java/io/reactivex/internal/subscribers/DisposableSubscriber.java index d3ad27816f..cb6adfcdc3 100644 --- a/src/main/java/io/reactivex/internal/subscribers/DisposableSubscriber.java +++ b/src/main/java/io/reactivex/internal/subscribers/DisposableSubscriber.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,7 +13,7 @@ package io.reactivex.internal.subscribers; -import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; +import java.util.concurrent.atomic.*; import org.reactivestreams.*; @@ -26,10 +26,7 @@ * @param */ public abstract class DisposableSubscriber implements Subscriber, Disposable { - volatile Subscription s; - @SuppressWarnings("rawtypes") - static final AtomicReferenceFieldUpdater S = - AtomicReferenceFieldUpdater.newUpdater(DisposableSubscriber.class, Subscription.class, "s"); + final AtomicReference s = new AtomicReference(); static final Subscription CANCELLED = new Subscription() { @Override @@ -45,9 +42,9 @@ public void cancel() { @Override public final void onSubscribe(Subscription s) { - if (!S.compareAndSet(this, null, s)) { + if (!this.s.compareAndSet(null, s)) { s.cancel(); - if (this.s != CANCELLED) { + if (this.s.get() != CANCELLED) { SubscriptionHelper.reportSubscriptionSet(); } return; @@ -56,15 +53,15 @@ public final void onSubscribe(Subscription s) { } protected final Subscription subscription() { - return s; + return s.get(); } protected void onStart() { - s.request(Long.MAX_VALUE); + s.get().request(Long.MAX_VALUE); } protected final void request(long n) { - s.request(n); + s.get().request(n); } protected final void cancel() { @@ -72,14 +69,14 @@ protected final void cancel() { } public final boolean isDisposed() { - return s == CANCELLED; + return s.get() == CANCELLED; } @Override public final void dispose() { - Subscription a = s; + Subscription a = s.get(); if (a != CANCELLED) { - a = S.getAndSet(this, CANCELLED); + a = s.getAndSet(CANCELLED); if (a != CANCELLED && a != null) { a.cancel(); } diff --git a/src/main/java/io/reactivex/internal/subscribers/EmptySubscriber.java b/src/main/java/io/reactivex/internal/subscribers/EmptySubscriber.java index 7527f7c6a9..b6a8b3b2c5 100644 --- a/src/main/java/io/reactivex/internal/subscribers/EmptySubscriber.java +++ b/src/main/java/io/reactivex/internal/subscribers/EmptySubscriber.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 diff --git a/src/main/java/io/reactivex/internal/subscribers/FullArbiterSubscriber.java b/src/main/java/io/reactivex/internal/subscribers/FullArbiterSubscriber.java index 6a4a8bca4f..19d5613344 100644 --- a/src/main/java/io/reactivex/internal/subscribers/FullArbiterSubscriber.java +++ b/src/main/java/io/reactivex/internal/subscribers/FullArbiterSubscriber.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 diff --git a/src/main/java/io/reactivex/internal/subscribers/LambdaSubscriber.java b/src/main/java/io/reactivex/internal/subscribers/LambdaSubscriber.java index c4d9f37649..c9372d4a5e 100644 --- a/src/main/java/io/reactivex/internal/subscribers/LambdaSubscriber.java +++ b/src/main/java/io/reactivex/internal/subscribers/LambdaSubscriber.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -14,11 +14,11 @@ package io.reactivex.internal.subscribers; import java.util.concurrent.atomic.AtomicReference; -import java.util.function.Consumer; import org.reactivestreams.*; import io.reactivex.disposables.Disposable; +import io.reactivex.functions.Consumer; import io.reactivex.plugins.RxJavaPlugins; public final class LambdaSubscriber extends AtomicReference implements Subscriber, Subscription, Disposable { @@ -68,8 +68,8 @@ public void onError(Throwable t) { try { onError.accept(t); } catch (Throwable e) { - e.addSuppressed(t); RxJavaPlugins.onError(e); + RxJavaPlugins.onError(t); } } diff --git a/src/main/java/io/reactivex/internal/subscribers/NbpFullArbiterSubscriber.java b/src/main/java/io/reactivex/internal/subscribers/NbpFullArbiterSubscriber.java index 238a13b263..675f293ca2 100644 --- a/src/main/java/io/reactivex/internal/subscribers/NbpFullArbiterSubscriber.java +++ b/src/main/java/io/reactivex/internal/subscribers/NbpFullArbiterSubscriber.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 diff --git a/src/main/java/io/reactivex/internal/subscribers/QueueDrainSubscriber.java b/src/main/java/io/reactivex/internal/subscribers/QueueDrainSubscriber.java index 7cb77b0995..75e61285bf 100644 --- a/src/main/java/io/reactivex/internal/subscribers/QueueDrainSubscriber.java +++ b/src/main/java/io/reactivex/internal/subscribers/QueueDrainSubscriber.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -56,19 +56,19 @@ public final boolean done() { @Override public final boolean enter() { - return WIP.getAndIncrement(this) == 0; + return wip.getAndIncrement() == 0; } public final boolean fastEnter() { - return wip == 0 && WIP.compareAndSet(this, 0, 1); + return wip.get() == 0 && wip.compareAndSet(0, 1); } protected final void fastpathEmit(U value, boolean delayError) { final Subscriber s = actual; final Queue q = queue; - if (wip == 0 && WIP.compareAndSet(this, 0, 1)) { - long r = requested; + if (wip.get() == 0 && wip.compareAndSet(0, 1)) { + long r = requested.get(); if (r != 0L) { if (accept(s, value)) { if (r != Long.MAX_VALUE) { @@ -86,15 +86,15 @@ protected final void fastpathEmit(U value, boolean delayError) { return; } } - drainLoop(q, s, delayError); + QueueDrainHelper.drainLoop(q, s, delayError, this); } protected final void fastpathEmitMax(U value, boolean delayError, Disposable dispose) { final Subscriber s = actual; final Queue q = queue; - if (wip == 0 && WIP.compareAndSet(this, 0, 1)) { - long r = requested; + if (wip.get() == 0 && wip.compareAndSet(0, 1)) { + long r = requested.get(); if (r != 0L) { if (accept(s, value)) { if (r != Long.MAX_VALUE) { @@ -115,15 +115,15 @@ protected final void fastpathEmitMax(U value, boolean delayError, Disposable dis return; } } - drainMaxLoop(q, s, delayError, dispose); + QueueDrainHelper.drainMaxLoop(q, s, delayError, dispose, this); } protected final void fastpathOrderedEmitMax(U value, boolean delayError, Disposable dispose) { final Subscriber s = actual; final Queue q = queue; - if (wip == 0 && WIP.compareAndSet(this, 0, 1)) { - long r = requested; + if (wip.get() == 0 && wip.compareAndSet(0, 1)) { + long r = requested.get(); if (r != 0L) { if (q.isEmpty()) { if (accept(s, value)) { @@ -149,7 +149,7 @@ protected final void fastpathOrderedEmitMax(U value, boolean delayError, Disposa return; } } - drainMaxLoop(q, s, delayError, dispose); + QueueDrainHelper.drainMaxLoop(q, s, delayError, dispose, this); } /** @@ -161,9 +161,9 @@ protected final void fastpathOrderedEmit(U value, boolean delayError) { final Subscriber s = actual; final Queue q = queue; - if (wip == 0 && WIP.compareAndSet(this, 0, 1)) { + if (wip.get() == 0 && wip.compareAndSet(0, 1)) { if (q.isEmpty()) { - long r = requested; + long r = requested.get(); if (r != 0L) { if (accept(s, value)) { if (r != Long.MAX_VALUE) { @@ -182,7 +182,7 @@ protected final void fastpathOrderedEmit(U value, boolean delayError) { return; } } - drainLoop(q, s, delayError); + QueueDrainHelper.drainLoop(q, s, delayError, this); } @Override @@ -192,29 +192,29 @@ public final Throwable error() { @Override public final int leave(int m) { - return WIP.addAndGet(this, m); + return wip.addAndGet(m); } @Override public final long requested() { - return requested; + return requested.get(); } @Override public final long produced(long n) { - return REQUESTED.addAndGet(this, -n); + return requested.addAndGet(-n); } public final void requested(long n) { if (SubscriptionHelper.validateRequest(n)) { return; } - BackpressureHelper.add(REQUESTED, this, n); + BackpressureHelper.add(requested, n); } public void drain(boolean delayError) { if (enter()) { - drainLoop(queue, actual, delayError); + QueueDrainHelper.drainLoop(queue, actual, delayError, this); } } } @@ -231,9 +231,7 @@ class QueueDrainSubscriberPad0 { /** The WIP counter. */ class QueueDrainSubscriberWip extends QueueDrainSubscriberPad0 { - volatile int wip; - static final AtomicIntegerFieldUpdater WIP = - AtomicIntegerFieldUpdater.newUpdater(QueueDrainSubscriberWip.class, "wip"); + final AtomicInteger wip = new AtomicInteger(); } /** Pads away the wip from the other fields. */ @@ -244,9 +242,7 @@ class QueueDrainSubscriberPad2 extends QueueDrainSubscriberWip { /** Contains the requested field. */ class QueueDrainSubscriberPad3 extends QueueDrainSubscriberPad2 { - volatile long requested; - static final AtomicLongFieldUpdater REQUESTED = - AtomicLongFieldUpdater.newUpdater(QueueDrainSubscriberPad3.class, "requested"); + final AtomicLong requested = new AtomicLong(); } /** Pads away the requested from the other fields. */ diff --git a/src/main/java/io/reactivex/internal/subscribers/SubscriptionLambdaSubscriber.java b/src/main/java/io/reactivex/internal/subscribers/SubscriptionLambdaSubscriber.java index f13438ac7f..33a0d744eb 100644 --- a/src/main/java/io/reactivex/internal/subscribers/SubscriptionLambdaSubscriber.java +++ b/src/main/java/io/reactivex/internal/subscribers/SubscriptionLambdaSubscriber.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,10 +13,9 @@ package io.reactivex.internal.subscribers; -import java.util.function.*; - import org.reactivestreams.*; +import io.reactivex.functions.*; import io.reactivex.internal.subscriptions.*; import io.reactivex.plugins.RxJavaPlugins; diff --git a/src/main/java/io/reactivex/internal/subscribers/ToNotificationSubscriber.java b/src/main/java/io/reactivex/internal/subscribers/ToNotificationSubscriber.java index 5c3ab04653..706dddec59 100644 --- a/src/main/java/io/reactivex/internal/subscribers/ToNotificationSubscriber.java +++ b/src/main/java/io/reactivex/internal/subscribers/ToNotificationSubscriber.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,12 +13,10 @@ package io.reactivex.internal.subscribers; -import java.util.Optional; -import java.util.function.Consumer; - import org.reactivestreams.*; import io.reactivex.*; +import io.reactivex.functions.Consumer; import io.reactivex.internal.subscriptions.SubscriptionHelper; public final class ToNotificationSubscriber implements Subscriber { @@ -45,13 +43,13 @@ public void onNext(T t) { s.cancel(); onError(new NullPointerException()); } else { - consumer.accept(Try.ofValue(Optional.of(t))); + consumer.accept(Try.ofValue(Optional.of(t))); } } @Override public void onError(Throwable t) { - consumer.accept(Try.ofError(t)); + consumer.accept(Try.>ofError(t)); } @Override diff --git a/src/main/java/io/reactivex/internal/subscribers/nbp/NbpBlockingSubscriber.java b/src/main/java/io/reactivex/internal/subscribers/nbp/NbpBlockingSubscriber.java index bdc49851b1..8ebf82ed3f 100644 --- a/src/main/java/io/reactivex/internal/subscribers/nbp/NbpBlockingSubscriber.java +++ b/src/main/java/io/reactivex/internal/subscribers/nbp/NbpBlockingSubscriber.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -16,8 +16,8 @@ import java.util.Queue; import java.util.concurrent.atomic.AtomicReference; -import io.reactivex.NbpObservable.NbpSubscriber; import io.reactivex.Notification; +import io.reactivex.NbpObservable.NbpSubscriber; import io.reactivex.disposables.Disposable; import io.reactivex.internal.util.NotificationLite; @@ -25,7 +25,10 @@ public final class NbpBlockingSubscriber extends AtomicReference /** */ private static final long serialVersionUID = -4875965440900746268L; - static final Disposable CANCELLED = () -> { }; + static final Disposable CANCELLED = new Disposable() { + @Override + public void dispose() { } + }; public static final Object TERMINATED = new Object(); diff --git a/src/main/java/io/reactivex/internal/subscribers/nbp/NbpCancelledSubscriber.java b/src/main/java/io/reactivex/internal/subscribers/nbp/NbpCancelledSubscriber.java index aa54610f74..f1a4658468 100644 --- a/src/main/java/io/reactivex/internal/subscribers/nbp/NbpCancelledSubscriber.java +++ b/src/main/java/io/reactivex/internal/subscribers/nbp/NbpCancelledSubscriber.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 diff --git a/src/main/java/io/reactivex/internal/subscribers/nbp/NbpConditionalSubscriber.java b/src/main/java/io/reactivex/internal/subscribers/nbp/NbpConditionalSubscriber.java index 33c8cb75fc..0bebcac1df 100644 --- a/src/main/java/io/reactivex/internal/subscribers/nbp/NbpConditionalSubscriber.java +++ b/src/main/java/io/reactivex/internal/subscribers/nbp/NbpConditionalSubscriber.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 diff --git a/src/main/java/io/reactivex/internal/subscribers/nbp/NbpDisposableSubscriber.java b/src/main/java/io/reactivex/internal/subscribers/nbp/NbpDisposableSubscriber.java index bacdb4f18e..19978e24ee 100644 --- a/src/main/java/io/reactivex/internal/subscribers/nbp/NbpDisposableSubscriber.java +++ b/src/main/java/io/reactivex/internal/subscribers/nbp/NbpDisposableSubscriber.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,7 +13,7 @@ package io.reactivex.internal.subscribers.nbp; -import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; +import java.util.concurrent.atomic.AtomicReference; import io.reactivex.NbpObservable.NbpSubscriber; import io.reactivex.disposables.Disposable; @@ -25,18 +25,18 @@ * @param */ public abstract class NbpDisposableSubscriber implements NbpSubscriber, Disposable { - volatile Disposable s; - @SuppressWarnings("rawtypes") - static final AtomicReferenceFieldUpdater S = - AtomicReferenceFieldUpdater.newUpdater(NbpDisposableSubscriber.class, Disposable.class, "s"); + final AtomicReference s = new AtomicReference(); - static final Disposable CANCELLED = () -> { }; + static final Disposable CANCELLED = new Disposable() { + @Override + public void dispose() { } + }; @Override public final void onSubscribe(Disposable s) { - if (!S.compareAndSet(this, null, s)) { + if (!this.s.compareAndSet(null, s)) { s.dispose(); - if (this.s != CANCELLED) { + if (this.s.get() != CANCELLED) { SubscriptionHelper.reportSubscriptionSet(); } return; @@ -53,9 +53,9 @@ public final boolean isDisposed() { @Override public final void dispose() { - Disposable a = s; + Disposable a = s.get(); if (a != CANCELLED) { - a = S.getAndSet(this, CANCELLED); + a = s.getAndSet(CANCELLED); if (a != CANCELLED && a != null) { a.dispose(); } diff --git a/src/main/java/io/reactivex/internal/subscribers/nbp/NbpEmptySubscriber.java b/src/main/java/io/reactivex/internal/subscribers/nbp/NbpEmptySubscriber.java index 646874fa0a..20461ed4a3 100644 --- a/src/main/java/io/reactivex/internal/subscribers/nbp/NbpEmptySubscriber.java +++ b/src/main/java/io/reactivex/internal/subscribers/nbp/NbpEmptySubscriber.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 diff --git a/src/main/java/io/reactivex/internal/subscribers/nbp/NbpLambdaSubscriber.java b/src/main/java/io/reactivex/internal/subscribers/nbp/NbpLambdaSubscriber.java index fb03a41761..dc20060b84 100644 --- a/src/main/java/io/reactivex/internal/subscribers/nbp/NbpLambdaSubscriber.java +++ b/src/main/java/io/reactivex/internal/subscribers/nbp/NbpLambdaSubscriber.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -14,10 +14,10 @@ package io.reactivex.internal.subscribers.nbp; import java.util.concurrent.atomic.AtomicReference; -import java.util.function.Consumer; import io.reactivex.NbpObservable.NbpSubscriber; import io.reactivex.disposables.Disposable; +import io.reactivex.functions.Consumer; import io.reactivex.internal.subscriptions.SubscriptionHelper; import io.reactivex.plugins.RxJavaPlugins; @@ -29,7 +29,10 @@ public final class NbpLambdaSubscriber extends AtomicReference im final Runnable onComplete; final Consumer onSubscribe; - static final Disposable CANCELLED = () -> { }; + static final Disposable CANCELLED = new Disposable() { + @Override + public void dispose() { } + }; public NbpLambdaSubscriber(Consumer onNext, Consumer onError, Runnable onComplete, @@ -68,8 +71,8 @@ public void onError(Throwable t) { try { onError.accept(t); } catch (Throwable e) { - e.addSuppressed(t); RxJavaPlugins.onError(e); + RxJavaPlugins.onError(t); } } diff --git a/src/main/java/io/reactivex/internal/subscribers/nbp/NbpQueueDrainSubscriber.java b/src/main/java/io/reactivex/internal/subscribers/nbp/NbpQueueDrainSubscriber.java index 0650f60863..6942b9c72c 100644 --- a/src/main/java/io/reactivex/internal/subscribers/nbp/NbpQueueDrainSubscriber.java +++ b/src/main/java/io/reactivex/internal/subscribers/nbp/NbpQueueDrainSubscriber.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -14,11 +14,11 @@ package io.reactivex.internal.subscribers.nbp; import java.util.Queue; -import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; +import java.util.concurrent.atomic.AtomicInteger; import io.reactivex.NbpObservable.NbpSubscriber; import io.reactivex.disposables.Disposable; -import io.reactivex.internal.util.NbpQueueDrain; +import io.reactivex.internal.util.*; /** * Abstract base class for subscribers that hold another subscriber, a queue @@ -54,18 +54,18 @@ public final boolean done() { @Override public final boolean enter() { - return WIP.getAndIncrement(this) == 0; + return wip.getAndIncrement() == 0; } public final boolean fastEnter() { - return wip == 0 && WIP.compareAndSet(this, 0, 1); + return wip.get() == 0 && wip.compareAndSet(0, 1); } protected final void fastpathEmit(U value, boolean delayError, Disposable dispose) { final NbpSubscriber s = actual; final Queue q = queue; - if (wip == 0 && WIP.compareAndSet(this, 0, 1)) { + if (wip.get() == 0 && wip.compareAndSet(0, 1)) { accept(s, value); if (leave(-1) == 0) { return; @@ -76,7 +76,7 @@ protected final void fastpathEmit(U value, boolean delayError, Disposable dispos return; } } - drainLoop(q, s, delayError, dispose); + QueueDrainHelper.drainLoop(q, s, delayError, dispose, this); } /** @@ -88,7 +88,7 @@ protected final void fastpathOrderedEmit(U value, boolean delayError, Disposable final NbpSubscriber s = actual; final Queue q = queue; - if (wip == 0 && WIP.compareAndSet(this, 0, 1)) { + if (wip.get() == 0 && wip.compareAndSet(0, 1)) { if (q.isEmpty()) { accept(s, value); if (leave(-1) == 0) { @@ -103,7 +103,7 @@ protected final void fastpathOrderedEmit(U value, boolean delayError, Disposable return; } } - drainLoop(q, s, delayError, disposable); + QueueDrainHelper.drainLoop(q, s, delayError, disposable, this); } @Override @@ -113,12 +113,12 @@ public final Throwable error() { @Override public final int leave(int m) { - return WIP.addAndGet(this, m); + return wip.addAndGet(m); } public void drain(boolean delayError, Disposable dispose) { if (enter()) { - drainLoop(queue, actual, delayError, dispose); + QueueDrainHelper.drainLoop(queue, actual, delayError, dispose, this); } } } @@ -133,11 +133,9 @@ class QueueDrainSubscriberPad0 { volatile long p8, p9, p10, p11, p12, p13, p14, p15; } -/** The WIP counter. */ +/** The wip counter. */ class QueueDrainSubscriberWip extends QueueDrainSubscriberPad0 { - volatile int wip; - static final AtomicIntegerFieldUpdater WIP = - AtomicIntegerFieldUpdater.newUpdater(QueueDrainSubscriberWip.class, "wip"); + final AtomicInteger wip = new AtomicInteger(); } /** Pads away the wip from the other fields. */ diff --git a/src/main/java/io/reactivex/internal/subscribers/nbp/NbpSubscriptionLambdaSubscriber.java b/src/main/java/io/reactivex/internal/subscribers/nbp/NbpSubscriptionLambdaSubscriber.java index d5bd478701..1add5bb72a 100644 --- a/src/main/java/io/reactivex/internal/subscribers/nbp/NbpSubscriptionLambdaSubscriber.java +++ b/src/main/java/io/reactivex/internal/subscribers/nbp/NbpSubscriptionLambdaSubscriber.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,10 +13,9 @@ package io.reactivex.internal.subscribers.nbp; -import java.util.function.*; - import io.reactivex.NbpObservable.NbpSubscriber; import io.reactivex.disposables.Disposable; +import io.reactivex.functions.Consumer; import io.reactivex.internal.disposables.EmptyDisposable; import io.reactivex.internal.subscriptions.SubscriptionHelper; import io.reactivex.plugins.RxJavaPlugins; diff --git a/src/main/java/io/reactivex/internal/subscribers/nbp/NbpToNotificationSubscriber.java b/src/main/java/io/reactivex/internal/subscribers/nbp/NbpToNotificationSubscriber.java index 7788ed5cad..0adef75192 100644 --- a/src/main/java/io/reactivex/internal/subscribers/nbp/NbpToNotificationSubscriber.java +++ b/src/main/java/io/reactivex/internal/subscribers/nbp/NbpToNotificationSubscriber.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,12 +13,10 @@ package io.reactivex.internal.subscribers.nbp; -import java.util.Optional; -import java.util.function.Consumer; - import io.reactivex.*; import io.reactivex.NbpObservable.NbpSubscriber; import io.reactivex.disposables.Disposable; +import io.reactivex.functions.Consumer; import io.reactivex.internal.subscriptions.SubscriptionHelper; public final class NbpToNotificationSubscriber implements NbpSubscriber { @@ -44,13 +42,13 @@ public void onNext(T t) { s.dispose(); onError(new NullPointerException()); } else { - consumer.accept(Try.ofValue(Optional.of(t))); + consumer.accept(Try.ofValue(Optional.of(t))); } } @Override public void onError(Throwable t) { - consumer.accept(Try.ofError(t)); + consumer.accept(Try.>ofError(t)); } @Override diff --git a/src/main/java/io/reactivex/internal/subscriptions/AsyncSubscription.java b/src/main/java/io/reactivex/internal/subscriptions/AsyncSubscription.java index fe8a0986d2..0bae5f22f3 100644 --- a/src/main/java/io/reactivex/internal/subscriptions/AsyncSubscription.java +++ b/src/main/java/io/reactivex/internal/subscriptions/AsyncSubscription.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -30,13 +30,9 @@ public final class AsyncSubscription extends AtomicLong implements Subscription, /** */ private static final long serialVersionUID = 7028635084060361255L; - volatile Subscription actual; - static final AtomicReferenceFieldUpdater ACTUAL = - AtomicReferenceFieldUpdater.newUpdater(AsyncSubscription.class, Subscription.class, "actual"); + final AtomicReference actual; - volatile Disposable resource; - static final AtomicReferenceFieldUpdater RESOURCE = - AtomicReferenceFieldUpdater.newUpdater(AsyncSubscription.class, Disposable.class, "resource"); + final AtomicReference resource; static final Subscription CANCELLED = new Subscription() { @Override @@ -67,16 +63,18 @@ public String toString() { }; public AsyncSubscription() { - + resource = new AtomicReference(); + actual = new AtomicReference(); } public AsyncSubscription(Disposable resource) { - RESOURCE.lazySet(this, resource); + this(); + this.resource.lazySet(resource); } @Override public void request(long n) { - Subscription s = actual; + Subscription s = actual.get(); if (s != null) { s.request(n); } else { @@ -84,7 +82,7 @@ public void request(long n) { return; } BackpressureHelper.add(this, n); - s = actual; + s = actual.get(); if (s != null) { long mr = getAndSet(0L); if (mr != 0L) { @@ -96,17 +94,17 @@ public void request(long n) { @Override public void cancel() { - Subscription s = actual; + Subscription s = actual.get(); if (s != CANCELLED) { - s = ACTUAL.getAndSet(this, CANCELLED); + s = actual.getAndSet(CANCELLED); if (s != CANCELLED && s != null) { s.cancel(); } } - Disposable d = resource; + Disposable d = resource.get(); if (d != DISPOSED) { - d = RESOURCE.getAndSet(this, DISPOSED); + d = resource.getAndSet(DISPOSED); if (d != CANCELLED && d != null) { d.dispose(); } @@ -126,14 +124,14 @@ public void dispose() { */ public boolean setResource(Disposable r) { for (;;) { - Disposable d = resource; + Disposable d = resource.get(); if (d == DISPOSED) { if (r != null) { r.dispose(); } return false; } - if (RESOURCE.compareAndSet(this, d, r)) { + if (resource.compareAndSet(d, r)) { if (d != null) { d.dispose(); } @@ -149,14 +147,14 @@ public boolean setResource(Disposable r) { */ public boolean replaceResource(Disposable r) { for (;;) { - Disposable d = resource; + Disposable d = resource.get(); if (d == DISPOSED) { if (r != null) { r.dispose(); } return false; } - if (RESOURCE.compareAndSet(this, d, r)) { + if (resource.compareAndSet(d, r)) { return true; } } @@ -169,7 +167,7 @@ public boolean replaceResource(Disposable r) { */ public boolean setSubscription(Subscription s) { for (;;) { - Subscription a = actual; + Subscription a = actual.get(); if (a == CANCELLED) { s.cancel(); return false; @@ -179,7 +177,7 @@ public boolean setSubscription(Subscription s) { SubscriptionHelper.reportSubscriptionSet(); return true; } - if (ACTUAL.compareAndSet(this, null, s)) { + if (actual.compareAndSet(null, s)) { long mr = getAndSet(0L); if (mr != 0L) { s.request(mr); diff --git a/src/main/java/io/reactivex/internal/subscriptions/BooleanSubscription.java b/src/main/java/io/reactivex/internal/subscriptions/BooleanSubscription.java index 6902be8ebb..a6ae20c2e2 100644 --- a/src/main/java/io/reactivex/internal/subscriptions/BooleanSubscription.java +++ b/src/main/java/io/reactivex/internal/subscriptions/BooleanSubscription.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 diff --git a/src/main/java/io/reactivex/internal/subscriptions/DisposableSubscription.java b/src/main/java/io/reactivex/internal/subscriptions/DisposableSubscription.java new file mode 100644 index 0000000000..247f08003a --- /dev/null +++ b/src/main/java/io/reactivex/internal/subscriptions/DisposableSubscription.java @@ -0,0 +1,108 @@ +/** + * 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.internal.subscriptions; + +import java.util.concurrent.atomic.AtomicReference; + +import org.reactivestreams.Subscription; + +import io.reactivex.disposables.Disposable; + +/** + * Subscription that ignores (but validates) requests and delegates cancel to a disposable instance. + */ +public final class DisposableSubscription extends AtomicReference implements Subscription { + /** */ + private static final long serialVersionUID = -2358839743797425727L; + /** The disposed state indicator. */ + static final Disposable DISPOSED = new Disposable() { + @Override + public void dispose() { } + }; + + /** + * Constructs an empty DisposableSubscription. + */ + public DisposableSubscription() { + } + + /** + * Constructs a DisposableSubscription by wrapping the given Disposable. + * @param d the disposable to wrap, may be null + */ + public DisposableSubscription(Disposable d) { + this.lazySet(d); + } + + @Override + public void request(long n) { + if (SubscriptionHelper.validateRequest(n)) { + return; + } + } + + /** + * Sets a new disposable resource and disposes any old one. + * @param d the new disposable to set + * @return false if this Subscription has been cancelled + */ + public boolean setDisposable(Disposable d) { + for (;;) { + Disposable a = get(); + if (a == DISPOSED) { + if (d != null) { + d.dispose(); + } + return false; + } + if (compareAndSet(a, d)) { + if (a != null) { + a.dispose(); + } + return true; + } + } + } + + /** + * Replaces any existing disposable with a new disposable but doesn't dispose the old one. + * @param d the new disposable to set + * @return false if this disposable was disposed + */ + public boolean replaceDisposable(Disposable d) { + for (;;) { + Disposable a = get(); + if (a == DISPOSED) { + if (d != null) { + d.dispose(); + } + return false; + } + if (compareAndSet(a, d)) { + return true; + } + } + } + + @Override + public void cancel() { + Disposable d = get(); + if (d != DISPOSED) { + d = getAndSet(DISPOSED); + if (d != DISPOSED && d != null) { + d.dispose(); + } + } + } +} \ No newline at end of file diff --git a/src/main/java/io/reactivex/internal/subscriptions/EmptySubscription.java b/src/main/java/io/reactivex/internal/subscriptions/EmptySubscription.java index 7e524c7e8f..0770c7da8b 100644 --- a/src/main/java/io/reactivex/internal/subscriptions/EmptySubscription.java +++ b/src/main/java/io/reactivex/internal/subscriptions/EmptySubscription.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 diff --git a/src/main/java/io/reactivex/internal/subscriptions/FullArbiter.java b/src/main/java/io/reactivex/internal/subscriptions/FullArbiter.java index bd887469c7..add78d936d 100644 --- a/src/main/java/io/reactivex/internal/subscriptions/FullArbiter.java +++ b/src/main/java/io/reactivex/internal/subscriptions/FullArbiter.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -38,12 +38,11 @@ public final class FullArbiter extends FullArbiterPad2 implements Subscriptio static final Subscription INITIAL = new Subscription() { @Override public void request(long n) { - + // deliberately no op } @Override public void cancel() { - // TODO Auto-generated method stub - + // deliberately no op } }; @@ -57,7 +56,7 @@ public void cancel() { public FullArbiter(Subscriber actual, Disposable resource, int capacity) { this.actual = actual; this.resource = resource; - this.queue = new SpscLinkedArrayQueue<>(capacity); + this.queue = new SpscLinkedArrayQueue(capacity); this.s = INITIAL; } @@ -66,7 +65,7 @@ public void request(long n) { if (SubscriptionHelper.validateRequest(n)) { return; } - BackpressureHelper.add(MISSED_REQUESTED, this, n); + BackpressureHelper.add(missedRequested, n); queue.offer(REQUEST, REQUEST); drain(); } @@ -122,7 +121,7 @@ public void onComplete(Subscription s) { } void drain() { - if (WIP.getAndIncrement(this) != 0) { + if (wip.getAndIncrement() != 0) { return; } @@ -144,7 +143,7 @@ void drain() { Object v = q.poll(); if (o == REQUEST) { - long mr = MISSED_REQUESTED.getAndSet(this, 0L); + long mr = missedRequested.getAndSet(0L); if (mr != 0L) { requested = BackpressureHelper.addCap(requested, mr); if (s != null) { @@ -189,13 +188,13 @@ void drain() { } else { long r = requested; if (r != 0) { - a.onNext(NotificationLite.getValue(v)); + a.onNext(NotificationLite.getValue(v)); requested = r - 1; } } } - missed = WIP.addAndGet(this, -missed); + missed = wip.addAndGet(-missed); if (missed == 0) { break; } @@ -211,9 +210,7 @@ class FullArbiterPad0 { /** The work-in-progress counter. */ class FullArbiterWip extends FullArbiterPad0 { - volatile int wip; - static final AtomicIntegerFieldUpdater WIP = - AtomicIntegerFieldUpdater.newUpdater(FullArbiterWip.class, "wip"); + final AtomicInteger wip = new AtomicInteger(); } /** Pads the wip counter away. */ @@ -224,9 +221,7 @@ class FullArbiterPad1 extends FullArbiterWip { /** The missed request counter. */ class FullArbiterMissed extends FullArbiterPad1 { - volatile long missedRequested; - static final AtomicLongFieldUpdater MISSED_REQUESTED = - AtomicLongFieldUpdater.newUpdater(FullArbiterMissed.class, "missedRequested"); + final AtomicLong missedRequested = new AtomicLong(); } /** Pads the missed request counter away. */ diff --git a/src/main/java/io/reactivex/internal/subscriptions/ScalarAsyncSubscription.java b/src/main/java/io/reactivex/internal/subscriptions/ScalarAsyncSubscription.java index 3041a7d08d..ad9bbe1128 100644 --- a/src/main/java/io/reactivex/internal/subscriptions/ScalarAsyncSubscription.java +++ b/src/main/java/io/reactivex/internal/subscriptions/ScalarAsyncSubscription.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,15 +13,16 @@ package io.reactivex.internal.subscriptions; -import java.util.Objects; import java.util.concurrent.atomic.AtomicInteger; import org.reactivestreams.*; +import io.reactivex.internal.functions.Objects; import io.reactivex.plugins.RxJavaPlugins; /** - * + * A Subscription that coordinates the emission of a single value set asynchronously. + * @param the value type */ public final class ScalarAsyncSubscription extends AtomicInteger implements Subscription { /** */ @@ -66,7 +67,7 @@ public void request(long n) { } public void setValue(T v) { - Objects.requireNonNull(v); + Objects.requireNonNull(v, "v is null"); for (;;) { int state = get(); diff --git a/src/main/java/io/reactivex/internal/subscriptions/ScalarSubscription.java b/src/main/java/io/reactivex/internal/subscriptions/ScalarSubscription.java index 8c10c05662..fa34c6f9d9 100644 --- a/src/main/java/io/reactivex/internal/subscriptions/ScalarSubscription.java +++ b/src/main/java/io/reactivex/internal/subscriptions/ScalarSubscription.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -20,7 +20,8 @@ import io.reactivex.plugins.RxJavaPlugins; /** - * + * A Subscription that holds a constant value and emits it only when requested. + * @param the value type */ public final class ScalarSubscription extends AtomicBoolean implements Subscription { /** */ diff --git a/src/main/java/io/reactivex/internal/subscriptions/SubscriptionArbiter.java b/src/main/java/io/reactivex/internal/subscriptions/SubscriptionArbiter.java index cc1a9860e1..95922f021d 100644 --- a/src/main/java/io/reactivex/internal/subscriptions/SubscriptionArbiter.java +++ b/src/main/java/io/reactivex/internal/subscriptions/SubscriptionArbiter.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,7 +13,7 @@ package io.reactivex.internal.subscriptions; /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -25,13 +25,14 @@ * the License for the specific language governing permissions and limitations under the License. */ -import java.util.*; +import java.util.Queue; import java.util.concurrent.atomic.*; import org.reactivestreams.Subscription; +import io.reactivex.internal.functions.Objects; import io.reactivex.internal.queue.MpscLinkedQueue; -import io.reactivex.internal.util.*; +import io.reactivex.internal.util.BackpressureHelper; import io.reactivex.plugins.RxJavaPlugins; /** @@ -41,20 +42,16 @@ public final class SubscriptionArbiter extends AtomicInteger implements Subscrip /** */ private static final long serialVersionUID = -2189523197179400958L; - final Queue missedSubscription = new MpscLinkedQueue<>(); + final Queue missedSubscription = new MpscLinkedQueue(); Subscription actual; long requested; volatile boolean cancelled; - volatile long missedRequested; - static final AtomicLongFieldUpdater MISSED_REQUESTED = - AtomicLongFieldUpdater.newUpdater(SubscriptionArbiter.class, "missedRequested"); + final AtomicLong missedRequested = new AtomicLong(); - volatile long missedProduced; - static final AtomicLongFieldUpdater MISSED_PRODUCED = - AtomicLongFieldUpdater.newUpdater(SubscriptionArbiter.class, "missedProduced"); + final AtomicLong missedProduced = new AtomicLong(); private long addRequested(long n) { long r = requested; @@ -64,52 +61,84 @@ private long addRequested(long n) { } @Override - public void request(long n) { + public void request(final long n) { if (SubscriptionHelper.validateRequest(n)) { return; } if (cancelled) { return; } - QueueDrainHelper.queueDrainLoop(this, () -> { + + if (get() == 0 && compareAndSet(0, 1)) { addRequested(n); Subscription s = actual; if (s != null) { s.request(n); } - }, () -> { - BackpressureHelper.add(MISSED_REQUESTED, this, n); - }, this::drain); + if (decrementAndGet() == 0) { + return; + } + } else { + BackpressureHelper.add(missedRequested, n); + if (getAndIncrement() != 0) { + return; + } + } + int missed = 1; + for (;;) { + SubscriptionArbiter.this.drain(); + + missed = addAndGet(-missed); + if (missed == 0) { + return; + } + } } - public void produced(long n) { + public void produced(final long n) { if (n <= 0) { RxJavaPlugins.onError(new IllegalArgumentException("n > 0 required but it was " + n)); return; } - QueueDrainHelper.queueDrainLoop(this, () -> { + + if (get() == 0 && compareAndSet(0, 1)) { long r = requested; - if (r == Long.MAX_VALUE) { + if (r != Long.MAX_VALUE) { + long u = r - n; + if (u < 0L) { + RxJavaPlugins.onError(new IllegalArgumentException("More produced than requested: " + u)); + u = 0; + } + requested = u; + } + if (decrementAndGet() == 0) { return; } - long u = r - n; - if (u < 0L) { - RxJavaPlugins.onError(new IllegalArgumentException("More produced than requested: " + u)); - u = 0; + } else { + BackpressureHelper.add(missedProduced, n); + if (getAndIncrement() != 0) { + return; } - requested = u; - }, () -> { - BackpressureHelper.add(MISSED_PRODUCED, this, n); - }, this::drain); + } + int missed = 1; + for (;;) { + SubscriptionArbiter.this.drain(); + + missed = addAndGet(-missed); + if (missed == 0) { + return; + } + } } - public void setSubscription(Subscription s) { - Objects.requireNonNull(s); + public void setSubscription(final Subscription s) { + Objects.requireNonNull(s, "s is null"); if (cancelled) { s.cancel(); return; } - QueueDrainHelper.queueDrainLoop(this, () -> { + + if (get() == 0 && compareAndSet(0, 1)) { Subscription a = actual; if (a != null) { a.cancel(); @@ -119,9 +148,24 @@ public void setSubscription(Subscription s) { if (r != 0L) { s.request(r); } - }, () -> { + if (decrementAndGet() == 0) { + return; + } + } else { missedSubscription.offer(s); - }, this::drain); + if (getAndIncrement() != 0) { + return; + } + } + int missed = 1; + for (;;) { + SubscriptionArbiter.this.drain(); + + missed = addAndGet(-missed); + if (missed == 0) { + return; + } + } } @Override @@ -130,15 +174,30 @@ public void cancel() { return; } cancelled = true; - QueueDrainHelper.queueDrainLoop(this, () -> { + + if (get() == 0 && compareAndSet(0, 1)) { Subscription a = actual; if (a != null) { actual = null; a.cancel(); } - }, () -> { - // nothing to queue - }, this::drain); + if (decrementAndGet() == 0) { + return; + } + } else { + if (getAndIncrement() != 0) { + return; + } + } + int missed = 1; + for (;;) { + SubscriptionArbiter.this.drain(); + + missed = addAndGet(-missed); + if (missed == 0) { + return; + } + } } public boolean isCancelled() { @@ -146,8 +205,8 @@ public boolean isCancelled() { } void drain() { - long mr = MISSED_REQUESTED.getAndSet(this, 0L); - long mp = MISSED_PRODUCED.getAndSet(this, 0L); + long mr = missedRequested.getAndSet(0L); + long mp = missedProduced.getAndSet(0L); Subscription ms = missedSubscription.poll(); boolean c = cancelled; diff --git a/src/main/java/io/reactivex/internal/subscriptions/SubscriptionHelper.java b/src/main/java/io/reactivex/internal/subscriptions/SubscriptionHelper.java index 9f30e6f4d4..b905e08a86 100644 --- a/src/main/java/io/reactivex/internal/subscriptions/SubscriptionHelper.java +++ b/src/main/java/io/reactivex/internal/subscriptions/SubscriptionHelper.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -16,11 +16,22 @@ import org.reactivestreams.*; import io.reactivex.disposables.Disposable; +import io.reactivex.functions.Consumer; import io.reactivex.plugins.RxJavaPlugins; +/** + * Utility methods to validate Subscriptions and Disposables in the various onSubscribe calls. + */ public enum SubscriptionHelper { ; + /** + * Verifies that current is null, next is not null, otherwise signals errors + * to the RxJavaPlugins and returns true + * @param current the current Subscription, expected to be null + * @param next the next Subscription, expected to be non-null + * @return true if the validation failed + */ public static boolean validateSubscription(Subscription current, Subscription next) { if (next == null) { RxJavaPlugins.onError(new NullPointerException("next is null")); @@ -34,10 +45,20 @@ public static boolean validateSubscription(Subscription current, Subscription ne return false; } + /** + * Reports that the subscription is already set to the RxJavaPlugins error handler. + */ public static void reportSubscriptionSet() { RxJavaPlugins.onError(new IllegalStateException("Subscription already set!")); } + /** + * Verifies that current is null, next is not null, otherwise signals errors + * to the RxJavaPlugins and returns true + * @param current the current Disposable, expected to be null + * @param next the next Disposable, expected to be non-null + * @return true if the validation failed + */ public static boolean validateDisposable(Disposable current, Disposable next) { if (next == null) { RxJavaPlugins.onError(new NullPointerException("next is null")); @@ -51,32 +72,18 @@ public static boolean validateDisposable(Disposable current, Disposable next) { return false; } + /** + * Reports that the disposable is already set to the RxJavaPlugins error handler. + */ public static void reportDisposableSet() { RxJavaPlugins.onError(new IllegalStateException("Disposable already set!")); } /** - *

- * Make sure error reporting via s.onError is serialized. - * - * @param current - * @param next - * @param s - * @return + * Validates that the n is positive. + * @param n the request amount + * @return false if n is non-positive. */ - public static boolean validateSubscription(Subscription current, Subscription next, Subscriber s) { - if (next == null) { - s.onError(new NullPointerException("next is null")); - return true; - } - if (current != null) { - next.cancel(); - reportSubscriptionSet(); - return true; - } - return false; - } - public static boolean validateRequest(long n) { if (n <= 0) { RxJavaPlugins.onError(new IllegalArgumentException("n > 0 required but it was " + n)); @@ -85,23 +92,19 @@ public static boolean validateRequest(long n) { return false; } + /** Singleton instance of a function which calls cancel on the supplied Subscription. */ + static final Consumer CONSUME_AND_CANCEL = new Consumer() { + @Override + public void accept(Subscription s) { + s.cancel(); + } + }; + /** - *

- * Make sure error reporting via s.onError is serialized. - * - * @param n - * @param current - * @param s - * @return + * Returns a consumer which calls cancel on the supplied Subscription. + * @return a consumer which calls cancel on the supplied Subscription */ - public static boolean validateRequest(long n, Subscription current, Subscriber s) { - if (n <= 0) { - if (current != null) { - current.cancel(); - } - s.onError(new IllegalArgumentException("n > 0 required but it was " + n)); - return true; - } - return false; + public static Consumer consumeAndCancel() { + return CONSUME_AND_CANCEL; } } diff --git a/src/main/java/io/reactivex/internal/util/AppendOnlyLinkedArrayList.java b/src/main/java/io/reactivex/internal/util/AppendOnlyLinkedArrayList.java index 1593a58a16..b12d0f0dd5 100644 --- a/src/main/java/io/reactivex/internal/util/AppendOnlyLinkedArrayList.java +++ b/src/main/java/io/reactivex/internal/util/AppendOnlyLinkedArrayList.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,7 +13,7 @@ package io.reactivex.internal.util; -import java.util.function.*; +import io.reactivex.functions.*; /** * A linked-array-list implementation that only supports appending and consumption. diff --git a/src/main/java/io/reactivex/internal/util/BackpressureHelper.java b/src/main/java/io/reactivex/internal/util/BackpressureHelper.java index 92148a18ae..7e72f0c511 100644 --- a/src/main/java/io/reactivex/internal/util/BackpressureHelper.java +++ b/src/main/java/io/reactivex/internal/util/BackpressureHelper.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -68,25 +68,4 @@ public static long add(AtomicLong requested, long n) { } } } - - /** - * Atomically adds the positive value n to the value in the instance through the field updater and - * caps the result at Long.MAX_VALUE and returns the previous value. - * @param updater the field updater for the requested value - * @param instance the instance holding the requested value - * @param n the value to add, must be positive (not verified) - * @return the original value before the add - */ - public static long add(AtomicLongFieldUpdater updater, T instance, long n) { - for (;;) { - long r = updater.get(instance); - if (r == Long.MAX_VALUE) { - return Long.MAX_VALUE; - } - long u = addCap(r, n); - if (updater.compareAndSet(instance, r, u)) { - return r; - } - } - } } diff --git a/src/main/java/io/reactivex/internal/util/Exceptions.java b/src/main/java/io/reactivex/internal/util/Exceptions.java index 043f7b59f6..b87a1ff270 100644 --- a/src/main/java/io/reactivex/internal/util/Exceptions.java +++ b/src/main/java/io/reactivex/internal/util/Exceptions.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 diff --git a/src/main/java/io/reactivex/internal/util/LinkedArrayList.java b/src/main/java/io/reactivex/internal/util/LinkedArrayList.java index ea65a533ab..9295f1eeab 100644 --- a/src/main/java/io/reactivex/internal/util/LinkedArrayList.java +++ b/src/main/java/io/reactivex/internal/util/LinkedArrayList.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -74,35 +74,35 @@ public void add(Object o) { } /** * Returns the head buffer segment or null if the list is empty. - * @return + * @return the head object array */ public Object[] head() { return head; } /** * Returns the tail buffer segment or null if the list is empty. - * @return + * @return the tail object array */ public Object[] tail() { return tail; } /** * Returns the total size of the list. - * @return + * @return the total size of the list */ public int size() { return size; } /** * Returns the index of the next slot in the tail buffer segment. - * @return + * @return the index of the next slot in the tail buffer segment */ public int indexInTail() { return indexInTail; } /** * Returns the capacity hint that indicates the capacity of each buffer segment. - * @return + * @return the capacity hint that indicates the capacity of each buffer segment */ public int capacityHint() { return capacityHint; @@ -110,7 +110,7 @@ public int capacityHint() { /* Test support */List toList() { final int cap = capacityHint; final int s = size; - final List list = new ArrayList<>(s + 1); + final List list = new ArrayList(s + 1); Object[] h = head(); int j = 0; diff --git a/src/main/java/io/reactivex/internal/util/NbpQueueDrain.java b/src/main/java/io/reactivex/internal/util/NbpQueueDrain.java index 0ee66a414a..c7ed796e7e 100644 --- a/src/main/java/io/reactivex/internal/util/NbpQueueDrain.java +++ b/src/main/java/io/reactivex/internal/util/NbpQueueDrain.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,10 +13,7 @@ package io.reactivex.internal.util; -import java.util.Queue; - import io.reactivex.NbpObservable.NbpSubscriber; -import io.reactivex.disposables.Disposable; public interface NbpQueueDrain { @@ -30,87 +27,15 @@ public interface NbpQueueDrain { /** * Adds m to the wip counter. - * @param m - * @return + * @param m the value to add + * @return the wip value after adding the value */ int leave(int m); /** * Accept the value and return true if forwarded. - * @param a - * @param v + * @param a the subscriber to deliver values to + * @param v the value to deliver */ void accept(NbpSubscriber a, T v); - - default void drainLoop(Queue q, NbpSubscriber a, boolean delayError, Disposable dispose) { - - int missed = 1; - - for (;;) { - if (checkTerminated(done(), q.isEmpty(), a, delayError, q, dispose)) { - return; - } - - for (;;) { - boolean d = done(); - T v = q.poll(); - - boolean empty = v == null; - - if (checkTerminated(d, empty, a, delayError, q, dispose)) { - return; - } - - if (empty) { - break; - } - - accept(a, v); - } - - missed = leave(-missed); - if (missed == 0) { - break; - } - } - } - - default boolean checkTerminated(boolean d, boolean empty, - NbpSubscriber s, boolean delayError, Queue q, Disposable disposable) { - if (cancelled()) { - q.clear(); - disposable.dispose(); - return true; - } - - if (d) { - if (delayError) { - if (empty) { - disposable.dispose(); - Throwable err = error(); - if (err != null) { - s.onError(err); - } else { - s.onComplete(); - } - return true; - } - } else { - Throwable err = error(); - if (err != null) { - q.clear(); - disposable.dispose(); - s.onError(err); - return true; - } else - if (empty) { - disposable.dispose(); - s.onComplete(); - return true; - } - } - } - - return false; - } } diff --git a/src/main/java/io/reactivex/internal/util/NotificationLite.java b/src/main/java/io/reactivex/internal/util/NotificationLite.java index c662c6eb13..d5752859cb 100644 --- a/src/main/java/io/reactivex/internal/util/NotificationLite.java +++ b/src/main/java/io/reactivex/internal/util/NotificationLite.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -91,6 +91,7 @@ public String toString() { /** * Converts a value into a notification value. + * @param the actual value type * @param value the value to convert * @return the notification representing the value */ @@ -117,13 +118,18 @@ public static Object error(Throwable e) { /** * Converts a Subscription into a notification value. - * @param e the Subscription to convert + * @param s the Subscription to convert * @return the notification representing the Subscription */ public static Object subscription(Subscription s) { return new SubscriptionNotification(s); } + /** + * Converts a Disposable into a notification value. + * @param d the disposable to convert + * @return the notification representing the Disposable + */ public static Object disposable(Disposable d) { return new DisposableNotification(d); } @@ -161,6 +167,7 @@ public static boolean isDisposable(Object o) { /** * Extracts the value from the notification object + * @param the expected value type when unwrapped * @param o the notification object * @return the extracted value */ @@ -194,6 +201,7 @@ public static Disposable getDisposable(Object o) { /** * Calls the appropriate Subscriber method based on the type of the notification. *

Does not check for a subscription notification, see {@link #acceptFull(Object, Subscriber)}. + * @param the expected value type when unwrapped * @param o the notification object * @param s the subscriber to call methods on * @return true if the notification was a terminal event (i.e., complete or error) @@ -216,6 +224,7 @@ public static boolean accept(Object o, Subscriber s) { /** * Calls the appropriate NbpSubscriber method based on the type of the notification. *

Does not check for a subscription notification. + * @param the expected value type when unwrapped * @param o the notification object * @param s the NbpSubscriber to call methods on * @return true if the notification was a terminal event (i.e., complete or error) @@ -236,6 +245,7 @@ public static boolean accept(Object o, NbpSubscriber s) { /** * Calls the appropriate Subscriber method based on the type of the notification. + * @param the expected value type when unwrapped * @param o the notification object * @param s the subscriber to call methods on * @return true if the notification was a terminal event (i.e., complete or error) @@ -261,6 +271,7 @@ public static boolean acceptFull(Object o, Subscriber s) { /** * Calls the appropriate NbpSubscriber method based on the type of the notification. + * @param the expected value type when unwrapped * @param o the notification object * @param s the subscriber to call methods on * @return true if the notification was a terminal event (i.e., complete or error) diff --git a/src/main/java/io/reactivex/internal/util/OpenHashSet.java b/src/main/java/io/reactivex/internal/util/OpenHashSet.java index a318ebdee9..ac099019f8 100644 --- a/src/main/java/io/reactivex/internal/util/OpenHashSet.java +++ b/src/main/java/io/reactivex/internal/util/OpenHashSet.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -19,9 +19,9 @@ package io.reactivex.internal.util; import java.util.Arrays; -import java.util.function.Consumer; import io.reactivex.exceptions.CompositeException; +import io.reactivex.functions.Consumer; /** * A simple open hash set with add, remove and clear capabilities only. @@ -212,12 +212,12 @@ public Throwable forEachSuppress(Consumer consumer) { ex = new CompositeException(); } count++; - ex.addSuppressed(e); + ex.suppress(e); } } } if (count == 1) { - return ex.getSuppressed()[0]; + return ex.getExceptions().get(0); } return ex; } diff --git a/src/main/java/io/reactivex/internal/util/Pow2.java b/src/main/java/io/reactivex/internal/util/Pow2.java index d0d036bc27..ed72a5afcb 100644 --- a/src/main/java/io/reactivex/internal/util/Pow2.java +++ b/src/main/java/io/reactivex/internal/util/Pow2.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 diff --git a/src/main/java/io/reactivex/internal/util/QueueDrain.java b/src/main/java/io/reactivex/internal/util/QueueDrain.java index 8ed411139b..2ff391ba2f 100644 --- a/src/main/java/io/reactivex/internal/util/QueueDrain.java +++ b/src/main/java/io/reactivex/internal/util/QueueDrain.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,12 +13,8 @@ package io.reactivex.internal.util; -import java.util.Queue; - import org.reactivestreams.Subscriber; -import io.reactivex.disposables.Disposable; - public interface QueueDrain { boolean cancelled(); @@ -35,146 +31,16 @@ public interface QueueDrain { /** * Adds m to the wip counter. - * @param m - * @return + * @param m the value to add + * @return the current value after adding m */ int leave(int m); /** * Accept the value and return true if forwarded. - * @param a - * @param v - * @return + * @param a the subscriber + * @param v the value + * @return true if the value was delivered */ boolean accept(Subscriber a, T v); - - default void drainLoop(Queue q, Subscriber a, boolean delayError) { - - int missed = 1; - - for (;;) { - if (checkTerminated(done(), q.isEmpty(), a, delayError, q)) { - return; - } - - long r = requested(); - boolean unbounded = r == Long.MAX_VALUE; - long e = 0L; - - while (e != r) { - boolean d = done(); - T v = q.poll(); - - boolean empty = v == null; - - if (checkTerminated(d, empty, a, delayError, q)) { - return; - } - - if (empty) { - break; - } - - if (accept(a, v)) { - e++; - } - } - - if (e != 0L && !unbounded) { - produced(e); - } - - missed = leave(-missed); - if (missed == 0) { - break; - } - } - } - - /** - * Drain the queue but give up with an error if there aren't enough requests. - * @param q - * @param a - * @param delayError - */ - default void drainMaxLoop(Queue q, Subscriber a, boolean delayError, - Disposable dispose) { - int missed = 1; - - for (;;) { - for (;;) { - boolean d = done(); - T v = q.poll(); - - boolean empty = v == null; - - if (checkTerminated(d, empty, a, delayError, q)) { - if (dispose != null) { - dispose.dispose(); - } - return; - } - - if (empty) { - break; - } - - long r = requested(); - if (r != 0L) { - if (accept(a, v)) { - if (r != Long.MAX_VALUE) { - r = produced(1); - } - } - } else { - q.clear(); - if (dispose != null) { - dispose.dispose(); - } - a.onError(new IllegalStateException("Could not emit value due to lack of requests.")); - return; - } - } - - missed = leave(-missed); - if (missed == 0) { - break; - } - } - } - - default boolean checkTerminated(boolean d, boolean empty, - Subscriber s, boolean delayError, Queue q) { - if (cancelled()) { - q.clear(); - return true; - } - - if (d) { - if (delayError) { - if (empty) { - Throwable err = error(); - if (err != null) { - s.onError(err); - } else { - s.onComplete(); - } - return true; - } - } else { - Throwable err = error(); - if (err != null) { - q.clear(); - s.onError(err); - return true; - } else - if (empty) { - s.onComplete(); - return true; - } - } - } - - return false; - } } diff --git a/src/main/java/io/reactivex/internal/util/QueueDrainHelper.java b/src/main/java/io/reactivex/internal/util/QueueDrainHelper.java index 759323f76d..ae9c53f2e4 100644 --- a/src/main/java/io/reactivex/internal/util/QueueDrainHelper.java +++ b/src/main/java/io/reactivex/internal/util/QueueDrainHelper.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -12,8 +12,14 @@ */ package io.reactivex.internal.util; +import java.util.Queue; import java.util.concurrent.atomic.*; -import java.util.function.BooleanSupplier; + +import org.reactivestreams.Subscriber; + +import io.reactivex.NbpObservable.NbpSubscriber; +import io.reactivex.disposables.Disposable; +import io.reactivex.functions.BooleanSupplier; /** * Utility class to help with the queue-drain serialization idiom. @@ -24,22 +30,22 @@ public enum QueueDrainHelper { /** * A fast-path queue-drain serialization logic. *

The decrementing of the state is left to the drain callback. - * @param updater + * @param the instance type * @param instance * @param fastPath called if the instance is uncontended. * @param queue called if the instance is contended to queue up work * @param drain called if the instance transitions to the drain state successfully */ - public static void queueDrain(AtomicIntegerFieldUpdater updater, T instance, + public static void queueDrain(AtomicInteger instance, Runnable fastPath, Runnable queue, Runnable drain) { - if (updater.get(instance) == 0 && updater.compareAndSet(instance, 0, 1)) { + if (instance.get() == 0 && instance.compareAndSet(0, 1)) { fastPath.run(); - if (updater.decrementAndGet(instance) == 0) { + if (instance.decrementAndGet() == 0) { return; } } else { queue.run(); - if (updater.getAndIncrement(instance) != 0) { + if (instance.getAndIncrement() != 0) { return; } } @@ -50,26 +56,26 @@ public static void queueDrain(AtomicIntegerFieldUpdater updater, T instan * A fast-path queue-drain serialization logic with the ability to leave the state * in fastpath/drain mode or not continue after the call to queue. *

The decrementing of the state is left to the drain callback. - * @param updater + * @param the instance type * @param instance * @param fastPath * @param queue * @param drain */ - public static void queueDrainIf(AtomicIntegerFieldUpdater updater, T instance, + public static void queueDrainIf(AtomicInteger instance, BooleanSupplier fastPath, BooleanSupplier queue, Runnable drain) { - if (updater.get(instance) == 0 && updater.compareAndSet(instance, 0, 1)) { + if (instance.get() == 0 && instance.compareAndSet(0, 1)) { if (fastPath.getAsBoolean()) { return; } - if (updater.decrementAndGet(instance) == 0) { + if (instance.decrementAndGet() == 0) { return; } } else { if (queue.getAsBoolean()) { return; } - if (updater.getAndIncrement(instance) != 0) { + if (instance.getAndIncrement() != 0) { return; } } @@ -79,22 +85,22 @@ public static void queueDrainIf(AtomicIntegerFieldUpdater updater, T inst /** * A fast-path queue-drain serialization logic where the drain is looped until * the instance state reaches 0 again. - * @param updater + * @param the instance type * @param instance * @param fastPath * @param queue * @param drain */ - public static void queueDrainLoop(AtomicIntegerFieldUpdater updater, T instance, + public static void queueDrainLoop(AtomicInteger instance, Runnable fastPath, Runnable queue, Runnable drain) { - if (updater.get(instance) == 0 && updater.compareAndSet(instance, 0, 1)) { + if (instance.get() == 0 && instance.compareAndSet(0, 1)) { fastPath.run(); - if (updater.decrementAndGet(instance) == 0) { + if (instance.decrementAndGet() == 0) { return; } } else { queue.run(); - if (updater.getAndIncrement(instance) != 0) { + if (instance.getAndIncrement() != 0) { return; } } @@ -102,7 +108,7 @@ public static void queueDrainLoop(AtomicIntegerFieldUpdater updater, T in for (;;) { drain.run(); - missed = updater.addAndGet(instance, -missed); + missed = instance.addAndGet(-missed); if (missed == 0) { return; } @@ -112,26 +118,26 @@ public static void queueDrainLoop(AtomicIntegerFieldUpdater updater, T in /** * A fast-path queue-drain serialization logic with looped drain call and the ability to leave the state * in fastpath/drain mode or not continue after the call to queue. - * @param updater + * @param the instance type * @param instance * @param fastPath * @param queue * @param drain */ - public static void queueDrainLoopIf(AtomicIntegerFieldUpdater updater, T instance, + public static void queueDrainLoopIf(AtomicInteger instance, BooleanSupplier fastPath, BooleanSupplier queue, BooleanSupplier drain) { - if (updater.get(instance) == 0 && updater.compareAndSet(instance, 0, 1)) { + if (instance.get() == 0 && instance.compareAndSet(0, 1)) { if (fastPath.getAsBoolean()) { return; } - if (updater.decrementAndGet(instance) == 0) { + if (instance.decrementAndGet() == 0) { return; } } else { if (queue.getAsBoolean()) { return; } - if (updater.getAndIncrement(instance) != 0) { + if (instance.getAndIncrement() != 0) { return; } } @@ -142,139 +148,216 @@ public static void queueDrainLoopIf(AtomicIntegerFieldUpdater updater, T return; } - missed = updater.addAndGet(instance, -missed); + missed = instance.addAndGet(-missed); if (missed == 0) { return; } } } - /** - * A fast-path queue-drain serialization logic. - *

The decrementing of the state is left to the drain callback. - * @param updater - * @param instance - * @param fastPath called if the instance is uncontended. - * @param queue called if the instance is contended to queue up work - * @param drain called if the instance transitions to the drain state successfully - */ - public static void queueDrain(AtomicInteger instance, - Runnable fastPath, Runnable queue, Runnable drain) { - if (instance.get() == 0 && instance.compareAndSet(0, 1)) { - fastPath.run(); - if (instance.decrementAndGet() == 0) { - return; - } - } else { - queue.run(); - if (instance.getAndIncrement() != 0) { - return; - } - } - drain.run(); - } - - /** - * A fast-path queue-drain serialization logic with the ability to leave the state - * in fastpath/drain mode or not continue after the call to queue. - *

The decrementing of the state is left to the drain callback. - * @param updater - * @param instance - * @param fastPath - * @param queue - * @param drain - */ - public static void queueDrainIf(AtomicInteger instance, - BooleanSupplier fastPath, BooleanSupplier queue, Runnable drain) { - if (instance.get() == 0 && instance.compareAndSet(0, 1)) { - if (fastPath.getAsBoolean()) { + public static void drainLoop(Queue q, Subscriber a, boolean delayError, QueueDrain qd) { + + int missed = 1; + + for (;;) { + if (checkTerminated(qd.done(), q.isEmpty(), a, delayError, q, qd)) { return; } - if (instance.decrementAndGet() == 0) { - return; + + long r = qd.requested(); + boolean unbounded = r == Long.MAX_VALUE; + long e = 0L; + + while (e != r) { + boolean d = qd.done(); + T v = q.poll(); + + boolean empty = v == null; + + if (checkTerminated(d, empty, a, delayError, q, qd)) { + return; + } + + if (empty) { + break; + } + + if (qd.accept(a, v)) { + e++; + } } - } else { - if (queue.getAsBoolean()) { - return; + + if (e != 0L && !unbounded) { + qd.produced(e); } - if (instance.getAndIncrement() != 0) { - return; + + missed = qd.leave(-missed); + if (missed == 0) { + break; } } - drain.run(); } /** - * A fast-path queue-drain serialization logic where the drain is looped until - * the instance state reaches 0 again. - * @param updater - * @param instance - * @param fastPath - * @param queue - * @param drain + * Drain the queue but give up with an error if there aren't enough requests. + * @param the queue value type + * @param the emission value type + * @param q the queue + * @param a the subscriber + * @param delayError true if errors should be delayed after all normal items + * @param dispose the disposable to call when termination happens and cleanup is necessary + * @param qd the QueueDrain instance that gives status information to the drain logic */ - public static void queueDrainLoop(AtomicInteger instance, - Runnable fastPath, Runnable queue, Runnable drain) { - if (instance.get() == 0 && instance.compareAndSet(0, 1)) { - fastPath.run(); - if (instance.decrementAndGet() == 0) { - return; - } - } else { - queue.run(); - if (instance.getAndIncrement() != 0) { - return; - } - } + public static void drainMaxLoop(Queue q, Subscriber a, boolean delayError, + Disposable dispose, QueueDrain qd) { int missed = 1; + for (;;) { - drain.run(); + for (;;) { + boolean d = qd.done(); + T v = q.poll(); + + boolean empty = v == null; + + if (checkTerminated(d, empty, a, delayError, q, qd)) { + if (dispose != null) { + dispose.dispose(); + } + return; + } + + if (empty) { + break; + } + + long r = qd.requested(); + if (r != 0L) { + if (qd.accept(a, v)) { + if (r != Long.MAX_VALUE) { + r = qd.produced(1); + } + } + } else { + q.clear(); + if (dispose != null) { + dispose.dispose(); + } + a.onError(new IllegalStateException("Could not emit value due to lack of requests.")); + return; + } + } - missed = instance.addAndGet(-missed); + missed = qd.leave(-missed); if (missed == 0) { - return; + break; } } } - - /** - * A fast-path queue-drain serialization logic with looped drain call and the ability to leave the state - * in fastpath/drain mode or not continue after the call to queue. - * @param updater - * @param instance - * @param fastPath - * @param queue - * @param drain - */ - public static void queueDrainLoopIf(AtomicInteger instance, - BooleanSupplier fastPath, BooleanSupplier queue, BooleanSupplier drain) { - if (instance.get() == 0 && instance.compareAndSet(0, 1)) { - if (fastPath.getAsBoolean()) { - return; - } - if (instance.decrementAndGet() == 0) { - return; - } - } else { - if (queue.getAsBoolean()) { - return; - } - if (instance.getAndIncrement() != 0) { - return; + + public static boolean checkTerminated(boolean d, boolean empty, + Subscriber s, boolean delayError, Queue q, QueueDrain qd) { + if (qd.cancelled()) { + q.clear(); + return true; + } + + if (d) { + if (delayError) { + if (empty) { + Throwable err = qd.error(); + if (err != null) { + s.onError(err); + } else { + s.onComplete(); + } + return true; + } + } else { + Throwable err = qd.error(); + if (err != null) { + q.clear(); + s.onError(err); + return true; + } else + if (empty) { + s.onComplete(); + return true; + } } } + + return false; + } + + public static void drainLoop(Queue q, NbpSubscriber a, boolean delayError, Disposable dispose, NbpQueueDrain qd) { + int missed = 1; + for (;;) { - - if (drain.getAsBoolean()) { + if (checkTerminated(qd.done(), q.isEmpty(), a, delayError, q, dispose, qd)) { return; } - missed = instance.addAndGet(-missed); + for (;;) { + boolean d = qd.done(); + T v = q.poll(); + + boolean empty = v == null; + + if (checkTerminated(d, empty, a, delayError, q, dispose, qd)) { + return; + } + + if (empty) { + break; + } + + qd.accept(a, v); + } + + missed = qd.leave(-missed); if (missed == 0) { - return; + break; } } } + public static boolean checkTerminated(boolean d, boolean empty, + NbpSubscriber s, boolean delayError, Queue q, Disposable disposable, NbpQueueDrain qd) { + if (qd.cancelled()) { + q.clear(); + disposable.dispose(); + return true; + } + + if (d) { + if (delayError) { + if (empty) { + disposable.dispose(); + Throwable err = qd.error(); + if (err != null) { + s.onError(err); + } else { + s.onComplete(); + } + return true; + } + } else { + Throwable err = qd.error(); + if (err != null) { + q.clear(); + disposable.dispose(); + s.onError(err); + return true; + } else + if (empty) { + disposable.dispose(); + s.onComplete(); + return true; + } + } + } + + return false; + } } diff --git a/src/main/java/io/reactivex/internal/util/TerminalAtomicsHelper.java b/src/main/java/io/reactivex/internal/util/TerminalAtomicsHelper.java index f91ab4e79b..47db4368c0 100644 --- a/src/main/java/io/reactivex/internal/util/TerminalAtomicsHelper.java +++ b/src/main/java/io/reactivex/internal/util/TerminalAtomicsHelper.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,7 +13,8 @@ package io.reactivex.internal.util; import java.util.concurrent.atomic.*; -import java.util.function.*; + +import io.reactivex.functions.*; /** * Helper class to handle copy-on-write arrays plus terminal state for arbitrary references. @@ -23,24 +24,7 @@ public enum TerminalAtomicsHelper { /** * Atomically swaps in the terminalValue and calls the given callback if not already terminated. - * @param updater - * @param instance - * @param terminalValue - * @param onTerminate - */ - public static void terminate(AtomicReferenceFieldUpdater updater, - T instance, U terminalValue, Consumer onTerminate) { - U a = updater.get(instance); - if (a != terminalValue) { - a = updater.getAndSet(instance, terminalValue); - if (a != terminalValue && a != null) { - onTerminate.accept(a); - } - } - } - - /** - * Atomically swaps in the terminalValue and calls the given callback if not already terminated. + * @param the reference type * @param instance * @param terminalValue * @param onTerminate @@ -58,25 +42,10 @@ public static void terminate(AtomicReference instance, /** * Atomically swaps in the terminal value and returns the previous value. - * @param updater - * @param instance - * @param terminalValue - * @return - */ - public static U terminate(AtomicReferenceFieldUpdater updater, - T instance, U terminalValue) { - U a = updater.get(instance); - if (a != terminalValue) { - a = updater.getAndSet(instance, terminalValue); - } - return a; - } - - /** - * Atomically swaps in the terminal value and returns the previous value. + * @param the reference type * @param instance * @param terminalValue - * @return + * @return the last value or the terminal value */ public static U terminate(AtomicReference instance, U terminalValue) { @@ -90,36 +59,8 @@ public static U terminate(AtomicReference instance, /** * Atomically replaces the contents of the instance and calls the callback with the old value * or calls the callback with the new value if the instance holds the terminal value. - * @param updater - * @param instance - * @param newValue - * @param terminalValue - * @param onTerminate - * @return false if the instance holds the terminal value - * @see #update(AtomicReferenceFieldUpdater, Object, Object, Object, Consumer) - */ - public static boolean set(AtomicReferenceFieldUpdater updater, T instance, - U newValue, U terminalValue, Consumer onTerminate) { - for (;;) { - U a = updater.get(instance); - if (a == terminalValue) { - if (newValue != null) { - onTerminate.accept(newValue); - } - return false; - } - if (updater.compareAndSet(instance, a, newValue)) { - if (a != null) { - onTerminate.accept(a); - } - return true; - } - } - } - - /** - * Atomically replaces the contents of the instance and calls the callback with the old value - * or calls the callback with the new value if the instance holds the terminal value. + * @param the instance type + * @param the reference type * @param instance * @param newValue * @param terminalValue @@ -149,33 +90,8 @@ public static boolean set(AtomicReference instance, /** * Atomically replaces the content of the instance but calls the callback only if the instance holds * the terminal value. - * @param updater - * @param instance - * @param newValue - * @param terminalValue - * @param onTerminate - * @return false if the instance holds the terminal value - * @see #set(AtomicReferenceFieldUpdater, Object, Object, Object, Consumer) - */ - public static boolean update(AtomicReferenceFieldUpdater updater, T instance, - U newValue, U terminalValue, Consumer onTerminate) { - for (;;) { - U a = updater.get(instance); - if (a == terminalValue) { - if (newValue != null) { - onTerminate.accept(newValue); - } - return false; - } - if (updater.compareAndSet(instance, a, newValue)) { - return true; - } - } - } - - /** - * Atomically replaces the content of the instance but calls the callback only if the instance holds - * the terminal value. + * @param the instance type + * @param the reference type * @param instance * @param newValue * @param terminalValue @@ -202,38 +118,12 @@ public static boolean update(AtomicReference instance, /** * Atomically replaces the array in instance with a new array that contains the newValue as well * or returns false if the instance holds the terminalValue. - * @param updater - * @param instance - * @param newValue - * @param terminalValue - * @param arraySupplier - * @return - */ - public static boolean add(AtomicReferenceFieldUpdater updater, T instance, - U newValue, U[] terminalValue, IntFunction arraySupplier) { - for (;;) { - U[] a = updater.get(instance); - if (a == terminalValue) { - return false; - } - int n = a.length; - U[] b = arraySupplier.apply(n + 1); - System.arraycopy(a, 0, b, 0, n); - b[n] = newValue; - if (updater.compareAndSet(instance, a, b)) { - return true; - } - } - } - - /** - * Atomically replaces the array in instance with a new array that contains the newValue as well - * or returns false if the instance holds the terminalValue. + * @param the reference type * @param instance * @param newValue * @param terminalValue * @param arraySupplier - * @return + * @return true if the add succeeded, false if the instance has terminated */ public static boolean add(AtomicReference instance, U newValue, U[] terminalValue, IntFunction arraySupplier) { @@ -256,59 +146,13 @@ public static boolean add(AtomicReference instance, * Atomically replaces the array in instance with a new array that doesn't contain the * given value or returns false if the instance holds the terminal state or an empty array * or the value is not in the array. - * @param updater - * @param instance - * @param value - * @param terminalValue - * @param zeroArray - * @param arraySupplier - * @return - */ - public static boolean remove(AtomicReferenceFieldUpdater updater, T instance, - U value, U[] terminalValue, U[] zeroArray, IntFunction arraySupplier) { - for (;;) { - U[] a = updater.get(instance); - if (a == terminalValue) { - return false; - } - int n = a.length; - if (n == 0) { - return false; - } - int j = -1; - for (int i = 0; i < n; i++) { - if (a[i] == value) { - j = i; - break; - } - } - if (j < 0) { - return false; - } - U[] b; - if (n == 1) { - b = zeroArray; - } else { - b = arraySupplier.apply(n - 1); - System.arraycopy(a, 0, b, 0, j); - System.arraycopy(a, j + 1, b, j, n - j - 1); - } - if (updater.compareAndSet(instance, a, b)) { - return true; - } - } - } - - /** - * Atomically replaces the array in instance with a new array that doesn't contain the - * given value or returns false if the instance holds the terminal state or an empty array - * or the value is not in the array. + * @param the reference type * @param reference * @param value * @param terminalValue * @param zeroArray * @param arraySupplier - * @return + * @return true if the remove succeeded, false if the instance has terminated */ public static boolean remove(AtomicReference reference, U value, U[] terminalValue, U[] zeroArray, IntFunction arraySupplier) { diff --git a/src/main/java/io/reactivex/observables/BlockingObservable.java b/src/main/java/io/reactivex/observables/BlockingObservable.java index 11af59099e..addae0669f 100644 --- a/src/main/java/io/reactivex/observables/BlockingObservable.java +++ b/src/main/java/io/reactivex/observables/BlockingObservable.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,21 +13,23 @@ package io.reactivex.observables; +import java.io.Closeable; import java.util.*; import java.util.concurrent.*; -import java.util.function.Consumer; -import java.util.stream.*; +import java.util.concurrent.atomic.AtomicReference; import org.reactivestreams.*; +import io.reactivex.Optional; import io.reactivex.Observable; import io.reactivex.Observer; -import io.reactivex.disposables.Disposable; +import io.reactivex.disposables.*; +import io.reactivex.functions.Consumer; +import io.reactivex.internal.functions.Functions; import io.reactivex.internal.operators.*; import io.reactivex.internal.subscribers.*; import io.reactivex.internal.util.*; import io.reactivex.plugins.RxJavaPlugins; -import io.reactivex.subscribers.AsyncObserver; public final class BlockingObservable implements Publisher, Iterable { final Publisher o; @@ -40,7 +42,7 @@ public static BlockingObservable from(Publisher source) { if (source instanceof BlockingObservable) { return (BlockingObservable)source; } - return new BlockingObservable<>(source); + return new BlockingObservable(source); } @Override @@ -48,7 +50,6 @@ public Iterator iterator() { return iterate(o); } - @Override public void forEach(Consumer action) { BlockingIterator it = iterate(o); while (it.hasNext()) { @@ -56,27 +57,47 @@ public void forEach(Consumer action) { action.accept(it.next()); } catch (Throwable e) { it.dispose(); - throw e; + throw Exceptions.propagate(e); } } } static final BlockingIterator iterate(Publisher p) { - final BlockingQueue queue = new LinkedBlockingQueue<>(); + final BlockingQueue queue = new LinkedBlockingQueue(); - LambdaSubscriber ls = new LambdaSubscriber<>( - v -> queue.offer(NotificationLite.next(v)), - e -> queue.offer(NotificationLite.error(e)), - () -> queue.offer(NotificationLite.complete()), - s -> s.request(Long.MAX_VALUE) + LambdaSubscriber ls = new LambdaSubscriber( + new Consumer() { + @Override + public void accept(T v) { + queue.offer(NotificationLite.next(v)); + } + }, + new Consumer() { + @Override + public void accept(Throwable e) { + queue.offer(NotificationLite.error(e)); + } + }, + new Runnable() { + @Override + public void run() { + queue.offer(NotificationLite.complete()); + } + }, + new Consumer() { + @Override + public void accept(Subscription s) { + s.request(Long.MAX_VALUE); + } + } ); p.subscribe(ls); - return new BlockingIterator<>(queue, ls); + return new BlockingIterator(queue, ls); } - static final class BlockingIterator implements Iterator, AutoCloseable, Disposable { + static final class BlockingIterator implements Iterator, Closeable, Disposable { final BlockingQueue queue; final Disposable resource; @@ -130,7 +151,12 @@ public T next() { } @Override - public void close() throws Exception { + public void remove() { + throw new UnsupportedOperationException(); + } + + @Override + public void close() { resource.dispose(); } @@ -140,59 +166,154 @@ public void dispose() { } } - static Stream makeStream(Iterator it, boolean parallel) { - Spliterator s = Spliterators.spliteratorUnknownSize(it, 0); - Stream st = StreamSupport.stream(s, parallel); - if (it instanceof BlockingIterator) { - - BlockingIterator bit = (BlockingIterator) it; - st = st.onClose(bit::dispose); - } - return st; + public Optional firstOption() { + return firstOption(o); } - public Stream stream() { - return makeStream(iterator(), false); - } - - public Stream parallelStream() { - return makeStream(iterator(), true); - } - - public Optional firstOption() { - return stream().findFirst(); + static Optional firstOption(Publisher o) { + final AtomicReference value = new AtomicReference(); + final AtomicReference error = new AtomicReference(); + final CountDownLatch cdl = new CountDownLatch(1); + final MultipleAssignmentDisposable mad = new MultipleAssignmentDisposable(); + + o.subscribe(new Subscriber() { + Subscription s; + @Override + public void onSubscribe(Subscription s) { + this.s = s; + mad.set(Disposables.from(s)); + s.request(Long.MAX_VALUE); + } + + @Override + public void onNext(T t) { + s.cancel(); + value.lazySet(t); + cdl.countDown(); + } + + @Override + public void onError(Throwable t) { + error.lazySet(t); + cdl.countDown(); + } + + @Override + public void onComplete() { + cdl.countDown(); + } + }); + + try { + cdl.await(); + } catch (InterruptedException ex) { + mad.dispose(); + Exceptions.propagate(ex); + } + + Throwable e = error.get(); + if (e != null) { + Exceptions.propagate(e); + } + T v = value.get(); + return v != null ? Optional.of(v) : Optional.empty(); } public T first() { - return firstOption().get(); + Optional o = firstOption(); + if (o.isPresent()) { + return o.get(); + } + throw new NoSuchElementException(); } public T first(T defaultValue) { - return firstOption().orElse(defaultValue); + Optional o = firstOption(); + if (o.isPresent()) { + return o.get(); + } + return defaultValue; } public Optional lastOption() { - return stream().reduce((a, b) -> b); + return lastOption(o); + } + + static Optional lastOption(Publisher o) { + final AtomicReference value = new AtomicReference(); + final AtomicReference error = new AtomicReference(); + final CountDownLatch cdl = new CountDownLatch(1); + final MultipleAssignmentDisposable mad = new MultipleAssignmentDisposable(); + + o.subscribe(new Subscriber() { + @Override + public void onSubscribe(Subscription s) { + mad.set(Disposables.from(s)); + s.request(Long.MAX_VALUE); + } + + @Override + public void onNext(T t) { + value.lazySet(t); + } + + @Override + public void onError(Throwable t) { + error.lazySet(t); + cdl.countDown(); + } + + @Override + public void onComplete() { + cdl.countDown(); + } + }); + + try { + cdl.await(); + } catch (InterruptedException ex) { + mad.dispose(); + Exceptions.propagate(ex); + } + + Throwable e = error.get(); + if (e != null) { + Exceptions.propagate(e); + } + T v = value.get(); + return v != null ? Optional.of(v) : Optional.empty(); } public T last() { - return lastOption().get(); + Optional o = lastOption(); + if (o.isPresent()) { + return o.get(); + } + throw new NoSuchElementException(); } public T last(T defaultValue) { - return lastOption().orElse(defaultValue); + Optional o = lastOption(); + if (o.isPresent()) { + return o.get(); + } + return defaultValue; } public T single() { - Iterator it = iterate(Observable.fromPublisher(o).single()); - Optional o = makeStream(it, false).findFirst(); - return o.get(); + Optional o = firstOption(Observable.fromPublisher(this.o).single()); + if (o.isPresent()) { + return o.get(); + } + throw new NoSuchElementException(); } public T single(T defaultValue) { - Iterator it = iterate(Observable.fromPublisher(o).single(defaultValue)); - Optional o = makeStream(it, false).findFirst(); - return o.orElse(defaultValue); + Optional o = firstOption(Observable.fromPublisher(this.o).single(defaultValue)); + if (o.isPresent()) { + return o.get(); + } + return defaultValue; } public Iterable mostRecent(T initialValue) { @@ -207,40 +328,87 @@ public Iterable latest() { return BlockingOperatorLatest.latest(o); } - public CompletableFuture toFuture() { - CompletableFuture f = new CompletableFuture<>(); - Observable source = Observable.fromPublisher(o); + public Future toFuture() { + final CountDownLatch cdl = new CountDownLatch(1); + final AtomicReference value = new AtomicReference(); + final AtomicReference error = new AtomicReference(); + final MultipleAssignmentDisposable mad = new MultipleAssignmentDisposable(); - AsyncObserver s = new AsyncObserver() { + o.subscribe(new Subscriber() { + @Override - protected void onStart() { - f.whenComplete((v, e) -> { - cancel(); - }); - request(Long.MAX_VALUE); + public void onSubscribe(Subscription d) { + mad.set(Disposables.from(d)); + d.request(Long.MAX_VALUE); } - + @Override - public void onNext(T t) { - f.complete(t); + public void onNext(T v) { + value.lazySet(v); } - + @Override - public void onError(Throwable t) { - f.completeExceptionally(t); + public void onError(Throwable e) { + error.lazySet(e); + cdl.countDown(); } - + @Override public void onComplete() { - if (!f.isDone()) { - f.completeExceptionally(new NoSuchElementException()); + cdl.countDown(); + } + + }); + + return new Future() { + + @Override + public boolean cancel(boolean mayInterruptIfRunning) { + if (cdl.getCount() != 0) { + mad.dispose(); + return true; } + return false; + } + + @Override + public boolean isCancelled() { + return mad.isDisposed(); } + + @Override + public boolean isDone() { + return cdl.getCount() == 0 && !mad.isDisposed(); + } + + @Override + public T get() throws InterruptedException, ExecutionException { + if (cdl.getCount() != 0) { + cdl.await(); + } + Throwable e = error.get(); + if (e != null) { + throw new ExecutionException(e); + } + return value.get(); + } + + @Override + public T get(long timeout, TimeUnit unit) + throws InterruptedException, ExecutionException, TimeoutException { + if (cdl.getCount() != 0) { + if (!cdl.await(timeout, unit)) { + throw new TimeoutException(); + } + } + Throwable e = error.get(); + if (e != null) { + throw new ExecutionException(e); + } + return value.get(); + } + }; - - source.takeLast(1).subscribe(s); - - return f; } private void awaitForComplete(CountDownLatch latch, Disposable subscription) { @@ -268,12 +436,26 @@ private void awaitForComplete(CountDownLatch latch, Disposable subscription) { public void run() { final CountDownLatch cdl = new CountDownLatch(1); final Throwable[] error = { null }; - LambdaSubscriber ls = new LambdaSubscriber<>(v -> { }, e -> { - error[0] = e; - cdl.countDown(); - }, () -> { - cdl.countDown(); - }, s -> s.request(Long.MAX_VALUE)); + LambdaSubscriber ls = new LambdaSubscriber(Functions.emptyConsumer(), + new Consumer() { + @Override + public void accept(Throwable e) { + error[0] = e; + cdl.countDown(); + } + }, new Runnable() { + @Override + public void run() { + cdl.countDown(); + } + }, new Consumer() { + @Override + public void accept(Subscription s) { + s.request(Long.MAX_VALUE); + } + }); + + o.subscribe(ls); awaitForComplete(cdl, ls); Throwable e = error[0]; @@ -294,9 +476,9 @@ public void run() { */ @Override public void subscribe(Subscriber subscriber) { - final BlockingQueue queue = new LinkedBlockingQueue<>(); + final BlockingQueue queue = new LinkedBlockingQueue(); - BlockingSubscriber bs = new BlockingSubscriber<>(queue); + BlockingSubscriber bs = new BlockingSubscriber(queue); o.subscribe(bs); @@ -343,7 +525,7 @@ public void subscribe() { * @param onNext the callback action for each source value */ public void subscribe(final Consumer onNext) { - subscribe(onNext, RxJavaPlugins::onError, () -> { }); + subscribe(onNext, RxJavaPlugins.errorConsumer(), Functions.emptyRunnable()); } /** @@ -352,7 +534,7 @@ public void subscribe(final Consumer onNext) { * @param onError the callback action for an error event */ public void subscribe(final Consumer onNext, final Consumer onError) { - subscribe(onNext, onError, () -> { }); + subscribe(onNext, onError, Functions.emptyRunnable()); } /** @@ -379,4 +561,4 @@ public void onComplete() { } }); } -} +} \ No newline at end of file diff --git a/src/main/java/io/reactivex/observables/ConnectableObservable.java b/src/main/java/io/reactivex/observables/ConnectableObservable.java index 19119966b2..d7e14a222c 100644 --- a/src/main/java/io/reactivex/observables/ConnectableObservable.java +++ b/src/main/java/io/reactivex/observables/ConnectableObservable.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,12 +13,12 @@ package io.reactivex.observables; -import java.util.function.Consumer; - import org.reactivestreams.*; import io.reactivex.Observable; import io.reactivex.disposables.Disposable; +import io.reactivex.functions.Consumer; +import io.reactivex.internal.functions.Functions; import io.reactivex.internal.operators.*; /** @@ -55,14 +55,19 @@ protected ConnectableObservable(Publisher onSubscribe) { * Instructs the {@code ConnectableObservable} to begin emitting the items from its underlying * {@link Observable} to its {@link Subscriber}s. *

- * To disconnect from a synchronous source, use the {@link #connect(java.util.function.Consumer)} method. + * To disconnect from a synchronous source, use the {@link #connect(io.reactivex.functions.Consumer)} method. * * @return the subscription representing the connection * @see ReactiveX documentation: Connect */ public final Disposable connect() { - Disposable[] connection = new Disposable[1]; - connect(d -> connection[0] = d); + final Disposable[] connection = new Disposable[1]; + connect(new Consumer() { + @Override + public void accept(Disposable d) { + connection[0] = d; + } + }); return connection[0]; } @@ -74,7 +79,7 @@ public final Disposable connect() { * @see ReactiveX documentation: RefCount */ public Observable refCount() { - return create(new PublisherRefCount<>(this)); + return create(new PublisherRefCount(this)); } /** @@ -98,7 +103,7 @@ public Observable autoConnect() { * when the specified number of Subscribers subscribe to it */ public Observable autoConnect(int numberOfSubscribers) { - return autoConnect(numberOfSubscribers, c -> { }); + return autoConnect(numberOfSubscribers, Functions.emptyConsumer()); } /** @@ -120,6 +125,6 @@ public Observable autoConnect(int numberOfSubscribers, Consumer(this, numberOfSubscribers, connection)); + return create(new PublisherAutoConnect(this, numberOfSubscribers, connection)); } } diff --git a/src/main/java/io/reactivex/observables/GroupedObservable.java b/src/main/java/io/reactivex/observables/GroupedObservable.java index 402058b61e..1404bfcba8 100644 --- a/src/main/java/io/reactivex/observables/GroupedObservable.java +++ b/src/main/java/io/reactivex/observables/GroupedObservable.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 diff --git a/src/main/java/io/reactivex/observables/nbp/NbpBlockingObservable.java b/src/main/java/io/reactivex/observables/nbp/NbpBlockingObservable.java index a524e822fd..50f8c2c76c 100644 --- a/src/main/java/io/reactivex/observables/nbp/NbpBlockingObservable.java +++ b/src/main/java/io/reactivex/observables/nbp/NbpBlockingObservable.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,20 +13,22 @@ package io.reactivex.observables.nbp; +import java.io.Closeable; import java.util.*; import java.util.concurrent.*; -import java.util.function.Consumer; -import java.util.stream.*; +import java.util.concurrent.atomic.AtomicReference; +import io.reactivex.Optional; import io.reactivex.*; import io.reactivex.NbpObservable.NbpSubscriber; -import io.reactivex.disposables.Disposable; +import io.reactivex.disposables.*; +import io.reactivex.functions.Consumer; +import io.reactivex.internal.functions.Functions; import io.reactivex.internal.operators.nbp.*; -import io.reactivex.internal.subscribers.*; +import io.reactivex.internal.subscribers.BlockingSubscriber; import io.reactivex.internal.subscribers.nbp.*; import io.reactivex.internal.util.*; import io.reactivex.plugins.RxJavaPlugins; -import io.reactivex.subscribers.nbp.NbpAsyncObserver; public final class NbpBlockingObservable implements Iterable { final NbpObservable o; @@ -35,7 +37,7 @@ protected NbpBlockingObservable(NbpObservable source) { } public static NbpBlockingObservable from(NbpObservable source) { - return new NbpBlockingObservable<>(source); + return new NbpBlockingObservable(source); } @Override @@ -43,7 +45,6 @@ public Iterator iterator() { return iterate(o); } - @Override public void forEach(Consumer action) { BlockingIterator it = iterate(o); while (it.hasNext()) { @@ -51,27 +52,42 @@ public void forEach(Consumer action) { action.accept(it.next()); } catch (Throwable e) { it.dispose(); - throw e; + Exceptions.propagate(e); } } } static final BlockingIterator iterate(NbpObservable p) { - final BlockingQueue queue = new LinkedBlockingQueue<>(); + final BlockingQueue queue = new LinkedBlockingQueue(); - NbpLambdaSubscriber ls = new NbpLambdaSubscriber<>( - v -> queue.offer(NotificationLite.next(v)), - e -> queue.offer(NotificationLite.error(e)), - () -> queue.offer(NotificationLite.complete()), - s -> { } + NbpLambdaSubscriber ls = new NbpLambdaSubscriber( + new Consumer() { + @Override + public void accept(T v) { + queue.offer(NotificationLite.next(v)); + } + }, + new Consumer() { + @Override + public void accept(Throwable e) { + queue.offer(NotificationLite.error(e)); + } + }, + new Runnable() { + @Override + public void run() { + queue.offer(NotificationLite.complete()); + } + }, + Functions.emptyConsumer() ); p.subscribe(ls); - return new BlockingIterator<>(queue, ls); + return new BlockingIterator(queue, ls); } - static final class BlockingIterator implements Iterator, AutoCloseable, Disposable { + static final class BlockingIterator implements Iterator, Closeable, Disposable { final BlockingQueue queue; final Disposable resource; @@ -125,7 +141,12 @@ public T next() { } @Override - public void close() throws Exception { + public void remove() { + throw new UnsupportedOperationException(); + } + + @Override + public void close() { resource.dispose(); } @@ -135,60 +156,153 @@ public void dispose() { } } - static Stream makeStream(Iterator it, boolean parallel) { - Spliterator s = Spliterators.spliteratorUnknownSize(it, 0); - Stream st = StreamSupport.stream(s, parallel); - if (it instanceof BlockingIterator) { - - BlockingIterator bit = (BlockingIterator) it; - st = st.onClose(bit::dispose); - } - return st; + public Optional firstOption() { + return firstOption(o); } - public Stream stream() { - return makeStream(iterator(), false); - } - - public Stream parallelStream() { - return makeStream(iterator(), true); - } - - public Optional firstOption() { - return stream().findFirst(); + static Optional firstOption(NbpObservable o) { + final AtomicReference value = new AtomicReference(); + final AtomicReference error = new AtomicReference(); + final CountDownLatch cdl = new CountDownLatch(1); + final MultipleAssignmentDisposable mad = new MultipleAssignmentDisposable(); + + o.subscribe(new NbpSubscriber() { + Disposable s; + @Override + public void onSubscribe(Disposable s) { + this.s = s; + mad.set(s); + } + + @Override + public void onNext(T t) { + s.dispose(); + value.lazySet(t); + cdl.countDown(); + } + + @Override + public void onError(Throwable t) { + error.lazySet(t); + cdl.countDown(); + } + + @Override + public void onComplete() { + cdl.countDown(); + } + }); + + try { + cdl.await(); + } catch (InterruptedException ex) { + mad.dispose(); + Exceptions.propagate(ex); + } + + Throwable e = error.get(); + if (e != null) { + Exceptions.propagate(e); + } + T v = value.get(); + return v != null ? Optional.of(v) : Optional.empty(); } public T first() { - return firstOption().get(); + Optional o = firstOption(); + if (o.isPresent()) { + return o.get(); + } + throw new NoSuchElementException(); } public T first(T defaultValue) { - return firstOption().orElse(defaultValue); + Optional o = firstOption(); + if (o.isPresent()) { + return o.get(); + } + return defaultValue; } public Optional lastOption() { - return stream().reduce((a, b) -> b); + return lastOption(o); + } + + static Optional lastOption(NbpObservable o) { + final AtomicReference value = new AtomicReference(); + final AtomicReference error = new AtomicReference(); + final CountDownLatch cdl = new CountDownLatch(1); + final MultipleAssignmentDisposable mad = new MultipleAssignmentDisposable(); + + o.subscribe(new NbpSubscriber() { + @Override + public void onSubscribe(Disposable s) { + mad.set(s); + } + + @Override + public void onNext(T t) { + value.lazySet(t); + } + + @Override + public void onError(Throwable t) { + error.lazySet(t); + cdl.countDown(); + } + + @Override + public void onComplete() { + cdl.countDown(); + } + }); + + try { + cdl.await(); + } catch (InterruptedException ex) { + mad.dispose(); + Exceptions.propagate(ex); + } + + Throwable e = error.get(); + if (e != null) { + Exceptions.propagate(e); + } + T v = value.get(); + return v != null ? Optional.of(v) : Optional.empty(); } public T last() { - return lastOption().get(); + Optional o = lastOption(); + if (o.isPresent()) { + return o.get(); + } + throw new NoSuchElementException(); } public T last(T defaultValue) { - return lastOption().orElse(defaultValue); + Optional o = lastOption(); + if (o.isPresent()) { + return o.get(); + } + return defaultValue; } public T single() { - Iterator it = iterate(o.single()); - Optional o = makeStream(it, false).findFirst(); - return o.get(); + Optional o = firstOption(this.o.single()); + if (o.isPresent()) { + return o.get(); + } + throw new NoSuchElementException(); } public T single(T defaultValue) { @SuppressWarnings("unchecked") - Iterator it = iterate(((NbpObservable)o).single(defaultValue)); - Optional o = makeStream(it, false).findFirst(); - return o.orElse(defaultValue); + Optional o = firstOption(((NbpObservable)this.o).single(defaultValue)); + if (o.isPresent()) { + return o.get(); + } + return defaultValue; } public Iterable mostRecent(T initialValue) { @@ -203,38 +317,86 @@ public Iterable latest() { return NbpBlockingOperatorLatest.latest(o); } - public CompletableFuture toFuture() { - CompletableFuture f = new CompletableFuture<>(); + public Future toFuture() { + final CountDownLatch cdl = new CountDownLatch(1); + final AtomicReference value = new AtomicReference(); + final AtomicReference error = new AtomicReference(); + final MultipleAssignmentDisposable mad = new MultipleAssignmentDisposable(); - NbpAsyncObserver s = new NbpAsyncObserver() { + o.subscribe(new NbpSubscriber() { + @Override - protected void onStart() { - f.whenComplete((v, e) -> { - cancel(); - }); + public void onSubscribe(Disposable d) { + mad.set(d); } - + @Override - public void onNext(T t) { - f.complete(t); + public void onNext(T v) { + value.lazySet(v); } - + @Override - public void onError(Throwable t) { - f.completeExceptionally(t); + public void onError(Throwable e) { + error.lazySet(e); + cdl.countDown(); } - + @Override public void onComplete() { - if (!f.isDone()) { - f.completeExceptionally(new NoSuchElementException()); + cdl.countDown(); + } + + }); + + return new Future() { + + @Override + public boolean cancel(boolean mayInterruptIfRunning) { + if (cdl.getCount() != 0) { + mad.dispose(); + return true; } + return false; + } + + @Override + public boolean isCancelled() { + return mad.isDisposed(); } + + @Override + public boolean isDone() { + return cdl.getCount() == 0 && !mad.isDisposed(); + } + + @Override + public T get() throws InterruptedException, ExecutionException { + if (cdl.getCount() != 0) { + cdl.await(); + } + Throwable e = error.get(); + if (e != null) { + throw new ExecutionException(e); + } + return value.get(); + } + + @Override + public T get(long timeout, TimeUnit unit) + throws InterruptedException, ExecutionException, TimeoutException { + if (cdl.getCount() != 0) { + if (!cdl.await(timeout, unit)) { + throw new TimeoutException(); + } + } + Throwable e = error.get(); + if (e != null) { + throw new ExecutionException(e); + } + return value.get(); + } + }; - - o.takeLast(1).subscribe(s); - - return f; } private void awaitForComplete(CountDownLatch latch, Disposable subscription) { @@ -262,12 +424,22 @@ private void awaitForComplete(CountDownLatch latch, Disposable subscription) { public void run() { final CountDownLatch cdl = new CountDownLatch(1); final Throwable[] error = { null }; - LambdaSubscriber ls = new LambdaSubscriber<>(v -> { }, e -> { - error[0] = e; - cdl.countDown(); - }, () -> { - cdl.countDown(); - }, s -> s.request(Long.MAX_VALUE)); + NbpLambdaSubscriber ls = new NbpLambdaSubscriber( + Functions.emptyConsumer(), + new Consumer() { + @Override + public void accept(Throwable e) { + error[0] = e; + cdl.countDown(); + } + }, new Runnable() { + @Override + public void run() { + cdl.countDown(); + } + }, Functions.emptyConsumer()); + + o.subscribe(ls); awaitForComplete(cdl, ls); Throwable e = error[0]; @@ -287,9 +459,9 @@ public void run() { * @param subscriber the subscriber to forward events and calls to in the current thread */ public void subscribe(NbpSubscriber subscriber) { - final BlockingQueue queue = new LinkedBlockingQueue<>(); + final BlockingQueue queue = new LinkedBlockingQueue(); - NbpBlockingSubscriber bs = new NbpBlockingSubscriber<>(queue); + NbpBlockingSubscriber bs = new NbpBlockingSubscriber(queue); o.subscribe(bs); @@ -336,7 +508,7 @@ public void subscribe() { * @param onNext the callback action for each source value */ public void subscribe(final Consumer onNext) { - subscribe(onNext, RxJavaPlugins::onError, () -> { }); + subscribe(onNext, RxJavaPlugins.errorConsumer(), Functions.emptyRunnable()); } /** @@ -345,7 +517,7 @@ public void subscribe(final Consumer onNext) { * @param onError the callback action for an error event */ public void subscribe(final Consumer onNext, final Consumer onError) { - subscribe(onNext, onError, () -> { }); + subscribe(onNext, onError, Functions.emptyRunnable()); } /** @@ -372,4 +544,4 @@ public void onComplete() { } }); } -} +} \ No newline at end of file diff --git a/src/main/java/io/reactivex/observables/nbp/NbpConnectableObservable.java b/src/main/java/io/reactivex/observables/nbp/NbpConnectableObservable.java index 8fe05c6571..16ca997b5d 100644 --- a/src/main/java/io/reactivex/observables/nbp/NbpConnectableObservable.java +++ b/src/main/java/io/reactivex/observables/nbp/NbpConnectableObservable.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,12 +13,12 @@ package io.reactivex.observables.nbp; -import java.util.function.Consumer; - import org.reactivestreams.Subscriber; import io.reactivex.*; import io.reactivex.disposables.Disposable; +import io.reactivex.functions.Consumer; +import io.reactivex.internal.functions.Functions; import io.reactivex.internal.operators.nbp.*; /** @@ -55,14 +55,19 @@ protected NbpConnectableObservable(NbpOnSubscribe onSubscribe) { * Instructs the {@code ConnectableObservable} to begin emitting the items from its underlying * {@link Observable} to its {@link Subscriber}s. *

- * To disconnect from a synchronous source, use the {@link #connect(java.util.function.Consumer)} method. + * To disconnect from a synchronous source, use the {@link #connect(Consumer)} method. * * @return the subscription representing the connection * @see ReactiveX documentation: Connect */ public final Disposable connect() { - Disposable[] connection = new Disposable[1]; - connect(d -> connection[0] = d); + final Disposable[] connection = new Disposable[1]; + connect(new Consumer() { + @Override + public void accept(Disposable d) { + connection[0] = d; + } + }); return connection[0]; } @@ -74,7 +79,7 @@ public final Disposable connect() { * @see ReactiveX documentation: RefCount */ public NbpObservable refCount() { - return create(new NbpOnSubscribeRefCount<>(this)); + return create(new NbpOnSubscribeRefCount(this)); } /** @@ -98,7 +103,7 @@ public NbpObservable autoConnect() { * when the specified number of Subscribers subscribe to it */ public NbpObservable autoConnect(int numberOfSubscribers) { - return autoConnect(numberOfSubscribers, c -> { }); + return autoConnect(numberOfSubscribers, Functions.emptyConsumer()); } /** @@ -120,6 +125,6 @@ public NbpObservable autoConnect(int numberOfSubscribers, Consumer(this, numberOfSubscribers, connection)); + return create(new NbpOnSubscribeAutoConnect(this, numberOfSubscribers, connection)); } } diff --git a/src/main/java/io/reactivex/observables/nbp/NbpGroupedObservable.java b/src/main/java/io/reactivex/observables/nbp/NbpGroupedObservable.java index 89f504fcaf..44a4a1a925 100644 --- a/src/main/java/io/reactivex/observables/nbp/NbpGroupedObservable.java +++ b/src/main/java/io/reactivex/observables/nbp/NbpGroupedObservable.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 diff --git a/src/main/java/io/reactivex/plugins/RxJavaPlugins.java b/src/main/java/io/reactivex/plugins/RxJavaPlugins.java index 0709f16467..31ae26074b 100644 --- a/src/main/java/io/reactivex/plugins/RxJavaPlugins.java +++ b/src/main/java/io/reactivex/plugins/RxJavaPlugins.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -12,12 +12,11 @@ */ package io.reactivex.plugins; -import java.util.function.*; - import org.reactivestreams.*; -import io.reactivex.NbpObservable.NbpSubscriber; import io.reactivex.Scheduler; +import io.reactivex.NbpObservable.NbpSubscriber; +import io.reactivex.functions.*; /** * Utility class to inject handlers to certain standard RxJava operations. @@ -164,8 +163,9 @@ public static Scheduler onComputationScheduler(Scheduler defaultScheduler) { } /** * Called when an Observable is created. - * @param publisher - * @return + * @param the value type + * @param publisher the original publisher + * @return the replacement publisher */ @SuppressWarnings({ "unchecked", "rawtypes"}) public static Publisher onCreate(Publisher publisher) { @@ -189,7 +189,7 @@ public static void onError(Throwable error) { if (error == null) { error = new NullPointerException(); } - error.addSuppressed(e); + e.printStackTrace(); } } else { if (error == null) { @@ -217,8 +217,8 @@ public static Scheduler onNewThreadScheduler(Scheduler defaultScheduler) { /** * Called when a task is scheduled. - * @param run - * @return + * @param run the runnable instance + * @return the replacement runnable */ public static Runnable onSchedule(Runnable run) { Function f = onScheduleHandler; @@ -238,8 +238,9 @@ public static Scheduler onSingleScheduler(Scheduler defaultScheduler) { /** * Called when a subscriber subscribes to an observable. - * @param subscriber - * @return + * @param the value type + * @param subscriber the original subscriber + * @return the subscriber replacement */ @SuppressWarnings({ "unchecked", "rawtypes"}) public static Subscriber onSubscribe(Subscriber subscriber) { @@ -252,8 +253,9 @@ public static Subscriber onSubscribe(Subscriber subscriber) { /** * Called when a subscriber subscribes to an observable. - * @param subscriber - * @return + * @param the value type + * @param subscriber the original NbpSubscriber + * @return the replacement NbpSubscriber */ @SuppressWarnings({ "unchecked", "rawtypes"}) public static NbpSubscriber onNbpSubscribe(NbpSubscriber subscriber) { @@ -266,8 +268,9 @@ public static NbpSubscriber onNbpSubscribe(NbpSubscriber subscriber) { /** * Called when a subscriber subscribes to an observable. - * @param subscriber - * @return + * @param the value type + * @param subscriber the original subscriber + * @return the replacement subscriber */ @SuppressWarnings({ "unchecked", "rawtypes"}) public static NbpSubscriber onSubscribe(NbpSubscriber subscriber) { @@ -401,7 +404,24 @@ public static void setNbpSubscribeHandler(Function, NbpSubs /* test. */static void unlock() { lockdown = false; } + + /** Singleton consumer that calls RxJavaPlugins.onError. */ + static final Consumer CONSUME_BY_RXJAVA_PLUGIN = new Consumer() { + @Override + public void accept(Throwable e) { + RxJavaPlugins.onError(e); + } + }; + + /** + * Returns a consumer which relays the received Throwable to RxJavaPlugins.onError(). + * @return the consumer + */ + public static final Consumer errorConsumer() { + return CONSUME_BY_RXJAVA_PLUGIN; + } + /** Helper class, no instances. */ private RxJavaPlugins() { throw new IllegalStateException("No instances!"); } diff --git a/src/main/java/io/reactivex/schedulers/Schedulers.java b/src/main/java/io/reactivex/schedulers/Schedulers.java index d3548b5166..82e41866cf 100644 --- a/src/main/java/io/reactivex/schedulers/Schedulers.java +++ b/src/main/java/io/reactivex/schedulers/Schedulers.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,7 +13,7 @@ package io.reactivex.schedulers; -import java.util.concurrent.*; +import java.util.concurrent.Executor; import io.reactivex.Scheduler; import io.reactivex.internal.schedulers.*; @@ -100,6 +100,7 @@ public static void shutdown() { newThread().shutdown(); single().shutdown(); trampoline().shutdown(); + SchedulerPoolFactory.shutdown(); } public static void start() { @@ -108,5 +109,6 @@ public static void start() { newThread().start(); single().start(); trampoline().start(); + SchedulerPoolFactory.start(); } } diff --git a/src/main/java/io/reactivex/schedulers/TestScheduler.java b/src/main/java/io/reactivex/schedulers/TestScheduler.java index ffa2a62c83..129d9c4cb3 100644 --- a/src/main/java/io/reactivex/schedulers/TestScheduler.java +++ b/src/main/java/io/reactivex/schedulers/TestScheduler.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -19,6 +19,7 @@ import io.reactivex.Scheduler; import io.reactivex.disposables.Disposable; import io.reactivex.internal.disposables.EmptyDisposable; +import io.reactivex.internal.functions.Objects; /** * A special, non thread-safe scheduler for testing operators that require @@ -27,7 +28,7 @@ */ public final class TestScheduler extends Scheduler { /** The ordered queue for the runnable tasks. */ - private final Queue queue = new PriorityQueue<>(11); + private final Queue queue = new PriorityQueue(11); /** The per-scheduler global order counter. */ long counter; @@ -53,9 +54,9 @@ public String toString() { @Override public int compareTo(TimedRunnable o) { if (time == o.time) { - return Long.compare(count, o.count); + return Objects.compare(count, o.count); } - return Long.compare(time, o.time); + return Objects.compare(time, o.time); } } @@ -140,7 +141,12 @@ public Disposable schedule(Runnable run, long delayTime, TimeUnit unit) { final TimedRunnable timedAction = new TimedRunnable(this, time + unit.toNanos(delayTime), run, counter++); queue.add(timedAction); - return () -> queue.remove(timedAction); + return new Disposable() { + @Override + public void dispose() { + queue.remove(timedAction); + } + }; } @Override @@ -150,7 +156,12 @@ public Disposable schedule(Runnable run) { } final TimedRunnable timedAction = new TimedRunnable(this, 0, run, counter++); queue.add(timedAction); - return () -> queue.remove(timedAction); + return new Disposable() { + @Override + public void dispose() { + queue.remove(timedAction); + } + }; } @Override diff --git a/src/main/java/io/reactivex/schedulers/Timed.java b/src/main/java/io/reactivex/schedulers/Timed.java index 491a383d35..f1bba85a87 100644 --- a/src/main/java/io/reactivex/schedulers/Timed.java +++ b/src/main/java/io/reactivex/schedulers/Timed.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,9 +13,10 @@ package io.reactivex.schedulers; -import java.util.Objects; import java.util.concurrent.TimeUnit; +import io.reactivex.internal.functions.Objects; + /** * Holds onto a value along with time information. * @@ -28,7 +29,7 @@ public final class Timed { public Timed(T value, long time, TimeUnit unit) { this.value = value; this.time = time; - this.unit = Objects.requireNonNull(unit); + this.unit = Objects.requireNonNull(unit, "unit is null"); } public T value() { diff --git a/src/main/java/io/reactivex/subjects/AsyncSubject.java b/src/main/java/io/reactivex/subjects/AsyncSubject.java index b409e17b66..7a8c0febff 100644 --- a/src/main/java/io/reactivex/subjects/AsyncSubject.java +++ b/src/main/java/io/reactivex/subjects/AsyncSubject.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -14,10 +14,10 @@ import java.util.Arrays; import java.util.concurrent.atomic.*; -import java.util.function.IntFunction; import org.reactivestreams.*; +import io.reactivex.functions.IntFunction; import io.reactivex.internal.util.*; import io.reactivex.plugins.RxJavaPlugins; @@ -36,11 +36,12 @@ public final class AsyncSubject extends Subject { /** * Constructs an empty AsyncSubject. + * @param the observed and observable value type * @return the new AsyncSubject instance. */ public static AsyncSubject create() { - State state = new State<>(); - return new AsyncSubject<>(state); + State state = new State(); + return new AsyncSubject(state); } /** The state holding onto the latest value or error and the array of subscribers. */ @@ -174,7 +175,8 @@ public T[] getValues(T[] array) { * @param the value type */ @SuppressWarnings("rawtypes") - static final class State extends AtomicReference implements Publisher, IntFunction { + static final class State extends AtomicReference + implements Publisher, IntFunction[]> { /** */ private static final long serialVersionUID = 2983503212425065796L; @@ -186,17 +188,14 @@ static final class State extends AtomicReference implements Publisher /** The array of current subscribers. */ @SuppressWarnings("unchecked") - volatile AsyncSubscription[] subscribers = EMPTY; - /** Field updater for subscribers. */ - static final AtomicReferenceFieldUpdater SUBSCRIBERS = - AtomicReferenceFieldUpdater.newUpdater(State.class, AsyncSubscription[].class, "subscribers"); + final AtomicReference[]> subscribers = new AtomicReference[]>(EMPTY); /** * Returns the array of current subscribers. * @return the array of current subscribers */ public AsyncSubscription[] subscribers() { - return subscribers; + return subscribers.get(); } /** @@ -205,7 +204,7 @@ public AsyncSubscription[] subscribers() { */ @SuppressWarnings("unchecked") public AsyncSubscription[] terminate() { - return TerminalAtomicsHelper.terminate(SUBSCRIBERS, this, TERMINATED); + return TerminalAtomicsHelper.terminate(subscribers, TERMINATED); } /** @@ -214,27 +213,30 @@ public AsyncSubscription[] terminate() { * @param as the AsyncSubscription to add * @return true if successful, false if the state has been terminated */ + @SuppressWarnings("unchecked") boolean add(AsyncSubscription as) { - return TerminalAtomicsHelper.add(SUBSCRIBERS, this, as, TERMINATED, this); + return TerminalAtomicsHelper.add(subscribers, as, TERMINATED, this); } /** * Atomically removes the given AsyncSubscription. * @param as the AsyncSubscription to remove */ + @SuppressWarnings("unchecked") void remove(AsyncSubscription as) { - TerminalAtomicsHelper.remove(SUBSCRIBERS, this, as, TERMINATED, EMPTY, this); + TerminalAtomicsHelper.remove(subscribers, as, TERMINATED, EMPTY, this); } + @SuppressWarnings("unchecked") @Override - public AsyncSubscription[] apply(int value) { + public AsyncSubscription[] apply(int value) { return new AsyncSubscription[value]; } @Override @SuppressWarnings("unchecked") public void subscribe(Subscriber t) { - AsyncSubscription as = new AsyncSubscription<>(t, this); + AsyncSubscription as = new AsyncSubscription(t, this); t.onSubscribe(as); if (add(as)) { diff --git a/src/main/java/io/reactivex/subjects/BehaviorSubject.java b/src/main/java/io/reactivex/subjects/BehaviorSubject.java index e0ad51b7cb..5d1c5836ec 100644 --- a/src/main/java/io/reactivex/subjects/BehaviorSubject.java +++ b/src/main/java/io/reactivex/subjects/BehaviorSubject.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -14,12 +14,13 @@ package io.reactivex.subjects; import java.lang.reflect.Array; -import java.util.Objects; import java.util.concurrent.atomic.*; -import java.util.concurrent.locks.StampedLock; +import java.util.concurrent.locks.*; import org.reactivestreams.*; +import io.reactivex.functions.Predicate; +import io.reactivex.internal.functions.Objects; import io.reactivex.internal.subscriptions.SubscriptionHelper; import io.reactivex.internal.util.*; import io.reactivex.plugins.RxJavaPlugins; @@ -27,16 +28,16 @@ public final class BehaviorSubject extends Subject { public static BehaviorSubject create() { - State state = new State<>(); - return new BehaviorSubject<>(state); + State state = new State(); + return new BehaviorSubject(state); } // TODO a plain create() would create a method ambiguity with Observable.create with javac public static BehaviorSubject createDefault(T defaultValue) { - Objects.requireNonNull(defaultValue); - State state = new State<>(); + Objects.requireNonNull(defaultValue, "defaultValue is null"); + State state = new State(); state.lazySet(defaultValue); - return new BehaviorSubject<>(state); + return new BehaviorSubject(state); } final State state; @@ -74,12 +75,12 @@ public void onComplete() { @Override public boolean hasSubscribers() { - return state.subscribers.length != 0; + return state.subscribers.get().length != 0; } /* test support*/ int subscriberCount() { - return state.subscribers.length; + return state.subscribers.get().length; } @Override @@ -147,11 +148,7 @@ static final class State extends AtomicReference implements Publisher boolean done; - volatile BehaviorSubscription[] subscribers; - - @SuppressWarnings("rawtypes") - static final AtomicReferenceFieldUpdater SUBSCRIBERS = - AtomicReferenceFieldUpdater.newUpdater(State.class, BehaviorSubscription[].class, "subscribers"); + final AtomicReference[]> subscribers; @SuppressWarnings("rawtypes") static final BehaviorSubscription[] EMPTY = new BehaviorSubscription[0]; @@ -161,16 +158,21 @@ static final class State extends AtomicReference implements Publisher long index; - final StampedLock lock; + final ReadWriteLock lock; + final Lock readLock; + final Lock writeLock; + @SuppressWarnings("unchecked") public State() { - this.lock = new StampedLock(); - SUBSCRIBERS.lazySet(this, EMPTY); + this.lock = new ReentrantReadWriteLock(); + this.readLock = lock.readLock(); + this.writeLock = lock.writeLock(); + this.subscribers = new AtomicReference[]>(EMPTY); } public boolean add(BehaviorSubscription rs) { for (;;) { - BehaviorSubscription[] a = subscribers; + BehaviorSubscription[] a = subscribers.get(); if (a == TERMINATED) { return false; } @@ -179,7 +181,7 @@ public boolean add(BehaviorSubscription rs) { BehaviorSubscription[] b = new BehaviorSubscription[len + 1]; System.arraycopy(a, 0, b, 0, len); b[len] = rs; - if (SUBSCRIBERS.compareAndSet(this, a, b)) { + if (subscribers.compareAndSet(a, b)) { return true; } } @@ -188,7 +190,7 @@ public boolean add(BehaviorSubscription rs) { @SuppressWarnings("unchecked") public void remove(BehaviorSubscription rs) { for (;;) { - BehaviorSubscription[] a = subscribers; + BehaviorSubscription[] a = subscribers.get(); if (a == TERMINATED || a == EMPTY) { return; } @@ -212,7 +214,7 @@ public void remove(BehaviorSubscription rs) { System.arraycopy(a, 0, b, 0, j); System.arraycopy(a, j + 1, b, j, len - j - 1); } - if (SUBSCRIBERS.compareAndSet(this, a, b)) { + if (subscribers.compareAndSet(a, b)) { return; } } @@ -221,9 +223,9 @@ public void remove(BehaviorSubscription rs) { @SuppressWarnings("unchecked") public BehaviorSubscription[] terminate(Object terminalValue) { - BehaviorSubscription[] a = subscribers; + BehaviorSubscription[] a = subscribers.get(); if (a != TERMINATED) { - a = SUBSCRIBERS.getAndSet(this, TERMINATED); + a = subscribers.getAndSet(TERMINATED); if (a != TERMINATED) { // either this or atomics with lots of allocation setCurrent(terminalValue); @@ -235,7 +237,7 @@ public BehaviorSubscription[] terminate(Object terminalValue) { @Override public void subscribe(Subscriber s) { - BehaviorSubscription bs = new BehaviorSubscription<>(s, this); + BehaviorSubscription bs = new BehaviorSubscription(s, this); s.onSubscribe(bs); if (!bs.cancelled) { if (add(bs)) { @@ -265,12 +267,12 @@ public void onSubscribe(Subscription s) { } void setCurrent(Object o) { - long stamp = lock.writeLock(); + writeLock.lock(); try { index++; lazySet(o); } finally { - lock.unlockWrite(stamp); + writeLock.unlock(); } } @@ -281,7 +283,7 @@ public void onNext(T t) { } Object o = NotificationLite.next(t); setCurrent(o); - for (BehaviorSubscription bs : subscribers) { + for (BehaviorSubscription bs : subscribers.get()) { bs.emitNext(o, index); } } @@ -312,7 +314,7 @@ public void onComplete() { } } - static final class BehaviorSubscription extends AtomicLong implements Subscription { + static final class BehaviorSubscription extends AtomicLong implements Subscription, Predicate { /** */ private static final long serialVersionUID = 3293175281126227086L; @@ -366,19 +368,14 @@ void emitFirst() { } State s = state; - StampedLock lock = s.lock; - long stamp = lock.tryOptimisticRead(); - index = s.index; - o = s.get(); - if (!lock.validate(stamp)) { - stamp = lock.readLock(); - try { - index = s.index; - o = s.get(); - } finally { - lock.unlockRead(stamp); - } + Lock readLock = s.readLock; + readLock.lock(); + try { + index = s.index; + o = s.get(); + } finally { + readLock.unlock(); } emitting = o != null; @@ -386,7 +383,7 @@ void emitFirst() { } if (o != null) { - if (emit(o)) { + if (test(o)) { return; } @@ -409,7 +406,7 @@ void emitNext(Object value, long stateIndex) { if (emitting) { AppendOnlyLinkedArrayList q = queue; if (q == null) { - q = new AppendOnlyLinkedArrayList<>(4); + q = new AppendOnlyLinkedArrayList(4); queue = q; } q.add(value); @@ -420,10 +417,11 @@ void emitNext(Object value, long stateIndex) { fastPath = true; } - emit(value); + test(value); } - boolean emit(Object o) { + @Override + public boolean test(Object o) { if (cancelled) { return true; } @@ -441,7 +439,7 @@ boolean emit(Object o) { long r = get(); if (r != 0L) { - actual.onNext(NotificationLite.getValue(o)); + actual.onNext(NotificationLite.getValue(o)); if (r != Long.MAX_VALUE) { decrementAndGet(); } @@ -467,7 +465,7 @@ void emitLoop() { queue = null; } - q.forEachWhile(this::emit); + q.forEachWhile(this); } } } diff --git a/src/main/java/io/reactivex/subjects/PublishSubject.java b/src/main/java/io/reactivex/subjects/PublishSubject.java index 1e00e17010..78db4506f5 100644 --- a/src/main/java/io/reactivex/subjects/PublishSubject.java +++ b/src/main/java/io/reactivex/subjects/PublishSubject.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,11 +13,11 @@ package io.reactivex.subjects; import java.util.concurrent.atomic.*; -import java.util.function.IntFunction; import org.reactivestreams.*; import io.reactivex.exceptions.MissingBackpressureException; +import io.reactivex.functions.IntFunction; import io.reactivex.internal.subscriptions.SubscriptionHelper; import io.reactivex.internal.util.*; import io.reactivex.plugins.RxJavaPlugins; @@ -42,11 +42,12 @@ public final class PublishSubject extends Subject { /** * Constructs a PublishSubject. + * @param the value type * @return the new PublishSubject */ public static PublishSubject create() { - State state = new State<>(); - return new PublishSubject<>(state); + State state = new State(); + return new PublishSubject(state); } /** Holds the terminal event and manages the array of subscribers. */ @@ -163,7 +164,8 @@ public boolean hasComplete() { * @param the value type of the events */ @SuppressWarnings("rawtypes") - static final class State extends AtomicReference implements Publisher, IntFunction { + static final class State extends AtomicReference + implements Publisher, IntFunction[]> { /** */ private static final long serialVersionUID = -2699311989055418316L; /** The completion token. */ @@ -176,21 +178,17 @@ static final class State extends AtomicReference implements Publisher /** The array of currently subscribed subscribers. */ @SuppressWarnings("unchecked") - volatile PublishSubscriber[] subscribers = EMPTY; - - /** Field updater for subscribers. */ - static final AtomicReferenceFieldUpdater SUBSCRIBERS = - AtomicReferenceFieldUpdater.newUpdater(State.class, PublishSubscriber[].class, "subscribers"); + final AtomicReference[]> subscribers = new AtomicReference[]>(EMPTY); @Override public void subscribe(Subscriber t) { - PublishSubscriber ps = new PublishSubscriber<>(t, this); + PublishSubscriber ps = new PublishSubscriber(t, this); t.onSubscribe(ps); - if (ps.cancelled == 0) { + if (!ps.cancelled.get()) { if (add(ps)) { // if cancellation happened while a successful add, the remove() didn't work // so we need to do it again - if (ps.cancelled != 0) { + if (ps.cancelled.get()) { remove(ps); } } else { @@ -208,7 +206,7 @@ public void subscribe(Subscriber t) { * @return the array of currently subscribed subscribers */ PublishSubscriber[] subscribers() { - return subscribers; + return subscribers.get(); } /** @@ -229,7 +227,7 @@ PublishSubscriber[] terminate() { @SuppressWarnings("unchecked") PublishSubscriber[] terminate(Object event) { if (compareAndSet(null, event)) { - return TerminalAtomicsHelper.terminate(SUBSCRIBERS, this, TERMINATED); + return TerminalAtomicsHelper.terminate(subscribers, TERMINATED); } return TERMINATED; } @@ -240,20 +238,23 @@ PublishSubscriber[] terminate(Object event) { * @param ps the subscriber to add * @return true if successful, false if the subject has terminated */ + @SuppressWarnings("unchecked") boolean add(PublishSubscriber ps) { - return TerminalAtomicsHelper.add(SUBSCRIBERS, this, ps, TERMINATED, this); + return TerminalAtomicsHelper.add(subscribers, ps, TERMINATED, this); } /** * Atomically removes the given subscriber if it is subscribed to the subject. * @param ps the subject to remove */ + @SuppressWarnings("unchecked") void remove(PublishSubscriber ps) { - TerminalAtomicsHelper.remove(SUBSCRIBERS, this, ps, TERMINATED, EMPTY, this); + TerminalAtomicsHelper.remove(subscribers, ps, TERMINATED, EMPTY, this); } + @SuppressWarnings("unchecked") @Override - public PublishSubscriber[] apply(int value) { + public PublishSubscriber[] apply(int value) { return new PublishSubscriber[value]; } } @@ -272,12 +273,7 @@ static final class PublishSubscriber extends AtomicLong implements Subscriber /** The subject state. */ final State state; - /** Indicates the cancelled state if not zero. */ - volatile int cancelled; - /** Field updater for cancelled. */ - @SuppressWarnings("rawtypes") - static final AtomicIntegerFieldUpdater CANCELLED = - AtomicIntegerFieldUpdater.newUpdater(PublishSubscriber.class, "cancelled"); + final AtomicBoolean cancelled = new AtomicBoolean(); /** * Constructs a PublishSubscriber, wraps the actual subscriber and the state. @@ -328,7 +324,7 @@ public void request(long n) { @Override public void cancel() { - if (cancelled == 0 && CANCELLED.compareAndSet(this, 0, 1)) { + if (!cancelled.get() && cancelled.compareAndSet(false, true)) { state.remove(this); } } diff --git a/src/main/java/io/reactivex/subjects/ReplaySubject.java b/src/main/java/io/reactivex/subjects/ReplaySubject.java index 22718694ad..698604bcf1 100644 --- a/src/main/java/io/reactivex/subjects/ReplaySubject.java +++ b/src/main/java/io/reactivex/subjects/ReplaySubject.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -21,10 +21,11 @@ import org.reactivestreams.*; import io.reactivex.Scheduler; +import io.reactivex.internal.functions.Objects; import io.reactivex.internal.subscriptions.SubscriptionHelper; import io.reactivex.internal.util.*; import io.reactivex.plugins.RxJavaPlugins; -import io.reactivex.schedulers.*; +import io.reactivex.schedulers.Schedulers; /** * Replays events to Subscribers. @@ -43,7 +44,7 @@ public static ReplaySubject create(int capacityHint) { if (capacityHint <= 0) { throw new IllegalArgumentException("capacityHint > 0 required but it was " + capacityHint); } - ReplayBuffer buffer = new UnboundedReplayBuffer<>(capacityHint); + ReplayBuffer buffer = new UnboundedReplayBuffer(capacityHint); return createWithBuffer(buffer); } @@ -51,12 +52,12 @@ public static ReplaySubject createWithSize(int size) { if (size <= 0) { throw new IllegalArgumentException("size > 0 required but it was " + size); } - SizeBoundReplayBuffer buffer = new SizeBoundReplayBuffer<>(size); + SizeBoundReplayBuffer buffer = new SizeBoundReplayBuffer(size); return createWithBuffer(buffer); } /* test */ static ReplaySubject createUnbounded() { - SizeBoundReplayBuffer buffer = new SizeBoundReplayBuffer<>(Integer.MAX_VALUE); + SizeBoundReplayBuffer buffer = new SizeBoundReplayBuffer(Integer.MAX_VALUE); return createWithBuffer(buffer); } @@ -69,18 +70,18 @@ public static ReplaySubject createWithTime(long maxAge, TimeUnit unit, Sc } public static ReplaySubject createWithTimeAndSize(long maxAge, TimeUnit unit, Scheduler scheduler, int size) { - Objects.requireNonNull(unit); - Objects.requireNonNull(scheduler); + Objects.requireNonNull(unit, "unit is null"); + Objects.requireNonNull(scheduler, "scheduler is null"); if (size <= 0) { throw new IllegalArgumentException("size > 0 required but it was " + size); } - SizeAndTimeBoundReplayBuffer buffer = new SizeAndTimeBoundReplayBuffer<>(size, maxAge, unit, scheduler); + SizeAndTimeBoundReplayBuffer buffer = new SizeAndTimeBoundReplayBuffer(size, maxAge, unit, scheduler); return createWithBuffer(buffer); } static ReplaySubject createWithBuffer(ReplayBuffer buffer) { - State state = new State<>(buffer); - return new ReplaySubject<>(state); + State state = new State(buffer); + return new ReplaySubject(state); } @@ -120,11 +121,11 @@ public void onComplete() { @Override public boolean hasSubscribers() { - return state.subscribers.length != 0; + return state.subscribers.get().length != 0; } /* test */ int subscriberCount() { - return state.subscribers.length; + return state.subscribers.get().length; } @Override @@ -175,10 +176,7 @@ static final class State extends AtomicReference implements Publisher boolean done; - volatile ReplaySubscription[] subscribers; - @SuppressWarnings("rawtypes") - static final AtomicReferenceFieldUpdater SUBSCRIBERS = - AtomicReferenceFieldUpdater.newUpdater(State.class, ReplaySubscription[].class, "subscribers"); + final AtomicReference[]> subscribers; @SuppressWarnings("rawtypes") static final ReplaySubscription[] EMPTY = new ReplaySubscription[0]; @@ -186,14 +184,15 @@ static final class State extends AtomicReference implements Publisher @SuppressWarnings("rawtypes") static final ReplaySubscription[] TERMINATED = new ReplaySubscription[0]; + @SuppressWarnings("unchecked") public State(ReplayBuffer buffer) { this.buffer = buffer; - SUBSCRIBERS.lazySet(this, EMPTY); + this.subscribers = new AtomicReference[]>(EMPTY); } @Override public void subscribe(Subscriber s) { - ReplaySubscription rs = new ReplaySubscription<>(s, this); + ReplaySubscription rs = new ReplaySubscription(s, this); s.onSubscribe(rs); if (!rs.cancelled) { @@ -209,7 +208,7 @@ public void subscribe(Subscriber s) { public boolean add(ReplaySubscription rs) { for (;;) { - ReplaySubscription[] a = subscribers; + ReplaySubscription[] a = subscribers.get(); if (a == TERMINATED) { return false; } @@ -218,7 +217,7 @@ public boolean add(ReplaySubscription rs) { ReplaySubscription[] b = new ReplaySubscription[len + 1]; System.arraycopy(a, 0, b, 0, len); b[len] = rs; - if (SUBSCRIBERS.compareAndSet(this, a, b)) { + if (subscribers.compareAndSet(a, b)) { return true; } } @@ -227,7 +226,7 @@ public boolean add(ReplaySubscription rs) { @SuppressWarnings("unchecked") public void remove(ReplaySubscription rs) { for (;;) { - ReplaySubscription[] a = subscribers; + ReplaySubscription[] a = subscribers.get(); if (a == TERMINATED || a == EMPTY) { return; } @@ -251,7 +250,7 @@ public void remove(ReplaySubscription rs) { System.arraycopy(a, 0, b, 0, j); System.arraycopy(a, j + 1, b, j, len - j - 1); } - if (SUBSCRIBERS.compareAndSet(this, a, b)) { + if (subscribers.compareAndSet(a, b)) { return; } } @@ -260,7 +259,7 @@ public void remove(ReplaySubscription rs) { @SuppressWarnings("unchecked") public ReplaySubscription[] terminate(Object terminalValue) { if (compareAndSet(null, terminalValue)) { - return SUBSCRIBERS.getAndSet(this, TERMINATED); + return subscribers.getAndSet(TERMINATED); } return TERMINATED; } @@ -283,7 +282,7 @@ public void onNext(T t) { ReplayBuffer b = buffer; b.add(t); - for (ReplaySubscription rs : subscribers) { + for (ReplaySubscription rs : subscribers.get()) { b.replay(rs); } } @@ -349,23 +348,21 @@ static final class ReplaySubscription extends AtomicInteger implements Subscr Object index; - volatile long requested; - @SuppressWarnings("rawtypes") - static final AtomicLongFieldUpdater REQUESTED = - AtomicLongFieldUpdater.newUpdater(ReplaySubscription.class, "requested"); + final AtomicLong requested; volatile boolean cancelled; public ReplaySubscription(Subscriber actual, State state) { this.actual = actual; this.state = state; + this.requested = new AtomicLong(); } @Override public void request(long n) { if (SubscriptionHelper.validateRequest(n)) { return; } - BackpressureHelper.add(REQUESTED, this, n); + BackpressureHelper.add(requested, n); state.buffer.replay(this); } @@ -386,7 +383,7 @@ static final class UnboundedReplayBuffer implements ReplayBuffer { volatile int size; public UnboundedReplayBuffer(int capacityHint) { - this.buffer = new ArrayList<>(capacityHint); + this.buffer = new ArrayList(capacityHint); } @Override @@ -485,9 +482,9 @@ public void replay(ReplaySubscription rs) { } int s = size; - long r = rs.requested; + long r = rs.requested.get(); boolean unbounded = r == Long.MAX_VALUE; - long e = 0; + long e = 0L; while (s != index) { @@ -515,7 +512,7 @@ public void replay(ReplaySubscription rs) { } if (r == 0) { - r = rs.requested; + r = rs.requested.get() + e; if (r == 0) { break; } @@ -527,8 +524,10 @@ public void replay(ReplaySubscription rs) { index++; } - if (!unbounded) { - r = ReplaySubscription.REQUESTED.addAndGet(rs, e); + if (e != 0L) { + if (!unbounded) { + r = rs.requested.addAndGet(e); + } } if (index != size && r != 0L) { continue; @@ -593,7 +592,7 @@ static final class SizeBoundReplayBuffer implements ReplayBuffer { public SizeBoundReplayBuffer(int maxSize) { this.maxSize = maxSize; - Node h = new Node<>(null); + Node h = new Node(null); this.tail = h; this.head = h; } @@ -609,7 +608,7 @@ void trim() { @Override public void add(T value) { Object o = value; - Node n = new Node<>(o); + Node n = new Node(o); Node t = tail; tail = n; @@ -627,7 +626,7 @@ public void add(T value) { @Override public void addFinal(Object notificationLite) { Object o = notificationLite; - Node n = new Node<>(o); + Node n = new Node(o); Node t = tail; tail = n; @@ -715,7 +714,7 @@ public void replay(ReplaySubscription rs) { return; } - long r = rs.requested; + long r = rs.requested.get(); boolean unbounded = r == Long.MAX_VALUE; long e = 0; @@ -748,7 +747,7 @@ public void replay(ReplaySubscription rs) { } if (r == 0) { - r = rs.requested; + r = rs.requested.get() + e; if (r == 0) { break; } @@ -763,7 +762,7 @@ public void replay(ReplaySubscription rs) { if (e != 0L) { if (!unbounded) { - r = ReplaySubscription.REQUESTED.addAndGet(rs, e); + r = rs.requested.addAndGet(e); } } @@ -820,7 +819,7 @@ public SizeAndTimeBoundReplayBuffer(int maxSize, long maxAge, TimeUnit unit, Sch this.maxAge = maxAge; this.unit = unit; this.scheduler = scheduler; - TimedNode h = new TimedNode<>(null, 0L); + TimedNode h = new TimedNode(null, 0L); this.tail = h; this.head = h; } @@ -876,7 +875,7 @@ void trimFinal() { @Override public void add(T value) { Object o = value; - TimedNode n = new TimedNode<>(o, scheduler.now(unit)); + TimedNode n = new TimedNode(o, scheduler.now(unit)); TimedNode t = tail; tail = n; @@ -894,7 +893,7 @@ public void add(T value) { @Override public void addFinal(Object notificationLite) { Object o = notificationLite; - TimedNode n = new TimedNode<>(o, Long.MAX_VALUE); + TimedNode n = new TimedNode(o, Long.MAX_VALUE); TimedNode t = tail; tail = n; @@ -996,7 +995,7 @@ public void replay(ReplaySubscription rs) { return; } - long r = rs.requested; + long r = rs.requested.get(); boolean unbounded = r == Long.MAX_VALUE; long e = 0; @@ -1029,7 +1028,7 @@ public void replay(ReplaySubscription rs) { } if (r == 0) { - r = rs.requested; + r = rs.requested.get() + e; if (r == 0) { break; } @@ -1044,7 +1043,7 @@ public void replay(ReplaySubscription rs) { if (e != 0L) { if (!unbounded) { - r = ReplaySubscription.REQUESTED.addAndGet(rs, e); + r = rs.requested.addAndGet(e); } } @@ -1081,4 +1080,4 @@ public int size() { return s; } } -} +} \ No newline at end of file diff --git a/src/main/java/io/reactivex/subjects/SerializedSubject.java b/src/main/java/io/reactivex/subjects/SerializedSubject.java index e182ba290a..cf3f41c3bf 100644 --- a/src/main/java/io/reactivex/subjects/SerializedSubject.java +++ b/src/main/java/io/reactivex/subjects/SerializedSubject.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,8 +13,9 @@ package io.reactivex.subjects; -import org.reactivestreams.Subscription; +import org.reactivestreams.*; +import io.reactivex.functions.Predicate; import io.reactivex.internal.util.*; import io.reactivex.plugins.RxJavaPlugins; @@ -39,8 +40,13 @@ * Constructor that wraps an actual subject. * @param actual the subject wrapped */ - public SerializedSubject(Subject actual) { - super(actual::subscribe); + public SerializedSubject(final Subject actual) { + super(new Publisher() { + @Override + public void subscribe(Subscriber s) { + actual.subscribe(s); + } + }); this.actual = actual; } @@ -56,7 +62,7 @@ public void onSubscribe(Subscription s) { if (emitting) { AppendOnlyLinkedArrayList q = queue; if (q == null) { - q = new AppendOnlyLinkedArrayList<>(4); + q = new AppendOnlyLinkedArrayList(4); queue = q; } q.add(NotificationLite.subscription(s)); @@ -80,7 +86,7 @@ public void onNext(T t) { if (emitting) { AppendOnlyLinkedArrayList q = queue; if (q == null) { - q = new AppendOnlyLinkedArrayList<>(4); + q = new AppendOnlyLinkedArrayList(4); queue = q; } q.add(NotificationLite.next(t)); @@ -108,7 +114,7 @@ public void onError(Throwable t) { if (emitting) { AppendOnlyLinkedArrayList q = queue; if (q == null) { - q = new AppendOnlyLinkedArrayList<>(4); + q = new AppendOnlyLinkedArrayList(4); queue = q; } q.setFirst(NotificationLite.error(t)); @@ -138,7 +144,7 @@ public void onComplete() { if (emitting) { AppendOnlyLinkedArrayList q = queue; if (q == null) { - q = new AppendOnlyLinkedArrayList<>(4); + q = new AppendOnlyLinkedArrayList(4); queue = q; } q.add(NotificationLite.complete()); @@ -161,10 +167,17 @@ void emitLoop() { } queue = null; } - q.forEachWhile(this::accept); + q.forEachWhile(consumer); } } + final Predicate consumer = new Predicate() { + @Override + public boolean test(Object v) { + return SerializedSubject.this.accept(v); + } + }; + /** Delivers the notification to the actual subscriber. */ boolean accept(Object o) { return NotificationLite.acceptFull(o, actual); diff --git a/src/main/java/io/reactivex/subjects/Subject.java b/src/main/java/io/reactivex/subjects/Subject.java index 44ec061ca2..f912b51b02 100644 --- a/src/main/java/io/reactivex/subjects/Subject.java +++ b/src/main/java/io/reactivex/subjects/Subject.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -44,7 +44,7 @@ protected Subject(Publisher onSubscribe) { *

The method is thread-safe. * @return true if the subject has reached a terminal state through an error event * @see #getThrowable() - * &see {@link #hasComplete()} + * @see #hasComplete() */ public boolean hasThrowable() { throw new UnsupportedOperationException(); @@ -99,7 +99,7 @@ public final Subject toSerialized() { if (this instanceof SerializedSubject) { return this; } - return new SerializedSubject<>(this); + return new SerializedSubject(this); } /** An empty array to avoid allocation in getValues(). */ diff --git a/src/main/java/io/reactivex/subjects/UnicastSubject.java b/src/main/java/io/reactivex/subjects/UnicastSubject.java index 1b14fd364d..ea273ce8b8 100644 --- a/src/main/java/io/reactivex/subjects/UnicastSubject.java +++ b/src/main/java/io/reactivex/subjects/UnicastSubject.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -40,6 +40,7 @@ public final class UnicastSubject extends Subject { /** * Creates an UnicastSubject with an internal buffer capacity hint 16. + * @param the value type * @return an UnicastSubject instance */ public static UnicastSubject create() { @@ -48,6 +49,7 @@ public static UnicastSubject create() { /** * Creates an UnicastSubject with the given internal buffer capacity hint. + * @param the value type * @param capacityHint the hint to size the internal unbounded buffer * @return an UnicastSubject instance */ @@ -62,13 +64,14 @@ public static UnicastSubject create(int capacityHint) { *

The callback, if not null, is called exactly once and * non-overlapped with any active replay. * + * @param the value type * @param capacityHint the hint to size the internal unbounded buffer * @param onCancelled the optional callback * @return an UnicastSubject instance */ public static UnicastSubject create(int capacityHint, Runnable onCancelled) { - State state = new State<>(capacityHint, onCancelled); - return new UnicastSubject<>(state); + State state = new State(capacityHint, onCancelled); + return new UnicastSubject(state); } /** The subject state. */ @@ -98,10 +101,7 @@ static abstract class StateRequested extends StatePad0 { /** */ private static final long serialVersionUID = -2744070795149472578L; /** Holds the current requested amount. */ - volatile long requested; - /** Updater to the field requested. */ - static final AtomicLongFieldUpdater REQUESTED = - AtomicLongFieldUpdater.newUpdater(StateRequested.class, "requested"); + final AtomicLong requested = new AtomicLong(); } /** Pads away the requested counter. */ @@ -123,11 +123,7 @@ static final class State extends StatePad1 implements Publisher, Subscript final Queue queue; /** The single subscriber. */ - volatile Subscriber subscriber; - /** Updater to the field subscriber. */ - @SuppressWarnings("rawtypes") - static final AtomicReferenceFieldUpdater SUBSCRIBER = - AtomicReferenceFieldUpdater.newUpdater(State.class, Subscriber.class, "subscriber"); + final AtomicReference> subscriber = new AtomicReference>(); /** Indicates the single subscriber has cancelled. */ volatile boolean cancelled; @@ -141,11 +137,7 @@ static final class State extends StatePad1 implements Publisher, Subscript Throwable error; /** Set to 1 atomically for the first and only Subscriber. */ - volatile int once; - /** Updater to field once. */ - @SuppressWarnings("rawtypes") - static final AtomicIntegerFieldUpdater ONCE = - AtomicIntegerFieldUpdater.newUpdater(State.class, "once"); + final AtomicBoolean once = new AtomicBoolean(); /** * Called when the Subscriber has called cancel. @@ -161,14 +153,19 @@ static final class State extends StatePad1 implements Publisher, Subscript */ public State(int capacityHint, Runnable onCancelled) { this.onCancelled = onCancelled; - queue = new SpscLinkedArrayQueue<>(capacityHint); + queue = new SpscLinkedArrayQueue(capacityHint); } @Override public void subscribe(Subscriber s) { - if (once == 0 && ONCE.compareAndSet(this, 0, 1)) { - SUBSCRIBER.lazySet(this, s); + if (!once.get() && once.compareAndSet(false, true)) { s.onSubscribe(this); + subscriber.lazySet(s); // full barrier in drain + if (cancelled) { + subscriber.lazySet(null); + return; + } + drain(); } else { if (done) { Throwable e = error; @@ -188,7 +185,7 @@ public void request(long n) { if (SubscriptionHelper.validateRequest(n)) { return; } - BackpressureHelper.add(REQUESTED, this, n); + BackpressureHelper.add(requested, n); drain(); } @@ -216,7 +213,7 @@ void notifyOnCancelled() { * @param q the queue reference (avoid re-reading instance field). */ void clear(Queue q) { - SUBSCRIBER.lazySet(this, null); + subscriber.lazySet(null); q.clear(); notifyOnCancelled(); } @@ -271,7 +268,7 @@ void drain() { } final Queue q = queue; - Subscriber a = subscriber; + Subscriber a = subscriber.get(); int missed = 1; for (;;) { @@ -287,7 +284,7 @@ void drain() { boolean d = done; boolean empty = q.isEmpty(); if (d && empty) { - SUBSCRIBER.lazySet(this, null); + subscriber.lazySet(null); Throwable ex = error; if (ex != null) { a.onError(ex); @@ -297,7 +294,7 @@ void drain() { return; } - long r = requested; + long r = requested.get(); boolean unbounded = r == Long.MAX_VALUE; long e = 0L; @@ -314,7 +311,7 @@ void drain() { empty = v == null; if (d && empty) { - SUBSCRIBER.lazySet(this, null); + subscriber.lazySet(null); Throwable ex = error; if (ex != null) { a.onError(ex); @@ -335,7 +332,7 @@ void drain() { } if (e != 0 && !unbounded) { - REQUESTED.getAndAdd(this, e); + requested.getAndAdd(e); } } @@ -346,7 +343,7 @@ void drain() { } if (a == null) { - a = subscriber; + a = subscriber.get(); } } } @@ -415,4 +412,4 @@ public T[] getValues(T[] array) { } return array; } -} +} \ No newline at end of file diff --git a/src/main/java/io/reactivex/subjects/nbp/NbpAsyncSubject.java b/src/main/java/io/reactivex/subjects/nbp/NbpAsyncSubject.java index 8994338605..9f8ccd389a 100644 --- a/src/main/java/io/reactivex/subjects/nbp/NbpAsyncSubject.java +++ b/src/main/java/io/reactivex/subjects/nbp/NbpAsyncSubject.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -34,8 +34,8 @@ public final class NbpAsyncSubject extends NbpSubject { public static NbpAsyncSubject create() { - State state = new State<>(); - return new NbpAsyncSubject<>(state); + State state = new State(); + return new NbpAsyncSubject(state); } final State state; @@ -46,7 +46,7 @@ protected NbpAsyncSubject(State state) { @Override public void onSubscribe(Disposable d) { - if (state.subscribers == State.TERMINATED) { + if (state.subscribers.get() == State.TERMINATED) { d.dispose(); } } @@ -68,7 +68,7 @@ public void onComplete() { @Override public boolean hasSubscribers() { - return state.subscribers.length != 0; + return state.subscribers.get().length != 0; } @Override @@ -123,7 +123,7 @@ public T[] getValues(T[] array) { @Override public boolean hasComplete() { - return state.subscribers == State.TERMINATED && !NotificationLite.isError(state.get()); + return state.subscribers.get() == State.TERMINATED && !NotificationLite.isError(state.get()); } @Override @@ -141,10 +141,7 @@ static final class State extends AtomicReference implements NbpOnSubs /** */ private static final long serialVersionUID = 4876574210612691772L; - volatile NbpSubscriber[] subscribers; - @SuppressWarnings("rawtypes") - static final AtomicReferenceFieldUpdater SUBSCRIBERS = - AtomicReferenceFieldUpdater.newUpdater(State.class, NbpSubscriber[].class, "subscribers"); + final AtomicReference[]> subscribers; @SuppressWarnings("rawtypes") static final NbpSubscriber[] EMPTY = new NbpSubscriber[0]; @@ -153,13 +150,14 @@ static final class State extends AtomicReference implements NbpOnSubs boolean done; + @SuppressWarnings("unchecked") public State() { - SUBSCRIBERS.lazySet(this, EMPTY); + subscribers = new AtomicReference[]>(EMPTY); } boolean add(NbpSubscriber s) { for (;;) { - NbpSubscriber[] a = subscribers; + NbpSubscriber[] a = subscribers.get(); if (a == TERMINATED) { return false; } @@ -170,7 +168,7 @@ boolean add(NbpSubscriber s) { System.arraycopy(a, 0, b, 0, n); b[n] = s; - if (SUBSCRIBERS.compareAndSet(this, a, b)) { + if (subscribers.compareAndSet(a, b)) { return true; } } @@ -179,7 +177,7 @@ boolean add(NbpSubscriber s) { @SuppressWarnings("unchecked") void remove(NbpSubscriber s) { for (;;) { - NbpSubscriber[] a = subscribers; + NbpSubscriber[] a = subscribers.get(); if (a == TERMINATED || a == EMPTY) { return; } @@ -203,7 +201,7 @@ void remove(NbpSubscriber s) { System.arraycopy(a, 0, b, 0, j); System.arraycopy(a, j + 1, b, j, n - j - 1); } - if (SUBSCRIBERS.compareAndSet(this, a, b)) { + if (subscribers.compareAndSet(a, b)) { return; } } @@ -212,9 +210,9 @@ void remove(NbpSubscriber s) { @SuppressWarnings("unchecked") NbpSubscriber[] terminate(Object notification) { if (compareAndSet(get(), notification)) { - NbpSubscriber[] a = subscribers; + NbpSubscriber[] a = subscribers.get(); if (a != TERMINATED) { - return SUBSCRIBERS.getAndSet(this, TERMINATED); + return subscribers.getAndSet(TERMINATED); } } return TERMINATED; @@ -227,14 +225,19 @@ void emit(NbpSubscriber t, Object v) { if (NotificationLite.isError(v)) { t.onError(NotificationLite.getError(v)); } else { - t.onNext(NotificationLite.getValue(v)); + t.onNext(NotificationLite.getValue(v)); t.onComplete(); } } @Override - public void accept(NbpSubscriber t) { - BooleanDisposable bd = new BooleanDisposable(() -> remove(t)); + public void accept(final NbpSubscriber t) { + BooleanDisposable bd = new BooleanDisposable(new Runnable() { + @Override + public void run() { + remove(t); + } + }); t.onSubscribe(bd); if (add(t)) { if (bd.isDisposed()) { @@ -258,6 +261,10 @@ public void onNext(T value) { if (done) { return; } + if (value == null) { + onError(new NullPointerException()); + return; + } lazySet(value); } @@ -268,6 +275,9 @@ public void onError(Throwable e) { return; } done = true; + if (e == null) { + e = new NullPointerException(); + } for (NbpSubscriber v : terminate(NotificationLite.error(e))) { v.onError(e); } @@ -292,4 +302,4 @@ public void onComplete() { } } } -} +} \ No newline at end of file diff --git a/src/main/java/io/reactivex/subjects/nbp/NbpBehaviorSubject.java b/src/main/java/io/reactivex/subjects/nbp/NbpBehaviorSubject.java index 699b4c8caa..10707bc80d 100644 --- a/src/main/java/io/reactivex/subjects/nbp/NbpBehaviorSubject.java +++ b/src/main/java/io/reactivex/subjects/nbp/NbpBehaviorSubject.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -14,27 +14,28 @@ package io.reactivex.subjects.nbp; import java.lang.reflect.Array; -import java.util.Objects; import java.util.concurrent.atomic.*; -import java.util.concurrent.locks.StampedLock; +import java.util.concurrent.locks.*; import io.reactivex.disposables.Disposable; +import io.reactivex.functions.Predicate; +import io.reactivex.internal.functions.Objects; import io.reactivex.internal.util.*; import io.reactivex.plugins.RxJavaPlugins; public final class NbpBehaviorSubject extends NbpSubject { public static NbpBehaviorSubject create() { - State state = new State<>(); - return new NbpBehaviorSubject<>(state); + State state = new State(); + return new NbpBehaviorSubject(state); } - // TODO a plain create() would create a method ambiguity with Observable.create with javac + // A plain create(T) would create a method ambiguity with Observable.create with javac public static NbpBehaviorSubject createDefault(T defaultValue) { - Objects.requireNonNull(defaultValue); - State state = new State<>(); + Objects.requireNonNull(defaultValue, "defaultValue is null"); + State state = new State(); state.lazySet(defaultValue); - return new NbpBehaviorSubject<>(state); + return new NbpBehaviorSubject(state); } final State state; @@ -72,12 +73,12 @@ public void onComplete() { @Override public boolean hasSubscribers() { - return state.subscribers.length != 0; + return state.subscribers.get().length != 0; } /* test support*/ int subscriberCount() { - return state.subscribers.length; + return state.subscribers.get().length; } @Override @@ -145,11 +146,7 @@ static final class State extends AtomicReference implements NbpOnSubs boolean done; - volatile BehaviorDisposable[] subscribers; - - @SuppressWarnings("rawtypes") - static final AtomicReferenceFieldUpdater SUBSCRIBERS = - AtomicReferenceFieldUpdater.newUpdater(State.class, BehaviorDisposable[].class, "subscribers"); + final AtomicReference[]> subscribers; @SuppressWarnings("rawtypes") static final BehaviorDisposable[] EMPTY = new BehaviorDisposable[0]; @@ -159,16 +156,21 @@ static final class State extends AtomicReference implements NbpOnSubs long index; - final StampedLock lock; + final ReadWriteLock lock; + final Lock readLock; + final Lock writeLock; + @SuppressWarnings("unchecked") public State() { - this.lock = new StampedLock(); - SUBSCRIBERS.lazySet(this, EMPTY); + this.lock = new ReentrantReadWriteLock(); + this.readLock = lock.readLock(); + this.writeLock = lock.writeLock(); + this.subscribers = new AtomicReference[]>(EMPTY); } public boolean add(BehaviorDisposable rs) { for (;;) { - BehaviorDisposable[] a = subscribers; + BehaviorDisposable[] a = subscribers.get(); if (a == TERMINATED) { return false; } @@ -177,7 +179,7 @@ public boolean add(BehaviorDisposable rs) { BehaviorDisposable[] b = new BehaviorDisposable[len + 1]; System.arraycopy(a, 0, b, 0, len); b[len] = rs; - if (SUBSCRIBERS.compareAndSet(this, a, b)) { + if (subscribers.compareAndSet(a, b)) { return true; } } @@ -186,7 +188,7 @@ public boolean add(BehaviorDisposable rs) { @SuppressWarnings("unchecked") public void remove(BehaviorDisposable rs) { for (;;) { - BehaviorDisposable[] a = subscribers; + BehaviorDisposable[] a = subscribers.get(); if (a == TERMINATED || a == EMPTY) { return; } @@ -210,7 +212,7 @@ public void remove(BehaviorDisposable rs) { System.arraycopy(a, 0, b, 0, j); System.arraycopy(a, j + 1, b, j, len - j - 1); } - if (SUBSCRIBERS.compareAndSet(this, a, b)) { + if (subscribers.compareAndSet(a, b)) { return; } } @@ -219,9 +221,9 @@ public void remove(BehaviorDisposable rs) { @SuppressWarnings("unchecked") public BehaviorDisposable[] terminate(Object terminalValue) { - BehaviorDisposable[] a = subscribers; + BehaviorDisposable[] a = subscribers.get(); if (a != TERMINATED) { - a = SUBSCRIBERS.getAndSet(this, TERMINATED); + a = subscribers.getAndSet(TERMINATED); if (a != TERMINATED) { // either this or atomics with lots of allocation setCurrent(terminalValue); @@ -233,7 +235,7 @@ public BehaviorDisposable[] terminate(Object terminalValue) { @Override public void accept(NbpSubscriber s) { - BehaviorDisposable bs = new BehaviorDisposable<>(s, this); + BehaviorDisposable bs = new BehaviorDisposable(s, this); s.onSubscribe(bs); if (!bs.cancelled) { if (add(bs)) { @@ -262,12 +264,12 @@ public void onSubscribe(Disposable s) { } void setCurrent(Object o) { - long stamp = lock.writeLock(); + writeLock.lock(); try { index++; lazySet(o); } finally { - lock.unlockWrite(stamp); + writeLock.unlock(); } } @@ -278,7 +280,7 @@ public void onNext(T t) { } Object o = NotificationLite.next(t); setCurrent(o); - for (BehaviorDisposable bs : subscribers) { + for (BehaviorDisposable bs : subscribers.get()) { bs.emitNext(o, index); } } @@ -309,7 +311,7 @@ public void onComplete() { } } - static final class BehaviorDisposable implements Disposable { + static final class BehaviorDisposable implements Disposable, Predicate { final NbpSubscriber actual; final State state; @@ -352,19 +354,14 @@ void emitFirst() { } State s = state; - StampedLock lock = s.lock; + Lock lock = s.readLock; - long stamp = lock.tryOptimisticRead(); - index = s.index; - o = s.get(); - if (!lock.validate(stamp)) { - stamp = lock.readLock(); - try { - index = s.index; - o = s.get(); - } finally { - lock.unlockRead(stamp); - } + lock.lock(); + try { + index = s.index; + o = s.get(); + } finally { + lock.unlock(); } emitting = o != null; @@ -372,7 +369,7 @@ void emitFirst() { } if (o != null) { - if (emit(o)) { + if (test(o)) { return; } @@ -395,7 +392,7 @@ void emitNext(Object value, long stateIndex) { if (emitting) { AppendOnlyLinkedArrayList q = queue; if (q == null) { - q = new AppendOnlyLinkedArrayList<>(4); + q = new AppendOnlyLinkedArrayList(4); queue = q; } q.add(value); @@ -406,10 +403,11 @@ void emitNext(Object value, long stateIndex) { fastPath = true; } - emit(value); + test(value); } - boolean emit(Object o) { + @Override + public boolean test(Object o) { if (cancelled) { return true; } @@ -431,7 +429,7 @@ void emitLoop() { queue = null; } - q.forEachWhile(this::emit); + q.forEachWhile(this); } } } diff --git a/src/main/java/io/reactivex/subjects/nbp/NbpPublishSubject.java b/src/main/java/io/reactivex/subjects/nbp/NbpPublishSubject.java index f2b1caebf7..4c07c6a086 100644 --- a/src/main/java/io/reactivex/subjects/nbp/NbpPublishSubject.java +++ b/src/main/java/io/reactivex/subjects/nbp/NbpPublishSubject.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -22,8 +22,8 @@ public final class NbpPublishSubject extends NbpSubject { public static NbpPublishSubject create() { - State state = new State<>(); - return new NbpPublishSubject<>(state); + State state = new State(); + return new NbpPublishSubject(state); } final State state; @@ -34,7 +34,9 @@ protected NbpPublishSubject(State state) { @Override public void onSubscribe(Disposable d) { - // NbpSubjects never cancel the disposable + if (state.done) { + d.dispose(); + } } @Override @@ -54,7 +56,7 @@ public void onComplete() { @Override public boolean hasSubscribers() { - return state.subscribers.length != 0; + return state.subscribers.get().length != 0; } @Override @@ -99,25 +101,23 @@ static final class State extends AtomicReference implements NbpOnSubs /** */ private static final long serialVersionUID = 4876574210612691772L; - volatile NbpSubscriber[] subscribers; - @SuppressWarnings("rawtypes") - static final AtomicReferenceFieldUpdater SUBSCRIBERS = - AtomicReferenceFieldUpdater.newUpdater(State.class, NbpSubscriber[].class, "subscribers"); + final AtomicReference[]> subscribers = new AtomicReference[]>(); @SuppressWarnings("rawtypes") static final NbpSubscriber[] EMPTY = new NbpSubscriber[0]; @SuppressWarnings("rawtypes") static final NbpSubscriber[] TERMINATED = new NbpSubscriber[0]; - boolean done; + volatile boolean done; + @SuppressWarnings("unchecked") public State() { - SUBSCRIBERS.lazySet(this, EMPTY); + subscribers.lazySet(EMPTY); } boolean add(NbpSubscriber s) { for (;;) { - NbpSubscriber[] a = subscribers; + NbpSubscriber[] a = subscribers.get(); if (a == TERMINATED) { return false; } @@ -128,7 +128,7 @@ boolean add(NbpSubscriber s) { System.arraycopy(a, 0, b, 0, n); b[n] = s; - if (SUBSCRIBERS.compareAndSet(this, a, b)) { + if (subscribers.compareAndSet(a, b)) { return true; } } @@ -137,7 +137,7 @@ boolean add(NbpSubscriber s) { @SuppressWarnings("unchecked") void remove(NbpSubscriber s) { for (;;) { - NbpSubscriber[] a = subscribers; + NbpSubscriber[] a = subscribers.get(); if (a == TERMINATED || a == EMPTY) { return; } @@ -161,7 +161,7 @@ void remove(NbpSubscriber s) { System.arraycopy(a, 0, b, 0, j); System.arraycopy(a, j + 1, b, j, n - j - 1); } - if (SUBSCRIBERS.compareAndSet(this, a, b)) { + if (subscribers.compareAndSet(a, b)) { return; } } @@ -170,9 +170,9 @@ void remove(NbpSubscriber s) { @SuppressWarnings("unchecked") NbpSubscriber[] terminate(Object notification) { if (compareAndSet(null, notification)) { - NbpSubscriber[] a = subscribers; + NbpSubscriber[] a = subscribers.get(); if (a != TERMINATED) { - return SUBSCRIBERS.getAndSet(this, TERMINATED); + return subscribers.getAndSet(TERMINATED); } } return TERMINATED; @@ -187,14 +187,19 @@ void emit(NbpSubscriber t, Object v) { } @Override - public void accept(NbpSubscriber t) { + public void accept(final NbpSubscriber t) { Object v = get(); if (v != null) { t.onSubscribe(EmptyDisposable.INSTANCE); emit(t, v); return; } - BooleanDisposable bd = new BooleanDisposable(() -> remove(t)); + BooleanDisposable bd = new BooleanDisposable(new Runnable() { + @Override + public void run() { + remove(t); + } + }); t.onSubscribe(bd); if (add(t)) { if (bd.isDisposed()) { @@ -218,7 +223,11 @@ public void onNext(T value) { if (done) { return; } - for (NbpSubscriber v : subscribers) { + if (value == null) { + onError(new NullPointerException("The value is null")); + return; + } + for (NbpSubscriber v : subscribers.get()) { v.onNext(value); } } @@ -230,6 +239,10 @@ public void onError(Throwable e) { return; } done = true; + if (e == null) { + e = new NullPointerException(); + } + for (NbpSubscriber v : terminate(NotificationLite.error(e))) { v.onError(e); } @@ -246,4 +259,4 @@ public void onComplete() { } } } -} +} \ No newline at end of file diff --git a/src/main/java/io/reactivex/subjects/nbp/NbpReplaySubject.java b/src/main/java/io/reactivex/subjects/nbp/NbpReplaySubject.java index ea4f1baa0b..dc2c1a7f2d 100644 --- a/src/main/java/io/reactivex/subjects/nbp/NbpReplaySubject.java +++ b/src/main/java/io/reactivex/subjects/nbp/NbpReplaySubject.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -20,6 +20,7 @@ import io.reactivex.Scheduler; import io.reactivex.disposables.Disposable; +import io.reactivex.internal.functions.Objects; import io.reactivex.internal.util.NotificationLite; import io.reactivex.plugins.RxJavaPlugins; import io.reactivex.schedulers.Schedulers; @@ -41,7 +42,7 @@ public static NbpReplaySubject create(int capacityHint) { if (capacityHint <= 0) { throw new IllegalArgumentException("capacityHint > 0 required but it was " + capacityHint); } - ReplayBuffer buffer = new UnboundedReplayBuffer<>(capacityHint); + ReplayBuffer buffer = new UnboundedReplayBuffer(capacityHint); return createWithBuffer(buffer); } @@ -49,12 +50,12 @@ public static NbpReplaySubject createWithSize(int size) { if (size <= 0) { throw new IllegalArgumentException("size > 0 required but it was " + size); } - SizeBoundReplayBuffer buffer = new SizeBoundReplayBuffer<>(size); + SizeBoundReplayBuffer buffer = new SizeBoundReplayBuffer(size); return createWithBuffer(buffer); } /* test */ static NbpReplaySubject createUnbounded() { - SizeBoundReplayBuffer buffer = new SizeBoundReplayBuffer<>(Integer.MAX_VALUE); + SizeBoundReplayBuffer buffer = new SizeBoundReplayBuffer(Integer.MAX_VALUE); return createWithBuffer(buffer); } @@ -67,18 +68,18 @@ public static NbpReplaySubject createWithTime(long maxAge, TimeUnit unit, } public static NbpReplaySubject createWithTimeAndSize(long maxAge, TimeUnit unit, Scheduler scheduler, int size) { - Objects.requireNonNull(unit); - Objects.requireNonNull(scheduler); + Objects.requireNonNull(unit, "unit is null"); + Objects.requireNonNull(scheduler, "scheduler is null"); if (size <= 0) { throw new IllegalArgumentException("size > 0 required but it was " + size); } - SizeAndTimeBoundReplayBuffer buffer = new SizeAndTimeBoundReplayBuffer<>(size, maxAge, unit, scheduler); + SizeAndTimeBoundReplayBuffer buffer = new SizeAndTimeBoundReplayBuffer(size, maxAge, unit, scheduler); return createWithBuffer(buffer); } static NbpReplaySubject createWithBuffer(ReplayBuffer buffer) { - State state = new State<>(buffer); - return new NbpReplaySubject<>(state); + State state = new State(buffer); + return new NbpReplaySubject(state); } @@ -118,11 +119,11 @@ public void onComplete() { @Override public boolean hasSubscribers() { - return state.subscribers.length != 0; + return state.subscribers.get().length != 0; } /* test */ int subscriberCount() { - return state.subscribers.length; + return state.subscribers.get().length; } @Override @@ -173,10 +174,7 @@ static final class State extends AtomicReference implements NbpOnSubs boolean done; - volatile ReplayDisposable[] subscribers; - @SuppressWarnings("rawtypes") - static final AtomicReferenceFieldUpdater SUBSCRIBERS = - AtomicReferenceFieldUpdater.newUpdater(State.class, ReplayDisposable[].class, "subscribers"); + final AtomicReference[]> subscribers = new AtomicReference[]>(); @SuppressWarnings("rawtypes") static final ReplayDisposable[] EMPTY = new ReplayDisposable[0]; @@ -184,14 +182,15 @@ static final class State extends AtomicReference implements NbpOnSubs @SuppressWarnings("rawtypes") static final ReplayDisposable[] TERMINATED = new ReplayDisposable[0]; + @SuppressWarnings("unchecked") public State(ReplayBuffer buffer) { this.buffer = buffer; - SUBSCRIBERS.lazySet(this, EMPTY); + subscribers.lazySet(EMPTY); } @Override public void accept(NbpSubscriber s) { - ReplayDisposable rs = new ReplayDisposable<>(s, this); + ReplayDisposable rs = new ReplayDisposable(s, this); s.onSubscribe(rs); if (!rs.cancelled) { @@ -207,7 +206,7 @@ public void accept(NbpSubscriber s) { public boolean add(ReplayDisposable rs) { for (;;) { - ReplayDisposable[] a = subscribers; + ReplayDisposable[] a = subscribers.get(); if (a == TERMINATED) { return false; } @@ -216,7 +215,7 @@ public boolean add(ReplayDisposable rs) { ReplayDisposable[] b = new ReplayDisposable[len + 1]; System.arraycopy(a, 0, b, 0, len); b[len] = rs; - if (SUBSCRIBERS.compareAndSet(this, a, b)) { + if (subscribers.compareAndSet(a, b)) { return true; } } @@ -225,7 +224,7 @@ public boolean add(ReplayDisposable rs) { @SuppressWarnings("unchecked") public void remove(ReplayDisposable rs) { for (;;) { - ReplayDisposable[] a = subscribers; + ReplayDisposable[] a = subscribers.get(); if (a == TERMINATED || a == EMPTY) { return; } @@ -249,7 +248,7 @@ public void remove(ReplayDisposable rs) { System.arraycopy(a, 0, b, 0, j); System.arraycopy(a, j + 1, b, j, len - j - 1); } - if (SUBSCRIBERS.compareAndSet(this, a, b)) { + if (subscribers.compareAndSet(a, b)) { return; } } @@ -258,7 +257,7 @@ public void remove(ReplayDisposable rs) { @SuppressWarnings("unchecked") public ReplayDisposable[] terminate(Object terminalValue) { if (compareAndSet(null, terminalValue)) { - return SUBSCRIBERS.getAndSet(this, TERMINATED); + return subscribers.getAndSet(TERMINATED); } return TERMINATED; } @@ -279,7 +278,7 @@ public void onNext(T t) { ReplayBuffer b = buffer; b.add(t); - for (ReplayDisposable rs : subscribers) { + for (ReplayDisposable rs : subscribers.get()) { // FIXME there is a caught-up optimization possible here as is with 1.x b.replay(rs); } @@ -370,7 +369,7 @@ static final class UnboundedReplayBuffer implements ReplayBuffer { volatile int size; public UnboundedReplayBuffer(int capacityHint) { - this.buffer = new ArrayList<>(capacityHint); + this.buffer = new ArrayList(capacityHint); } @Override @@ -562,7 +561,7 @@ static final class SizeBoundReplayBuffer implements ReplayBuffer { public SizeBoundReplayBuffer(int maxSize) { this.maxSize = maxSize; - Node h = new Node<>(null); + Node h = new Node(null); this.tail = h; this.head = h; } @@ -578,7 +577,7 @@ void trim() { @Override public void add(T value) { Object o = value; - Node n = new Node<>(o); + Node n = new Node(o); Node t = tail; tail = n; @@ -596,7 +595,7 @@ public void add(T value) { @Override public void addFinal(Object notificationLite) { Object o = notificationLite; - Node n = new Node<>(o); + Node n = new Node(o); Node t = tail; tail = n; @@ -770,7 +769,7 @@ public SizeAndTimeBoundReplayBuffer(int maxSize, long maxAge, TimeUnit unit, Sch this.maxAge = maxAge; this.unit = unit; this.scheduler = scheduler; - TimedNode h = new TimedNode<>(null, 0L); + TimedNode h = new TimedNode(null, 0L); this.tail = h; this.head = h; } @@ -826,7 +825,7 @@ void trimFinal() { @Override public void add(T value) { Object o = value; - TimedNode n = new TimedNode<>(o, scheduler.now(unit)); + TimedNode n = new TimedNode(o, scheduler.now(unit)); TimedNode t = tail; tail = n; @@ -844,7 +843,7 @@ public void add(T value) { @Override public void addFinal(Object notificationLite) { Object o = notificationLite; - TimedNode n = new TimedNode<>(o, Long.MAX_VALUE); + TimedNode n = new TimedNode(o, Long.MAX_VALUE); TimedNode t = tail; tail = n; diff --git a/src/main/java/io/reactivex/subjects/nbp/NbpSerializedSubject.java b/src/main/java/io/reactivex/subjects/nbp/NbpSerializedSubject.java index 3e87c7851d..ff32dadb15 100644 --- a/src/main/java/io/reactivex/subjects/nbp/NbpSerializedSubject.java +++ b/src/main/java/io/reactivex/subjects/nbp/NbpSerializedSubject.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -14,6 +14,7 @@ package io.reactivex.subjects.nbp; import io.reactivex.disposables.Disposable; +import io.reactivex.functions.Predicate; import io.reactivex.internal.util.*; import io.reactivex.plugins.RxJavaPlugins; @@ -38,8 +39,13 @@ * Constructor that wraps an actual subject. * @param actual the subject wrapped */ - public NbpSerializedSubject(NbpSubject actual) { - super(actual::subscribe); + public NbpSerializedSubject(final NbpSubject actual) { + super(new io.reactivex.NbpObservable.NbpOnSubscribe() { + @Override + public void accept(io.reactivex.NbpObservable.NbpSubscriber s) { + actual.subscribe(s); + } + }); this.actual = actual; } @@ -60,7 +66,7 @@ public void onNext(T t) { if (emitting) { AppendOnlyLinkedArrayList q = queue; if (q == null) { - q = new AppendOnlyLinkedArrayList<>(4); + q = new AppendOnlyLinkedArrayList(4); queue = q; } q.add(NotificationLite.next(t)); @@ -88,7 +94,7 @@ public void onError(Throwable t) { if (emitting) { AppendOnlyLinkedArrayList q = queue; if (q == null) { - q = new AppendOnlyLinkedArrayList<>(4); + q = new AppendOnlyLinkedArrayList(4); queue = q; } q.setFirst(NotificationLite.error(t)); @@ -118,7 +124,7 @@ public void onComplete() { if (emitting) { AppendOnlyLinkedArrayList q = queue; if (q == null) { - q = new AppendOnlyLinkedArrayList<>(4); + q = new AppendOnlyLinkedArrayList(4); queue = q; } q.add(NotificationLite.complete()); @@ -141,9 +147,16 @@ void emitLoop() { } queue = null; } - q.forEachWhile(this::accept); + q.forEachWhile(consumer); } } + + final Predicate consumer = new Predicate() { + @Override + public boolean test(Object v) { + return accept(v); + } + }; /** Delivers the notification to the actual subscriber. */ boolean accept(Object o) { diff --git a/src/main/java/io/reactivex/subjects/nbp/NbpSubject.java b/src/main/java/io/reactivex/subjects/nbp/NbpSubject.java index 7d0cbb4e07..b30aa892d7 100644 --- a/src/main/java/io/reactivex/subjects/nbp/NbpSubject.java +++ b/src/main/java/io/reactivex/subjects/nbp/NbpSubject.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -98,7 +98,7 @@ public final NbpSubject toSerialized() { if (this instanceof NbpSerializedSubject) { return this; } - return new NbpSerializedSubject<>(this); + return new NbpSerializedSubject(this); } /** An empty array to avoid allocation in getValues(). */ diff --git a/src/main/java/io/reactivex/subjects/nbp/NbpUnicastSubject.java b/src/main/java/io/reactivex/subjects/nbp/NbpUnicastSubject.java index ae29966819..2efca09044 100644 --- a/src/main/java/io/reactivex/subjects/nbp/NbpUnicastSubject.java +++ b/src/main/java/io/reactivex/subjects/nbp/NbpUnicastSubject.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -38,6 +38,7 @@ public final class NbpUnicastSubject extends NbpSubject { /** * Creates an UnicastSubject with an internal buffer capacity hint 16. + * @param the value type * @return an UnicastSubject instance */ public static NbpUnicastSubject create() { @@ -46,6 +47,7 @@ public static NbpUnicastSubject create() { /** * Creates an UnicastSubject with the given internal buffer capacity hint. + * @param the value type * @param capacityHint the hint to size the internal unbounded buffer * @return an UnicastSubject instance */ @@ -60,13 +62,14 @@ public static NbpUnicastSubject create(int capacityHint) { *

The callback, if not null, is called exactly once and * non-overlapped with any active replay. * + * @param the value type * @param capacityHint the hint to size the internal unbounded buffer * @param onCancelled the optional callback * @return an UnicastSubject instance */ public static NbpUnicastSubject create(int capacityHint, Runnable onCancelled) { - State state = new State<>(capacityHint, onCancelled); - return new NbpUnicastSubject<>(state); + State state = new State(capacityHint, onCancelled); + return new NbpUnicastSubject(state); } /** The subject state. */ @@ -100,11 +103,7 @@ static final class State extends StatePad0 implements NbpOnSubscribe, Disp final Queue queue; /** The single subscriber. */ - volatile NbpSubscriber subscriber; - /** Updater to the field subscriber. */ - @SuppressWarnings("rawtypes") - static final AtomicReferenceFieldUpdater SUBSCRIBER = - AtomicReferenceFieldUpdater.newUpdater(State.class, NbpSubscriber.class, "subscriber"); + final AtomicReference> subscriber = new AtomicReference>(); /** Indicates the single subscriber has cancelled. */ volatile boolean cancelled; @@ -118,11 +117,7 @@ static final class State extends StatePad0 implements NbpOnSubscribe, Disp Throwable error; /** Set to 1 atomically for the first and only Subscriber. */ - volatile int once; - /** Updater to field once. */ - @SuppressWarnings("rawtypes") - static final AtomicIntegerFieldUpdater ONCE = - AtomicIntegerFieldUpdater.newUpdater(State.class, "once"); + final AtomicBoolean once = new AtomicBoolean(); /** * Called when the Subscriber has called cancel. @@ -138,27 +133,18 @@ static final class State extends StatePad0 implements NbpOnSubscribe, Disp */ public State(int capacityHint, Runnable onCancelled) { this.onCancelled = onCancelled; - queue = new SpscLinkedArrayQueue<>(capacityHint); + queue = new SpscLinkedArrayQueue(capacityHint); } @Override public void accept(NbpSubscriber s) { - if (once == 0 && ONCE.compareAndSet(this, 0, 1)) { - SUBSCRIBER.lazySet(this, s); + if (!once.get() && once.compareAndSet(false, true)) { s.onSubscribe(this); + subscriber.lazySet(s); // full barrier in drain drain(); } else { s.onSubscribe(EmptyDisposable.INSTANCE); - if (done) { - Throwable e = error; - if (e != null) { - s.onError(e); - } else { - s.onComplete(); - } - } else { - s.onError(new IllegalStateException("Only a single subscriber allowed.")); - } + s.onError(new IllegalStateException("Only a single subscriber allowed.")); } } @@ -186,7 +172,7 @@ void notifyOnCancelled() { * @param q the queue reference (avoid re-reading instance field). */ void clear(Queue q) { - SUBSCRIBER.lazySet(this, null); + subscriber.lazySet(null); q.clear(); notifyOnCancelled(); } @@ -239,7 +225,7 @@ void drain() { } final Queue q = queue; - NbpSubscriber a = subscriber; + NbpSubscriber a = subscriber.get(); int missed = 1; for (;;) { @@ -255,7 +241,7 @@ void drain() { boolean d = done; boolean empty = q.isEmpty(); if (d && empty) { - SUBSCRIBER.lazySet(this, null); + subscriber.lazySet(null); Throwable ex = error; if (ex != null) { a.onError(ex); @@ -278,7 +264,7 @@ void drain() { empty = v == null; if (d && empty) { - SUBSCRIBER.lazySet(this, null); + subscriber.lazySet(null); Throwable ex = error; if (ex != null) { a.onError(ex); @@ -302,7 +288,7 @@ void drain() { } if (a == null) { - a = subscriber; + a = subscriber.get(); } } } @@ -371,4 +357,4 @@ public T[] getValues(T[] array) { } return array; } -} +} \ No newline at end of file diff --git a/src/main/java/io/reactivex/subscribers/AsyncObserver.java b/src/main/java/io/reactivex/subscribers/AsyncObserver.java index 821e4cd191..ffbb66b386 100644 --- a/src/main/java/io/reactivex/subscribers/AsyncObserver.java +++ b/src/main/java/io/reactivex/subscribers/AsyncObserver.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,13 +13,13 @@ package io.reactivex.subscribers; -import java.util.Objects; import java.util.concurrent.atomic.*; import org.reactivestreams.*; -import io.reactivex.disposables.Disposable; +import io.reactivex.disposables.*; import io.reactivex.internal.disposables.ListCompositeResource; +import io.reactivex.internal.functions.Objects; import io.reactivex.internal.subscriptions.SubscriptionHelper; import io.reactivex.internal.util.BackpressureHelper; @@ -36,22 +36,13 @@ */ public abstract class AsyncObserver implements Subscriber, Disposable { /** The active subscription. */ - private volatile Subscription s; - /** Updater of s. */ - @SuppressWarnings("rawtypes") - private static final AtomicReferenceFieldUpdater S = - AtomicReferenceFieldUpdater.newUpdater(AsyncObserver.class, Subscription.class, "s"); + private final AtomicReference s; /** The resource composite, can be null. */ private final ListCompositeResource resources; /** Remembers the request(n) counts until a subscription arrives. */ - @SuppressWarnings("unused") - private volatile long missedRequested; - /** The updater of missedRequested. */ - @SuppressWarnings("rawtypes") - private static final AtomicLongFieldUpdater MISSED_REQUESTED = - AtomicLongFieldUpdater.newUpdater(AsyncObserver.class, "missedRequested"); + private final AtomicLong missedRequested; /** The cancelled subscription indicator. */ private static final Subscription CANCELLED = new Subscription() { @@ -78,7 +69,9 @@ public AsyncObserver() { * @param withResources true if resource support should be on. */ public AsyncObserver(boolean withResources) { - this.resources = withResources ? new ListCompositeResource<>(Disposable::dispose) : null; + this.resources = withResources ? new ListCompositeResource(Disposables.consumeAndDispose()) : null; + this.missedRequested = new AtomicLong(); + this.s = new AtomicReference(); } /** @@ -95,7 +88,7 @@ public AsyncObserver(boolean withResources) { * @see #supportsResources() */ public final void add(Disposable resource) { - Objects.requireNonNull(resource); + Objects.requireNonNull(resource, "resource is null"); if (resources != null) { add(resource); } else { @@ -115,7 +108,7 @@ public final boolean supportsResources() { @Override public final void onSubscribe(Subscription s) { - if (!S.compareAndSet(this, null, s)) { + if (!this.s.compareAndSet(null, s)) { s.cancel(); if (s != CANCELLED) { SubscriptionHelper.reportSubscriptionSet(); @@ -123,7 +116,7 @@ public final void onSubscribe(Subscription s) { return; } - long mr = MISSED_REQUESTED.getAndSet(this, 0L); + long mr = missedRequested.getAndSet(0L); if (mr != 0L) { s.request(mr); } @@ -152,12 +145,12 @@ protected final void request(long n) { if (SubscriptionHelper.validateRequest(n)) { return; } - Subscription a = s; + Subscription a = s.get(); if (a == null) { - BackpressureHelper.add(MISSED_REQUESTED, this, n); - a = s; + BackpressureHelper.add(missedRequested, n); + a = s.get(); if (a != null) { - long mr = MISSED_REQUESTED.getAndSet(this, 0L); + long mr = missedRequested.getAndSet(0L); if (mr != 0L) { a.request(mr); } @@ -175,9 +168,9 @@ protected final void request(long n) { * case the Subscription will be immediately cancelled. */ protected final void cancel() { - Subscription a = s; + Subscription a = s.get(); if (a != CANCELLED) { - a = S.getAndSet(this, CANCELLED); + a = s.getAndSet(CANCELLED); if (a != CANCELLED && a != null) { a.cancel(); if (resources != null) { diff --git a/src/main/java/io/reactivex/subscribers/Observers.java b/src/main/java/io/reactivex/subscribers/Observers.java index c715438a06..00d0629b06 100644 --- a/src/main/java/io/reactivex/subscribers/Observers.java +++ b/src/main/java/io/reactivex/subscribers/Observers.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,10 +13,9 @@ package io.reactivex.subscribers; -import java.util.Objects; -import java.util.function.Consumer; - import io.reactivex.Observer; +import io.reactivex.functions.Consumer; +import io.reactivex.internal.functions.*; import io.reactivex.plugins.RxJavaPlugins; /** @@ -67,25 +66,28 @@ public void onComplete() { } public static Observer create(Consumer onNext) { - return create(onNext, RxJavaPlugins::onError, () -> { }, () -> { }); + return create(onNext, RxJavaPlugins.errorConsumer(), Functions.emptyRunnable(), Functions.emptyRunnable()); } public static Observer create(Consumer onNext, Consumer onError) { - return create(onNext, onError, () -> { }, () -> { }); + return create(onNext, onError, Functions.emptyRunnable(), Functions.emptyRunnable()); } public static Observer create(Consumer onNext, Consumer onError, Runnable onComplete) { - return create(onNext, onError, onComplete, () -> { }); + return create(onNext, onError, onComplete, Functions.emptyRunnable()); } - public static Observer create(Consumer onNext, - Consumer onError, Runnable onComplete, Runnable onStart) { - Objects.requireNonNull(onNext); - Objects.requireNonNull(onError); - Objects.requireNonNull(onComplete); - Objects.requireNonNull(onStart); + public static Observer create( + final Consumer onNext, + final Consumer onError, + final Runnable onComplete, + final Runnable onStart) { + Objects.requireNonNull(onNext, "onNext is null"); + Objects.requireNonNull(onError, "onError is null"); + Objects.requireNonNull(onComplete, "onComplete is null"); + Objects.requireNonNull(onStart, "onStart is null"); return new Observer() { boolean done; @Override @@ -99,7 +101,7 @@ protected void onStart() { try { onError.accept(e); } catch (Throwable ex) { - ex.addSuppressed(e); + RxJavaPlugins.onError(e); RxJavaPlugins.onError(ex); } } @@ -117,7 +119,7 @@ public void onNext(T t) { try { onError.accept(e); } catch (Throwable ex) { - ex.addSuppressed(e); + RxJavaPlugins.onError(e); RxJavaPlugins.onError(ex); } } @@ -133,8 +135,8 @@ public void onError(Throwable t) { try { onError.accept(t); } catch (Throwable ex) { - ex.addSuppressed(t); RxJavaPlugins.onError(ex); + RxJavaPlugins.onError(t); } } @@ -154,29 +156,33 @@ public void onComplete() { } public static AsyncObserver createAsync(Consumer onNext) { - return createAsync(onNext, RxJavaPlugins::onError, () -> { }, () -> { }); + return createAsync(onNext, RxJavaPlugins.errorConsumer(), Functions.emptyRunnable(), Functions.emptyRunnable()); } public static AsyncObserver createAsync(Consumer onNext, Consumer onError) { - return createAsync(onNext, onError, () -> { }, () -> { }); + return createAsync(onNext, onError, Functions.emptyRunnable(), Functions.emptyRunnable()); } public static AsyncObserver createAsync(Consumer onNext, Consumer onError, Runnable onComplete) { - return createAsync(onNext, onError, onComplete, () -> { }); + return createAsync(onNext, onError, onComplete, Functions.emptyRunnable()); } - public static AsyncObserver createAsync(Consumer onNext, - Consumer onError, Runnable onComplete, Runnable onStart) { - Objects.requireNonNull(onNext); - Objects.requireNonNull(onError); - Objects.requireNonNull(onComplete); - Objects.requireNonNull(onStart); + public static AsyncObserver createAsync( + final Consumer onNext, + final Consumer onError, + final Runnable onComplete, + final Runnable onStart) { + Objects.requireNonNull(onNext, "onNext is null"); + Objects.requireNonNull(onError, "onError is null"); + Objects.requireNonNull(onComplete, "onComplete is null"); + Objects.requireNonNull(onStart, "onStart is null"); return new AsyncObserver() { boolean done; @Override protected void onStart() { + super.onStart(); try { onStart.run(); } catch (Throwable e) { @@ -185,8 +191,8 @@ protected void onStart() { try { onError.accept(e); } catch (Throwable ex) { - ex.addSuppressed(e); RxJavaPlugins.onError(ex); + RxJavaPlugins.onError(e); } } } @@ -203,8 +209,8 @@ public void onNext(T t) { try { onError.accept(e); } catch (Throwable ex) { - ex.addSuppressed(e); RxJavaPlugins.onError(ex); + RxJavaPlugins.onError(e); } } } @@ -219,8 +225,8 @@ public void onError(Throwable t) { try { onError.accept(t); } catch (Throwable ex) { - ex.addSuppressed(t); RxJavaPlugins.onError(ex); + RxJavaPlugins.onError(t); } } diff --git a/src/main/java/io/reactivex/subscribers/SafeSubscriber.java b/src/main/java/io/reactivex/subscribers/SafeSubscriber.java index 11284ac5ff..f4f5adb56d 100644 --- a/src/main/java/io/reactivex/subscribers/SafeSubscriber.java +++ b/src/main/java/io/reactivex/subscribers/SafeSubscriber.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -14,6 +14,7 @@ import org.reactivestreams.*; +import io.reactivex.exceptions.CompositeException; import io.reactivex.internal.subscriptions.EmptySubscription; import io.reactivex.plugins.RxJavaPlugins; @@ -45,7 +46,7 @@ public void onSubscribe(Subscription s) { try { s.cancel(); } catch (Throwable e) { - ise.addSuppressed(e); + ise.initCause(e); } onError(ise); return; @@ -64,7 +65,10 @@ public void onSubscribe(Subscription s) { try { s.cancel(); } catch (Throwable e1) { - e.addSuppressed(e1); + CompositeException ce = new CompositeException(); + ce.suppress(e1); + ce.suppress(e); + e = ce; } RxJavaPlugins.onError(e); } @@ -98,33 +102,29 @@ public void onError(Throwable t) { done = true; if (subscription == null) { - Throwable t2; - if (t == null) { - t2 = new NullPointerException("Subscription not set!"); - } else { - t2 = t; - t2.addSuppressed(new NullPointerException("Subscription not set!")); - } + CompositeException t2 = new CompositeException(t, new NullPointerException("Subscription not set!")); + try { actual.onSubscribe(EmptySubscription.INSTANCE); } catch (Throwable e) { // can't call onError because the actual's state may be corrupt at this point - e.addSuppressed(t2); + t2.suppress(e); - RxJavaPlugins.onError(e); + RxJavaPlugins.onError(t2); return; } try { actual.onError(t2); } catch (Throwable e) { // if onError failed, all that's left is to report the error to plugins - e.addSuppressed(t2); + t2.suppress(e); - RxJavaPlugins.onError(e); + RxJavaPlugins.onError(t2); } return; } + CompositeException t2 = null; if (t == null) { t = new NullPointerException(); } @@ -132,15 +132,19 @@ public void onError(Throwable t) { try { subscription.cancel(); } catch (Throwable e) { - t.addSuppressed(e); + t2 = new CompositeException(e, t); } try { - actual.onError(t); + if (t2 != null) { + actual.onError(t2); + } else { + actual.onError(t); + } } catch (Throwable e) { - e.addSuppressed(t); + t2.suppress(e); - RxJavaPlugins.onError(e); + RxJavaPlugins.onError(t2); } } @@ -162,9 +166,7 @@ public void onComplete() { try { actual.onError(e); } catch (Throwable e1) { - e1.addSuppressed(e); - - RxJavaPlugins.onError(e1); + RxJavaPlugins.onError(new CompositeException(e1, e)); } return; } diff --git a/src/main/java/io/reactivex/subscribers/SerializedSubscriber.java b/src/main/java/io/reactivex/subscribers/SerializedSubscriber.java index 46aa5069b4..4bb7ad9340 100644 --- a/src/main/java/io/reactivex/subscribers/SerializedSubscriber.java +++ b/src/main/java/io/reactivex/subscribers/SerializedSubscriber.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -14,6 +14,7 @@ import org.reactivestreams.*; +import io.reactivex.functions.Predicate; import io.reactivex.internal.util.*; import io.reactivex.plugins.RxJavaPlugins; @@ -77,7 +78,7 @@ public void onNext(T t) { if (emitting) { AppendOnlyLinkedArrayList q = queue; if (q == null) { - q = new AppendOnlyLinkedArrayList<>(QUEUE_LINK_SIZE); + q = new AppendOnlyLinkedArrayList(QUEUE_LINK_SIZE); queue = q; } q.add(NotificationLite.next(t)); @@ -106,7 +107,7 @@ public void onError(Throwable t) { done = true; AppendOnlyLinkedArrayList q = queue; if (q == null) { - q = new AppendOnlyLinkedArrayList<>(QUEUE_LINK_SIZE); + q = new AppendOnlyLinkedArrayList(QUEUE_LINK_SIZE); queue = q; } Object err = NotificationLite.error(t); @@ -144,7 +145,7 @@ public void onComplete() { if (emitting) { AppendOnlyLinkedArrayList q = queue; if (q == null) { - q = new AppendOnlyLinkedArrayList<>(QUEUE_LINK_SIZE); + q = new AppendOnlyLinkedArrayList(QUEUE_LINK_SIZE); queue = q; } q.add(NotificationLite.complete()); @@ -170,10 +171,17 @@ void emitLoop() { queue = null; } - q.forEachWhile(this::accept); + q.forEachWhile(consumer); } } + final Predicate consumer = new Predicate() { + @Override + public boolean test(Object v) { + return accept(v); + } + }; + boolean accept(Object value) { return NotificationLite.accept(value, actual); } diff --git a/src/main/java/io/reactivex/subscribers/Subscribers.java b/src/main/java/io/reactivex/subscribers/Subscribers.java index bd66a7935f..5aef09cebc 100644 --- a/src/main/java/io/reactivex/subscribers/Subscribers.java +++ b/src/main/java/io/reactivex/subscribers/Subscribers.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,11 +13,10 @@ package io.reactivex.subscribers; -import java.util.Objects; -import java.util.function.Consumer; - import org.reactivestreams.*; +import io.reactivex.functions.Consumer; +import io.reactivex.internal.functions.*; import io.reactivex.internal.subscribers.*; import io.reactivex.internal.subscriptions.SubscriptionHelper; import io.reactivex.plugins.RxJavaPlugins; @@ -63,14 +62,14 @@ public void onComplete() { public static DisposableSubscriber createDisposable( Consumer onNext ) { - return createDisposable(onNext, RxJavaPlugins::onError, () -> { }, () -> { }); + return createDisposable(onNext, RxJavaPlugins.errorConsumer(), Functions.emptyRunnable(), Functions.emptyRunnable()); } public static DisposableSubscriber createDisposable( Consumer onNext, Consumer onError ) { - return createDisposable(onNext, onError, () -> { }, () -> { }); + return createDisposable(onNext, onError, Functions.emptyRunnable(), Functions.emptyRunnable()); } public static DisposableSubscriber createDisposable( @@ -78,19 +77,19 @@ public static DisposableSubscriber createDisposable( Consumer onError, Runnable onComplete ) { - return createDisposable(onNext, onError, onComplete, () -> { }); + return createDisposable(onNext, onError, onComplete, Functions.emptyRunnable()); } public static DisposableSubscriber createDisposable( - Consumer onNext, - Consumer onError, - Runnable onComplete, - Runnable onStart + final Consumer onNext, + final Consumer onError, + final Runnable onComplete, + final Runnable onStart ) { - Objects.requireNonNull(onNext); - Objects.requireNonNull(onError); - Objects.requireNonNull(onComplete); - Objects.requireNonNull(onStart); + Objects.requireNonNull(onNext, "onNext is null"); + Objects.requireNonNull(onError, "onError is null"); + Objects.requireNonNull(onComplete, "onComplete is null"); + Objects.requireNonNull(onStart, "onStart is null"); return new DisposableSubscriber() { boolean done; @Override @@ -104,8 +103,8 @@ protected void onStart() { try { onError.accept(e); } catch (Throwable ex) { - ex.addSuppressed(e); RxJavaPlugins.onError(ex); + RxJavaPlugins.onError(e); } } } @@ -122,8 +121,8 @@ public void onNext(T t) { try { onError.accept(e); } catch (Throwable ex) { - ex.addSuppressed(e); RxJavaPlugins.onError(ex); + RxJavaPlugins.onError(e); } } } @@ -138,8 +137,8 @@ public void onError(Throwable t) { try { onError.accept(t); } catch (Throwable ex) { - ex.addSuppressed(t); RxJavaPlugins.onError(ex); + RxJavaPlugins.onError(t); } } @@ -158,17 +157,24 @@ public void onComplete() { }; } + static final Consumer REQUEST_ALL = new Consumer() { + @Override + public void accept(Subscription t) { + t.request(Long.MAX_VALUE); + } + }; + public static Subscriber create( Consumer onNext ) { - return create(onNext, RxJavaPlugins::onError, () -> { }, s -> { }); + return create(onNext, RxJavaPlugins.errorConsumer(), Functions.emptyRunnable(), REQUEST_ALL); } public static Subscriber create( Consumer onNext, Consumer onError ) { - return create(onNext, onError, () -> { }, s -> { }); + return create(onNext, onError, Functions.emptyRunnable(), REQUEST_ALL); } public static Subscriber create( @@ -176,19 +182,19 @@ public static Subscriber create( Consumer onError, Runnable onComplete ) { - return create(onNext, onError, onComplete, s -> { }); + return create(onNext, onError, onComplete, REQUEST_ALL); } public static Subscriber create( - Consumer onNext, - Consumer onError, - Runnable onComplete, - Consumer onStart + final Consumer onNext, + final Consumer onError, + final Runnable onComplete, + final Consumer onStart ) { - Objects.requireNonNull(onNext); - Objects.requireNonNull(onError); - Objects.requireNonNull(onComplete); - Objects.requireNonNull(onStart); + Objects.requireNonNull(onNext, "onNext is null"); + Objects.requireNonNull(onError, "onError is null"); + Objects.requireNonNull(onComplete, "onComplete is null"); + Objects.requireNonNull(onStart, "onStart is null"); return new Subscriber() { boolean done; @@ -207,8 +213,8 @@ public void onSubscribe(Subscription s) { try { onError.accept(e); } catch (Throwable ex) { - ex.addSuppressed(e); RxJavaPlugins.onError(ex); + RxJavaPlugins.onError(e); } } } @@ -225,8 +231,8 @@ public void onNext(T t) { try { onError.accept(e); } catch (Throwable ex) { - ex.addSuppressed(e); RxJavaPlugins.onError(ex); + RxJavaPlugins.onError(e); } } } @@ -241,8 +247,8 @@ public void onError(Throwable t) { try { onError.accept(t); } catch (Throwable ex) { - ex.addSuppressed(t); RxJavaPlugins.onError(ex); + RxJavaPlugins.onError(t); } } diff --git a/src/main/java/io/reactivex/subscribers/TestSubscriber.java b/src/main/java/io/reactivex/subscribers/TestSubscriber.java index 030caa49f0..cd2ed205d8 100644 --- a/src/main/java/io/reactivex/subscribers/TestSubscriber.java +++ b/src/main/java/io/reactivex/subscribers/TestSubscriber.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -20,6 +20,8 @@ import io.reactivex.Notification; import io.reactivex.disposables.Disposable; +import io.reactivex.exceptions.CompositeException; +import io.reactivex.internal.functions.Objects; import io.reactivex.internal.subscribers.EmptySubscriber; import io.reactivex.internal.subscriptions.SubscriptionHelper; import io.reactivex.internal.util.BackpressureHelper; @@ -57,19 +59,12 @@ public class TestSubscriber implements Subscriber, Subscription, Disposabl private volatile boolean cancelled; /** Holds the current subscription if any. */ - private volatile Subscription subscription; - /** Updater for subscription. */ - @SuppressWarnings("rawtypes") - private static final AtomicReferenceFieldUpdater SUBSCRIPTION = - AtomicReferenceFieldUpdater.newUpdater(TestSubscriber.class, Subscription.class, "subscription"); + private final AtomicReference subscription = new AtomicReference(); /** Holds the requested amount until a subscription arrives. */ - @SuppressWarnings("unused") - private volatile long missedRequested; - /** Updater for subscription. */ - @SuppressWarnings("rawtypes") - private static final AtomicLongFieldUpdater MISSED_REQUESTED = - AtomicLongFieldUpdater.newUpdater(TestSubscriber.class, "missedRequested"); + private final AtomicLong missedRequested = new AtomicLong(); + + private boolean checkSubscriptionOnce; /** Indicates a cancelled subscription. */ private static final Subscription CANCELLED = new Subscription() { @@ -118,8 +113,8 @@ public TestSubscriber(Subscriber actual) { public TestSubscriber(Subscriber actual, Long initialRequest) { this.actual = actual; this.initialRequest = initialRequest; - this.values = new ArrayList<>(); - this.errors = new ArrayList<>(); + this.values = new ArrayList(); + this.errors = new ArrayList(); this.done = new CountDownLatch(1); } @@ -131,10 +126,10 @@ public void onSubscribe(Subscription s) { errors.add(new NullPointerException("onSubscribe received a null Subscription")); return; } - if (!SUBSCRIPTION.compareAndSet(this, null, s)) { + if (!subscription.compareAndSet(null, s)) { s.cancel(); - if (subscription != CANCELLED) { - errors.add(new NullPointerException("onSubscribe received multiple subscriptions: " + s)); + if (subscription.get() != CANCELLED) { + errors.add(new IllegalStateException("onSubscribe received multiple subscriptions: " + s)); } return; } @@ -153,7 +148,7 @@ public void onSubscribe(Subscription s) { s.request(initialRequest); } - long mr = MISSED_REQUESTED.getAndSet(this, 0L); + long mr = missedRequested.getAndSet(0L); if (mr != 0L) { s.request(mr); } @@ -161,6 +156,12 @@ public void onSubscribe(Subscription s) { @Override public void onNext(T t) { + if (!checkSubscriptionOnce) { + checkSubscriptionOnce = true; + if (subscription.get() == null) { + errors.add(new IllegalStateException("onSubscribe not called in proper order")); + } + } lastThread = Thread.currentThread(); values.add(t); @@ -173,12 +174,18 @@ public void onNext(T t) { @Override public void onError(Throwable t) { + if (!checkSubscriptionOnce) { + checkSubscriptionOnce = true; + if (subscription.get() == null) { + errors.add(new NullPointerException("onSubscribe not called in proper order")); + } + } try { lastThread = Thread.currentThread(); errors.add(t); if (t == null) { - errors.add(new NullPointerException("onError received a null Subscription")); + errors.add(new IllegalStateException("onError received a null Subscription")); } actual.onError(t); @@ -189,6 +196,12 @@ public void onError(Throwable t) { @Override public void onComplete() { + if (!checkSubscriptionOnce) { + checkSubscriptionOnce = true; + if (subscription.get() == null) { + errors.add(new IllegalStateException("onSubscribe not called in proper order")); + } + } try { lastThread = Thread.currentThread(); completions++; @@ -204,14 +217,14 @@ public void request(long n) { if (SubscriptionHelper.validateRequest(n)) { return; } - Subscription s = subscription; + Subscription s = subscription.get(); if (s != null) { s.request(n); } else { - BackpressureHelper.add(MISSED_REQUESTED, this, n); - s = subscription; + BackpressureHelper.add(missedRequested, n); + s = subscription.get(); if (s != null) { - long mr = MISSED_REQUESTED.getAndSet(this, 0L); + long mr = missedRequested.getAndSet(0L); if (mr != 0L) { s.request(mr); } @@ -223,9 +236,9 @@ public void request(long n) { public void cancel() { if (!cancelled) { cancelled = true; - Subscription s = subscription; + Subscription s = subscription.get(); if (s != CANCELLED) { - s = SUBSCRIPTION.getAndSet(this, CANCELLED); + s = subscription.getAndSet(CANCELLED); if (s != CANCELLED && s != null) { s.cancel(); } @@ -309,7 +322,7 @@ public final int errorCount() { * @return true if this TestSubscriber received a subscription */ public final boolean hasSubscription() { - return subscription != null; + return subscription.get() != null; } /** @@ -354,13 +367,17 @@ public final boolean await(long time, TimeUnit unit) throws InterruptedException */ private void fail(String prefix, String message, Iterable errors) { AssertionError ae = new AssertionError(prefix + message); - errors.forEach(e -> { + CompositeException ce = new CompositeException(); + for (Throwable e : errors) { if (e == null) { - ae.addSuppressed(new NullPointerException("Throwable was null!")); + ce.suppress(new NullPointerException("Throwable was null!")); } else { - ae.addSuppressed(e); + ce.suppress(e); } - }); + }; + if (!ce.isEmpty()) { + ae.initCause(ce); + } throw ae; } @@ -432,7 +449,7 @@ public void assertError(Throwable error) { } int s = errors.size(); if (s == 0) { - fail(prefix, "No errors", Collections.emptyList()); + fail(prefix, "No errors", Collections.emptyList()); } if (errors.contains(error)) { if (s != 1) { @@ -455,11 +472,17 @@ public void assertError(Class errorClass) { } int s = errors.size(); if (s == 0) { - fail(prefix, "No errors", Collections.emptyList()); + fail(prefix, "No errors", Collections.emptyList()); } - boolean found = errors.stream() - .anyMatch(errorClass::isInstance); + boolean found = false; + + for (Throwable e : errors) { + if (errorClass.isInstance(e)) { + found = true; + break; + } + } if (found) { if (s != 1) { @@ -525,7 +548,6 @@ public final void assertNoValues() { * @param values the values expected * @see #assertValueSet(Collection) */ - @SafeVarargs public final void assertValues(T... values) { String prefix = ""; if (done.getCount() != 0) { @@ -641,7 +663,7 @@ public final void assertSubscribed() { if (done.getCount() != 0) { prefix = "Subscriber still running! "; } - if (subscription == null) { + if (subscription.get() == null) { fail(prefix, "Not subscribed!", errors); } } @@ -654,7 +676,7 @@ public final void assertNotSubscribed() { if (done.getCount() != 0) { prefix = "Subscriber still running! "; } - if (subscription != null) { + if (subscription.get() != null) { fail(prefix, "Subscribed!", errors); } else if (!errors.isEmpty()) { @@ -680,7 +702,7 @@ public boolean awaitTerminalEvent() { /** * Awaits the specified amount of time or until this TestSubscriber * receives an onError or onComplete events, whichever happens first. - * @param time the waiting time + * @param duration the waiting time * @param unit the time unit of the waiting time * @return true if the TestSubscriber terminated, false if timeout or interrupt happened */ @@ -700,12 +722,12 @@ public void assertErrorMessage(String message) { } int s = errors.size(); if (s == 0) { - fail(prefix, "No errors", Collections.emptyList()); + fail(prefix, "No errors", Collections.emptyList()); } else if (s == 1) { Throwable e = errors.get(0); if (e == null) { - fail(prefix, "Error is null", Collections.emptyList()); + fail(prefix, "Error is null", Collections.emptyList()); } String errorMessage = e.getMessage(); if (!Objects.equals(message, errorMessage)) { @@ -725,13 +747,13 @@ public void assertErrorMessage(String message) { */ @SuppressWarnings({ "rawtypes", "unchecked" }) public List> getEvents() { - List> result = new ArrayList<>(); + List> result = new ArrayList>(); result.add((List)values()); result.add((List)errors()); - List completeList = new ArrayList<>(); + List completeList = new ArrayList(); for (long i = 0; i < completions; i++) { completeList.add(Notification.complete()); } diff --git a/src/main/java/io/reactivex/subscribers/completable/CompletableSerializedSubscriber.java b/src/main/java/io/reactivex/subscribers/completable/CompletableSerializedSubscriber.java new file mode 100644 index 0000000000..5b35fdf964 --- /dev/null +++ b/src/main/java/io/reactivex/subscribers/completable/CompletableSerializedSubscriber.java @@ -0,0 +1,50 @@ +/** + * 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.subscribers.completable; + +import java.util.concurrent.atomic.AtomicBoolean; + +import io.reactivex.Completable.CompletableSubscriber; +import io.reactivex.disposables.Disposable; + +public final class CompletableSerializedSubscriber implements CompletableSubscriber { + + final CompletableSubscriber actual; + + final AtomicBoolean once = new AtomicBoolean(); + + public CompletableSerializedSubscriber(CompletableSubscriber actual) { + this.actual = actual; + } + + @Override + public void onSubscribe(Disposable d) { + actual.onSubscribe(d); + } + + @Override + public void onError(Throwable e) { + if (once.compareAndSet(false, true)) { + actual.onError(e); + } + } + + @Override + public void onComplete() { + if (once.compareAndSet(false, true)) { + actual.onComplete(); + } + } + +} \ No newline at end of file diff --git a/src/main/java/io/reactivex/subscribers/nbp/NbpAsyncObserver.java b/src/main/java/io/reactivex/subscribers/nbp/NbpAsyncObserver.java index 0006244de3..3e72165d77 100644 --- a/src/main/java/io/reactivex/subscribers/nbp/NbpAsyncObserver.java +++ b/src/main/java/io/reactivex/subscribers/nbp/NbpAsyncObserver.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,12 +13,12 @@ package io.reactivex.subscribers.nbp; -import java.util.Objects; -import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; +import java.util.concurrent.atomic.*; import io.reactivex.NbpObservable.NbpSubscriber; -import io.reactivex.disposables.Disposable; +import io.reactivex.disposables.*; import io.reactivex.internal.disposables.ListCompositeResource; +import io.reactivex.internal.functions.Objects; import io.reactivex.internal.subscriptions.SubscriptionHelper; /** @@ -34,17 +34,16 @@ */ public abstract class NbpAsyncObserver implements NbpSubscriber, Disposable { /** The active subscription. */ - private volatile Disposable s; - /** Updater of s. */ - @SuppressWarnings("rawtypes") - private static final AtomicReferenceFieldUpdater S = - AtomicReferenceFieldUpdater.newUpdater(NbpAsyncObserver.class, Disposable.class, "s"); + private final AtomicReference s = new AtomicReference(); /** The resource composite, can be null. */ private final ListCompositeResource resources; /** The cancelled subscription indicator. */ - private static final Disposable CANCELLED = () -> { }; + private static final Disposable CANCELLED = new Disposable() { + @Override + public void dispose() { } + }; /** * Constructs an AsyncObserver with resource support. @@ -58,7 +57,7 @@ public NbpAsyncObserver() { * @param withResources true if resource support should be on. */ public NbpAsyncObserver(boolean withResources) { - this.resources = withResources ? new ListCompositeResource<>(Disposable::dispose) : null; + this.resources = withResources ? new ListCompositeResource(Disposables.consumeAndDispose()) : null; } /** @@ -75,7 +74,7 @@ public NbpAsyncObserver(boolean withResources) { * @see #supportsResources() */ public final void add(Disposable resource) { - Objects.requireNonNull(resource); + Objects.requireNonNull(resource, "resource is null"); if (resources != null) { add(resource); } else { @@ -95,9 +94,9 @@ public final boolean supportsResources() { @Override public final void onSubscribe(Disposable s) { - if (!S.compareAndSet(this, null, s)) { + if (!this.s.compareAndSet(null, s)) { s.dispose(); - if (s != CANCELLED) { + if (this.s.get() != CANCELLED) { SubscriptionHelper.reportDisposableSet(); } return; @@ -123,9 +122,9 @@ protected void onStart() { * case the main Disposable will be immediately disposed. */ protected final void cancel() { - Disposable a = s; + Disposable a = s.get(); if (a != CANCELLED) { - a = S.getAndSet(this, CANCELLED); + a = s.getAndSet(CANCELLED); if (a != CANCELLED && a != null) { a.dispose(); if (resources != null) { diff --git a/src/main/java/io/reactivex/subscribers/nbp/NbpObservers.java b/src/main/java/io/reactivex/subscribers/nbp/NbpObservers.java index 4d79ec2cba..9623182bd3 100644 --- a/src/main/java/io/reactivex/subscribers/nbp/NbpObservers.java +++ b/src/main/java/io/reactivex/subscribers/nbp/NbpObservers.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,10 +13,9 @@ package io.reactivex.subscribers.nbp; -import java.util.Objects; -import java.util.function.Consumer; - -import io.reactivex.*; +import io.reactivex.NbpObserver; +import io.reactivex.functions.Consumer; +import io.reactivex.internal.functions.*; import io.reactivex.plugins.RxJavaPlugins; /** @@ -67,25 +66,28 @@ public void onComplete() { } public static NbpObserver create(Consumer onNext) { - return create(onNext, RxJavaPlugins::onError, () -> { }, () -> { }); + return create(onNext, RxJavaPlugins.errorConsumer(), Functions.emptyRunnable(), Functions.emptyRunnable()); } public static NbpObserver create(Consumer onNext, Consumer onError) { - return create(onNext, onError, () -> { }, () -> { }); + return create(onNext, onError, Functions.emptyRunnable(), Functions.emptyRunnable()); } public static NbpObserver create(Consumer onNext, Consumer onError, Runnable onComplete) { - return create(onNext, onError, onComplete, () -> { }); + return create(onNext, onError, onComplete, Functions.emptyRunnable()); } - public static NbpObserver create(Consumer onNext, - Consumer onError, Runnable onComplete, Runnable onStart) { - Objects.requireNonNull(onNext); - Objects.requireNonNull(onError); - Objects.requireNonNull(onComplete); - Objects.requireNonNull(onStart); + public static NbpObserver create( + final Consumer onNext, + final Consumer onError, + final Runnable onComplete, + final Runnable onStart) { + Objects.requireNonNull(onNext, "onNext is null"); + Objects.requireNonNull(onError, "onError is null"); + Objects.requireNonNull(onComplete, "onComplete is null"); + Objects.requireNonNull(onStart, "onStart ins null"); return new NbpObserver() { boolean done; @Override @@ -99,8 +101,8 @@ protected void onStart() { try { onError.accept(e); } catch (Throwable ex) { - ex.addSuppressed(e); RxJavaPlugins.onError(ex); + RxJavaPlugins.onError(e); } } } @@ -117,8 +119,8 @@ public void onNext(T t) { try { onError.accept(e); } catch (Throwable ex) { - ex.addSuppressed(e); RxJavaPlugins.onError(ex); + RxJavaPlugins.onError(e); } } } @@ -133,8 +135,8 @@ public void onError(Throwable t) { try { onError.accept(t); } catch (Throwable ex) { - ex.addSuppressed(t); RxJavaPlugins.onError(ex); + RxJavaPlugins.onError(t); } } @@ -154,25 +156,28 @@ public void onComplete() { } public static NbpAsyncObserver createAsync(Consumer onNext) { - return createAsync(onNext, RxJavaPlugins::onError, () -> { }, () -> { }); + return createAsync(onNext, RxJavaPlugins.errorConsumer(), Functions.emptyRunnable(), Functions.emptyRunnable()); } public static NbpAsyncObserver createAsync(Consumer onNext, Consumer onError) { - return createAsync(onNext, onError, () -> { }, () -> { }); + return createAsync(onNext, onError, Functions.emptyRunnable(), Functions.emptyRunnable()); } public static NbpAsyncObserver createAsync(Consumer onNext, Consumer onError, Runnable onComplete) { - return createAsync(onNext, onError, onComplete, () -> { }); + return createAsync(onNext, onError, onComplete, Functions.emptyRunnable()); } - public static NbpAsyncObserver createAsync(Consumer onNext, - Consumer onError, Runnable onComplete, Runnable onStart) { - Objects.requireNonNull(onNext); - Objects.requireNonNull(onError); - Objects.requireNonNull(onComplete); - Objects.requireNonNull(onStart); + public static NbpAsyncObserver createAsync( + final Consumer onNext, + final Consumer onError, + final Runnable onComplete, + final Runnable onStart) { + Objects.requireNonNull(onNext, "onNext is null"); + Objects.requireNonNull(onError, "onError is null"); + Objects.requireNonNull(onComplete, "onComplete is null"); + Objects.requireNonNull(onStart, "onStart is null"); return new NbpAsyncObserver() { boolean done; @Override @@ -185,8 +190,8 @@ protected void onStart() { try { onError.accept(e); } catch (Throwable ex) { - ex.addSuppressed(e); RxJavaPlugins.onError(ex); + RxJavaPlugins.onError(e); } } } @@ -203,8 +208,8 @@ public void onNext(T t) { try { onError.accept(e); } catch (Throwable ex) { - ex.addSuppressed(e); RxJavaPlugins.onError(ex); + RxJavaPlugins.onError(e); } } } @@ -219,8 +224,8 @@ public void onError(Throwable t) { try { onError.accept(t); } catch (Throwable ex) { - ex.addSuppressed(t); RxJavaPlugins.onError(ex); + RxJavaPlugins.onError(t); } } diff --git a/src/main/java/io/reactivex/subscribers/nbp/NbpSafeSubscriber.java b/src/main/java/io/reactivex/subscribers/nbp/NbpSafeSubscriber.java index 310b39c45c..04cee6f371 100644 --- a/src/main/java/io/reactivex/subscribers/nbp/NbpSafeSubscriber.java +++ b/src/main/java/io/reactivex/subscribers/nbp/NbpSafeSubscriber.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -14,6 +14,7 @@ import io.reactivex.NbpObservable.NbpSubscriber; import io.reactivex.disposables.Disposable; +import io.reactivex.exceptions.CompositeException; import io.reactivex.internal.disposables.EmptyDisposable; import io.reactivex.plugins.RxJavaPlugins; @@ -41,11 +42,11 @@ public void onSubscribe(Disposable s) { return; } if (this.subscription != null) { - IllegalStateException ise = new IllegalStateException("Disposable already set!"); + Throwable ise = new IllegalStateException("Disposable already set!"); try { s.dispose(); } catch (Throwable e) { - ise.addSuppressed(e); + ise = new CompositeException(e, ise); } onError(ise); return; @@ -64,7 +65,7 @@ public void onSubscribe(Disposable s) { try { s.dispose(); } catch (Throwable e1) { - e.addSuppressed(e1); + RxJavaPlugins.onError(e1); } RxJavaPlugins.onError(e); } @@ -98,33 +99,29 @@ public void onError(Throwable t) { done = true; if (subscription == null) { - Throwable t2; - if (t == null) { - t2 = new NullPointerException("Subscription not set!"); - } else { - t2 = t; - t2.addSuppressed(new NullPointerException("Subscription not set!")); - } + CompositeException t2 = new CompositeException(t, new NullPointerException("Subscription not set!")); + try { actual.onSubscribe(EmptyDisposable.INSTANCE); } catch (Throwable e) { // can't call onError because the actual's state may be corrupt at this point - e.addSuppressed(t2); + t2.suppress(e); - RxJavaPlugins.onError(e); + RxJavaPlugins.onError(t2); return; } try { actual.onError(t2); } catch (Throwable e) { // if onError failed, all that's left is to report the error to plugins - e.addSuppressed(t2); + t2.suppress(e); - RxJavaPlugins.onError(e); + RxJavaPlugins.onError(t2); } return; } + CompositeException t2 = null; if (t == null) { t = new NullPointerException(); } @@ -132,15 +129,19 @@ public void onError(Throwable t) { try { subscription.dispose(); } catch (Throwable e) { - t.addSuppressed(e); + t2 = new CompositeException(e, t); } try { - actual.onError(t); + if (t2 != null) { + actual.onError(t2); + } else { + actual.onError(t); + } } catch (Throwable e) { - e.addSuppressed(t); + t2.suppress(e); - RxJavaPlugins.onError(e); + RxJavaPlugins.onError(t2); } } @@ -162,9 +163,7 @@ public void onComplete() { try { actual.onError(e); } catch (Throwable e1) { - e1.addSuppressed(e); - - RxJavaPlugins.onError(e1); + RxJavaPlugins.onError(new CompositeException(e1, e)); } return; } diff --git a/src/main/java/io/reactivex/subscribers/nbp/NbpSerializedSubscriber.java b/src/main/java/io/reactivex/subscribers/nbp/NbpSerializedSubscriber.java index 7163c29c47..31766924e2 100644 --- a/src/main/java/io/reactivex/subscribers/nbp/NbpSerializedSubscriber.java +++ b/src/main/java/io/reactivex/subscribers/nbp/NbpSerializedSubscriber.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -14,6 +14,7 @@ import io.reactivex.NbpObservable.NbpSubscriber; import io.reactivex.disposables.Disposable; +import io.reactivex.functions.Predicate; import io.reactivex.internal.subscriptions.SubscriptionHelper; import io.reactivex.internal.util.*; import io.reactivex.plugins.RxJavaPlugins; @@ -76,7 +77,7 @@ public void onNext(T t) { if (emitting) { AppendOnlyLinkedArrayList q = queue; if (q == null) { - q = new AppendOnlyLinkedArrayList<>(QUEUE_LINK_SIZE); + q = new AppendOnlyLinkedArrayList(QUEUE_LINK_SIZE); queue = q; } q.add(NotificationLite.next(t)); @@ -105,7 +106,7 @@ public void onError(Throwable t) { done = true; AppendOnlyLinkedArrayList q = queue; if (q == null) { - q = new AppendOnlyLinkedArrayList<>(QUEUE_LINK_SIZE); + q = new AppendOnlyLinkedArrayList(QUEUE_LINK_SIZE); queue = q; } Object err = NotificationLite.error(t); @@ -143,7 +144,7 @@ public void onComplete() { if (emitting) { AppendOnlyLinkedArrayList q = queue; if (q == null) { - q = new AppendOnlyLinkedArrayList<>(QUEUE_LINK_SIZE); + q = new AppendOnlyLinkedArrayList(QUEUE_LINK_SIZE); queue = q; } q.add(NotificationLite.complete()); @@ -169,10 +170,18 @@ void emitLoop() { queue = null; } - q.forEachWhile(this::accept); + q.forEachWhile(consumer); } } + final Predicate consumer = new Predicate() { + @Override + public boolean test(Object v) { + return accept(v); + } + }; + + boolean accept(Object value) { if (NotificationLite.isComplete(value)) { actual.onComplete(); @@ -182,7 +191,7 @@ boolean accept(Object value) { actual.onError(NotificationLite.getError(value)); return true; } - actual.onNext(NotificationLite.getValue(value)); + actual.onNext(NotificationLite.getValue(value)); return false; } } diff --git a/src/main/java/io/reactivex/subscribers/nbp/NbpSubscribers.java b/src/main/java/io/reactivex/subscribers/nbp/NbpSubscribers.java index c22d5dc82a..80fe46f9b0 100644 --- a/src/main/java/io/reactivex/subscribers/nbp/NbpSubscribers.java +++ b/src/main/java/io/reactivex/subscribers/nbp/NbpSubscribers.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,11 +13,10 @@ package io.reactivex.subscribers.nbp; -import java.util.Objects; -import java.util.function.Consumer; - import io.reactivex.NbpObservable.NbpSubscriber; import io.reactivex.disposables.Disposable; +import io.reactivex.functions.Consumer; +import io.reactivex.internal.functions.*; import io.reactivex.internal.subscribers.nbp.*; import io.reactivex.internal.subscriptions.SubscriptionHelper; import io.reactivex.plugins.RxJavaPlugins; @@ -63,14 +62,14 @@ public void onComplete() { public static NbpDisposableSubscriber createDisposable( Consumer onNext ) { - return createDisposable(onNext, RxJavaPlugins::onError, () -> { }, () -> { }); + return createDisposable(onNext, RxJavaPlugins.errorConsumer(), Functions.emptyRunnable(), Functions.emptyRunnable()); } public static NbpDisposableSubscriber createDisposable( Consumer onNext, Consumer onError ) { - return createDisposable(onNext, onError, () -> { }, () -> { }); + return createDisposable(onNext, onError, Functions.emptyRunnable(), Functions.emptyRunnable()); } public static NbpDisposableSubscriber createDisposable( @@ -78,19 +77,19 @@ public static NbpDisposableSubscriber createDisposable( Consumer onError, Runnable onComplete ) { - return createDisposable(onNext, onError, onComplete, () -> { }); + return createDisposable(onNext, onError, onComplete, Functions.emptyRunnable()); } public static NbpDisposableSubscriber createDisposable( - Consumer onNext, - Consumer onError, - Runnable onComplete, - Runnable onStart + final Consumer onNext, + final Consumer onError, + final Runnable onComplete, + final Runnable onStart ) { - Objects.requireNonNull(onNext); - Objects.requireNonNull(onError); - Objects.requireNonNull(onComplete); - Objects.requireNonNull(onStart); + Objects.requireNonNull(onNext, "onNext is null"); + Objects.requireNonNull(onError, "onError is null"); + Objects.requireNonNull(onComplete, "onComplete is null"); + Objects.requireNonNull(onStart, "onStart is null"); return new NbpDisposableSubscriber() { boolean done; @Override @@ -104,8 +103,8 @@ protected void onStart() { try { onError.accept(e); } catch (Throwable ex) { - ex.addSuppressed(e); RxJavaPlugins.onError(ex); + RxJavaPlugins.onError(e); } } } @@ -122,8 +121,8 @@ public void onNext(T t) { try { onError.accept(e); } catch (Throwable ex) { - ex.addSuppressed(e); RxJavaPlugins.onError(ex); + RxJavaPlugins.onError(e); } } } @@ -138,8 +137,8 @@ public void onError(Throwable t) { try { onError.accept(t); } catch (Throwable ex) { - ex.addSuppressed(t); RxJavaPlugins.onError(ex); + RxJavaPlugins.onError(t); } } @@ -161,14 +160,14 @@ public void onComplete() { public static NbpSubscriber create( Consumer onNext ) { - return create(onNext, RxJavaPlugins::onError, () -> { }, s -> { }); + return create(onNext, RxJavaPlugins.errorConsumer(), Functions.emptyRunnable(), Functions.emptyConsumer()); } public static NbpSubscriber create( Consumer onNext, Consumer onError ) { - return create(onNext, onError, () -> { }, s -> { }); + return create(onNext, onError, Functions.emptyRunnable(), Functions.emptyConsumer()); } public static NbpSubscriber create( @@ -176,19 +175,19 @@ public static NbpSubscriber create( Consumer onError, Runnable onComplete ) { - return create(onNext, onError, onComplete, s -> { }); + return create(onNext, onError, onComplete, Functions.emptyConsumer()); } public static NbpSubscriber create( - Consumer onNext, - Consumer onError, - Runnable onComplete, - Consumer onStart + final Consumer onNext, + final Consumer onError, + final Runnable onComplete, + final Consumer onStart ) { - Objects.requireNonNull(onNext); - Objects.requireNonNull(onError); - Objects.requireNonNull(onComplete); - Objects.requireNonNull(onStart); + Objects.requireNonNull(onNext, "onNext is null"); + Objects.requireNonNull(onError, "onError is null"); + Objects.requireNonNull(onComplete, "onComplete is null"); + Objects.requireNonNull(onStart, "onStart is null"); return new NbpSubscriber() { boolean done; @@ -207,8 +206,8 @@ public void onSubscribe(Disposable s) { try { onError.accept(e); } catch (Throwable ex) { - ex.addSuppressed(e); RxJavaPlugins.onError(ex); + RxJavaPlugins.onError(e); } } } @@ -225,8 +224,8 @@ public void onNext(T t) { try { onError.accept(e); } catch (Throwable ex) { - ex.addSuppressed(e); RxJavaPlugins.onError(ex); + RxJavaPlugins.onError(e); } } } @@ -241,8 +240,8 @@ public void onError(Throwable t) { try { onError.accept(t); } catch (Throwable ex) { - ex.addSuppressed(t); RxJavaPlugins.onError(ex); + RxJavaPlugins.onError(t); } } diff --git a/src/main/java/io/reactivex/subscribers/nbp/NbpTestSubscriber.java b/src/main/java/io/reactivex/subscribers/nbp/NbpTestSubscriber.java index c684991a24..704200f41b 100644 --- a/src/main/java/io/reactivex/subscribers/nbp/NbpTestSubscriber.java +++ b/src/main/java/io/reactivex/subscribers/nbp/NbpTestSubscriber.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -14,11 +14,13 @@ import java.util.*; import java.util.concurrent.*; -import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; +import java.util.concurrent.atomic.*; import io.reactivex.NbpObservable.NbpSubscriber; import io.reactivex.Notification; import io.reactivex.disposables.Disposable; +import io.reactivex.exceptions.CompositeException; +import io.reactivex.internal.functions.Objects; import io.reactivex.internal.subscribers.nbp.NbpEmptySubscriber; /** @@ -52,14 +54,16 @@ public class NbpTestSubscriber implements NbpSubscriber, Disposable { private volatile boolean cancelled; /** Holds the current subscription if any. */ - private volatile Disposable subscription; - /** Updater for subscription. */ - @SuppressWarnings("rawtypes") - private static final AtomicReferenceFieldUpdater SUBSCRIPTION = - AtomicReferenceFieldUpdater.newUpdater(NbpTestSubscriber.class, Disposable.class, "subscription"); + private final AtomicReference subscription = new AtomicReference(); /** Indicates a cancelled subscription. */ - private static final Disposable CANCELLED = () -> { }; + private static final Disposable CANCELLED = new Disposable() { + @Override + public void dispose() { } + }; + + private boolean checkSubscriptionOnce; + /** * Constructs a non-forwarding TestSubscriber with an initial request value of Long.MAX_VALUE. */ @@ -73,8 +77,8 @@ public NbpTestSubscriber() { */ public NbpTestSubscriber(NbpSubscriber actual) { this.actual = actual; - this.values = new ArrayList<>(); - this.errors = new ArrayList<>(); + this.values = new ArrayList(); + this.errors = new ArrayList(); this.done = new CountDownLatch(1); } @@ -86,9 +90,9 @@ public void onSubscribe(Disposable s) { errors.add(new NullPointerException("onSubscribe received a null Subscription")); return; } - if (!SUBSCRIPTION.compareAndSet(this, null, s)) { + if (!subscription.compareAndSet(null, s)) { s.dispose(); - if (subscription != CANCELLED) { + if (subscription.get() != CANCELLED) { errors.add(new NullPointerException("onSubscribe received multiple subscriptions: " + s)); } return; @@ -107,6 +111,13 @@ public void onSubscribe(Disposable s) { @Override public void onNext(T t) { + if (!checkSubscriptionOnce) { + checkSubscriptionOnce = true; + if (subscription.get() == null) { + errors.add(new IllegalStateException("onSubscribe not called in proper order")); + } + } + lastThread = Thread.currentThread(); values.add(t); @@ -119,6 +130,13 @@ public void onNext(T t) { @Override public void onError(Throwable t) { + if (!checkSubscriptionOnce) { + checkSubscriptionOnce = true; + if (subscription.get() == null) { + errors.add(new IllegalStateException("onSubscribe not called in proper order")); + } + } + try { lastThread = Thread.currentThread(); errors.add(t); @@ -135,6 +153,13 @@ public void onError(Throwable t) { @Override public void onComplete() { + if (!checkSubscriptionOnce) { + checkSubscriptionOnce = true; + if (subscription.get() == null) { + errors.add(new IllegalStateException("onSubscribe not called in proper order")); + } + } + try { lastThread = Thread.currentThread(); completions++; @@ -157,9 +182,9 @@ public final boolean isCancelled() { public final void dispose() { if (!cancelled) { cancelled = true; - Disposable s = subscription; + Disposable s = subscription.get(); if (s != CANCELLED) { - s = SUBSCRIPTION.getAndSet(this, CANCELLED); + s = subscription.getAndSet(CANCELLED); if (s != CANCELLED && s != null) { s.dispose(); } @@ -275,13 +300,17 @@ public final boolean await(long time, TimeUnit unit) throws InterruptedException */ private void fail(String prefix, String message, Iterable errors) { AssertionError ae = new AssertionError(prefix + message); - errors.forEach(e -> { + CompositeException ce = new CompositeException(); + for (Throwable e : errors) { if (e == null) { - ae.addSuppressed(new NullPointerException("Throwable was null!")); + ce.suppress(new NullPointerException("Throwable was null!")); } else { - ae.addSuppressed(e); + ce.suppress(e); } - }); + }; + if (!ce.isEmpty()) { + ae.initCause(ce); + } throw ae; } @@ -353,7 +382,7 @@ public void assertError(Throwable error) { } int s = errors.size(); if (s == 0) { - fail(prefix, "No errors", Collections.emptyList()); + fail(prefix, "No errors", Collections.emptyList()); } if (errors.contains(error)) { if (s != 1) { @@ -376,11 +405,17 @@ public void assertError(Class errorClass) { } int s = errors.size(); if (s == 0) { - fail(prefix, "No errors", Collections.emptyList()); + fail(prefix, "No errors", Collections.emptyList()); } - boolean found = errors.stream() - .anyMatch(errorClass::isInstance); + boolean found = false; + + for (Throwable e : errors) { + if (errorClass.isInstance(e)) { + found = true; + break; + } + } if (found) { if (s != 1) { @@ -446,7 +481,6 @@ public final void assertNoValues() { * @param values the values expected * @see #assertValueSet(Collection) */ - @SafeVarargs public final void assertValues(T... values) { String prefix = ""; if (done.getCount() != 0) { @@ -601,7 +635,7 @@ public boolean awaitTerminalEvent() { /** * Awaits the specified amount of time or until this TestSubscriber * receives an onError or onComplete events, whichever happens first. - * @param time the waiting time + * @param duration the waiting time * @param unit the time unit of the waiting time * @return true if the TestSubscriber terminated, false if timeout or interrupt happened */ @@ -621,12 +655,12 @@ public void assertErrorMessage(String message) { } int s = errors.size(); if (s == 0) { - fail(prefix, "No errors", Collections.emptyList()); + fail(prefix, "No errors", Collections.emptyList()); } else if (s == 1) { Throwable e = errors.get(0); if (e == null) { - fail(prefix, "Error is null", Collections.emptyList()); + fail(prefix, "Error is null", Collections.emptyList()); } String errorMessage = e.getMessage(); if (!Objects.equals(message, errorMessage)) { @@ -646,13 +680,13 @@ public void assertErrorMessage(String message) { */ @SuppressWarnings({ "rawtypes", "unchecked" }) public List> getEvents() { - List> result = new ArrayList<>(); + List> result = new ArrayList>(); result.add((List)values()); result.add((List)errors()); - List completeList = new ArrayList<>(); + List completeList = new ArrayList(); for (long i = 0; i < completions; i++) { completeList.add(Notification.complete()); } diff --git a/src/perf/java/io/reactivex/EachTypeFlatMapPerf.java b/src/perf/java/io/reactivex/EachTypeFlatMapPerf.java index 4bcc9f2946..ce567d6880 100644 --- a/src/perf/java/io/reactivex/EachTypeFlatMapPerf.java +++ b/src/perf/java/io/reactivex/EachTypeFlatMapPerf.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,10 +13,13 @@ package io.reactivex; -import java.util.concurrent.*; +import java.util.concurrent.TimeUnit; import org.openjdk.jmh.annotations.*; import org.openjdk.jmh.infra.Blackhole; +import org.reactivestreams.Publisher; + +import io.reactivex.functions.Function; @BenchmarkMode(Mode.Throughput) @Warmup(iterations = 5) @@ -44,48 +47,73 @@ public void setup() { bpRange = Observable.range(1, times); nbpRange = NbpObservable.range(1, times); - bpRangeMapJust = bpRange.flatMap(Observable::just); - nbpRangeMapJust = nbpRange.flatMap(NbpObservable::just); + bpRangeMapJust = bpRange.flatMap(new Function>() { + @Override + public Publisher apply(Integer v) { + return Observable.just(v); + } + }); + nbpRangeMapJust = nbpRange.flatMap(new Function>() { + @Override + public NbpObservable apply(Integer v) { + return NbpObservable.just(v); + } + }); - bpRangeMapRange = bpRange.flatMap(v -> Observable.range(v, 2)); - nbpRangeMapRange = nbpRange.flatMap(v -> NbpObservable.range(v, 2)); + bpRangeMapRange = bpRange.flatMap(new Function>() { + @Override + public Publisher apply(Integer v) { + return Observable.range(v, 2); + } + }); + nbpRangeMapRange = nbpRange.flatMap(new Function>() { + @Override + public NbpObservable apply(Integer v) { + return NbpObservable.range(v, 2); + } + }); singleJust = Single.just(1); - singleJustMapJust = singleJust.flatMap(Single::just); + singleJustMapJust = singleJust.flatMap(new Function>() { + @Override + public Single apply(Integer v) { + return Single.just(v); + } + }); } @Benchmark public void bpRange(Blackhole bh) { - bpRange.subscribe(new LatchedObserver<>(bh)); + bpRange.subscribe(new LatchedObserver(bh)); } @Benchmark public void bpRangeMapJust(Blackhole bh) { - bpRangeMapJust.subscribe(new LatchedObserver<>(bh)); + bpRangeMapJust.subscribe(new LatchedObserver(bh)); } @Benchmark public void bpRangeMapRange(Blackhole bh) { - bpRangeMapRange.subscribe(new LatchedObserver<>(bh)); + bpRangeMapRange.subscribe(new LatchedObserver(bh)); } @Benchmark public void nbpRange(Blackhole bh) { - nbpRange.subscribe(new LatchedNbpObserver<>(bh)); + nbpRange.subscribe(new LatchedNbpObserver(bh)); } @Benchmark public void nbpRangeMapJust(Blackhole bh) { - nbpRangeMapJust.subscribe(new LatchedNbpObserver<>(bh)); + nbpRangeMapJust.subscribe(new LatchedNbpObserver(bh)); } @Benchmark public void nbpRangeMapRange(Blackhole bh) { - nbpRangeMapRange.subscribe(new LatchedNbpObserver<>(bh)); + nbpRangeMapRange.subscribe(new LatchedNbpObserver(bh)); } @Benchmark public void singleJust(Blackhole bh) { - singleJust.subscribe(new LatchedSingleObserver<>(bh)); + singleJust.subscribe(new LatchedSingleObserver(bh)); } @Benchmark public void singleJustMapJust(Blackhole bh) { - singleJustMapJust.subscribe(new LatchedSingleObserver<>(bh)); + singleJustMapJust.subscribe(new LatchedSingleObserver(bh)); } } \ No newline at end of file diff --git a/src/perf/java/io/reactivex/InputWithIncrementingInteger.java b/src/perf/java/io/reactivex/InputWithIncrementingInteger.java index 6dd4bc24db..7ff7e5a63d 100644 --- a/src/perf/java/io/reactivex/InputWithIncrementingInteger.java +++ b/src/perf/java/io/reactivex/InputWithIncrementingInteger.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -18,7 +18,8 @@ import org.openjdk.jmh.annotations.Setup; import org.openjdk.jmh.infra.Blackhole; import org.reactivestreams.*; -import io.reactivex.internal.subscriptions.*; + +import io.reactivex.internal.subscriptions.EmptySubscription; /** * Exposes an Observable and Observer that increments n Integers and consumes them in a Blackhole. @@ -77,7 +78,7 @@ public void remove() { } public LatchedObserver newLatchedObserver() { - return new LatchedObserver<>(bh); + return new LatchedObserver(bh); } public Subscriber newSubscriber() { diff --git a/src/perf/java/io/reactivex/LatchedNbpObserver.java b/src/perf/java/io/reactivex/LatchedNbpObserver.java index 130d5af799..629b277233 100644 --- a/src/perf/java/io/reactivex/LatchedNbpObserver.java +++ b/src/perf/java/io/reactivex/LatchedNbpObserver.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 diff --git a/src/perf/java/io/reactivex/LatchedObserver.java b/src/perf/java/io/reactivex/LatchedObserver.java index 2396d379c3..e02e562a5b 100644 --- a/src/perf/java/io/reactivex/LatchedObserver.java +++ b/src/perf/java/io/reactivex/LatchedObserver.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -17,6 +17,8 @@ import org.openjdk.jmh.infra.Blackhole; +import io.reactivex.Observer; + public class LatchedObserver extends Observer { public CountDownLatch latch = new CountDownLatch(1); diff --git a/src/perf/java/io/reactivex/LatchedSingleObserver.java b/src/perf/java/io/reactivex/LatchedSingleObserver.java index 6b13f4d19a..35ff228921 100644 --- a/src/perf/java/io/reactivex/LatchedSingleObserver.java +++ b/src/perf/java/io/reactivex/LatchedSingleObserver.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 diff --git a/src/perf/java/io/reactivex/OperatorFlatMapPerf.java b/src/perf/java/io/reactivex/OperatorFlatMapPerf.java index 5c4791fa4f..f8d27eeb00 100644 --- a/src/perf/java/io/reactivex/OperatorFlatMapPerf.java +++ b/src/perf/java/io/reactivex/OperatorFlatMapPerf.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -16,7 +16,11 @@ import java.util.concurrent.TimeUnit; import org.openjdk.jmh.annotations.*; -import io.reactivex.schedulers.*; +import org.reactivestreams.Publisher; + +import io.reactivex.Observable; +import io.reactivex.functions.Function; +import io.reactivex.schedulers.Schedulers; @BenchmarkMode(Mode.Throughput) @OutputTimeUnit(TimeUnit.SECONDS) @@ -38,14 +42,22 @@ public int getSize() { @Benchmark public void flatMapIntPassthruSync(Input input) throws InterruptedException { - input.observable.flatMap(Observable::just).subscribe(input.newSubscriber()); + input.observable.flatMap(new Function>() { + @Override + public Publisher apply(Integer v) { + return Observable.just(v); + } + }).subscribe(input.newSubscriber()); } @Benchmark public void flatMapIntPassthruAsync(Input input) throws InterruptedException { LatchedObserver latchedObserver = input.newLatchedObserver(); - input.observable.flatMap(i -> { - return Observable.just(i).subscribeOn(Schedulers.computation()); + input.observable.flatMap(new Function>() { + @Override + public Publisher apply(Integer i) { + return Observable.just(i).subscribeOn(Schedulers.computation()); + } }).subscribe(latchedObserver); if (input.size == 1) { while (latchedObserver.latch.getCount() != 0); @@ -56,8 +68,11 @@ public void flatMapIntPassthruAsync(Input input) throws InterruptedException { @Benchmark public void flatMapTwoNestedSync(final Input input) throws InterruptedException { - Observable.range(1, 2).flatMap(i -> { - return input.observable; + Observable.range(1, 2).flatMap(new Function>() { + @Override + public Publisher apply(Integer i) { + return input.observable; + } }).subscribe(input.newSubscriber()); } diff --git a/src/perf/java/io/reactivex/OperatorMergePerf.java b/src/perf/java/io/reactivex/OperatorMergePerf.java index e1e2847c06..e8eef8b97d 100644 --- a/src/perf/java/io/reactivex/OperatorMergePerf.java +++ b/src/perf/java/io/reactivex/OperatorMergePerf.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -19,7 +19,9 @@ import org.openjdk.jmh.annotations.*; import org.openjdk.jmh.infra.Blackhole; -import io.reactivex.schedulers.*; +import io.reactivex.Observable; +import io.reactivex.functions.Function; +import io.reactivex.schedulers.Schedulers; @BenchmarkMode(Mode.Throughput) @OutputTimeUnit(TimeUnit.SECONDS) @@ -28,7 +30,13 @@ public class OperatorMergePerf { // flatMap @Benchmark public void oneStreamOfNthatMergesIn1(final InputMillion input) throws InterruptedException { - Observable> os = Observable.range(1, input.size).map(Observable::just); + Observable> os = Observable.range(1, input.size) + .map(new Function>() { + @Override + public Observable apply(Integer v) { + return Observable.just(v); + } + }); LatchedObserver o = input.newLatchedObserver(); Observable.merge(os).subscribe(o); @@ -42,8 +50,11 @@ public void oneStreamOfNthatMergesIn1(final InputMillion input) throws Interrupt // flatMap @Benchmark public void merge1SyncStreamOfN(final InputMillion input) throws InterruptedException { - Observable> os = Observable.just(1).map(i -> { - return Observable.range(0, input.size); + Observable> os = Observable.just(1).map(new Function>() { + @Override + public Observable apply(Integer i) { + return Observable.range(0, input.size); + } }); LatchedObserver o = input.newLatchedObserver(); Observable.merge(os).subscribe(o); @@ -57,8 +68,11 @@ public void merge1SyncStreamOfN(final InputMillion input) throws InterruptedExce @Benchmark public void mergeNSyncStreamsOfN(final InputThousand input) throws InterruptedException { - Observable> os = input.observable.map(i -> { - return Observable.range(0, input.size); + Observable> os = input.observable.map(new Function>() { + @Override + public Observable apply(Integer i) { + return Observable.range(0, input.size); + } }); LatchedObserver o = input.newLatchedObserver(); Observable.merge(os).subscribe(o); @@ -71,8 +85,11 @@ public void mergeNSyncStreamsOfN(final InputThousand input) throws InterruptedEx @Benchmark public void mergeNAsyncStreamsOfN(final InputThousand input) throws InterruptedException { - Observable> os = input.observable.map(i -> { - return Observable.range(0, input.size).subscribeOn(Schedulers.computation()); + Observable> os = input.observable.map(new Function>() { + @Override + public Observable apply(Integer i) { + return Observable.range(0, input.size).subscribeOn(Schedulers.computation()); + } }); LatchedObserver o = input.newLatchedObserver(); Observable.merge(os).subscribe(o); @@ -118,14 +135,14 @@ public static class InputForMergeN { @Setup public void setup(final Blackhole bh) { this.bh = bh; - observables = new ArrayList<>(); + observables = new ArrayList>(); for (int i = 0; i < size; i++) { observables.add(Observable.just(i)); } } public LatchedObserver newLatchedObserver() { - return new LatchedObserver<>(bh); + return new LatchedObserver(bh); } } diff --git a/src/perf/java/io/reactivex/RangePerf.java b/src/perf/java/io/reactivex/RangePerf.java index c54b71e4f8..768ccdb3b3 100644 --- a/src/perf/java/io/reactivex/RangePerf.java +++ b/src/perf/java/io/reactivex/RangePerf.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -18,6 +18,7 @@ import org.openjdk.jmh.annotations.*; import org.openjdk.jmh.infra.Blackhole; +import io.reactivex.Observable; import io.reactivex.internal.schedulers.SingleScheduler; import io.reactivex.schedulers.Schedulers; @@ -48,16 +49,16 @@ public void setup() { @Benchmark public Object rangeSync(Blackhole bh) { - LatchedObserver lo = new LatchedObserver<>(bh); + LatchedObserver lo = new LatchedObserver(bh); range.subscribe(lo); return lo; } - @Benchmark +// @Benchmark public void rangeAsync(Blackhole bh) throws Exception { - LatchedObserver lo = new LatchedObserver<>(bh); + LatchedObserver lo = new LatchedObserver(bh); rangeAsync.subscribe(lo); @@ -68,9 +69,9 @@ public void rangeAsync(Blackhole bh) throws Exception { } } - @Benchmark +// @Benchmark public void rangePipeline(Blackhole bh) throws Exception { - LatchedObserver lo = new LatchedObserver<>(bh); + LatchedObserver lo = new LatchedObserver(bh); rangeAsyncPipeline.subscribe(lo); diff --git a/src/perf/java/io/reactivex/RxVsStreamPerf.java b/src/perf/java/io/reactivex/RxVsStreamPerf.java index 46adab6575..67a1e86bb9 100644 --- a/src/perf/java/io/reactivex/RxVsStreamPerf.java +++ b/src/perf/java/io/reactivex/RxVsStreamPerf.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,15 +13,18 @@ package io.reactivex; -import java.util.*; +import java.util.List; import java.util.concurrent.TimeUnit; import org.openjdk.jmh.annotations.*; import org.openjdk.jmh.infra.Blackhole; +import org.reactivestreams.Publisher; + +import io.reactivex.functions.Function; @BenchmarkMode(Mode.Throughput) @Warmup(iterations = 5) -@Measurement(iterations = 5, time = 5, timeUnit = TimeUnit.SECONDS) +@Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS) @OutputTimeUnit(TimeUnit.SECONDS) @Fork(value = 1) @State(Scope.Thread) @@ -36,64 +39,78 @@ public class RxVsStreamPerf { Observable rangeFlatMap; NbpObservable rangeNbpFlatMap; - + + Observable rangeFlatMapJust; + + NbpObservable rangeNbpFlatMapJust; + List values; @Setup public void setup() { range = Observable.range(1, times); - - rangeFlatMap = range.flatMap(v -> Observable.range(v, 2)); + + rangeFlatMapJust = range.flatMap(new Function>() { + @Override + public Publisher apply(Integer v) { + return Observable.just(v); + } + }); + + rangeFlatMap = range.flatMap(new Function>() { + @Override + public Publisher apply(Integer v) { + return Observable.range(v, 2); + } + }); rangeNbp = NbpObservable.range(1, times); - rangeNbpFlatMap = rangeNbp.flatMap(v -> NbpObservable.range(v, 2)); + rangeNbpFlatMapJust = rangeNbp.flatMap(new Function>() { + @Override + public NbpObservable apply(Integer v) { + return NbpObservable.just(v); + } + }); + + rangeNbpFlatMap = rangeNbp.flatMap(new Function>() { + @Override + public NbpObservable apply(Integer v) { + return NbpObservable.range(v, 2); + } + }); values = range.toList().toBlocking().first(); } @Benchmark public void range(Blackhole bh) { - range.subscribe(new LatchedObserver<>(bh)); + range.subscribe(new LatchedObserver(bh)); } @Benchmark public void rangeNbp(Blackhole bh) { - rangeNbp.subscribe(new LatchedNbpObserver<>(bh)); + rangeNbp.subscribe(new LatchedNbpObserver(bh)); } @Benchmark public void rangeFlatMap(Blackhole bh) { - rangeFlatMap.subscribe(new LatchedObserver<>(bh)); + rangeFlatMap.subscribe(new LatchedObserver(bh)); } @Benchmark public void rangeNbpFlatMap(Blackhole bh) { - rangeNbpFlatMap.subscribe(new LatchedNbpObserver<>(bh)); + rangeNbpFlatMap.subscribe(new LatchedNbpObserver(bh)); } @Benchmark - public void stream(Blackhole bh) { - values.stream().forEach(bh::consume); + public void rangeFlatMapJust(Blackhole bh) { + rangeFlatMapJust.subscribe(new LatchedObserver(bh)); } @Benchmark - public void streamFlatMap(Blackhole bh) { - values.stream() - .flatMap(v -> Arrays.asList(v, v + 1).stream()) - .forEach(bh::consume); - } - - @Benchmark - public void streamParallel(Blackhole bh) { - values.stream().parallel().forEach(bh::consume); + public void rangeNbpFlatMapJust(Blackhole bh) { + rangeNbpFlatMapJust.subscribe(new LatchedNbpObserver(bh)); } - @Benchmark - public void streamParallelFlatMap(Blackhole bh) { - values.stream() - .flatMap(v -> Arrays.asList(v, v + 1).stream()) - .parallel() - .forEach(bh::consume); - } } \ No newline at end of file diff --git a/src/test/java/io/reactivex/BackpressureTests.java b/src/test/java/io/reactivex/BackpressureTests.java index c2f222e05d..de964ef8fa 100644 --- a/src/test/java/io/reactivex/BackpressureTests.java +++ b/src/test/java/io/reactivex/BackpressureTests.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -18,13 +18,14 @@ import java.util.List; import java.util.concurrent.*; import java.util.concurrent.atomic.*; -import java.util.function.Function; import org.junit.*; import org.junit.rules.TestName; import org.reactivestreams.*; +import io.reactivex.Observable; import io.reactivex.exceptions.MissingBackpressureException; +import io.reactivex.functions.*; import io.reactivex.internal.subscriptions.SubscriptionHelper; import io.reactivex.internal.util.BackpressureHelper; import io.reactivex.schedulers.Schedulers; @@ -81,7 +82,7 @@ public void doAfterTest() { public void testObserveOn() { int NUM = (int) (Observable.bufferSize() * 2.1); AtomicInteger c = new AtomicInteger(); - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); incrementingIntegers(c).observeOn(Schedulers.computation()).take(NUM).subscribe(ts); ts.awaitTerminalEvent(); ts.assertNoErrors(); @@ -94,15 +95,18 @@ public void testObserveOn() { public void testObserveOnWithSlowConsumer() { int NUM = (int) (Observable.bufferSize() * 0.2); AtomicInteger c = new AtomicInteger(); - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); incrementingIntegers(c).observeOn(Schedulers.computation()).map( - i -> { - try { - Thread.sleep(1); - } catch (InterruptedException e) { - e.printStackTrace(); + new Function() { + @Override + public Integer apply(Integer i) { + try { + Thread.sleep(1); + } catch (InterruptedException e) { + e.printStackTrace(); + } + return i; } - return i; } ).take(NUM).subscribe(ts); ts.awaitTerminalEvent(); @@ -117,7 +121,7 @@ public void testMergeSync() { int NUM = (int) (Observable.bufferSize() * 4.1); AtomicInteger c1 = new AtomicInteger(); AtomicInteger c2 = new AtomicInteger(); - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); Observable merged = Observable.merge(incrementingIntegers(c1), incrementingIntegers(c2)); merged.take(NUM).subscribe(ts); @@ -138,7 +142,7 @@ public void testMergeAsync() { int NUM = (int) (Observable.bufferSize() * 4.1); AtomicInteger c1 = new AtomicInteger(); AtomicInteger c2 = new AtomicInteger(); - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); Observable merged = Observable.merge( incrementingIntegers(c1).subscribeOn(Schedulers.computation()), incrementingIntegers(c2).subscribeOn(Schedulers.computation())); @@ -167,7 +171,7 @@ public void testMergeAsyncThenObserveOnLoop() { AtomicInteger c1 = new AtomicInteger(); AtomicInteger c2 = new AtomicInteger(); - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); Observable merged = Observable.merge( incrementingIntegers(c1).subscribeOn(Schedulers.computation()), incrementingIntegers(c2).subscribeOn(Schedulers.computation())); @@ -191,7 +195,7 @@ public void testMergeAsyncThenObserveOn() { int NUM = (int) (Observable.bufferSize() * 4.1); AtomicInteger c1 = new AtomicInteger(); AtomicInteger c2 = new AtomicInteger(); - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); Observable merged = Observable.merge( incrementingIntegers(c1).subscribeOn(Schedulers.computation()), incrementingIntegers(c2).subscribeOn(Schedulers.computation())); @@ -213,10 +217,15 @@ public void testMergeAsyncThenObserveOn() { public void testFlatMapSync() { int NUM = (int) (Observable.bufferSize() * 2.1); AtomicInteger c = new AtomicInteger(); - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); incrementingIntegers(c) - .flatMap(i -> incrementingIntegers(new AtomicInteger()).take(10)) + .flatMap(new Function>() { + @Override + public Publisher apply(Integer i) { + return incrementingIntegers(new AtomicInteger()).take(10); + } + }) .take(NUM).subscribe(ts); ts.awaitTerminalEvent(); @@ -232,13 +241,18 @@ public void testFlatMapSync() { public void testFlatMapAsync() { int NUM = (int) (Observable.bufferSize() * 2.1); AtomicInteger c = new AtomicInteger(); - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); incrementingIntegers(c) .subscribeOn(Schedulers.computation()) - .flatMap(i -> incrementingIntegers(new AtomicInteger()) - .take(10) - .subscribeOn(Schedulers.computation()) + .flatMap(new Function>() { + @Override + public Publisher apply(Integer i) { + return incrementingIntegers(new AtomicInteger()) + .take(10) + .subscribeOn(Schedulers.computation()); + } + } ) .take(NUM).subscribe(ts); @@ -257,12 +271,17 @@ public void testZipSync() { int NUM = (int) (Observable.bufferSize() * 4.1); AtomicInteger c1 = new AtomicInteger(); AtomicInteger c2 = new AtomicInteger(); - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); Observable zipped = Observable.zip( incrementingIntegers(c1), incrementingIntegers(c2), - (t1, t2) -> t1 + t2); + new BiFunction() { + @Override + public Integer apply(Integer t1, Integer t2) { + return t1 + t2; + } + }); zipped.take(NUM) .subscribe(ts); @@ -280,11 +299,16 @@ public void testZipAsync() { int NUM = (int) (Observable.bufferSize() * 2.1); AtomicInteger c1 = new AtomicInteger(); AtomicInteger c2 = new AtomicInteger(); - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); Observable zipped = Observable.zip( incrementingIntegers(c1).subscribeOn(Schedulers.computation()), incrementingIntegers(c2).subscribeOn(Schedulers.computation()), - (t1, t2) -> t1 + t2); + new BiFunction() { + @Override + public Integer apply(Integer t1, Integer t2) { + return t1 + t2; + } + }); zipped.take(NUM).subscribe(ts); ts.awaitTerminalEvent(); @@ -302,8 +326,8 @@ public void testSubscribeOnScheduling() { for (int i = 0; i < 100; i++) { int NUM = (int) (Observable.bufferSize() * 2.1); AtomicInteger c = new AtomicInteger(); - ConcurrentLinkedQueue threads = new ConcurrentLinkedQueue<>(); - TestSubscriber ts = new TestSubscriber<>(); + ConcurrentLinkedQueue threads = new ConcurrentLinkedQueue(); + TestSubscriber ts = new TestSubscriber(); // observeOn is there to make it async and need backpressure incrementingIntegers(c, threads).subscribeOn(Schedulers.computation()).observeOn(Schedulers.computation()).take(NUM).subscribe(ts); ts.awaitTerminalEvent(); @@ -332,10 +356,15 @@ public void testSubscribeOnScheduling() { public void testTakeFilterSkipChainAsync() { int NUM = (int) (Observable.bufferSize() * 2.1); AtomicInteger c = new AtomicInteger(); - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); incrementingIntegers(c).observeOn(Schedulers.computation()) .skip(10000) - .filter(i -> i > 11000).take(NUM).subscribe(ts); + .filter(new Predicate() { + @Override + public boolean test(Integer i) { + return i > 11000; + } + }).take(NUM).subscribe(ts); ts.awaitTerminalEvent(); ts.assertNoErrors(); @@ -454,16 +483,19 @@ public void onNext(Integer t) { @Test(timeout = 2000) public void testFirehoseFailsAsExpected() { AtomicInteger c = new AtomicInteger(); - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); firehose(c).observeOn(Schedulers.computation()) - .map(v -> { - try { - Thread.sleep(10); - } catch (Exception e) { - e.printStackTrace(); + .map(new Function() { + @Override + public Integer apply(Integer v) { + try { + Thread.sleep(10); + } catch (Exception e) { + e.printStackTrace(); + } + return v; } - return v; }) .subscribe(ts); @@ -495,7 +527,7 @@ public void testOnBackpressureDrop() { } int NUM = (int) (Observable.bufferSize() * 1.1); // > 1 so that take doesn't prevent buffer overflow AtomicInteger c = new AtomicInteger(); - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); firehose(c).onBackpressureDrop() .observeOn(Schedulers.computation()) .map(SLOW_PASS_THRU).take(NUM).subscribe(ts); @@ -520,11 +552,21 @@ public void testOnBackpressureDropWithAction() { final AtomicInteger dropCount = new AtomicInteger(); final AtomicInteger passCount = new AtomicInteger(); final int NUM = Observable.bufferSize() * 3; // > 1 so that take doesn't prevent buffer overflow - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); firehose(emitCount) - .onBackpressureDrop(v -> dropCount.incrementAndGet()) - .doOnNext(v -> passCount.incrementAndGet()) + .onBackpressureDrop(new Consumer() { + @Override + public void accept(Integer v) { + dropCount.incrementAndGet(); + } + }) + .doOnNext(new Consumer() { + @Override + public void accept(Integer v) { + passCount.incrementAndGet(); + } + }) .observeOn(Schedulers.computation()) .map(SLOW_PASS_THRU) .take(NUM).subscribe(ts); @@ -550,7 +592,7 @@ public void testOnBackpressureDropSynchronous() { for (int i = 0; i < 100; i++) { int NUM = (int) (Observable.bufferSize() * 1.1); // > 1 so that take doesn't prevent buffer overflow AtomicInteger c = new AtomicInteger(); - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); firehose(c).onBackpressureDrop() .map(SLOW_PASS_THRU).take(NUM).subscribe(ts); ts.awaitTerminalEvent(); @@ -573,8 +615,13 @@ public void testOnBackpressureDropSynchronousWithAction() { final AtomicInteger dropCount = new AtomicInteger(); int NUM = (int) (Observable.bufferSize() * 1.1); // > 1 so that take doesn't prevent buffer overflow AtomicInteger c = new AtomicInteger(); - TestSubscriber ts = new TestSubscriber<>(); - firehose(c).onBackpressureDrop(j -> dropCount.incrementAndGet()) + TestSubscriber ts = new TestSubscriber(); + firehose(c).onBackpressureDrop(new Consumer() { + @Override + public void accept(Integer j) { + dropCount.incrementAndGet(); + } + }) .map(SLOW_PASS_THRU).take(NUM).subscribe(ts); ts.awaitTerminalEvent(); ts.assertNoErrors(); @@ -597,9 +644,14 @@ public void testOnBackpressureDropSynchronousWithAction() { public void testOnBackpressureBuffer() { int NUM = (int) (Observable.bufferSize() * 1.1); // > 1 so that take doesn't prevent buffer overflow AtomicInteger c = new AtomicInteger(); - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); - firehose(c).takeWhile(t1 -> t1 < 100000) + firehose(c).takeWhile(new Predicate() { + @Override + public boolean test(Integer t1) { + return t1 < 100000; + } + }) .onBackpressureBuffer() .observeOn(Schedulers.computation()) .map(SLOW_PASS_THRU).take(NUM).subscribe(ts); @@ -672,9 +724,12 @@ public void cancel() { * @return */ private static Observable firehose(final AtomicInteger counter) { - return Observable.create(s -> { - Subscription s2 = new FirehoseNoBackpressure(counter, s); - s.onSubscribe(s2); + return Observable.create(new Publisher() { + @Override + public void subscribe(Subscriber s) { + Subscription s2 = new FirehoseNoBackpressure(counter, s); + s.onSubscribe(s2); + } }); } diff --git a/src/test/java/io/reactivex/CombineLatestTests.java b/src/test/java/io/reactivex/CombineLatestTests.java index b245fb40a9..a33d3b6ed9 100644 --- a/src/test/java/io/reactivex/CombineLatestTests.java +++ b/src/test/java/io/reactivex/CombineLatestTests.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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. @@ -18,11 +18,11 @@ import static io.reactivex.Observable.combineLatest; import static org.junit.Assert.assertNull; -import java.util.function.*; - import org.junit.*; +import io.reactivex.Observable; import io.reactivex.CovarianceTest.*; +import io.reactivex.functions.*; import io.reactivex.subjects.BehaviorSubject; public class CombineLatestTests { @@ -43,11 +43,26 @@ public void testCovarianceOfCombineLatest() { Observable. combineLatest(horrors, ratings, combine); } - BiFunction combine = (m, r) -> new ExtendedResult(); + BiFunction combine = new BiFunction() { + @Override + public ExtendedResult apply(Media m, Rating r) { + return new ExtendedResult(); + } + }; - Consumer action = t1 -> System.out.println("Result: " + t1); + Consumer action = new Consumer() { + @Override + public void accept(Result t1) { + System.out.println("Result: " + t1); + } + }; - Consumer extendedAction = t1 -> System.out.println("Result: " + t1); + Consumer extendedAction = new Consumer() { + @Override + public void accept(ExtendedResult t1) { + System.out.println("Result: " + t1); + } + }; @Ignore @Test @@ -62,6 +77,11 @@ public Boolean apply(Boolean bool1, Boolean bool2) { return bool1 == null ? null : bool2; } }); - combined.subscribe(aBoolean -> assertNull(aBoolean)); + combined.subscribe(new Consumer() { + @Override + public void accept(Boolean aBoolean) { + assertNull(aBoolean); + } + }); } } \ No newline at end of file diff --git a/src/test/java/io/reactivex/CompletableTest.java b/src/test/java/io/reactivex/CompletableTest.java new file mode 100644 index 0000000000..cc1577ed46 --- /dev/null +++ b/src/test/java/io/reactivex/CompletableTest.java @@ -0,0 +1,3593 @@ +/** + * 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.*; +import java.util.concurrent.*; +import java.util.concurrent.atomic.*; + +import org.junit.*; +import org.reactivestreams.*; + +import io.reactivex.Completable.*; +import io.reactivex.NbpObservable.NbpSubscriber; +import io.reactivex.disposables.*; +import io.reactivex.exceptions.*; +import io.reactivex.functions.*; +import io.reactivex.internal.disposables.EmptyDisposable; +import io.reactivex.internal.functions.Functions; +import io.reactivex.plugins.RxJavaPlugins; +import io.reactivex.schedulers.*; +import io.reactivex.subjects.PublishSubject; +import io.reactivex.subscribers.TestSubscriber; +import io.reactivex.subscribers.nbp.NbpTestSubscriber; + +/** + * Test Completable methods and operators. + */ +public class CompletableTest { + /** + * Iterable that returns an Iterator that throws in its hasNext method. + */ + static final class IterableIteratorNextThrows implements Iterable { + @Override + public Iterator iterator() { + return new Iterator() { + @Override + public boolean hasNext() { + return true; + } + + @Override + public Completable next() { + throw new TestException(); + } + + @Override + public void remove() { + // TODO Auto-generated method stub + + } + }; + } + } + + /** + * Iterable that returns an Iterator that throws in its next method. + */ + static final class IterableIteratorHasNextThrows implements Iterable { + @Override + public Iterator iterator() { + return new Iterator() { + @Override + public boolean hasNext() { + throw new TestException(); + } + + @Override + public Completable next() { + return null; + } + + @Override + public void remove() { + // TODO Auto-generated method stub + + } + }; + } + } + + /** + * A class containing a completable instance and counts the number of subscribers. + */ + static final class NormalCompletable extends AtomicInteger { + /** */ + private static final long serialVersionUID = 7192337844700923752L; + + public final Completable completable = Completable.create(new CompletableOnSubscribe() { + @Override + public void accept(CompletableSubscriber s) { + getAndIncrement(); + s.onSubscribe(EmptyDisposable.INSTANCE); + s.onComplete(); + } + }); + + /** + * Asserts the given number of subscriptions happened. + * @param n the expected number of subscriptions + */ + public void assertSubscriptions(int n) { + Assert.assertEquals(n, get()); + } + } + + /** + * A class containing a completable instance that emits a TestException and counts + * the number of subscribers. + */ + static final class ErrorCompletable extends AtomicInteger { + /** */ + private static final long serialVersionUID = 7192337844700923752L; + + public final Completable completable = Completable.create(new CompletableOnSubscribe() { + @Override + public void accept(CompletableSubscriber s) { + getAndIncrement(); + s.onSubscribe(EmptyDisposable.INSTANCE); + s.onError(new TestException()); + } + }); + + /** + * Asserts the given number of subscriptions happened. + * @param n the expected number of subscriptions + */ + public void assertSubscriptions(int n) { + Assert.assertEquals(n, get()); + } + } + + /** A normal Completable object. */ + final NormalCompletable normal = new NormalCompletable(); + + /** An error Completable object. */ + final ErrorCompletable error = new ErrorCompletable(); + + @Test(timeout = 1000) + public void complete() { + Completable c = Completable.complete(); + + c.await(); + } + + @Test(expected = NullPointerException.class) + public void concatNull() { + Completable.concat((Completable[])null); + } + + @Test(timeout = 1000) + public void concatEmpty() { + Completable c = Completable.concat(); + + c.await(); + } + + @Test(timeout = 1000) + public void concatSingleSource() { + Completable c = Completable.concat(normal.completable); + + c.await(); + + normal.assertSubscriptions(1); + } + + @Test(timeout = 1000, expected = TestException.class) + public void concatSingleSourceThrows() { + Completable c = Completable.concat(error.completable); + + c.await(); + } + + @Test(timeout = 1000) + public void concatMultipleSources() { + Completable c = Completable.concat(normal.completable, normal.completable, normal.completable); + + c.await(); + + normal.assertSubscriptions(3); + } + + @Test(timeout = 1000, expected = TestException.class) + public void concatMultipleOneThrows() { + Completable c = Completable.concat(normal.completable, error.completable, normal.completable); + + c.await(); + } + + @Test(timeout = 1000, expected = NullPointerException.class) + public void concatMultipleOneIsNull() { + Completable c = Completable.concat(normal.completable, null); + + c.await(); + } + + @Test(timeout = 1000) + public void concatIterableEmpty() { + Completable c = Completable.concat(Collections.emptyList()); + + c.await(); + } + + @Test(expected = NullPointerException.class) + public void concatIterableNull() { + Completable.concat((Iterable)null); + } + + @Test(timeout = 1000, expected = NullPointerException.class) + public void concatIterableIteratorNull() { + Completable c = Completable.concat(new Iterable() { + @Override + public Iterator iterator() { + return null; + } + }); + + c.await(); + } + + @Test(timeout = 1000, expected = NullPointerException.class) + public void concatIterableWithNull() { + Completable c = Completable.concat(Arrays.asList(normal.completable, (Completable)null)); + + c.await(); + } + + @Test(timeout = 1000) + public void concatIterableSingle() { + Completable c = Completable.concat(Collections.singleton(normal.completable)); + + c.await(); + + normal.assertSubscriptions(1); + } + + @Test(timeout = 1000) + public void concatIterableMany() { + Completable c = Completable.concat(Arrays.asList(normal.completable, normal.completable, normal.completable)); + + c.await(); + + normal.assertSubscriptions(3); + } + + @Test(timeout = 1000, expected = TestException.class) + public void concatIterableOneThrows() { + Completable c = Completable.concat(Collections.singleton(error.completable)); + + c.await(); + } + + @Test(timeout = 1000, expected = TestException.class) + public void concatIterableManyOneThrows() { + Completable c = Completable.concat(Arrays.asList(normal.completable, error.completable)); + + c.await(); + } + + @Test(expected = TestException.class) + public void concatIterableIterableThrows() { + Completable c = Completable.concat(new Iterable() { + @Override + public Iterator iterator() { + throw new TestException(); + } + }); + + c.await(); + } + + @Test(expected = TestException.class) + public void concatIterableIteratorHasNextThrows() { + Completable c = Completable.concat(new IterableIteratorHasNextThrows()); + + c.await(); + } + + @Test(expected = TestException.class) + public void concatIterableIteratorNextThrows() { + Completable c = Completable.concat(new IterableIteratorNextThrows()); + + c.await(); + } + + @Test(timeout = 1000) + public void concatObservableEmpty() { + Completable c = Completable.concat(Observable.empty()); + + c.await(); + } + + @Test(timeout = 1000, expected = TestException.class) + public void concatObservableError() { + Completable c = Completable.concat(Observable.error(new Supplier() { + @Override + public Throwable get() { + return new TestException(); + } + })); + + c.await(); + } + + @Test(timeout = 1000) + public void concatObservableSingle() { + Completable c = Completable.concat(Observable.just(normal.completable)); + + c.await(); + + normal.assertSubscriptions(1); + } + + @Test(timeout = 1000, expected = TestException.class) + public void concatObservableSingleThrows() { + Completable c = Completable.concat(Observable.just(error.completable)); + + c.await(); + } + + @Test(timeout = 1000) + public void concatObservableMany() { + Completable c = Completable.concat(Observable.just(normal.completable).repeat(3)); + + c.await(); + + normal.assertSubscriptions(3); + } + + @Test(timeout = 1000, expected = TestException.class) + public void concatObservableManyOneThrows() { + Completable c = Completable.concat(Observable.just(normal.completable, error.completable)); + + c.await(); + } + + @Test(timeout = 1000) + public void concatObservablePrefetch() { + final List requested = new ArrayList(); + Observable cs = Observable + .just(normal.completable) + .repeat(10) + .doOnRequest(new LongConsumer() { + @Override + public void accept(long v) { + requested.add(v); + } + }); + + Completable c = Completable.concat(cs, 5); + + c.await(); + + // FIXME this request pattern looks odd because all 10 completions trigger 1 requests + Assert.assertEquals(Arrays.asList(5L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), requested); + } + + @Test(expected = NullPointerException.class) + public void createNull() { + Completable.create(null); + } + + @Test(timeout = 1000, expected = NullPointerException.class) + public void createOnSubscribeThrowsNPE() { + Completable c = Completable.create(new CompletableOnSubscribe() { + @Override + public void accept(CompletableSubscriber s) { throw new NullPointerException(); } + }); + + c.await(); + } + + @Test(timeout = 1000) + public void createOnSubscribeThrowsRuntimeException() { + try { + Completable c = Completable.create(new CompletableOnSubscribe() { + @Override + public void accept(CompletableSubscriber s) { + throw new TestException(); + } + }); + + c.await(); + + Assert.fail("Did not throw exception"); + } catch (NullPointerException ex) { + if (!(ex.getCause() instanceof TestException)) { + ex.printStackTrace(); + Assert.fail("Did not wrap the TestException but it returned: " + ex); + } + } + } + + @Test(timeout = 1000) + public void defer() { + Completable c = Completable.defer(new Supplier() { + @Override + public Completable get() { + return normal.completable; + } + }); + + normal.assertSubscriptions(0); + + c.await(); + + normal.assertSubscriptions(1); + } + + @Test(expected = NullPointerException.class) + public void deferNull() { + Completable.defer(null); + } + + @Test(timeout = 1000, expected = NullPointerException.class) + public void deferReturnsNull() { + Completable c = Completable.defer(new Supplier() { + @Override + public Completable get() { + return null; + } + }); + + c.await(); + } + + @Test(timeout = 1000, expected = TestException.class) + public void deferFunctionThrows() { + Completable c = Completable.defer(new Supplier() { + @Override + public Completable get() { throw new TestException(); } + }); + + c.await(); + } + + @Test(timeout = 1000, expected = TestException.class) + public void deferErrorSource() { + Completable c = Completable.defer(new Supplier() { + @Override + public Completable get() { + return error.completable; + } + }); + + c.await(); + } + + @Test(expected = NullPointerException.class) + public void errorSupplierNull() { + Completable.error((Supplier)null); + } + + @Test(timeout = 1000, expected = TestException.class) + public void errorSupplierNormal() { + Completable c = Completable.error(new Supplier() { + @Override + public Throwable get() { + return new TestException(); + } + }); + + c.await(); + } + + @Test(timeout = 1000, expected = NullPointerException.class) + public void errorSupplierReturnsNull() { + Completable c = Completable.error(new Supplier() { + @Override + public Throwable get() { + return null; + } + }); + + c.await(); + } + + @Test(timeout = 1000, expected = TestException.class) + public void errorSupplierThrows() { + Completable c = Completable.error(new Supplier() { + @Override + public Throwable get() { throw new TestException(); } + }); + + c.await(); + } + + @Test(expected = NullPointerException.class) + public void errorNull() { + Completable.error((Throwable)null); + } + + @Test(timeout = 1000, expected = TestException.class) + public void errorNormal() { + Completable c = Completable.error(new TestException()); + + c.await(); + } + + @Test(expected = NullPointerException.class) + public void fromCallableNull() { + Completable.fromCallable(null); + } + + @Test(timeout = 1000) + public void fromCallableNormal() { + final AtomicInteger calls = new AtomicInteger(); + + Completable c = Completable.fromCallable(new Callable() { + @Override + public Object call() throws Exception { + return calls.getAndIncrement(); + } + }); + + c.await(); + + Assert.assertEquals(1, calls.get()); + } + + @Test(timeout = 1000, expected = TestException.class) + public void fromCallableThrows() { + Completable c = Completable.fromCallable(new Callable() { + @Override + public Object call() throws Exception { throw new TestException(); } + }); + + c.await(); + } + + @Test(expected = NullPointerException.class) + public void fromFlowableNull() { + Completable.fromFlowable(null); + } + + @Test(timeout = 1000) + public void fromFlowableEmpty() { + Completable c = Completable.fromFlowable(Observable.empty()); + + c.await(); + } + + @Test(timeout = 5000) + public void fromFlowableSome() { + for (int n = 1; n < 10000; n *= 10) { + Completable c = Completable.fromFlowable(Observable.range(1, n)); + + c.await(); + } + } + + @Test(timeout = 1000, expected = TestException.class) + public void fromFlowableError() { + Completable c = Completable.fromFlowable(Observable.error(new Supplier() { + @Override + public Throwable get() { + return new TestException(); + } + })); + + c.await(); + } + + @Test(expected = NullPointerException.class) + public void fromNbpObservableNull() { + Completable.fromNbpObservable(null); + } + + @Test(timeout = 1000) + public void fromNbpObservableEmpty() { + Completable c = Completable.fromNbpObservable(NbpObservable.empty()); + + c.await(); + } + + @Test(timeout = 5000) + public void fromNbpObservableSome() { + for (int n = 1; n < 10000; n *= 10) { + Completable c = Completable.fromNbpObservable(NbpObservable.range(1, n)); + + c.await(); + } + } + + @Test(timeout = 1000, expected = TestException.class) + public void fromNbpObservableError() { + Completable c = Completable.fromNbpObservable(NbpObservable.error(new Supplier() { + @Override + public Throwable get() { + return new TestException(); + } + })); + + c.await(); + } + + @Test(expected = NullPointerException.class) + public void fromRunnableNull() { + Completable.fromRunnable(null); + } + + @Test(timeout = 1000) + public void fromRunnableNormal() { + final AtomicInteger calls = new AtomicInteger(); + + Completable c = Completable.fromRunnable(new Runnable() { + @Override + public void run() { + calls.getAndIncrement(); + } + }); + + c.await(); + + Assert.assertEquals(1, calls.get()); + } + + @Test(timeout = 1000, expected = TestException.class) + public void fromRunnableThrows() { + Completable c = Completable.fromRunnable(new Runnable() { + @Override + public void run() { throw new TestException(); } + }); + + c.await(); + } + + @Test(expected = NullPointerException.class) + public void fromSingleNull() { + Completable.fromSingle(null); + } + + @Test(timeout = 1000) + public void fromSingleNormal() { + Completable c = Completable.fromSingle(Single.just(1)); + + c.await(); + } + + @Test(timeout = 1000, expected = TestException.class) + public void fromSingleThrows() { + Completable c = Completable.fromSingle(Single.error(new Supplier() { + @Override + public Throwable get() { + return new TestException(); + } + })); + + c.await(); + } + + @Test(expected = NullPointerException.class) + public void mergeNull() { + Completable.merge((Completable[])null); + } + + @Test(timeout = 1000) + public void mergeEmpty() { + Completable c = Completable.merge(); + + c.await(); + } + + @Test(timeout = 1000) + public void mergeSingleSource() { + Completable c = Completable.merge(normal.completable); + + c.await(); + + normal.assertSubscriptions(1); + } + + @Test(timeout = 1000, expected = TestException.class) + public void mergeSingleSourceThrows() { + Completable c = Completable.merge(error.completable); + + c.await(); + } + + @Test(timeout = 1000) + public void mergeMultipleSources() { + Completable c = Completable.merge(normal.completable, normal.completable, normal.completable); + + c.await(); + + normal.assertSubscriptions(3); + } + + @Test(timeout = 1000, expected = TestException.class) + public void mergeMultipleOneThrows() { + Completable c = Completable.merge(normal.completable, error.completable, normal.completable); + + c.await(); + } + + @Test(timeout = 1000, expected = NullPointerException.class) + public void mergeMultipleOneIsNull() { + Completable c = Completable.merge(normal.completable, null); + + c.await(); + } + + @Test(timeout = 1000) + public void mergeIterableEmpty() { + Completable c = Completable.merge(Collections.emptyList()); + + c.await(); + } + + @Test(expected = NullPointerException.class) + public void mergeIterableNull() { + Completable.merge((Iterable)null); + } + + @Test(timeout = 1000, expected = NullPointerException.class) + public void mergeIterableIteratorNull() { + Completable c = Completable.merge(new Iterable() { + @Override + public Iterator iterator() { + return null; + } + }); + + c.await(); + } + + @Test(timeout = 1000, expected = NullPointerException.class) + public void mergeIterableWithNull() { + Completable c = Completable.merge(Arrays.asList(normal.completable, (Completable)null)); + + c.await(); + } + + @Test(timeout = 1000) + public void mergeIterableSingle() { + Completable c = Completable.merge(Collections.singleton(normal.completable)); + + c.await(); + + normal.assertSubscriptions(1); + } + + @Test(timeout = 1000) + public void mergeIterableMany() { + Completable c = Completable.merge(Arrays.asList(normal.completable, normal.completable, normal.completable)); + + c.await(); + + normal.assertSubscriptions(3); + } + + @Test(timeout = 1000, expected = TestException.class) + public void mergeIterableOneThrows() { + Completable c = Completable.merge(Collections.singleton(error.completable)); + + c.await(); + } + + @Test(timeout = 1000, expected = TestException.class) + public void mergeIterableManyOneThrows() { + Completable c = Completable.merge(Arrays.asList(normal.completable, error.completable)); + + c.await(); + } + + @Test(expected = TestException.class) + public void mergeIterableIterableThrows() { + Completable c = Completable.merge(new Iterable() { + @Override + public Iterator iterator() { + throw new TestException(); + } + }); + + c.await(); + } + + @Test(expected = TestException.class) + public void mergeIterableIteratorHasNextThrows() { + Completable c = Completable.merge(new IterableIteratorHasNextThrows()); + + c.await(); + } + + @Test(expected = TestException.class) + public void mergeIterableIteratorNextThrows() { + Completable c = Completable.merge(new IterableIteratorNextThrows()); + + c.await(); + } + + @Test(timeout = 1000) + public void mergeObservableEmpty() { + Completable c = Completable.merge(Observable.empty()); + + c.await(); + } + + @Test(timeout = 1000, expected = TestException.class) + public void mergeObservableError() { + Completable c = Completable.merge(Observable.error(new Supplier() { + @Override + public Throwable get() { + return new TestException(); + } + })); + + c.await(); + } + + @Test(timeout = 1000) + public void mergeObservableSingle() { + Completable c = Completable.merge(Observable.just(normal.completable)); + + c.await(); + + normal.assertSubscriptions(1); + } + + @Test(timeout = 1000, expected = TestException.class) + public void mergeObservableSingleThrows() { + Completable c = Completable.merge(Observable.just(error.completable)); + + c.await(); + } + + @Test(timeout = 1000) + public void mergeObservableMany() { + Completable c = Completable.merge(Observable.just(normal.completable).repeat(3)); + + c.await(); + + normal.assertSubscriptions(3); + } + + @Test(timeout = 1000, expected = TestException.class) + public void mergeObservableManyOneThrows() { + Completable c = Completable.merge(Observable.just(normal.completable, error.completable)); + + c.await(); + } + + @Test(timeout = 1000) + public void mergeObservableMaxConcurrent() { + final List requested = new ArrayList(); + Observable cs = Observable + .just(normal.completable) + .repeat(10) + .doOnRequest(new LongConsumer() { + @Override + public void accept(long v) { + requested.add(v); + } + }); + + Completable c = Completable.merge(cs, 5); + + c.await(); + + // FIXME this request pattern looks odd because all 10 completions trigger 1 requests + Assert.assertEquals(Arrays.asList(5L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), requested); + } + + @Test(expected = NullPointerException.class) + public void mergeDelayErrorNull() { + Completable.mergeDelayError((Completable[])null); + } + + @Test(timeout = 1000) + public void mergeDelayErrorEmpty() { + Completable c = Completable.mergeDelayError(); + + c.await(); + } + + @Test(timeout = 1000) + public void mergeDelayErrorSingleSource() { + Completable c = Completable.mergeDelayError(normal.completable); + + c.await(); + + normal.assertSubscriptions(1); + } + + @Test(timeout = 1000, expected = TestException.class) + public void mergeDelayErrorSingleSourceThrows() { + Completable c = Completable.mergeDelayError(error.completable); + + c.await(); + } + + @Test(timeout = 1000) + public void mergeDelayErrorMultipleSources() { + Completable c = Completable.mergeDelayError(normal.completable, normal.completable, normal.completable); + + c.await(); + + normal.assertSubscriptions(3); + } + + @Test(timeout = 1000) + public void mergeDelayErrorMultipleOneThrows() { + Completable c = Completable.mergeDelayError(normal.completable, error.completable, normal.completable); + + try { + c.await(); + } catch (TestException ex) { + normal.assertSubscriptions(2); + } + } + + @Test(timeout = 1000, expected = NullPointerException.class) + public void mergeDelayErrorMultipleOneIsNull() { + Completable c = Completable.mergeDelayError(normal.completable, null); + + c.await(); + } + + @Test(timeout = 1000) + public void mergeDelayErrorIterableEmpty() { + Completable c = Completable.mergeDelayError(Collections.emptyList()); + + c.await(); + } + + @Test(expected = NullPointerException.class) + public void mergeDelayErrorIterableNull() { + Completable.mergeDelayError((Iterable)null); + } + + @Test(timeout = 1000, expected = NullPointerException.class) + public void mergeDelayErrorIterableIteratorNull() { + Completable c = Completable.mergeDelayError(new Iterable() { + @Override + public Iterator iterator() { + return null; + } + }); + + c.await(); + } + + @Test(timeout = 1000, expected = NullPointerException.class) + public void mergeDelayErrorIterableWithNull() { + Completable c = Completable.mergeDelayError(Arrays.asList(normal.completable, (Completable)null)); + + c.await(); + } + + @Test(timeout = 1000) + public void mergeDelayErrorIterableSingle() { + Completable c = Completable.mergeDelayError(Collections.singleton(normal.completable)); + + c.await(); + + normal.assertSubscriptions(1); + } + + @Test(timeout = 1000) + public void mergeDelayErrorIterableMany() { + Completable c = Completable.mergeDelayError(Arrays.asList(normal.completable, normal.completable, normal.completable)); + + c.await(); + + normal.assertSubscriptions(3); + } + + @Test(timeout = 1000, expected = TestException.class) + public void mergeDelayErrorIterableOneThrows() { + Completable c = Completable.mergeDelayError(Collections.singleton(error.completable)); + + c.await(); + } + + @Test(timeout = 1000) + public void mergeDelayErrorIterableManyOneThrows() { + Completable c = Completable.mergeDelayError(Arrays.asList(normal.completable, error.completable, normal.completable)); + + try { + c.await(); + } catch (TestException ex) { + normal.assertSubscriptions(2); + } + } + + @Test(expected = TestException.class) + public void mergeDelayErrorIterableIterableThrows() { + Completable c = Completable.mergeDelayError(new Iterable() { + @Override + public Iterator iterator() { + throw new TestException(); + } + }); + + c.await(); + } + + @Test(expected = TestException.class) + public void mergeDelayErrorIterableIteratorHasNextThrows() { + Completable c = Completable.mergeDelayError(new IterableIteratorHasNextThrows()); + + c.await(); + } + + @Test(expected = TestException.class) + public void mergeDelayErrorIterableIteratorNextThrows() { + Completable c = Completable.mergeDelayError(new IterableIteratorNextThrows()); + + c.await(); + } + + @Test(timeout = 1000) + public void mergeDelayErrorObservableEmpty() { + Completable c = Completable.mergeDelayError(Observable.empty()); + + c.await(); + } + + @Test(timeout = 1000, expected = TestException.class) + public void mergeDelayErrorObservableError() { + Completable c = Completable.mergeDelayError(Observable.error(new Supplier() { + @Override + public Throwable get() { + return new TestException(); + } + })); + + c.await(); + } + + @Test(timeout = 1000) + public void mergeDelayErrorObservableSingle() { + Completable c = Completable.mergeDelayError(Observable.just(normal.completable)); + + c.await(); + + normal.assertSubscriptions(1); + } + + @Test(timeout = 1000, expected = TestException.class) + public void mergeDelayErrorObservableSingleThrows() { + Completable c = Completable.mergeDelayError(Observable.just(error.completable)); + + c.await(); + } + + @Test(timeout = 1000) + public void mergeDelayErrorObservableMany() { + Completable c = Completable.mergeDelayError(Observable.just(normal.completable).repeat(3)); + + c.await(); + + normal.assertSubscriptions(3); + } + + @Test(timeout = 1000, expected = TestException.class) + public void mergeDelayErrorObservableManyOneThrows() { + Completable c = Completable.mergeDelayError(Observable.just(normal.completable, error.completable)); + + c.await(); + } + + @Test(timeout = 1000) + public void mergeDelayErrorObservableMaxConcurrent() { + final List requested = new ArrayList(); + Observable cs = Observable + .just(normal.completable) + .repeat(10) + .doOnRequest(new LongConsumer() { + @Override + public void accept(long v) { + requested.add(v); + } + }); + + Completable c = Completable.mergeDelayError(cs, 5); + + c.await(); + + // FIXME this request pattern looks odd because all 10 completions trigger 1 requests + Assert.assertEquals(Arrays.asList(5L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), requested); + } + + @Test(timeout = 1000) + public void never() { + final AtomicBoolean onSubscribeCalled = new AtomicBoolean(); + final AtomicInteger calls = new AtomicInteger(); + Completable.never().subscribe(new CompletableSubscriber() { + @Override + public void onSubscribe(Disposable d) { + onSubscribeCalled.set(true); + } + + @Override + public void onError(Throwable e) { + calls.getAndIncrement(); + } + + @Override + public void onComplete() { + calls.getAndIncrement(); + } + }); + + Assert.assertTrue("onSubscribe not called", onSubscribeCalled.get()); + Assert.assertEquals("There were calls to onXXX methods", 0, calls.get()); + } + + @Test(timeout = 1500) + public void timer() { + Completable c = Completable.timer(500, TimeUnit.MILLISECONDS); + + c.await(); + } + + @Test(timeout = 1500) + public void timerNewThread() { + Completable c = Completable.timer(500, TimeUnit.MILLISECONDS, Schedulers.newThread()); + + c.await(); + } + + @Test(timeout = 1000) + public void timerTestScheduler() { + TestScheduler scheduler = Schedulers.test(); + + Completable c = Completable.timer(250, TimeUnit.MILLISECONDS, scheduler); + + final AtomicInteger calls = new AtomicInteger(); + + c.subscribe(new CompletableSubscriber() { + @Override + public void onSubscribe(Disposable d) { + + } + + @Override + public void onComplete() { + calls.getAndIncrement(); + } + + @Override + public void onError(Throwable e) { + RxJavaPlugins.onError(e); + } + }); + + scheduler.advanceTimeBy(100, TimeUnit.MILLISECONDS); + + Assert.assertEquals(0, calls.get()); + + scheduler.advanceTimeBy(200, TimeUnit.MILLISECONDS); + + Assert.assertEquals(1, calls.get()); + } + + @Test(timeout = 2000) + public void timerCancel() throws InterruptedException { + Completable c = Completable.timer(250, TimeUnit.MILLISECONDS); + + final MultipleAssignmentDisposable mad = new MultipleAssignmentDisposable(); + final AtomicInteger calls = new AtomicInteger(); + + c.subscribe(new CompletableSubscriber() { + @Override + public void onSubscribe(Disposable d) { + mad.set(d); + } + + @Override + public void onError(Throwable e) { + calls.getAndIncrement(); + } + + @Override + public void onComplete() { + calls.getAndIncrement(); + } + }); + + Thread.sleep(100); + + mad.dispose(); + + Thread.sleep(200); + + Assert.assertEquals(0, calls.get()); + } + + @Test(expected = NullPointerException.class) + public void timerUnitNull() { + Completable.timer(1, null); + } + + @Test(expected = NullPointerException.class) + public void timerSchedulerNull() { + Completable.timer(1, TimeUnit.SECONDS, null); + } + + @Test(timeout = 1000) + public void usingNormalEager() { + final AtomicInteger dispose = new AtomicInteger(); + + Completable c = Completable.using(new Supplier() { + @Override + public Integer get() { + return 1; + } + }, new Function() { + @Override + public Completable apply(Object v) { + return normal.completable; + } + }, new Consumer() { + @Override + public void accept(Integer d) { + dispose.set(d); + } + }); + + final AtomicBoolean disposedFirst = new AtomicBoolean(); + final AtomicReference error = new AtomicReference(); + + c.subscribe(new CompletableSubscriber() { + @Override + public void onSubscribe(Disposable d) { + + } + + @Override + public void onError(Throwable e) { + error.lazySet(e); + } + + @Override + public void onComplete() { + disposedFirst.set(dispose.get() != 0); + } + }); + + Assert.assertEquals(1, dispose.get()); + Assert.assertTrue("Not disposed first", disposedFirst.get()); + Assert.assertNull(error.get()); + } + + @Test(timeout = 1000) + public void usingNormalLazy() { + final AtomicInteger dispose = new AtomicInteger(); + + Completable c = Completable.using(new Supplier() { + @Override + public Integer get() { + return 1; + } + }, new Function() { + @Override + public Completable apply(Integer v) { + return normal.completable; + } + }, new Consumer() { + @Override + public void accept(Integer d) { + dispose.set(d); + } + }, false); + + final AtomicBoolean disposedFirst = new AtomicBoolean(); + final AtomicReference error = new AtomicReference(); + + c.subscribe(new CompletableSubscriber() { + @Override + public void onSubscribe(Disposable d) { + + } + + @Override + public void onError(Throwable e) { + error.lazySet(e); + } + + @Override + public void onComplete() { + disposedFirst.set(dispose.get() != 0); + } + }); + + Assert.assertEquals(1, dispose.get()); + Assert.assertFalse("Disposed first", disposedFirst.get()); + Assert.assertNull(error.get()); + } + + @Test(timeout = 1000) + public void usingErrorEager() { + final AtomicInteger dispose = new AtomicInteger(); + + Completable c = Completable.using(new Supplier() { + @Override + public Integer get() { + return 1; + } + }, new Function() { + @Override + public Completable apply(Integer v) { + return error.completable; + } + }, new Consumer() { + @Override + public void accept(Integer d) { + dispose.set(d); + } + }); + + final AtomicBoolean disposedFirst = new AtomicBoolean(); + final AtomicBoolean complete = new AtomicBoolean(); + + c.subscribe(new CompletableSubscriber() { + @Override + public void onSubscribe(Disposable d) { + + } + + @Override + public void onError(Throwable e) { + disposedFirst.set(dispose.get() != 0); + } + + @Override + public void onComplete() { + complete.set(true); + } + }); + + Assert.assertEquals(1, dispose.get()); + Assert.assertTrue("Not disposed first", disposedFirst.get()); + Assert.assertFalse(complete.get()); + } + + @Test(timeout = 1000) + public void usingErrorLazy() { + final AtomicInteger dispose = new AtomicInteger(); + + Completable c = Completable.using(new Supplier() { + @Override + public Integer get() { + return 1; + } + }, new Function() { + @Override + public Completable apply(Integer v) { + return error.completable; + } + }, new Consumer() { + @Override + public void accept(Integer d) { + dispose.set(d); + } + }, false); + + final AtomicBoolean disposedFirst = new AtomicBoolean(); + final AtomicBoolean complete = new AtomicBoolean(); + + c.subscribe(new CompletableSubscriber() { + @Override + public void onSubscribe(Disposable d) { + + } + + @Override + public void onError(Throwable e) { + disposedFirst.set(dispose.get() != 0); + } + + @Override + public void onComplete() { + complete.set(true); + } + }); + + Assert.assertEquals(1, dispose.get()); + Assert.assertFalse("Disposed first", disposedFirst.get()); + Assert.assertFalse(complete.get()); + } + + @Test(expected = NullPointerException.class) + public void usingResourceSupplierNull() { + Completable.using(null, new Function() { + @Override + public Completable apply(Object v) { + return normal.completable; + } + }, new Consumer() { + @Override + public void accept(Object v) { } + }); + } + + @Test(expected = NullPointerException.class) + public void usingMapperNull() { + Completable.using(new Supplier() { + @Override + public Object get() { + return 1; + } + }, null, new Consumer() { + @Override + public void accept(Object v) { } + }); + } + + @Test(expected = NullPointerException.class) + public void usingMapperReturnsNull() { + Completable c = Completable.using(new Supplier() { + @Override + public Object get() { + return 1; + } + }, new Function() { + @Override + public Completable apply(Object v) { + return null; + } + }, new Consumer() { + @Override + public void accept(Object v) { } + }); + + c.await(); + } + + @Test(expected = NullPointerException.class) + public void usingDisposeNull() { + Completable.using(new Supplier() { + @Override + public Object get() { + return 1; + } + }, new Function() { + @Override + public Completable apply(Object v) { + return normal.completable; + } + }, null); + } + + @Test(expected = TestException.class) + public void usingResourceThrows() { + Completable c = Completable.using(new Supplier() { + @Override + public Object get() { throw new TestException(); } + }, + new Function() { + @Override + public Completable apply(Object v) { + return normal.completable; + } + }, new Consumer() { + @Override + public void accept(Object v) { } + }); + + c.await(); + } + + @Test(expected = TestException.class) + public void usingMapperThrows() { + Completable c = Completable.using(new Supplier() { + @Override + public Object get() { + return 1; + } + }, + new Function() { + @Override + public Completable apply(Object v) { throw new TestException(); } + }, new Consumer() { + @Override + public void accept(Object v) { } + }); + + c.await(); + } + + @Test(expected = TestException.class) + public void usingDisposerThrows() { + Completable c = Completable.using(new Supplier() { + @Override + public Object get() { + return 1; + } + }, + new Function() { + @Override + public Completable apply(Object v) { + return normal.completable; + } + }, new Consumer() { + @Override + public void accept(Object v) { throw new TestException(); } + }); + + c.await(); + } + + @Test(timeout = 1000) + public void composeNormal() { + Completable c = error.completable.compose(new CompletableTransformer() { + @Override + public Completable apply(Completable n) { + return n.onErrorComplete(); + } + }); + + c.await(); + } + + @Test(expected = NullPointerException.class) + public void composeNull() { + error.completable.compose(null); + } + + @Test(timeout = 1000) + public void concatWithNormal() { + Completable c = normal.completable.concatWith(normal.completable); + + c.await(); + + normal.assertSubscriptions(2); + } + + @Test(timeout = 1000, expected = TestException.class) + public void concatWithError() { + Completable c = normal.completable.concatWith(error.completable); + + c.await(); + } + + @Test(expected = NullPointerException.class) + public void concatWithNull() { + normal.completable.concatWith(null); + } + + @Test(expected = NullPointerException.class) + public void delayUnitNull() { + normal.completable.delay(1, null); + } + + @Test(expected = NullPointerException.class) + public void delaySchedulerNull() { + normal.completable.delay(1, TimeUnit.SECONDS, null); + } + + @Test(timeout = 1000) + public void delayNormal() throws InterruptedException { + Completable c = normal.completable.delay(250, TimeUnit.MILLISECONDS); + + final AtomicBoolean done = new AtomicBoolean(); + final AtomicReference error = new AtomicReference(); + + c.subscribe(new CompletableSubscriber() { + @Override + public void onSubscribe(Disposable d) { + + } + + @Override + public void onError(Throwable e) { + error.set(e); + } + + @Override + public void onComplete() { + done.set(true); + } + }); + + Thread.sleep(100); + + Assert.assertFalse("Already done", done.get()); + + Thread.sleep(200); + + Assert.assertTrue("Not done", done.get()); + + Assert.assertNull(error.get()); + } + + @Test(timeout = 1000) + public void delayErrorImmediately() throws InterruptedException { + Completable c = error.completable.delay(250, TimeUnit.MILLISECONDS); + + final AtomicBoolean done = new AtomicBoolean(); + final AtomicReference error = new AtomicReference(); + + c.subscribe(new CompletableSubscriber() { + @Override + public void onSubscribe(Disposable d) { + + } + + @Override + public void onError(Throwable e) { + error.set(e); + } + + @Override + public void onComplete() { + done.set(true); + } + }); + + Assert.assertTrue(error.get().toString(), error.get() instanceof TestException); + Assert.assertFalse("Already done", done.get()); + + Thread.sleep(100); + + Assert.assertFalse("Already done", done.get()); + + Thread.sleep(200); + } + + @Test(timeout = 1000) + public void delayErrorToo() throws InterruptedException { + Completable c = error.completable.delay(250, TimeUnit.MILLISECONDS, Schedulers.computation(), true); + + final AtomicBoolean done = new AtomicBoolean(); + final AtomicReference error = new AtomicReference(); + + c.subscribe(new CompletableSubscriber() { + @Override + public void onSubscribe(Disposable d) { + + } + + @Override + public void onError(Throwable e) { + error.set(e); + } + + @Override + public void onComplete() { + done.set(true); + } + }); + + Thread.sleep(100); + + Assert.assertFalse("Already done", done.get()); + Assert.assertNull(error.get()); + + Thread.sleep(200); + + Assert.assertFalse("Already done", done.get()); + Assert.assertTrue(error.get() instanceof TestException); + } + + @Test(timeout = 1000) + public void doOnCompleteNormal() { + final AtomicInteger calls = new AtomicInteger(); + + Completable c = normal.completable.doOnComplete(new Runnable() { + @Override + public void run() { + calls.getAndIncrement(); + } + }); + + c.await(); + + Assert.assertEquals(1, calls.get()); + } + + @Test(timeout = 1000) + public void doOnCompleteError() { + final AtomicInteger calls = new AtomicInteger(); + + Completable c = error.completable.doOnComplete(new Runnable() { + @Override + public void run() { + calls.getAndIncrement(); + } + }); + + try { + c.await(); + Assert.fail("Failed to throw TestException"); + } catch (TestException ex) { + // expected + } + + Assert.assertEquals(0, calls.get()); + } + + @Test(expected = NullPointerException.class) + public void doOnCompleteNull() { + normal.completable.doOnComplete(null); + } + + @Test(timeout = 1000, expected = TestException.class) + public void doOnCompleteThrows() { + Completable c = normal.completable.doOnComplete(new Runnable() { + @Override + public void run() { throw new TestException(); } + }); + + c.await(); + } + + @Test(timeout = 1000) + public void doOnDisposeNormalDoesntCall() { + final AtomicInteger calls = new AtomicInteger(); + + Completable c = normal.completable.doOnDispose(new Runnable() { + @Override + public void run() { + calls.getAndIncrement(); + } + }); + + c.await(); + + Assert.assertEquals(0, calls.get()); + } + + @Test(timeout = 1000) + public void doOnDisposeErrorDoesntCall() { + final AtomicInteger calls = new AtomicInteger(); + + Completable c = error.completable.doOnDispose(new Runnable() { + @Override + public void run() { + calls.getAndIncrement(); + } + }); + + try { + c.await(); + Assert.fail("No exception thrown"); + } catch (TestException ex) { + // expected + } + Assert.assertEquals(0, calls.get()); + } + + @Test(timeout = 1000) + public void doOnDisposeChildCancels() { + final AtomicInteger calls = new AtomicInteger(); + + Completable c = normal.completable.doOnDispose(new Runnable() { + @Override + public void run() { + calls.getAndIncrement(); + } + }); + + c.subscribe(new CompletableSubscriber() { + @Override + public void onSubscribe(Disposable d) { + d.dispose(); + } + + @Override + public void onError(Throwable e) { + // ignored + } + + @Override + public void onComplete() { + // ignored + } + }); + + Assert.assertEquals(1, calls.get()); + } + + @Test(expected = NullPointerException.class) + public void doOnDisposeNull() { + normal.completable.doOnDispose(null); + } + + @Test(timeout = 1000) + public void doOnDisposeThrows() { + Completable c = normal.completable.doOnDispose(new Runnable() { + @Override + public void run() { throw new TestException(); } + }); + + c.subscribe(new CompletableSubscriber() { + @Override + public void onSubscribe(Disposable d) { + d.dispose(); + } + + @Override + public void onError(Throwable e) { + // ignored + } + + @Override + public void onComplete() { + // ignored + } + }); + } + + @Test(timeout = 1000) + public void doOnErrorNoError() { + final AtomicReference error = new AtomicReference(); + + Completable c = normal.completable.doOnError(new Consumer() { + @Override + public void accept(Throwable e) { + error.set(e); + } + }); + + c.await(); + + Assert.assertNull(error.get()); + } + + @Test(timeout = 1000) + public void doOnErrorHasError() { + final AtomicReference err = new AtomicReference(); + + Completable c = error.completable.doOnError(new Consumer() { + @Override + public void accept(Throwable e) { + err.set(e); + } + }); + + try { + c.await(); + Assert.fail("Did not throw exception"); + } catch (Throwable e) { + // expected + } + + Assert.assertTrue(err.get() instanceof TestException); + } + + @Test(expected = NullPointerException.class) + public void doOnErrorNull() { + normal.completable.doOnError(null); + } + + @Test(timeout = 1000) + public void doOnErrorThrows() { + Completable c = error.completable.doOnError(new Consumer() { + @Override + public void accept(Throwable e) { throw new IllegalStateException(); } + }); + + try { + c.await(); + } catch (CompositeException ex) { + List a = ex.getExceptions(); + Assert.assertEquals(2, a.size()); + Assert.assertTrue(a.get(0) instanceof IllegalStateException); + Assert.assertTrue(a.get(1) instanceof TestException); + } + } + + @Test(timeout = 1000) + public void doOnSubscribeNormal() { + final AtomicInteger calls = new AtomicInteger(); + + Completable c = normal.completable.doOnSubscribe(new Consumer() { + @Override + public void accept(Disposable s) { + calls.getAndIncrement(); + } + }); + + for (int i = 0; i < 10; i++) { + c.await(); + } + + Assert.assertEquals(10, calls.get()); + } + + @Test(expected = NullPointerException.class) + public void doOnSubscribeNull() { + normal.completable.doOnSubscribe(null); + } + + @Test(expected = TestException.class) + public void doOnSubscribeThrows() { + Completable c = normal.completable.doOnSubscribe(new Consumer() { + @Override + public void accept(Disposable d) { throw new TestException(); } + }); + + c.await(); + } + + @Test(timeout = 1000) + public void doOnTerminateNormal() { + final AtomicInteger calls = new AtomicInteger(); + + Completable c = normal.completable.doOnTerminate(new Runnable() { + @Override + public void run() { + calls.getAndIncrement(); + } + }); + + c.await(); + + Assert.assertEquals(1, calls.get()); + } + + @Test(timeout = 1000) + public void doOnTerminateError() { + final AtomicInteger calls = new AtomicInteger(); + + Completable c = error.completable.doOnTerminate(new Runnable() { + @Override + public void run() { + calls.getAndIncrement(); + } + }); + + try { + c.await(); + Assert.fail("Did dot throw exception"); + } catch (TestException ex) { + // expected + } + + Assert.assertEquals(1, calls.get()); + } + + @Test(timeout = 1000) + public void finallyDoNormal() { + final AtomicBoolean doneAfter = new AtomicBoolean(); + final AtomicBoolean complete = new AtomicBoolean(); + + Completable c = normal.completable.finallyDo(new Runnable() { + @Override + public void run() { + doneAfter.set(complete.get()); + } + }); + + c.subscribe(new CompletableSubscriber() { + @Override + public void onSubscribe(Disposable d) { + + } + + @Override + public void onError(Throwable e) { + + } + + @Override + public void onComplete() { + complete.set(true); + } + }); + + c.await(); + + Assert.assertTrue("Not completed", complete.get()); + Assert.assertTrue("Finally called before onComplete", doneAfter.get()); + } + + @Test(timeout = 1000) + public void finallyDoWithError() { + final AtomicBoolean doneAfter = new AtomicBoolean(); + + Completable c = error.completable.finallyDo(new Runnable() { + @Override + public void run() { + doneAfter.set(true); + } + }); + + try { + c.await(); + Assert.fail("Did not throw TestException"); + } catch (TestException ex) { + // expected + } + + Assert.assertFalse("FinallyDo called", doneAfter.get()); + } + + @Test(expected = NullPointerException.class) + public void finallyDoNull() { + normal.completable.finallyDo(null); + } + + @Test(timeout = 1000) + public void getNormal() { + Assert.assertNull(normal.completable.get()); + } + + @Test(timeout = 1000) + public void getError() { + Assert.assertTrue(error.completable.get() instanceof TestException); + } + + @Test(timeout = 1000) + public void getTimeout() { + try { + Completable.never().get(100, TimeUnit.MILLISECONDS); + } catch (RuntimeException ex) { + if (!(ex.getCause() instanceof TimeoutException)) { + Assert.fail("Wrong exception cause: " + ex.getCause()); + } + } + } + + @Test(expected = NullPointerException.class) + public void getNullUnit() { + normal.completable.get(1, null); + } + + @Test(expected = NullPointerException.class) + public void liftNull() { + normal.completable.lift(null); + } + + @Test(timeout = 1000, expected = NullPointerException.class) + public void liftReturnsNull() { + Completable c = normal.completable.lift(new CompletableOperator() { + @Override + public CompletableSubscriber apply(CompletableSubscriber v) { + return null; + } + }); + + c.await(); + } + + final static class CompletableOperatorSwap implements CompletableOperator { + @Override + public CompletableSubscriber apply(final CompletableSubscriber v) { + return new CompletableSubscriber() { + + @Override + public void onComplete() { + v.onError(new TestException()); + } + + @Override + public void onError(Throwable e) { + v.onComplete(); + } + + @Override + public void onSubscribe(Disposable d) { + v.onSubscribe(d); + } + + }; + } + } + @Test(timeout = 1000, expected = TestException.class) + public void liftOnCompleteError() { + Completable c = normal.completable.lift(new CompletableOperatorSwap()); + + c.await(); + } + + @Test(timeout = 1000) + public void liftOnErrorComplete() { + Completable c = error.completable.lift(new CompletableOperatorSwap()); + + c.await(); + } + + @Test(expected = NullPointerException.class) + public void mergeWithNull() { + normal.completable.mergeWith(null); + } + + @Test(timeout = 1000) + public void mergeWithNormal() { + Completable c = normal.completable.mergeWith(normal.completable); + + c.await(); + + normal.assertSubscriptions(2); + } + + @Test(expected = NullPointerException.class) + public void observeOnNull() { + normal.completable.observeOn(null); + } + + @Test(timeout = 1000) + public void observeOnNormal() throws InterruptedException { + final AtomicReference name = new AtomicReference(); + final AtomicReference err = new AtomicReference(); + final CountDownLatch cdl = new CountDownLatch(1); + + Completable c = normal.completable.observeOn(Schedulers.computation()); + + c.subscribe(new CompletableSubscriber() { + @Override + public void onSubscribe(Disposable d) { + + } + + @Override + public void onComplete() { + name.set(Thread.currentThread().getName()); + cdl.countDown(); + } + + @Override + public void onError(Throwable e) { + err.set(e); + cdl.countDown(); + } + }); + + cdl.await(); + + Assert.assertNull(err.get()); + Assert.assertTrue(name.get().startsWith("RxComputation")); + } + + @Test(timeout = 1000) + public void observeOnError() throws InterruptedException { + final AtomicReference name = new AtomicReference(); + final AtomicReference err = new AtomicReference(); + final CountDownLatch cdl = new CountDownLatch(1); + + Completable c = error.completable.observeOn(Schedulers.computation()); + + c.subscribe(new CompletableSubscriber() { + @Override + public void onSubscribe(Disposable d) { + + } + + @Override + public void onComplete() { + name.set(Thread.currentThread().getName()); + cdl.countDown(); + } + + @Override + public void onError(Throwable e) { + name.set(Thread.currentThread().getName()); + err.set(e); + cdl.countDown(); + } + }); + + cdl.await(); + + Assert.assertTrue(err.get() instanceof TestException); + Assert.assertTrue(name.get().startsWith("RxComputation")); + } + + @Test(timeout = 1000) + public void onErrorComplete() { + Completable c = error.completable.onErrorComplete(); + + c.await(); + } + + @Test(timeout = 1000, expected = TestException.class) + public void onErrorCompleteFalse() { + Completable c = error.completable.onErrorComplete(new Predicate() { + @Override + public boolean test(Throwable e) { + return e instanceof IllegalStateException; + } + }); + + c.await(); + } + + @Test(expected = NullPointerException.class) + public void onErrorCompleteNull() { + error.completable.onErrorComplete(null); + } + + @Test(expected = NullPointerException.class) + public void onErrorResumeNextNull() { + error.completable.onErrorResumeNext(null); + } + + @Test(timeout = 1000) + public void onErrorResumeNextFunctionReturnsNull() { + Completable c = error.completable.onErrorResumeNext(new Function() { + @Override + public Completable apply(Throwable e) { + return null; + } + }); + + try { + c.await(); + Assert.fail("Did not throw an exception"); + } catch (NullPointerException ex) { + Assert.assertTrue(ex.getCause() instanceof TestException); + } + } + + @Test(timeout = 1000) + public void onErrorResumeNextFunctionThrows() { + Completable c = error.completable.onErrorResumeNext(new Function() { + @Override + public Completable apply(Throwable e) { throw new TestException(); } + }); + + try { + c.await(); + Assert.fail("Did not throw an exception"); + } catch (CompositeException ex) { + List a = ex.getExceptions(); + + Assert.assertEquals(2, a.size()); + Assert.assertTrue(a.get(0) instanceof TestException); + Assert.assertTrue(a.get(1) instanceof TestException); + } + } + + @Test(timeout = 1000) + public void onErrorResumeNextNormal() { + Completable c = error.completable.onErrorResumeNext(new Function() { + @Override + public Completable apply(Throwable v) { + return normal.completable; + } + }); + + c.await(); + } + + @Test(timeout = 1000, expected = TestException.class) + public void onErrorResumeNextError() { + Completable c = error.completable.onErrorResumeNext(new Function() { + @Override + public Completable apply(Throwable v) { + return error.completable; + } + }); + + c.await(); + } + + @Test(timeout = 2000) + public void repeatNormal() { + final AtomicReference err = new AtomicReference(); + final AtomicInteger calls = new AtomicInteger(); + + Completable c = Completable.fromCallable(new Callable() { + @Override + public Object call() throws Exception { + calls.getAndIncrement(); + Thread.sleep(100); + return null; + } + }).repeat(); + + c.subscribe(new CompletableSubscriber() { + @Override + public void onSubscribe(final Disposable d) { + Schedulers.single().scheduleDirect(new Runnable() { + @Override + public void run() { + d.dispose(); + } + }, 550, TimeUnit.MILLISECONDS); + } + + @Override + public void onError(Throwable e) { + err.set(e); + } + + @Override + public void onComplete() { + + } + }); + + Assert.assertEquals(6, calls.get()); + Assert.assertNull(err.get()); + } + + @Test(timeout = 1000, expected = TestException.class) + public void repeatError() { + Completable c = error.completable.repeat(); + + c.await(); + } + + @Test(timeout = 1000) + public void repeat5Times() { + final AtomicInteger calls = new AtomicInteger(); + + Completable c = Completable.fromCallable(new Callable() { + @Override + public Object call() throws Exception { + calls.getAndIncrement(); + return null; + } + }).repeat(5); + + c.await(); + + Assert.assertEquals(5, calls.get()); + } + + @Test(timeout = 1000) + public void repeat1Time() { + final AtomicInteger calls = new AtomicInteger(); + + Completable c = Completable.fromCallable(new Callable() { + @Override + public Object call() throws Exception { + calls.getAndIncrement(); + return null; + } + }).repeat(1); + + c.await(); + + Assert.assertEquals(1, calls.get()); + } + + @Test(timeout = 1000) + public void repeat0Time() { + final AtomicInteger calls = new AtomicInteger(); + + Completable c = Completable.fromCallable(new Callable() { + @Override + public Object call() throws Exception { + calls.getAndIncrement(); + return null; + } + }).repeat(0); + + c.await(); + + Assert.assertEquals(0, calls.get()); + } + + @Test(timeout = 1000) + public void repeatUntilNormal() { + final AtomicInteger calls = new AtomicInteger(); + final AtomicInteger times = new AtomicInteger(5); + + Completable c = Completable.fromCallable(new Callable() { + @Override + public Object call() throws Exception { + calls.getAndIncrement(); + return null; + } + }).repeatUntil(new BooleanSupplier() { + @Override + public boolean getAsBoolean() { + return times.decrementAndGet() == 0; + } + }); + + c.await(); + + Assert.assertEquals(5, calls.get()); + } + + @Test(expected = NullPointerException.class) + public void repeatUntilNull() { + normal.completable.repeatUntil(null); + } + + @Test(expected = NullPointerException.class) + public void repeatWhenNull() { + normal.completable.repeatWhen(null); + } + + @Test(timeout = 1000) + public void retryNormal() { + Completable c = normal.completable.retry(); + + c.await(); + + normal.assertSubscriptions(1); + } + + @Test(timeout = 1000) + public void retry5Times() { + final AtomicInteger calls = new AtomicInteger(5); + Completable c = Completable.fromRunnable(new Runnable() { + @Override + public void run() { + if (calls.decrementAndGet() != 0) { + throw new TestException(); + } + } + }).retry(); + + c.await(); + } + + @Test(timeout = 1000, expected = TestException.class) + public void retryBiPredicate5Times() { + Completable c = error.completable.retry(new BiPredicate() { + @Override + public boolean test(Integer n, Throwable e) { + return n < 5; + } + }); + + c.await(); + } + + @Test(timeout = 1000, expected = TestException.class) + public void retryTimes5Error() { + Completable c = error.completable.retry(5); + + c.await(); + } + + @Test(timeout = 1000) + public void retryTimes5Normal() { + final AtomicInteger calls = new AtomicInteger(5); + + Completable c = Completable.fromRunnable(new Runnable() { + @Override + public void run() { + if (calls.decrementAndGet() != 0) { + throw new TestException(); + } + } + }).retry(5); + + c.await(); + } + + @Test(expected = IllegalArgumentException.class) + public void retryNegativeTimes() { + normal.completable.retry(-1); + } + + @Test(timeout = 1000, expected = TestException.class) + public void retryPredicateError() { + Completable c = error.completable.retry(new Predicate() { + @Override + public boolean test(Throwable e) { + return false; + } + }); + + c.await(); + } + + @Test(expected = NullPointerException.class) + public void retryPredicateNull() { + error.completable.retry((Predicate)null); + } + + @Test(timeout = 1000) + public void retryPredicate5Times() { + final AtomicInteger calls = new AtomicInteger(5); + + Completable c = Completable.fromRunnable(new Runnable() { + @Override + public void run() { + if (calls.decrementAndGet() != 0) { + throw new TestException(); + } + } + }).retry(new Predicate() { + @Override + public boolean test(Throwable e) { + return true; + } + }); + + c.await(); + } + + @Test(timeout = 1000) + public void retryWhen5Times() { + final AtomicInteger calls = new AtomicInteger(5); + + Completable c = Completable.fromRunnable(new Runnable() { + @Override + public void run() { + if (calls.decrementAndGet() != 0) { + throw new TestException(); + } + } + }).retryWhen(new Function, Publisher>() { + @SuppressWarnings({ "rawtypes", "unchecked" }) + @Override + public Publisher apply(Observable o) { + return (Publisher)o; + } + }); + + c.await(); + } + + @Test(timeout = 1000) + public void subscribe() throws InterruptedException { + final AtomicBoolean complete = new AtomicBoolean(); + + Completable c = normal.completable + .delay(100, TimeUnit.MILLISECONDS) + .doOnComplete(new Runnable() { + @Override + public void run() { + complete.set(true); + } + }); + + c.subscribe(); + + Thread.sleep(150); + + Assert.assertTrue("Not completed", complete.get()); + } + + @Test(timeout = 1000) + public void subscribeDispose() throws InterruptedException { + final AtomicBoolean complete = new AtomicBoolean(); + + Completable c = normal.completable + .delay(200, TimeUnit.MILLISECONDS) + .doOnComplete(new Runnable() { + @Override + public void run() { + complete.set(true); + } + }); + + Disposable d = c.subscribe(); + + Thread.sleep(100); + + d.dispose(); + + Thread.sleep(150); + + Assert.assertFalse("Completed", complete.get()); + } + + @Test(timeout = 1000) + public void subscribeTwoCallbacksNormal() { + final AtomicReference err = new AtomicReference(); + final AtomicBoolean complete = new AtomicBoolean(); + normal.completable.subscribe(new Consumer() { + @Override + public void accept(Throwable e) { + err.set(e); + } + }, new Runnable() { + @Override + public void run() { + complete.set(true); + } + }); + + Assert.assertNull(err.get()); + Assert.assertTrue("Not completed", complete.get()); + } + + @Test(timeout = 1000) + public void subscribeTwoCallbacksError() { + final AtomicReference err = new AtomicReference(); + final AtomicBoolean complete = new AtomicBoolean(); + error.completable.subscribe(new Consumer() { + @Override + public void accept(Throwable e) { + err.set(e); + } + }, new Runnable() { + @Override + public void run() { + complete.set(true); + } + }); + + Assert.assertTrue(err.get() instanceof TestException); + Assert.assertFalse("Not completed", complete.get()); + } + + @Test(expected = NullPointerException.class) + public void subscribeTwoCallbacksFirstNull() { + normal.completable.subscribe(null, new Runnable() { + @Override + public void run() { } + }); + } + + @Test(expected = NullPointerException.class) + public void subscribeTwoCallbacksSecondNull() { + normal.completable.subscribe(null, new Runnable() { + @Override + public void run() { } + }); + } + + @Test(timeout = 1000) + public void subscribeTwoCallbacksCompleteThrows() { + final AtomicReference err = new AtomicReference(); + normal.completable.subscribe(new Consumer() { + @Override + public void accept(Throwable e) { + err.set(e); + } + }, new Runnable() { + @Override + public void run() { throw new TestException(); } + }); + + Assert.assertTrue(String.valueOf(err.get()), err.get() instanceof TestException); + } + + @Test(timeout = 1000) + public void subscribeTwoCallbacksOnErrorThrows() { + error.completable.subscribe(new Consumer() { + @Override + public void accept(Throwable e) { throw new TestException(); } + }, new Runnable() { + @Override + public void run() { } + }); + } + + @Test(timeout = 1000) + public void subscribeNbpSubscriberNormal() { + NbpTestSubscriber ts = new NbpTestSubscriber(); + + normal.completable.subscribe(ts); + + ts.assertComplete(); + ts.assertNoValues(); + ts.assertNoErrors(); + } + + @Test(timeout = 1000) + public void subscribeNbpSubscriberError() { + NbpTestSubscriber ts = new NbpTestSubscriber(); + + error.completable.subscribe(ts); + + ts.assertNotComplete(); + ts.assertNoValues(); + ts.assertError(TestException.class); + } + + @Test(timeout = 1000) + public void subscribeRunnableNormal() { + final AtomicBoolean run = new AtomicBoolean(); + + normal.completable.subscribe(new Runnable() { + @Override + public void run() { + run.set(true); + } + }); + + Assert.assertTrue("Not completed", run.get()); + } + + @Test(timeout = 1000) + public void subscribeRunnableError() { + final AtomicBoolean run = new AtomicBoolean(); + + error.completable.subscribe(new Runnable() { + @Override + public void run() { + run.set(true); + } + }); + + Assert.assertFalse("Completed", run.get()); + } + + @Test(expected = NullPointerException.class) + public void subscribeRunnableNull() { + normal.completable.subscribe((Runnable)null); + } + + @Test(expected = NullPointerException.class) + public void subscribeSubscriberNull() { + normal.completable.subscribe((Subscriber)null); + } + + @Test(expected = NullPointerException.class) + public void subscribeNbpSubscriberNull() { + normal.completable.subscribe((NbpSubscriber)null); + } + + @Test(expected = NullPointerException.class) + public void subscribeCompletableSubscriberNull() { + normal.completable.subscribe((CompletableSubscriber)null); + } + + @Test(timeout = 1000) + public void subscribeSubscriberNormal() { + TestSubscriber ts = new TestSubscriber(); + + normal.completable.subscribe(ts); + + ts.assertComplete(); + ts.assertNoValues(); + ts.assertNoErrors(); + } + + @Test(timeout = 1000) + public void subscribeSubscriberError() { + TestSubscriber ts = new TestSubscriber(); + + error.completable.subscribe(ts); + + ts.assertNotComplete(); + ts.assertNoValues(); + ts.assertError(TestException.class); + } + + @Test(expected = NullPointerException.class) + public void subscribeOnNull() { + normal.completable.subscribeOn(null); + } + + @Test(timeout = 1000) + public void subscribeOnNormal() { + final AtomicReference name = new AtomicReference(); + + Completable c = Completable.create(new CompletableOnSubscribe() { + @Override + public void accept(CompletableSubscriber s) { + name.set(Thread.currentThread().getName()); + s.onSubscribe(EmptyDisposable.INSTANCE); + s.onComplete(); + } + }).subscribeOn(Schedulers.computation()); + + c.await(); + + Assert.assertTrue(name.get().startsWith("RxComputation")); + } + + @Test(timeout = 1000) + public void subscribeOnError() { + final AtomicReference name = new AtomicReference(); + + Completable c = Completable.create(new CompletableOnSubscribe() { + @Override + public void accept(CompletableSubscriber s) { + name.set(Thread.currentThread().getName()); + s.onSubscribe(EmptyDisposable.INSTANCE); + s.onError(new TestException()); + } + }).subscribeOn(Schedulers.computation()); + + try { + c.await(); + Assert.fail("No exception thrown"); + } catch (TestException ex) { + // expected + } + + Assert.assertTrue(name.get().startsWith("RxComputation")); + } + + @Test(timeout = 1000) + public void timeoutEmitError() { + Throwable e = Completable.never().timeout(100, TimeUnit.MILLISECONDS).get(); + + Assert.assertTrue(e instanceof TimeoutException); + } + + @Test(timeout = 1000) + public void timeoutSwitchNormal() { + Completable c = Completable.never().timeout(100, TimeUnit.MILLISECONDS, normal.completable); + + c.await(); + + normal.assertSubscriptions(1); + } + + @Test(timeout = 1000) + public void timeoutTimerCancelled() throws InterruptedException { + Completable c = Completable.fromCallable(new Callable() { + @Override + public Object call() throws Exception { + Thread.sleep(50); + return null; + } + }).timeout(100, TimeUnit.MILLISECONDS, normal.completable); + + c.await(); + + Thread.sleep(100); + + normal.assertSubscriptions(0); + } + + @Test(expected = NullPointerException.class) + public void timeoutUnitNull() { + normal.completable.timeout(1, null); + } + + @Test(expected = NullPointerException.class) + public void timeoutSchedulerNull() { + normal.completable.timeout(1, TimeUnit.SECONDS, (Scheduler)null); + } + + @Test(expected = NullPointerException.class) + public void timeoutOtherNull() { + normal.completable.timeout(1, TimeUnit.SECONDS, (Completable)null); + } + + @Test(timeout = 1000) + public void toNormal() { + Observable flow = normal.completable.to(new Function>() { + @Override + public Observable apply(Completable c) { + return c.toFlowable(); + } + }); + + flow.toBlocking().forEach(new Consumer() { + @Override + public void accept(Object e) { } + }); + } + + @Test(expected = NullPointerException.class) + public void toNull() { + normal.completable.to(null); + } + + @Test(timeout = 1000) + public void toFlowableNormal() { + normal.completable.toFlowable().toBlocking().forEach(Functions.emptyConsumer()); + } + + @Test(timeout = 1000, expected = TestException.class) + public void toFlowableError() { + error.completable.toFlowable().toBlocking().forEach(Functions.emptyConsumer()); + } + + @Test(timeout = 1000) + public void toNbpObservableNormal() { + normal.completable.toNbpObservable().toBlocking().forEach(Functions.emptyConsumer()); + } + + @Test(timeout = 1000, expected = TestException.class) + public void toNbpObservableError() { + error.completable.toNbpObservable().toBlocking().forEach(Functions.emptyConsumer()); + } + + @Test(timeout = 1000) + public void toSingleSupplierNormal() { + Assert.assertEquals(1, normal.completable.toSingle(new Supplier() { + @Override + public Object get() { + return 1; + } + }).get()); + } + + @Test(timeout = 1000, expected = TestException.class) + public void toSingleSupplierError() { + error.completable.toSingle(new Supplier() { + @Override + public Object get() { + return 1; + } + }).get(); + } + + @Test(expected = NullPointerException.class) + public void toSingleSupplierNull() { + normal.completable.toSingle(null); + } + + @Test(expected = NullPointerException.class) + public void toSingleSupplierReturnsNull() { + normal.completable.toSingle(new Supplier() { + @Override + public Object get() { + return null; + } + }).get(); + } + + @Test(expected = TestException.class) + public void toSingleSupplierThrows() { + normal.completable.toSingle(new Supplier() { + @Override + public Object get() { throw new TestException(); } + }).get(); + } + + @Test(timeout = 1000, expected = TestException.class) + public void toSingleDefaultError() { + error.completable.toSingleDefault(1).get(); + } + + @Test(timeout = 1000) + public void toSingleDefaultNormal() { + Assert.assertEquals((Integer)1, normal.completable.toSingleDefault(1).get()); + } + + @Test(expected = NullPointerException.class) + public void toSingleDefaultNull() { + normal.completable.toSingleDefault(null); + } + + @Test(timeout = 1000) + public void unsubscribeOnNormal() throws InterruptedException { + final AtomicReference name = new AtomicReference(); + final CountDownLatch cdl = new CountDownLatch(1); + + normal.completable.delay(1, TimeUnit.SECONDS) + .doOnDispose(new Runnable() { + @Override + public void run() { + name.set(Thread.currentThread().getName()); + cdl.countDown(); + } + }) + .unsubscribeOn(Schedulers.computation()) + .subscribe(new CompletableSubscriber() { + @Override + public void onSubscribe(final Disposable d) { + Schedulers.single().scheduleDirect(new Runnable() { + @Override + public void run() { + d.dispose(); + } + }, 100, TimeUnit.MILLISECONDS); + } + + @Override + public void onError(Throwable e) { + + } + + @Override + public void onComplete() { + + } + }); + + cdl.await(); + + Assert.assertTrue(name.get().startsWith("RxComputation")); + } + + @Test(expected = NullPointerException.class) + public void ambArrayNull() { + Completable.amb((Completable[])null); + } + + @Test(timeout = 1000) + public void ambArrayEmpty() { + Completable c = Completable.amb(); + + c.await(); + } + + @Test(timeout = 1000) + public void ambArraySingleNormal() { + Completable c = Completable.amb(normal.completable); + + c.await(); + } + + @Test(timeout = 1000, expected = TestException.class) + public void ambArraySingleError() { + Completable c = Completable.amb(error.completable); + + c.await(); + } + + @Test(timeout = 1000) + public void ambArrayOneFires() { + PublishSubject ps1 = PublishSubject.create(); + PublishSubject ps2 = PublishSubject.create(); + + Completable c1 = Completable.fromFlowable(ps1); + + Completable c2 = Completable.fromFlowable(ps2); + + Completable c = Completable.amb(c1, c2); + + final AtomicBoolean complete = new AtomicBoolean(); + + c.subscribe(new Runnable() { + @Override + public void run() { + complete.set(true); + } + }); + + Assert.assertTrue("First subject no subscribers", ps1.hasSubscribers()); + Assert.assertTrue("Second subject no subscribers", ps2.hasSubscribers()); + + ps1.onComplete(); + + Assert.assertFalse("First subject has subscribers", ps1.hasSubscribers()); + Assert.assertFalse("Second subject has subscribers", ps2.hasSubscribers()); + + Assert.assertTrue("Not completed", complete.get()); + } + + @Test(timeout = 1000) + public void ambArrayOneFiresError() { + PublishSubject ps1 = PublishSubject.create(); + PublishSubject ps2 = PublishSubject.create(); + + Completable c1 = Completable.fromFlowable(ps1); + + Completable c2 = Completable.fromFlowable(ps2); + + Completable c = Completable.amb(c1, c2); + + final AtomicReference complete = new AtomicReference(); + + c.subscribe(new Consumer() { + @Override + public void accept(Throwable v) { + complete.set(v); + } + }, Functions.emptyRunnable()); + + Assert.assertTrue("First subject no subscribers", ps1.hasSubscribers()); + Assert.assertTrue("Second subject no subscribers", ps2.hasSubscribers()); + + ps1.onError(new TestException()); + + Assert.assertFalse("First subject has subscribers", ps1.hasSubscribers()); + Assert.assertFalse("Second subject has subscribers", ps2.hasSubscribers()); + + Assert.assertTrue("Not completed", complete.get() instanceof TestException); + } + + @Test(timeout = 1000) + public void ambArraySecondFires() { + PublishSubject ps1 = PublishSubject.create(); + PublishSubject ps2 = PublishSubject.create(); + + Completable c1 = Completable.fromFlowable(ps1); + + Completable c2 = Completable.fromFlowable(ps2); + + Completable c = Completable.amb(c1, c2); + + final AtomicBoolean complete = new AtomicBoolean(); + + c.subscribe(new Runnable() { + @Override + public void run() { + complete.set(true); + } + }); + + Assert.assertTrue("First subject no subscribers", ps1.hasSubscribers()); + Assert.assertTrue("Second subject no subscribers", ps2.hasSubscribers()); + + ps2.onComplete(); + + Assert.assertFalse("First subject has subscribers", ps1.hasSubscribers()); + Assert.assertFalse("Second subject has subscribers", ps2.hasSubscribers()); + + Assert.assertTrue("Not completed", complete.get()); + } + + @Test(timeout = 1000) + public void ambArraySecondFiresError() { + PublishSubject ps1 = PublishSubject.create(); + PublishSubject ps2 = PublishSubject.create(); + + Completable c1 = Completable.fromFlowable(ps1); + + Completable c2 = Completable.fromFlowable(ps2); + + Completable c = Completable.amb(c1, c2); + + final AtomicReference complete = new AtomicReference(); + + c.subscribe(new Consumer() { + @Override + public void accept(Throwable v) { + complete.set(v); + } + }, Functions.emptyRunnable()); + + Assert.assertTrue("First subject no subscribers", ps1.hasSubscribers()); + Assert.assertTrue("Second subject no subscribers", ps2.hasSubscribers()); + + ps2.onError(new TestException()); + + Assert.assertFalse("First subject has subscribers", ps1.hasSubscribers()); + Assert.assertFalse("Second subject has subscribers", ps2.hasSubscribers()); + + Assert.assertTrue("Not completed", complete.get() instanceof TestException); + } + + @Test(timeout = 1000, expected = NullPointerException.class) + public void ambMultipleOneIsNull() { + Completable c = Completable.amb(null, normal.completable); + + c.await(); + } + + @Test(timeout = 1000) + public void ambIterableEmpty() { + Completable c = Completable.amb(Collections.emptyList()); + + c.await(); + } + + @Test(expected = NullPointerException.class) + public void ambIterableNull() { + Completable.amb((Iterable)null); + } + + @Test(timeout = 1000, expected = NullPointerException.class) + public void ambIterableIteratorNull() { + Completable c = Completable.amb(new Iterable() { + @Override + public Iterator iterator() { + return null; + } + }); + + c.await(); + } + + @Test(timeout = 1000, expected = NullPointerException.class) + public void ambIterableWithNull() { + Completable c = Completable.amb(Arrays.asList(null, normal.completable)); + + c.await(); + } + + @Test(timeout = 1000) + public void ambIterableSingle() { + Completable c = Completable.amb(Collections.singleton(normal.completable)); + + c.await(); + + normal.assertSubscriptions(1); + } + + @Test(timeout = 1000) + public void ambIterableMany() { + Completable c = Completable.amb(Arrays.asList(normal.completable, normal.completable, normal.completable)); + + c.await(); + + normal.assertSubscriptions(1); + } + + @Test(timeout = 1000, expected = TestException.class) + public void ambIterableOneThrows() { + Completable c = Completable.amb(Collections.singleton(error.completable)); + + c.await(); + } + + @Test(timeout = 1000, expected = TestException.class) + public void ambIterableManyOneThrows() { + Completable c = Completable.amb(Arrays.asList(error.completable, normal.completable)); + + c.await(); + } + + @Test(expected = TestException.class) + public void ambIterableIterableThrows() { + Completable c = Completable.amb(new Iterable() { + @Override + public Iterator iterator() { + throw new TestException(); + } + }); + + c.await(); + } + + @Test(expected = TestException.class) + public void ambIterableIteratorHasNextThrows() { + Completable c = Completable.amb(new IterableIteratorHasNextThrows()); + + c.await(); + } + + @Test(expected = TestException.class) + public void ambIterableIteratorNextThrows() { + Completable c = Completable.amb(new IterableIteratorNextThrows()); + + c.await(); + } + + @Test(expected = NullPointerException.class) + public void ambWithNull() { + normal.completable.ambWith(null); + } + + @Test(timeout = 1000) + public void ambWithArrayOneFires() { + PublishSubject ps1 = PublishSubject.create(); + PublishSubject ps2 = PublishSubject.create(); + + Completable c1 = Completable.fromFlowable(ps1); + + Completable c2 = Completable.fromFlowable(ps2); + + Completable c = c1.ambWith(c2); + + final AtomicBoolean complete = new AtomicBoolean(); + + c.subscribe(new Runnable() { + @Override + public void run() { + complete.set(true); + } + }); + + Assert.assertTrue("First subject no subscribers", ps1.hasSubscribers()); + Assert.assertTrue("Second subject no subscribers", ps2.hasSubscribers()); + + ps1.onComplete(); + + Assert.assertFalse("First subject has subscribers", ps1.hasSubscribers()); + Assert.assertFalse("Second subject has subscribers", ps2.hasSubscribers()); + + Assert.assertTrue("Not completed", complete.get()); + } + + @Test(timeout = 1000) + public void ambWithArrayOneFiresError() { + PublishSubject ps1 = PublishSubject.create(); + PublishSubject ps2 = PublishSubject.create(); + + Completable c1 = Completable.fromFlowable(ps1); + + Completable c2 = Completable.fromFlowable(ps2); + + Completable c = c1.ambWith(c2); + + final AtomicReference complete = new AtomicReference(); + + c.subscribe(new Consumer() { + @Override + public void accept(Throwable v) { + complete.set(v); + } + }, Functions.emptyRunnable()); + + Assert.assertTrue("First subject no subscribers", ps1.hasSubscribers()); + Assert.assertTrue("Second subject no subscribers", ps2.hasSubscribers()); + + ps1.onError(new TestException()); + + Assert.assertFalse("First subject has subscribers", ps1.hasSubscribers()); + Assert.assertFalse("Second subject has subscribers", ps2.hasSubscribers()); + + Assert.assertTrue("Not completed", complete.get() instanceof TestException); + } + + @Test(timeout = 1000) + public void ambWithArraySecondFires() { + PublishSubject ps1 = PublishSubject.create(); + PublishSubject ps2 = PublishSubject.create(); + + Completable c1 = Completable.fromFlowable(ps1); + + Completable c2 = Completable.fromFlowable(ps2); + + Completable c = c1.ambWith(c2); + + final AtomicBoolean complete = new AtomicBoolean(); + + c.subscribe(new Runnable() { + @Override + public void run() { + complete.set(true); + } + }); + + Assert.assertTrue("First subject no subscribers", ps1.hasSubscribers()); + Assert.assertTrue("Second subject no subscribers", ps2.hasSubscribers()); + + ps2.onComplete(); + + Assert.assertFalse("First subject has subscribers", ps1.hasSubscribers()); + Assert.assertFalse("Second subject has subscribers", ps2.hasSubscribers()); + + Assert.assertTrue("Not completed", complete.get()); + } + + @Test(timeout = 1000) + public void ambWithArraySecondFiresError() { + PublishSubject ps1 = PublishSubject.create(); + PublishSubject ps2 = PublishSubject.create(); + + Completable c1 = Completable.fromFlowable(ps1); + + Completable c2 = Completable.fromFlowable(ps2); + + Completable c = c1.ambWith(c2); + + final AtomicReference complete = new AtomicReference(); + + c.subscribe(new Consumer() { + @Override + public void accept(Throwable v) { + complete.set(v); + } + }, Functions.emptyRunnable()); + + Assert.assertTrue("First subject no subscribers", ps1.hasSubscribers()); + Assert.assertTrue("Second subject no subscribers", ps2.hasSubscribers()); + + ps2.onError(new TestException()); + + Assert.assertFalse("First subject has subscribers", ps1.hasSubscribers()); + Assert.assertFalse("Second subject has subscribers", ps2.hasSubscribers()); + + Assert.assertTrue("Not completed", complete.get() instanceof TestException); + } + + @Test(timeout = 1000) + public void startWithCompletableNormal() { + final AtomicBoolean run = new AtomicBoolean(); + Completable c = normal.completable + .startWith(Completable.fromCallable(new Callable() { + @Override + public Object call() throws Exception { + run.set(normal.get() == 0); + return null; + } + })); + + c.await(); + + Assert.assertTrue("Did not start with other", run.get()); + normal.assertSubscriptions(1); + } + + @Test(timeout = 1000) + public void startWithCompletableError() { + Completable c = normal.completable.startWith(error.completable); + + try { + c.await(); + Assert.fail("Did not throw TestException"); + } catch (TestException ex) { + normal.assertSubscriptions(0); + error.assertSubscriptions(1); + } + } + + @Test(timeout = 1000) + public void startWithFlowableNormal() { + final AtomicBoolean run = new AtomicBoolean(); + Observable c = normal.completable + .startWith(Observable.fromCallable(new Callable() { + @Override + public Object call() throws Exception { + run.set(normal.get() == 0); + return 1; + } + })); + + TestSubscriber ts = new TestSubscriber(); + + c.subscribe(ts); + + Assert.assertTrue("Did not start with other", run.get()); + normal.assertSubscriptions(1); + + ts.assertValue(1); + ts.assertComplete(); + ts.assertNoErrors(); + } + + @Test(timeout = 1000) + public void startWithFlowableError() { + Observable c = normal.completable + .startWith(Observable.error(new TestException())); + + TestSubscriber ts = new TestSubscriber(); + + c.subscribe(ts); + + normal.assertSubscriptions(0); + + ts.assertNoValues(); + ts.assertError(TestException.class); + ts.assertNotComplete(); + } + + @Test(timeout = 1000) + public void startWithNbpObservableNormal() { + final AtomicBoolean run = new AtomicBoolean(); + NbpObservable c = normal.completable + .startWith(NbpObservable.fromCallable(new Callable() { + @Override + public Object call() throws Exception { + run.set(normal.get() == 0); + return 1; + } + })); + + NbpTestSubscriber ts = new NbpTestSubscriber(); + + c.subscribe(ts); + + Assert.assertTrue("Did not start with other", run.get()); + normal.assertSubscriptions(1); + + ts.assertValue(1); + ts.assertComplete(); + ts.assertNoErrors(); + } + + @Test(timeout = 1000) + public void startWithNbpObservableError() { + NbpObservable c = normal.completable + .startWith(NbpObservable.error(new TestException())); + + NbpTestSubscriber ts = new NbpTestSubscriber(); + + c.subscribe(ts); + + normal.assertSubscriptions(0); + + ts.assertNoValues(); + ts.assertError(TestException.class); + ts.assertNotComplete(); + } + + @Test(expected = NullPointerException.class) + public void startWithCompletableNull() { + normal.completable.startWith((Completable)null); + } + + @Test(expected = NullPointerException.class) + public void startWithFlowableNull() { + normal.completable.startWith((Observable)null); + } + + @Test(expected = NullPointerException.class) + public void startWithNbpObservableNull() { + normal.completable.startWith((NbpObservable)null); + } + + @Test(expected = NullPointerException.class) + public void endWithCompletableNull() { + normal.completable.endWith((Completable)null); + } + + @Test(expected = NullPointerException.class) + public void endWithFlowableNull() { + normal.completable.endWith((Observable)null); + } + + @Test(expected = NullPointerException.class) + public void endWithNbpObservableNull() { + normal.completable.endWith((NbpObservable)null); + } + + @Test(timeout = 1000) + public void endWithCompletableNormal() { + final AtomicBoolean run = new AtomicBoolean(); + Completable c = normal.completable + .endWith(Completable.fromCallable(new Callable() { + @Override + public Object call() throws Exception { + run.set(normal.get() == 0); + return null; + } + })); + + c.await(); + + Assert.assertFalse("Start with other", run.get()); + normal.assertSubscriptions(1); + } + + @Test(timeout = 1000) + public void endWithCompletableError() { + Completable c = normal.completable.endWith(error.completable); + + try { + c.await(); + Assert.fail("Did not throw TestException"); + } catch (TestException ex) { + normal.assertSubscriptions(1); + error.assertSubscriptions(1); + } + } + + @Test(timeout = 1000) + public void endWithFlowableNormal() { + final AtomicBoolean run = new AtomicBoolean(); + Observable c = normal.completable + .endWith(Observable.fromCallable(new Callable() { + @Override + public Object call() throws Exception { + run.set(normal.get() == 0); + return 1; + } + })); + + TestSubscriber ts = new TestSubscriber(); + + c.subscribe(ts); + + Assert.assertFalse("Start with other", run.get()); + normal.assertSubscriptions(1); + + ts.assertValue(1); + ts.assertComplete(); + ts.assertNoErrors(); + } + + @Test(timeout = 1000) + public void endWithFlowableError() { + Observable c = normal.completable + .endWith(Observable.error(new TestException())); + + TestSubscriber ts = new TestSubscriber(); + + c.subscribe(ts); + + normal.assertSubscriptions(1); + + ts.assertNoValues(); + ts.assertError(TestException.class); + ts.assertNotComplete(); + } + + @Test(timeout = 1000) + public void endWithNbpObservableNormal() { + final AtomicBoolean run = new AtomicBoolean(); + NbpObservable c = normal.completable + .endWith(NbpObservable.fromCallable(new Callable() { + @Override + public Object call() throws Exception { + run.set(normal.get() == 0); + return 1; + } + })); + + NbpTestSubscriber ts = new NbpTestSubscriber(); + + c.subscribe(ts); + + Assert.assertFalse("Start with other", run.get()); + normal.assertSubscriptions(1); + + ts.assertValue(1); + ts.assertComplete(); + ts.assertNoErrors(); + } + + @Test(timeout = 1000) + public void endWithNbpObservableError() { + NbpObservable c = normal.completable + .endWith(NbpObservable.error(new TestException())); + + NbpTestSubscriber ts = new NbpTestSubscriber(); + + c.subscribe(ts); + + normal.assertSubscriptions(1); + + ts.assertNoValues(); + ts.assertError(TestException.class); + ts.assertNotComplete(); + } +} \ No newline at end of file diff --git a/src/test/java/io/reactivex/ConcatTests.java b/src/test/java/io/reactivex/ConcatTests.java index 5b95e3e876..529e3cb7a9 100644 --- a/src/test/java/io/reactivex/ConcatTests.java +++ b/src/test/java/io/reactivex/ConcatTests.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -17,7 +17,9 @@ import java.util.*; import org.junit.Test; +import org.reactivestreams.*; +import io.reactivex.Observable; import io.reactivex.CovarianceTest.*; public class ConcatTests { @@ -59,6 +61,7 @@ public void testConcatWithIterableOfObservable() { Observable o2 = Observable.just("three", "four"); Observable o3 = Observable.just("five", "six"); + @SuppressWarnings("unchecked") Iterable> is = Arrays.asList(o1, o2, o3); List values = Observable.concat(Observable.fromIterable(is)).toList().toBlocking().single(); @@ -141,11 +144,14 @@ public void testConcatCovariance4() { Media media = new Media(); HorrorMovie horrorMovie2 = new HorrorMovie(); - Observable o1 = Observable.create(o -> { - o.onNext(horrorMovie1); - o.onNext(movie); - // o.onNext(new Media()); // correctly doesn't compile - o.onComplete(); + Observable o1 = Observable.create(new Publisher() { + @Override + public void subscribe(Subscriber o) { + o.onNext(horrorMovie1); + o.onNext(movie); + // o.onNext(new Media()); // correctly doesn't compile + o.onComplete(); + } }); Observable o2 = Observable.just(media, horrorMovie2); diff --git a/src/test/java/io/reactivex/CovarianceTest.java b/src/test/java/io/reactivex/CovarianceTest.java index 64bc7c1fef..3f5ddc4df4 100644 --- a/src/test/java/io/reactivex/CovarianceTest.java +++ b/src/test/java/io/reactivex/CovarianceTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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. @@ -19,11 +19,14 @@ import static org.junit.Assert.assertEquals; import java.util.*; -import java.util.function.Function; import org.junit.Test; +import org.reactivestreams.Publisher; +import io.reactivex.Observable; import io.reactivex.Observable.Transformer; +import io.reactivex.functions.*; +import io.reactivex.observables.GroupedObservable; import io.reactivex.subscribers.TestSubscriber; /** @@ -45,7 +48,12 @@ public void testCovarianceOfFrom() { @Test public void testSortedList() { - Comparator SORT_FUNCTION = (t1, t2) -> 1; + Comparator SORT_FUNCTION = new Comparator() { + @Override + public int compare(Media t1, Media t2) { + return 1; + } + }; // this one would work without the covariance generics Observable o = Observable.just(new Movie(), new TVSeason(), new Album()); @@ -59,16 +67,46 @@ public void testSortedList() { @Test public void testGroupByCompose() { Observable movies = Observable.just(new HorrorMovie(), new ActionMovie(), new Movie()); - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); + movies - .groupBy(Object::getClass) - .doOnNext(g -> System.out.println(g.key())) - .flatMap(g -> - g - .doOnNext(System.out::println) - .compose(m -> m.concatWith(Observable.just(new ActionMovie())) - ) - .map(Object::toString)) + .groupBy(new Function() { + @Override + public Object apply(Movie v) { + return v.getClass(); + } + }) + .doOnNext(new Consumer>() { + @Override + public void accept(GroupedObservable g) { + System.out.println(g.key()); + } + }) + .flatMap(new Function, Publisher>() { + @Override + public Publisher apply(GroupedObservable g) { + return g + .doOnNext(new Consumer() { + @Override + public void accept(Movie v) { + System.out.println(v); + } + }) + .compose(new Transformer() { + @Override + public Publisher apply(Observable m) { + return m.concatWith(Observable.just(new ActionMovie())); + } + } + ) + .map(new Function() { + @Override + public String apply(Object v) { + return v.toString(); + } + }); + } + }) .subscribe(ts); ts.assertTerminated(); ts.assertNoErrors(); @@ -80,22 +118,41 @@ public void testGroupByCompose() { @Test public void testCovarianceOfCompose() { Observable movie = Observable.just(new HorrorMovie()); - Observable movie2 = movie.compose(t -> Observable.just(new Movie())); + Observable movie2 = movie.compose(new Transformer() { + @Override + public Publisher apply(Observable t) { + return Observable.just(new Movie()); + } + }); } @SuppressWarnings("unused") @Test public void testCovarianceOfCompose2() { Observable movie = Observable. just(new HorrorMovie()); - Observable movie2 = movie.compose(t -> Observable.just(new HorrorMovie())); + Observable movie2 = movie.compose(new Transformer() { + @Override + public Publisher apply(Observable t) { + return Observable.just(new HorrorMovie()); + } + }); } @SuppressWarnings("unused") @Test public void testCovarianceOfCompose3() { Observable movie = Observable.just(new HorrorMovie()); - Observable movie2 = movie.compose(t -> - Observable.just(new HorrorMovie()).map(v -> v) + Observable movie2 = movie.compose(new Transformer() { + @Override + public Publisher apply(Observable t) { + return Observable.just(new HorrorMovie()).map(new Function() { + @Override + public HorrorMovie apply(HorrorMovie v) { + return v; + } + }); + } + } ); } @@ -103,7 +160,17 @@ public void testCovarianceOfCompose3() { @Test public void testCovarianceOfCompose4() { Observable movie = Observable.just(new HorrorMovie()); - Observable movie2 = movie.compose(t1 -> t1.map(v -> v)); + Observable movie2 = movie.compose(new Transformer() { + @Override + public Publisher apply(Observable t1) { + return t1.map(new Function() { + @Override + public HorrorMovie apply(HorrorMovie v) { + return v; + } + }); + } + }); } @Test @@ -114,37 +181,43 @@ public void testComposeWithDeltaLogic() { movies.compose(deltaTransformer); } - static Function>, Observable> calculateDelta = listOfLists -> { - if (listOfLists.size() == 1) { - return Observable.fromIterable(listOfLists.get(0)); - } else { - // diff the two - List newList = listOfLists.get(1); - List oldList = new ArrayList<>(listOfLists.get(0)); + static Function>, Observable> calculateDelta = new Function>, Observable>() { + @Override + public Observable apply(List> listOfLists) { + if (listOfLists.size() == 1) { + return Observable.fromIterable(listOfLists.get(0)); + } else { + // diff the two + List newList = listOfLists.get(1); + List oldList = new ArrayList(listOfLists.get(0)); - Set delta = new LinkedHashSet<>(); - delta.addAll(newList); - // remove all that match in old - delta.removeAll(oldList); + Set delta = new LinkedHashSet(); + delta.addAll(newList); + // remove all that match in old + delta.removeAll(oldList); - // filter oldList to those that aren't in the newList - oldList.removeAll(newList); + // filter oldList to those that aren't in the newList + oldList.removeAll(newList); - // for all left in the oldList we'll create DROP events - for (@SuppressWarnings("unused") Movie old : oldList) { - delta.add(new Movie()); - } + // for all left in the oldList we'll create DROP events + for (@SuppressWarnings("unused") Movie old : oldList) { + delta.add(new Movie()); + } - return Observable.fromIterable(delta); + return Observable.fromIterable(delta); + } } }; - static Transformer, Movie> deltaTransformer = movieList -> { - return movieList - .startWith(new ArrayList()) - .buffer(2, 1) - .skip(1) - .flatMap(calculateDelta); + static Transformer, Movie> deltaTransformer = new Transformer, Movie>() { + @Override + public Publisher apply(Observable> movieList) { + return movieList + .startWith(new ArrayList()) + .buffer(2, 1) + .skip(1) + .flatMap(calculateDelta); + } }; /* diff --git a/src/test/java/io/reactivex/ErrorHandlingTests.java b/src/test/java/io/reactivex/ErrorHandlingTests.java index f99a2bc307..b538fe216e 100644 --- a/src/test/java/io/reactivex/ErrorHandlingTests.java +++ b/src/test/java/io/reactivex/ErrorHandlingTests.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -18,7 +18,7 @@ import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicReference; -import org.junit.*; +import org.junit.Test; import org.reactivestreams.Subscriber; import io.reactivex.schedulers.Schedulers; @@ -27,11 +27,12 @@ public class ErrorHandlingTests { /** * Test that an error from a user provided Observer.onNext is handled and emitted to the onError + * @throws InterruptedException if the test is interrupted */ @Test public void testOnNextError() throws InterruptedException { final CountDownLatch latch = new CountDownLatch(1); - final AtomicReference caughtError = new AtomicReference<>(); + final AtomicReference caughtError = new AtomicReference(); Observable o = Observable.interval(50, TimeUnit.MILLISECONDS); Subscriber observer = new Observer() { @@ -62,11 +63,12 @@ public void onNext(Long args) { /** * Test that an error from a user provided Observer.onNext is handled and emitted to the onError * even when done across thread boundaries with observeOn + * @throws InterruptedException if the test is interrupted */ @Test public void testOnNextErrorAcrossThread() throws InterruptedException { final CountDownLatch latch = new CountDownLatch(1); - final AtomicReference caughtError = new AtomicReference<>(); + final AtomicReference caughtError = new AtomicReference(); Observable o = Observable.interval(50, TimeUnit.MILLISECONDS); Subscriber observer = new Observer() { diff --git a/src/test/java/io/reactivex/EventStream.java b/src/test/java/io/reactivex/EventStream.java index 3db10f538d..45a3e3992c 100644 --- a/src/test/java/io/reactivex/EventStream.java +++ b/src/test/java/io/reactivex/EventStream.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -15,6 +15,10 @@ import java.util.*; +import org.reactivestreams.Subscriber; + +import io.reactivex.Observable; +import io.reactivex.functions.Consumer; import io.reactivex.schedulers.Schedulers; /** @@ -26,20 +30,23 @@ private EventStream() { } public static Observable getEventStream(final String type, final int numInstances) { - return Observable.generate(s -> { - s.onNext(randomEvent(type, numInstances)); - try { - // slow it down somewhat - Thread.sleep(50); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - s.onError(e); + return Observable.generate(new Consumer>() { + @Override + public void accept(Subscriber s) { + s.onNext(randomEvent(type, numInstances)); + try { + // slow it down somewhat + Thread.sleep(50); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + s.onError(e); + } } }).subscribeOn(Schedulers.newThread()); } public static Event randomEvent(String type, int numInstances) { - Map values = new LinkedHashMap<>(); + Map values = new LinkedHashMap(); values.put("count200", randomIntFrom0to(4000)); values.put("count4xx", randomIntFrom0to(300)); values.put("count5xx", randomIntFrom0to(500)); diff --git a/src/test/java/io/reactivex/GroupByTests.java b/src/test/java/io/reactivex/GroupByTests.java index da5c3e6b72..73ba84e80b 100644 --- a/src/test/java/io/reactivex/GroupByTests.java +++ b/src/test/java/io/reactivex/GroupByTests.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -14,6 +14,12 @@ package io.reactivex; import org.junit.Test; +import org.reactivestreams.Publisher; + +import io.reactivex.Observable; +import io.reactivex.EventStream.Event; +import io.reactivex.functions.*; +import io.reactivex.observables.GroupedObservable; public class GroupByTests { @@ -24,12 +30,20 @@ public void testTakeUnsubscribesOnGroupBy() { EventStream.getEventStream("HTTP-ClusterB", 20) ) // group by type (2 clusters) - .groupBy(event -> event.type) + .groupBy(new Function() { + @Override + public Object apply(Event event) { + return event.type; + } + }) .take(1) .toBlocking() - .forEach(v -> { - System.out.println(v); - v.take(1).subscribe(); // FIXME groups need consumption to a certain degree to cancel upstream + .forEach(new Consumer>() { + @Override + public void accept(GroupedObservable v) { + System.out.println(v); + v.take(1).subscribe(); // FIXME groups need consumption to a certain degree to cancel upstream + } }); System.out.println("**** finished"); @@ -42,11 +56,31 @@ public void testTakeUnsubscribesOnFlatMapOfGroupBy() { EventStream.getEventStream("HTTP-ClusterB", 20) ) // group by type (2 clusters) - .groupBy(event -> event.type) - .flatMap(g -> g.map(event -> event.instanceId + " - " + event.values.get("count200"))) + .groupBy(new Function() { + @Override + public Object apply(Event event) { + return event.type; + } + }) + .flatMap(new Function, Publisher>() { + @Override + public Publisher apply(GroupedObservable g) { + return g.map(new Function() { + @Override + public Object apply(Event event) { + return event.instanceId + " - " + event.values.get("count200"); + } + }); + } + }) .take(20) .toBlocking() - .forEach(System.out::println); + .forEach(new Consumer() { + @Override + public void accept(Object v) { + System.out.println(v); + } + }); System.out.println("**** finished"); } diff --git a/src/test/java/io/reactivex/MergeTests.java b/src/test/java/io/reactivex/MergeTests.java index f89416238f..4fcc2ec74b 100644 --- a/src/test/java/io/reactivex/MergeTests.java +++ b/src/test/java/io/reactivex/MergeTests.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -18,8 +18,11 @@ import java.util.List; import org.junit.Test; +import org.reactivestreams.Publisher; +import io.reactivex.Observable; import io.reactivex.CovarianceTest.*; +import io.reactivex.functions.Supplier; public class MergeTests { @@ -73,10 +76,15 @@ public void testMergeCovariance3() { @Test public void testMergeCovariance4() { - Observable o1 = Observable.defer(() -> Observable.just( - new HorrorMovie(), - new Movie() - )); + Observable o1 = Observable.defer(new Supplier>() { + @Override + public Publisher get() { + return Observable.just( + new HorrorMovie(), + new Movie() + ); + } + }); Observable o2 = Observable.just(new Media(), new HorrorMovie()); diff --git a/src/test/java/io/reactivex/NbpObservableNullTests.java b/src/test/java/io/reactivex/NbpObservableNullTests.java new file mode 100644 index 0000000000..0de47ca4d4 --- /dev/null +++ b/src/test/java/io/reactivex/NbpObservableNullTests.java @@ -0,0 +1,2786 @@ +/** + * 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.lang.reflect.*; +import java.util.*; +import java.util.concurrent.*; + +import org.junit.*; + +import io.reactivex.NbpObservable.*; +import io.reactivex.disposables.Disposable; +import io.reactivex.exceptions.TestException; +import io.reactivex.functions.*; +import io.reactivex.internal.functions.Functions; +import io.reactivex.schedulers.Schedulers; +import io.reactivex.subscribers.nbp.NbpTestSubscriber; + +/** + * Verifies the operators handle null values properly by emitting/throwing NullPointerExceptions + */ +public class NbpObservableNullTests { + + NbpObservable just1 = NbpObservable.just(1); + + //*********************************************************** + // Static methods + //*********************************************************** + + @Test(expected = NullPointerException.class) + public void ambVarargsNull() { + NbpObservable.amb((NbpObservable[])null); + } + + @SuppressWarnings("unchecked") + @Test(expected = NullPointerException.class) + public void ambVarargsOneIsNull() { + NbpObservable.amb(NbpObservable.never(), null).toBlocking().lastOption(); + } + + @Test(expected = NullPointerException.class) + public void ambIterableNull() { + NbpObservable.amb((Iterable>)null); + } + + @Test(expected = NullPointerException.class) + public void ambIterableIteratorNull() { + NbpObservable.amb(new Iterable>() { + @Override + public Iterator> iterator() { + return null; + } + }).toBlocking().lastOption(); + } + + @SuppressWarnings("unchecked") + @Test(expected = NullPointerException.class) + public void ambIterableOneIsNull() { + NbpObservable.amb(Arrays.asList(NbpObservable.never(), null)).toBlocking().lastOption(); + } + + @Test(expected = NullPointerException.class) + public void combineLatestVarargsNull() { + NbpObservable.combineLatest(new Function() { + @Override + public Object apply(Object[] v) { + return 1; + } + }, true, 128, (NbpObservable[])null); + } + + @SuppressWarnings("unchecked") + @Test(expected = NullPointerException.class) + public void combineLatestVarargsOneIsNull() { + NbpObservable.combineLatest(new Function() { + @Override + public Object apply(Object[] v) { + return 1; + } + }, true, 128, NbpObservable.never(), null).toBlocking().lastOption(); + } + + @Test(expected = NullPointerException.class) + public void combineLatestIterableNull() { + NbpObservable.combineLatest((Iterable>)null, new Function() { + @Override + public Object apply(Object[] v) { + return 1; + } + }, true, 128); + } + + @Test(expected = NullPointerException.class) + public void combineLatestIterableIteratorNull() { + NbpObservable.combineLatest(new Iterable>() { + @Override + public Iterator> iterator() { + return null; + } + }, new Function() { + @Override + public Object apply(Object[] v) { + return 1; + } + }, true, 128).toBlocking().lastOption(); + } + + @SuppressWarnings("unchecked") + @Test(expected = NullPointerException.class) + public void combineLatestIterableOneIsNull() { + NbpObservable.combineLatest(Arrays.asList(NbpObservable.never(), null), new Function() { + @Override + public Object apply(Object[] v) { + return 1; + } + }, true, 128).toBlocking().lastOption(); + } + + @SuppressWarnings("unchecked") + @Test(expected = NullPointerException.class) + public void combineLatestVarargsFunctionNull() { + NbpObservable.combineLatest(null, true, 128, NbpObservable.never()); + } + + @SuppressWarnings("unchecked") + @Test(expected = NullPointerException.class) + public void combineLatestVarargsFunctionReturnsNull() { + NbpObservable.combineLatest(new Function() { + @Override + public Object apply(Object[] v) { + return null; + } + }, true, 128, just1).toBlocking().lastOption(); + } + + @SuppressWarnings("unchecked") + @Test(expected = NullPointerException.class) + public void combineLatestIterableFunctionNull() { + NbpObservable.combineLatest(Arrays.asList(just1), null, true, 128); + } + + @SuppressWarnings("unchecked") + @Test(expected = NullPointerException.class) + public void combineLatestIterableFunctionReturnsNull() { + NbpObservable.combineLatest(Arrays.asList(just1), new Function() { + @Override + public Object apply(Object[] v) { + return null; + } + }, true, 128).toBlocking().lastOption(); + } + + @Test(expected = NullPointerException.class) + public void concatIterableNull() { + NbpObservable.concat((Iterable>)null); + } + + @Test(expected = NullPointerException.class) + public void concatIterableIteratorNull() { + NbpObservable.concat(new Iterable>() { + @Override + public Iterator> iterator() { + return null; + } + }).toBlocking().lastOption(); + } + + @SuppressWarnings("unchecked") + @Test(expected = NullPointerException.class) + public void concatIterableOneIsNull() { + NbpObservable.concat(Arrays.asList(just1, null)).toBlocking().lastOption(); + } + + @Test(expected = NullPointerException.class) + public void concatNbpObservableNull() { + NbpObservable.concat((NbpObservable>)null); + + } + + @Test(expected = NullPointerException.class) + public void concatArrayNull() { + NbpObservable.concatArray((NbpObservable[])null); + } + + @SuppressWarnings("unchecked") + @Test(expected = NullPointerException.class) + public void concatArrayOneIsNull() { + NbpObservable.concatArray(just1, null).toBlocking().lastOption(); + } + + @Test(expected = NullPointerException.class) + public void createNull() { + NbpObservable.create(null); + } + + @Test(expected = NullPointerException.class) + public void deferFunctionNull() { + NbpObservable.defer(null); + } + + @Test(expected = NullPointerException.class) + public void deferFunctionReturnsNull() { + NbpObservable.defer(new Supplier>() { + @Override + public NbpObservable get() { + return null; + } + }).toBlocking().lastOption(); + } + + @Test(expected = NullPointerException.class) + public void errorFunctionNull() { + NbpObservable.error((Supplier)null); + } + + @Test(expected = NullPointerException.class) + public void errorFunctionReturnsNull() { + NbpObservable.error(new Supplier() { + @Override + public Throwable get() { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void errorThrowableNull() { + NbpObservable.error((Throwable)null); + } + + @Test(expected = NullPointerException.class) + public void fromArrayNull() { + NbpObservable.fromArray((Object[])null); + } + + @Test(expected = NullPointerException.class) + public void fromArrayOneIsNull() { + NbpObservable.fromArray(1, null).toBlocking().lastOption(); + } + + @Test(expected = NullPointerException.class) + public void fromCallableNull() { + NbpObservable.fromCallable(null); + } + + @Test(expected = NullPointerException.class) + public void fromCallableReturnsNull() { + NbpObservable.fromCallable(new Callable() { + @Override + public Object call() throws Exception { + return null; + } + }).toBlocking().lastOption(); + } + + @Test(expected = NullPointerException.class) + public void fromFutureNull() { + NbpObservable.fromFuture(null); + } + + @Test + public void fromFutureReturnsNull() { + FutureTask f = new FutureTask(Functions.emptyRunnable(), null); + f.run(); + + NbpTestSubscriber ts = new NbpTestSubscriber(); + NbpObservable.fromFuture(f).subscribe(ts); + ts.assertNoValues(); + ts.assertNotComplete(); + ts.assertError(NullPointerException.class); + } + + @Test(expected = NullPointerException.class) + public void fromFutureTimedFutureNull() { + NbpObservable.fromFuture(null, 1, TimeUnit.SECONDS); + } + + @Test(expected = NullPointerException.class) + public void fromFutureTimedUnitNull() { + NbpObservable.fromFuture(new FutureTask(Functions.emptyRunnable(), null), 1, null); + } + + @Test(expected = NullPointerException.class) + public void fromFutureTimedSchedulerNull() { + NbpObservable.fromFuture(new FutureTask(Functions.emptyRunnable(), null), 1, TimeUnit.SECONDS, null); + } + + @Test(expected = NullPointerException.class) + public void fromFutureTimedReturnsNull() { + FutureTask f = new FutureTask(Functions.emptyRunnable(), null); + f.run(); + NbpObservable.fromFuture(f, 1, TimeUnit.SECONDS).toBlocking().lastOption(); + } + + @Test(expected = NullPointerException.class) + public void fromFutureSchedulerNull() { + FutureTask f = new FutureTask(Functions.emptyRunnable(), null); + NbpObservable.fromFuture(f, null); + } + + @Test(expected = NullPointerException.class) + public void fromIterableNull() { + NbpObservable.fromIterable(null); + } + + @Test(expected = NullPointerException.class) + public void fromIterableIteratorNull() { + NbpObservable.fromIterable(new Iterable() { + @Override + public Iterator iterator() { + return null; + } + }).toBlocking().lastOption(); + } + + @Test(expected = NullPointerException.class) + public void fromIterableValueNull() { + NbpObservable.fromIterable(Arrays.asList(1, null)).toBlocking().lastOption(); + } + + @Test(expected = NullPointerException.class) + public void generateConsumerNull() { + NbpObservable.generate(null); + } + + @Test(expected = NullPointerException.class) + public void generateConsumerEmitsNull() { + NbpObservable.generate(new Consumer>() { + @Override + public void accept(NbpSubscriber s) { + s.onNext(null); + } + }).toBlocking().lastOption(); + } + + @Test(expected = NullPointerException.class) + public void generateStateConsumerInitialStateNull() { + BiConsumer> generator = new BiConsumer>() { + @Override + public void accept(Integer s, NbpSubscriber o) { + o.onNext(1); + } + }; + NbpObservable.generate(null, generator); + } + + @Test(expected = NullPointerException.class) + public void generateStateFunctionInitialStateNull() { + NbpObservable.generate(null, new BiFunction, Object>() { + @Override + public Object apply(Object s, NbpSubscriber o) { o.onNext(1); return s; } + }); + } + + @Test(expected = NullPointerException.class) + public void generateStateConsumerNull() { + NbpObservable.generate(new Supplier() { + @Override + public Integer get() { + return 1; + } + }, (BiConsumer>)null); + } + + @Test + public void generateConsumerStateNullAllowed() { + BiConsumer> generator = new BiConsumer>() { + @Override + public void accept(Integer s, NbpSubscriber o) { + o.onComplete(); + } + }; + NbpObservable.generate(new Supplier() { + @Override + public Integer get() { + return null; + } + }, generator).toBlocking().lastOption(); + } + + @Test + public void generateFunctionStateNullAllowed() { + NbpObservable.generate(new Supplier() { + @Override + public Object get() { + return null; + } + }, new BiFunction, Object>() { + @Override + public Object apply(Object s, NbpSubscriber o) { o.onComplete(); return s; } + }).toBlocking().lastOption(); + } + + @Test(expected = NullPointerException.class) + public void generateConsumerDisposeNull() { + BiConsumer> generator = new BiConsumer>() { + @Override + public void accept(Integer s, NbpSubscriber o) { + o.onNext(1); + } + }; + NbpObservable.generate(new Supplier() { + @Override + public Integer get() { + return 1; + } + }, generator, null); + } + + @Test(expected = NullPointerException.class) + public void generateFunctionDisposeNull() { + NbpObservable.generate(new Supplier() { + @Override + public Object get() { + return 1; + } + }, new BiFunction, Object>() { + @Override + public Object apply(Object s, NbpSubscriber o) { o.onNext(1); return s; } + }, null); + } + + @Test(expected = NullPointerException.class) + public void intervalUnitNull() { + NbpObservable.interval(1, null); + } + + public void intervalSchedulerNull() { + NbpObservable.interval(1, TimeUnit.SECONDS, null); + } + + @Test(expected = NullPointerException.class) + public void intervalPeriodUnitNull() { + NbpObservable.interval(1, 1, null); + } + + @Test(expected = NullPointerException.class) + public void intervalPeriodSchedulerNull() { + NbpObservable.interval(1, 1, TimeUnit.SECONDS, null); + } + + @Test(expected = NullPointerException.class) + public void intervalRangeUnitNull() { + NbpObservable.intervalRange(1,1, 1, 1, null); + } + + @Test(expected = NullPointerException.class) + public void intervalRangeSchedulerNull() { + NbpObservable.intervalRange(1, 1, 1, 1, TimeUnit.SECONDS, null); + } + + @Test + public void justNull() throws Exception { + @SuppressWarnings("rawtypes") + Class clazz = NbpObservable.class; + for (int argCount = 1; argCount < 10; argCount++) { + for (int argNull = 1; argNull <= argCount; argNull++) { + Class[] params = new Class[argCount]; + Arrays.fill(params, Object.class); + + Object[] values = new Object[argCount]; + Arrays.fill(values, 1); + values[argNull - 1] = null; + + Method m = clazz.getMethod("just", params); + + try { + m.invoke(null, values); + Assert.fail("No exception for argCount " + argCount + " / argNull " + argNull); + } catch (InvocationTargetException ex) { + if (!(ex.getCause() instanceof NullPointerException)) { + Assert.fail("Unexpected exception for argCount " + argCount + " / argNull " + argNull + ": " + ex); + } + } + } + } + } + + @Test(expected = NullPointerException.class) + public void mergeIterableNull() { + NbpObservable.merge(128, 128, (Iterable>)null); + } + + @Test(expected = NullPointerException.class) + public void mergeIterableIteratorNull() { + NbpObservable.merge(128, 128, new Iterable>() { + @Override + public Iterator> iterator() { + return null; + } + }).toBlocking().lastOption(); + } + + @SuppressWarnings("unchecked") + @Test(expected = NullPointerException.class) + public void mergeIterableOneIsNull() { + NbpObservable.merge(128, 128, Arrays.asList(just1, null)).toBlocking().lastOption(); + } + + @Test(expected = NullPointerException.class) + public void mergeArrayNull() { + NbpObservable.merge(128, 128, (NbpObservable[])null); + } + + @SuppressWarnings("unchecked") + @Test(expected = NullPointerException.class) + public void mergeArrayOneIsNull() { + NbpObservable.merge(128, 128, just1, null).toBlocking().lastOption(); + } + + @Test(expected = NullPointerException.class) + public void mergeDelayErrorIterableNull() { + NbpObservable.mergeDelayError(128, 128, (Iterable>)null); + } + + @Test(expected = NullPointerException.class) + public void mergeDelayErrorIterableIteratorNull() { + NbpObservable.mergeDelayError(128, 128, new Iterable>() { + @Override + public Iterator> iterator() { + return null; + } + }).toBlocking().lastOption(); + } + + @SuppressWarnings("unchecked") + @Test(expected = NullPointerException.class) + public void mergeDelayErrorIterableOneIsNull() { + NbpObservable.mergeDelayError(128, 128, Arrays.asList(just1, null)).toBlocking().lastOption(); + } + + @Test(expected = NullPointerException.class) + public void mergeDelayErrorArrayNull() { + NbpObservable.mergeDelayError(128, 128, (NbpObservable[])null); + } + + @SuppressWarnings("unchecked") + @Test(expected = NullPointerException.class) + public void mergeDelayErrorArrayOneIsNull() { + NbpObservable.mergeDelayError(128, 128, just1, null).toBlocking().lastOption(); + } + + @Test(expected = NullPointerException.class) + public void sequenceEqualFirstNull() { + NbpObservable.sequenceEqual(null, just1); + } + + @Test(expected = NullPointerException.class) + public void sequenceEqualSecondNull() { + NbpObservable.sequenceEqual(just1, null); + } + + @Test(expected = NullPointerException.class) + public void sequenceEqualComparatorNull() { + NbpObservable.sequenceEqual(just1, just1, null); + } + + @Test(expected = NullPointerException.class) + public void switchOnNextNull() { + NbpObservable.switchOnNext(null); + } + + @Test(expected = NullPointerException.class) + public void timerUnitNull() { + NbpObservable.timer(1, null); + } + + @Test(expected = NullPointerException.class) + public void timerSchedulerNull() { + NbpObservable.timer(1, TimeUnit.SECONDS, null); + } + + @Test(expected = NullPointerException.class) + public void usingResourceSupplierNull() { + NbpObservable.using(null, new Function>() { + @Override + public NbpObservable apply(Object d) { + return just1; + } + }, new Consumer() { + @Override + public void accept(Object d) { } + }); + } + + @Test(expected = NullPointerException.class) + public void usingNbpObservableSupplierNull() { + NbpObservable.using(new Supplier() { + @Override + public Object get() { + return 1; + } + }, null, new Consumer() { + @Override + public void accept(Object d) { } + }); + } + + @Test(expected = NullPointerException.class) + public void usingNbpObservableSupplierReturnsNull() { + NbpObservable.using(new Supplier() { + @Override + public Object get() { + return 1; + } + }, new Function>() { + @Override + public NbpObservable apply(Object d) { + return null; + } + }, new Consumer() { + @Override + public void accept(Object d) { } + }).toBlocking().lastOption(); + } + + @Test(expected = NullPointerException.class) + public void usingDisposeNull() { + NbpObservable.using(new Supplier() { + @Override + public Object get() { + return 1; + } + }, new Function>() { + @Override + public NbpObservable apply(Object d) { + return just1; + } + }, null); + } + + @Test(expected = NullPointerException.class) + public void zipIterableNull() { + NbpObservable.zip((Iterable>)null, new Function() { + @Override + public Object apply(Object[] v) { + return 1; + } + }); + } + + @Test(expected = NullPointerException.class) + public void zipIterableIteratorNull() { + NbpObservable.zip(new Iterable>() { + @Override + public Iterator> iterator() { + return null; + } + }, new Function() { + @Override + public Object apply(Object[] v) { + return 1; + } + }).toBlocking().lastOption(); + } + + @SuppressWarnings("unchecked") + @Test(expected = NullPointerException.class) + public void zipIterableFunctionNull() { + NbpObservable.zip(Arrays.asList(just1, just1), null); + } + + @SuppressWarnings("unchecked") + @Test(expected = NullPointerException.class) + public void zipIterableFunctionReturnsNull() { + NbpObservable.zip(Arrays.asList(just1, just1), new Function() { + @Override + public Object apply(Object[] a) { + return null; + } + }).toBlocking().lastOption(); + } + + @Test(expected = NullPointerException.class) + public void zipNbpObservableNull() { + NbpObservable.zip((NbpObservable>)null, new Function() { + @Override + public Object apply(Object[] a) { + return 1; + } + }); + } + + @Test(expected = NullPointerException.class) + public void zipNbpObservableFunctionNull() { + NbpObservable.zip((NbpObservable.just(just1)), null); + } + + @Test(expected = NullPointerException.class) + public void zipNbpObservableFunctionReturnsNull() { + NbpObservable.zip((NbpObservable.just(just1)), new Function() { + @Override + public Object apply(Object[] a) { + return null; + } + }).toBlocking().lastOption(); + } + + @Test(expected = NullPointerException.class) + public void zipIterable2Null() { + NbpObservable.zipIterable(new Function() { + @Override + public Object apply(Object[] a) { + return 1; + } + }, true, 128, (Iterable>)null); + } + + @Test(expected = NullPointerException.class) + public void zipIterable2IteratorNull() { + NbpObservable.zipIterable(new Function() { + @Override + public Object apply(Object[] a) { + return 1; + } + }, true, 128, new Iterable>() { + @Override + public Iterator> iterator() { + return null; + } + }).toBlocking().lastOption(); + } + + @SuppressWarnings("unchecked") + @Test(expected = NullPointerException.class) + public void zipIterable2FunctionNull() { + NbpObservable.zipIterable(null, true, 128, Arrays.asList(just1, just1)); + } + + @SuppressWarnings("unchecked") + @Test(expected = NullPointerException.class) + public void zipIterable2FunctionReturnsNull() { + NbpObservable.zipIterable(new Function() { + @Override + public Object apply(Object[] a) { + return null; + } + }, true, 128, Arrays.asList(just1, just1)).toBlocking().lastOption(); + } + + //************************************************************* + // Instance methods + //************************************************************* + + @Test(expected = NullPointerException.class) + public void allPredicateNull() { + just1.all(null); + } + + @Test(expected = NullPointerException.class) + public void ambWithNull() { + just1.ambWith(null); + } + + @Test(expected = NullPointerException.class) + public void anyPredicateNull() { + just1.any(null); + } + + @Test(expected = NullPointerException.class) + public void bufferSupplierNull() { + just1.buffer(1, 1, (Supplier>)null); + } + + @Test(expected = NullPointerException.class) + public void bufferSupplierReturnsNull() { + just1.buffer(1, 1, new Supplier>() { + @Override + public Collection get() { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void bufferTimedUnitNull() { + just1.buffer(1L, 1L, null); + } + + @Test(expected = NullPointerException.class) + public void bufferTimedSchedulerNull() { + just1.buffer(1L, 1L, TimeUnit.SECONDS, null); + } + + @Test(expected = NullPointerException.class) + public void bufferTimedSupplierNull() { + just1.buffer(1L, 1L, TimeUnit.SECONDS, Schedulers.single(), null); + } + + @Test(expected = NullPointerException.class) + public void bufferTimedSupplierReturnsNull() { + just1.buffer(1L, 1L, TimeUnit.SECONDS, Schedulers.single(), new Supplier>() { + @Override + public Collection get() { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void bufferOpenCloseOpenNull() { + just1.buffer(null, new Function>() { + @Override + public NbpObservable apply(Object o) { + return just1; + } + }); + } + + @Test(expected = NullPointerException.class) + public void bufferOpenCloseCloseNull() { + just1.buffer(just1, (Function>)null); + } + + @Test(expected = NullPointerException.class) + public void bufferOpenCloseCloseReturnsNull() { + just1.buffer(just1, new Function>() { + @Override + public NbpObservable apply(Integer v) { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void bufferBoundaryNull() { + just1.buffer((NbpObservable)null); + } + + @Test(expected = NullPointerException.class) + public void bufferBoundarySupplierNull() { + just1.buffer(just1, (Supplier>)null); + } + + @Test(expected = NullPointerException.class) + public void bufferBoundarySupplierReturnsNull() { + just1.buffer(just1, new Supplier>() { + @Override + public Collection get() { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void bufferBoundarySupplier2Null() { + just1.buffer((Supplier>)null); + } + + @Test(expected = NullPointerException.class) + public void bufferBoundarySupplier2ReturnsNull() { + just1.buffer(new Supplier>() { + @Override + public NbpObservable get() { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void bufferBoundarySupplier2SupplierNull() { + just1.buffer(new Supplier>() { + @Override + public NbpObservable get() { + return just1; + } + }, null); + } + + @Test(expected = NullPointerException.class) + public void bufferBoundarySupplier2SupplierReturnsNull() { + just1.buffer(new Supplier>() { + @Override + public NbpObservable get() { + return just1; + } + }, new Supplier>() { + @Override + public Collection get() { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void castNull() { + just1.cast(null); + } + + @Test(expected = NullPointerException.class) + public void collectInitialSupplierNull() { + just1.collect((Supplier)null, new BiConsumer() { + @Override + public void accept(Integer a, Integer b) { } + }); + } + + @Test(expected = NullPointerException.class) + public void collectInitialSupplierReturnsNull() { + just1.collect(new Supplier() { + @Override + public Object get() { + return null; + } + }, new BiConsumer() { + @Override + public void accept(Object a, Integer b) { } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void collectInitialCollectorNull() { + just1.collect(new Supplier() { + @Override + public Object get() { + return 1; + } + }, null); + } + + @Test(expected = NullPointerException.class) + public void collectIntoInitialNull() { + just1.collectInto(null, new BiConsumer() { + @Override + public void accept(Object a, Integer b) { } + }); + } + + @Test(expected = NullPointerException.class) + public void collectIntoCollectorNull() { + just1.collectInto(1, null); + } + + @Test(expected = NullPointerException.class) + public void composeNull() { + just1.compose(null); + } + + @Test(expected = NullPointerException.class) + public void concatMapNull() { + just1.concatMap(null); + } + + @Test(expected = NullPointerException.class) + public void concatMapReturnsNull() { + just1.concatMap(new Function>() { + @Override + public NbpObservable apply(Integer v) { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void concatMapIterableNull() { + just1.concatMapIterable(null); + } + + @Test(expected = NullPointerException.class) + public void concatMapIterableReturnNull() { + just1.concatMapIterable(new Function>() { + @Override + public Iterable apply(Integer v) { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void concatMapIterableIteratorNull() { + just1.concatMapIterable(new Function>() { + @Override + public Iterable apply(Integer v) { + return new Iterable() { + @Override + public Iterator iterator() { + return null; + } + }; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void concatWithNull() { + just1.concatWith(null); + } + + @Test(expected = NullPointerException.class) + public void containsNull() { + just1.contains(null); + } + + @Test(expected = NullPointerException.class) + public void debounceFunctionNull() { + just1.debounce(null); + } + + @Test(expected = NullPointerException.class) + public void debounceFunctionReturnsNull() { + just1.debounce(new Function>() { + @Override + public NbpObservable apply(Integer v) { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void debounceTimedUnitNull() { + just1.debounce(1, null); + } + + @Test(expected = NullPointerException.class) + public void debounceTimedSchedulerNull() { + just1.debounce(1, TimeUnit.SECONDS, null); + } + + @Test(expected = NullPointerException.class) + public void defaultIfEmptyNull() { + just1.defaultIfEmpty(null); + } + + @Test(expected = NullPointerException.class) + public void delayWithFunctionNull() { + just1.delay(null); + } + + @Test(expected = NullPointerException.class) + public void delayWithFunctionReturnsNull() { + just1.delay(new Function>() { + @Override + public NbpObservable apply(Integer v) { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void delayTimedUnitNull() { + just1.delay(1, null); + } + + @Test(expected = NullPointerException.class) + public void delayTimedSchedulerNull() { + just1.delay(1, TimeUnit.SECONDS, null); + } + + @Test(expected = NullPointerException.class) + public void delaySubscriptionTimedUnitNull() { + just1.delaySubscription(1, null); + } + + @Test(expected = NullPointerException.class) + public void delaySubscriptionTimedSchedulerNull() { + just1.delaySubscription(1, TimeUnit.SECONDS, null); + } + + @Test(expected = NullPointerException.class) + public void delaySubscriptionOtherNull() { + just1.delaySubscription((NbpObservable)null); + } + + @Test(expected = NullPointerException.class) + public void delaySubscriptionFunctionNull() { + just1.delaySubscription((Supplier>)null); + } + + @Test(expected = NullPointerException.class) + public void delayBothInitialSupplierNull() { + just1.delay(null, new Function>() { + @Override + public NbpObservable apply(Integer v) { + return just1; + } + }); + } + + @Test(expected = NullPointerException.class) + public void delayBothInitialSupplierReturnsNull() { + just1.delay(new Supplier>() { + @Override + public NbpObservable get() { + return null; + } + }, new Function>() { + @Override + public NbpObservable apply(Integer v) { + return just1; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void delayBothItemSupplierNull() { + just1.delay(new Supplier>() { + @Override + public NbpObservable get() { + return just1; + } + }, null); + } + + @Test(expected = NullPointerException.class) + public void delayBothItemSupplierReturnsNull() { + just1.delay(new Supplier>() { + @Override + public NbpObservable get() { + return just1; + } + }, new Function>() { + @Override + public NbpObservable apply(Integer v) { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void distinctFunctionNull() { + just1.distinct(null); + } + + @Test(expected = NullPointerException.class) + public void distinctSupplierNull() { + just1.distinct(new Function() { + @Override + public Object apply(Integer v) { + return v; + } + }, null); + } + + @Test(expected = NullPointerException.class) + public void distinctSupplierReturnsNull() { + just1.distinct(new Function() { + @Override + public Object apply(Integer v) { + return v; + } + }, new Supplier>() { + @Override + public Collection get() { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void distinctFunctionReturnsNull() { + just1.distinct(new Function() { + @Override + public Object apply(Integer v) { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void distinctUntilChangedFunctionNull() { + just1.distinctUntilChanged(null); + } + + @Test(expected = NullPointerException.class) + public void distinctUntilChangedFunctionReturnsNull() { + just1.distinctUntilChanged(new Function() { + @Override + public Object apply(Integer v) { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void doOnCancelNull() { + just1.doOnCancel(null); + } + + @Test(expected = NullPointerException.class) + public void doOnCompleteNull() { + just1.doOnComplete(null); + } + + @Test(expected = NullPointerException.class) + public void doOnEachSupplierNull() { + just1.doOnEach((Consumer>>)null); + } + + @Test(expected = NullPointerException.class) + public void doOnEachSubscriberNull() { + just1.doOnEach((NbpSubscriber)null); + } + + @Test(expected = NullPointerException.class) + public void doOnErrorNull() { + just1.doOnError(null); + } + + @Test(expected = NullPointerException.class) + public void doOnLifecycleOnSubscribeNull() { + just1.doOnLifecycle(null, Functions.emptyRunnable()); + } + + @Test(expected = NullPointerException.class) + public void doOnLifecycleOnCancelNull() { + just1.doOnLifecycle(new Consumer() { + @Override + public void accept(Disposable s) { } + }, null); + } + + @Test(expected = NullPointerException.class) + public void doOnNextNull() { + just1.doOnNext(null); + } + + @Test(expected = NullPointerException.class) + public void doOnSubscribeNull() { + just1.doOnSubscribe(null); + } + + @Test(expected = NullPointerException.class) + public void doOnTerminatedNull() { + just1.doOnTerminate(null); + } + + @Test(expected = NullPointerException.class) + public void elementAtNull() { + just1.elementAt(1, null); + } + + @Test(expected = NullPointerException.class) + public void endWithIterableNull() { + just1.endWith((Iterable)null); + } + + @Test(expected = NullPointerException.class) + public void endWithIterableIteratorNull() { + just1.endWith(new Iterable() { + @Override + public Iterator iterator() { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void endWithIterableOneIsNull() { + just1.endWith(Arrays.asList(1, null)).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void endWithNbpObservableNull() { + just1.endWith((NbpObservable)null); + } + + @Test(expected = NullPointerException.class) + public void endWithNull() { + just1.endWith((Integer)null); + } + + @Test(expected = NullPointerException.class) + public void endWithArrayNull() { + just1.endWithArray((Integer[])null); + } + + @Test(expected = NullPointerException.class) + public void endWithArrayOneIsNull() { + just1.endWithArray(1, null).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void filterNull() { + just1.filter(null); + } + + @Test(expected = NullPointerException.class) + public void finallyDoNull() { + just1.finallyDo(null); + } + + @Test(expected = NullPointerException.class) + public void firstNull() { + just1.first(null); + } + + @Test(expected = NullPointerException.class) + public void flatMapNull() { + just1.flatMap(null); + } + + @Test(expected = NullPointerException.class) + public void flatMapFunctionReturnsNull() { + just1.flatMap(new Function>() { + @Override + public NbpObservable apply(Integer v) { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void flatMapNotificationOnNextNull() { + just1.flatMap(null, new Function>() { + @Override + public NbpObservable apply(Throwable e) { + return just1; + } + }, new Supplier>() { + @Override + public NbpObservable get() { + return just1; + } + }); + } + + @Test(expected = NullPointerException.class) + public void flatMapNotificationOnNextReturnsNull() { + just1.flatMap(new Function>() { + @Override + public NbpObservable apply(Integer v) { + return null; + } + }, new Function>() { + @Override + public NbpObservable apply(Throwable e) { + return just1; + } + }, new Supplier>() { + @Override + public NbpObservable get() { + return just1; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void flatMapNotificationOnErrorNull() { + just1.flatMap(new Function>() { + @Override + public NbpObservable apply(Integer v) { + return just1; + } + }, null, new Supplier>() { + @Override + public NbpObservable get() { + return just1; + } + }); + } + + @Test(expected = NullPointerException.class) + public void flatMapNotificationOnErrorReturnsNull() { + NbpObservable.error(new TestException()).flatMap(new Function>() { + @Override + public NbpObservable apply(Object v) { + return just1; + } + }, new Function>() { + @Override + public NbpObservable apply(Throwable e) { + return null; + } + }, new Supplier>() { + @Override + public NbpObservable get() { + return just1; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void flatMapNotificationOnCompleteNull() { + just1.flatMap(new Function>() { + @Override + public NbpObservable apply(Integer v) { + return just1; + } + }, new Function>() { + @Override + public NbpObservable apply(Throwable e) { + return just1; + } + }, null); + } + + @Test(expected = NullPointerException.class) + public void flatMapNotificationOnCompleteReturnsNull() { + just1.flatMap(new Function>() { + @Override + public NbpObservable apply(Integer v) { + return just1; + } + }, new Function>() { + @Override + public NbpObservable apply(Throwable e) { + return just1; + } + }, new Supplier>() { + @Override + public NbpObservable get() { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void flatMapCombinerMapperNull() { + just1.flatMap(null, new BiFunction() { + @Override + public Object apply(Integer a, Object b) { + return 1; + } + }); + } + + @Test(expected = NullPointerException.class) + public void flatMapCombinerMapperReturnsNull() { + just1.flatMap(new Function>() { + @Override + public NbpObservable apply(Integer v) { + return null; + } + }, new BiFunction() { + @Override + public Object apply(Integer a, Object b) { + return 1; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void flatMapCombinerCombinerNull() { + just1.flatMap(new Function>() { + @Override + public NbpObservable apply(Integer v) { + return just1; + } + }, null); + } + + @Test(expected = NullPointerException.class) + public void flatMapCombinerCombinerReturnsNull() { + just1.flatMap(new Function>() { + @Override + public NbpObservable apply(Integer v) { + return just1; + } + }, new BiFunction() { + @Override + public Object apply(Integer a, Integer b) { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void flatMapIterableMapperNull() { + just1.flatMapIterable(null); + } + + @Test(expected = NullPointerException.class) + public void flatMapIterableMapperReturnsNull() { + just1.flatMapIterable(new Function>() { + @Override + public Iterable apply(Integer v) { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void flatMapIterableMapperIteratorNull() { + just1.flatMapIterable(new Function>() { + @Override + public Iterable apply(Integer v) { + return new Iterable() { + @Override + public Iterator iterator() { + return null; + } + }; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void flatMapIterableMapperIterableOneNull() { + just1.flatMapIterable(new Function>() { + @Override + public Iterable apply(Integer v) { + return Arrays.asList(1, null); + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void flatMapIterableCombinerNull() { + just1.flatMapIterable(new Function>() { + @Override + public Iterable apply(Integer v) { + return Arrays.asList(1); + } + }, null); + } + + @Test(expected = NullPointerException.class) + public void flatMapIterableCombinerReturnsNull() { + just1.flatMapIterable(new Function>() { + @Override + public Iterable apply(Integer v) { + return Arrays.asList(1); + } + }, new BiFunction() { + @Override + public Object apply(Integer a, Integer b) { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void forEachNull() { + just1.forEach(null); + } + + @Test(expected = NullPointerException.class) + public void forEachWhileNull() { + just1.forEachWhile(null); + } + + @Test(expected = NullPointerException.class) + public void forEachWhileOnErrorNull() { + just1.forEachWhile(new Predicate() { + @Override + public boolean test(Integer v) { + return true; + } + }, null); + } + + @Test(expected = NullPointerException.class) + public void forEachWhileOnCompleteNull() { + just1.forEachWhile(new Predicate() { + @Override + public boolean test(Integer v) { + return true; + } + }, new Consumer() { + @Override + public void accept(Throwable e) { } + }, null); + } + + @Test(expected = NullPointerException.class) + public void groupByNull() { + just1.groupBy(null); + } + + public void groupByKeyNull() { + just1.groupBy(new Function() { + @Override + public Object apply(Integer v) { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void groupByValueNull() { + just1.groupBy(new Function() { + @Override + public Object apply(Integer v) { + return v; + } + }, null); + } + + @Test(expected = NullPointerException.class) + public void groupByValueReturnsNull() { + just1.groupBy(new Function() { + @Override + public Object apply(Integer v) { + return v; + } + }, new Function() { + @Override + public Object apply(Integer v) { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void lastNull() { + just1.last(null); + } + + @Test(expected = NullPointerException.class) + public void liftNull() { + just1.lift(null); + } + + @Test(expected = NullPointerException.class) + public void liftReturnsNull() { + just1.lift(new NbpOperator() { + @Override + public NbpSubscriber apply(NbpSubscriber s) { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void mapNull() { + just1.map(null); + } + + @Test(expected = NullPointerException.class) + public void mapReturnsNull() { + just1.map(new Function() { + @Override + public Object apply(Integer v) { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void mergeWithNull() { + just1.mergeWith(null); + } + + @Test(expected = NullPointerException.class) + public void observeOnNull() { + just1.observeOn(null); + } + + @Test(expected = NullPointerException.class) + public void ofTypeNull() { + just1.ofType(null); + } + + @Test(expected = NullPointerException.class) + public void onErrorResumeNextFunctionNull() { + just1.onErrorResumeNext((Function>)null); + } + + @Test(expected = NullPointerException.class) + public void onErrorResumeNextFunctionReturnsNull() { + NbpObservable.error(new TestException()).onErrorResumeNext(new Function>() { + @Override + public NbpObservable apply(Throwable e) { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void onErrorResumeNextNbpObservableNull() { + just1.onErrorResumeNext((NbpObservable)null); + } + + @Test(expected = NullPointerException.class) + public void onErrorReturnFunctionNull() { + just1.onErrorReturn(null); + } + + @Test(expected = NullPointerException.class) + public void onErrorReturnValueNull() { + just1.onErrorReturnValue(null); + } + + @Test(expected = NullPointerException.class) + public void onErrorReturnFunctionReturnsNull() { + NbpObservable.error(new TestException()).onErrorReturn(new Function() { + @Override + public Object apply(Throwable e) { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void onExceptionResumeNext() { + just1.onExceptionResumeNext(null); + } + + @Test(expected = NullPointerException.class) + public void publishFunctionNull() { + just1.publish(null); + } + + @Test(expected = NullPointerException.class) + public void publishFunctionReturnsNull() { + just1.publish(new Function, NbpObservable>() { + @Override + public NbpObservable apply(NbpObservable v) { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void reduceFunctionNull() { + just1.reduce(null); + } + + @Test(expected = NullPointerException.class) + public void reduceFunctionReturnsNull() { + NbpObservable.just(1, 1).reduce(new BiFunction() { + @Override + public Integer apply(Integer a, Integer b) { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void reduceSeedNull() { + just1.reduce(null, new BiFunction() { + @Override + public Object apply(Object a, Integer b) { + return 1; + } + }); + } + + @Test(expected = NullPointerException.class) + public void reduceSeedFunctionNull() { + just1.reduce(1, null); + } + + @Test(expected = NullPointerException.class) + public void reduceSeedFunctionReturnsNull() { + just1.reduce(1, new BiFunction() { + @Override + public Integer apply(Integer a, Integer b) { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void reduceWithSeedNull() { + just1.reduceWith(null, new BiFunction() { + @Override + public Object apply(Object a, Integer b) { + return 1; + } + }); + } + + @Test(expected = NullPointerException.class) + public void reduceWithSeedReturnsNull() { + just1.reduceWith(new Supplier() { + @Override + public Object get() { + return null; + } + }, new BiFunction() { + @Override + public Object apply(Object a, Integer b) { + return 1; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void repeatUntilNull() { + just1.repeatUntil(null); + } + + @Test(expected = NullPointerException.class) + public void repeatWhenNull() { + just1.repeatWhen(null); + } + + @Test(expected = NullPointerException.class) + public void repeatWhenFunctionReturnsNull() { + just1.repeatWhen(new Function, NbpObservable>() { + @Override + public NbpObservable apply(NbpObservable v) { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void replaySelectorNull() { + just1.replay((Function, NbpObservable>)null); + } + + @Test(expected = NullPointerException.class) + public void replaySelectorReturnsNull() { + just1.replay(new Function, NbpObservable>() { + @Override + public NbpObservable apply(NbpObservable o) { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void replayBoundedSelectorNull() { + just1.replay((Function, NbpObservable>)null, 1, 1, TimeUnit.SECONDS); + } + + @Test(expected = NullPointerException.class) + public void replayBoundedSelectorReturnsNull() { + just1.replay(new Function, NbpObservable>() { + @Override + public NbpObservable apply(NbpObservable v) { + return null; + } + }, 1, 1, TimeUnit.SECONDS).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void replaySchedulerNull() { + just1.replay((Scheduler)null); + } + + @Test(expected = NullPointerException.class) + public void replayBoundedUnitNull() { + just1.replay(new Function, NbpObservable>() { + @Override + public NbpObservable apply(NbpObservable v) { + return v; + } + }, 1, 1, null).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void replayBoundedSchedulerNull() { + just1.replay(new Function, NbpObservable>() { + @Override + public NbpObservable apply(NbpObservable v) { + return v; + } + }, 1, 1, TimeUnit.SECONDS, null).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void replayTimeBoundedSelectorNull() { + just1.replay(null, 1, TimeUnit.SECONDS, Schedulers.single()); + } + + @Test(expected = NullPointerException.class) + public void replayTimeBoundedSelectorReturnsNull() { + just1.replay(new Function, NbpObservable>() { + @Override + public NbpObservable apply(NbpObservable v) { + return null; + } + }, 1, TimeUnit.SECONDS, Schedulers.single()).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void replaySelectorTimeBoundedUnitNull() { + just1.replay(new Function, NbpObservable>() { + @Override + public NbpObservable apply(NbpObservable v) { + return v; + } + }, 1, null, Schedulers.single()); + } + + @Test(expected = NullPointerException.class) + public void replaySelectorTimeBoundedSchedulerNull() { + just1.replay(new Function, NbpObservable>() { + @Override + public NbpObservable apply(NbpObservable v) { + return v; + } + }, 1, TimeUnit.SECONDS, null); + } + + @Test(expected = NullPointerException.class) + public void replayTimeSizeBoundedUnitNull() { + just1.replay(1, 1, null, Schedulers.single()); + } + + @Test(expected = NullPointerException.class) + public void replayTimeSizeBoundedSchedulerNull() { + just1.replay(1, 1, TimeUnit.SECONDS, null); + } + + @Test(expected = NullPointerException.class) + public void replayBufferSchedulerNull() { + just1.replay(1, (Scheduler)null); + } + + @Test(expected = NullPointerException.class) + public void replayTimeBoundedUnitNull() { + just1.replay(1, null, Schedulers.single()); + } + + @Test(expected = NullPointerException.class) + public void replayTimeBoundedSchedulerNull() { + just1.replay(1, TimeUnit.SECONDS, null); + } + + @Test(expected = NullPointerException.class) + public void retryFunctionNull() { + just1.retry((BiPredicate)null); + } + + @Test(expected = NullPointerException.class) + public void retryCountFunctionNull() { + just1.retry(1, null); + } + + @Test(expected = NullPointerException.class) + public void retryPredicateNull() { + just1.retry((Predicate)null); + } + + @Test(expected = NullPointerException.class) + public void retryWhenFunctionNull() { + just1.retryWhen(null); + } + + @Test(expected = NullPointerException.class) + public void retryWhenFunctionReturnsNull() { + NbpObservable.error(new TestException()).retryWhen(new Function, NbpObservable>() { + @Override + public NbpObservable apply(NbpObservable f) { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void retryUntil() { + just1.retryUntil(null); + } + + @Test(expected = NullPointerException.class) + public void safeSubscribeNull() { + just1.safeSubscribe(null); + } + + @Test(expected = NullPointerException.class) + public void sampleUnitNull() { + just1.sample(1, null); + } + + @Test(expected = NullPointerException.class) + public void sampleSchedulerNull() { + just1.sample(1, TimeUnit.SECONDS, null); + } + + @Test(expected = NullPointerException.class) + public void sampleNbpObservableNull() { + just1.sample(null); + } + + @Test(expected = NullPointerException.class) + public void scanFunctionNull() { + just1.scan(null); + } + + @Test(expected = NullPointerException.class) + public void scanFunctionReturnsNull() { + NbpObservable.just(1, 1).scan(new BiFunction() { + @Override + public Integer apply(Integer a, Integer b) { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void scanSeedNull() { + just1.scan(null, new BiFunction() { + @Override + public Object apply(Object a, Integer b) { + return 1; + } + }); + } + + @Test(expected = NullPointerException.class) + public void scanSeedFunctionNull() { + just1.scan(1, null); + } + + @Test(expected = NullPointerException.class) + public void scanSeedFunctionReturnsNull() { + just1.scan(1, new BiFunction() { + @Override + public Integer apply(Integer a, Integer b) { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void scanSeedSupplierNull() { + just1.scanWith(null, new BiFunction() { + @Override + public Object apply(Object a, Integer b) { + return 1; + } + }); + } + + @Test(expected = NullPointerException.class) + public void scanSeedSupplierReturnsNull() { + just1.scanWith(new Supplier() { + @Override + public Object get() { + return null; + } + }, new BiFunction() { + @Override + public Object apply(Object a, Integer b) { + return 1; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void scanSeedSupplierFunctionNull() { + just1.scanWith(new Supplier() { + @Override + public Object get() { + return 1; + } + }, null); + } + + @Test(expected = NullPointerException.class) + public void scanSeedSupplierFunctionReturnsNull() { + just1.scanWith(new Supplier() { + @Override + public Object get() { + return 1; + } + }, new BiFunction() { + @Override + public Object apply(Object a, Integer b) { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void singleNull() { + just1.single(null); + } + + @Test(expected = NullPointerException.class) + public void skipTimedUnitNull() { + just1.skip(1, null, Schedulers.single()); + } + + @Test(expected = NullPointerException.class) + public void skipTimedSchedulerNull() { + just1.skip(1, TimeUnit.SECONDS, null); + } + + @Test(expected = NullPointerException.class) + public void skipLastTimedUnitNull() { + just1.skipLast(1, null, Schedulers.single()); + } + + @Test(expected = NullPointerException.class) + public void skipLastTimedSchedulerNull() { + just1.skipLast(1, TimeUnit.SECONDS, null); + } + + @Test(expected = NullPointerException.class) + public void skipUntilNull() { + just1.skipUntil(null); + } + + @Test(expected = NullPointerException.class) + public void skipWhileNull() { + just1.skipWhile(null); + } + + @Test(expected = NullPointerException.class) + public void startWithIterableNull() { + just1.startWith((Iterable)null); + } + + @Test(expected = NullPointerException.class) + public void startWithIterableIteratorNull() { + just1.startWith(new Iterable() { + @Override + public Iterator iterator() { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void startWithIterableOneNull() { + just1.startWith(Arrays.asList(1, null)).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void startWithSingleNull() { + just1.startWith((Integer)null); + } + + @Test(expected = NullPointerException.class) + public void startWithNbpObservableNull() { + just1.startWith((NbpObservable)null); + } + + @Test(expected = NullPointerException.class) + public void startWithArrayNull() { + just1.startWithArray((Integer[])null); + } + + @Test(expected = NullPointerException.class) + public void startWithArrayOneNull() { + just1.startWithArray(1, null).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void subscribeOnNextNull() { + just1.subscribe((Consumer)null); + } + + @Test(expected = NullPointerException.class) + public void subscribeOnErrorNull() { + just1.subscribe(new Consumer() { + @Override + public void accept(Integer e) { } + }, null); + } + + @Test(expected = NullPointerException.class) + public void subscribeOnCompleteNull() { + just1.subscribe(new Consumer() { + @Override + public void accept(Integer e) { } + }, new Consumer() { + @Override + public void accept(Throwable e) { } + }, null); + } + + @Test(expected = NullPointerException.class) + public void subscribeOnSubscribeNull() { + just1.subscribe(new Consumer() { + @Override + public void accept(Integer e) { } + }, new Consumer() { + @Override + public void accept(Throwable e) { } + }, Functions.emptyRunnable(), null); + } + + @Test(expected = NullPointerException.class) + public void subscribeNull() { + just1.subscribe((NbpSubscriber)null); + } + + @Test(expected = NullPointerException.class) + public void subscribeOnNull() { + just1.subscribeOn(null); + } + + @Test(expected = NullPointerException.class) + public void switchIfEmptyNull() { + just1.switchIfEmpty(null); + } + + @Test(expected = NullPointerException.class) + public void switchMapNull() { + just1.switchMap(null); + } + + @Test(expected = NullPointerException.class) + public void switchMapFunctionReturnsNull() { + just1.switchMap(new Function>() { + @Override + public NbpObservable apply(Integer v) { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void takeTimedUnitNull() { + just1.take(1, null, Schedulers.single()); + } + + @Test(expected = NullPointerException.class) + public void takeTimedSchedulerNull() { + just1.take(1, TimeUnit.SECONDS, null); + } + + @Test(expected = NullPointerException.class) + public void takeFirstNull() { + just1.takeFirst(null); + } + + @Test(expected = NullPointerException.class) + public void takeLastTimedUnitNull() { + just1.takeLast(1, null, Schedulers.single()); + } + + @Test(expected = NullPointerException.class) + public void takeLastSizeTimedUnitNull() { + just1.takeLast(1, 1, null, Schedulers.single()); + } + + @Test(expected = NullPointerException.class) + public void takeLastTimedSchedulerNull() { + just1.takeLast(1, TimeUnit.SECONDS, null); + } + + @Test(expected = NullPointerException.class) + public void takeLastSizeTimedSchedulerNull() { + just1.takeLast(1, 1, TimeUnit.SECONDS, null); + } + + @Test(expected = NullPointerException.class) + public void takeLastBufferTimedUnitNull() { + just1.takeLastBuffer(1, null, Schedulers.single()); + } + + @Test(expected = NullPointerException.class) + public void takeLastBufferTimedSchedulerNull() { + just1.takeLastBuffer(1, TimeUnit.SECONDS, null); + } + + @Test(expected = NullPointerException.class) + public void takeLastBufferSizeTimedUnitNull() { + just1.takeLastBuffer(1, 1, null, Schedulers.single()); + } + + @Test(expected = NullPointerException.class) + public void takeLastBufferSizeTimedSchedulerNull() { + just1.takeLastBuffer(1, 1, TimeUnit.SECONDS, null); + } + + @Test(expected = NullPointerException.class) + public void takeUntilPredicateNull() { + just1.takeUntil((Predicate)null); + } + + @Test(expected = NullPointerException.class) + public void takeUntilNbpObservableNull() { + just1.takeUntil((NbpObservable)null); + } + + @Test(expected = NullPointerException.class) + public void takeWhileNull() { + just1.takeWhile(null); + } + + @Test(expected = NullPointerException.class) + public void throttleFirstUnitNull() { + just1.throttleFirst(1, null, Schedulers.single()); + } + + @Test(expected = NullPointerException.class) + public void throttleFirstSchedulerNull() { + just1.throttleFirst(1, TimeUnit.SECONDS, null); + } + + @Test(expected = NullPointerException.class) + public void throttleLastUnitNull() { + just1.throttleLast(1, null, Schedulers.single()); + } + + @Test(expected = NullPointerException.class) + public void throttleLastSchedulerNull() { + just1.throttleLast(1, TimeUnit.SECONDS, null); + } + + @Test(expected = NullPointerException.class) + public void throttleWithTimeoutUnitNull() { + just1.throttleWithTimeout(1, null, Schedulers.single()); + } + + @Test(expected = NullPointerException.class) + public void throttleWithTimeoutSchedulerNull() { + just1.throttleWithTimeout(1, TimeUnit.SECONDS, null); + } + + @Test(expected = NullPointerException.class) + public void timeIntervalUnitNull() { + just1.timeInterval(null, Schedulers.single()); + } + + @Test(expected = NullPointerException.class) + public void timeIntervalSchedulerNull() { + just1.timeInterval(TimeUnit.SECONDS, null); + } + + @Test(expected = NullPointerException.class) + public void timeoutSelectorNull() { + just1.timeout(null); + } + + @Test(expected = NullPointerException.class) + public void timeoutSelectorReturnsNull() { + just1.timeout(new Function>() { + @Override + public NbpObservable apply(Integer v) { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void timeoutSelectorOtherNull() { + just1.timeout(new Function>() { + @Override + public NbpObservable apply(Integer v) { + return just1; + } + }, null); + } + + @Test(expected = NullPointerException.class) + public void timeoutUnitNull() { + just1.timeout(1, null, just1, Schedulers.single()); + } + + @Test(expected = NullPointerException.class) + public void timeouOtherNull() { + just1.timeout(1, TimeUnit.SECONDS, null, Schedulers.single()); + } + + @Test(expected = NullPointerException.class) + public void timeouSchedulerNull() { + just1.timeout(1, TimeUnit.SECONDS, just1, null); + } + + @Test(expected = NullPointerException.class) + public void timeoutFirstNull() { + just1.timeout((Supplier>)null, new Function>() { + @Override + public NbpObservable apply(Integer v) { + return just1; + } + }); + } + + @Test(expected = NullPointerException.class) + public void timeoutFirstReturnsNull() { + just1.timeout(new Supplier>() { + @Override + public NbpObservable get() { + return null; + } + }, new Function>() { + @Override + public NbpObservable apply(Integer v) { + return just1; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void timeoutFirstItemNull() { + just1.timeout(new Supplier>() { + @Override + public NbpObservable get() { + return just1; + } + }, null); + } + + @Test(expected = NullPointerException.class) + public void timeoutFirstItemReturnsNull() { + NbpObservable.just(1, 1).timeout(new Supplier>() { + @Override + public NbpObservable get() { + return NbpObservable.never(); + } + }, new Function>() { + @Override + public NbpObservable apply(Integer v) { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void timestampUnitNull() { + just1.timestamp(null, Schedulers.single()); + } + + @Test(expected = NullPointerException.class) + public void timestampSchedulerNull() { + just1.timestamp(TimeUnit.SECONDS, null); + } + + @Test(expected = NullPointerException.class) + public void toNull() { + just1.to(null); + } + + @Test(expected = NullPointerException.class) + public void toListNull() { + just1.toList(null); + } + + @Test(expected = NullPointerException.class) + public void toListSupplierReturnsNull() { + just1.toList(new Supplier>() { + @Override + public Collection get() { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void toSortedListNull() { + just1.toSortedList(null); + } + + @Test + public void toMapKeyNullAllowed() { + just1.toMap(null); + } + + @Test(expected = NullPointerException.class) + public void toMapValueNull() { + just1.toMap(new Function() { + @Override + public Object apply(Integer v) { + return v; + } + }, null); + } + + @Test + public void toMapValueSelectorReturnsNull() { + just1.toMap(new Function() { + @Override + public Object apply(Integer v) { + return v; + } + }, new Function() { + @Override + public Object apply(Integer v) { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void toMapMapSupplierNull() { + just1.toMap(new Function() { + @Override + public Object apply(Integer v) { + return v; + } + }, new Function() { + @Override + public Object apply(Integer v) { + return v; + } + }, null); + } + + @Test(expected = NullPointerException.class) + public void toMapMapSupplierReturnsNull() { + just1.toMap(new Function() { + @Override + public Object apply(Integer v) { + return v; + } + }, new Function() { + @Override + public Object apply(Integer v) { + return v; + } + }, new Supplier>() { + @Override + public Map get() { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void toMultimapKeyNull() { + just1.toMultimap(null); + } + + @Test(expected = NullPointerException.class) + public void toMultimapValueNull() { + just1.toMultimap(new Function() { + @Override + public Object apply(Integer v) { + return v; + } + }, null); + } + + @Test + public void toMultiMapValueSelectorReturnsNullAllowed() { + just1.toMap(new Function() { + @Override + public Object apply(Integer v) { + return v; + } + }, new Function() { + @Override + public Object apply(Integer v) { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void toMultimapMapMapSupplierNull() { + just1.toMultimap(new Function() { + @Override + public Object apply(Integer v) { + return v; + } + }, new Function() { + @Override + public Object apply(Integer v) { + return v; + } + }, null); + } + + @Test(expected = NullPointerException.class) + public void toMultimapMapSupplierReturnsNull() { + just1.toMultimap(new Function() { + @Override + public Object apply(Integer v) { + return v; + } + }, new Function() { + @Override + public Object apply(Integer v) { + return v; + } + }, new Supplier>>() { + @Override + public Map> get() { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void toMultimapMapMapCollectionSupplierNull() { + just1.toMultimap(new Function() { + @Override + public Integer apply(Integer v) { + return v; + } + }, new Function() { + @Override + public Integer apply(Integer v) { + return v; + } + }, new Supplier>>() { + @Override + public Map> get() { + return new HashMap>(); + } + }, null); + } + + @Test(expected = NullPointerException.class) + public void toMultimapMapCollectionSupplierReturnsNull() { + just1.toMultimap(new Function() { + @Override + public Integer apply(Integer v) { + return v; + } + }, new Function() { + @Override + public Integer apply(Integer v) { + return v; + } + }, new Supplier>>() { + @Override + public Map> get() { + return new HashMap>(); + } + }, new Function>() { + @Override + public Collection apply(Integer v) { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void unsafeSubscribeNull() { + just1.unsafeSubscribe(null); + } + + @Test(expected = NullPointerException.class) + public void unsubscribeOnNull() { + just1.unsubscribeOn(null); + } + + @Test(expected = NullPointerException.class) + public void windowTimedUnitNull() { + just1.window(1, null, Schedulers.single()); + } + + @Test(expected = NullPointerException.class) + public void windowSizeTimedUnitNull() { + just1.window(1, null, Schedulers.single(), 1); + } + + @Test(expected = NullPointerException.class) + public void windowTimedSchedulerNull() { + just1.window(1, TimeUnit.SECONDS, null); + } + + @Test(expected = NullPointerException.class) + public void windowSizeTimedSchedulerNull() { + just1.window(1, TimeUnit.SECONDS, null, 1); + } + + @Test(expected = NullPointerException.class) + public void windowBoundaryNull() { + just1.window((NbpObservable)null); + } + + @Test(expected = NullPointerException.class) + public void windowOpenCloseOpenNull() { + just1.window(null, new Function>() { + @Override + public NbpObservable apply(Object v) { + return just1; + } + }); + } + + @Test(expected = NullPointerException.class) + public void windowOpenCloseCloseNull() { + just1.window(just1, null); + } + + @Test(expected = NullPointerException.class) + public void windowOpenCloseCloseReturnsNull() { + NbpObservable.never().window(just1, new Function>() { + @Override + public NbpObservable apply(Integer v) { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void windowBoundarySupplierNull() { + just1.window((Supplier>)null); + } + + @Test(expected = NullPointerException.class) + public void windowBoundarySupplierReturnsNull() { + just1.window(new Supplier>() { + @Override + public NbpObservable get() { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void withLatestFromOtherNull() { + just1.withLatestFrom(null, new BiFunction() { + @Override + public Object apply(Integer a, Object b) { + return 1; + } + }); + } + + @Test(expected = NullPointerException.class) + public void withLatestFromCombinerNull() { + just1.withLatestFrom(just1, null); + } + + @Test(expected = NullPointerException.class) + public void withLatestFromCombinerReturnsNull() { + just1.withLatestFrom(just1, new BiFunction() { + @Override + public Object apply(Integer a, Integer b) { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void zipWithIterableNull() { + just1.zipWith((Iterable)null, new BiFunction() { + @Override + public Object apply(Integer a, Integer b) { + return 1; + } + }); + } + + @Test(expected = NullPointerException.class) + public void zipWithIterableCombinerNull() { + just1.zipWith(Arrays.asList(1), null); + } + + @Test(expected = NullPointerException.class) + public void zipWithIterableCombinerReturnsNull() { + just1.zipWith(Arrays.asList(1), new BiFunction() { + @Override + public Object apply(Integer a, Integer b) { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void zipWithIterableIteratorNull() { + just1.zipWith(new Iterable() { + @Override + public Iterator iterator() { + return null; + } + }, new BiFunction() { + @Override + public Object apply(Integer a, Object b) { + return 1; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void zipWithIterableOneIsNull() { + NbpObservable.just(1, 2).zipWith(Arrays.asList(1, null), new BiFunction() { + @Override + public Object apply(Integer a, Integer b) { + return 1; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void zipWithNbpObservableNull() { + just1.zipWith((NbpObservable)null, new BiFunction() { + @Override + public Object apply(Integer a, Integer b) { + return 1; + } + }); + } + + + @Test(expected = NullPointerException.class) + public void zipWithCombinerNull() { + just1.zipWith(just1, null); + } + + @Test(expected = NullPointerException.class) + public void zipWithCombinerReturnsNull() { + just1.zipWith(just1, new BiFunction() { + @Override + public Object apply(Integer a, Integer b) { + return null; + } + }).toBlocking().run(); + } + +} \ No newline at end of file diff --git a/src/test/java/io/reactivex/NbpObservableTest.java b/src/test/java/io/reactivex/NbpObservableTest.java index 2e956735c7..f0cad9c657 100644 --- a/src/test/java/io/reactivex/NbpObservableTest.java +++ b/src/test/java/io/reactivex/NbpObservableTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -17,10 +17,18 @@ import org.junit.*; +import io.reactivex.NbpObservable; +import io.reactivex.functions.Function; + public class NbpObservableTest { @Test public void testFlatMap() { - List list = NbpObservable.range(1, 5).flatMap(v -> NbpObservable.range(v, 2)).getList(); + List list = NbpObservable.range(1, 5).flatMap(new Function>() { + @Override + public NbpObservable apply(Integer v) { + return NbpObservable.range(v, 2); + } + }).getList(); Assert.assertEquals(Arrays.asList(1, 2, 2, 3, 3, 4, 4, 5, 5, 6), list); } diff --git a/src/test/java/io/reactivex/NotificationTest.java b/src/test/java/io/reactivex/NotificationTest.java index 002291b8d0..85e609c751 100644 --- a/src/test/java/io/reactivex/NotificationTest.java +++ b/src/test/java/io/reactivex/NotificationTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,8 +13,6 @@ package io.reactivex; -import java.util.Optional; - import org.junit.*; public class NotificationTest { diff --git a/src/test/java/io/reactivex/ObservableConversionTest.java b/src/test/java/io/reactivex/ObservableConversionTest.java index cd5c6974d7..dac7b15419 100644 --- a/src/test/java/io/reactivex/ObservableConversionTest.java +++ b/src/test/java/io/reactivex/ObservableConversionTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -16,12 +16,12 @@ import java.util.*; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.atomic.*; -import java.util.function.*; import org.junit.*; import org.reactivestreams.*; import io.reactivex.Observable.Operator; +import io.reactivex.functions.*; import io.reactivex.internal.operators.*; import io.reactivex.schedulers.Schedulers; import io.reactivex.subscribers.TestSubscriber; @@ -42,7 +42,7 @@ public static class CylonDetectorObservable { protected Publisher onSubscribe; public static CylonDetectorObservable create(Publisher onSubscribe) { - return new CylonDetectorObservable<>(onSubscribe); + return new CylonDetectorObservable(onSubscribe); } protected CylonDetectorObservable(Publisher onSubscribe) { @@ -137,7 +137,7 @@ public Observable apply(final Publisher onSubscribe) { @Test public void testConversionBetweenObservableClasses() { - final TestSubscriber subscriber = new TestSubscriber<>(new Observer() { + final TestSubscriber subscriber = new TestSubscriber(new Observer() { @Override public void onComplete() { @@ -159,13 +159,33 @@ public void onNext(String t) { List crewOfBattlestarGalactica = Arrays.asList(new Object[] {"William Adama", "Laura Roslin", "Lee Adama", new Cylon()}); Observable.fromIterable(crewOfBattlestarGalactica) - .doOnNext(System.out::println) - .to(new ConvertToCylonDetector<>()) - .beep(t -> t instanceof Cylon) - .boop(cylon -> new Jail(cylon)) + .doOnNext(new Consumer() { + @Override + public void accept(Object pv) { + System.out.println(pv); + } + }) + .to(new ConvertToCylonDetector()) + .beep(new Predicate() { + @Override + public boolean test(Object t) { + return t instanceof Cylon; + } + }) + .boop(new Function() { + @Override + public Object apply(Object cylon) { + return new Jail(cylon); + } + }) .DESTROY() .x(new ConvertToObservable()) - .reduce("Cylon Detector finished. Report:\n", (a, n) -> a + n + "\n") + .reduce("Cylon Detector finished. Report:\n", new BiFunction() { + @Override + public String apply(String a, String n) { + return a + n + "\n"; + } + }) .subscribe(subscriber); subscriber.assertNoErrors(); @@ -174,37 +194,48 @@ public void onNext(String t) { @Test public void testConvertToConcurrentQueue() { - final AtomicReference thrown = new AtomicReference<>(null); + final AtomicReference thrown = new AtomicReference(null); final AtomicBoolean isFinished = new AtomicBoolean(false); ConcurrentLinkedQueue queue = Observable.range(0,5) - .flatMap(i -> Observable.range(0, 5) - .observeOn(Schedulers.io()) - .map(k -> { - try { - Thread.sleep(System.currentTimeMillis() % 100); - } catch (InterruptedException e) { - e.printStackTrace(); - } - return i + k; - })) - .to(onSubscribe -> { - final ConcurrentLinkedQueue q = new ConcurrentLinkedQueue<>(); - onSubscribe.subscribe(new Observer(){ - @Override - public void onComplete() { - isFinished.set(true); - } - - @Override - public void onError(Throwable e) { - thrown.set(e); - } - - @Override - public void onNext(Integer t) { - q.add(t); - }}); - return q; + .flatMap(new Function>() { + @Override + public Publisher apply(final Integer i) { + return Observable.range(0, 5) + .observeOn(Schedulers.io()) + .map(new Function() { + @Override + public Integer apply(Integer k) { + try { + Thread.sleep(System.currentTimeMillis() % 100); + } catch (InterruptedException e) { + e.printStackTrace(); + } + return i + k; + } + }); + } + }) + .to(new Function, ConcurrentLinkedQueue>() { + @Override + public ConcurrentLinkedQueue apply(Observable onSubscribe) { + final ConcurrentLinkedQueue q = new ConcurrentLinkedQueue(); + onSubscribe.subscribe(new Observer(){ + @Override + public void onComplete() { + isFinished.set(true); + } + + @Override + public void onError(Throwable e) { + thrown.set(e); + } + + @Override + public void onNext(Integer t) { + q.add(t); + }}); + return q; + } }); int x = 0; diff --git a/src/test/java/io/reactivex/ObservableDoOnTest.java b/src/test/java/io/reactivex/ObservableDoOnTest.java index e1a4a9e33e..1ad2fafd90 100644 --- a/src/test/java/io/reactivex/ObservableDoOnTest.java +++ b/src/test/java/io/reactivex/ObservableDoOnTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -19,12 +19,20 @@ import org.junit.Test; +import io.reactivex.Observable; +import io.reactivex.functions.Consumer; + public class ObservableDoOnTest { @Test public void testDoOnEach() { - final AtomicReference r = new AtomicReference<>(); - String output = Observable.just("one").doOnNext(r::set).toBlocking().single(); + final AtomicReference r = new AtomicReference(); + String output = Observable.just("one").doOnNext(new Consumer() { + @Override + public void accept(String v) { + r.set(v); + } + }).toBlocking().single(); assertEquals("one", output); assertEquals("one", r.get()); @@ -32,11 +40,16 @@ public void testDoOnEach() { @Test public void testDoOnError() { - final AtomicReference r = new AtomicReference<>(); + final AtomicReference r = new AtomicReference(); Throwable t = null; try { Observable. error(new RuntimeException("an error")) - .doOnError(r::set).toBlocking().single(); + .doOnError(new Consumer() { + @Override + public void accept(Throwable v) { + r.set(v); + } + }).toBlocking().single(); fail("expected exception, not a return value"); } catch (Throwable e) { t = e; @@ -49,7 +62,12 @@ Observable. error(new RuntimeException("an error")) @Test public void testDoOnCompleted() { final AtomicBoolean r = new AtomicBoolean(); - String output = Observable.just("one").doOnComplete(() -> r.set(true)).toBlocking().single(); + String output = Observable.just("one").doOnComplete(new Runnable() { + @Override + public void run() { + r.set(true); + } + }).toBlocking().single(); assertEquals("one", output); assertTrue(r.get()); diff --git a/src/test/java/io/reactivex/ObservableNullTests.java b/src/test/java/io/reactivex/ObservableNullTests.java new file mode 100644 index 0000000000..35274c9452 --- /dev/null +++ b/src/test/java/io/reactivex/ObservableNullTests.java @@ -0,0 +1,2876 @@ +/** + * 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.lang.reflect.*; +import java.util.*; +import java.util.concurrent.*; + +import org.junit.*; +import org.reactivestreams.*; + +import io.reactivex.Observable.Operator; +import io.reactivex.exceptions.TestException; +import io.reactivex.functions.*; +import io.reactivex.internal.functions.Functions; +import io.reactivex.schedulers.Schedulers; +import io.reactivex.subjects.*; +import io.reactivex.subscribers.TestSubscriber; + +/** + * Verifies the operators handle null values properly by emitting/throwing NullPointerExceptions + */ +public class ObservableNullTests { + + Observable just1 = Observable.just(1); + + //*********************************************************** + // Static methods + //*********************************************************** + + @Test(expected = NullPointerException.class) + public void ambVarargsNull() { + Observable.amb((Publisher[])null); + } + + @SuppressWarnings("unchecked") + @Test(expected = NullPointerException.class) + public void ambVarargsOneIsNull() { + Observable.amb(Observable.never(), null).toBlocking().lastOption(); + } + + @Test(expected = NullPointerException.class) + public void ambIterableNull() { + Observable.amb((Iterable>)null); + } + + @Test(expected = NullPointerException.class) + public void ambIterableIteratorNull() { + Observable.amb(new Iterable>() { + @Override + public Iterator> iterator() { + return null; + } + }).toBlocking().lastOption(); + } + + @SuppressWarnings("unchecked") + @Test(expected = NullPointerException.class) + public void ambIterableOneIsNull() { + Observable.amb(Arrays.asList(Observable.never(), null)).toBlocking().lastOption(); + } + + @Test(expected = NullPointerException.class) + public void combineLatestVarargsNull() { + Observable.combineLatest(new Function() { + @Override + public Object apply(Object[] v) { + return 1; + } + }, true, 128, (Publisher[])null); + } + + @SuppressWarnings("unchecked") + @Test(expected = NullPointerException.class) + public void combineLatestVarargsOneIsNull() { + Observable.combineLatest(new Function() { + @Override + public Object apply(Object[] v) { + return 1; + } + }, true, 128, Observable.never(), null).toBlocking().lastOption(); + } + + @Test(expected = NullPointerException.class) + public void combineLatestIterableNull() { + Observable.combineLatest((Iterable>)null, new Function() { + @Override + public Object apply(Object[] v) { + return 1; + } + }, true, 128); + } + + @Test(expected = NullPointerException.class) + public void combineLatestIterableIteratorNull() { + Observable.combineLatest(new Iterable>() { + @Override + public Iterator> iterator() { + return null; + } + }, new Function() { + @Override + public Object apply(Object[] v) { + return 1; + } + }, true, 128).toBlocking().lastOption(); + } + + @SuppressWarnings("unchecked") + @Test(expected = NullPointerException.class) + public void combineLatestIterableOneIsNull() { + Observable.combineLatest(Arrays.asList(Observable.never(), null), new Function() { + @Override + public Object apply(Object[] v) { + return 1; + } + }, true, 128).toBlocking().lastOption(); + } + + @SuppressWarnings("unchecked") + @Test(expected = NullPointerException.class) + public void combineLatestVarargsFunctionNull() { + Observable.combineLatest(null, true, 128, Observable.never()); + } + + @SuppressWarnings("unchecked") + @Test(expected = NullPointerException.class) + public void combineLatestVarargsFunctionReturnsNull() { + Observable.combineLatest(new Function() { + @Override + public Object apply(Object[] v) { + return null; + } + }, true, 128, just1).toBlocking().lastOption(); + } + + @SuppressWarnings("unchecked") + @Test(expected = NullPointerException.class) + public void combineLatestIterableFunctionNull() { + Observable.combineLatest(Arrays.asList(just1), null, true, 128); + } + + @SuppressWarnings("unchecked") + @Test(expected = NullPointerException.class) + public void combineLatestIterableFunctionReturnsNull() { + Observable.combineLatest(Arrays.asList(just1), new Function() { + @Override + public Object apply(Object[] v) { + return null; + } + }, true, 128).toBlocking().lastOption(); + } + + @Test(expected = NullPointerException.class) + public void concatIterableNull() { + Observable.concat((Iterable>)null); + } + + @Test(expected = NullPointerException.class) + public void concatIterableIteratorNull() { + Observable.concat(new Iterable>() { + @Override + public Iterator> iterator() { + return null; + } + }).toBlocking().lastOption(); + } + + @SuppressWarnings("unchecked") + @Test(expected = NullPointerException.class) + public void concatIterableOneIsNull() { + Observable.concat(Arrays.asList(just1, null)).toBlocking().lastOption(); + } + + @Test(expected = NullPointerException.class) + public void concatPublisherNull() { + Observable.concat((Publisher>)null); + + } + + @Test(expected = NullPointerException.class) + public void concatArrayNull() { + Observable.concatArray((Publisher[])null); + } + + @SuppressWarnings("unchecked") + @Test(expected = NullPointerException.class) + public void concatArrayOneIsNull() { + Observable.concatArray(just1, null).toBlocking().lastOption(); + } + + @Test(expected = NullPointerException.class) + public void createNull() { + Observable.create(null); + } + + @Test(expected = NullPointerException.class) + public void deferFunctionNull() { + Observable.defer(null); + } + + @Test(expected = NullPointerException.class) + public void deferFunctionReturnsNull() { + Observable.defer(new Supplier>() { + @Override + public Publisher get() { + return null; + } + }).toBlocking().lastOption(); + } + + @Test(expected = NullPointerException.class) + public void errorFunctionNull() { + Observable.error((Supplier)null); + } + + @Test(expected = NullPointerException.class) + public void errorFunctionReturnsNull() { + Observable.error(new Supplier() { + @Override + public Throwable get() { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void errorThrowableNull() { + Observable.error((Throwable)null); + } + + @Test(expected = NullPointerException.class) + public void fromArrayNull() { + Observable.fromArray((Object[])null); + } + + @Test(expected = NullPointerException.class) + public void fromArrayOneIsNull() { + Observable.fromArray(1, null).toBlocking().lastOption(); + } + + @Test(expected = NullPointerException.class) + public void fromCallableNull() { + Observable.fromCallable(null); + } + + @Test(expected = NullPointerException.class) + public void fromCallableReturnsNull() { + Observable.fromCallable(new Callable() { + @Override + public Object call() throws Exception { + return null; + } + }).toBlocking().lastOption(); + } + + @Test(expected = NullPointerException.class) + public void fromFutureNull() { + Observable.fromFuture(null); + } + + @Test + public void fromFutureReturnsNull() { + FutureTask f = new FutureTask(Functions.emptyRunnable(), null); + f.run(); + + TestSubscriber ts = new TestSubscriber(); + Observable.fromFuture(f).subscribe(ts); + ts.assertNoValues(); + ts.assertNotComplete(); + ts.assertError(NullPointerException.class); + } + + @Test(expected = NullPointerException.class) + public void fromFutureTimedFutureNull() { + Observable.fromFuture(null, 1, TimeUnit.SECONDS); + } + + @Test(expected = NullPointerException.class) + public void fromFutureTimedUnitNull() { + Observable.fromFuture(new FutureTask(Functions.emptyRunnable(), null), 1, null); + } + + @Test(expected = NullPointerException.class) + public void fromFutureTimedSchedulerNull() { + Observable.fromFuture(new FutureTask(Functions.emptyRunnable(), null), 1, TimeUnit.SECONDS, null); + } + + @Test(expected = NullPointerException.class) + public void fromFutureTimedReturnsNull() { + FutureTask f = new FutureTask(Functions.emptyRunnable(), null); + f.run(); + Observable.fromFuture(f, 1, TimeUnit.SECONDS).toBlocking().lastOption(); + } + + @Test(expected = NullPointerException.class) + public void fromFutureSchedulerNull() { + Observable.fromFuture(new FutureTask(Functions.emptyRunnable(), null), null); + } + + @Test(expected = NullPointerException.class) + public void fromIterableNull() { + Observable.fromIterable(null); + } + + @Test(expected = NullPointerException.class) + public void fromIterableIteratorNull() { + Observable.fromIterable(new Iterable() { + @Override + public Iterator iterator() { + return null; + } + }).toBlocking().lastOption(); + } + + @Test(expected = NullPointerException.class) + public void fromIterableValueNull() { + Observable.fromIterable(Arrays.asList(1, null)).toBlocking().lastOption(); + } + + @Test(expected = NullPointerException.class) + public void fromPublisherNull() { + Observable.fromPublisher(null); + } + + @Test(expected = NullPointerException.class) + public void generateConsumerNull() { + Observable.generate(null); + } + + @Test(expected = NullPointerException.class) + public void generateConsumerEmitsNull() { + Observable.generate(new Consumer>() { + @Override + public void accept(Subscriber s) { + s.onNext(null); + } + }).toBlocking().lastOption(); + } + + @Test(expected = NullPointerException.class) + public void generateStateConsumerInitialStateNull() { + BiConsumer> generator = new BiConsumer>() { + @Override + public void accept(Integer s, Subscriber o) { + o.onNext(1); + } + }; + Observable.generate(null, generator); + } + + @Test(expected = NullPointerException.class) + public void generateStateFunctionInitialStateNull() { + Observable.generate(null, new BiFunction, Object>() { + @Override + public Object apply(Object s, Subscriber o) { o.onNext(1); return s; } + }); + } + + @Test(expected = NullPointerException.class) + public void generateStateConsumerNull() { + Observable.generate(new Supplier() { + @Override + public Integer get() { + return 1; + } + }, (BiConsumer>)null); + } + + @Test + public void generateConsumerStateNullAllowed() { + BiConsumer> generator = new BiConsumer>() { + @Override + public void accept(Integer s, Subscriber o) { + o.onComplete(); + } + }; + Observable.generate(new Supplier() { + @Override + public Integer get() { + return null; + } + }, generator).toBlocking().lastOption(); + } + + @Test + public void generateFunctionStateNullAllowed() { + Observable.generate(new Supplier() { + @Override + public Object get() { + return null; + } + }, new BiFunction, Object>() { + @Override + public Object apply(Object s, Subscriber o) { o.onComplete(); return s; } + }).toBlocking().lastOption(); + } + + @Test(expected = NullPointerException.class) + public void generateConsumerDisposeNull() { + BiConsumer> generator = new BiConsumer>() { + @Override + public void accept(Integer s, Subscriber o) { + o.onNext(1); + } + }; + Observable.generate(new Supplier() { + @Override + public Integer get() { + return 1; + } + }, generator, null); + } + + @Test(expected = NullPointerException.class) + public void generateFunctionDisposeNull() { + Observable.generate(new Supplier() { + @Override + public Object get() { + return 1; + } + }, new BiFunction, Object>() { + @Override + public Object apply(Object s, Subscriber o) { o.onNext(1); return s; } + }, null); + } + + @Test(expected = NullPointerException.class) + public void intervalUnitNull() { + Observable.interval(1, null); + } + + public void intervalSchedulerNull() { + Observable.interval(1, TimeUnit.SECONDS, null); + } + + @Test(expected = NullPointerException.class) + public void intervalPeriodUnitNull() { + Observable.interval(1, 1, null); + } + + @Test(expected = NullPointerException.class) + public void intervalPeriodSchedulerNull() { + Observable.interval(1, 1, TimeUnit.SECONDS, null); + } + + @Test(expected = NullPointerException.class) + public void intervalRangeUnitNull() { + Observable.intervalRange(1,1, 1, 1, null); + } + + @Test(expected = NullPointerException.class) + public void intervalRangeSchedulerNull() { + Observable.intervalRange(1, 1, 1, 1, TimeUnit.SECONDS, null); + } + + @Test + public void justNull() throws Exception { + @SuppressWarnings("rawtypes") + Class clazz = Observable.class; + for (int argCount = 1; argCount < 10; argCount++) { + for (int argNull = 1; argNull <= argCount; argNull++) { + Class[] params = new Class[argCount]; + Arrays.fill(params, Object.class); + + Object[] values = new Object[argCount]; + Arrays.fill(values, 1); + values[argNull - 1] = null; + + Method m = clazz.getMethod("just", params); + + try { + m.invoke(null, values); + Assert.fail("No exception for argCount " + argCount + " / argNull " + argNull); + } catch (InvocationTargetException ex) { + if (!(ex.getCause() instanceof NullPointerException)) { + Assert.fail("Unexpected exception for argCount " + argCount + " / argNull " + argNull + ": " + ex); + } + } + } + } + } + + @Test(expected = NullPointerException.class) + public void mergeIterableNull() { + Observable.merge(128, 128, (Iterable>)null); + } + + @Test(expected = NullPointerException.class) + public void mergeIterableIteratorNull() { + Observable.merge(128, 128, new Iterable>() { + @Override + public Iterator> iterator() { + return null; + } + }).toBlocking().lastOption(); + } + + @SuppressWarnings("unchecked") + @Test(expected = NullPointerException.class) + public void mergeIterableOneIsNull() { + Observable.merge(128, 128, Arrays.asList(just1, null)).toBlocking().lastOption(); + } + + @Test(expected = NullPointerException.class) + public void mergeArrayNull() { + Observable.merge(128, 128, (Publisher[])null); + } + + @SuppressWarnings("unchecked") + @Test(expected = NullPointerException.class) + public void mergeArrayOneIsNull() { + Observable.merge(128, 128, just1, null).toBlocking().lastOption(); + } + + @Test(expected = NullPointerException.class) + public void mergeDelayErrorIterableNull() { + Observable.mergeDelayError(128, 128, (Iterable>)null); + } + + @Test(expected = NullPointerException.class) + public void mergeDelayErrorIterableIteratorNull() { + Observable.mergeDelayError(128, 128, new Iterable>() { + @Override + public Iterator> iterator() { + return null; + } + }).toBlocking().lastOption(); + } + + @SuppressWarnings("unchecked") + @Test(expected = NullPointerException.class) + public void mergeDelayErrorIterableOneIsNull() { + Observable.mergeDelayError(128, 128, Arrays.asList(just1, null)).toBlocking().lastOption(); + } + + @Test(expected = NullPointerException.class) + public void mergeDelayErrorArrayNull() { + Observable.mergeDelayError(128, 128, (Publisher[])null); + } + + @SuppressWarnings("unchecked") + @Test(expected = NullPointerException.class) + public void mergeDelayErrorArrayOneIsNull() { + Observable.mergeDelayError(128, 128, just1, null).toBlocking().lastOption(); + } + + @Test(expected = NullPointerException.class) + public void sequenceEqualFirstNull() { + Observable.sequenceEqual(null, just1); + } + + @Test(expected = NullPointerException.class) + public void sequenceEqualSecondNull() { + Observable.sequenceEqual(just1, null); + } + + @Test(expected = NullPointerException.class) + public void sequenceEqualComparatorNull() { + Observable.sequenceEqual(just1, just1, null); + } + + @Test(expected = NullPointerException.class) + public void switchOnNextNull() { + Observable.switchOnNext(null); + } + + @Test(expected = NullPointerException.class) + public void timerUnitNull() { + Observable.timer(1, null); + } + + @Test(expected = NullPointerException.class) + public void timerSchedulerNull() { + Observable.timer(1, TimeUnit.SECONDS, null); + } + + @Test(expected = NullPointerException.class) + public void usingResourceSupplierNull() { + Observable.using(null, new Function>() { + @Override + public Publisher apply(Object d) { + return just1; + } + }, Functions.emptyConsumer()); + } + + @Test(expected = NullPointerException.class) + public void usingObservableSupplierNull() { + Observable.using(new Supplier() { + @Override + public Object get() { + return 1; + } + }, null, Functions.emptyConsumer()); + } + + @Test(expected = NullPointerException.class) + public void usingObservableSupplierReturnsNull() { + Observable.using(new Supplier() { + @Override + public Object get() { + return 1; + } + }, new Function>() { + @Override + public Publisher apply(Object d) { + return null; + } + }, Functions.emptyConsumer()).toBlocking().lastOption(); + } + + @Test(expected = NullPointerException.class) + public void usingDisposeNull() { + Observable.using(new Supplier() { + @Override + public Object get() { + return 1; + } + }, new Function>() { + @Override + public Publisher apply(Object d) { + return just1; + } + }, null); + } + + @Test(expected = NullPointerException.class) + public void zipIterableNull() { + Observable.zip((Iterable>)null, new Function() { + @Override + public Object apply(Object[] v) { + return 1; + } + }); + } + + @Test(expected = NullPointerException.class) + public void zipIterableIteratorNull() { + Observable.zip(new Iterable>() { + @Override + public Iterator> iterator() { + return null; + } + }, new Function() { + @Override + public Object apply(Object[] v) { + return 1; + } + }).toBlocking().lastOption(); + } + + @SuppressWarnings("unchecked") + @Test(expected = NullPointerException.class) + public void zipIterableFunctionNull() { + Observable.zip(Arrays.asList(just1, just1), null); + } + + @SuppressWarnings("unchecked") + @Test(expected = NullPointerException.class) + public void zipIterableFunctionReturnsNull() { + Observable.zip(Arrays.asList(just1, just1), new Function() { + @Override + public Object apply(Object[] a) { + return null; + } + }).toBlocking().lastOption(); + } + + @Test(expected = NullPointerException.class) + public void zipPublisherNull() { + Observable.zip((Publisher>)null, new Function() { + @Override + public Object apply(Object[] a) { + return 1; + } + }); + } + + @Test(expected = NullPointerException.class) + public void zipPublisherFunctionNull() { + Observable.zip((Observable.just(just1)), null); + } + + @Test(expected = NullPointerException.class) + public void zipPublisherFunctionReturnsNull() { + Observable.zip((Observable.just(just1)), new Function() { + @Override + public Object apply(Object[] a) { + return null; + } + }).toBlocking().lastOption(); + } + + @Test(expected = NullPointerException.class) + public void zipIterable2Null() { + Observable.zipIterable(new Function() { + @Override + public Object apply(Object[] a) { + return 1; + } + }, true, 128, (Iterable>)null); + } + + @Test(expected = NullPointerException.class) + public void zipIterable2IteratorNull() { + Observable.zipIterable(new Function() { + @Override + public Object apply(Object[] a) { + return 1; + } + }, true, 128, new Iterable>() { + @Override + public Iterator> iterator() { + return null; + } + }).toBlocking().lastOption(); + } + + @SuppressWarnings("unchecked") + @Test(expected = NullPointerException.class) + public void zipIterable2FunctionNull() { + Observable.zipIterable(null, true, 128, Arrays.asList(just1, just1)); + } + + @SuppressWarnings("unchecked") + @Test(expected = NullPointerException.class) + public void zipIterable2FunctionReturnsNull() { + Observable.zipIterable(new Function() { + @Override + public Object apply(Object[] a) { + return null; + } + }, true, 128, Arrays.asList(just1, just1)).toBlocking().lastOption(); + } + + //************************************************************* + // Instance methods + //************************************************************* + + @Test(expected = NullPointerException.class) + public void allPredicateNull() { + just1.all(null); + } + + @Test(expected = NullPointerException.class) + public void ambWithNull() { + just1.ambWith(null); + } + + @Test(expected = NullPointerException.class) + public void anyPredicateNull() { + just1.any(null); + } + + @Test(expected = NullPointerException.class) + public void bufferSupplierNull() { + just1.buffer(1, 1, (Supplier>)null); + } + + @Test(expected = NullPointerException.class) + public void bufferSupplierReturnsNull() { + just1.buffer(1, 1, new Supplier>() { + @Override + public Collection get() { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void bufferTimedUnitNull() { + just1.buffer(1L, 1L, null); + } + + @Test(expected = NullPointerException.class) + public void bufferTimedSchedulerNull() { + just1.buffer(1L, 1L, TimeUnit.SECONDS, null); + } + + @Test(expected = NullPointerException.class) + public void bufferTimedSupplierNull() { + just1.buffer(1L, 1L, TimeUnit.SECONDS, Schedulers.single(), null); + } + + @Test(expected = NullPointerException.class) + public void bufferTimedSupplierReturnsNull() { + just1.buffer(1L, 1L, TimeUnit.SECONDS, Schedulers.single(), new Supplier>() { + @Override + public Collection get() { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void bufferOpenCloseOpenNull() { + just1.buffer(null, new Function>() { + @Override + public Publisher apply(Object o) { + return just1; + } + }); + } + + @Test(expected = NullPointerException.class) + public void bufferOpenCloseCloseNull() { + just1.buffer(just1, (Function>)null); + } + + @Test(expected = NullPointerException.class) + public void bufferOpenCloseCloseReturnsNull() { + just1.buffer(just1, new Function>() { + @Override + public Publisher apply(Integer v) { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void bufferBoundaryNull() { + just1.buffer((Publisher)null); + } + + @Test(expected = NullPointerException.class) + public void bufferBoundarySupplierNull() { + just1.buffer(just1, (Supplier>)null); + } + + @Test(expected = NullPointerException.class) + public void bufferBoundarySupplierReturnsNull() { + just1.buffer(just1, new Supplier>() { + @Override + public Collection get() { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void bufferBoundarySupplier2Null() { + just1.buffer((Supplier>)null); + } + + @Test(expected = NullPointerException.class) + public void bufferBoundarySupplier2ReturnsNull() { + just1.buffer(new Supplier>() { + @Override + public Publisher get() { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void bufferBoundarySupplier2SupplierNull() { + just1.buffer(new Supplier>() { + @Override + public Observable get() { + return just1; + } + }, null); + } + + @Test(expected = NullPointerException.class) + public void bufferBoundarySupplier2SupplierReturnsNull() { + just1.buffer(new Supplier>() { + @Override + public Observable get() { + return just1; + } + }, new Supplier>() { + @Override + public Collection get() { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void castNull() { + just1.cast(null); + } + + @Test(expected = NullPointerException.class) + public void collectInitialSupplierNull() { + just1.collect((Supplier)null, new BiConsumer() { + @Override + public void accept(Integer a, Integer b) { } + }); + } + + @Test(expected = NullPointerException.class) + public void collectInitialSupplierReturnsNull() { + just1.collect(new Supplier() { + @Override + public Object get() { + return null; + } + }, new BiConsumer() { + @Override + public void accept(Object a, Integer b) { } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void collectInitialCollectorNull() { + just1.collect(new Supplier() { + @Override + public Object get() { + return 1; + } + }, null); + } + + @Test(expected = NullPointerException.class) + public void collectIntoInitialNull() { + just1.collectInto(null, new BiConsumer() { + @Override + public void accept(Object a, Integer b) { } + }); + } + + @Test(expected = NullPointerException.class) + public void collectIntoCollectorNull() { + just1.collectInto(1, null); + } + + @Test(expected = NullPointerException.class) + public void composeNull() { + just1.compose(null); + } + + @Test(expected = NullPointerException.class) + public void concatMapNull() { + just1.concatMap(null); + } + + @Test(expected = NullPointerException.class) + public void concatMapReturnsNull() { + just1.concatMap(new Function>() { + @Override + public Publisher apply(Integer v) { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void concatMapIterableNull() { + just1.concatMapIterable(null); + } + + @Test(expected = NullPointerException.class) + public void concatMapIterableReturnNull() { + just1.concatMapIterable(new Function>() { + @Override + public Iterable apply(Integer v) { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void concatMapIterableIteratorNull() { + just1.concatMapIterable(new Function>() { + @Override + public Iterable apply(Integer v) { + return new Iterable() { + @Override + public Iterator iterator() { + return null; + } + }; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void concatWithNull() { + just1.concatWith(null); + } + + @Test(expected = NullPointerException.class) + public void containsNull() { + just1.contains(null); + } + + @Test(expected = NullPointerException.class) + public void debounceFunctionNull() { + just1.debounce(null); + } + + @Test(expected = NullPointerException.class) + public void debounceFunctionReturnsNull() { + just1.debounce(new Function>() { + @Override + public Publisher apply(Integer v) { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void debounceTimedUnitNull() { + just1.debounce(1, null); + } + + @Test(expected = NullPointerException.class) + public void debounceTimedSchedulerNull() { + just1.debounce(1, TimeUnit.SECONDS, null); + } + + @Test(expected = NullPointerException.class) + public void defaultIfEmptyNull() { + just1.defaultIfEmpty(null); + } + + @Test(expected = NullPointerException.class) + public void delayWithFunctionNull() { + just1.delay(null); + } + + @Test(expected = NullPointerException.class) + public void delayWithFunctionReturnsNull() { + just1.delay(new Function>() { + @Override + public Publisher apply(Integer v) { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void delayTimedUnitNull() { + just1.delay(1, null); + } + + @Test(expected = NullPointerException.class) + public void delayTimedSchedulerNull() { + just1.delay(1, TimeUnit.SECONDS, null); + } + + @Test(expected = NullPointerException.class) + public void delaySubscriptionTimedUnitNull() { + just1.delaySubscription(1, null); + } + + @Test(expected = NullPointerException.class) + public void delaySubscriptionTimedSchedulerNull() { + just1.delaySubscription(1, TimeUnit.SECONDS, null); + } + + @Test(expected = NullPointerException.class) + public void delaySubscriptionSupplierNull() { + just1.delaySubscription((Supplier>)null); + } + + @Test(expected = NullPointerException.class) + public void delaySubscriptionFunctionNull() { + just1.delaySubscription((Publisher)null); + } + + @Test(expected = NullPointerException.class) + public void delayBothInitialSupplierNull() { + just1.delay(null, new Function>() { + @Override + public Publisher apply(Integer v) { + return just1; + } + }); + } + + @Test(expected = NullPointerException.class) + public void delayBothInitialSupplierReturnsNull() { + just1.delay(new Supplier>() { + @Override + public Publisher get() { + return null; + } + }, new Function>() { + @Override + public Publisher apply(Integer v) { + return just1; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void delayBothItemSupplierNull() { + just1.delay(new Supplier>() { + @Override + public Publisher get() { + return just1; + } + }, null); + } + + @Test(expected = NullPointerException.class) + public void delayBothItemSupplierReturnsNull() { + just1.delay(new Supplier>() { + @Override + public Publisher get() { + return just1; + } + }, new Function>() { + @Override + public Publisher apply(Integer v) { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void distinctFunctionNull() { + just1.distinct(null); + } + + @Test(expected = NullPointerException.class) + public void distinctSupplierNull() { + just1.distinct(new Function() { + @Override + public Object apply(Integer v) { + return v; + } + }, null); + } + + @Test(expected = NullPointerException.class) + public void distinctSupplierReturnsNull() { + just1.distinct(new Function() { + @Override + public Object apply(Integer v) { + return v; + } + }, new Supplier>() { + @Override + public Collection get() { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void distinctFunctionReturnsNull() { + just1.distinct(new Function() { + @Override + public Object apply(Integer v) { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void distinctUntilChangedFunctionNull() { + just1.distinctUntilChanged(null); + } + + @Test(expected = NullPointerException.class) + public void distinctUntilChangedFunctionReturnsNull() { + just1.distinctUntilChanged(new Function() { + @Override + public Object apply(Integer v) { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void doOnCancelNull() { + just1.doOnCancel(null); + } + + @Test(expected = NullPointerException.class) + public void doOnCompleteNull() { + just1.doOnComplete(null); + } + + @Test(expected = NullPointerException.class) + public void doOnEachSupplierNull() { + just1.doOnEach((Consumer>>)null); + } + + @Test(expected = NullPointerException.class) + public void doOnEachSubscriberNull() { + just1.doOnEach((Subscriber)null); + } + + @Test(expected = NullPointerException.class) + public void doOnErrorNull() { + just1.doOnError(null); + } + + @Test(expected = NullPointerException.class) + public void doOnLifecycleOnSubscribeNull() { + just1.doOnLifecycle(null, new LongConsumer() { + @Override + public void accept(long v) { } + }, new Runnable() { + @Override + public void run() { } + }); + } + + @Test(expected = NullPointerException.class) + public void doOnLifecycleOnRequestNull() { + just1.doOnLifecycle(new Consumer() { + @Override + public void accept(Subscription s) { } + }, null, new Runnable() { + @Override + public void run() { } + }); + } + + @Test(expected = NullPointerException.class) + public void doOnLifecycleOnCancelNull() { + just1.doOnLifecycle(new Consumer() { + @Override + public void accept(Subscription s) { } + }, new LongConsumer() { + @Override + public void accept(long v) { } + }, null); + } + + @Test(expected = NullPointerException.class) + public void doOnNextNull() { + just1.doOnNext(null); + } + + @Test(expected = NullPointerException.class) + public void doOnRequestNull() { + just1.doOnRequest(null); + } + + @Test(expected = NullPointerException.class) + public void doOnSubscribeNull() { + just1.doOnSubscribe(null); + } + + @Test(expected = NullPointerException.class) + public void doOnTerminatedNull() { + just1.doOnTerminate(null); + } + + @Test(expected = NullPointerException.class) + public void elementAtNull() { + just1.elementAt(1, null); + } + + @Test(expected = NullPointerException.class) + public void endWithIterableNull() { + just1.endWith((Iterable)null); + } + + @Test(expected = NullPointerException.class) + public void endWithIterableIteratorNull() { + just1.endWith(new Iterable() { + @Override + public Iterator iterator() { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void endWithIterableOneIsNull() { + just1.endWith(Arrays.asList(1, null)).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void endWithPublisherNull() { + just1.endWith((Publisher)null); + } + + @Test(expected = NullPointerException.class) + public void endWithNull() { + just1.endWith((Integer)null); + } + + @Test(expected = NullPointerException.class) + public void endWithArrayNull() { + just1.endWithArray((Integer[])null); + } + + @Test(expected = NullPointerException.class) + public void endWithArrayOneIsNull() { + just1.endWithArray(1, null).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void filterNull() { + just1.filter(null); + } + + @Test(expected = NullPointerException.class) + public void finallyDoNull() { + just1.finallyDo(null); + } + + @Test(expected = NullPointerException.class) + public void firstNull() { + just1.first(null); + } + + @Test(expected = NullPointerException.class) + public void flatMapNull() { + just1.flatMap(null); + } + + @Test(expected = NullPointerException.class) + public void flatMapFunctionReturnsNull() { + just1.flatMap(new Function>() { + @Override + public Publisher apply(Integer v) { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void flatMapNotificationOnNextNull() { + just1.flatMap(null, new Function>() { + @Override + public Publisher apply(Throwable e) { + return just1; + } + }, new Supplier>() { + @Override + public Publisher get() { + return just1; + } + }); + } + + @Test(expected = NullPointerException.class) + public void flatMapNotificationOnNextReturnsNull() { + just1.flatMap(new Function>() { + @Override + public Publisher apply(Integer v) { + return null; + } + }, new Function>() { + @Override + public Publisher apply(Throwable e) { + return just1; + } + }, new Supplier>() { + @Override + public Publisher get() { + return just1; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void flatMapNotificationOnErrorNull() { + just1.flatMap(new Function>() { + @Override + public Publisher apply(Integer v) { + return just1; + } + }, null, new Supplier>() { + @Override + public Publisher get() { + return just1; + } + }); + } + + @Test(expected = NullPointerException.class) + public void flatMapNotificationOnErrorReturnsNull() { + Observable.error(new TestException()).flatMap(new Function>() { + @Override + public Publisher apply(Object v) { + return just1; + } + }, new Function>() { + @Override + public Publisher apply(Throwable e) { + return null; + } + }, new Supplier>() { + @Override + public Publisher get() { + return just1; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void flatMapNotificationOnCompleteNull() { + just1.flatMap(new Function>() { + @Override + public Publisher apply(Integer v) { + return just1; + } + }, new Function>() { + @Override + public Publisher apply(Throwable e) { + return just1; + } + }, null); + } + + @Test(expected = NullPointerException.class) + public void flatMapNotificationOnCompleteReturnsNull() { + just1.flatMap(new Function>() { + @Override + public Publisher apply(Integer v) { + return just1; + } + }, new Function>() { + @Override + public Publisher apply(Throwable e) { + return just1; + } + }, new Supplier>() { + @Override + public Publisher get() { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void flatMapCombinerMapperNull() { + just1.flatMap(null, new BiFunction() { + @Override + public Object apply(Integer a, Object b) { + return 1; + } + }); + } + + @Test(expected = NullPointerException.class) + public void flatMapCombinerMapperReturnsNull() { + just1.flatMap(new Function>() { + @Override + public Publisher apply(Integer v) { + return null; + } + }, new BiFunction() { + @Override + public Object apply(Integer a, Object b) { + return 1; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void flatMapCombinerCombinerNull() { + just1.flatMap(new Function>() { + @Override + public Publisher apply(Integer v) { + return just1; + } + }, null); + } + + @Test(expected = NullPointerException.class) + public void flatMapCombinerCombinerReturnsNull() { + just1.flatMap(new Function>() { + @Override + public Publisher apply(Integer v) { + return just1; + } + }, new BiFunction() { + @Override + public Object apply(Integer a, Integer b) { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void flatMapIterableMapperNull() { + just1.flatMapIterable(null); + } + + @Test(expected = NullPointerException.class) + public void flatMapIterableMapperReturnsNull() { + just1.flatMapIterable(new Function>() { + @Override + public Iterable apply(Integer v) { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void flatMapIterableMapperIteratorNull() { + just1.flatMapIterable(new Function>() { + @Override + public Iterable apply(Integer v) { + return new Iterable() { + @Override + public Iterator iterator() { + return null; + } + }; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void flatMapIterableMapperIterableOneNull() { + just1.flatMapIterable(new Function>() { + @Override + public Iterable apply(Integer v) { + return Arrays.asList(1, null); + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void flatMapIterableCombinerNull() { + just1.flatMapIterable(new Function>() { + @Override + public Iterable apply(Integer v) { + return Arrays.asList(1); + } + }, null); + } + + @Test(expected = NullPointerException.class) + public void flatMapIterableCombinerReturnsNull() { + just1.flatMapIterable(new Function>() { + @Override + public Iterable apply(Integer v) { + return Arrays.asList(1); + } + }, new BiFunction() { + @Override + public Object apply(Integer a, Integer b) { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void forEachNull() { + just1.forEach(null); + } + + @Test(expected = NullPointerException.class) + public void forEachWhileNull() { + just1.forEachWhile(null); + } + + @Test(expected = NullPointerException.class) + public void forEachWhileOnErrorNull() { + just1.forEachWhile(new Predicate() { + @Override + public boolean test(Integer v) { + return true; + } + }, null); + } + + @Test(expected = NullPointerException.class) + public void forEachWhileOnCompleteNull() { + just1.forEachWhile(new Predicate() { + @Override + public boolean test(Integer v) { + return true; + } + }, new Consumer() { + @Override + public void accept(Throwable e) { } + }, null); + } + + @Test(expected = NullPointerException.class) + public void groupByNull() { + just1.groupBy(null); + } + + public void groupByKeyNull() { + just1.groupBy(new Function() { + @Override + public Object apply(Integer v) { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void groupByValueNull() { + just1.groupBy(new Function() { + @Override + public Object apply(Integer v) { + return v; + } + }, null); + } + + @Test(expected = NullPointerException.class) + public void groupByValueReturnsNull() { + just1.groupBy(new Function() { + @Override + public Object apply(Integer v) { + return v; + } + }, new Function() { + @Override + public Object apply(Integer v) { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void lastNull() { + just1.last(null); + } + + @Test(expected = NullPointerException.class) + public void liftNull() { + just1.lift(null); + } + + @Test(expected = NullPointerException.class) + public void liftReturnsNull() { + just1.lift(new Operator() { + @Override + public Subscriber apply(Subscriber s) { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void mapNull() { + just1.map(null); + } + + @Test(expected = NullPointerException.class) + public void mapReturnsNull() { + just1.map(new Function() { + @Override + public Object apply(Integer v) { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void mergeWithNull() { + just1.mergeWith(null); + } + + @Test(expected = NullPointerException.class) + public void observeOnNull() { + just1.observeOn(null); + } + + @Test(expected = NullPointerException.class) + public void ofTypeNull() { + just1.ofType(null); + } + + @Test(expected = NullPointerException.class) + public void onBackpressureBufferOverflowNull() { + just1.onBackpressureBuffer(10, null); + } + + @Test(expected = NullPointerException.class) + public void onBackpressureDropActionNull() { + just1.onBackpressureDrop(null); + } + + @Test(expected = NullPointerException.class) + public void onErrorResumeNextFunctionNull() { + just1.onErrorResumeNext((Function>)null); + } + + @Test(expected = NullPointerException.class) + public void onErrorResumeNextFunctionReturnsNull() { + Observable.error(new TestException()).onErrorResumeNext(new Function>() { + @Override + public Publisher apply(Throwable e) { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void onErrorResumeNextPublisherNull() { + just1.onErrorResumeNext((Publisher)null); + } + + @Test(expected = NullPointerException.class) + public void onErrorReturnFunctionNull() { + just1.onErrorReturn(null); + } + + @Test(expected = NullPointerException.class) + public void onErrorReturnValueNull() { + just1.onErrorReturnValue(null); + } + + @Test(expected = NullPointerException.class) + public void onErrorReturnFunctionReturnsNull() { + Observable.error(new TestException()).onErrorReturn(new Function() { + @Override + public Object apply(Throwable e) { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void onExceptionResumeNext() { + just1.onExceptionResumeNext(null); + } + + @Test(expected = NullPointerException.class) + public void publishFunctionNull() { + just1.publish(null); + } + + @Test(expected = NullPointerException.class) + public void publishFunctionReturnsNull() { + just1.publish(new Function, Publisher>() { + @Override + public Publisher apply(Observable v) { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void reduceFunctionNull() { + just1.reduce(null); + } + + @Test(expected = NullPointerException.class) + public void reduceFunctionReturnsNull() { + Observable.just(1, 1).reduce(new BiFunction() { + @Override + public Integer apply(Integer a, Integer b) { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void reduceSeedNull() { + just1.reduce(null, new BiFunction() { + @Override + public Object apply(Object a, Integer b) { + return 1; + } + }); + } + + @Test(expected = NullPointerException.class) + public void reduceSeedFunctionNull() { + just1.reduce(1, null); + } + + @Test(expected = NullPointerException.class) + public void reduceSeedFunctionReturnsNull() { + just1.reduce(1, new BiFunction() { + @Override + public Integer apply(Integer a, Integer b) { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void reduceWithSeedNull() { + just1.reduceWith(null, new BiFunction() { + @Override + public Object apply(Object a, Integer b) { + return 1; + } + }); + } + + @Test(expected = NullPointerException.class) + public void reduceWithSeedReturnsNull() { + just1.reduceWith(new Supplier() { + @Override + public Object get() { + return null; + } + }, new BiFunction() { + @Override + public Object apply(Object a, Integer b) { + return 1; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void repeatUntilNull() { + just1.repeatUntil(null); + } + + @Test(expected = NullPointerException.class) + public void repeatWhenNull() { + just1.repeatWhen(null); + } + + @Test(expected = NullPointerException.class) + public void repeatWhenFunctionReturnsNull() { + just1.repeatWhen(new Function, Publisher>() { + @Override + public Publisher apply(Observable v) { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void replaySelectorNull() { + just1.replay((Function, Observable>)null); + } + + @Test(expected = NullPointerException.class) + public void replaySelectorReturnsNull() { + just1.replay(new Function, Publisher>() { + @Override + public Publisher apply(Observable o) { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void replayBoundedSelectorNull() { + just1.replay((Function, Observable>)null, 1, 1, TimeUnit.SECONDS); + } + + @Test(expected = NullPointerException.class) + public void replayBoundedSelectorReturnsNull() { + just1.replay(new Function, Publisher>() { + @Override + public Publisher apply(Observable v) { + return null; + } + }, 1, 1, TimeUnit.SECONDS).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void replaySchedulerNull() { + just1.replay((Scheduler)null); + } + + @Test(expected = NullPointerException.class) + public void replayBoundedUnitNull() { + just1.replay(new Function, Publisher>() { + @Override + public Publisher apply(Observable v) { + return v; + } + }, 1, 1, null).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void replayBoundedSchedulerNull() { + just1.replay(new Function, Publisher>() { + @Override + public Publisher apply(Observable v) { + return v; + } + }, 1, 1, TimeUnit.SECONDS, null).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void replayTimeBoundedSelectorNull() { + just1.replay(null, 1, TimeUnit.SECONDS, Schedulers.single()); + } + + @Test(expected = NullPointerException.class) + public void replayTimeBoundedSelectorReturnsNull() { + just1.replay(new Function, Publisher>() { + @Override + public Publisher apply(Observable v) { + return null; + } + }, 1, TimeUnit.SECONDS, Schedulers.single()).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void replaySelectorTimeBoundedUnitNull() { + just1.replay(new Function, Publisher>() { + @Override + public Publisher apply(Observable v) { + return v; + } + }, 1, null, Schedulers.single()); + } + + @Test(expected = NullPointerException.class) + public void replaySelectorTimeBoundedSchedulerNull() { + just1.replay(new Function, Publisher>() { + @Override + public Publisher apply(Observable v) { + return v; + } + }, 1, TimeUnit.SECONDS, null); + } + + @Test(expected = NullPointerException.class) + public void replayTimeSizeBoundedUnitNull() { + just1.replay(1, 1, null, Schedulers.single()); + } + + @Test(expected = NullPointerException.class) + public void replayTimeSizeBoundedSchedulerNull() { + just1.replay(1, 1, TimeUnit.SECONDS, null); + } + + @Test(expected = NullPointerException.class) + public void replayBufferSchedulerNull() { + just1.replay(1, (Scheduler)null); + } + + @Test(expected = NullPointerException.class) + public void replayTimeBoundedUnitNull() { + just1.replay(1, null, Schedulers.single()); + } + + @Test(expected = NullPointerException.class) + public void replayTimeBoundedSchedulerNull() { + just1.replay(1, TimeUnit.SECONDS, null); + } + + @Test(expected = NullPointerException.class) + public void retryFunctionNull() { + just1.retry((BiPredicate)null); + } + + @Test(expected = NullPointerException.class) + public void retryCountFunctionNull() { + just1.retry(1, null); + } + + @Test(expected = NullPointerException.class) + public void retryPredicateNull() { + just1.retry((Predicate)null); + } + + @Test(expected = NullPointerException.class) + public void retryWhenFunctionNull() { + just1.retryWhen(null); + } + + @Test(expected = NullPointerException.class) + public void retryWhenFunctionReturnsNull() { + Observable.error(new TestException()).retryWhen(new Function, Publisher>() { + @Override + public Publisher apply(Observable f) { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void retryUntil() { + just1.retryUntil(null); + } + + @Test(expected = NullPointerException.class) + public void safeSubscribeNull() { + just1.safeSubscribe(null); + } + + @Test(expected = NullPointerException.class) + public void sampleUnitNull() { + just1.sample(1, null); + } + + @Test(expected = NullPointerException.class) + public void sampleSchedulerNull() { + just1.sample(1, TimeUnit.SECONDS, null); + } + + @Test(expected = NullPointerException.class) + public void samplePublisherNull() { + just1.sample(null); + } + + @Test(expected = NullPointerException.class) + public void scanFunctionNull() { + just1.scan(null); + } + + @Test(expected = NullPointerException.class) + public void scanFunctionReturnsNull() { + Observable.just(1, 1).scan(new BiFunction() { + @Override + public Integer apply(Integer a, Integer b) { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void scanSeedNull() { + just1.scan(null, new BiFunction() { + @Override + public Object apply(Object a, Integer b) { + return 1; + } + }); + } + + @Test(expected = NullPointerException.class) + public void scanSeedFunctionNull() { + just1.scan(1, null); + } + + @Test(expected = NullPointerException.class) + public void scanSeedFunctionReturnsNull() { + just1.scan(1, new BiFunction() { + @Override + public Integer apply(Integer a, Integer b) { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void scanSeedSupplierNull() { + just1.scanWith(null, new BiFunction() { + @Override + public Object apply(Object a, Integer b) { + return 1; + } + }); + } + + @Test(expected = NullPointerException.class) + public void scanSeedSupplierReturnsNull() { + just1.scanWith(new Supplier() { + @Override + public Object get() { + return null; + } + }, new BiFunction() { + @Override + public Object apply(Object a, Integer b) { + return 1; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void scanSeedSupplierFunctionNull() { + just1.scanWith(new Supplier() { + @Override + public Object get() { + return 1; + } + }, null); + } + + @Test(expected = NullPointerException.class) + public void scanSeedSupplierFunctionReturnsNull() { + just1.scanWith(new Supplier() { + @Override + public Object get() { + return 1; + } + }, new BiFunction() { + @Override + public Object apply(Object a, Integer b) { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void singleNull() { + just1.single(null); + } + + @Test(expected = NullPointerException.class) + public void skipTimedUnitNull() { + just1.skip(1, null, Schedulers.single()); + } + + @Test(expected = NullPointerException.class) + public void skipTimedSchedulerNull() { + just1.skip(1, TimeUnit.SECONDS, null); + } + + @Test(expected = NullPointerException.class) + public void skipLastTimedUnitNull() { + just1.skipLast(1, null, Schedulers.single()); + } + + @Test(expected = NullPointerException.class) + public void skipLastTimedSchedulerNull() { + just1.skipLast(1, TimeUnit.SECONDS, null); + } + + @Test(expected = NullPointerException.class) + public void skipUntilNull() { + just1.skipUntil(null); + } + + @Test(expected = NullPointerException.class) + public void skipWhileNull() { + just1.skipWhile(null); + } + + @Test(expected = NullPointerException.class) + public void startWithIterableNull() { + just1.startWith((Iterable)null); + } + + @Test(expected = NullPointerException.class) + public void startWithIterableIteratorNull() { + just1.startWith(new Iterable() { + @Override + public Iterator iterator() { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void startWithIterableOneNull() { + just1.startWith(Arrays.asList(1, null)).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void startWithSingleNull() { + just1.startWith((Integer)null); + } + + @Test(expected = NullPointerException.class) + public void startWithPublisherNull() { + just1.startWith((Publisher)null); + } + + @Test(expected = NullPointerException.class) + public void startWithArrayNull() { + just1.startWithArray((Integer[])null); + } + + @Test(expected = NullPointerException.class) + public void startWithArrayOneNull() { + just1.startWithArray(1, null).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void subscribeOnNextNull() { + just1.subscribe((Consumer)null); + } + + @Test(expected = NullPointerException.class) + public void subscribeOnErrorNull() { + just1.subscribe(Functions.emptyConsumer(), null); + } + + @Test(expected = NullPointerException.class) + public void subscribeOnCompleteNull() { + just1.subscribe(Functions.emptyConsumer(), Functions.emptyConsumer(), null); + } + + @Test(expected = NullPointerException.class) + public void subscribeOnSubscribeNull() { + just1.subscribe(Functions.emptyConsumer(), Functions.emptyConsumer(), Functions.emptyRunnable(), null); + } + + @Test(expected = NullPointerException.class) + public void subscribeNull() { + just1.subscribe((Subscriber)null); + } + + @Test(expected = NullPointerException.class) + public void subscribeOnNull() { + just1.subscribeOn(null); + } + + @Test(expected = NullPointerException.class) + public void switchIfEmptyNull() { + just1.switchIfEmpty(null); + } + + @Test(expected = NullPointerException.class) + public void switchMapNull() { + just1.switchMap(null); + } + + @Test(expected = NullPointerException.class) + public void switchMapFunctionReturnsNull() { + just1.switchMap(new Function>() { + @Override + public Publisher apply(Integer v) { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void takeTimedUnitNull() { + just1.take(1, null, Schedulers.single()); + } + + @Test(expected = NullPointerException.class) + public void takeTimedSchedulerNull() { + just1.take(1, TimeUnit.SECONDS, null); + } + + @Test(expected = NullPointerException.class) + public void takeFirstNull() { + just1.takeFirst(null); + } + + @Test(expected = NullPointerException.class) + public void takeLastTimedUnitNull() { + just1.takeLast(1, null, Schedulers.single()); + } + + @Test(expected = NullPointerException.class) + public void takeLastSizeTimedUnitNull() { + just1.takeLast(1, 1, null, Schedulers.single()); + } + + @Test(expected = NullPointerException.class) + public void takeLastTimedSchedulerNull() { + just1.takeLast(1, TimeUnit.SECONDS, null); + } + + @Test(expected = NullPointerException.class) + public void takeLastSizeTimedSchedulerNull() { + just1.takeLast(1, 1, TimeUnit.SECONDS, null); + } + + @Test(expected = NullPointerException.class) + public void takeLastBufferTimedUnitNull() { + just1.takeLastBuffer(1, null, Schedulers.single()); + } + + @Test(expected = NullPointerException.class) + public void takeLastBufferTimedSchedulerNull() { + just1.takeLastBuffer(1, TimeUnit.SECONDS, null); + } + + @Test(expected = NullPointerException.class) + public void takeLastBufferSizeTimedUnitNull() { + just1.takeLastBuffer(1, 1, null, Schedulers.single()); + } + + @Test(expected = NullPointerException.class) + public void takeLastBufferSizeTimedSchedulerNull() { + just1.takeLastBuffer(1, 1, TimeUnit.SECONDS, null); + } + + @Test(expected = NullPointerException.class) + public void takeUntilPredicateNull() { + just1.takeUntil((Predicate)null); + } + + @Test(expected = NullPointerException.class) + public void takeUntilPublisherNull() { + just1.takeUntil((Publisher)null); + } + + @Test(expected = NullPointerException.class) + public void takeWhileNull() { + just1.takeWhile(null); + } + + @Test(expected = NullPointerException.class) + public void throttleFirstUnitNull() { + just1.throttleFirst(1, null, Schedulers.single()); + } + + @Test(expected = NullPointerException.class) + public void throttleFirstSchedulerNull() { + just1.throttleFirst(1, TimeUnit.SECONDS, null); + } + + @Test(expected = NullPointerException.class) + public void throttleLastUnitNull() { + just1.throttleLast(1, null, Schedulers.single()); + } + + @Test(expected = NullPointerException.class) + public void throttleLastSchedulerNull() { + just1.throttleLast(1, TimeUnit.SECONDS, null); + } + + @Test(expected = NullPointerException.class) + public void throttleWithTimeoutUnitNull() { + just1.throttleWithTimeout(1, null, Schedulers.single()); + } + + @Test(expected = NullPointerException.class) + public void throttleWithTimeoutSchedulerNull() { + just1.throttleWithTimeout(1, TimeUnit.SECONDS, null); + } + + @Test(expected = NullPointerException.class) + public void timeIntervalUnitNull() { + just1.timeInterval(null, Schedulers.single()); + } + + @Test(expected = NullPointerException.class) + public void timeIntervalSchedulerNull() { + just1.timeInterval(TimeUnit.SECONDS, null); + } + + @Test(expected = NullPointerException.class) + public void timeoutSelectorNull() { + just1.timeout(null); + } + + @Test(expected = NullPointerException.class) + public void timeoutSelectorReturnsNull() { + just1.timeout(new Function>() { + @Override + public Publisher apply(Integer v) { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void timeoutSelectorOtherNull() { + just1.timeout(new Function>() { + @Override + public Publisher apply(Integer v) { + return just1; + } + }, null); + } + + @Test(expected = NullPointerException.class) + public void timeoutUnitNull() { + just1.timeout(1, null, just1, Schedulers.single()); + } + + @Test(expected = NullPointerException.class) + public void timeouOtherNull() { + just1.timeout(1, TimeUnit.SECONDS, null, Schedulers.single()); + } + + @Test(expected = NullPointerException.class) + public void timeouSchedulerNull() { + just1.timeout(1, TimeUnit.SECONDS, just1, null); + } + + @Test(expected = NullPointerException.class) + public void timeoutFirstNull() { + just1.timeout((Supplier>)null, new Function>() { + @Override + public Publisher apply(Integer v) { + return just1; + } + }); + } + + @Test(expected = NullPointerException.class) + public void timeoutFirstReturnsNull() { + just1.timeout(new Supplier>() { + @Override + public Publisher get() { + return null; + } + }, new Function>() { + @Override + public Publisher apply(Integer v) { + return just1; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void timeoutFirstItemNull() { + just1.timeout(new Supplier>() { + @Override + public Publisher get() { + return just1; + } + }, null); + } + + @Test(expected = NullPointerException.class) + public void timeoutFirstItemReturnsNull() { + just1.timeout(new Supplier>() { + @Override + public Publisher get() { + return just1; + } + }, new Function>() { + @Override + public Publisher apply(Integer v) { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void timestampUnitNull() { + just1.timestamp(null, Schedulers.single()); + } + + @Test(expected = NullPointerException.class) + public void timestampSchedulerNull() { + just1.timestamp(TimeUnit.SECONDS, null); + } + + @Test(expected = NullPointerException.class) + public void toNull() { + just1.to(null); + } + + @Test(expected = NullPointerException.class) + public void toListNull() { + just1.toList(null); + } + + @Test(expected = NullPointerException.class) + public void toListSupplierReturnsNull() { + just1.toList(new Supplier>() { + @Override + public Collection get() { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void toSortedListNull() { + just1.toSortedList(null); + } + + @Test(expected = NullPointerException.class) + public void toMapKeyNullAllowed() { + just1.toMap(null); + } + + @Test(expected = NullPointerException.class) + public void toMapValueNull() { + just1.toMap(new Function() { + @Override + public Object apply(Integer v) { + return v; + } + }, null); + } + + @Test + public void toMapValueSelectorReturnsNull() { + just1.toMap(new Function() { + @Override + public Object apply(Integer v) { + return v; + } + }, new Function() { + @Override + public Object apply(Integer v) { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void toMapMapSupplierNull() { + just1.toMap(new Function() { + @Override + public Object apply(Integer v) { + return v; + } + }, new Function() { + @Override + public Object apply(Integer v) { + return v; + } + }, null); + } + + @Test(expected = NullPointerException.class) + public void toMapMapSupplierReturnsNull() { + just1.toMap(new Function() { + @Override + public Object apply(Integer v) { + return v; + } + }, new Function() { + @Override + public Object apply(Integer v) { + return v; + } + }, new Supplier>() { + @Override + public Map get() { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void toMultimapKeyNull() { + just1.toMultimap(null); + } + + @Test(expected = NullPointerException.class) + public void toMultimapValueNull() { + just1.toMultimap(new Function() { + @Override + public Object apply(Integer v) { + return v; + } + }, null); + } + + @Test + public void toMultiMapValueSelectorReturnsNullAllowed() { + just1.toMap(new Function() { + @Override + public Object apply(Integer v) { + return v; + } + }, new Function() { + @Override + public Object apply(Integer v) { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void toMultimapMapMapSupplierNull() { + just1.toMultimap(new Function() { + @Override + public Object apply(Integer v) { + return v; + } + }, new Function() { + @Override + public Object apply(Integer v) { + return v; + } + }, null); + } + + @Test(expected = NullPointerException.class) + public void toMultimapMapSupplierReturnsNull() { + just1.toMultimap(new Function() { + @Override + public Object apply(Integer v) { + return v; + } + }, new Function() { + @Override + public Object apply(Integer v) { + return v; + } + }, new Supplier>>() { + @Override + public Map> get() { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void toMultimapMapMapCollectionSupplierNull() { + just1.toMultimap(new Function() { + @Override + public Integer apply(Integer v) { + return v; + } + }, new Function() { + @Override + public Integer apply(Integer v) { + return v; + } + }, new Supplier>>() { + @Override + public Map> get() { + return new HashMap>(); + } + }, null); + } + + @Test(expected = NullPointerException.class) + public void toMultimapMapCollectionSupplierReturnsNull() { + just1.toMultimap(new Function() { + @Override + public Integer apply(Integer v) { + return v; + } + }, new Function() { + @Override + public Integer apply(Integer v) { + return v; + } + }, new Supplier>>() { + @Override + public Map> get() { + return new HashMap>(); + } + }, new Function>() { + @Override + public Collection apply(Integer v) { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void unsafeSubscribeNull() { + just1.unsafeSubscribe(null); + } + + @Test(expected = NullPointerException.class) + public void unsubscribeOnNull() { + just1.unsubscribeOn(null); + } + + @Test(expected = NullPointerException.class) + public void windowTimedUnitNull() { + just1.window(1, null, Schedulers.single()); + } + + @Test(expected = NullPointerException.class) + public void windowSizeTimedUnitNull() { + just1.window(1, null, Schedulers.single(), 1); + } + + @Test(expected = NullPointerException.class) + public void windowTimedSchedulerNull() { + just1.window(1, TimeUnit.SECONDS, null); + } + + @Test(expected = NullPointerException.class) + public void windowSizeTimedSchedulerNull() { + just1.window(1, TimeUnit.SECONDS, null, 1); + } + + @Test(expected = NullPointerException.class) + public void windowBoundaryNull() { + just1.window((Publisher)null); + } + + @Test(expected = NullPointerException.class) + public void windowOpenCloseOpenNull() { + just1.window(null, new Function>() { + @Override + public Publisher apply(Object v) { + return just1; + } + }); + } + + @Test(expected = NullPointerException.class) + public void windowOpenCloseCloseNull() { + just1.window(just1, null); + } + + @Test(expected = NullPointerException.class) + public void windowOpenCloseCloseReturnsNull() { + Observable.never().window(just1, new Function>() { + @Override + public Publisher apply(Integer v) { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void windowBoundarySupplierNull() { + just1.window((Supplier>)null); + } + + @Test(expected = NullPointerException.class) + public void windowBoundarySupplierReturnsNull() { + just1.window(new Supplier>() { + @Override + public Publisher get() { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void withLatestFromOtherNull() { + just1.withLatestFrom(null, new BiFunction() { + @Override + public Object apply(Integer a, Object b) { + return 1; + } + }); + } + + @Test(expected = NullPointerException.class) + public void withLatestFromCombinerNull() { + just1.withLatestFrom(just1, null); + } + + @Test(expected = NullPointerException.class) + public void withLatestFromCombinerReturnsNull() { + just1.withLatestFrom(just1, new BiFunction() { + @Override + public Object apply(Integer a, Integer b) { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void zipWithIterableNull() { + just1.zipWith((Iterable)null, new BiFunction() { + @Override + public Object apply(Integer a, Integer b) { + return 1; + } + }); + } + + @Test(expected = NullPointerException.class) + public void zipWithIterableCombinerNull() { + just1.zipWith(Arrays.asList(1), null); + } + + @Test(expected = NullPointerException.class) + public void zipWithIterableCombinerReturnsNull() { + just1.zipWith(Arrays.asList(1), new BiFunction() { + @Override + public Object apply(Integer a, Integer b) { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void zipWithIterableIteratorNull() { + just1.zipWith(new Iterable() { + @Override + public Iterator iterator() { + return null; + } + }, new BiFunction() { + @Override + public Object apply(Integer a, Object b) { + return 1; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void zipWithIterableOneIsNull() { + Observable.just(1, 2).zipWith(Arrays.asList(1, null), new BiFunction() { + @Override + public Object apply(Integer a, Integer b) { + return 1; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void zipWithPublisherNull() { + just1.zipWith((Publisher)null, new BiFunction() { + @Override + public Object apply(Integer a, Integer b) { + return 1; + } + }); + } + + + @Test(expected = NullPointerException.class) + public void zipWithCombinerNull() { + just1.zipWith(just1, null); + } + + @Test(expected = NullPointerException.class) + public void zipWithCombinerReturnsNull() { + just1.zipWith(just1, new BiFunction() { + @Override + public Object apply(Integer a, Integer b) { + return null; + } + }).toBlocking().run(); + } + + //********************************************* + // Subject null tests + //********************************************* + + @Test(expected = NullPointerException.class) + public void asyncSubjectOnNextNull() { + Subject subject = AsyncSubject.create(); + subject.onNext(null); + subject.toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void asyncSubjectOnErrorNull() { + Subject subject = AsyncSubject.create(); + subject.onError(null); + subject.toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void behaviorSubjectOnNextNull() { + Subject subject = BehaviorSubject.create(); + subject.onNext(null); + subject.toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void behaviorSubjectOnErrorNull() { + Subject subject = BehaviorSubject.create(); + subject.onError(null); + subject.toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void publishSubjectOnNextNull() { + Subject subject = PublishSubject.create(); + subject.onNext(null); + subject.toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void publishSubjectOnErrorNull() { + Subject subject = PublishSubject.create(); + subject.onError(null); + subject.toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void replaycSubjectOnNextNull() { + Subject subject = ReplaySubject.create(); + subject.onNext(null); + subject.toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void replaySubjectOnErrorNull() { + Subject subject = ReplaySubject.create(); + subject.onError(null); + subject.toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void serializedcSubjectOnNextNull() { + Subject subject = PublishSubject.create().toSerialized(); + subject.onNext(null); + subject.toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void serializedSubjectOnErrorNull() { + Subject subject = PublishSubject.create().toSerialized(); + subject.onError(null); + subject.toBlocking().run(); + } + +} \ No newline at end of file diff --git a/src/test/java/io/reactivex/ObservableTests.java b/src/test/java/io/reactivex/ObservableTests.java index 919c85f815..abbab199a3 100644 --- a/src/test/java/io/reactivex/ObservableTests.java +++ b/src/test/java/io/reactivex/ObservableTests.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -20,13 +20,14 @@ import java.util.*; import java.util.concurrent.*; import java.util.concurrent.atomic.*; -import java.util.function.Predicate; import org.junit.*; -import org.mockito.*; +import org.mockito.InOrder; import org.reactivestreams.*; +import io.reactivex.Observable.Transformer; import io.reactivex.disposables.Disposable; +import io.reactivex.functions.*; import io.reactivex.internal.subscriptions.EmptySubscription; import io.reactivex.observables.ConnectableObservable; import io.reactivex.schedulers.*; @@ -37,7 +38,12 @@ public class ObservableTests { Subscriber w; - private static final Predicate IS_EVEN = v -> v % 2 == 0; + private static final Predicate IS_EVEN = new Predicate() { + @Override + public boolean test(Integer v) { + return v % 2 == 0; + } + }; @Before public void before() { @@ -54,7 +60,7 @@ public void fromArray() { @Test public void fromIterable() { - ArrayList items = new ArrayList<>(); + ArrayList items = new ArrayList(); items.add("one"); items.add("two"); items.add("three"); @@ -123,7 +129,12 @@ public void testCountZeroItems() { @Test public void testCountError() { - Observable o = Observable.error(() -> new RuntimeException()); + Observable o = Observable.error(new Supplier() { + @Override + public Throwable get() { + return new RuntimeException(); + } + }); o.count().subscribe(w); verify(w, never()).onNext(anyInt()); @@ -189,7 +200,12 @@ public void testFirstWithPredicateOfNoneMatchingThePredicate() { @Test public void testReduce() { Observable observable = Observable.just(1, 2, 3, 4); - observable.reduce((t1, t2) -> t1 + t2) + observable.reduce(new BiFunction() { + @Override + public Integer apply(Integer t1, Integer t2) { + return t1 + t2; + } + }) .subscribe(w); // we should be called only once verify(w, times(1)).onNext(anyInt()); @@ -202,9 +218,17 @@ public void testReduce() { @Test(expected = NoSuchElementException.class) public void testReduceWithEmptyObservable() { Observable observable = Observable.range(1, 0); - observable.reduce((t1, t2) -> t1 + t2) - .toBlocking().forEach(t1 -> { - // do nothing ... we expect an exception instead + observable.reduce(new BiFunction() { + @Override + public Integer apply(Integer t1, Integer t2) { + return t1 + t2; + } + }) + .toBlocking().forEach(new Consumer() { + @Override + public void accept(Integer t1) { + // do nothing ... we expect an exception instead + } }); fail("Expected an exception to be thrown"); @@ -218,7 +242,12 @@ public void testReduceWithEmptyObservable() { @Test public void testReduceWithEmptyObservableAndSeed() { Observable observable = Observable.range(1, 0); - int value = observable.reduce(1, (t1, t2) -> t1 + t2) + int value = observable.reduce(1, new BiFunction() { + @Override + public Integer apply(Integer t1, Integer t2) { + return t1 + t2; + } + }) .toBlocking().last(); assertEquals(1, value); @@ -227,7 +256,12 @@ public void testReduceWithEmptyObservableAndSeed() { @Test public void testReduceWithInitialValue() { Observable observable = Observable.just(1, 2, 3, 4); - observable.reduce(50, (t1, t2) -> t1 + t2) + observable.reduce(50, new BiFunction() { + @Override + public Integer apply(Integer t1, Integer t2) { + return t1 + t2; + } + }) .subscribe(w); // we should be called only once verify(w, times(1)).onNext(anyInt()); @@ -240,7 +274,10 @@ public void testOnSubscribeFails() { Subscriber observer = TestHelper.mockSubscriber(); final RuntimeException re = new RuntimeException("bad impl"); - Observable o = Observable.create(s -> { throw re; }); + Observable o = Observable.create(new Publisher() { + @Override + public void subscribe(Subscriber s) { throw re; } + }); o.subscribe(observer); verify(observer, times(0)).onNext(anyString()); @@ -268,12 +305,13 @@ public void testMaterializeDematerializeChaining() { * It is handled by the AtomicObserver that wraps the provided Observer. * * Result: Passes (if AtomicObserver functionality exists) + * @throws InterruptedException if the test is interrupted */ @Test public void testCustomObservableWithErrorInObserverAsynchronous() throws InterruptedException { final CountDownLatch latch = new CountDownLatch(1); final AtomicInteger count = new AtomicInteger(); - final AtomicReference error = new AtomicReference<>(); + final AtomicReference error = new AtomicReference(); // FIXME custom built??? Observable.just("1", "2", "three", "4") @@ -321,7 +359,7 @@ public void onNext(String v) { @Test public void testCustomObservableWithErrorInObserverSynchronous() { final AtomicInteger count = new AtomicInteger(); - final AtomicReference error = new AtomicReference<>(); + final AtomicReference error = new AtomicReference(); // FIXME custom built??? Observable.just("1", "2", "three", "4") @@ -364,9 +402,14 @@ public void onNext(String v) { @Test public void testCustomObservableWithErrorInObservableSynchronous() { final AtomicInteger count = new AtomicInteger(); - final AtomicReference error = new AtomicReference<>(); + final AtomicReference error = new AtomicReference(); // FIXME custom built??? - Observable.just("1", "2").concatWith(Observable.error(() -> new NumberFormatException())) + Observable.just("1", "2").concatWith(Observable.error(new Supplier() { + @Override + public Throwable get() { + return new NumberFormatException(); + } + })) .subscribe(new Observer() { @Override @@ -398,21 +441,30 @@ public void onNext(String v) { @Test public void testPublishLast() throws InterruptedException { final AtomicInteger count = new AtomicInteger(); - ConnectableObservable connectable = Observable.create(observer -> { - observer.onSubscribe(EmptySubscription.INSTANCE); - count.incrementAndGet(); - new Thread(() -> { - observer.onNext("first"); - observer.onNext("last"); - observer.onComplete(); - }).start(); + ConnectableObservable connectable = Observable.create(new Publisher() { + @Override + public void subscribe(final Subscriber observer) { + observer.onSubscribe(EmptySubscription.INSTANCE); + count.incrementAndGet(); + new Thread(new Runnable() { + @Override + public void run() { + observer.onNext("first"); + observer.onNext("last"); + observer.onComplete(); + } + }).start(); + } }).takeLast(1).publish(); // subscribe once final CountDownLatch latch = new CountDownLatch(1); - connectable.subscribe(value -> { - assertEquals("last", value); - latch.countDown(); + connectable.subscribe(new Consumer() { + @Override + public void accept(String value) { + assertEquals("last", value); + latch.countDown(); + } }); // subscribe twice @@ -427,17 +479,20 @@ public void testPublishLast() throws InterruptedException { @Test public void testReplay() throws InterruptedException { final AtomicInteger counter = new AtomicInteger(); - ConnectableObservable o = Observable.create(observer -> { - observer.onSubscribe(EmptySubscription.INSTANCE); - new Thread(new Runnable() { - - @Override - public void run() { - counter.incrementAndGet(); - observer.onNext("one"); - observer.onComplete(); - } - }).start(); + ConnectableObservable o = Observable.create(new Publisher() { + @Override + public void subscribe(final Subscriber observer) { + observer.onSubscribe(EmptySubscription.INSTANCE); + new Thread(new Runnable() { + + @Override + public void run() { + counter.incrementAndGet(); + observer.onNext("one"); + observer.onComplete(); + } + }).start(); + } }).replay(); // we connect immediately and it will emit the value @@ -448,15 +503,21 @@ public void run() { final CountDownLatch latch = new CountDownLatch(2); // subscribe once - o.subscribe(v -> { - assertEquals("one", v); - latch.countDown(); + o.subscribe(new Consumer() { + @Override + public void accept(String v) { + assertEquals("one", v); + latch.countDown(); + } }); // subscribe again - o.subscribe(v -> { - assertEquals("one", v); - latch.countDown(); + o.subscribe(new Consumer() { + @Override + public void accept(String v) { + assertEquals("one", v); + latch.countDown(); + } }); if (!latch.await(1000, TimeUnit.MILLISECONDS)) { @@ -471,28 +532,40 @@ public void run() { @Test public void testCache() throws InterruptedException { final AtomicInteger counter = new AtomicInteger(); - Observable o = Observable.create(observer -> { - observer.onSubscribe(EmptySubscription.INSTANCE); - new Thread(() -> { - counter.incrementAndGet(); - observer.onNext("one"); - observer.onComplete(); - }).start(); + Observable o = Observable.create(new Publisher() { + @Override + public void subscribe(final Subscriber observer) { + observer.onSubscribe(EmptySubscription.INSTANCE); + new Thread(new Runnable() { + @Override + public void run() { + counter.incrementAndGet(); + observer.onNext("one"); + observer.onComplete(); + } + }).start(); + } }).cache(); // we then expect the following 2 subscriptions to get that same value final CountDownLatch latch = new CountDownLatch(2); // subscribe once - o.subscribe(v -> { - assertEquals("one", v); - latch.countDown(); + o.subscribe(new Consumer() { + @Override + public void accept(String v) { + assertEquals("one", v); + latch.countDown(); + } }); // subscribe again - o.subscribe(v -> { - assertEquals("one", v); - latch.countDown(); + o.subscribe(new Consumer() { + @Override + public void accept(String v) { + assertEquals("one", v); + latch.countDown(); + } }); if (!latch.await(1000, TimeUnit.MILLISECONDS)) { @@ -504,28 +577,40 @@ public void testCache() throws InterruptedException { @Test public void testCacheWithCapacity() throws InterruptedException { final AtomicInteger counter = new AtomicInteger(); - Observable o = Observable.create(observer -> { - observer.onSubscribe(EmptySubscription.INSTANCE); - new Thread(() -> { - counter.incrementAndGet(); - observer.onNext("one"); - observer.onComplete(); - }).start(); + Observable o = Observable.create(new Publisher() { + @Override + public void subscribe(final Subscriber observer) { + observer.onSubscribe(EmptySubscription.INSTANCE); + new Thread(new Runnable() { + @Override + public void run() { + counter.incrementAndGet(); + observer.onNext("one"); + observer.onComplete(); + } + }).start(); + } }).cache(1); // we then expect the following 2 subscriptions to get that same value final CountDownLatch latch = new CountDownLatch(2); // subscribe once - o.subscribe(v -> { - assertEquals("one", v); - latch.countDown(); + o.subscribe(new Consumer() { + @Override + public void accept(String v) { + assertEquals("one", v); + latch.countDown(); + } }); // subscribe again - o.subscribe(v -> { - assertEquals("one", v); - latch.countDown(); + o.subscribe(new Consumer() { + @Override + public void accept(String v) { + assertEquals("one", v); + latch.countDown(); + } }); if (!latch.await(1000, TimeUnit.MILLISECONDS)) { @@ -570,17 +655,24 @@ public void testErrorThrownWithoutErrorHandlerSynchronous() { @Ignore("Subscribers can't throw") public void testErrorThrownWithoutErrorHandlerAsynchronous() throws InterruptedException { final CountDownLatch latch = new CountDownLatch(1); - final AtomicReference exception = new AtomicReference<>(); - Observable.create(observer -> { - new Thread(() -> { - try { - observer.onError(new Error("failure")); - } catch (Throwable e) { - // without an onError handler it has to just throw on whatever thread invokes it - exception.set(e); - } - latch.countDown(); - }).start(); + final AtomicReference exception = new AtomicReference(); + Observable.create(new Publisher() { + @Override + public void subscribe(final Subscriber observer) { + observer.onSubscribe(EmptySubscription.INSTANCE); + new Thread(new Runnable() { + @Override + public void run() { + try { + observer.onError(new Error("failure")); + } catch (Throwable e) { + // without an onError handler it has to just throw on whatever thread invokes it + exception.set(e); + } + latch.countDown(); + } + }).start(); + } }).subscribe(); // wait for exception latch.await(3000, TimeUnit.MILLISECONDS); @@ -591,7 +683,7 @@ public void testErrorThrownWithoutErrorHandlerAsynchronous() throws InterruptedE @Test public void testTakeWithErrorInObserver() { final AtomicInteger count = new AtomicInteger(); - final AtomicReference error = new AtomicReference<>(); + final AtomicReference error = new AtomicReference(); Observable.just("1", "2", "three", "4").take(3) .safeSubscribe(new Observer() { @@ -642,9 +734,9 @@ public void testOfType() { @Test public void testOfTypeWithPolymorphism() { - ArrayList l1 = new ArrayList<>(); + ArrayList l1 = new ArrayList(); l1.add(1); - LinkedList l2 = new LinkedList<>(); + LinkedList l2 = new LinkedList(); l2.add(2); @SuppressWarnings("rawtypes") @@ -797,7 +889,17 @@ public void testRangeWithScheduler() { @Test public void testCollectToList() { Observable> o = Observable.just(1, 2, 3) - .collect(ArrayList::new, (list, v) -> list.add(v)); + .collect(new Supplier>() { + @Override + public List get() { + return new ArrayList(); + } + }, new BiConsumer, Integer>() { + @Override + public void accept(List list, Integer v) { + list.add(v); + } + }); List list = o.toBlocking().last(); @@ -817,34 +919,42 @@ public void testCollectToList() { @Test public void testCollectToString() { - String value = Observable.just(1, 2, 3).collect(StringBuilder::new, - (sb, v) -> { - if (sb.length() > 0) { - sb.append("-"); + String value = Observable.just(1, 2, 3).collect(new Supplier() { + @Override + public StringBuilder get() { + return new StringBuilder(); } - sb.append(v); - }).toBlocking().last().toString(); + }, + new BiConsumer() { + @Override + public void accept(StringBuilder sb, Integer v) { + if (sb.length() > 0) { + sb.append("-"); + } + sb.append(v); + } + }).toBlocking().last().toString(); assertEquals("1-2-3", value); } @Test public void testMergeWith() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); Observable.just(1).mergeWith(Observable.just(2)).subscribe(ts); ts.assertValues(1, 2); } @Test public void testConcatWith() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); Observable.just(1).concatWith(Observable.just(2)).subscribe(ts); ts.assertValues(1, 2); } @Test public void testAmbWith() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); Observable.just(1).ambWith(Observable.just(2)).subscribe(ts); ts.assertValue(1); } @@ -867,9 +977,19 @@ public void testTakeWhileToList() { for (int i = 0;i < expectedCount; i++) { Observable .just(Boolean.TRUE, Boolean.FALSE) - .takeWhile(v -> v) + .takeWhile(new Predicate() { + @Override + public boolean test(Boolean v) { + return v; + } + }) .toList() - .doOnNext(booleans -> count.incrementAndGet()) + .doOnNext(new Consumer>() { + @Override + public void accept(List booleans) { + count.incrementAndGet(); + } + }) .subscribe(); } assertEquals(expectedCount, count.get()); @@ -877,8 +997,18 @@ public void testTakeWhileToList() { @Test public void testCompose() { - TestSubscriber ts = new TestSubscriber<>(); - Observable.just(1, 2, 3).compose(t1 ->t1.map(String::valueOf)) + TestSubscriber ts = new TestSubscriber(); + Observable.just(1, 2, 3).compose(new Transformer() { + @Override + public Publisher apply(Observable t1) { + return t1.map(new Function() { + @Override + public String apply(Integer v) { + return String.valueOf(v); + } + }); + } + }) .subscribe(ts); ts.assertTerminated(); ts.assertNoErrors(); @@ -918,7 +1048,7 @@ public void testEmptyIsEmpty() { // FIXME this test doesn't make sense // @Test // cf. https://github.com/ReactiveX/RxJava/issues/2599 // public void testSubscribingSubscriberAsObserverMaintainsSubscriptionChain() { -// TestSubscriber subscriber = new TestSubscriber<>(); +// TestSubscriber subscriber = new TestSubscriber(); // Subscription subscription = Observable.just("event").subscribe((Observer) subscriber); // subscription.unsubscribe(); // @@ -946,14 +1076,17 @@ public void testForEachWithNull() { @Test public void testExtend() { - final TestSubscriber subscriber = new TestSubscriber<>(); + final TestSubscriber subscriber = new TestSubscriber(); final Object value = new Object(); - Observable.just(value).to(onSubscribe -> { - onSubscribe.subscribe(subscriber); - subscriber.assertNoErrors(); - subscriber.assertComplete(); - subscriber.assertValue(value); - return subscriber.values().get(0); - }); + Observable.just(value).to(new Function, Object>() { + @Override + public Object apply(Observable onSubscribe) { + onSubscribe.subscribe(subscriber); + subscriber.assertNoErrors(); + subscriber.assertComplete(); + subscriber.assertValue(value); + return subscriber.values().get(0); + } + }); } } \ No newline at end of file diff --git a/src/test/java/io/reactivex/ObservableWindowTests.java b/src/test/java/io/reactivex/ObservableWindowTests.java index 5969c24c58..e6f797a7c4 100644 --- a/src/test/java/io/reactivex/ObservableWindowTests.java +++ b/src/test/java/io/reactivex/ObservableWindowTests.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -19,18 +19,31 @@ import org.junit.Test; +import io.reactivex.Observable; +import io.reactivex.functions.*; + public class ObservableWindowTests { @Test public void testWindow() { - final ArrayList> lists = new ArrayList<>(); + final ArrayList> lists = new ArrayList>(); Observable.concat( Observable.just(1, 2, 3, 4, 5, 6) .window(3) - .map(xs -> xs.toList()) + .map(new Function, Observable>>() { + @Override + public Observable> apply(Observable xs) { + return xs.toList(); + } + }) ) - .toBlocking().forEach(xs -> lists.add(xs)); + .toBlocking().forEach(new Consumer>() { + @Override + public void accept(List xs) { + lists.add(xs); + } + }); assertArrayEquals(lists.get(0).toArray(new Integer[3]), new Integer[] { 1, 2, 3 }); assertArrayEquals(lists.get(1).toArray(new Integer[3]), new Integer[] { 4, 5, 6 }); diff --git a/src/test/java/io/reactivex/ReduceTests.java b/src/test/java/io/reactivex/ReduceTests.java index 2e9c6a18d2..1abc64cf89 100644 --- a/src/test/java/io/reactivex/ReduceTests.java +++ b/src/test/java/io/reactivex/ReduceTests.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -17,14 +17,21 @@ import org.junit.Test; +import io.reactivex.Observable; import io.reactivex.CovarianceTest.*; +import io.reactivex.functions.BiFunction; public class ReduceTests { @Test public void reduceInts() { Observable o = Observable.just(1, 2, 3); - int value = o.reduce((t1, t2) -> t1 + t2).toBlocking().single(); + int value = o.reduce(new BiFunction() { + @Override + public Integer apply(Integer t1, Integer t2) { + return t1 + t2; + } + }).toBlocking().single(); assertEquals(6, value); } @@ -34,9 +41,19 @@ public void reduceInts() { public void reduceWithObjects() { Observable horrorMovies = Observable. just(new HorrorMovie()); - Observable reduceResult = horrorMovies.scan((t1, t2) -> t2).takeLast(1); - - Observable reduceResult2 = horrorMovies.reduce((t1, t2) -> t2); + Observable reduceResult = horrorMovies.scan(new BiFunction() { + @Override + public Movie apply(Movie t1, Movie t2) { + return t2; + } + }).takeLast(1); + + Observable reduceResult2 = horrorMovies.reduce(new BiFunction() { + @Override + public Movie apply(Movie t1, Movie t2) { + return t2; + } + }); } /** @@ -49,7 +66,12 @@ public void reduceWithObjects() { public void reduceWithCovariantObjects() { Observable horrorMovies = Observable. just(new HorrorMovie()); - Observable reduceResult2 = horrorMovies.reduce((t1, t2) -> t2); + Observable reduceResult2 = horrorMovies.reduce(new BiFunction() { + @Override + public Movie apply(Movie t1, Movie t2) { + return t2; + } + }); } /** @@ -69,7 +91,12 @@ public void reduceCovariance() { */ public void libraryFunctionActingOnMovieObservables(Observable obs) { - obs.reduce((t1, t2) -> t2); + obs.reduce(new BiFunction() { + @Override + public Movie apply(Movie t1, Movie t2) { + return t2; + } + }); } } \ No newline at end of file diff --git a/src/test/java/io/reactivex/ScanTests.java b/src/test/java/io/reactivex/ScanTests.java index f128912ca0..c5fa8a4197 100644 --- a/src/test/java/io/reactivex/ScanTests.java +++ b/src/test/java/io/reactivex/ScanTests.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -17,18 +17,29 @@ import org.junit.Test; +import io.reactivex.EventStream.Event; +import io.reactivex.functions.*; + public class ScanTests { @Test public void testUnsubscribeScan() { EventStream.getEventStream("HTTP-ClusterB", 20) - .scan(new HashMap(), (accum, perInstanceEvent) -> { - accum.put("instance", perInstanceEvent.instanceId); - return accum; + .scan(new HashMap(), new BiFunction, Event, HashMap>() { + @Override + public HashMap apply(HashMap accum, Event perInstanceEvent) { + accum.put("instance", perInstanceEvent.instanceId); + return accum; + } }) .take(10) .toBlocking() - .forEach(System.out::println); + .forEach(new Consumer>() { + @Override + public void accept(HashMap v) { + System.out.println(v); + } + }); } } \ No newline at end of file diff --git a/src/test/java/io/reactivex/SingleNullTests.java b/src/test/java/io/reactivex/SingleNullTests.java new file mode 100644 index 0000000000..3850e5d871 --- /dev/null +++ b/src/test/java/io/reactivex/SingleNullTests.java @@ -0,0 +1,843 @@ +/** + * 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.lang.reflect.*; +import java.util.*; +import java.util.concurrent.*; + +import org.junit.*; +import org.reactivestreams.*; + +import io.reactivex.Single.*; +import io.reactivex.exceptions.TestException; +import io.reactivex.functions.*; +import io.reactivex.internal.functions.Functions; +import io.reactivex.schedulers.Schedulers; + +public class SingleNullTests { + + Single just1 = Single.just(1); + + Single error = Single.error(new TestException()); + + @Test(expected = NullPointerException.class) + public void ambIterableNull() { + Single.amb((Iterable>)null); + } + + @Test(expected = NullPointerException.class) + public void ambIterableIteratorNull() { + Single.amb(new Iterable>() { + @Override + public Iterator> iterator() { + return null; + } + }).get(); + } + + @SuppressWarnings("unchecked") + @Test(expected = NullPointerException.class) + public void ambIterableOneIsNull() { + Single.amb(Arrays.asList(null, just1)).get(); + } + + @Test(expected = NullPointerException.class) + public void ambArrayNull() { + Single.amb((Single[])null); + } + + @SuppressWarnings("unchecked") + @Test(expected = NullPointerException.class) + public void ambArrayOneIsNull() { + Single.amb(null, just1).get(); + } + + @Test(expected = NullPointerException.class) + public void concatIterableNull() { + Single.concat((Iterable>)null); + } + + @Test(expected = NullPointerException.class) + public void concatIterableIteratorNull() { + Single.concat(new Iterable>() { + @Override + public Iterator> iterator() { + return null; + } + }).toBlocking().run(); + } + + @SuppressWarnings("unchecked") + @Test(expected = NullPointerException.class) + public void concatIterableOneIsNull() { + Single.concat(Arrays.asList(just1, null)).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void concatObservableNull() { + Single.concat((Observable>)null); + } + + @Test + public void concatNull() throws Exception { + @SuppressWarnings("rawtypes") + Class clazz = Single.class; + for (int argCount = 2; argCount < 10; argCount++) { + for (int argNull = 1; argNull <= argCount; argNull++) { + Class[] params = new Class[argCount]; + Arrays.fill(params, Single.class); + + Object[] values = new Object[argCount]; + Arrays.fill(values, just1); + values[argNull - 1] = null; + + Method m = clazz.getMethod("concat", params); + + try { + m.invoke(null, values); + Assert.fail("No exception for argCount " + argCount + " / argNull " + argNull); + } catch (InvocationTargetException ex) { + if (!(ex.getCause() instanceof NullPointerException)) { + Assert.fail("Unexpected exception for argCount " + argCount + " / argNull " + argNull + ": " + ex); + } + } + } + } + } + + @Test(expected = NullPointerException.class) + public void createNull() { + Single.create(null); + } + + @Test(expected = NullPointerException.class) + public void deferNull() { + Single.defer(null); + } + + @Test(expected = NullPointerException.class) + public void deferReturnsNull() { + Single.defer(Functions.>nullSupplier()).get(); + } + + @Test(expected = NullPointerException.class) + public void errorSupplierNull() { + Single.error((Supplier)null); + } + + @Test(expected = NullPointerException.class) + public void errorSupplierReturnsNull() { + Single.error(Functions.nullSupplier()).get(); + } + + @Test(expected = NullPointerException.class) + public void errorNull() { + Single.error((Throwable)null); + } + + @Test(expected = NullPointerException.class) + public void fromCallableNull() { + Single.fromCallable(null); + } + + @Test(expected = NullPointerException.class) + public void fromCallableReturnsNull() { + Single.fromCallable(new Callable() { + @Override + public Object call() throws Exception { + return null; + } + }).get(); + } + + @Test(expected = NullPointerException.class) + public void fromFutureNull() { + Single.fromFuture((Future)null); + } + + @Test(expected = NullPointerException.class) + public void fromFutureReturnsNull() { + FutureTask f = new FutureTask(Functions.emptyRunnable(), null); + f.run(); + Single.fromFuture(f).get(); + } + + @Test(expected = NullPointerException.class) + public void fromFutureTimedFutureNull() { + Single.fromFuture(null, 1, TimeUnit.SECONDS); + } + + @Test(expected = NullPointerException.class) + public void fromFutureTimedUnitNull() { + Single.fromFuture(new FutureTask(new Callable() { + @Override + public Object call() throws Exception { + return null; + } + }), 1, null); + } + + @Test(expected = NullPointerException.class) + public void fromFutureTimedSchedulerNull() { + Single.fromFuture(new FutureTask(new Callable() { + @Override + public Object call() throws Exception { + return null; + } + }), 1, TimeUnit.SECONDS, null); + } + + @Test(expected = NullPointerException.class) + public void fromFutureTimedReturnsNull() { + FutureTask f = new FutureTask(Functions.emptyRunnable(), null); + f.run(); + Single.fromFuture(f, 1, TimeUnit.SECONDS).get(); + } + + @Test(expected = NullPointerException.class) + public void fromFutureSchedulerNull() { + Single.fromFuture(new FutureTask(new Callable() { + @Override + public Object call() throws Exception { + return null; + } + }), null); + } + + @Test(expected = NullPointerException.class) + public void fromPublisherNull() { + Single.fromPublisher(null); + } + + @Test(expected = NullPointerException.class) + public void justNull() { + Single.just(null); + } + + @Test(expected = NullPointerException.class) + public void mergeIterableNull() { + Single.merge((Iterable>)null); + } + + @Test(expected = NullPointerException.class) + public void mergeIterableIteratorNull() { + Single.merge(new Iterable>() { + @Override + public Iterator> iterator() { + return null; + } + }).toBlocking().run(); + } + + @SuppressWarnings("unchecked") + @Test(expected = NullPointerException.class) + public void mergeIterableOneIsNull() { + Single.merge(Arrays.asList(null, just1)).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void mergeSingleNull() { + Single.merge((Single>)null); + } + + @Test + public void mergeNull() throws Exception { + @SuppressWarnings("rawtypes") + Class clazz = Single.class; + for (int argCount = 2; argCount < 10; argCount++) { + for (int argNull = 1; argNull <= argCount; argNull++) { + Class[] params = new Class[argCount]; + Arrays.fill(params, Single.class); + + Object[] values = new Object[argCount]; + Arrays.fill(values, just1); + values[argNull - 1] = null; + + Method m = clazz.getMethod("merge", params); + + try { + m.invoke(null, values); + Assert.fail("No exception for argCount " + argCount + " / argNull " + argNull); + } catch (InvocationTargetException ex) { + if (!(ex.getCause() instanceof NullPointerException)) { + Assert.fail("Unexpected exception for argCount " + argCount + " / argNull " + argNull + ": " + ex); + } + } + } + } + } + + @Test(expected = NullPointerException.class) + public void timerUnitNull() { + Single.timer(1, null); + } + + @Test(expected = NullPointerException.class) + public void timerSchedulerNull() { + Single.timer(1, TimeUnit.SECONDS, null); + } + + @Test(expected = NullPointerException.class) + public void equalsFirstNull() { + Single.equals(null, just1); + } + + @Test(expected = NullPointerException.class) + public void equalsSecondNull() { + Single.equals(just1, null); + } + + @Test(expected = NullPointerException.class) + public void usingResourceSupplierNull() { + Single.using(null, new Function>() { + @Override + public Single apply(Object d) { + return just1; + } + }, Functions.emptyConsumer()); + } + + @Test(expected = NullPointerException.class) + public void usingSingleSupplierNull() { + Single.using(new Supplier() { + @Override + public Object get() { + return 1; + } + }, null, Functions.emptyConsumer()); + } + + @Test(expected = NullPointerException.class) + public void usingSingleSupplierReturnsNull() { + Single.using(new Supplier() { + @Override + public Object get() { + return 1; + } + }, new Function>() { + @Override + public Single apply(Object d) { + return null; + } + }, Functions.emptyConsumer()).get(); + } + + @Test(expected = NullPointerException.class) + public void usingDisposeNull() { + Single.using(new Supplier() { + @Override + public Object get() { + return 1; + } + }, new Function>() { + @Override + public Single apply(Object d) { + return just1; + } + }, null); + } + + @Test(expected = NullPointerException.class) + public void zipIterableNull() { + Single.zip((Iterable>)null, new Function() { + @Override + public Object apply(Object[] v) { + return 1; + } + }); + } + + @Test(expected = NullPointerException.class) + public void zipIterableIteratorNull() { + Single.zip(new Iterable>() { + @Override + public Iterator> iterator() { + return null; + } + }, new Function() { + @Override + public Object apply(Object[] v) { + return 1; + } + }).get(); + } + + @SuppressWarnings("unchecked") + @Test(expected = NullPointerException.class) + public void zipIterableOneIsNull() { + Single.zip(Arrays.asList(null, just1), new Function() { + @Override + public Object apply(Object[] v) { + return 1; + } + }).get(); + } + + @SuppressWarnings("unchecked") + @Test(expected = NullPointerException.class) + public void zipIterableOneFunctionNull() { + Single.zip(Arrays.asList(just1, just1), null).get(); + } + + @SuppressWarnings("unchecked") + @Test(expected = NullPointerException.class) + public void zipIterableOneFunctionReturnsNull() { + Single.zip(Arrays.asList(just1, just1), new Function() { + @Override + public Object apply(Object[] v) { + return null; + } + }).get(); + } + + @SuppressWarnings("unchecked") + @Test + public void zipNull() throws Exception { + @SuppressWarnings("rawtypes") + Class clazz = Single.class; + for (int argCount = 3; argCount < 10; argCount++) { + for (int argNull = 1; argNull <= argCount; argNull++) { + Class[] params = new Class[argCount + 1]; + Arrays.fill(params, Single.class); + Class fniClass = Class.forName("io.reactivex.functions.Function" + argCount); + params[argCount] = fniClass; + + Object[] values = new Object[argCount + 1]; + Arrays.fill(values, just1); + values[argNull - 1] = null; + values[argCount] = Proxy.newProxyInstance(getClass().getClassLoader(), new Class[] { fniClass }, new InvocationHandler() { + @Override + public Object invoke(Object o, Method m, Object[] a) throws Throwable { + return 1; + } + }); + + Method m = clazz.getMethod("zip", params); + + try { + m.invoke(null, values); + Assert.fail("No exception for argCount " + argCount + " / argNull " + argNull); + } catch (InvocationTargetException ex) { + if (!(ex.getCause() instanceof NullPointerException)) { + Assert.fail("Unexpected exception for argCount " + argCount + " / argNull " + argNull + ": " + ex); + } + } + + values[argCount] = Proxy.newProxyInstance(getClass().getClassLoader(), new Class[] { fniClass }, new InvocationHandler() { + @Override + public Object invoke(Object o, Method m1, Object[] a) throws Throwable { + return null; + } + }); + try { + ((Single)m.invoke(null, values)).get(); + Assert.fail("No exception for argCount " + argCount + " / argNull " + argNull); + } catch (InvocationTargetException ex) { + if (!(ex.getCause() instanceof NullPointerException)) { + Assert.fail("Unexpected exception for argCount " + argCount + " / argNull " + argNull + ": " + ex); + } + } + + } + + Class[] params = new Class[argCount + 1]; + Arrays.fill(params, Single.class); + Class fniClass = Class.forName("io.reactivex.functions.Function" + argCount); + params[argCount] = fniClass; + + Object[] values = new Object[argCount + 1]; + Arrays.fill(values, just1); + values[argCount] = null; + + Method m = clazz.getMethod("zip", params); + + try { + m.invoke(null, values); + Assert.fail("No exception for argCount " + argCount + " / zipper function "); + } catch (InvocationTargetException ex) { + if (!(ex.getCause() instanceof NullPointerException)) { + Assert.fail("Unexpected exception for argCount " + argCount + " / zipper function: " + ex); + } + } + } + } + + @Test(expected = NullPointerException.class) + public void zip2FirstNull() { + Single.zip(null, just1, new BiFunction() { + @Override + public Object apply(Object a, Integer b) { + return 1; + } + }); + } + + @Test(expected = NullPointerException.class) + public void zip2SecondNull() { + Single.zip(just1, null, new BiFunction() { + @Override + public Object apply(Integer a, Object b) { + return 1; + } + }); + } + + @Test(expected = NullPointerException.class) + public void zip2ZipperNull() { + Single.zip(just1, just1, null); + } + + @Test(expected = NullPointerException.class) + public void zip2ZipperReturnsdNull() { + Single.zip(just1, null, new BiFunction() { + @Override + public Object apply(Integer a, Object b) { + return null; + } + }).get(); + } + + @Test(expected = NullPointerException.class) + public void zipArrayNull() { + Single.zipArray(new Function() { + @Override + public Object apply(Object[] v) { + return 1; + } + }, (Single[])null); + } + + @SuppressWarnings("unchecked") + @Test(expected = NullPointerException.class) + public void zipArrayOneIsNull() { + Single.zipArray(new Function() { + @Override + public Object apply(Object[] v) { + return 1; + } + }, just1, null); + } + + @SuppressWarnings("unchecked") + @Test(expected = NullPointerException.class) + public void zipArrayFunctionNull() { + Single.zipArray(null, just1, just1); + } + + @SuppressWarnings("unchecked") + @Test(expected = NullPointerException.class) + public void zipArrayFunctionReturnsNull() { + Single.zipArray(new Function() { + @Override + public Object apply(Object[] v) { + return null; + } + }, just1, just1).get(); + } + + //************************************************** + // Instance methods + //************************************************** + + @Test(expected = NullPointerException.class) + public void ambWithNull() { + just1.ambWith(null); + } + + @Test(expected = NullPointerException.class) + public void composeNull() { + just1.compose(null); + } + + @Test(expected = NullPointerException.class) + public void castNull() { + just1.cast(null); + } + + @Test(expected = NullPointerException.class) + public void concatWith() { + just1.concatWith(null); + } + + @Test(expected = NullPointerException.class) + public void delayUnitNull() { + just1.delay(1, null); + } + + @Test(expected = NullPointerException.class) + public void delaySchedulerNull() { + just1.delay(1, TimeUnit.SECONDS, null); + } + + @Test(expected = NullPointerException.class) + public void doOnSubscribeNull() { + just1.doOnSubscribe(null); + } + + @Test(expected = NullPointerException.class) + public void doOnSuccess() { + just1.doOnSuccess(null); + } + + @Test(expected = NullPointerException.class) + public void doOnError() { + error.doOnError(null); + } + + @Test(expected = NullPointerException.class) + public void doOnCancelNull() { + just1.doOnCancel(null); + } + + @Test(expected = NullPointerException.class) + public void flatMapNull() { + just1.flatMap(null); + } + + @Test(expected = NullPointerException.class) + public void flatMapFunctionReturnsNull() { + just1.flatMap(new Function>() { + @Override + public Single apply(Integer v) { + return null; + } + }).get(); + } + + @Test(expected = NullPointerException.class) + public void flatMapPublisherNull() { + just1.flatMapPublisher(null); + } + + @Test(expected = NullPointerException.class) + public void flatMapPublisherFunctionReturnsNull() { + just1.flatMapPublisher(new Function>() { + @Override + public Publisher apply(Integer v) { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void liftNull() { + just1.lift(null); + } + + @Test(expected = NullPointerException.class) + public void liftFunctionReturnsNull() { + just1.lift(new SingleOperator() { + @Override + public SingleSubscriber apply(SingleSubscriber s) { + return null; + } + }).get(); + } + + @Test(expected = NullPointerException.class) + public void containsNull() { + just1.contains(null); + } + + @Test(expected = NullPointerException.class) + public void containsComparerNull() { + just1.contains(1, null); + } + + @Test(expected = NullPointerException.class) + public void mergeWithNull() { + just1.mergeWith(null); + } + + @Test(expected = NullPointerException.class) + public void observeOnNull() { + just1.observeOn(null); + } + + @Test(expected = NullPointerException.class) + public void onErrorReturnSupplierNull() { + just1.onErrorReturn((Supplier)null); + } + + @Test(expected = NullPointerException.class) + public void onErrorReturnsSupplierReturnsNull() { + error.onErrorReturn(Functions.nullSupplier()).get(); + } + + @Test(expected = NullPointerException.class) + public void onErrorReturnValueNull() { + error.onErrorReturn((Integer)null); + } + + @Test(expected = NullPointerException.class) + public void onErrorResumeNextNull() { + error.onErrorResumeNext(null); + } + + @Test(expected = NullPointerException.class) + public void onErrorResumeNextFunctionReturnsNull() { + error.onErrorResumeNext(new Function>() { + @Override + public Single apply(Throwable e) { + return null; + } + }).get(); + } + + @Test(expected = NullPointerException.class) + public void repeatWhenNull() { + error.repeatWhen(null); + } + + @Test(expected = NullPointerException.class) + public void repeatWhenFunctionReturnsNull() { + error.repeatWhen(new Function, Publisher>() { + @Override + public Publisher apply(Observable v) { + return null; + } + }).toBlocking().run(); + } + + @Test(expected = NullPointerException.class) + public void repeatUntilNull() { + error.repeatUntil(null); + } + + @Test(expected = NullPointerException.class) + public void retryBiPreducateNull() { + error.retry((BiPredicate)null); + } + + @Test(expected = NullPointerException.class) + public void retryPredicateNull() { + error.retry((Predicate)null); + } + + @Test(expected = NullPointerException.class) + public void retryWhenNull() { + error.retryWhen(null); + } + + @Test(expected = NullPointerException.class) + public void retryWhenFunctionReturnsNull() { + error.retryWhen(new Function, Publisher>() { + @Override + public Publisher apply(Observable e) { + return null; + } + }).get(); + } + + @Test(expected = NullPointerException.class) + public void safeSubscribeNull() { + just1.safeSubscribe(null); + } + + @Test(expected = NullPointerException.class) + public void subscribeBiConsumerNull() { + just1.subscribe((BiConsumer)null); + } + + @Test(expected = NullPointerException.class) + public void subscribeConsumerNull() { + just1.subscribe((Consumer)null); + } + + @Test(expected = NullPointerException.class) + public void subscribeSingeSubscriberNull() { + just1.subscribe((SingleSubscriber)null); + } + + @Test(expected = NullPointerException.class) + public void subscribeOnSuccessNull() { + just1.subscribe(null, new Consumer() { + @Override + public void accept(Throwable e) { } + }); + } + + @Test(expected = NullPointerException.class) + public void subscribeOnErrorNull() { + just1.subscribe(new Consumer() { + @Override + public void accept(Integer v) { } + }, null); + } + @Test(expected = NullPointerException.class) + public void subscribeSubscriberNull() { + just1.subscribe((Subscriber)null); + } + + @Test(expected = NullPointerException.class) + public void subscribeOnNull() { + just1.subscribeOn(null); + } + + @Test(expected = NullPointerException.class) + public void timeoutUnitNull() { + just1.timeout(1, null); + } + + @Test(expected = NullPointerException.class) + public void timeoutSchedulerNull() { + just1.timeout(1, TimeUnit.SECONDS, (Scheduler)null); + } + + @Test(expected = NullPointerException.class) + public void timeoutOtherNull() { + just1.timeout(1, TimeUnit.SECONDS, Schedulers.single(), null); + } + + @Test(expected = NullPointerException.class) + public void timeoutOther2Null() { + just1.timeout(1, TimeUnit.SECONDS, (Single)null); + } + + @Test(expected = NullPointerException.class) + public void toNull() { + just1.to(null); + } + + @Test(expected = NullPointerException.class) + public void unsafeSubscribeNull() { + just1.unsafeSubscribe(null); + } + + @Test(expected = NullPointerException.class) + public void zipWithNull() { + just1.zipWith(null, new BiFunction() { + @Override + public Object apply(Integer a, Object b) { + return 1; + } + }); + } + + @Test(expected = NullPointerException.class) + public void zipWithFunctionNull() { + just1.zipWith(just1, null); + } + + @Test(expected = NullPointerException.class) + public void zipWithFunctionReturnsNull() { + just1.zipWith(just1, new BiFunction() { + @Override + public Object apply(Integer a, Integer b) { + return null; + } + }).get(); + } +} \ No newline at end of file diff --git a/src/test/java/io/reactivex/SingleTest.java b/src/test/java/io/reactivex/SingleTest.java index 1379c7c800..68313c657a 100644 --- a/src/test/java/io/reactivex/SingleTest.java +++ b/src/test/java/io/reactivex/SingleTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -21,8 +21,9 @@ import org.junit.Test; -import io.reactivex.Single.SingleSubscriber; +import io.reactivex.Single.*; import io.reactivex.disposables.*; +import io.reactivex.functions.*; import io.reactivex.internal.disposables.EmptyDisposable; import io.reactivex.schedulers.Schedulers; import io.reactivex.subscribers.TestSubscriber; @@ -31,14 +32,14 @@ public class SingleTest { @Test public void testHelloWorld() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); Single.just("Hello World!").subscribe(ts); ts.assertValueSequence(Arrays.asList("Hello World!")); } @Test public void testHelloWorld2() { - final AtomicReference v = new AtomicReference<>(); + final AtomicReference v = new AtomicReference(); Single.just("Hello World!").subscribe(new SingleSubscriber() { @Override @@ -62,36 +63,51 @@ public void onError(Throwable error) { @Test public void testMap() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); Single.just("A") - .map(s -> s + "B") + .map(new Function() { + @Override + public String apply(String s) { + return s + "B"; + } + }) .subscribe(ts); ts.assertValueSequence(Arrays.asList("AB")); } @Test public void testZip() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); Single a = Single.just("A"); Single b = Single.just("B"); - Single.zip(a, b, (a1, b1) -> a1 + b1) - .subscribe(ts); + Single.zip(a, b, new BiFunction() { + @Override + public String apply(String a1, String b1) { + return a1 + b1; + } + }) + .subscribe(ts); ts.assertValueSequence(Arrays.asList("AB")); } @Test public void testZipWith() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); - Single.just("A").zipWith(Single.just("B"), (a1, b1) -> a1 + b1) - .subscribe(ts); + Single.just("A").zipWith(Single.just("B"), new BiFunction() { + @Override + public String apply(String a1, String b1) { + return a1 + b1; + } + }) + .subscribe(ts); ts.assertValueSequence(Arrays.asList("AB")); } @Test public void testMerge() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); Single a = Single.just("A"); Single b = Single.just("B"); @@ -101,7 +117,7 @@ public void testMerge() { @Test public void testMergeWith() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); Single.just("A").mergeWith(Single.just("B")).subscribe(ts); ts.assertValueSequence(Arrays.asList("A", "B")); @@ -109,11 +125,14 @@ public void testMergeWith() { @Test public void testCreateSuccess() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); - Single.create(s -> { - s.onSubscribe(EmptyDisposable.INSTANCE); - s.onSuccess("Hello"); + Single.create(new SingleOnSubscribe() { + @Override + public void accept(SingleSubscriber s) { + s.onSubscribe(EmptyDisposable.INSTANCE); + s.onSuccess("Hello"); + } }).subscribe(ts); ts.assertValueSequence(Arrays.asList("Hello")); @@ -121,10 +140,13 @@ public void testCreateSuccess() { @Test public void testCreateError() { - TestSubscriber ts = new TestSubscriber<>(); - Single.create(s -> { - s.onSubscribe(EmptyDisposable.INSTANCE); - s.onError(new RuntimeException("fail")); + TestSubscriber ts = new TestSubscriber(); + Single.create(new SingleOnSubscribe() { + @Override + public void accept(SingleSubscriber s) { + s.onSubscribe(EmptyDisposable.INSTANCE); + s.onError(new RuntimeException("fail")); + } }).subscribe(ts); ts.assertError(RuntimeException.class); @@ -133,17 +155,23 @@ public void testCreateError() { @Test public void testAsync() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); Single.just("Hello") .subscribeOn(Schedulers.io()) - .map(v -> { - System.out.println("SubscribeOn Thread: " + Thread.currentThread()); - return v; + .map(new Function() { + @Override + public String apply(String v) { + System.out.println("SubscribeOn Thread: " + Thread.currentThread()); + return v; + } }) .observeOn(Schedulers.computation()) - .map(v -> { - System.out.println("ObserveOn Thread: " + Thread.currentThread()); - return v; + .map(new Function() { + @Override + public String apply(String v) { + System.out.println("ObserveOn Thread: " + Thread.currentThread()); + return v; + } }) .subscribe(ts); ts.awaitTerminalEvent(); @@ -152,8 +180,13 @@ public void testAsync() { @Test public void testFlatMap() { - TestSubscriber ts = new TestSubscriber<>(); - Single.just("Hello").flatMap(s -> Single.just(s + " World!").subscribeOn(Schedulers.computation()) + TestSubscriber ts = new TestSubscriber(); + Single.just("Hello").flatMap(new Function>() { + @Override + public Single apply(String s) { + return Single.just(s + " World!").subscribeOn(Schedulers.computation()); + } + } ).subscribe(ts); ts.awaitTerminalEvent(); ts.assertValueSequence(Arrays.asList("Hello World!")); @@ -161,15 +194,18 @@ public void testFlatMap() { @Test public void testTimeout() { - TestSubscriber ts = new TestSubscriber<>(); - Single s1 = Single.create(s -> { - s.onSubscribe(EmptyDisposable.INSTANCE); - try { - Thread.sleep(5000); - } catch (InterruptedException e) { - // ignore as we expect this for the test + TestSubscriber ts = new TestSubscriber(); + Single s1 = Single.create(new SingleOnSubscribe() { + @Override + public void accept(SingleSubscriber s) { + s.onSubscribe(EmptyDisposable.INSTANCE); + try { + Thread.sleep(5000); + } catch (InterruptedException e) { + // ignore as we expect this for the test + } + s.onSuccess("success"); } - s.onSuccess("success"); }).subscribeOn(Schedulers.io()); s1.timeout(100, TimeUnit.MILLISECONDS).subscribe(ts); @@ -180,15 +216,18 @@ public void testTimeout() { @Test public void testTimeoutWithFallback() { - TestSubscriber ts = new TestSubscriber<>(); - Single s1 = Single.create(s -> { - s.onSubscribe(EmptyDisposable.INSTANCE); - try { - Thread.sleep(5000); - } catch (InterruptedException e) { - // ignore as we expect this for the test - } - s.onSuccess("success"); + TestSubscriber ts = new TestSubscriber(); + Single s1 = Single.create(new SingleOnSubscribe() { + @Override + public void accept(SingleSubscriber s) { + s.onSubscribe(EmptyDisposable.INSTANCE); + try { + Thread.sleep(5000); + } catch (InterruptedException e) { + // ignore as we expect this for the test + } + s.onSuccess("success"); + } }).subscribeOn(Schedulers.io()); s1.timeout(100, TimeUnit.MILLISECONDS, Single.just("hello")).subscribe(ts); @@ -200,34 +239,40 @@ public void testTimeoutWithFallback() { @Test public void testUnsubscribe() throws InterruptedException { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); final AtomicBoolean unsubscribed = new AtomicBoolean(); final AtomicBoolean interrupted = new AtomicBoolean(); final CountDownLatch latch = new CountDownLatch(2); - Single s1 = Single.create(s -> { - MultipleAssignmentDisposable mad = new MultipleAssignmentDisposable(); - s.onSubscribe(mad); - final Thread t = new Thread(new Runnable() { + Single s1 = Single.create(new SingleOnSubscribe() { + @Override + public void accept(final SingleSubscriber s) { + MultipleAssignmentDisposable mad = new MultipleAssignmentDisposable(); + s.onSubscribe(mad); + final Thread t = new Thread(new Runnable() { + + @Override + public void run() { + try { + Thread.sleep(5000); + s.onSuccess("success"); + } catch (InterruptedException e) { + interrupted.set(true); + latch.countDown(); + } + } - @Override - public void run() { - try { - Thread.sleep(5000); - s.onSuccess("success"); - } catch (InterruptedException e) { - interrupted.set(true); + }); + mad.set(new Disposable() { + @Override + public void dispose() { + unsubscribed.set(true); + t.interrupt(); latch.countDown(); } - } - - }); - mad.set(() -> { - unsubscribed.set(true); - t.interrupt(); - latch.countDown(); - }); - t.start(); + }); + t.start(); + } }); s1.subscribe(ts); @@ -246,10 +291,11 @@ public void run() { /** * Assert that unsubscribe propagates when passing in a SingleSubscriber and not a Subscriber + * @throws InterruptedException if the test is interrupted */ @Test public void testUnsubscribe2() throws InterruptedException { - MultipleAssignmentDisposable md = new MultipleAssignmentDisposable(); + final MultipleAssignmentDisposable md = new MultipleAssignmentDisposable(); SingleSubscriber ts = new SingleSubscriber() { @Override @@ -272,30 +318,36 @@ public void onError(Throwable error) { final AtomicBoolean interrupted = new AtomicBoolean(); final CountDownLatch latch = new CountDownLatch(2); - Single s1 = Single.create(s -> { - MultipleAssignmentDisposable mad = new MultipleAssignmentDisposable(); - s.onSubscribe(mad); - final Thread t = new Thread(new Runnable() { + Single s1 = Single.create(new SingleOnSubscribe() { + @Override + public void accept(final SingleSubscriber s) { + MultipleAssignmentDisposable mad = new MultipleAssignmentDisposable(); + s.onSubscribe(mad); + final Thread t = new Thread(new Runnable() { + + @Override + public void run() { + try { + Thread.sleep(5000); + s.onSuccess("success"); + } catch (InterruptedException e) { + interrupted.set(true); + latch.countDown(); + } + } - @Override - public void run() { - try { - Thread.sleep(5000); - s.onSuccess("success"); - } catch (InterruptedException e) { - interrupted.set(true); + }); + mad.set(new Disposable() { + @Override + public void dispose() { + unsubscribed.set(true); + t.interrupt(); latch.countDown(); } - } - - }); - mad.set(() -> { - unsubscribed.set(true); - t.interrupt(); - latch.countDown(); - }); - t.start(); + }); + t.start(); + } }); s1.subscribe(ts); @@ -314,6 +366,7 @@ public void run() { /** * Assert that unsubscribe propagates when passing in a SingleSubscriber and not a Subscriber + * @throws InterruptedException if the test is interrupted */ @Test public void testUnsubscribeViaReturnedSubscription() throws InterruptedException { @@ -321,30 +374,36 @@ public void testUnsubscribeViaReturnedSubscription() throws InterruptedException final AtomicBoolean interrupted = new AtomicBoolean(); final CountDownLatch latch = new CountDownLatch(2); - Single s1 = Single.create(s -> { - MultipleAssignmentDisposable mad = new MultipleAssignmentDisposable(); - s.onSubscribe(mad); - final Thread t = new Thread(new Runnable() { + Single s1 = Single.create(new SingleOnSubscribe() { + @Override + public void accept(final SingleSubscriber s) { + MultipleAssignmentDisposable mad = new MultipleAssignmentDisposable(); + s.onSubscribe(mad); + final Thread t = new Thread(new Runnable() { + + @Override + public void run() { + try { + Thread.sleep(5000); + s.onSuccess("success"); + } catch (InterruptedException e) { + interrupted.set(true); + latch.countDown(); + } + } - @Override - public void run() { - try { - Thread.sleep(5000); - s.onSuccess("success"); - } catch (InterruptedException e) { - interrupted.set(true); + }); + mad.set(new Disposable() { + @Override + public void dispose() { + unsubscribed.set(true); + t.interrupt(); latch.countDown(); } - } - - }); - mad.set(() -> { - unsubscribed.set(true); - t.interrupt(); - latch.countDown(); - }); - t.start(); + }); + t.start(); + } }); Disposable subscription = s1.subscribe(); @@ -363,12 +422,15 @@ public void run() { @Test public void testBackpressureAsObservable() { - Single s = Single.create(t -> { - t.onSubscribe(EmptyDisposable.INSTANCE); - t.onSuccess("hello"); + Single s = Single.create(new SingleOnSubscribe() { + @Override + public void accept(SingleSubscriber t) { + t.onSubscribe(EmptyDisposable.INSTANCE); + t.onSuccess("hello"); + } }); - TestSubscriber ts = new TestSubscriber<>((Long)null); + TestSubscriber ts = new TestSubscriber((Long)null); s.subscribe(ts); @@ -382,7 +444,7 @@ public void testBackpressureAsObservable() { @Test public void testToObservable() { Observable a = Single.just("a").toFlowable(); - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); a.subscribe(ts); ts.assertValue("a"); ts.assertNoErrors(); diff --git a/src/test/java/io/reactivex/StartWithTests.java b/src/test/java/io/reactivex/StartWithTests.java index bcd61a3628..4ae91ae6fe 100644 --- a/src/test/java/io/reactivex/StartWithTests.java +++ b/src/test/java/io/reactivex/StartWithTests.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -19,6 +19,8 @@ import org.junit.Test; +import io.reactivex.Observable; + public class StartWithTests { @Test @@ -32,7 +34,7 @@ public void startWith1() { @Test public void startWithIterable() { - List li = new ArrayList<>(); + List li = new ArrayList(); li.add("alpha"); li.add("beta"); List values = Observable.just("one", "two").startWith(li).toList().toBlocking().single(); @@ -45,7 +47,7 @@ public void startWithIterable() { @Test public void startWithObservable() { - List li = new ArrayList<>(); + List li = new ArrayList(); li.add("alpha"); li.add("beta"); List values = Observable.just("one", "two") diff --git a/src/test/java/io/reactivex/SubscriberTest.java b/src/test/java/io/reactivex/SubscriberTest.java index b18592b445..46b0ae00b6 100644 --- a/src/test/java/io/reactivex/SubscriberTest.java +++ b/src/test/java/io/reactivex/SubscriberTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -23,6 +23,7 @@ import org.reactivestreams.*; import io.reactivex.Observable.Operator; +import io.reactivex.internal.functions.Functions; import io.reactivex.subscribers.*; public class SubscriberTest { @@ -32,7 +33,7 @@ public class SubscriberTest { */ @Test public void testRequestFromFinalSubscribeWithRequestValue() { - TestSubscriber s = new TestSubscriber<>((Long)null); + TestSubscriber s = new TestSubscriber((Long)null); s.request(10); final AtomicLong r = new AtomicLong(); s.onSubscribe(new Subscription() { @@ -56,7 +57,7 @@ public void cancel() { */ @Test public void testRequestFromFinalSubscribeWithoutRequestValue() { - TestSubscriber s = new TestSubscriber<>(); + TestSubscriber s = new TestSubscriber(); final AtomicLong r = new AtomicLong(); s.onSubscribe(new Subscription() { @@ -76,29 +77,34 @@ public void cancel() { @Test public void testRequestFromChainedOperator() { - TestSubscriber s = new TestSubscriber<>(); - Operator o = s1 -> new Subscriber() { - - @Override - public void onSubscribe(Subscription a) { - s1.onSubscribe(a); - } - + TestSubscriber s = new TestSubscriber(); + Operator o = new Operator() { @Override - public void onComplete() { + public Subscriber apply(final Subscriber s1) { + return new Subscriber() { - } + @Override + public void onSubscribe(Subscription a) { + s1.onSubscribe(a); + } + + @Override + public void onComplete() { - @Override - public void onError(Throwable e) { + } - } + @Override + public void onError(Throwable e) { - @Override - public void onNext(String t) { + } - } + @Override + public void onNext(String t) { + + } + }; + } }; s.request(10); Subscriber ns = o.apply(s); @@ -124,29 +130,34 @@ public void cancel() { @Test public void testRequestFromDecoupledOperator() { - TestSubscriber s = new TestSubscriber<>((Long)null); - Operator o = s1 -> new Subscriber() { - - @Override - public void onSubscribe(Subscription a) { - s1.onSubscribe(a); - } - + TestSubscriber s = new TestSubscriber((Long)null); + Operator o = new Operator() { @Override - public void onComplete() { + public Subscriber apply(final Subscriber s1) { + return new Subscriber() { - } + @Override + public void onSubscribe(Subscription a) { + s1.onSubscribe(a); + } + + @Override + public void onComplete() { - @Override - public void onError(Throwable e) { + } - } + @Override + public void onError(Throwable e) { - @Override - public void onNext(String t) { + } - } + @Override + public void onNext(String t) { + + } + }; + } }; s.request(10); Subscriber ns = o.apply(s); @@ -172,50 +183,53 @@ public void cancel() { @Test public void testRequestFromDecoupledOperatorThatRequestsN() { - TestSubscriber s = new TestSubscriber<>(); + TestSubscriber s = new TestSubscriber(); final AtomicLong innerR = new AtomicLong(); - Operator o = child -> { - // we want to decouple the chain so set our own Producer on the child instead of it coming from the parent - child.onSubscribe(new Subscription() { - - @Override - public void request(long n) { - innerR.set(n); - } - - @Override - public void cancel() { + Operator o = new Operator() { + @Override + public Subscriber apply(Subscriber child) { + // we want to decouple the chain so set our own Producer on the child instead of it coming from the parent + child.onSubscribe(new Subscription() { + + @Override + public void request(long n) { + innerR.set(n); + } - } + @Override + public void cancel() { + + } - }); + }); - AsyncObserver as = new AsyncObserver() { - - @Override - protected void onStart() { - // we request 99 up to the parent - request(99); - } - - @Override - public void onComplete() { + AsyncObserver as = new AsyncObserver() { + + @Override + protected void onStart() { + // we request 99 up to the parent + request(99); + } + + @Override + public void onComplete() { - } + } - @Override - public void onError(Throwable e) { + @Override + public void onError(Throwable e) { - } + } - @Override - public void onNext(String t) { + @Override + public void onNext(String t) { - } - - - }; - return as; + } + + + }; + return as; + } }; s.request(10); Subscriber ns = o.apply(s); @@ -242,62 +256,77 @@ public void cancel() { @Test public void testRequestToObservable() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); ts.request(3); final AtomicLong requested = new AtomicLong(); - Observable.create(s -> s.onSubscribe(new Subscription() { - + Observable.create(new Publisher() { @Override - public void request(long n) { - requested.set(n); - } + public void subscribe(Subscriber s) { + s.onSubscribe(new Subscription() { - @Override - public void cancel() { - + @Override + public void request(long n) { + requested.set(n); + } + + @Override + public void cancel() { + + } + }); } - })).subscribe(ts); + }).subscribe(ts); assertEquals(3, requested.get()); } @Test public void testRequestThroughMap() { - TestSubscriber ts = new TestSubscriber<>((Long)null); + TestSubscriber ts = new TestSubscriber((Long)null); ts.request(3); final AtomicLong requested = new AtomicLong(); - Observable.create(s -> s.onSubscribe(new Subscription() { - + Observable.create(new Publisher() { @Override - public void request(long n) { - requested.set(n); - } + public void subscribe(Subscriber s) { + s.onSubscribe(new Subscription() { - @Override - public void cancel() { - + @Override + public void request(long n) { + requested.set(n); + } + + @Override + public void cancel() { + + } + }); } - })).map(v -> v).subscribe(ts); + }).map(Functions.identity()).subscribe(ts); assertEquals(3, requested.get()); } @Test public void testRequestThroughTakeThatReducesRequest() { - TestSubscriber ts = new TestSubscriber<>((Long)null); + TestSubscriber ts = new TestSubscriber((Long)null); ts.request(3); final AtomicLong requested = new AtomicLong(); - Observable.create(s -> s.onSubscribe(new Subscription() { - + Observable.create(new Publisher() { @Override - public void request(long n) { - requested.set(n); - } + public void subscribe(Subscriber s) { + s.onSubscribe(new Subscription() { - @Override - public void cancel() { - + @Override + public void request(long n) { + requested.set(n); + } + + @Override + public void cancel() { + + } + + }); } - - })).take(2).subscribe(ts); + }).take(2).subscribe(ts); // FIXME the take now requests Long.MAX_PATH if downstream requests at least the limit assertEquals(Long.MAX_VALUE, requested.get()); @@ -305,22 +334,27 @@ public void cancel() { @Test public void testRequestThroughTakeWhereRequestIsSmallerThanTake() { - TestSubscriber ts = new TestSubscriber<>((Long)null); + TestSubscriber ts = new TestSubscriber((Long)null); ts.request(3); final AtomicLong requested = new AtomicLong(); - Observable.create(s -> s.onSubscribe(new Subscription() { - - @Override - public void request(long n) { - requested.set(n); - } - + Observable.create(new Publisher() { @Override - public void cancel() { - - } + public void subscribe(Subscriber s) { + s.onSubscribe(new Subscription() { - })).take(10).subscribe(ts); + @Override + public void request(long n) { + requested.set(n); + } + + @Override + public void cancel() { + + } + + }); + } + }).take(10).subscribe(ts); assertEquals(3, requested.get()); } @@ -429,7 +463,7 @@ public void onNext(Integer t) { @Test public void testNegativeRequestThrowsIllegalArgumentException() throws InterruptedException { final CountDownLatch latch = new CountDownLatch(1); - final AtomicReference exception = new AtomicReference<>(); + final AtomicReference exception = new AtomicReference(); Observable.just(1,2,3,4).subscribe(new Observer() { @Override @@ -460,7 +494,7 @@ public void onNext(Integer t) { @Test public void testOnStartRequestsAreAdditive() { - final List list = new ArrayList<>(); + final List list = new ArrayList(); Observable.just(1,2,3,4,5).subscribe(new Observer() { @Override public void onStart() { @@ -487,7 +521,7 @@ public void onNext(Integer t) { @Test public void testOnStartRequestsAreAdditiveAndOverflowBecomesMaxValue() { - final List list = new ArrayList<>(); + final List list = new ArrayList(); Observable.just(1,2,3,4,5).subscribe(new Observer() { @Override public void onStart() { diff --git a/src/test/java/io/reactivex/TestHelper.java b/src/test/java/io/reactivex/TestHelper.java index 1a3d235561..3c1bd2efa0 100644 --- a/src/test/java/io/reactivex/TestHelper.java +++ b/src/test/java/io/reactivex/TestHelper.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -17,6 +17,8 @@ import static org.mockito.Mockito.mock; import org.mockito.Mockito; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; import org.reactivestreams.*; import io.reactivex.NbpObservable.NbpSubscriber; @@ -28,17 +30,21 @@ public enum TestHelper { ; /** * Mocks a subscriber and prepares it to request Long.MAX_VALUE. + * @param the value type * @return the mocked subscriber */ @SuppressWarnings("unchecked") public static Subscriber mockSubscriber() { Subscriber w = mock(Subscriber.class); - Mockito.doAnswer(a -> { - Subscription s = a.getArgumentAt(0, Subscription.class); - s.request(Long.MAX_VALUE); - return null; - }).when(w).onSubscribe(any()); + Mockito.doAnswer(new Answer() { + @Override + public Object answer(InvocationOnMock a) throws Throwable { + Subscription s = a.getArgumentAt(0, Subscription.class); + s.request(Long.MAX_VALUE); + return null; + } + }).when(w).onSubscribe((Subscription)any()); return w; } diff --git a/src/test/java/io/reactivex/ThrottleLastTests.java b/src/test/java/io/reactivex/ThrottleLastTests.java index 3da394b7aa..e0d753d8f3 100644 --- a/src/test/java/io/reactivex/ThrottleLastTests.java +++ b/src/test/java/io/reactivex/ThrottleLastTests.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 diff --git a/src/test/java/io/reactivex/ThrottleWithTimeoutTests.java b/src/test/java/io/reactivex/ThrottleWithTimeoutTests.java index 2aeb65f72e..a9d8ff3ec4 100644 --- a/src/test/java/io/reactivex/ThrottleWithTimeoutTests.java +++ b/src/test/java/io/reactivex/ThrottleWithTimeoutTests.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,7 +13,7 @@ package io.reactivex; -import static org.mockito.Mockito.*; +import static org.mockito.Mockito.inOrder; import java.util.concurrent.TimeUnit; diff --git a/src/test/java/io/reactivex/ZipTests.java b/src/test/java/io/reactivex/ZipTests.java index aeaa21aefc..49b819db61 100644 --- a/src/test/java/io/reactivex/ZipTests.java +++ b/src/test/java/io/reactivex/ZipTests.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -16,27 +16,48 @@ import static org.junit.Assert.*; import java.util.*; -import java.util.function.*; import org.junit.Test; +import org.reactivestreams.Publisher; +import io.reactivex.Observable; import io.reactivex.CovarianceTest.*; +import io.reactivex.EventStream.Event; +import io.reactivex.functions.*; +import io.reactivex.observables.GroupedObservable; public class ZipTests { @Test public void testZipObservableOfObservables() { EventStream.getEventStream("HTTP-ClusterB", 20) - .groupBy(e -> e.instanceId) + .groupBy(new Function() { + @Override + public String apply(Event e) { + return e.instanceId; + } + }) // now we have streams of cluster+instanceId - .flatMap(ge -> { - return ge.scan(new HashMap(), (accum, perInstanceEvent) -> { - accum.put("instance", ge.key()); - return accum; - }); + .flatMap(new Function, Publisher>>() { + @Override + public Publisher> apply(final GroupedObservable ge) { + return ge.scan(new HashMap(), new BiFunction, Event, HashMap>() { + @Override + public HashMap apply(HashMap accum, + Event perInstanceEvent) { + accum.put("instance", ge.key()); + return accum; + } + }); + } }) .take(10) - .toBlocking().forEach(System.out::println); + .toBlocking().forEach(new Consumer>() { + @Override + public void accept(HashMap v) { + System.out.println(v); + } + }); System.out.println("**** finished"); } @@ -71,20 +92,36 @@ public void nonBlockingObservable() { Collection> observables = Collections.emptyList(); - Observable result = Observable.zip(observables, args -> { - System.out.println("received: " + args); - assertEquals("No argument should have been passed", 0, args.length); - return invoked; + Observable result = Observable.zip(observables, new Function() { + @Override + public Object apply(Object[] args) { + System.out.println("received: " + args); + assertEquals("No argument should have been passed", 0, args.length); + return invoked; + } }); assertSame(invoked, result.toBlocking().last()); } - BiFunction combine = (m, r) -> { - return new ExtendedResult(); + BiFunction combine = new BiFunction() { + @Override + public ExtendedResult apply(Media m, Rating r) { + return new ExtendedResult(); + } }; - Consumer action = t1 -> System.out.println("Result: " + t1); + Consumer action = new Consumer() { + @Override + public void accept(Result t1) { + System.out.println("Result: " + t1); + } + }; - Consumer extendedAction = t1 -> System.out.println("Result: " + t1); + Consumer extendedAction = new Consumer() { + @Override + public void accept(ExtendedResult t1) { + System.out.println("Result: " + t1); + } + }; } \ No newline at end of file diff --git a/src/test/java/io/reactivex/disposables/CompositeDisposableTest.java b/src/test/java/io/reactivex/disposables/CompositeDisposableTest.java index 9c8375cd2b..93d7c172fc 100644 --- a/src/test/java/io/reactivex/disposables/CompositeDisposableTest.java +++ b/src/test/java/io/reactivex/disposables/CompositeDisposableTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -68,7 +68,7 @@ public void dispose() { }); } - final List threads = new ArrayList<>(); + final List threads = new ArrayList(); for (int i = 0; i < count; i++) { final Thread t = new Thread() { @Override @@ -249,7 +249,7 @@ public void dispose() { }); - final List threads = new ArrayList<>(); + final List threads = new ArrayList(); for (int i = 0; i < count; i++) { final Thread t = new Thread() { @Override diff --git a/src/test/java/io/reactivex/disposables/DisposablesTest.java b/src/test/java/io/reactivex/disposables/DisposablesTest.java index 2572d2a43a..bba0c6686c 100644 --- a/src/test/java/io/reactivex/disposables/DisposablesTest.java +++ b/src/test/java/io/reactivex/disposables/DisposablesTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 diff --git a/src/test/java/io/reactivex/disposables/MultipleAssignmentDisposableTest.java b/src/test/java/io/reactivex/disposables/MultipleAssignmentDisposableTest.java index 6962d57ec8..eade769846 100644 --- a/src/test/java/io/reactivex/disposables/MultipleAssignmentDisposableTest.java +++ b/src/test/java/io/reactivex/disposables/MultipleAssignmentDisposableTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 diff --git a/src/test/java/io/reactivex/disposables/RefCountDisposableTest.java b/src/test/java/io/reactivex/disposables/RefCountDisposableTest.java index 1c59a1da25..edd9173875 100644 --- a/src/test/java/io/reactivex/disposables/RefCountDisposableTest.java +++ b/src/test/java/io/reactivex/disposables/RefCountDisposableTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,13 +13,9 @@ package io.reactivex.disposables; -import static org.mockito.Mockito.inOrder; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.times; +import static org.mockito.Mockito.*; -import org.junit.Before; -import org.junit.Test; +import org.junit.*; import org.mockito.InOrder; public class RefCountDisposableTest { diff --git a/src/test/java/io/reactivex/disposables/SerialDisposableTests.java b/src/test/java/io/reactivex/disposables/SerialDisposableTests.java index 7b25c53d55..b0c821d6f5 100644 --- a/src/test/java/io/reactivex/disposables/SerialDisposableTests.java +++ b/src/test/java/io/reactivex/disposables/SerialDisposableTests.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -115,7 +115,7 @@ public void settingUnderlyingWhenUnsubscribedCausesImmediateUnsubscriptionConcur final int count = 10; final CountDownLatch end = new CountDownLatch(count); - final List threads = new ArrayList<>(); + final List threads = new ArrayList(); for (int i = 0; i < count; i++) { final Thread t = new Thread() { @Override @@ -150,12 +150,12 @@ public void run() { public void concurrentSetDisposableShouldNotInterleave() throws InterruptedException { final int count = 10; - final List subscriptions = new ArrayList<>(); + final List subscriptions = new ArrayList(); final CountDownLatch start = new CountDownLatch(1); final CountDownLatch end = new CountDownLatch(count); - final List threads = new ArrayList<>(); + final List threads = new ArrayList(); for (int i = 0; i < count; i++) { final Disposable subscription = mock(Disposable.class); subscriptions.add(subscription); diff --git a/src/test/java/io/reactivex/exceptions/TestException.java b/src/test/java/io/reactivex/exceptions/TestException.java index 0aa930811f..5db7977581 100644 --- a/src/test/java/io/reactivex/exceptions/TestException.java +++ b/src/test/java/io/reactivex/exceptions/TestException.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 diff --git a/src/test/java/io/reactivex/internal/operators/BackpressureHelperTest.java b/src/test/java/io/reactivex/internal/operators/BackpressureHelperTest.java index 491c1dd32b..d3674fe83a 100644 --- a/src/test/java/io/reactivex/internal/operators/BackpressureHelperTest.java +++ b/src/test/java/io/reactivex/internal/operators/BackpressureHelperTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 diff --git a/src/test/java/io/reactivex/internal/operators/BlockingOperatorLatestTest.java b/src/test/java/io/reactivex/internal/operators/BlockingOperatorLatestTest.java index b454b4d20a..ab123c2c00 100644 --- a/src/test/java/io/reactivex/internal/operators/BlockingOperatorLatestTest.java +++ b/src/test/java/io/reactivex/internal/operators/BlockingOperatorLatestTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 diff --git a/src/test/java/io/reactivex/internal/operators/BlockingOperatorMostRecentTest.java b/src/test/java/io/reactivex/internal/operators/BlockingOperatorMostRecentTest.java index 0aa92a6562..e4221555f6 100644 --- a/src/test/java/io/reactivex/internal/operators/BlockingOperatorMostRecentTest.java +++ b/src/test/java/io/reactivex/internal/operators/BlockingOperatorMostRecentTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,8 +13,8 @@ package io.reactivex.internal.operators; -import static org.junit.Assert.*; import static io.reactivex.internal.operators.BlockingOperatorMostRecent.mostRecent; +import static org.junit.Assert.*; import java.util.Iterator; import java.util.concurrent.TimeUnit; diff --git a/src/test/java/io/reactivex/internal/operators/BlockingOperatorNextTest.java b/src/test/java/io/reactivex/internal/operators/BlockingOperatorNextTest.java index e26b6bd15d..62e249abd9 100644 --- a/src/test/java/io/reactivex/internal/operators/BlockingOperatorNextTest.java +++ b/src/test/java/io/reactivex/internal/operators/BlockingOperatorNextTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -25,6 +25,7 @@ import io.reactivex.Observable; import io.reactivex.exceptions.TestException; +import io.reactivex.internal.operators.BlockingOperatorNext; import io.reactivex.internal.subscriptions.EmptySubscription; import io.reactivex.observables.BlockingObservable; import io.reactivex.schedulers.Schedulers; diff --git a/src/test/java/io/reactivex/internal/operators/BlockingOperatorToIteratorTest.java b/src/test/java/io/reactivex/internal/operators/BlockingOperatorToIteratorTest.java index b8d8b3f359..d02df09f88 100644 --- a/src/test/java/io/reactivex/internal/operators/BlockingOperatorToIteratorTest.java +++ b/src/test/java/io/reactivex/internal/operators/BlockingOperatorToIteratorTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 diff --git a/src/test/java/io/reactivex/internal/operators/BufferUntilSubscriberTest.java b/src/test/java/io/reactivex/internal/operators/BufferUntilSubscriberTest.java index e9e012ad01..7912fd5d95 100644 --- a/src/test/java/io/reactivex/internal/operators/BufferUntilSubscriberTest.java +++ b/src/test/java/io/reactivex/internal/operators/BufferUntilSubscriberTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,12 +13,15 @@ package io.reactivex.internal.operators; +import java.util.List; import java.util.concurrent.*; import java.util.concurrent.atomic.*; import org.junit.*; +import org.reactivestreams.Publisher; import io.reactivex.Observable; +import io.reactivex.functions.*; import io.reactivex.schedulers.Schedulers; import io.reactivex.subjects.PublishSubject; @@ -39,23 +42,32 @@ public void testIssue1677() throws InterruptedException { Observable.fromArray(numbers) .takeUntil(s) .window(50) - .flatMap(integerObservable -> { - return integerObservable - .subscribeOn(Schedulers.computation()) - .map(integer -> { - if (integer >= 5 && completed.compareAndSet(false, true)) { - s.onComplete(); + .flatMap(new Function, Publisher>() { + @Override + public Publisher apply(Observable integerObservable) { + return integerObservable + .subscribeOn(Schedulers.computation()) + .map(new Function() { + @Override + public Object apply(Integer integer) { + if (integer >= 5 && completed.compareAndSet(false, true)) { + s.onComplete(); + } + // do some work + Math.pow(Math.random(), Math.random()); + return integer * 2; } - // do some work - Math.pow(Math.random(), Math.random()); - return integer * 2; - }); + }); + } }) .toList() - .doOnNext(integers -> { - counter.incrementAndGet(); - latch.countDown(); - innerLatch.countDown(); + .doOnNext(new Consumer>() { + @Override + public void accept(List integers) { + counter.incrementAndGet(); + latch.countDown(); + innerLatch.countDown(); + } }) .subscribe(); if (!innerLatch.await(30, TimeUnit.SECONDS)) diff --git a/src/test/java/io/reactivex/internal/operators/CachedObservableTest.java b/src/test/java/io/reactivex/internal/operators/CachedObservableTest.java index 3a6314d183..46dad13f44 100644 --- a/src/test/java/io/reactivex/internal/operators/CachedObservableTest.java +++ b/src/test/java/io/reactivex/internal/operators/CachedObservableTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -25,6 +25,8 @@ import io.reactivex.Observable; import io.reactivex.exceptions.TestException; +import io.reactivex.functions.Consumer; +import io.reactivex.internal.operators.CachedObservable; import io.reactivex.internal.subscriptions.EmptySubscription; import io.reactivex.schedulers.Schedulers; import io.reactivex.subscribers.TestSubscriber; @@ -36,7 +38,7 @@ public void testColdReplayNoBackpressure() { assertFalse("Source is connected!", source.isConnected()); - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); source.subscribe(ts); @@ -58,7 +60,7 @@ public void testColdReplayBackpressure() { assertFalse("Source is connected!", source.isConnected()); - TestSubscriber ts = new TestSubscriber<>((Long)null); + TestSubscriber ts = new TestSubscriber((Long)null); ts.request(10); source.subscribe(ts); @@ -104,17 +106,23 @@ public void run() { final CountDownLatch latch = new CountDownLatch(2); // subscribe once - o.subscribe(v -> { - assertEquals("one", v); - System.out.println("v: " + v); - latch.countDown(); + o.subscribe(new Consumer() { + @Override + public void accept(String v) { + assertEquals("one", v); + System.out.println("v: " + v); + latch.countDown(); + } }); // subscribe again - o.subscribe(v -> { - assertEquals("one", v); - System.out.println("v: " + v); - latch.countDown(); + o.subscribe(new Consumer() { + @Override + public void accept(String v) { + assertEquals("one", v); + System.out.println("v: " + v); + latch.countDown(); + } }); if (!latch.await(1000, TimeUnit.MILLISECONDS)) { @@ -135,7 +143,7 @@ public void testUnsubscribeSource() { @Test public void testTake() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); CachedObservable cached = CachedObservable.from(Observable.range(1, 100)); cached.take(10).subscribe(ts); @@ -151,7 +159,7 @@ public void testTake() { public void testAsync() { Observable source = Observable.range(1, 10000); for (int i = 0; i < 100; i++) { - TestSubscriber ts1 = new TestSubscriber<>(); + TestSubscriber ts1 = new TestSubscriber(); CachedObservable cached = CachedObservable.from(source); @@ -162,7 +170,7 @@ public void testAsync() { ts1.assertComplete(); assertEquals(10000, ts1.values().size()); - TestSubscriber ts2 = new TestSubscriber<>(); + TestSubscriber ts2 = new TestSubscriber(); cached.observeOn(Schedulers.computation()).subscribe(ts2); ts2.awaitTerminalEvent(2, TimeUnit.SECONDS); @@ -180,14 +188,14 @@ public void testAsyncComeAndGo() { Observable output = cached.observeOn(Schedulers.computation()); - List> list = new ArrayList<>(100); + List> list = new ArrayList>(100); for (int i = 0; i < 100; i++) { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); list.add(ts); output.skip(i * 10).take(10).subscribe(ts); } - List expected = new ArrayList<>(); + List expected = new ArrayList(); for (int i = 0; i < 10; i++) { expected.add((long)(i - 10)); } @@ -221,7 +229,7 @@ public void subscribe(Subscriber t) { } }); - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); firehose.cache().observeOn(Schedulers.computation()).takeLast(100).subscribe(ts); ts.awaitTerminalEvent(3, TimeUnit.SECONDS); @@ -238,14 +246,14 @@ public void testValuesAndThenError() { .cache(); - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); source.subscribe(ts); ts.assertValues(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); ts.assertNotComplete(); ts.assertError(TestException.class); - TestSubscriber ts2 = new TestSubscriber<>(); + TestSubscriber ts2 = new TestSubscriber(); source.subscribe(ts2); ts2.assertValues(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); @@ -258,7 +266,12 @@ public void unsafeChildThrows() { final AtomicInteger count = new AtomicInteger(); Observable source = Observable.range(1, 100) - .doOnNext(t -> count.getAndIncrement()) + .doOnNext(new Consumer() { + @Override + public void accept(Integer t) { + count.getAndIncrement(); + } + }) .cache(); TestSubscriber ts = new TestSubscriber() { diff --git a/src/test/java/io/reactivex/internal/operators/NotificationLiteTest.java b/src/test/java/io/reactivex/internal/operators/NotificationLiteTest.java index 3d9ccebbfe..d5f6db73cf 100644 --- a/src/test/java/io/reactivex/internal/operators/NotificationLiteTest.java +++ b/src/test/java/io/reactivex/internal/operators/NotificationLiteTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 diff --git a/src/test/java/io/reactivex/internal/operators/OnSubscribeAmbTest.java b/src/test/java/io/reactivex/internal/operators/OnSubscribeAmbTest.java index 7e08b23b33..71195544e7 100644 --- a/src/test/java/io/reactivex/internal/operators/OnSubscribeAmbTest.java +++ b/src/test/java/io/reactivex/internal/operators/OnSubscribeAmbTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,13 +13,12 @@ package io.reactivex.internal.operators; -import static org.junit.Assert.assertEquals; +import static org.junit.Assert.*; import static org.mockito.Mockito.*; import java.io.IOException; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicLong; -import java.util.function.Consumer; import org.junit.*; import org.mockito.InOrder; @@ -27,7 +26,9 @@ import io.reactivex.*; import io.reactivex.disposables.CompositeDisposable; +import io.reactivex.functions.Consumer; import io.reactivex.schedulers.*; +import io.reactivex.subjects.PublishSubject; import io.reactivex.subscribers.TestSubscriber; public class OnSubscribeAmbTest { @@ -47,7 +48,7 @@ private Observable createObservable(final String[] values, @Override public void subscribe(final Subscriber subscriber) { - CompositeDisposable parentSubscription = new CompositeDisposable(); + final CompositeDisposable parentSubscription = new CompositeDisposable(); subscriber.onSubscribe(new Subscription() { @Override @@ -63,17 +64,24 @@ public void cancel() { long delay = interval; for (final String value : values) { - parentSubscription.add(innerScheduler.schedule(() -> - subscriber.onNext(value) + parentSubscription.add(innerScheduler.schedule(new Runnable() { + @Override + public void run() { + subscriber.onNext(value); + } + } , delay, TimeUnit.MILLISECONDS)); delay += interval; } - parentSubscription.add(innerScheduler.schedule(() -> { - if (e == null) { - subscriber.onComplete(); - } else { - subscriber.onError(e); - } + parentSubscription.add(innerScheduler.schedule(new Runnable() { + @Override + public void run() { + if (e == null) { + subscriber.onComplete(); + } else { + subscriber.onError(e); + } + } }, delay, TimeUnit.MILLISECONDS)); } }); @@ -88,6 +96,7 @@ public void testAmb() { Observable observable3 = createObservable(new String[] { "3", "33", "333", "3333" }, 3000, null); + @SuppressWarnings("unchecked") Observable o = Observable.amb(observable1, observable2, observable3); @@ -117,6 +126,7 @@ public void testAmb2() { Observable observable3 = createObservable(new String[] {}, 3000, new IOException("fake exception")); + @SuppressWarnings("unchecked") Observable o = Observable.amb(observable1, observable2, observable3); @@ -144,6 +154,7 @@ public void testAmb3() { Observable observable3 = createObservable(new String[] { "3" }, 3000, null); + @SuppressWarnings("unchecked") Observable o = Observable.amb(observable1, observable2, observable3); @@ -157,9 +168,10 @@ public void testAmb3() { inOrder.verifyNoMoreInteractions(); } + @SuppressWarnings("unchecked") @Test public void testProducerRequestThroughAmb() { - TestSubscriber ts = new TestSubscriber<>((Long)null); + TestSubscriber ts = new TestSubscriber((Long)null); ts.request(3); final AtomicLong requested1 = new AtomicLong(); final AtomicLong requested2 = new AtomicLong(); @@ -210,7 +222,7 @@ public void cancel() { @Test public void testBackpressure() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); Observable.range(0, Observable.bufferSize() * 2) .ambWith(Observable.range(0, Observable.bufferSize() * 2)) .observeOn(Schedulers.computation()) // observeOn has a backpressured RxRingBuffer @@ -223,10 +235,16 @@ public void testBackpressure() { } + @SuppressWarnings("unchecked") @Test public void testSubscriptionOnlyHappensOnce() throws InterruptedException { final AtomicLong count = new AtomicLong(); - Consumer incrementer = s -> count.incrementAndGet(); + Consumer incrementer = new Consumer() { + @Override + public void accept(Subscription s) { + count.incrementAndGet(); + } + }; //this aync stream should emit first Observable o1 = Observable.just(1).doOnSubscribe(incrementer) @@ -234,7 +252,7 @@ public void testSubscriptionOnlyHappensOnce() throws InterruptedException { //this stream emits second Observable o2 = Observable.just(1).doOnSubscribe(incrementer) .delay(100, TimeUnit.MILLISECONDS).subscribeOn(Schedulers.computation()); - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); Observable.amb(o1, o2).subscribe(ts); ts.request(1); ts.awaitTerminalEvent(5, TimeUnit.SECONDS); @@ -242,6 +260,7 @@ public void testSubscriptionOnlyHappensOnce() throws InterruptedException { assertEquals(2, count.get()); } + @SuppressWarnings("unchecked") @Test public void testSecondaryRequestsPropagatedToChildren() throws InterruptedException { //this aync stream should emit first @@ -250,7 +269,7 @@ public void testSecondaryRequestsPropagatedToChildren() throws InterruptedExcept //this stream emits second Observable o2 = Observable.fromArray(4, 5, 6) .delay(200, TimeUnit.MILLISECONDS).subscribeOn(Schedulers.computation()); - TestSubscriber ts = new TestSubscriber<>(1L); + TestSubscriber ts = new TestSubscriber(1L); Observable.amb(o1, o2).subscribe(ts); // before first emission request 20 more @@ -268,14 +287,39 @@ public void testSynchronousSources() { // then second observable does not get subscribed to before first // subscription completes hence first observable emits result through // amb - int result = Observable.just(1).doOnNext(t -> { - try { - Thread.sleep(100); - } catch (InterruptedException e) { - // - } + int result = Observable.just(1).doOnNext(new Consumer() { + @Override + public void accept(Integer t) { + try { + Thread.sleep(100); + } catch (InterruptedException e) { + // + } + } }).ambWith(Observable.just(2)).toBlocking().single(); assertEquals(1, result); } - + + @SuppressWarnings("unchecked") + @Test + public void testAmbCancelsOthers() { + PublishSubject source1 = PublishSubject.create(); + PublishSubject source2 = PublishSubject.create(); + PublishSubject source3 = PublishSubject.create(); + + TestSubscriber ts = new TestSubscriber(); + + Observable.amb(source1, source2, source3).subscribe(ts); + + assertTrue("Source 1 doesn't have subscribers!", source1.hasSubscribers()); + assertTrue("Source 2 doesn't have subscribers!", source2.hasSubscribers()); + assertTrue("Source 3 doesn't have subscribers!", source3.hasSubscribers()); + + source1.onNext(1); + + assertTrue("Source 1 doesn't have subscribers!", source1.hasSubscribers()); + assertFalse("Source 2 still has subscribers!", source2.hasSubscribers()); + assertFalse("Source 2 still has subscribers!", source3.hasSubscribers()); + + } } \ No newline at end of file diff --git a/src/test/java/io/reactivex/internal/operators/OnSubscribeCombineLatestTest.java b/src/test/java/io/reactivex/internal/operators/OnSubscribeCombineLatestTest.java index ee665ffda3..c9ab0bd385 100644 --- a/src/test/java/io/reactivex/internal/operators/OnSubscribeCombineLatestTest.java +++ b/src/test/java/io/reactivex/internal/operators/OnSubscribeCombineLatestTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -20,15 +20,15 @@ import java.util.*; import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.*; import org.junit.Test; import org.mockito.*; import org.reactivestreams.Subscriber; -import io.reactivex.*; +import io.reactivex.Optional; import io.reactivex.Observable; import io.reactivex.Observer; +import io.reactivex.*; import io.reactivex.functions.*; import io.reactivex.schedulers.Schedulers; import io.reactivex.subjects.PublishSubject; @@ -43,8 +43,11 @@ public void testCombineLatestWithFunctionThatThrowsAnException() { PublishSubject w1 = PublishSubject.create(); PublishSubject w2 = PublishSubject.create(); - Observable combined = Observable.combineLatest(w1, w2, (v1, v2) -> { - throw new RuntimeException("I don't work."); + Observable combined = Observable.combineLatest(w1, w2, new BiFunction() { + @Override + public String apply(String v1, String v2) { + throw new RuntimeException("I don't work."); + } }); combined.subscribe(w); @@ -216,28 +219,41 @@ public void testCombineLatest3TypesB() { } private Function3 getConcat3StringsCombineLatestFunction() { - Function3 combineLatestFunction = (a1, a2, a3) -> { - if (a1 == null) { - a1 = ""; - } - if (a2 == null) { - a2 = ""; - } - if (a3 == null) { - a3 = ""; + Function3 combineLatestFunction = new Function3() { + @Override + public String apply(String a1, String a2, String a3) { + if (a1 == null) { + a1 = ""; + } + if (a2 == null) { + a2 = ""; + } + if (a3 == null) { + a3 = ""; + } + return a1 + a2 + a3; } - return a1 + a2 + a3; }; return combineLatestFunction; } private BiFunction getConcatStringIntegerCombineLatestFunction() { - BiFunction combineLatestFunction = (s, i) -> getStringValue(s) + getStringValue(i); + BiFunction combineLatestFunction = new BiFunction() { + @Override + public String apply(String s, Integer i) { + return getStringValue(s) + getStringValue(i); + } + }; return combineLatestFunction; } private Function3 getConcatStringIntegerIntArrayCombineLatestFunction() { - return (s, i, iArray) -> getStringValue(s) + getStringValue(i) + getStringValue(iArray); + return new Function3() { + @Override + public String apply(String s, Integer i, int[] iArray) { + return getStringValue(s) + getStringValue(i) + getStringValue(iArray); + } + }; } private static String getStringValue(Object o) { @@ -252,7 +268,12 @@ private static String getStringValue(Object o) { } } - BiFunction or = (t1, t2) -> t1 | t2; + BiFunction or = new BiFunction() { + @Override + public Integer apply(Integer t1, Integer t2) { + return t1 | t2; + } + }; @Test public void combineSimple() { @@ -416,8 +437,8 @@ public List apply(Object[] args) { }; for (int i = 1; i <= n; i++) { System.out.println("test1ToNSources: " + i + " sources"); - List> sources = new ArrayList<>(); - List values = new ArrayList<>(); + List> sources = new ArrayList>(); + List values = new ArrayList(); for (int j = 0; j < i; j++) { sources.add(Observable.just(j)); values.add(j); @@ -447,8 +468,8 @@ public List apply(Object[] args) { }; for (int i = 1; i <= n; i++) { System.out.println("test1ToNSourcesScheduled: " + i + " sources"); - List> sources = new ArrayList<>(); - List values = new ArrayList<>(); + List> sources = new ArrayList>(); + List values = new ArrayList(); for (int j = 0; j < i; j++) { sources.add(Observable.just(j).subscribeOn(Schedulers.io())); values.add(j); @@ -496,7 +517,12 @@ public void test2SourcesOverload() { Observable s2 = Observable.just(2); Observable> result = Observable.combineLatest(s1, s2, - (t1, t2) -> Arrays.asList(t1, t2)); + new BiFunction>() { + @Override + public List apply(Integer t1, Integer t2) { + return Arrays.asList(t1, t2); + } + }); Subscriber o = TestHelper.mockSubscriber(); @@ -514,7 +540,12 @@ public void test3SourcesOverload() { Observable s3 = Observable.just(3); Observable> result = Observable.combineLatest(s1, s2, s3, - (Function3>) (t1, t2, t3) -> Arrays.asList(t1, t2, t3)); + new Function3>() { + @Override + public List apply(Integer t1, Integer t2, Integer t3) { + return Arrays.asList(t1, t2, t3); + } + }); Subscriber o = TestHelper.mockSubscriber(); @@ -718,7 +749,7 @@ public void testBackpressure() { BiFunction combineLatestFunction = getConcatStringIntegerCombineLatestFunction(); int NUM = Observable.bufferSize() * 4; - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); Observable.combineLatest( Observable.just("one", "two"), Observable.range(2, NUM), @@ -743,16 +774,24 @@ public void testWithCombineLatestIssue1717() throws InterruptedException { final int SIZE = 2000; Observable timer = Observable.interval(0, 1, TimeUnit.MILLISECONDS) .observeOn(Schedulers.newThread()) - .doOnEach(n -> { - // System.out.println(n); - if (count.incrementAndGet() >= SIZE) { - latch.countDown(); - } + .doOnEach(new Consumer>>() { + @Override + public void accept(Try> n) { + // System.out.println(n); + if (count.incrementAndGet() >= SIZE) { + latch.countDown(); + } + } }).take(SIZE); - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); - Observable.combineLatest(timer, Observable. never(), (t1, t2) -> t1).subscribe(ts); + Observable.combineLatest(timer, Observable. never(), new BiFunction() { + @Override + public Long apply(Long t1, Integer t2) { + return t1; + } + }).subscribe(ts); if (!latch.await(SIZE + 1000, TimeUnit.MILLISECONDS)) { fail("timed out"); @@ -763,6 +802,7 @@ public void testWithCombineLatestIssue1717() throws InterruptedException { @Test(timeout=10000) public void testCombineLatestRequestOverflow() throws InterruptedException { + @SuppressWarnings("unchecked") List> sources = Arrays.asList(Observable.fromArray(1, 2, 3, 4), Observable.fromArray(5,6,7,8)); Observable o = Observable.combineLatest(sources,new Function() { diff --git a/src/test/java/io/reactivex/internal/operators/OnSubscribeDeferTest.java b/src/test/java/io/reactivex/internal/operators/OnSubscribeDeferTest.java index 554188f3b3..25a5ef9d6e 100644 --- a/src/test/java/io/reactivex/internal/operators/OnSubscribeDeferTest.java +++ b/src/test/java/io/reactivex/internal/operators/OnSubscribeDeferTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -16,13 +16,12 @@ import static org.mockito.Matchers.any; import static org.mockito.Mockito.*; -import java.util.function.Supplier; - import org.junit.Test; import org.reactivestreams.Subscriber; import io.reactivex.*; import io.reactivex.exceptions.TestException; +import io.reactivex.functions.Supplier; @SuppressWarnings("unchecked") public class OnSubscribeDeferTest { diff --git a/src/test/java/io/reactivex/internal/operators/OnSubscribeFromIterableTest.java b/src/test/java/io/reactivex/internal/operators/OnSubscribeFromIterableTest.java index 7eae1b5107..443bab026e 100644 --- a/src/test/java/io/reactivex/internal/operators/OnSubscribeFromIterableTest.java +++ b/src/test/java/io/reactivex/internal/operators/OnSubscribeFromIterableTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -27,7 +27,7 @@ import io.reactivex.Observable; import io.reactivex.Observer; -import io.reactivex.TestHelper; +import io.reactivex.*; import io.reactivex.schedulers.Schedulers; import io.reactivex.subscribers.TestSubscriber; @@ -114,13 +114,13 @@ public void testObservableFromIterable() { @Test public void testBackpressureViaRequest() { - ArrayList list = new ArrayList<>(Observable.bufferSize()); + ArrayList list = new ArrayList(Observable.bufferSize()); for (int i = 1; i <= Observable.bufferSize() + 1; i++) { list.add(i); } Observable o = Observable.fromIterable(list); - TestSubscriber ts = new TestSubscriber<>((Long)null); + TestSubscriber ts = new TestSubscriber((Long)null); ts.assertNoValues(); ts.request(1); @@ -140,7 +140,7 @@ public void testBackpressureViaRequest() { public void testNoBackpressure() { Observable o = Observable.fromIterable(Arrays.asList(1, 2, 3, 4, 5)); - TestSubscriber ts = new TestSubscriber<>((Long)null); + TestSubscriber ts = new TestSubscriber((Long)null); ts.assertNoValues(); ts.request(Long.MAX_VALUE); // infinite @@ -156,7 +156,7 @@ public void testSubscribeMultipleTimes() { Observable o = Observable.fromIterable(Arrays.asList(1, 2, 3)); for (int i = 0; i < 10; i++) { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); o.subscribe(ts); diff --git a/src/test/java/io/reactivex/internal/operators/OnSubscribeRangeTest.java b/src/test/java/io/reactivex/internal/operators/OnSubscribeRangeTest.java index a071a78fa2..817f1521b3 100644 --- a/src/test/java/io/reactivex/internal/operators/OnSubscribeRangeTest.java +++ b/src/test/java/io/reactivex/internal/operators/OnSubscribeRangeTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -24,7 +24,8 @@ import io.reactivex.Observable; import io.reactivex.Observer; -import io.reactivex.TestHelper; +import io.reactivex.*; +import io.reactivex.functions.Consumer; import io.reactivex.subscribers.TestSubscriber; public class OnSubscribeRangeTest { @@ -49,7 +50,12 @@ public void testRangeUnsubscribe() { final AtomicInteger count = new AtomicInteger(); - Observable.range(1, 1000).doOnNext(t1 -> count.incrementAndGet()) + Observable.range(1, 1000).doOnNext(new Consumer() { + @Override + public void accept(Integer t1) { + count.incrementAndGet(); + } + }) .take(3).subscribe(observer); verify(observer, times(1)).onNext(1); @@ -90,7 +96,7 @@ public void testRangeWithOverflow5() { public void testBackpressureViaRequest() { Observable o = Observable.range(1, Observable.bufferSize()); - TestSubscriber ts = new TestSubscriber<>((Long)null); + TestSubscriber ts = new TestSubscriber((Long)null); ts.assertNoValues(); ts.request(1); @@ -111,14 +117,14 @@ public void testBackpressureViaRequest() { @Test public void testNoBackpressure() { - ArrayList list = new ArrayList<>(Observable.bufferSize() * 2); + ArrayList list = new ArrayList(Observable.bufferSize() * 2); for (int i = 1; i <= Observable.bufferSize() * 2 + 1; i++) { list.add(i); } Observable o = Observable.range(1, list.size()); - TestSubscriber ts = new TestSubscriber<>((Long)null); + TestSubscriber ts = new TestSubscriber((Long)null); ts.assertNoValues(); ts.request(Long.MAX_VALUE); // infinite @@ -131,11 +137,11 @@ public void testNoBackpressure() { void testWithBackpressureOneByOne(int start) { Observable source = Observable.range(start, 100); - TestSubscriber ts = new TestSubscriber<>((Long)null); + TestSubscriber ts = new TestSubscriber((Long)null); ts.request(1); source.subscribe(ts); - List list = new ArrayList<>(100); + List list = new ArrayList(100); for (int i = 0; i < 100; i++) { list.add(i + start); ts.request(1); @@ -146,11 +152,11 @@ void testWithBackpressureOneByOne(int start) { void testWithBackpressureAllAtOnce(int start) { Observable source = Observable.range(start, 100); - TestSubscriber ts = new TestSubscriber<>((Long)null); + TestSubscriber ts = new TestSubscriber((Long)null); ts.request(100); source.subscribe(ts); - List list = new ArrayList<>(100); + List list = new ArrayList(100); for (int i = 0; i < 100; i++) { list.add(i + start); } @@ -173,11 +179,11 @@ public void testWithBackpressureAllAtOnce() { public void testWithBackpressureRequestWayMore() { Observable source = Observable.range(50, 100); - TestSubscriber ts = new TestSubscriber<>((Long)null); + TestSubscriber ts = new TestSubscriber((Long)null); ts.request(150); source.subscribe(ts); - List list = new ArrayList<>(100); + List list = new ArrayList(100); for (int i = 0; i < 100; i++) { list.add(i + 50); } @@ -246,7 +252,7 @@ public void onNext(Integer t) { @Test(timeout = 1000) public void testNearMaxValueWithoutBackpressure() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); Observable.range(Integer.MAX_VALUE - 1, 2).subscribe(ts); ts.assertComplete(); @@ -255,7 +261,7 @@ public void testNearMaxValueWithoutBackpressure() { } @Test(timeout = 1000) public void testNearMaxValueWithBackpressure() { - TestSubscriber ts = new TestSubscriber<>(3L); + TestSubscriber ts = new TestSubscriber(3L); Observable.range(Integer.MAX_VALUE - 1, 2).subscribe(ts); ts.assertComplete(); diff --git a/src/test/java/io/reactivex/internal/operators/OnSubscribeRefCountTest.java b/src/test/java/io/reactivex/internal/operators/OnSubscribeRefCountTest.java index a79d0cd36d..1c1c46abd5 100644 --- a/src/test/java/io/reactivex/internal/operators/OnSubscribeRefCountTest.java +++ b/src/test/java/io/reactivex/internal/operators/OnSubscribeRefCountTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -28,6 +28,7 @@ import io.reactivex.Observable; import io.reactivex.TestHelper; import io.reactivex.disposables.Disposable; +import io.reactivex.functions.*; import io.reactivex.internal.subscribers.CancelledSubscriber; import io.reactivex.schedulers.*; import io.reactivex.subjects.ReplaySubject; @@ -40,12 +41,27 @@ public void testRefCountAsync() { final AtomicInteger subscribeCount = new AtomicInteger(); final AtomicInteger nextCount = new AtomicInteger(); Observable r = Observable.interval(0, 5, TimeUnit.MILLISECONDS) - .doOnSubscribe(s -> subscribeCount.incrementAndGet()) - .doOnNext(l -> nextCount.incrementAndGet()) + .doOnSubscribe(new Consumer() { + @Override + public void accept(Subscription s) { + subscribeCount.incrementAndGet(); + } + }) + .doOnNext(new Consumer() { + @Override + public void accept(Long l) { + nextCount.incrementAndGet(); + } + }) .publish().refCount(); final AtomicInteger receivedCount = new AtomicInteger(); - Disposable s1 = r.subscribe(l -> receivedCount.incrementAndGet()); + Disposable s1 = r.subscribe(new Consumer() { + @Override + public void accept(Long l) { + receivedCount.incrementAndGet(); + } + }); Disposable s2 = r.subscribe(); @@ -72,12 +88,27 @@ public void testRefCountSynchronous() { final AtomicInteger subscribeCount = new AtomicInteger(); final AtomicInteger nextCount = new AtomicInteger(); Observable r = Observable.just(1, 2, 3, 4, 5, 6, 7, 8, 9) - .doOnSubscribe(s -> subscribeCount.incrementAndGet()) - .doOnNext(l -> nextCount.incrementAndGet()) + .doOnSubscribe(new Consumer() { + @Override + public void accept(Subscription s) { + subscribeCount.incrementAndGet(); + } + }) + .doOnNext(new Consumer() { + @Override + public void accept(Integer l) { + nextCount.incrementAndGet(); + } + }) .publish().refCount(); final AtomicInteger receivedCount = new AtomicInteger(); - Disposable s1 = r.subscribe(l -> receivedCount.incrementAndGet()); + Disposable s1 = r.subscribe(new Consumer() { + @Override + public void accept(Integer l) { + receivedCount.incrementAndGet(); + } + }); Disposable s2 = r.subscribe(); @@ -103,15 +134,23 @@ public void testRefCountSynchronous() { public void testRefCountSynchronousTake() { final AtomicInteger nextCount = new AtomicInteger(); Observable r = Observable.just(1, 2, 3, 4, 5, 6, 7, 8, 9) - .doOnNext(l -> { - System.out.println("onNext --------> " + l); - nextCount.incrementAndGet(); + .doOnNext(new Consumer() { + @Override + public void accept(Integer l) { + System.out.println("onNext --------> " + l); + nextCount.incrementAndGet(); + } }) .take(4) .publish().refCount(); final AtomicInteger receivedCount = new AtomicInteger(); - r.subscribe(l -> receivedCount.incrementAndGet()); + r.subscribe(new Consumer() { + @Override + public void accept(Integer l) { + receivedCount.incrementAndGet(); + } + }); System.out.println("onNext: " + nextCount.get()); @@ -124,21 +163,27 @@ public void testRepeat() { final AtomicInteger subscribeCount = new AtomicInteger(); final AtomicInteger unsubscribeCount = new AtomicInteger(); Observable r = Observable.interval(0, 1, TimeUnit.MILLISECONDS) - .doOnSubscribe(s -> { - System.out.println("******************************* Subscribe received"); - // when we are subscribed - subscribeCount.incrementAndGet(); + .doOnSubscribe(new Consumer() { + @Override + public void accept(Subscription s) { + System.out.println("******************************* Subscribe received"); + // when we are subscribed + subscribeCount.incrementAndGet(); + } }) - .doOnCancel(() -> { - System.out.println("******************************* Unsubscribe received"); - // when we are unsubscribed - unsubscribeCount.incrementAndGet(); + .doOnCancel(new Runnable() { + @Override + public void run() { + System.out.println("******************************* Unsubscribe received"); + // when we are unsubscribed + unsubscribeCount.incrementAndGet(); + } }) .publish().refCount(); for (int i = 0; i < 10; i++) { - TestSubscriber ts1 = new TestSubscriber<>(); - TestSubscriber ts2 = new TestSubscriber<>(); + TestSubscriber ts1 = new TestSubscriber(); + TestSubscriber ts2 = new TestSubscriber(); r.subscribe(ts1); r.subscribe(ts2); try { @@ -163,18 +208,24 @@ public void testConnectUnsubscribe() throws InterruptedException { final CountDownLatch subscribeLatch = new CountDownLatch(1); Observable o = synchronousInterval() - .doOnSubscribe(s -> { - System.out.println("******************************* Subscribe received"); - // when we are subscribed - subscribeLatch.countDown(); + .doOnSubscribe(new Consumer() { + @Override + public void accept(Subscription s) { + System.out.println("******************************* Subscribe received"); + // when we are subscribed + subscribeLatch.countDown(); + } }) - .doOnCancel(() -> { - System.out.println("******************************* Unsubscribe received"); - // when we are unsubscribed - unsubscribeLatch.countDown(); + .doOnCancel(new Runnable() { + @Override + public void run() { + System.out.println("******************************* Unsubscribe received"); + // when we are unsubscribed + unsubscribeLatch.countDown(); + } }); - TestSubscriber s = new TestSubscriber<>(); + TestSubscriber s = new TestSubscriber(); o.publish().refCount().subscribeOn(Schedulers.newThread()).subscribe(s); System.out.println("send unsubscribe"); // wait until connected @@ -203,17 +254,23 @@ public void testConnectUnsubscribeRaceConditionLoop() throws InterruptedExceptio public void testConnectUnsubscribeRaceCondition() throws InterruptedException { final AtomicInteger subUnsubCount = new AtomicInteger(); Observable o = synchronousInterval() - .doOnCancel(() -> { - System.out.println("******************************* Unsubscribe received"); - // when we are unsubscribed - subUnsubCount.decrementAndGet(); + .doOnCancel(new Runnable() { + @Override + public void run() { + System.out.println("******************************* Unsubscribe received"); + // when we are unsubscribed + subUnsubCount.decrementAndGet(); + } }) - .doOnSubscribe(s -> { - System.out.println("******************************* SUBSCRIBE received"); - subUnsubCount.incrementAndGet(); + .doOnSubscribe(new Consumer() { + @Override + public void accept(Subscription s) { + System.out.println("******************************* SUBSCRIBE received"); + subUnsubCount.incrementAndGet(); + } }); - TestSubscriber s = new TestSubscriber<>(); + TestSubscriber s = new TestSubscriber(); o.publish().refCount().subscribeOn(Schedulers.computation()).subscribe(s); System.out.println("send unsubscribe"); @@ -234,29 +291,32 @@ public void testConnectUnsubscribeRaceCondition() throws InterruptedException { } private Observable synchronousInterval() { - return Observable.create(subscriber -> { - AtomicBoolean cancel = new AtomicBoolean(); - subscriber.onSubscribe(new Subscription() { - @Override - public void request(long n) { - - } + return Observable.create(new Publisher() { + @Override + public void subscribe(Subscriber subscriber) { + final AtomicBoolean cancel = new AtomicBoolean(); + subscriber.onSubscribe(new Subscription() { + @Override + public void request(long n) { + + } - @Override - public void cancel() { - cancel.set(true); - } - - }); - for (;;) { - if (cancel.get()) { - break; - } - try { - Thread.sleep(100); - } catch (InterruptedException e) { + @Override + public void cancel() { + cancel.set(true); + } + + }); + for (;;) { + if (cancel.get()) { + break; + } + try { + Thread.sleep(100); + } catch (InterruptedException e) { + } + subscriber.onNext(1L); } - subscriber.onNext(1L); } }); } @@ -303,8 +363,13 @@ public void testRefCount() { Observable interval = Observable.interval(100, TimeUnit.MILLISECONDS, s).publish().refCount(); // subscribe list1 - final List list1 = new ArrayList<>(); - Disposable s1 = interval.subscribe(t1 -> list1.add(t1)); + final List list1 = new ArrayList(); + Disposable s1 = interval.subscribe(new Consumer() { + @Override + public void accept(Long t1) { + list1.add(t1); + } + }); s.advanceTimeBy(200, TimeUnit.MILLISECONDS); @@ -313,8 +378,13 @@ public void testRefCount() { assertEquals(1L, list1.get(1).longValue()); // subscribe list2 - final List list2 = new ArrayList<>(); - Disposable s2 = interval.subscribe(t1 -> list2.add(t1)); + final List list2 = new ArrayList(); + Disposable s2 = interval.subscribe(new Consumer() { + @Override + public void accept(Long t1) { + list2.add(t1); + } + }); s.advanceTimeBy(300, TimeUnit.MILLISECONDS); @@ -353,8 +423,13 @@ public void testRefCount() { // subscribing a new one should start over because the source should have been unsubscribed // subscribe list3 - final List list3 = new ArrayList<>(); - interval.subscribe(t1 -> list3.add(t1)); + final List list3 = new ArrayList(); + interval.subscribe(new Consumer() { + @Override + public void accept(Long t1) { + list3.add(t1); + } + }); s.advanceTimeBy(200, TimeUnit.MILLISECONDS); @@ -411,11 +486,16 @@ public void testAlreadyUnsubscribedInterleavesWithClient() { public void testConnectDisconnectConnectAndSubjectState() { Observable o1 = Observable.just(10); Observable o2 = Observable.just(20); - Observable combined = Observable.combineLatest(o1, o2, (t1, t2) -> t1 + t2) - .publish().refCount(); + Observable combined = Observable.combineLatest(o1, o2, new BiFunction() { + @Override + public Integer apply(Integer t1, Integer t2) { + return t1 + t2; + } + }) + .publish().refCount(); - TestSubscriber ts1 = new TestSubscriber<>(); - TestSubscriber ts2 = new TestSubscriber<>(); + TestSubscriber ts1 = new TestSubscriber(); + TestSubscriber ts2 = new TestSubscriber(); combined.subscribe(ts1); combined.subscribe(ts2); @@ -434,37 +514,61 @@ public void testUpstreamErrorAllowsRetry() throws InterruptedException { final AtomicInteger intervalSubscribed = new AtomicInteger(); Observable interval = Observable.interval(200,TimeUnit.MILLISECONDS) - .doOnSubscribe(s -> { - System.out.println("Subscribing to interval " + intervalSubscribed.incrementAndGet()); - } + .doOnSubscribe(new Consumer() { + @Override + public void accept(Subscription s) { + System.out.println("Subscribing to interval " + intervalSubscribed.incrementAndGet()); + } + } ) - .flatMap(t1 -> { - return Observable.defer(() -> { - return Observable.error(new Exception("Some exception")); - }); + .flatMap(new Function>() { + @Override + public Publisher apply(Long t1) { + return Observable.defer(new Supplier>() { + @Override + public Publisher get() { + return Observable.error(new Exception("Some exception")); + } + }); + } }) - .onErrorResumeNext(t1 -> { - return Observable.error(t1); + .onErrorResumeNext(new Function>() { + @Override + public Publisher apply(Throwable t1) { + return Observable.error(t1); + } }) .publish() .refCount(); interval - .doOnError(t1 -> { - System.out.println("Subscriber 1 onError: " + t1); + .doOnError(new Consumer() { + @Override + public void accept(Throwable t1) { + System.out.println("Subscriber 1 onError: " + t1); + } }) .retry(5) - .subscribe(t1 -> { - System.out.println("Subscriber 1: " + t1); + .subscribe(new Consumer() { + @Override + public void accept(String t1) { + System.out.println("Subscriber 1: " + t1); + } }); Thread.sleep(100); interval - .doOnError(t1 -> { - System.out.println("Subscriber 2 onError: " + t1); + .doOnError(new Consumer() { + @Override + public void accept(Throwable t1) { + System.out.println("Subscriber 2 onError: " + t1); + } }) .retry(5) - .subscribe(t1 -> { - System.out.println("Subscriber 2: " + t1); + .subscribe(new Consumer() { + @Override + public void accept(String t1) { + System.out.println("Subscriber 2: " + t1); + } }); Thread.sleep(1300); diff --git a/src/test/java/io/reactivex/internal/operators/OnSubscribeTimerTest.java b/src/test/java/io/reactivex/internal/operators/OnSubscribeTimerTest.java index 6e4deffab7..d069f7fa79 100644 --- a/src/test/java/io/reactivex/internal/operators/OnSubscribeTimerTest.java +++ b/src/test/java/io/reactivex/internal/operators/OnSubscribeTimerTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -57,7 +57,7 @@ public void testTimerOnce() { @Test public void testTimerPeriodically() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); Observable.interval(100, 100, TimeUnit.MILLISECONDS, scheduler).subscribe(ts); @@ -84,7 +84,7 @@ public void testTimerPeriodically() { @Test public void testInterval() { Observable w = Observable.interval(1, TimeUnit.SECONDS, scheduler); - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); w.subscribe(ts); ts.assertNoValues(); @@ -109,8 +109,8 @@ public void testInterval() { public void testWithMultipleSubscribersStartingAtSameTime() { Observable w = Observable.interval(1, TimeUnit.SECONDS, scheduler); - TestSubscriber ts1 = new TestSubscriber<>(); - TestSubscriber ts2 = new TestSubscriber<>(); + TestSubscriber ts1 = new TestSubscriber(); + TestSubscriber ts2 = new TestSubscriber(); w.subscribe(ts1); w.subscribe(ts2); @@ -146,7 +146,7 @@ public void testWithMultipleSubscribersStartingAtSameTime() { public void testWithMultipleStaggeredSubscribers() { Observable w = Observable.interval(1, TimeUnit.SECONDS, scheduler); - TestSubscriber ts1 = new TestSubscriber<>(); + TestSubscriber ts1 = new TestSubscriber(); w.subscribe(ts1); @@ -154,7 +154,7 @@ public void testWithMultipleStaggeredSubscribers() { scheduler.advanceTimeTo(2, TimeUnit.SECONDS); - TestSubscriber ts2 = new TestSubscriber<>(); + TestSubscriber ts2 = new TestSubscriber(); w.subscribe(ts2); @@ -186,7 +186,7 @@ public void testWithMultipleStaggeredSubscribers() { public void testWithMultipleStaggeredSubscribersAndPublish() { ConnectableObservable w = Observable.interval(1, TimeUnit.SECONDS, scheduler).publish(); - TestSubscriber ts1 = new TestSubscriber<>(); + TestSubscriber ts1 = new TestSubscriber(); w.subscribe(ts1); w.connect(); @@ -195,7 +195,7 @@ public void testWithMultipleStaggeredSubscribersAndPublish() { scheduler.advanceTimeTo(2, TimeUnit.SECONDS); - TestSubscriber ts2 = new TestSubscriber<>(); + TestSubscriber ts2 = new TestSubscriber(); w.subscribe(ts2); ts1.assertValues(0L, 1L); diff --git a/src/test/java/io/reactivex/internal/operators/OnSubscribeToObservableFutureTest.java b/src/test/java/io/reactivex/internal/operators/OnSubscribeToObservableFutureTest.java index 58618b6be7..35cc0062e4 100644 --- a/src/test/java/io/reactivex/internal/operators/OnSubscribeToObservableFutureTest.java +++ b/src/test/java/io/reactivex/internal/operators/OnSubscribeToObservableFutureTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -37,7 +37,7 @@ public void testSuccess() throws Exception { Subscriber o = TestHelper.mockSubscriber(); - TestSubscriber ts = new TestSubscriber<>(o); + TestSubscriber ts = new TestSubscriber(o); Observable.fromFuture(future).subscribe(ts); @@ -58,7 +58,7 @@ public void testFailure() throws Exception { Subscriber o = TestHelper.mockSubscriber(); - TestSubscriber ts = new TestSubscriber<>(o); + TestSubscriber ts = new TestSubscriber(o); Observable.fromFuture(future).subscribe(ts); @@ -79,7 +79,7 @@ public void testCancelledBeforeSubscribe() throws Exception { Subscriber o = TestHelper.mockSubscriber(); - TestSubscriber ts = new TestSubscriber<>(o); + TestSubscriber ts = new TestSubscriber(o); ts.dispose(); Observable.fromFuture(future).subscribe(ts); @@ -125,7 +125,7 @@ public Object get(long timeout, TimeUnit unit) throws InterruptedException, Exec Subscriber o = TestHelper.mockSubscriber(); - TestSubscriber ts = new TestSubscriber<>(o); + TestSubscriber ts = new TestSubscriber(o); Observable futureObservable = Observable.fromFuture(future); futureObservable.subscribeOn(Schedulers.computation()).subscribe(ts); diff --git a/src/test/java/io/reactivex/internal/operators/OnSubscribeUsingTest.java b/src/test/java/io/reactivex/internal/operators/OnSubscribeUsingTest.java index a0b897445e..abb3c21fab 100644 --- a/src/test/java/io/reactivex/internal/operators/OnSubscribeUsingTest.java +++ b/src/test/java/io/reactivex/internal/operators/OnSubscribeUsingTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -17,16 +17,16 @@ import static org.mockito.Mockito.*; import java.util.*; -import java.util.function.*; import org.junit.*; import org.mockito.InOrder; -import org.reactivestreams.Subscriber; +import org.reactivestreams.*; import io.reactivex.Observable; import io.reactivex.TestHelper; import io.reactivex.disposables.*; import io.reactivex.exceptions.TestException; +import io.reactivex.functions.*; public class OnSubscribeUsingTest { @@ -68,10 +68,18 @@ private void performTestUsing(boolean disposeEagerly) { final Resource resource = mock(Resource.class); when(resource.getTextFromWeb()).thenReturn("Hello world!"); - Supplier resourceFactory = () -> resource; + Supplier resourceFactory = new Supplier() { + @Override + public Resource get() { + return resource; + } + }; - Function> observableFactory = res -> { - return Observable.fromArray(res.getTextFromWeb().split(" ")); + Function> observableFactory = new Function>() { + @Override + public Observable apply(Resource res) { + return Observable.fromArray(res.getTextFromWeb().split(" ")); + } }; Subscriber observer = TestHelper.mockSubscriber(); @@ -127,8 +135,11 @@ public void dispose() { } }; - Function> observableFactory = res -> { - return Observable.fromArray(res.getTextFromWeb().split(" ")); + Function> observableFactory = new Function>() { + @Override + public Observable apply(Resource res) { + return Observable.fromArray(res.getTextFromWeb().split(" ")); + } }; Subscriber observer = TestHelper.mockSubscriber(); @@ -161,11 +172,19 @@ public void testUsingWithResourceFactoryErrorDisposeEagerly() { } private void performTestUsingWithResourceFactoryError(boolean disposeEagerly) { - Supplier resourceFactory = () -> { - throw new TestException(); + Supplier resourceFactory = new Supplier() { + @Override + public Disposable get() { + throw new TestException(); + } }; - Function> observableFactory = s -> Observable.empty(); + Function> observableFactory = new Function>() { + @Override + public Observable apply(Disposable s) { + return Observable.empty(); + } + }; Observable.using(resourceFactory, observableFactory, disposeSubscription) .toBlocking() @@ -184,10 +203,18 @@ public void testUsingWithObservableFactoryErrorDisposeEagerly() { private void performTestUsingWithObservableFactoryError(boolean disposeEagerly) { final Runnable unsubscribe = mock(Runnable.class); - Supplier resourceFactory = () -> Disposables.from(unsubscribe); + Supplier resourceFactory = new Supplier() { + @Override + public Disposable get() { + return Disposables.from(unsubscribe); + } + }; - Function> observableFactory = subscription -> { - throw new TestException(); + Function> observableFactory = new Function>() { + @Override + public Observable apply(Disposable subscription) { + throw new TestException(); + } }; try { @@ -222,10 +249,16 @@ public Disposable get() { } }; - Function> observableFactory = subscription -> { - return Observable.create(t1 -> { - throw new TestException(); - }); + Function> observableFactory = new Function>() { + @Override + public Observable apply(Disposable subscription) { + return Observable.create(new Publisher() { + @Override + public void subscribe(Subscriber t1) { + throw new TestException(); + } + }); + } }; try { @@ -243,12 +276,17 @@ public Disposable get() { @Test public void testUsingDisposesEagerlyBeforeCompletion() { - final List events = new ArrayList<>(); + final List events = new ArrayList(); Supplier resourceFactory = createResourceFactory(events); final Runnable completion = createOnCompletedAction(events); final Runnable unsub =createUnsubAction(events); - Function> observableFactory = resource -> Observable.fromArray(resource.getTextFromWeb().split(" ")); + Function> observableFactory = new Function>() { + @Override + public Observable apply(Resource resource) { + return Observable.fromArray(resource.getTextFromWeb().split(" ")); + } + }; Subscriber observer = TestHelper.mockSubscriber(); @@ -265,7 +303,7 @@ public void testUsingDisposesEagerlyBeforeCompletion() { @Test public void testUsingDoesNotDisposesEagerlyBeforeCompletion() { - final List events = new ArrayList<>(); + final List events = new ArrayList(); Supplier resourceFactory = createResourceFactory(events); final Runnable completion = createOnCompletedAction(events); final Runnable unsub = createUnsubAction(events); @@ -294,7 +332,7 @@ public Observable apply(Resource resource) { @Test public void testUsingDisposesEagerlyBeforeError() { - final List events = new ArrayList<>(); + final List events = new ArrayList(); Supplier resourceFactory = createResourceFactory(events); final Consumer onError = createOnErrorAction(events); final Runnable unsub = createUnsubAction(events); @@ -322,14 +360,17 @@ public Observable apply(Resource resource) { @Test public void testUsingDoesNotDisposesEagerlyBeforeError() { - final List events = new ArrayList<>(); + final List events = new ArrayList(); final Supplier resourceFactory = createResourceFactory(events); final Consumer onError = createOnErrorAction(events); final Runnable unsub = createUnsubAction(events); - Function> observableFactory = resource -> { - return Observable.fromArray(resource.getTextFromWeb().split(" ")) - .concatWith(Observable.error(new RuntimeException())); + Function> observableFactory = new Function>() { + @Override + public Observable apply(Resource resource) { + return Observable.fromArray(resource.getTextFromWeb().split(" ")) + .concatWith(Observable.error(new RuntimeException())); + } }; Subscriber observer = TestHelper.mockSubscriber(); @@ -345,30 +386,50 @@ public void testUsingDoesNotDisposesEagerlyBeforeError() { } private static Runnable createUnsubAction(final List events) { - return () -> events.add("unsub"); + return new Runnable() { + @Override + public void run() { + events.add("unsub"); + } + }; } private static Consumer createOnErrorAction(final List events) { - return t -> events.add("error"); + return new Consumer() { + @Override + public void accept(Throwable t) { + events.add("error"); + } + }; } private static Supplier createResourceFactory(final List events) { - return () -> new Resource() { - + return new Supplier() { @Override - public String getTextFromWeb() { - return "hello world"; - } + public Resource get() { + return new Resource() { - @Override - public void dispose() { - events.add("disposed"); + @Override + public String getTextFromWeb() { + return "hello world"; + } + + @Override + public void dispose() { + events.add("disposed"); + } + }; } }; } private static Runnable createOnCompletedAction(final List events) { - return () -> events.add("completed"); + return new Runnable() { + @Override + public void run() { + events.add("completed"); + } + }; } } \ No newline at end of file diff --git a/src/test/java/io/reactivex/internal/operators/OperatorAllTest.java b/src/test/java/io/reactivex/internal/operators/OperatorAllTest.java index 788c4cca0d..50daa68cbd 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorAllTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorAllTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -14,14 +14,16 @@ package io.reactivex.internal.operators; import static org.junit.Assert.*; +import static org.mockito.Matchers.any; import static org.mockito.Mockito.*; import java.util.concurrent.TimeUnit; import org.junit.Test; -import org.reactivestreams.Subscriber; +import org.reactivestreams.*; import io.reactivex.*; +import io.reactivex.functions.*; import io.reactivex.subscribers.TestSubscriber; public class OperatorAllTest { @@ -32,10 +34,15 @@ public void testAll() { Subscriber observer = TestHelper.mockSubscriber(); - obs.all(s -> s.length() == 3) + obs.all(new Predicate() { + @Override + public boolean test(String s) { + return s.length() == 3; + } + }) .subscribe(observer); - verify(observer).onSubscribe(any()); + verify(observer).onSubscribe((Subscription)any()); verify(observer).onNext(true); verify(observer).onComplete(); verifyNoMoreInteractions(observer); @@ -47,10 +54,15 @@ public void testNotAll() { Subscriber observer = TestHelper.mockSubscriber(); - obs.all(s -> s.length() == 3) + obs.all(new Predicate() { + @Override + public boolean test(String s) { + return s.length() == 3; + } + }) .subscribe(observer); - verify(observer).onSubscribe(any()); + verify(observer).onSubscribe((Subscription)any()); verify(observer).onNext(false); verify(observer).onComplete(); verifyNoMoreInteractions(observer); @@ -62,10 +74,15 @@ public void testEmpty() { Subscriber observer = TestHelper.mockSubscriber(); - obs.all(s -> s.length() == 3) + obs.all(new Predicate() { + @Override + public boolean test(String s) { + return s.length() == 3; + } + }) .subscribe(observer); - verify(observer).onSubscribe(any()); + verify(observer).onSubscribe((Subscription)any()); verify(observer).onNext(true); verify(observer).onComplete(); verifyNoMoreInteractions(observer); @@ -78,10 +95,15 @@ public void testError() { Subscriber observer = TestHelper.mockSubscriber(); - obs.all(s -> s.length() == 3) + obs.all(new Predicate() { + @Override + public boolean test(String s) { + return s.length() == 3; + } + }) .subscribe(observer); - verify(observer).onSubscribe(any()); + verify(observer).onSubscribe((Subscription)any()); verify(observer).onError(error); verifyNoMoreInteractions(observer); } @@ -89,23 +111,43 @@ public void testError() { @Test public void testFollowingFirst() { Observable o = Observable.fromArray(1, 3, 5, 6); - Observable allOdd = o.all(i -> i % 2 == 1); + Observable allOdd = o.all(new Predicate() { + @Override + public boolean test(Integer i) { + return i % 2 == 1; + } + }); assertFalse(allOdd.toBlocking().first()); } @Test(timeout = 5000) public void testIssue1935NoUnsubscribeDownstream() { Observable source = Observable.just(1) - .all(t1 -> false) - .flatMap(t1 -> Observable.just(2).delay(500, TimeUnit.MILLISECONDS)); + .all(new Predicate() { + @Override + public boolean test(Integer t1) { + return false; + } + }) + .flatMap(new Function>() { + @Override + public Publisher apply(Boolean t1) { + return Observable.just(2).delay(500, TimeUnit.MILLISECONDS); + } + }); assertEquals((Object)2, source.toBlocking().first()); } @Test public void testBackpressureIfNoneRequestedNoneShouldBeDelivered() { - TestSubscriber ts = new TestSubscriber<>((Long)null); - Observable.empty().all(t1 -> false).subscribe(ts); + TestSubscriber ts = new TestSubscriber((Long)null); + Observable.empty().all(new Predicate() { + @Override + public boolean test(Object t1) { + return false; + } + }).subscribe(ts); ts.assertNoValues(); ts.assertNoErrors(); @@ -114,9 +156,14 @@ public void testBackpressureIfNoneRequestedNoneShouldBeDelivered() { @Test public void testBackpressureIfOneRequestedOneShouldBeDelivered() { - TestSubscriber ts = new TestSubscriber<>(1L); + TestSubscriber ts = new TestSubscriber(1L); - Observable.empty().all(t -> false).subscribe(ts); + Observable.empty().all(new Predicate() { + @Override + public boolean test(Object t) { + return false; + } + }).subscribe(ts); ts.assertTerminated(); ts.assertNoErrors(); @@ -127,12 +174,15 @@ public void testBackpressureIfOneRequestedOneShouldBeDelivered() { @Test public void testPredicateThrowsExceptionAndValueInCauseMessage() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); final IllegalArgumentException ex = new IllegalArgumentException(); - Observable.just("Boo!").all(v -> { - throw ex; + Observable.just("Boo!").all(new Predicate() { + @Override + public boolean test(String v) { + throw ex; + } }) .subscribe(ts); diff --git a/src/test/java/io/reactivex/internal/operators/OperatorAnyTest.java b/src/test/java/io/reactivex/internal/operators/OperatorAnyTest.java index a16e5728d4..8172f579f2 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorAnyTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorAnyTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -19,9 +19,10 @@ import java.util.concurrent.TimeUnit; import org.junit.Test; -import org.reactivestreams.Subscriber; +import org.reactivestreams.*; import io.reactivex.*; +import io.reactivex.functions.*; import io.reactivex.subscribers.TestSubscriber; public class OperatorAnyTest { @@ -29,7 +30,12 @@ public class OperatorAnyTest { @Test public void testAnyWithTwoItems() { Observable w = Observable.just(1, 2); - Observable observable = w.any(v -> true); + Observable observable = w.any(new Predicate() { + @Override + public boolean test(Integer v) { + return true; + } + }); Subscriber observer = TestHelper.mockSubscriber(); @@ -59,7 +65,12 @@ public void testIsEmptyWithTwoItems() { @Test public void testAnyWithOneItem() { Observable w = Observable.just(1); - Observable observable = w.any(v -> true); + Observable observable = w.any(new Predicate() { + @Override + public boolean test(Integer v) { + return true; + } + }); Subscriber observer = TestHelper.mockSubscriber(); @@ -89,7 +100,12 @@ public void testIsEmptyWithOneItem() { @Test public void testAnyWithEmpty() { Observable w = Observable.empty(); - Observable observable = w.any(v -> true); + Observable observable = w.any(new Predicate() { + @Override + public boolean test(Integer v) { + return true; + } + }); Subscriber observer = TestHelper.mockSubscriber(); @@ -119,7 +135,12 @@ public void testIsEmptyWithEmpty() { @Test public void testAnyWithPredicate1() { Observable w = Observable.just(1, 2, 3); - Observable observable = w.any(t1 -> t1 < 2); + Observable observable = w.any(new Predicate() { + @Override + public boolean test(Integer t1) { + return t1 < 2; + } + }); Subscriber observer = TestHelper.mockSubscriber(); @@ -134,7 +155,12 @@ public void testAnyWithPredicate1() { @Test public void testExists1() { Observable w = Observable.just(1, 2, 3); - Observable observable = w.any(t1 -> t1 < 2); + Observable observable = w.any(new Predicate() { + @Override + public boolean test(Integer t1) { + return t1 < 2; + } + }); Subscriber observer = TestHelper.mockSubscriber(); @@ -149,7 +175,12 @@ public void testExists1() { @Test public void testAnyWithPredicate2() { Observable w = Observable.just(1, 2, 3); - Observable observable = w.any(t1 -> t1 < 1); + Observable observable = w.any(new Predicate() { + @Override + public boolean test(Integer t1) { + return t1 < 1; + } + }); Subscriber observer = TestHelper.mockSubscriber(); @@ -165,7 +196,12 @@ public void testAnyWithPredicate2() { public void testAnyWithEmptyAndPredicate() { // If the source is empty, always output false. Observable w = Observable.empty(); - Observable observable = w.any(t -> true); + Observable observable = w.any(new Predicate() { + @Override + public boolean test(Integer t) { + return true; + } + }); Subscriber observer = TestHelper.mockSubscriber(); @@ -180,23 +216,38 @@ public void testAnyWithEmptyAndPredicate() { @Test public void testWithFollowingFirst() { Observable o = Observable.fromArray(1, 3, 5, 6); - Observable anyEven = o.any(i -> i % 2 == 0); + Observable anyEven = o.any(new Predicate() { + @Override + public boolean test(Integer i) { + return i % 2 == 0; + } + }); assertTrue(anyEven.toBlocking().first()); } @Test(timeout = 5000) public void testIssue1935NoUnsubscribeDownstream() { Observable source = Observable.just(1).isEmpty() - .flatMap(t1 -> Observable.just(2).delay(500, TimeUnit.MILLISECONDS)); + .flatMap(new Function>() { + @Override + public Publisher apply(Boolean t1) { + return Observable.just(2).delay(500, TimeUnit.MILLISECONDS); + } + }); assertEquals((Object)2, source.toBlocking().first()); } @Test public void testBackpressureIfNoneRequestedNoneShouldBeDelivered() { - TestSubscriber ts = new TestSubscriber<>((Long)null); + TestSubscriber ts = new TestSubscriber((Long)null); - Observable.just(1).any(t -> true) + Observable.just(1).any(new Predicate() { + @Override + public boolean test(Integer t) { + return true; + } + }) .subscribe(ts); ts.assertNoValues(); @@ -206,8 +257,13 @@ public void testBackpressureIfNoneRequestedNoneShouldBeDelivered() { @Test public void testBackpressureIfOneRequestedOneShouldBeDelivered() { - TestSubscriber ts = new TestSubscriber<>(1L); - Observable.just(1).any(v -> true).subscribe(ts); + TestSubscriber ts = new TestSubscriber(1L); + Observable.just(1).any(new Predicate() { + @Override + public boolean test(Integer v) { + return true; + } + }).subscribe(ts); ts.assertTerminated(); ts.assertNoErrors(); @@ -217,11 +273,14 @@ public void testBackpressureIfOneRequestedOneShouldBeDelivered() { @Test public void testPredicateThrowsExceptionAndValueInCauseMessage() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); final IllegalArgumentException ex = new IllegalArgumentException(); - Observable.just("Boo!").any(v -> { - throw ex; + Observable.just("Boo!").any(new Predicate() { + @Override + public boolean test(String v) { + throw ex; + } }).subscribe(ts); ts.assertTerminated(); diff --git a/src/test/java/io/reactivex/internal/operators/OperatorAsObservableTest.java b/src/test/java/io/reactivex/internal/operators/OperatorAsObservableTest.java index 059b91e004..bbc6962f3d 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorAsObservableTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorAsObservableTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 diff --git a/src/test/java/io/reactivex/internal/operators/OperatorBufferTest.java b/src/test/java/io/reactivex/internal/operators/OperatorBufferTest.java index b630bc96dc..79cbd9ea14 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorBufferTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorBufferTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -20,7 +20,6 @@ import java.util.*; import java.util.concurrent.*; import java.util.concurrent.atomic.*; -import java.util.function.*; import org.junit.*; import org.mockito.*; @@ -30,6 +29,7 @@ import io.reactivex.Observable; import io.reactivex.Observer; import io.reactivex.exceptions.TestException; +import io.reactivex.functions.*; import io.reactivex.internal.subscriptions.EmptySubscription; import io.reactivex.schedulers.TestScheduler; import io.reactivex.subjects.PublishSubject; @@ -312,7 +312,7 @@ public void accept(List t1) { } private List list(String... args) { - List list = new ArrayList<>(); + List list = new ArrayList(); for (String arg : args) { list.add(arg); } @@ -320,11 +320,21 @@ private List list(String... args) { } private void push(final Subscriber observer, final T value, int delay) { - innerScheduler.schedule(() -> observer.onNext(value), delay, TimeUnit.MILLISECONDS); + innerScheduler.schedule(new Runnable() { + @Override + public void run() { + observer.onNext(value); + } + }, delay, TimeUnit.MILLISECONDS); } private void complete(final Subscriber observer, int delay) { - innerScheduler.schedule(observer::onComplete, delay, TimeUnit.MILLISECONDS); + innerScheduler.schedule(new Runnable() { + @Override + public void run() { + observer.onComplete(); + } + }, delay, TimeUnit.MILLISECONDS); } @Test @@ -332,10 +342,15 @@ public void testBufferStopsWhenUnsubscribed1() { Observable source = Observable.never(); Subscriber> o = TestHelper.mockSubscriber(); - TestSubscriber> ts = new TestSubscriber<>(o, (Long)null); + TestSubscriber> ts = new TestSubscriber>(o, (Long)null); source.buffer(100, 200, TimeUnit.MILLISECONDS, scheduler) - .doOnNext(System.out::println) + .doOnNext(new Consumer>() { + @Override + public void accept(List pv) { + System.out.println(pv); + } + }) .subscribe(ts); InOrder inOrder = Mockito.inOrder(o); @@ -578,7 +593,12 @@ public Observable apply(Long t1) { InOrder inOrder = inOrder(o); result - .doOnNext(System.out::println) + .doOnNext(new Consumer>() { + @Override + public void accept(List pv) { + System.out.println(pv); + } + }) .subscribe(o); scheduler.advanceTimeBy(5, TimeUnit.SECONDS); @@ -742,7 +762,7 @@ public Observable apply(Integer t1) { @Test public void testProducerRequestThroughBufferWithSize1() { - TestSubscriber> ts = new TestSubscriber<>(3L); + TestSubscriber> ts = new TestSubscriber>(3L); final AtomicLong requested = new AtomicLong(); Observable.create(new Publisher() { @@ -773,7 +793,7 @@ public void cancel() { @Test public void testProducerRequestThroughBufferWithSize2() { - TestSubscriber> ts = new TestSubscriber<>(); + TestSubscriber> ts = new TestSubscriber>(); final AtomicLong requested = new AtomicLong(); Observable.create(new Publisher() { @@ -801,7 +821,7 @@ public void cancel() { @Test public void testProducerRequestThroughBufferWithSize3() { - TestSubscriber> ts = new TestSubscriber<>(3L); + TestSubscriber> ts = new TestSubscriber>(3L); final AtomicLong requested = new AtomicLong(); Observable.create(new Publisher() { @@ -830,7 +850,7 @@ public void cancel() { @Test public void testProducerRequestThroughBufferWithSize4() { - TestSubscriber> ts = new TestSubscriber<>(); + TestSubscriber> ts = new TestSubscriber>(); final AtomicLong requested = new AtomicLong(); Observable.create(new Publisher() { @@ -858,7 +878,7 @@ public void cancel() { @Test public void testProducerRequestOverflowThroughBufferWithSize1() { - TestSubscriber> ts = new TestSubscriber<>(Long.MAX_VALUE >> 1); + TestSubscriber> ts = new TestSubscriber>(Long.MAX_VALUE >> 1); final AtomicLong requested = new AtomicLong(); @@ -887,7 +907,7 @@ public void cancel() { @Test public void testProducerRequestOverflowThroughBufferWithSize2() { - TestSubscriber> ts = new TestSubscriber<>(Long.MAX_VALUE >> 1); + TestSubscriber> ts = new TestSubscriber>(Long.MAX_VALUE >> 1); final AtomicLong requested = new AtomicLong(); diff --git a/src/test/java/io/reactivex/internal/operators/OperatorCastTest.java b/src/test/java/io/reactivex/internal/operators/OperatorCastTest.java index 47d07533bc..68f078a71a 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorCastTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorCastTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 diff --git a/src/test/java/io/reactivex/internal/operators/OperatorConcatTest.java b/src/test/java/io/reactivex/internal/operators/OperatorConcatTest.java index 4f57b89862..605b872241 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorConcatTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorConcatTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -20,7 +20,6 @@ import java.util.*; import java.util.concurrent.*; import java.util.concurrent.atomic.*; -import java.util.function.Function; import org.junit.Test; import org.mockito.InOrder; @@ -30,6 +29,7 @@ import io.reactivex.Observable; import io.reactivex.Observer; import io.reactivex.disposables.BooleanDisposable; +import io.reactivex.functions.Function; import io.reactivex.internal.subscriptions.EmptySubscription; import io.reactivex.schedulers.*; import io.reactivex.subjects.*; @@ -62,7 +62,7 @@ public void testConcatWithList() { final Observable odds = Observable.fromArray(o); final Observable even = Observable.fromArray(e); - final List> list = new ArrayList<>(); + final List> list = new ArrayList>(); list.add(odds); list.add(even); Observable concat = Observable.concat(Observable.fromIterable(list)); @@ -107,8 +107,8 @@ public void subscribe(Subscriber> observer) { public void testSimpleAsyncConcat() { Subscriber observer = TestHelper.mockSubscriber(); - TestObservable o1 = new TestObservable<>("one", "two", "three"); - TestObservable o2 = new TestObservable<>("four", "five", "six"); + TestObservable o1 = new TestObservable("one", "two", "three"); + TestObservable o2 = new TestObservable("four", "five", "six"); Observable.concat(Observable.create(o1), Observable.create(o2)).subscribe(observer); @@ -141,17 +141,18 @@ public void testNestedAsyncConcatLoop() throws Throwable { /** * Test an async Observable that emits more async Observables + * @throws InterruptedException if the test is interrupted */ @Test - public void testNestedAsyncConcat() throws Throwable { + public void testNestedAsyncConcat() throws InterruptedException { Subscriber observer = TestHelper.mockSubscriber(); - final TestObservable o1 = new TestObservable<>("one", "two", "three"); - final TestObservable o2 = new TestObservable<>("four", "five", "six"); - final TestObservable o3 = new TestObservable<>("seven", "eight", "nine"); + final TestObservable o1 = new TestObservable("one", "two", "three"); + final TestObservable o2 = new TestObservable("four", "five", "six"); + final TestObservable o3 = new TestObservable("seven", "eight", "nine"); final CountDownLatch allowThird = new CountDownLatch(1); - final AtomicReference parent = new AtomicReference<>(); + final AtomicReference parent = new AtomicReference(); final CountDownLatch parentHasStarted = new CountDownLatch(1); final CountDownLatch parentHasFinished = new CountDownLatch(1); @@ -279,7 +280,8 @@ public void testBlockedObservableOfObservables() { final Observable even = Observable.fromArray(e); final CountDownLatch callOnce = new CountDownLatch(1); final CountDownLatch okToContinue = new CountDownLatch(1); - TestObservable> observableOfObservables = new TestObservable<>(callOnce, okToContinue, odds, even); + @SuppressWarnings("unchecked") + TestObservable> observableOfObservables = new TestObservable>(callOnce, okToContinue, odds, even); Observable concatF = Observable.concat(Observable.create(observableOfObservables)); concatF.subscribe(observer); try { @@ -311,13 +313,14 @@ public void testBlockedObservableOfObservables() { @Test public void testConcatConcurrentWithInfinity() { - final TestObservable w1 = new TestObservable<>("one", "two", "three"); + final TestObservable w1 = new TestObservable("one", "two", "three"); //This observable will send "hello" MAX_VALUE time. - final TestObservable w2 = new TestObservable<>("hello", Integer.MAX_VALUE); + final TestObservable w2 = new TestObservable("hello", Integer.MAX_VALUE); Subscriber observer = TestHelper.mockSubscriber(); - TestObservable> observableOfObservables = new TestObservable<>(Observable.create(w1), Observable.create(w2)); + @SuppressWarnings("unchecked") + TestObservable> observableOfObservables = new TestObservable>(Observable.create(w1), Observable.create(w2)); Observable concatF = Observable.concat(Observable.create(observableOfObservables)); concatF.take(50).subscribe(observer); @@ -345,8 +348,8 @@ public void testConcatNonBlockingObservables() { final CountDownLatch okToContinueW1 = new CountDownLatch(1); final CountDownLatch okToContinueW2 = new CountDownLatch(1); - final TestObservable w1 = new TestObservable<>(null, okToContinueW1, "one", "two", "three"); - final TestObservable w2 = new TestObservable<>(null, okToContinueW2, "four", "five", "six"); + final TestObservable w1 = new TestObservable(null, okToContinueW1, "one", "two", "three"); + final TestObservable w2 = new TestObservable(null, okToContinueW2, "four", "five", "six"); Subscriber observer = TestHelper.mockSubscriber(); @@ -396,11 +399,11 @@ public void subscribe(Subscriber> observer) { public void testConcatUnsubscribe() { final CountDownLatch callOnce = new CountDownLatch(1); final CountDownLatch okToContinue = new CountDownLatch(1); - final TestObservable w1 = new TestObservable<>("one", "two", "three"); - final TestObservable w2 = new TestObservable<>(callOnce, okToContinue, "four", "five", "six"); + final TestObservable w1 = new TestObservable("one", "two", "three"); + final TestObservable w2 = new TestObservable(callOnce, okToContinue, "four", "five", "six"); Subscriber observer = TestHelper.mockSubscriber(); - TestSubscriber ts = new TestSubscriber<>(observer, null); + TestSubscriber ts = new TestSubscriber(observer, null); final Observable concat = Observable.concat(Observable.create(w1), Observable.create(w2)); @@ -438,13 +441,14 @@ public void testConcatUnsubscribe() { public void testConcatUnsubscribeConcurrent() { final CountDownLatch callOnce = new CountDownLatch(1); final CountDownLatch okToContinue = new CountDownLatch(1); - final TestObservable w1 = new TestObservable<>("one", "two", "three"); - final TestObservable w2 = new TestObservable<>(callOnce, okToContinue, "four", "five", "six"); + final TestObservable w1 = new TestObservable("one", "two", "three"); + final TestObservable w2 = new TestObservable(callOnce, okToContinue, "four", "five", "six"); Subscriber observer = TestHelper.mockSubscriber(); - TestSubscriber ts = new TestSubscriber<>(observer, null); + TestSubscriber ts = new TestSubscriber(observer, null); - TestObservable> observableOfObservables = new TestObservable<>(Observable.create(w1), Observable.create(w2)); + @SuppressWarnings("unchecked") + TestObservable> observableOfObservables = new TestObservable>(Observable.create(w1), Observable.create(w2)); Observable concatF = Observable.concat(Observable.create(observableOfObservables)); concatF.subscribe(ts); @@ -499,12 +503,10 @@ public void cancel() { private final T seed; private final int size; - @SafeVarargs public TestObservable(T... values) { this(null, null, values); } - @SafeVarargs public TestObservable(CountDownLatch once, CountDownLatch okToContinue, T... values) { this.values = Arrays.asList(values); this.size = this.values.size(); @@ -607,7 +609,12 @@ public void testMultipleObservers() { @Test public void concatVeryLongObservableOfObservables() { final int n = 10000; - Observable> source = Observable.range(0, n).map(Observable::just); + Observable> source = Observable.range(0, n).map(new Function>() { + @Override + public Observable apply(Integer v) { + return Observable.just(v); + } + }); Observable> result = Observable.concat(source).toList(); @@ -616,7 +623,7 @@ public void concatVeryLongObservableOfObservables() { result.subscribe(o); - List list = new ArrayList<>(n); + List list = new ArrayList(n); for (int i = 0; i < n; i++) { list.add(i); } @@ -627,7 +634,12 @@ public void concatVeryLongObservableOfObservables() { @Test public void concatVeryLongObservableOfObservablesTakeHalf() { final int n = 10000; - Observable> source = Observable.range(0, n).map(Observable::just); + Observable> source = Observable.range(0, n).map(new Function>() { + @Override + public Observable apply(Integer v) { + return Observable.just(v); + } + }); Observable> result = Observable.concat(source).take(n / 2).toList(); @@ -636,7 +648,7 @@ public void concatVeryLongObservableOfObservablesTakeHalf() { result.subscribe(o); - List list = new ArrayList<>(n); + List list = new ArrayList(n); for (int i = 0; i < n / 2; i++) { list.add(i); } @@ -656,7 +668,7 @@ public void testConcatOuterBackpressure() { @Test public void testInnerBackpressureWithAlignedBoundaries() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); Observable.range(0, Observable.bufferSize() * 2) .concatWith(Observable.range(0, Observable.bufferSize() * 2)) .observeOn(Schedulers.computation()) // observeOn has a backpressured RxRingBuffer @@ -675,7 +687,7 @@ public void testInnerBackpressureWithAlignedBoundaries() { */ @Test public void testInnerBackpressureWithoutAlignedBoundaries() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); Observable.range(0, (Observable.bufferSize() * 2) + 10) .concatWith(Observable.range(0, (Observable.bufferSize() * 2) + 10)) .observeOn(Schedulers.computation()) // observeOn has a backpressured RxRingBuffer @@ -701,7 +713,7 @@ public void subscribe(Subscriber s) { }); - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); Observable.concat(o, o).subscribe(ts); ts.awaitTerminalEvent(500, TimeUnit.MILLISECONDS); ts.assertTerminated(); @@ -796,7 +808,7 @@ public void concatMapRangeAsyncLoopIssue2876() { if (i % 1000 == 0) { System.out.println("concatMapRangeAsyncLoop > " + i); } - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); Observable.range(0, 1000) .concatMap(new Function>() { @Override diff --git a/src/test/java/io/reactivex/internal/operators/OperatorDebounceTest.java b/src/test/java/io/reactivex/internal/operators/OperatorDebounceTest.java index 6437ea9ddf..4491ab8aac 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorDebounceTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorDebounceTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -17,7 +17,6 @@ import static org.mockito.Mockito.*; import java.util.concurrent.TimeUnit; -import java.util.function.Function; import org.junit.*; import org.mockito.InOrder; @@ -25,6 +24,7 @@ import io.reactivex.*; import io.reactivex.exceptions.TestException; +import io.reactivex.functions.Function; import io.reactivex.internal.subscriptions.EmptySubscription; import io.reactivex.schedulers.TestScheduler; import io.reactivex.subjects.PublishSubject; @@ -279,7 +279,7 @@ public Observable apply(Integer t1) { @Test public void debounceWithTimeBackpressure() throws InterruptedException { TestScheduler scheduler = new TestScheduler(); - TestSubscriber subscriber = new TestSubscriber<>(); + TestSubscriber subscriber = new TestSubscriber(); Observable.merge( Observable.just(1), Observable.just(2).delay(10, TimeUnit.MILLISECONDS, scheduler) diff --git a/src/test/java/io/reactivex/internal/operators/OperatorDefaultIfEmptyTest.java b/src/test/java/io/reactivex/internal/operators/OperatorDefaultIfEmptyTest.java index 88739d05db..ad2ccea977 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorDefaultIfEmptyTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorDefaultIfEmptyTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -59,7 +59,7 @@ public void testDefaultIfEmptyWithEmpty() { @Test @Ignore("Subscribers should not throw") public void testEmptyButClientThrows() { - Subscriber o = TestHelper.mockSubscriber(); + final Subscriber o = TestHelper.mockSubscriber(); Observable.empty().defaultIfEmpty(1).subscribe(new Observer() { @Override @@ -85,7 +85,7 @@ public void onComplete() { @Test public void testBackpressureEmpty() { - TestSubscriber ts = new TestSubscriber<>((Long)null); + TestSubscriber ts = new TestSubscriber((Long)null); Observable.empty().defaultIfEmpty(1).subscribe(ts); ts.assertNoValues(); ts.assertNotTerminated(); @@ -97,7 +97,7 @@ public void testBackpressureEmpty() { @Test public void testBackpressureNonEmpty() { - TestSubscriber ts = new TestSubscriber<>((Long)null); + TestSubscriber ts = new TestSubscriber((Long)null); Observable.just(1,2,3).defaultIfEmpty(1).subscribe(ts); ts.assertNoValues(); ts.assertNotTerminated(); diff --git a/src/test/java/io/reactivex/internal/operators/OperatorDelayTest.java b/src/test/java/io/reactivex/internal/operators/OperatorDelayTest.java index 1a578ba603..30d9668e51 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorDelayTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorDelayTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -19,15 +19,16 @@ import java.util.*; import java.util.concurrent.TimeUnit; -import java.util.function.*; import org.junit.*; import org.mockito.InOrder; -import org.reactivestreams.Subscriber; +import org.reactivestreams.*; import io.reactivex.*; +import io.reactivex.Optional; import io.reactivex.Observable; import io.reactivex.exceptions.TestException; +import io.reactivex.functions.*; import io.reactivex.schedulers.*; import io.reactivex.subjects.PublishSubject; import io.reactivex.subscribers.TestSubscriber; @@ -216,7 +217,7 @@ public void testDelaySubscriptionCancelBeforeTime() { Observable result = Observable.just(1, 2, 3).delaySubscription(100, TimeUnit.MILLISECONDS, scheduler); Subscriber o = TestHelper.mockSubscriber(); - TestSubscriber ts = new TestSubscriber<>(o); + TestSubscriber ts = new TestSubscriber(o); result.subscribe(ts); ts.dispose(); @@ -230,7 +231,7 @@ public void testDelaySubscriptionCancelBeforeTime() { @Test public void testDelayWithObservableNormal1() { PublishSubject source = PublishSubject.create(); - final List> delays = new ArrayList<>(); + final List> delays = new ArrayList>(); final int n = 10; for (int i = 0; i < n; i++) { PublishSubject delay = PublishSubject.create(); @@ -581,7 +582,7 @@ public void testDelayWithObservableReorder() { int n = 3; PublishSubject source = PublishSubject.create(); - final List> subjects = new ArrayList<>(); + final List> subjects = new ArrayList>(); for (int i = 0; i < n; i++) { subjects.add(PublishSubject. create()); } @@ -629,7 +630,7 @@ public void accept(Try> t1) { } }); - TestSubscriber observer = new TestSubscriber<>(); + TestSubscriber observer = new TestSubscriber(); delayed.subscribe(observer); // all will be delivered after 500ms since range does not delay between them scheduler.advanceTimeBy(500L, TimeUnit.MILLISECONDS); @@ -638,7 +639,7 @@ public void accept(Try> t1) { @Test public void testBackpressureWithTimedDelay() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); Observable.range(1, Observable.bufferSize() * 2) .delay(100, TimeUnit.MILLISECONDS) .observeOn(Schedulers.computation()) @@ -666,7 +667,7 @@ public Integer apply(Integer t) { @Test public void testBackpressureWithSubscriptionTimedDelay() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); Observable.range(1, Observable.bufferSize() * 2) .delaySubscription(100, TimeUnit.MILLISECONDS) .delay(100, TimeUnit.MILLISECONDS) @@ -695,7 +696,7 @@ public Integer apply(Integer t) { @Test public void testBackpressureWithSelectorDelay() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); Observable.range(1, Observable.bufferSize() * 2) .delay(new Function>() { @@ -730,7 +731,7 @@ public Integer apply(Integer t) { @Test public void testBackpressureWithSelectorDelayAndSubscriptionDelay() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); Observable.range(1, Observable.bufferSize() * 2) .delay(new Supplier>() { @@ -775,7 +776,7 @@ public void testErrorRunsBeforeOnNext() { PublishSubject ps = PublishSubject.create(); - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); ps.delay(1, TimeUnit.SECONDS, test).subscribe(ts); @@ -791,4 +792,82 @@ public void testErrorRunsBeforeOnNext() { ts.assertError(TestException.class); ts.assertNotComplete(); } + public void testDelaySupplierSimple() { + final PublishSubject ps = PublishSubject.create(); + + Observable source = Observable.range(1, 5); + + TestSubscriber ts = new TestSubscriber(); + + source.delaySubscription(new Supplier>() { + @Override + public Publisher get() { + return ps; + } + }).subscribe(ts); + + ts.assertNoValues(); + ts.assertNoErrors(); + ts.assertNotComplete(); + + ps.onNext(1); + + ts.assertValues(1, 2, 3, 4, 5); + ts.assertComplete(); + ts.assertNoErrors(); + } + + @Test + public void testDelaySupplierCompletes() { + final PublishSubject ps = PublishSubject.create(); + + Observable source = Observable.range(1, 5); + + TestSubscriber ts = new TestSubscriber(); + + source.delaySubscription(new Supplier>() { + @Override + public Publisher get() { + return ps; + } + }).subscribe(ts); + + ts.assertNoValues(); + ts.assertNoErrors(); + ts.assertNotComplete(); + + // FIXME should this complete the source instead of consuming it? + ps.onComplete(); + + ts.assertValues(1, 2, 3, 4, 5); + ts.assertComplete(); + ts.assertNoErrors(); + } + + @Test + public void testDelaySupplierErrors() { + final PublishSubject ps = PublishSubject.create(); + + Observable source = Observable.range(1, 5); + + TestSubscriber ts = new TestSubscriber(); + + source.delaySubscription(new Supplier>() { + @Override + public Publisher get() { + return ps; + } + }).subscribe(ts); + + ts.assertNoValues(); + ts.assertNoErrors(); + ts.assertNotComplete(); + + ps.onError(new TestException()); + + ts.assertNoValues(); + ts.assertNotComplete(); + ts.assertError(TestException.class); + } + } \ No newline at end of file diff --git a/src/test/java/io/reactivex/internal/operators/OperatorDematerializeTest.java b/src/test/java/io/reactivex/internal/operators/OperatorDematerializeTest.java index 85b009b8a1..20318e14c8 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorDematerializeTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorDematerializeTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -16,8 +16,6 @@ import static org.mockito.Matchers.any; import static org.mockito.Mockito.*; -import java.util.Optional; - import org.junit.Test; import org.reactivestreams.Subscriber; @@ -94,7 +92,7 @@ public void testCompletePassThru() { Subscriber observer = TestHelper.mockSubscriber(); - TestSubscriber ts = new TestSubscriber<>(observer); + TestSubscriber ts = new TestSubscriber(observer); dematerialize.subscribe(ts); System.out.println(ts.errors()); diff --git a/src/test/java/io/reactivex/internal/operators/OperatorDistinctTest.java b/src/test/java/io/reactivex/internal/operators/OperatorDistinctTest.java index e112f54184..ac0008a261 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorDistinctTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorDistinctTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -16,13 +16,12 @@ import static org.mockito.Matchers.*; import static org.mockito.Mockito.*; -import java.util.function.Function; - import org.junit.*; import org.mockito.InOrder; import org.reactivestreams.Subscriber; import io.reactivex.*; +import io.reactivex.functions.Function; public class OperatorDistinctTest { diff --git a/src/test/java/io/reactivex/internal/operators/OperatorDistinctUntilChangedTest.java b/src/test/java/io/reactivex/internal/operators/OperatorDistinctUntilChangedTest.java index 4eef16702e..8e593f7021 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorDistinctUntilChangedTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorDistinctUntilChangedTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -16,13 +16,12 @@ import static org.mockito.Matchers.*; import static org.mockito.Mockito.*; -import java.util.function.Function; - import org.junit.*; -import org.mockito.*; +import org.mockito.InOrder; import org.reactivestreams.Subscriber; import io.reactivex.*; +import io.reactivex.functions.Function; public class OperatorDistinctUntilChangedTest { diff --git a/src/test/java/io/reactivex/internal/operators/OperatorDoOnEachTest.java b/src/test/java/io/reactivex/internal/operators/OperatorDoOnEachTest.java index fde39e48db..ce216aad2e 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorDoOnEachTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorDoOnEachTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -19,12 +19,12 @@ import java.util.List; import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.*; import org.junit.*; import org.reactivestreams.Subscriber; import io.reactivex.*; +import io.reactivex.functions.*; public class OperatorDoOnEachTest { diff --git a/src/test/java/io/reactivex/internal/operators/OperatorDoOnRequestTest.java b/src/test/java/io/reactivex/internal/operators/OperatorDoOnRequestTest.java index d922b9934c..f1e15aaa8c 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorDoOnRequestTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorDoOnRequestTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -17,12 +17,12 @@ import java.util.*; import java.util.concurrent.atomic.AtomicBoolean; -import java.util.function.LongConsumer; import org.junit.Test; import io.reactivex.Observable; import io.reactivex.Observer; +import io.reactivex.functions.LongConsumer; public class OperatorDoOnRequestTest { @@ -51,7 +51,7 @@ public void accept(long n) { @Test public void testDoRequest() { - final List requests = new ArrayList<>(); + final List requests = new ArrayList(); Observable.range(1, 5) // .doOnRequest(new LongConsumer() { diff --git a/src/test/java/io/reactivex/internal/operators/OperatorDoOnSubscribeTest.java b/src/test/java/io/reactivex/internal/operators/OperatorDoOnSubscribeTest.java index 057671da15..1b839990ca 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorDoOnSubscribeTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorDoOnSubscribeTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -21,6 +21,7 @@ import org.reactivestreams.*; import io.reactivex.Observable; +import io.reactivex.functions.Consumer; import io.reactivex.internal.subscriptions.EmptySubscription; public class OperatorDoOnSubscribeTest { @@ -28,8 +29,11 @@ public class OperatorDoOnSubscribeTest { @Test public void testDoOnSubscribe() throws Exception { final AtomicInteger count = new AtomicInteger(); - Observable o = Observable.just(1).doOnSubscribe(s -> { - count.incrementAndGet(); + Observable o = Observable.just(1).doOnSubscribe(new Consumer() { + @Override + public void accept(Subscription s) { + count.incrementAndGet(); + } }); o.subscribe(); @@ -41,10 +45,16 @@ public void testDoOnSubscribe() throws Exception { @Test public void testDoOnSubscribe2() throws Exception { final AtomicInteger count = new AtomicInteger(); - Observable o = Observable.just(1).doOnSubscribe(s -> { - count.incrementAndGet(); - }).take(1).doOnSubscribe(s -> { - count.incrementAndGet(); + Observable o = Observable.just(1).doOnSubscribe(new Consumer() { + @Override + public void accept(Subscription s) { + count.incrementAndGet(); + } + }).take(1).doOnSubscribe(new Consumer() { + @Override + public void accept(Subscription s) { + count.incrementAndGet(); + } }); o.subscribe(); @@ -56,7 +66,7 @@ public void testDoOnUnSubscribeWorksWithRefCount() throws Exception { final AtomicInteger onSubscribed = new AtomicInteger(); final AtomicInteger countBefore = new AtomicInteger(); final AtomicInteger countAfter = new AtomicInteger(); - final AtomicReference> sref = new AtomicReference<>(); + final AtomicReference> sref = new AtomicReference>(); Observable o = Observable.create(new Publisher() { @Override @@ -66,11 +76,17 @@ public void subscribe(Subscriber s) { sref.set(s); } - }).doOnSubscribe(s -> { - countBefore.incrementAndGet(); + }).doOnSubscribe(new Consumer() { + @Override + public void accept(Subscription s) { + countBefore.incrementAndGet(); + } }).publish().refCount() - .doOnSubscribe(s -> { - countAfter.incrementAndGet(); + .doOnSubscribe(new Consumer() { + @Override + public void accept(Subscription s) { + countAfter.incrementAndGet(); + } }); o.subscribe(); diff --git a/src/test/java/io/reactivex/internal/operators/OperatorDoOnUnsubscribeTest.java b/src/test/java/io/reactivex/internal/operators/OperatorDoOnUnsubscribeTest.java index 2cc6084665..5437287a72 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorDoOnUnsubscribeTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorDoOnUnsubscribeTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -23,6 +23,7 @@ import io.reactivex.Observable; import io.reactivex.disposables.Disposable; +import io.reactivex.functions.Consumer; import io.reactivex.subscribers.TestSubscriber; public class OperatorDoOnUnsubscribeTest { @@ -40,27 +41,36 @@ public void testDoOnUnsubscribe() throws Exception { // The stream needs to be infinite to ensure the stream does not terminate // before it is unsubscribed .interval(50, TimeUnit.MILLISECONDS) - .doOnCancel(() -> { - // Test that upper stream will be notified for un-subscription - // from a child subscriber - upperLatch.countDown(); - upperCount.incrementAndGet(); + .doOnCancel(new Runnable() { + @Override + public void run() { + // Test that upper stream will be notified for un-subscription + // from a child subscriber + upperLatch.countDown(); + upperCount.incrementAndGet(); + } }) - .doOnNext(aLong -> { - // Ensure there is at least some onNext events before un-subscription happens - onNextLatch.countDown(); + .doOnNext(new Consumer() { + @Override + public void accept(Long aLong) { + // Ensure there is at least some onNext events before un-subscription happens + onNextLatch.countDown(); + } }) - .doOnCancel(() -> { - // Test that lower stream will be notified for a direct un-subscription - lowerLatch.countDown(); - lowerCount.incrementAndGet(); + .doOnCancel(new Runnable() { + @Override + public void run() { + // Test that lower stream will be notified for a direct un-subscription + lowerLatch.countDown(); + lowerCount.incrementAndGet(); + } }); - List subscriptions = new ArrayList<>(); - List> subscribers = new ArrayList<>(); + List subscriptions = new ArrayList(); + List> subscribers = new ArrayList>(); for (int i = 0; i < subCount; ++i) { - TestSubscriber subscriber = new TestSubscriber<>(); + TestSubscriber subscriber = new TestSubscriber(); subscriptions.add(subscriber); longs.subscribe(subscriber); subscribers.add(subscriber); @@ -93,28 +103,37 @@ public void testDoOnUnSubscribeWorksWithRefCount() throws Exception { // The stream needs to be infinite to ensure the stream does not terminate // before it is unsubscribed .interval(50, TimeUnit.MILLISECONDS) - .doOnCancel(() -> { - // Test that upper stream will be notified for un-subscription - upperLatch.countDown(); - upperCount.incrementAndGet(); + .doOnCancel(new Runnable() { + @Override + public void run() { + // Test that upper stream will be notified for un-subscription + upperLatch.countDown(); + upperCount.incrementAndGet(); + } }) - .doOnNext(aLong -> { - // Ensure there is at least some onNext events before un-subscription happens - onNextLatch.countDown(); + .doOnNext(new Consumer() { + @Override + public void accept(Long aLong) { + // Ensure there is at least some onNext events before un-subscription happens + onNextLatch.countDown(); + } }) - .doOnCancel(() -> { - // Test that lower stream will be notified for un-subscription - lowerLatch.countDown(); - lowerCount.incrementAndGet(); + .doOnCancel(new Runnable() { + @Override + public void run() { + // Test that lower stream will be notified for un-subscription + lowerLatch.countDown(); + lowerCount.incrementAndGet(); + } }) .publish() .refCount(); - List subscriptions = new ArrayList<>(); - List> subscribers = new ArrayList<>(); + List subscriptions = new ArrayList(); + List> subscribers = new ArrayList>(); for (int i = 0; i < subCount; ++i) { - TestSubscriber subscriber = new TestSubscriber<>(); + TestSubscriber subscriber = new TestSubscriber(); longs.subscribe(subscriber); subscriptions.add(subscriber); subscribers.add(subscriber); diff --git a/src/test/java/io/reactivex/internal/operators/OperatorElementAtTest.java b/src/test/java/io/reactivex/internal/operators/OperatorElementAtTest.java index f96f121020..9985b83cc5 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorElementAtTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorElementAtTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 diff --git a/src/test/java/io/reactivex/internal/operators/OperatorFilterTest.java b/src/test/java/io/reactivex/internal/operators/OperatorFilterTest.java index 54944be108..397b5f2909 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorFilterTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorFilterTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -17,13 +17,13 @@ import static org.mockito.Mockito.*; import java.util.concurrent.CountDownLatch; -import java.util.function.Predicate; import org.junit.Test; import org.mockito.Mockito; import org.reactivestreams.Subscriber; import io.reactivex.*; +import io.reactivex.functions.Predicate; import io.reactivex.subscribers.TestSubscriber; public class OperatorFilterTest { @@ -52,6 +52,8 @@ public boolean test(String t1) { /** * Make sure we are adjusting subscriber.request() for filtered items + * @throws InterruptedException if the test is interrupted + * @throws InterruptedException if the test is interrupted */ @Test(timeout = 500) public void testWithBackpressure() throws InterruptedException { @@ -98,6 +100,7 @@ public void onNext(String t) { /** * Make sure we are adjusting subscriber.request() for filtered items + * @throws InterruptedException if the test is interrupted */ @Test(timeout = 500000) public void testWithBackpressure2() throws InterruptedException { diff --git a/src/test/java/io/reactivex/internal/operators/OperatorFinallyTest.java b/src/test/java/io/reactivex/internal/operators/OperatorFinallyTest.java index 35aea3ba4e..08c6e449e0 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorFinallyTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorFinallyTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 diff --git a/src/test/java/io/reactivex/internal/operators/OperatorFirstTest.java b/src/test/java/io/reactivex/internal/operators/OperatorFirstTest.java index 220459ddc2..210923d73f 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorFirstTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorFirstTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -17,13 +17,13 @@ import static org.mockito.Mockito.*; import java.util.NoSuchElementException; -import java.util.function.Predicate; import org.junit.*; import org.mockito.InOrder; import org.reactivestreams.Subscriber; import io.reactivex.*; +import io.reactivex.functions.Predicate; public class OperatorFirstTest { @@ -127,7 +127,12 @@ public void testFirstWithEmpty() { @Test public void testFirstWithPredicate() { Observable observable = Observable.just(1, 2, 3, 4, 5, 6) - .filter(t1 -> t1 % 2 == 0) + .filter(new Predicate() { + @Override + public boolean test(Integer t1) { + return t1 % 2 == 0; + } + }) .first(); Subscriber observer = TestHelper.mockSubscriber(); @@ -142,7 +147,12 @@ public void testFirstWithPredicate() { @Test public void testFirstWithPredicateAndOneElement() { Observable observable = Observable.just(1, 2) - .filter(t1 -> t1 % 2 == 0) + .filter(new Predicate() { + @Override + public boolean test(Integer t1) { + return t1 % 2 == 0; + } + }) .first(); Subscriber observer = TestHelper.mockSubscriber(); @@ -157,7 +167,12 @@ public void testFirstWithPredicateAndOneElement() { @Test public void testFirstWithPredicateAndEmpty() { Observable observable = Observable.just(1) - .filter(t1 -> t1 % 2 == 0) + .filter(new Predicate() { + @Override + public boolean test(Integer t1) { + return t1 % 2 == 0; + } + }) .first(); Subscriber observer = TestHelper.mockSubscriber(); @@ -213,7 +228,12 @@ public void testFirstOrDefaultWithEmpty() { @Test public void testFirstOrDefaultWithPredicate() { Observable observable = Observable.just(1, 2, 3, 4, 5, 6) - .filter(t1 -> t1 % 2 == 0) + .filter(new Predicate() { + @Override + public boolean test(Integer t1) { + return t1 % 2 == 0; + } + }) .first(8); Subscriber observer = TestHelper.mockSubscriber(); @@ -228,7 +248,12 @@ public void testFirstOrDefaultWithPredicate() { @Test public void testFirstOrDefaultWithPredicateAndOneElement() { Observable observable = Observable.just(1, 2) - .filter(t1 -> t1 % 2 == 0) + .filter(new Predicate() { + @Override + public boolean test(Integer t1) { + return t1 % 2 == 0; + } + }) .first(4); Subscriber observer = TestHelper.mockSubscriber(); @@ -243,7 +268,12 @@ public void testFirstOrDefaultWithPredicateAndOneElement() { @Test public void testFirstOrDefaultWithPredicateAndEmpty() { Observable observable = Observable.just(1) - .filter(t1 -> t1 % 2 == 0) + .filter(new Predicate() { + @Override + public boolean test(Integer t1) { + return t1 % 2 == 0; + } + }) .first(2); Subscriber observer = TestHelper.mockSubscriber(); diff --git a/src/test/java/io/reactivex/internal/operators/OperatorFlatMapTest.java b/src/test/java/io/reactivex/internal/operators/OperatorFlatMapTest.java index 5d6ab835f5..08044c702c 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorFlatMapTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorFlatMapTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -20,14 +20,14 @@ import java.util.*; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.*; import org.junit.*; -import org.reactivestreams.Subscriber; +import org.reactivestreams.*; import io.reactivex.Observable; import io.reactivex.TestHelper; import io.reactivex.exceptions.TestException; +import io.reactivex.functions.*; import io.reactivex.schedulers.Schedulers; import io.reactivex.subscribers.TestSubscriber; @@ -302,16 +302,22 @@ public void testFlatMapTransformsMergeException() { } private static Observable composer(Observable source, final AtomicInteger subscriptionCount, final int m) { - return source.doOnSubscribe(s -> { - int n = subscriptionCount.getAndIncrement(); - if (n >= m) { - Assert.fail("Too many subscriptions! " + (n + 1)); - } - }).doOnComplete(() -> { - int n = subscriptionCount.decrementAndGet(); - if (n < 0) { - Assert.fail("Too many unsubscriptions! " + (n - 1)); - } + return source.doOnSubscribe(new Consumer() { + @Override + public void accept(Subscription s) { + int n = subscriptionCount.getAndIncrement(); + if (n >= m) { + Assert.fail("Too many subscriptions! " + (n + 1)); + } + } + }).doOnComplete(new Runnable() { + @Override + public void run() { + int n = subscriptionCount.decrementAndGet(); + if (n < 0) { + Assert.fail("Too many unsubscriptions! " + (n - 1)); + } + } }); } @@ -328,13 +334,13 @@ public Observable apply(Integer t1) { } }, m); - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); source.subscribe(ts); ts.awaitTerminalEvent(); ts.assertNoErrors(); - Set expected = new HashSet<>(Arrays.asList( + Set expected = new HashSet(Arrays.asList( 10, 11, 20, 21, 30, 31, 40, 41, 50, 51, 60, 61, 70, 71, 80, 81, 90, 91, 100, 101 )); Assert.assertEquals(expected.size(), ts.valueCount()); @@ -358,13 +364,13 @@ public Integer apply(Integer t1, Integer t2) { } }, m); - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); source.subscribe(ts); ts.awaitTerminalEvent(); ts.assertNoErrors(); - Set expected = new HashSet<>(Arrays.asList( + Set expected = new HashSet(Arrays.asList( 1010, 1011, 2020, 2021, 3030, 3031, 4040, 4041, 5050, 5051, 6060, 6061, 7070, 7071, 8080, 8081, 9090, 9091, 10100, 10101 )); @@ -404,9 +410,12 @@ public void testFlatMapTransformsMaxConcurrentNormal() { Observable source = Observable.fromIterable(Arrays.asList(10, 20, 30)); Subscriber o = TestHelper.mockSubscriber(); - TestSubscriber ts = new TestSubscriber<>(o); + TestSubscriber ts = new TestSubscriber(o); - source.flatMap(just(onNext), just(onError), just0(onCompleted), m).subscribe(ts); + Function> just = just(onNext); + Function> just2 = just(onError); + Supplier> just0 = just0(onCompleted); + source.flatMap(just, just2, just0, m).subscribe(ts); ts.awaitTerminalEvent(1, TimeUnit.SECONDS); ts.assertNoErrors(); @@ -429,7 +438,7 @@ public void flatMapRangeAsyncLoop() { if (i % 10 == 0) { System.out.println("flatMapRangeAsyncLoop > " + i); } - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); Observable.range(0, 1000) .flatMap(new Function>() { @Override @@ -466,7 +475,7 @@ public void flatMapRangeMixedAsyncLoop() { if (i % 10 == 0) { System.out.println("flatMapRangeAsyncLoop > " + i); } - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); Observable.range(0, 1000) .flatMap(new Function>() { final Random rnd = new Random(); @@ -490,7 +499,7 @@ public Observable apply(Integer t) { ts.assertNoErrors(); List list = ts.values(); if (list.size() < 1000) { - Set set = new HashSet<>(list); + Set set = new HashSet(list); for (int j = 0; j < 1000; j++) { if (!set.contains(j)) { System.out.println(j + " missing"); @@ -504,7 +513,7 @@ public Observable apply(Integer t) { @Test public void flatMapIntPassthruAsync() { for (int i = 0;i < 1000; i++) { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); Observable.range(1, 1000).flatMap(new Function>() { @Override @@ -522,7 +531,7 @@ public Observable apply(Integer t) { @Test public void flatMapTwoNestedSync() { for (final int n : new int[] { 1, 1000, 1000000 }) { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); Observable.just(1, 2).flatMap(new Function>() { @Override diff --git a/src/test/java/io/reactivex/internal/operators/OperatorGroupByTest.java b/src/test/java/io/reactivex/internal/operators/OperatorGroupByTest.java index c7ce0cc59f..63d2b6dd15 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorGroupByTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorGroupByTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -20,16 +20,17 @@ import java.util.*; import java.util.concurrent.*; import java.util.concurrent.atomic.*; -import java.util.function.*; -import org.junit.*; -import org.mockito.*; +import org.junit.Test; +import org.mockito.Matchers; import org.reactivestreams.*; +import io.reactivex.Optional; import io.reactivex.Observable; import io.reactivex.Observer; -import io.reactivex.Try; +import io.reactivex.*; import io.reactivex.exceptions.TestException; +import io.reactivex.functions.*; import io.reactivex.internal.subscriptions.*; import io.reactivex.observables.GroupedObservable; import io.reactivex.schedulers.Schedulers; @@ -37,7 +38,12 @@ public class OperatorGroupByTest { - final Function length = String::length; + final Function length = new Function() { + @Override + public Integer apply(String s) { + return s.length(); + } + }; @Test public void testGroupBy() { @@ -98,7 +104,7 @@ public void testError() { final AtomicInteger groupCounter = new AtomicInteger(); final AtomicInteger eventCounter = new AtomicInteger(); - final AtomicReference error = new AtomicReference<>(); + final AtomicReference error = new AtomicReference(); grouped.flatMap(new Function, Observable>() { @@ -141,7 +147,7 @@ public void onNext(String v) { private static Map> toMap(Observable> observable) { - final ConcurrentHashMap> result = new ConcurrentHashMap<>(); + final ConcurrentHashMap> result = new ConcurrentHashMap>(); observable.toBlocking().forEach(new Consumer>() { @@ -551,7 +557,12 @@ public Observable apply(GroupedObservable eventGroupedOb Observable eventStream = eventGroupedObservable; if (eventGroupedObservable.getKey() >= 2) { // filter these - eventStream = eventGroupedObservable.filter(t1 -> false); + eventStream = eventGroupedObservable.filter(new Predicate() { + @Override + public boolean test(Event t1) { + return false; + } + }); } return eventStream @@ -583,7 +594,7 @@ public void accept(String s) { @Test public void testFirstGroupsCompleteAndParentSlowToThenEmitFinalGroupsAndThenComplete() throws InterruptedException { final CountDownLatch first = new CountDownLatch(2); // there are two groups to first complete - final ArrayList results = new ArrayList<>(); + final ArrayList results = new ArrayList(); Observable.create(new Publisher() { @Override @@ -662,7 +673,7 @@ public void accept(String s) { public void testFirstGroupsCompleteAndParentSlowToThenEmitFinalGroupsWhichThenSubscribesOnAndDelaysAndThenCompletes() throws InterruptedException { System.err.println("----------------------------------------------------------------------------------------------"); final CountDownLatch first = new CountDownLatch(2); // there are two groups to first complete - final ArrayList results = new ArrayList<>(); + final ArrayList results = new ArrayList(); Observable.create(new Publisher() { @Override @@ -754,7 +765,7 @@ public void accept(String s) { @Test public void testFirstGroupsCompleteAndParentSlowToThenEmitFinalGroupsWhichThenObservesOnAndDelaysAndThenCompletes() throws InterruptedException { final CountDownLatch first = new CountDownLatch(2); // there are two groups to first complete - final ArrayList results = new ArrayList<>(); + final ArrayList results = new ArrayList(); Observable.create(new Publisher() { @Override @@ -831,7 +842,7 @@ public void accept(String s) { @Test public void testGroupsWithNestedSubscribeOn() throws InterruptedException { - final ArrayList results = new ArrayList<>(); + final ArrayList results = new ArrayList(); Observable.create(new Publisher() { @Override @@ -888,7 +899,7 @@ public void accept(String s) { @Test public void testGroupsWithNestedObserveOn() throws InterruptedException { - final ArrayList results = new ArrayList<>(); + final ArrayList results = new ArrayList(); Observable.create(new Publisher() { @Override @@ -1015,7 +1026,7 @@ public Boolean apply(Integer n) { @Test public void testGroupByBackpressure() throws InterruptedException { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); Observable.range(1, 4000) .groupBy(IS_EVEN2) @@ -1079,7 +1090,12 @@ public Integer apply(Integer t1) { return t1 * 2; } }; - Function identity = v -> v; + Function identity = new Function() { + @Override + public Integer apply(Integer v) { + return v; + } + }; @Test public void normalBehavior() { @@ -1119,22 +1135,25 @@ public String apply(String t1) { }; Observable m = source.groupBy(keysel, valuesel) - .flatMap(g -> { - System.out.println("-----------> NEXT: " + g.getKey()); - return g.take(2).map(new Function() { + .flatMap(new Function, Publisher>() { + @Override + public Publisher apply(final GroupedObservable g) { + System.out.println("-----------> NEXT: " + g.getKey()); + return g.take(2).map(new Function() { - int count = 0; + int count = 0; - @Override - public String apply(String v) { - System.out.println(v); - return g.getKey() + "-" + count++; - } + @Override + public String apply(String v) { + System.out.println(v); + return g.getKey() + "-" + count++; + } - }); + }); + } }); - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); m.subscribe(ts); ts.awaitTerminalEvent(); System.out.println("ts .get " + ts.values()); @@ -1150,7 +1169,7 @@ public void keySelectorThrows() { Observable m = source.groupBy(fail(0), dbl).flatMap(FLATTEN_INTEGER); - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); m.subscribe(ts); ts.awaitTerminalEvent(); assertEquals(1, ts.errorCount()); @@ -1162,7 +1181,7 @@ public void valueSelectorThrows() { Observable source = Observable.just(0, 1, 2, 3, 4, 5, 6); Observable m = source.groupBy(identity, fail(0)).flatMap(FLATTEN_INTEGER); - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); m.subscribe(ts); ts.awaitTerminalEvent(); assertEquals(1, ts.errorCount()); @@ -1176,7 +1195,7 @@ public void innerEscapeCompleted() { Observable m = source.groupBy(identity, dbl).flatMap(FLATTEN_INTEGER); - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); m.subscribe(ts); ts.awaitTerminalEvent(); ts.assertNoErrors(); @@ -1190,7 +1209,7 @@ public void innerEscapeCompleted() { public void testExceptionIfSubscribeToChildMoreThanOnce() { Observable source = Observable.just(0); - final AtomicReference> inner = new AtomicReference<>(); + final AtomicReference> inner = new AtomicReference>(); Observable> m = source.groupBy(identity, dbl); @@ -1220,7 +1239,7 @@ public void testError2() { Observable m = source.groupBy(identity, dbl).flatMap(FLATTEN_INTEGER); - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); m.subscribe(ts); ts.awaitTerminalEvent(); assertEquals(1, ts.errorCount()); @@ -1229,7 +1248,7 @@ public void testError2() { @Test public void testgroupByBackpressure() throws InterruptedException { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); Observable.range(1, 4000).groupBy(IS_EVEN2).flatMap(new Function, Observable>() { @@ -1286,9 +1305,16 @@ public void accept(Try> t1) { @Test public void testgroupByBackpressure2() throws InterruptedException { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); - Observable.range(1, 4000).groupBy(IS_EVEN2).flatMap(new Function, Observable>() { + Observable.range(1, 4000) + .doOnNext(new Consumer() { + @Override + public void accept(Integer v) { + System.out.println("testgroupByBackpressure2 >> " + v); + } + }) + .groupBy(IS_EVEN2).flatMap(new Function, Observable>() { @Override public Observable apply(final GroupedObservable g) { @@ -1327,7 +1353,7 @@ public Observable apply(GroupedObservable t) { @Test public void testGroupByWithNullKey() { final String[] key = new String[]{"uninitialized"}; - final List values = new ArrayList<>(); + final List values = new ArrayList(); Observable.just("a", "b", "c").groupBy(new Function() { @Override @@ -1363,7 +1389,7 @@ public void subscribe(Subscriber subscriber) { } } ); - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); o.groupBy(new Function() { @@ -1381,11 +1407,11 @@ public Integer apply(Integer integer) { @Test public void testGroupByShouldPropagateError() { final Throwable e = new RuntimeException("Oops"); - final TestSubscriber inner1 = new TestSubscriber<>(); - final TestSubscriber inner2 = new TestSubscriber<>(); + final TestSubscriber inner1 = new TestSubscriber(); + final TestSubscriber inner2 = new TestSubscriber(); final TestSubscriber> outer - = new TestSubscriber<>(new Observer>() { + = new TestSubscriber>(new Observer>() { @Override public void onComplete() { @@ -1471,4 +1497,102 @@ public void onNext(Integer t) { }}); assertTrue(completed.get()); } + + /** + * Issue #3425. + * + * The problem is that a request of 1 may create a new group, emit to the desired group + * or emit to a completely different group. In this test, the merge requests N which + * must be produced by the range, however it will create a bunch of groups before the actual + * group receives a value. + */ + @Test + public void testBackpressureObserveOnOuter() { + for (int j = 0; j < 1000; j++) { + Observable.merge( + Observable.range(0, 500) + .groupBy(new Function() { + @Override + public Object apply(Integer i) { + return i % (Observable.bufferSize() + 2); + } + }) + .observeOn(Schedulers.computation()) + ).toBlocking().last(); + } + } + + /** + * Synchronous verification of issue #3425. + */ + @Test + public void testBackpressureInnerDoesntOverflowOuter() { + TestSubscriber> ts = new TestSubscriber>((Long)null); + + Observable.fromArray(1, 2) + .groupBy(new Function() { + @Override + public Integer apply(Integer v) { + return v; + } + }) + .doOnNext(new Consumer>() { + @Override + public void accept(GroupedObservable g) { + g.subscribe(); + } + }) // this will request Long.MAX_VALUE + .subscribe(ts) + ; + ts.request(1); + + ts.assertNotComplete(); + ts.assertNoErrors(); + ts.assertValueCount(1); + } + + @Test + public void testOneGroupInnerRequestsTwiceBuffer() { + TestSubscriber ts1 = new TestSubscriber((Long)null); + final TestSubscriber ts2 = new TestSubscriber((Long)null); + + Observable.range(1, Observable.bufferSize() * 2) + .groupBy(new Function() { + @Override + public Object apply(Integer v) { + return 1; + } + }) + .doOnNext(new Consumer>() { + @Override + public void accept(GroupedObservable g) { + g.subscribe(ts2); + } + }) + .subscribe(ts1); + + ts1.assertNoValues(); + ts1.assertNoErrors(); + ts1.assertNotComplete(); + + ts2.assertNoValues(); + ts2.assertNoErrors(); + ts2.assertNotComplete(); + + ts1.request(1); + + ts1.assertValueCount(1); + ts1.assertNoErrors(); + ts1.assertNotComplete(); + + ts2.assertNoValues(); + ts2.assertNoErrors(); + ts2.assertNotComplete(); + + ts2.request(Observable.bufferSize() * 2); + + ts2.assertValueCount(Observable.bufferSize() * 2); + ts2.assertNoErrors(); + ts2.assertNotComplete(); + } } \ No newline at end of file diff --git a/src/test/java/io/reactivex/internal/operators/OperatorIgnoreElementsTest.java b/src/test/java/io/reactivex/internal/operators/OperatorIgnoreElementsTest.java index 49509565a4..ccf35ec5e5 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorIgnoreElementsTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorIgnoreElementsTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -16,12 +16,12 @@ import static org.junit.Assert.*; import java.util.concurrent.atomic.*; -import java.util.function.Consumer; import org.junit.Test; import io.reactivex.*; import io.reactivex.exceptions.TestException; +import io.reactivex.functions.Consumer; import io.reactivex.subscribers.TestSubscriber; public class OperatorIgnoreElementsTest { @@ -55,7 +55,7 @@ public void accept(Integer t) { @Test public void testCompletedOk() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); Observable.range(1, 10).ignoreElements().subscribe(ts); ts.assertNoErrors(); ts.assertNoValues(); @@ -66,7 +66,7 @@ public void testCompletedOk() { @Test public void testErrorReceived() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); TestException ex = new TestException("boo"); Observable.error(ex).ignoreElements().subscribe(ts); ts.assertNoValues(); diff --git a/src/test/java/io/reactivex/internal/operators/OperatorLastTest.java b/src/test/java/io/reactivex/internal/operators/OperatorLastTest.java index a4f28e5e85..1ad7796bb1 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorLastTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorLastTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -18,13 +18,13 @@ import static org.mockito.Mockito.*; import java.util.NoSuchElementException; -import java.util.function.Predicate; import org.junit.Test; import org.mockito.InOrder; import org.reactivestreams.Subscriber; import io.reactivex.*; +import io.reactivex.functions.Predicate; public class OperatorLastTest { diff --git a/src/test/java/io/reactivex/internal/operators/OperatorMapNotificationTest.java b/src/test/java/io/reactivex/internal/operators/OperatorMapNotificationTest.java index 4be98a82e4..e2c8f73b5b 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorMapNotificationTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorMapNotificationTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,17 +13,16 @@ package io.reactivex.internal.operators; -import java.util.function.*; - import org.junit.Test; import io.reactivex.Observable; +import io.reactivex.functions.*; import io.reactivex.subscribers.TestSubscriber; public class OperatorMapNotificationTest { @Test public void testJust() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); Observable.just(1) .flatMap( new Function>() { diff --git a/src/test/java/io/reactivex/internal/operators/OperatorMapTest.java b/src/test/java/io/reactivex/internal/operators/OperatorMapTest.java index 67bfa663c4..14cd32fcc5 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorMapTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorMapTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -17,13 +17,13 @@ import static org.mockito.Mockito.*; import java.util.*; -import java.util.function.*; import org.junit.*; import org.reactivestreams.Subscriber; import io.reactivex.Observable; import io.reactivex.TestHelper; +import io.reactivex.functions.*; import io.reactivex.schedulers.Schedulers; public class OperatorMapTest { @@ -50,7 +50,12 @@ public void testMap() { Map m2 = getMap("Two"); Observable> observable = Observable.just(m1, m2); - Observable m = observable.map(map -> map.get("firstName")); + Observable m = observable.map(new Function, String>() { + @Override + public String apply(Map map) { + return map.get("firstName"); + } + }); m.subscribe(stringObserver); @@ -296,7 +301,7 @@ public Integer apply(Integer i) { // } private static Map getMap(String prefix) { - Map m = new HashMap<>(); + Map m = new HashMap(); m.put("firstName", prefix + "First"); m.put("lastName", prefix + "Last"); return m; diff --git a/src/test/java/io/reactivex/internal/operators/OperatorMaterializeTest.java b/src/test/java/io/reactivex/internal/operators/OperatorMaterializeTest.java index 22ed1f396b..df5857872f 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorMaterializeTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorMaterializeTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -17,14 +17,15 @@ import java.util.*; import java.util.concurrent.ExecutionException; -import java.util.function.Consumer; import org.junit.Test; import org.reactivestreams.*; -import io.reactivex.*; +import io.reactivex.Optional; import io.reactivex.Observable; import io.reactivex.Observer; +import io.reactivex.*; +import io.reactivex.functions.Consumer; import io.reactivex.internal.subscriptions.EmptySubscription; import io.reactivex.schedulers.Schedulers; import io.reactivex.subscribers.TestSubscriber; @@ -97,7 +98,7 @@ public void testMultipleSubscribes() throws InterruptedException, ExecutionExcep @Test public void testBackpressureOnEmptyStream() { - TestSubscriber>> ts = new TestSubscriber<>((Long)null); + TestSubscriber>> ts = new TestSubscriber>>((Long)null); Observable. empty().materialize().subscribe(ts); ts.assertNoValues(); ts.request(1); @@ -108,7 +109,7 @@ public void testBackpressureOnEmptyStream() { @Test public void testBackpressureNoError() { - TestSubscriber>> ts = new TestSubscriber<>((Long)null); + TestSubscriber>> ts = new TestSubscriber>>((Long)null); Observable.just(1, 2, 3).materialize().subscribe(ts); ts.assertNoValues(); ts.request(1); @@ -122,7 +123,7 @@ public void testBackpressureNoError() { @Test public void testBackpressureNoErrorAsync() throws InterruptedException { - TestSubscriber>> ts = new TestSubscriber<>((Long)null); + TestSubscriber>> ts = new TestSubscriber>>((Long)null); Observable.just(1, 2, 3) .materialize() .subscribeOn(Schedulers.computation()) @@ -143,7 +144,7 @@ public void testBackpressureNoErrorAsync() throws InterruptedException { @Test public void testBackpressureWithError() { - TestSubscriber>> ts = new TestSubscriber<>((Long)null); + TestSubscriber>> ts = new TestSubscriber>>((Long)null); Observable. error(new IllegalArgumentException()).materialize().subscribe(ts); ts.assertNoValues(); ts.request(1); @@ -153,7 +154,7 @@ public void testBackpressureWithError() { @Test public void testBackpressureWithEmissionThenError() { - TestSubscriber>> ts = new TestSubscriber<>((Long)null); + TestSubscriber>> ts = new TestSubscriber>>((Long)null); IllegalArgumentException ex = new IllegalArgumentException(); Observable.fromIterable(Arrays.asList(1)).concatWith(Observable. error(ex)).materialize() .subscribe(ts); @@ -170,7 +171,7 @@ public void testBackpressureWithEmissionThenError() { @Test public void testWithCompletionCausingError() { - TestSubscriber>> ts = new TestSubscriber<>(); + TestSubscriber>> ts = new TestSubscriber>>(); final RuntimeException ex = new RuntimeException("boo"); Observable.empty().materialize().doOnNext(new Consumer() { @Override @@ -185,7 +186,7 @@ public void accept(Object t) { @Test public void testUnsubscribeJustBeforeCompletionNotificationShouldPreventThatNotificationArriving() { - TestSubscriber>> ts = new TestSubscriber<>((Long)null); + TestSubscriber>> ts = new TestSubscriber>>((Long)null); Observable.empty().materialize() .subscribe(ts); @@ -201,7 +202,7 @@ private static class TestObserver extends Observer>> { boolean onCompleted = false; boolean onError = false; - List>> notifications = new Vector<>(); + List>> notifications = new Vector>>(); @Override public void onComplete() { diff --git a/src/test/java/io/reactivex/internal/operators/OperatorMergeDelayErrorTest.java b/src/test/java/io/reactivex/internal/operators/OperatorMergeDelayErrorTest.java index 2ee237dbf8..86880e096b 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorMergeDelayErrorTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorMergeDelayErrorTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -19,16 +19,16 @@ import java.util.*; import java.util.concurrent.*; -import java.util.function.LongConsumer; import org.junit.*; import org.mockito.InOrder; import org.reactivestreams.*; +import io.reactivex.*; import io.reactivex.Observable; import io.reactivex.Observer; -import io.reactivex.TestHelper; -import io.reactivex.exceptions.TestException; +import io.reactivex.exceptions.*; +import io.reactivex.functions.LongConsumer; import io.reactivex.internal.subscriptions.EmptySubscription; import io.reactivex.subscribers.TestSubscriber; @@ -197,7 +197,11 @@ public void testCompositeErrorDelayed2() { assertNotNull(w.e); - assertEquals(1, w.e.getSuppressed().length); + int size = ((CompositeException)w.e).size(); + if (size != 2) { + w.e.printStackTrace(); + } + assertEquals(2, size); // if (w.e instanceof CompositeException) { // assertEquals(2, ((CompositeException) w.e).getExceptions().size()); @@ -254,7 +258,7 @@ public void testMergeArray() { public void testMergeList() { final Observable o1 = Observable.create(new TestSynchronousObservable()); final Observable o2 = Observable.create(new TestSynchronousObservable()); - List> listOfObservables = new ArrayList<>(); + List> listOfObservables = new ArrayList>(); listOfObservables.add(o1); listOfObservables.add(o2); @@ -490,7 +494,7 @@ public void onComplete() { @Test public void testErrorInParentObservable() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); Observable.mergeDelayError( Observable.just(Observable.just(1), Observable.just(2)) .startWith(Observable. error(new RuntimeException())) @@ -519,7 +523,7 @@ public void subscribe(Subscriber> op) { Subscriber stringObserver = TestHelper.mockSubscriber(); - TestSubscriber ts = new TestSubscriber<>(stringObserver); + TestSubscriber ts = new TestSubscriber(stringObserver); Observable m = Observable.mergeDelayError(parentObservable); m.subscribe(ts); System.out.println("testErrorInParentObservableDelayed | " + i); @@ -557,7 +561,7 @@ public void run() { } @Test public void testDelayErrorMaxConcurrent() { - final List requests = new ArrayList<>(); + final List requests = new ArrayList(); Observable source = Observable.mergeDelayError(Observable.just( Observable.just(1).asObservable(), Observable.error(new TestException())) @@ -568,7 +572,7 @@ public void accept(long t1) { } }), 1); - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); source.subscribe(ts); diff --git a/src/test/java/io/reactivex/internal/operators/OperatorMergeMaxConcurrentTest.java b/src/test/java/io/reactivex/internal/operators/OperatorMergeMaxConcurrentTest.java index abe705f74d..f83024c98d 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorMergeMaxConcurrentTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorMergeMaxConcurrentTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -41,14 +41,14 @@ public void before() { @Test public void testWhenMaxConcurrentIsOne() { for (int i = 0; i < 100; i++) { - List> os = new ArrayList<>(); + List> os = new ArrayList>(); os.add(Observable.just("one", "two", "three", "four", "five").subscribeOn(Schedulers.newThread())); os.add(Observable.just("one", "two", "three", "four", "five").subscribeOn(Schedulers.newThread())); os.add(Observable.just("one", "two", "three", "four", "five").subscribeOn(Schedulers.newThread())); List expected = Arrays.asList("one", "two", "three", "four", "five", "one", "two", "three", "four", "five", "one", "two", "three", "four", "five"); Iterator iter = Observable.merge(os, 1).toBlocking().iterator(); - List actual = new ArrayList<>(); + List actual = new ArrayList(); while (iter.hasNext()) { actual.add(iter.next()); } @@ -64,8 +64,8 @@ public void testMaxConcurrent() { int maxConcurrent = 2 + (times % 10); AtomicInteger subscriptionCount = new AtomicInteger(0); - List> os = new ArrayList<>(); - List scos = new ArrayList<>(); + List> os = new ArrayList>(); + List scos = new ArrayList(); for (int i = 0; i < observableCount; i++) { SubscriptionCheckObservable sco = new SubscriptionCheckObservable(subscriptionCount, maxConcurrent); scos.add(sco); @@ -73,7 +73,7 @@ public void testMaxConcurrent() { } Iterator iter = Observable.merge(os, maxConcurrent).toBlocking().iterator(); - List actual = new ArrayList<>(); + List actual = new ArrayList(); while (iter.hasNext()) { actual.add(iter.next()); } @@ -125,7 +125,7 @@ public void run() { @Test public void testMergeALotOfSourcesOneByOneSynchronously() { int n = 10000; - List> sourceList = new ArrayList<>(n); + List> sourceList = new ArrayList>(n); for (int i = 0; i < n; i++) { sourceList.add(Observable.just(i)); } @@ -140,7 +140,7 @@ public void testMergeALotOfSourcesOneByOneSynchronously() { @Test public void testMergeALotOfSourcesOneByOneSynchronouslyTakeHalf() { int n = 10000; - List> sourceList = new ArrayList<>(n); + List> sourceList = new ArrayList>(n); for (int i = 0; i < n; i++) { sourceList.add(Observable.just(i)); } @@ -156,9 +156,9 @@ public void testMergeALotOfSourcesOneByOneSynchronouslyTakeHalf() { @Test public void testSimple() { for (int i = 1; i < 100; i++) { - TestSubscriber ts = new TestSubscriber<>(); - List> sourceList = new ArrayList<>(i); - List result = new ArrayList<>(i); + TestSubscriber ts = new TestSubscriber(); + List> sourceList = new ArrayList>(i); + List result = new ArrayList(i); for (int j = 1; j <= i; j++) { sourceList.add(Observable.just(j)); result.add(j); @@ -174,9 +174,9 @@ public void testSimple() { @Test public void testSimpleOneLess() { for (int i = 2; i < 100; i++) { - TestSubscriber ts = new TestSubscriber<>(); - List> sourceList = new ArrayList<>(i); - List result = new ArrayList<>(i); + TestSubscriber ts = new TestSubscriber(); + List> sourceList = new ArrayList>(i); + List result = new ArrayList(i); for (int j = 1; j <= i; j++) { sourceList.add(Observable.just(j)); result.add(j); @@ -204,9 +204,9 @@ public void testSimpleAsyncLoop() { @Test(timeout = 10000) public void testSimpleAsync() { for (int i = 1; i < 50; i++) { - TestSubscriber ts = new TestSubscriber<>(); - List> sourceList = new ArrayList<>(i); - Set expected = new HashSet<>(i); + TestSubscriber ts = new TestSubscriber(); + List> sourceList = new ArrayList>(i); + Set expected = new HashSet(i); for (int j = 1; j <= i; j++) { sourceList.add(Observable.just(j).subscribeOn(Schedulers.io())); expected.add(j); @@ -216,7 +216,7 @@ public void testSimpleAsync() { ts.awaitTerminalEvent(1, TimeUnit.SECONDS); ts.assertNoErrors(); - Set actual = new HashSet<>(ts.values()); + Set actual = new HashSet(ts.values()); assertEquals(expected, actual); } @@ -234,9 +234,9 @@ public void testSimpleOneLessAsync() { if (System.currentTimeMillis() - t > TimeUnit.SECONDS.toMillis(9)) { break; } - TestSubscriber ts = new TestSubscriber<>(); - List> sourceList = new ArrayList<>(i); - Set expected = new HashSet<>(i); + TestSubscriber ts = new TestSubscriber(); + List> sourceList = new ArrayList>(i); + Set expected = new HashSet(i); for (int j = 1; j <= i; j++) { sourceList.add(Observable.just(j).subscribeOn(Schedulers.io())); expected.add(j); @@ -246,14 +246,14 @@ public void testSimpleOneLessAsync() { ts.awaitTerminalEvent(1, TimeUnit.SECONDS); ts.assertNoErrors(); - Set actual = new HashSet<>(ts.values()); + Set actual = new HashSet(ts.values()); assertEquals(expected, actual); } } @Test(timeout = 5000) public void testBackpressureHonored() throws Exception { - List> sourceList = new ArrayList<>(3); + List> sourceList = new ArrayList>(3); sourceList.add(Observable.range(0, 100000).subscribeOn(Schedulers.io())); sourceList.add(Observable.range(0, 100000).subscribeOn(Schedulers.io())); @@ -283,13 +283,13 @@ public void onNext(Integer t) { } @Test(timeout = 5000) public void testTake() throws Exception { - List> sourceList = new ArrayList<>(3); + List> sourceList = new ArrayList>(3); sourceList.add(Observable.range(0, 100000).subscribeOn(Schedulers.io())); sourceList.add(Observable.range(0, 100000).subscribeOn(Schedulers.io())); sourceList.add(Observable.range(0, 100000).subscribeOn(Schedulers.io())); - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); Observable.merge(sourceList, 2).take(5).subscribe(ts); diff --git a/src/test/java/io/reactivex/internal/operators/OperatorMergeTest.java b/src/test/java/io/reactivex/internal/operators/OperatorMergeTest.java index ec8adf3954..236b8e10e7 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorMergeTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorMergeTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -21,15 +21,15 @@ import java.util.*; import java.util.concurrent.*; import java.util.concurrent.atomic.*; -import java.util.function.*; import org.junit.*; import org.reactivestreams.*; -import io.reactivex.*; import io.reactivex.Observable; import io.reactivex.Observer; +import io.reactivex.*; import io.reactivex.Scheduler.Worker; +import io.reactivex.functions.*; import io.reactivex.internal.subscriptions.*; import io.reactivex.schedulers.*; import io.reactivex.subscribers.TestSubscriber; @@ -111,7 +111,7 @@ public void testMergeArray() { public void testMergeList() { final Observable o1 = Observable.create(new TestSynchronousObservable()); final Observable o2 = Observable.create(new TestSynchronousObservable()); - List> listOfObservables = new ArrayList<>(); + List> listOfObservables = new ArrayList>(); listOfObservables.add(o1); listOfObservables.add(o2); @@ -197,7 +197,7 @@ public void testMergeArrayWithThreading() { final TestASynchronousObservable o2 = new TestASynchronousObservable(); Observable m = Observable.merge(Observable.create(o1), Observable.create(o2)); - TestSubscriber ts = new TestSubscriber<>(stringObserver); + TestSubscriber ts = new TestSubscriber(stringObserver); m.subscribe(ts); ts.awaitTerminalEvent(); @@ -343,7 +343,7 @@ public void testError2() { @Test @Ignore("Subscribe should not throw") public void testThrownErrorHandling() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); Observable o1 = Observable.create(new Publisher() { @Override @@ -429,7 +429,7 @@ public void testUnsubscribeAsObservablesComplete() { AtomicBoolean os2 = new AtomicBoolean(false); Observable o2 = createObservableOf5IntervalsOf1SecondIncrementsWithSubscriptionHook(scheduler2, os2); - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); Observable.merge(o1, o2).subscribe(ts); // we haven't incremented time so nothing should be received yet @@ -471,7 +471,7 @@ public void testEarlyUnsubscribe() { AtomicBoolean os2 = new AtomicBoolean(false); Observable o2 = createObservableOf5IntervalsOf1SecondIncrementsWithSubscriptionHook(scheduler2, os2); - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); Observable.merge(o1, o2).subscribe(ts); // we haven't incremented time so nothing should be received yet @@ -501,12 +501,12 @@ private Observable createObservableOf5IntervalsOf1SecondIncrementsWithSubs return Observable.create(new Publisher() { @Override - public void subscribe(Subscriber child) { + public void subscribe(final Subscriber child) { Observable.interval(1, TimeUnit.SECONDS, scheduler) .take(5) .subscribe(new Subscriber() { @Override - public void onSubscribe(Subscription s) { + public void onSubscribe(final Subscription s) { child.onSubscribe(new Subscription() { @Override public void request(long n) { @@ -549,7 +549,7 @@ public void testConcurrency() { for (int i = 0; i < 10; i++) { Observable merge = Observable.merge(o.onBackpressureBuffer(), o.onBackpressureBuffer(), o.onBackpressureBuffer()); - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); merge.subscribe(ts); ts.awaitTerminalEvent(3, TimeUnit.SECONDS); @@ -570,7 +570,7 @@ public void testConcurrencyWithSleeping() { @Override public void subscribe(final Subscriber s) { Worker inner = Schedulers.newThread().createWorker(); - AsyncSubscription as = new AsyncSubscription(); + final AsyncSubscription as = new AsyncSubscription(); as.setSubscription(EmptySubscription.INSTANCE); as.setResource(inner); @@ -602,7 +602,7 @@ public void run() { for (int i = 0; i < 10; i++) { Observable merge = Observable.merge(o, o, o); - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); merge.subscribe(ts); ts.awaitTerminalEvent(); @@ -620,7 +620,7 @@ public void testConcurrencyWithBrokenOnCompleteContract() { @Override public void subscribe(final Subscriber s) { Worker inner = Schedulers.newThread().createWorker(); - AsyncSubscription as = new AsyncSubscription(); + final AsyncSubscription as = new AsyncSubscription(); as.setSubscription(EmptySubscription.INSTANCE); as.setResource(inner); @@ -649,7 +649,7 @@ public void run() { for (int i = 0; i < 10; i++) { Observable merge = Observable.merge(o.onBackpressureBuffer(), o.onBackpressureBuffer(), o.onBackpressureBuffer()); - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); merge.subscribe(ts); ts.awaitTerminalEvent(); @@ -733,6 +733,7 @@ public void onNext(Integer t) { * This is the same as the upstreams ones, but now adds the downstream as well by using observeOn. * * This requires merge to also obey the Product.request values coming from it's child subscriber. + * @throws InterruptedException if the test is interrupted */ @Test(timeout = 10000) public void testBackpressureDownstreamWithConcurrentStreams() throws InterruptedException { @@ -871,7 +872,7 @@ public void onNext(Integer t) { @Ignore("Null values not permitted") public void mergeWithNullValues() { System.out.println("mergeWithNullValues"); - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); Observable.merge(Observable.just(null, "one"), Observable.just("two", null)).subscribe(ts); ts.assertTerminated(); ts.assertNoErrors(); @@ -882,7 +883,7 @@ public void mergeWithNullValues() { @Ignore("Null values are no longer permitted") public void mergeWithTerminalEventAfterUnsubscribe() { System.out.println("mergeWithTerminalEventAfterUnsubscribe"); - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); Observable bad = Observable.create(new Publisher() { @Override @@ -902,7 +903,7 @@ public void subscribe(Subscriber s) { @Test @Ignore("Null values are not permitted") public void mergingNullObservable() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); Observable.merge(Observable.just("one"), null).subscribe(ts); ts.assertNoErrors(); ts.assertValue("one"); @@ -910,7 +911,7 @@ public void mergingNullObservable() { @Test public void merge1AsyncStreamOf1() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); mergeNAsyncStreamsOfN(1, 1).subscribe(ts); ts.awaitTerminalEvent(); ts.assertNoErrors(); @@ -919,7 +920,7 @@ public void merge1AsyncStreamOf1() { @Test public void merge1AsyncStreamOf1000() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); mergeNAsyncStreamsOfN(1, 1000).subscribe(ts); ts.awaitTerminalEvent(); ts.assertNoErrors(); @@ -928,7 +929,7 @@ public void merge1AsyncStreamOf1000() { @Test public void merge10AsyncStreamOf1000() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); mergeNAsyncStreamsOfN(10, 1000).subscribe(ts); ts.awaitTerminalEvent(); ts.assertNoErrors(); @@ -937,7 +938,7 @@ public void merge10AsyncStreamOf1000() { @Test public void merge1000AsyncStreamOf1000() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); mergeNAsyncStreamsOfN(1000, 1000).subscribe(ts); ts.awaitTerminalEvent(); ts.assertNoErrors(); @@ -946,7 +947,7 @@ public void merge1000AsyncStreamOf1000() { @Test public void merge2000AsyncStreamOf100() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); mergeNAsyncStreamsOfN(2000, 100).subscribe(ts); ts.awaitTerminalEvent(); ts.assertNoErrors(); @@ -955,7 +956,7 @@ public void merge2000AsyncStreamOf100() { @Test public void merge100AsyncStreamOf1() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); mergeNAsyncStreamsOfN(100, 1).subscribe(ts); ts.awaitTerminalEvent(); ts.assertNoErrors(); @@ -977,7 +978,7 @@ public Observable apply(Integer i) { @Test public void merge1SyncStreamOf1() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); mergeNSyncStreamsOfN(1, 1).subscribe(ts); ts.awaitTerminalEvent(); ts.assertNoErrors(); @@ -986,7 +987,7 @@ public void merge1SyncStreamOf1() { @Test public void merge1SyncStreamOf1000000() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); mergeNSyncStreamsOfN(1, 1000000).subscribe(ts); ts.awaitTerminalEvent(); ts.assertNoErrors(); @@ -995,7 +996,7 @@ public void merge1SyncStreamOf1000000() { @Test public void merge1000SyncStreamOf1000() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); mergeNSyncStreamsOfN(1000, 1000).subscribe(ts); ts.awaitTerminalEvent(); ts.assertNoErrors(); @@ -1004,7 +1005,7 @@ public void merge1000SyncStreamOf1000() { @Test public void merge10000SyncStreamOf10() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); mergeNSyncStreamsOfN(10000, 10).subscribe(ts); ts.awaitTerminalEvent(); ts.assertNoErrors(); @@ -1013,7 +1014,7 @@ public void merge10000SyncStreamOf10() { @Test public void merge1000000SyncStreamOf1() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); mergeNSyncStreamsOfN(1000000, 1).subscribe(ts); ts.awaitTerminalEvent(); ts.assertNoErrors(); @@ -1060,7 +1061,7 @@ public boolean hasNext() { @Test public void mergeManyAsyncSingle() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); Observable> os = Observable.range(1, 10000) .map(new Function>() { @@ -1095,7 +1096,7 @@ public void subscribe(Subscriber s) { @Test public void shouldCompleteAfterApplyingBackpressure_NormalPath() { Observable source = Observable.mergeDelayError(Observable.just(Observable.range(1, 2))); - TestSubscriber subscriber = new TestSubscriber<>((Long)null); + TestSubscriber subscriber = new TestSubscriber((Long)null); source.subscribe(subscriber); subscriber.request(3); // 1, 2, - with request(2) we get the 1 and 2 but not the subscriber.assertValues(1, 2); @@ -1105,7 +1106,7 @@ public void shouldCompleteAfterApplyingBackpressure_NormalPath() { @Test public void shouldCompleteAfterApplyingBackpressure_FastPath() { Observable source = Observable.mergeDelayError(Observable.just(Observable.just(1))); - TestSubscriber subscriber = new TestSubscriber<>((Long)null); + TestSubscriber subscriber = new TestSubscriber((Long)null); source.subscribe(subscriber); subscriber.request(2); // 1, - should work as per .._NormalPath above subscriber.assertValue(1); @@ -1116,7 +1117,7 @@ public void shouldCompleteAfterApplyingBackpressure_FastPath() { public void shouldNotCompleteIfThereArePendingScalarSynchronousEmissionsWhenTheLastInnerSubscriberCompletes() { TestScheduler scheduler = Schedulers.test(); Observable source = Observable.mergeDelayError(Observable.just(1L), Observable.timer(1, TimeUnit.SECONDS, scheduler).skip(1)); - TestSubscriber subscriber = new TestSubscriber<>((Long)null); + TestSubscriber subscriber = new TestSubscriber((Long)null); source.subscribe(subscriber); scheduler.advanceTimeBy(1, TimeUnit.SECONDS); subscriber.assertNoValues(); @@ -1133,7 +1134,7 @@ public void shouldNotCompleteIfThereArePendingScalarSynchronousEmissionsWhenTheL public void delayedErrorsShouldBeEmittedWhenCompleteAfterApplyingBackpressure_NormalPath() { Throwable exception = new Throwable(); Observable source = Observable.mergeDelayError(Observable.range(1, 2), Observable.error(exception)); - TestSubscriber subscriber = new TestSubscriber<>((Long)null); + TestSubscriber subscriber = new TestSubscriber((Long)null); source.subscribe(subscriber); subscriber.request(3); // 1, 2, subscriber.assertValues(1, 2); @@ -1145,7 +1146,7 @@ public void delayedErrorsShouldBeEmittedWhenCompleteAfterApplyingBackpressure_No public void delayedErrorsShouldBeEmittedWhenCompleteAfterApplyingBackpressure_FastPath() { Throwable exception = new Throwable(); Observable source = Observable.mergeDelayError(Observable.just(1), Observable.error(exception)); - TestSubscriber subscriber = new TestSubscriber<>((Long)null); + TestSubscriber subscriber = new TestSubscriber((Long)null); source.subscribe(subscriber); subscriber.request(2); // 1, subscriber.assertValue(1); @@ -1156,7 +1157,7 @@ public void delayedErrorsShouldBeEmittedWhenCompleteAfterApplyingBackpressure_Fa @Test public void shouldNotCompleteWhileThereAreStillScalarSynchronousEmissionsInTheQueue() { Observable source = Observable.merge(Observable.just(1), Observable.just(2)); - TestSubscriber subscriber = new TestSubscriber<>(1L); + TestSubscriber subscriber = new TestSubscriber(1L); source.subscribe(subscriber); subscriber.assertValue(1); subscriber.request(1); @@ -1167,7 +1168,7 @@ public void shouldNotCompleteWhileThereAreStillScalarSynchronousEmissionsInTheQu public void shouldNotReceivedDelayedErrorWhileThereAreStillScalarSynchronousEmissionsInTheQueue() { Throwable exception = new Throwable(); Observable source = Observable.mergeDelayError(Observable.just(1), Observable.just(2), Observable.error(exception)); - TestSubscriber subscriber = new TestSubscriber<>((Long)null); + TestSubscriber subscriber = new TestSubscriber((Long)null); subscriber.request(1); source.subscribe(subscriber); subscriber.assertValue(1); @@ -1181,7 +1182,7 @@ public void shouldNotReceivedDelayedErrorWhileThereAreStillScalarSynchronousEmis public void shouldNotReceivedDelayedErrorWhileThereAreStillNormalEmissionsInTheQueue() { Throwable exception = new Throwable(); Observable source = Observable.mergeDelayError(Observable.range(1, 2), Observable.range(3, 2), Observable.error(exception)); - TestSubscriber subscriber = new TestSubscriber<>((Long)null); + TestSubscriber subscriber = new TestSubscriber((Long)null); subscriber.request(3); source.subscribe(subscriber); subscriber.assertValues(1, 2, 3); @@ -1196,7 +1197,7 @@ public void testMergeKeepsRequesting() throws InterruptedException { //for (int i = 0; i < 5000; i++) { //System.out.println(i + "......................................................................."); final CountDownLatch latch = new CountDownLatch(1); - final ConcurrentLinkedQueue messages = new ConcurrentLinkedQueue<>(); + final ConcurrentLinkedQueue messages = new ConcurrentLinkedQueue(); Observable.range(1, 2) // produce many integers per second @@ -1234,8 +1235,11 @@ public void accept(long n) { // log count .doOnNext(printCount()) // release latch - .doOnComplete(() -> { - latch.countDown(); + .doOnComplete(new Runnable() { + @Override + public void run() { + latch.countDown(); + } }).subscribe(); boolean a = latch.await(2, TimeUnit.SECONDS); if (!a) { @@ -1305,14 +1309,23 @@ public void accept(Integer s) { }; } - Function> toScalar = Observable::just; + Function> toScalar = new Function>() { + @Override + public Observable apply(Integer v) { + return Observable.just(v); + } + }; - Function> toHiddenScalar = t -> - Observable.just(t).asObservable(); + Function> toHiddenScalar = new Function>() { + @Override + public Observable apply(Integer t) { + return Observable.just(t).asObservable(); + } + }; ; void runMerge(Function> func, TestSubscriber ts) { - List list = new ArrayList<>(); + List list = new ArrayList(); for (int i = 0; i < 1000; i++) { list.add(i); } diff --git a/src/test/java/io/reactivex/internal/operators/OperatorMulticastTest.java b/src/test/java/io/reactivex/internal/operators/OperatorMulticastTest.java index 0a7ad53a2f..32676aca4d 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorMulticastTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorMulticastTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 diff --git a/src/test/java/io/reactivex/internal/operators/OperatorObserveOnTest.java b/src/test/java/io/reactivex/internal/operators/OperatorObserveOnTest.java index f87ec7120c..8e5d91271e 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorObserveOnTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorObserveOnTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -20,16 +20,17 @@ import java.util.*; import java.util.concurrent.*; import java.util.concurrent.atomic.*; -import java.util.function.*; import org.junit.*; import org.mockito.InOrder; import org.reactivestreams.*; -import io.reactivex.*; +import io.reactivex.Optional; import io.reactivex.Observable; import io.reactivex.Observer; +import io.reactivex.*; import io.reactivex.exceptions.*; +import io.reactivex.functions.*; import io.reactivex.internal.subscriptions.EmptySubscription; import io.reactivex.schedulers.*; import io.reactivex.subjects.PublishSubject; @@ -62,7 +63,7 @@ public void testOrdering() throws InterruptedException { Subscriber observer = TestHelper.mockSubscriber(); InOrder inOrder = inOrder(observer); - TestSubscriber ts = new TestSubscriber<>(observer); + TestSubscriber ts = new TestSubscriber(observer); obs.observeOn(Schedulers.computation()).subscribe(ts); @@ -388,7 +389,7 @@ public void testAfterUnsubscribeCalledThenObserverOnNextNeverCalled() { final TestScheduler testScheduler = new TestScheduler(); final Subscriber observer = TestHelper.mockSubscriber(); - TestSubscriber ts = new TestSubscriber<>(observer); + TestSubscriber ts = new TestSubscriber(observer); Observable.just(1, 2, 3) .observeOn(testScheduler) @@ -523,7 +524,7 @@ public boolean hasNext() { } }); - TestSubscriber testSubscriber = new TestSubscriber<>(); + TestSubscriber testSubscriber = new TestSubscriber(); observable .take(7) .observeOn(Schedulers.newThread()) @@ -551,7 +552,7 @@ public void subscribe(Subscriber o) { }); - TestSubscriber testSubscriber = new TestSubscriber<>(new Observer() { + TestSubscriber testSubscriber = new TestSubscriber(new Observer() { @Override public void onComplete() { @@ -594,7 +595,7 @@ public void onNext(Integer t) { @Test public void testAsyncChild() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); Observable.range(0, 100000).observeOn(Schedulers.newThread()).observeOn(Schedulers.newThread()).subscribe(ts); ts.awaitTerminalEvent(); ts.assertNoErrors(); @@ -606,7 +607,7 @@ public void testOnErrorCutsAheadOfOnNext() { final PublishSubject subject = PublishSubject.create(); final AtomicLong counter = new AtomicLong(); - TestSubscriber ts = new TestSubscriber<>(new Observer() { + TestSubscriber ts = new TestSubscriber(new Observer() { @Override public void onComplete() { @@ -653,7 +654,7 @@ public void onNext(Long t) { */ @Test public void testHotOperatorBackpressure() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); Observable.interval(0, 1, TimeUnit.MICROSECONDS) .observeOn(Schedulers.computation()) .map(new Function() { @@ -701,7 +702,7 @@ public void accept(Try> n) { }); - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); Observable.combineLatest(timer, Observable. never(), new BiFunction() { diff --git a/src/test/java/io/reactivex/internal/operators/OperatorOnBackpressureBufferTest.java b/src/test/java/io/reactivex/internal/operators/OperatorOnBackpressureBufferTest.java index ef8fa11cc8..548c70da4e 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorOnBackpressureBufferTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorOnBackpressureBufferTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -30,7 +30,7 @@ public class OperatorOnBackpressureBufferTest { @Test public void testNoBackpressureSupport() { - TestSubscriber ts = new TestSubscriber<>((Long)null); + TestSubscriber ts = new TestSubscriber((Long)null); // this will be ignored ts.request(100); // we take 500 so it unsubscribes @@ -44,7 +44,7 @@ public void testNoBackpressureSupport() { public void testFixBackpressureWithBuffer() throws InterruptedException { final CountDownLatch l1 = new CountDownLatch(100); final CountDownLatch l2 = new CountDownLatch(150); - TestSubscriber ts = new TestSubscriber<>(new Observer() { + TestSubscriber ts = new TestSubscriber(new Observer() { @Override protected void onStart() { @@ -101,7 +101,7 @@ public void testFixBackpressureBufferZeroCapacity() throws InterruptedException public void testFixBackpressureBoundedBuffer() throws InterruptedException { final CountDownLatch l1 = new CountDownLatch(100); final CountDownLatch backpressureCallback = new CountDownLatch(1); - TestSubscriber ts = new TestSubscriber<>(new Observer() { + TestSubscriber ts = new TestSubscriber(new Observer() { @Override protected void onStart() { diff --git a/src/test/java/io/reactivex/internal/operators/OperatorOnBackpressureDropTest.java b/src/test/java/io/reactivex/internal/operators/OperatorOnBackpressureDropTest.java index 533c214507..8c0dab953f 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorOnBackpressureDropTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorOnBackpressureDropTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -30,7 +30,7 @@ public class OperatorOnBackpressureDropTest { @Test public void testNoBackpressureSupport() { - TestSubscriber ts = new TestSubscriber<>((Long)null); + TestSubscriber ts = new TestSubscriber((Long)null); // this will be ignored ts.request(100); // we take 500 so it unsubscribes @@ -42,7 +42,7 @@ public void testNoBackpressureSupport() { @Test(timeout = 500) public void testWithObserveOn() throws InterruptedException { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); Observable.range(0, Observable.bufferSize() * 10).onBackpressureDrop().observeOn(Schedulers.io()).subscribe(ts); ts.awaitTerminalEvent(); } @@ -51,7 +51,7 @@ public void testWithObserveOn() throws InterruptedException { public void testFixBackpressureWithBuffer() throws InterruptedException { final CountDownLatch l1 = new CountDownLatch(100); final CountDownLatch l2 = new CountDownLatch(150); - TestSubscriber ts = new TestSubscriber<>(new Observer() { + TestSubscriber ts = new TestSubscriber(new Observer() { @Override protected void onStart() { diff --git a/src/test/java/io/reactivex/internal/operators/OperatorOnBackpressureLatestTest.java b/src/test/java/io/reactivex/internal/operators/OperatorOnBackpressureLatestTest.java index 52ba3d334d..49ff71098b 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorOnBackpressureLatestTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorOnBackpressureLatestTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -27,7 +27,7 @@ public class OperatorOnBackpressureLatestTest { @Test public void testSimple() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); Observable.range(1, 5).onBackpressureLatest().subscribe(ts); @@ -37,7 +37,7 @@ public void testSimple() { } @Test public void testSimpleError() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); Observable.range(1, 5).concatWith(Observable.error(new TestException())) .onBackpressureLatest().subscribe(ts); @@ -48,7 +48,7 @@ public void testSimpleError() { } @Test public void testSimpleBackpressure() { - TestSubscriber ts = new TestSubscriber<>(2L); + TestSubscriber ts = new TestSubscriber(2L); Observable.range(1, 5).onBackpressureLatest().subscribe(ts); @@ -60,7 +60,7 @@ public void testSimpleBackpressure() { @Test public void testSynchronousDrop() { PublishSubject source = PublishSubject.create(); - TestSubscriber ts = new TestSubscriber<>((Long)null); + TestSubscriber ts = new TestSubscriber((Long)null); source.onBackpressureLatest().subscribe(ts); diff --git a/src/test/java/io/reactivex/internal/operators/OperatorOnErrorResumeNextViaFunctionTest.java b/src/test/java/io/reactivex/internal/operators/OperatorOnErrorResumeNextViaFunctionTest.java index 70652b13e1..aae1550b65 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorOnErrorResumeNextViaFunctionTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorOnErrorResumeNextViaFunctionTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -18,7 +18,6 @@ import static org.mockito.Mockito.*; import java.util.concurrent.atomic.AtomicReference; -import java.util.function.Function; import org.junit.*; import org.mockito.Mockito; @@ -26,6 +25,7 @@ import io.reactivex.*; import io.reactivex.Observable.Operator; +import io.reactivex.functions.Function; import io.reactivex.internal.subscriptions.EmptySubscription; import io.reactivex.schedulers.Schedulers; import io.reactivex.subscribers.TestSubscriber; @@ -34,7 +34,7 @@ public class OperatorOnErrorResumeNextViaFunctionTest { @Test public void testResumeNextWithSynchronousExecution() { - final AtomicReference receivedException = new AtomicReference<>(); + final AtomicReference receivedException = new AtomicReference(); Observable w = Observable.create(new Publisher() { @Override @@ -74,7 +74,7 @@ public Observable apply(Throwable t1) { @Test public void testResumeNextWithAsyncExecution() { - final AtomicReference receivedException = new AtomicReference<>(); + final AtomicReference receivedException = new AtomicReference(); Subscription s = mock(Subscription.class); TestObservable w = new TestObservable(s, "one"); Function> resume = new Function>() { @@ -150,7 +150,7 @@ public Observable apply(Throwable t1) { @Test @Ignore("Failed operator may leave the child subscriber in an inconsistent state which prevents further error delivery.") public void testOnErrorResumeReceivesErrorFromPreviousNonProtectedOperator() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); Observable.just(1).lift(new Operator() { @Override @@ -183,11 +183,11 @@ public Observable apply(Throwable t1) { @Test @Ignore("A crashing operator may leave the downstream in an inconsistent state and not suitable for event delivery") public void testOnErrorResumeReceivesErrorFromPreviousNonProtectedOperatorOnNext() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); Observable.just(1).lift(new Operator() { @Override - public Subscriber apply(Subscriber t1) { + public Subscriber apply(final Subscriber t1) { return new Subscriber() { @Override @@ -260,7 +260,7 @@ public Observable apply(Throwable t1) { @SuppressWarnings("unchecked") Observer observer = mock(Observer.class); - TestSubscriber ts = new TestSubscriber<>(observer, Long.MAX_VALUE); + TestSubscriber ts = new TestSubscriber(observer, Long.MAX_VALUE); observable.subscribe(ts); ts.awaitTerminalEvent(); @@ -312,7 +312,7 @@ public void run() { @Test public void testBackpressure() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); Observable.range(0, 100000) .onErrorResumeNext(new Function>() { diff --git a/src/test/java/io/reactivex/internal/operators/OperatorOnErrorResumeNextViaObservableTest.java b/src/test/java/io/reactivex/internal/operators/OperatorOnErrorResumeNextViaObservableTest.java index 9903b63561..e77335b9d3 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorOnErrorResumeNextViaObservableTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorOnErrorResumeNextViaObservableTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -17,13 +17,12 @@ import static org.mockito.Matchers.any; import static org.mockito.Mockito.*; -import java.util.function.Function; - import org.junit.*; import org.mockito.Mockito; import org.reactivestreams.*; import io.reactivex.*; +import io.reactivex.functions.Function; import io.reactivex.schedulers.Schedulers; import io.reactivex.subscribers.TestSubscriber; @@ -136,7 +135,7 @@ public void subscribe(Subscriber t1) { @SuppressWarnings("unchecked") Observer observer = mock(Observer.class); - TestSubscriber ts = new TestSubscriber<>(observer, Long.MAX_VALUE); + TestSubscriber ts = new TestSubscriber(observer, Long.MAX_VALUE); observable.subscribe(ts); ts.awaitTerminalEvent(); @@ -190,7 +189,7 @@ public void run() { @Test public void testBackpressure() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); Observable.range(0, 100000) .onErrorResumeNext(Observable.just(1)) .observeOn(Schedulers.computation()) diff --git a/src/test/java/io/reactivex/internal/operators/OperatorOnErrorReturnTest.java b/src/test/java/io/reactivex/internal/operators/OperatorOnErrorReturnTest.java index ceb944b6ec..a830da3716 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorOnErrorReturnTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorOnErrorReturnTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -18,13 +18,13 @@ import static org.mockito.Mockito.*; import java.util.concurrent.atomic.AtomicReference; -import java.util.function.Function; import org.junit.Test; import org.mockito.Mockito; import org.reactivestreams.*; import io.reactivex.*; +import io.reactivex.functions.Function; import io.reactivex.internal.subscriptions.EmptySubscription; import io.reactivex.schedulers.Schedulers; import io.reactivex.subscribers.TestSubscriber; @@ -35,7 +35,7 @@ public class OperatorOnErrorReturnTest { public void testResumeNext() { TestObservable f = new TestObservable("one"); Observable w = Observable.create(f); - final AtomicReference capturedException = new AtomicReference<>(); + final AtomicReference capturedException = new AtomicReference(); Observable observable = w.onErrorReturn(new Function() { @@ -71,7 +71,7 @@ public String apply(Throwable e) { public void testFunctionThrowsError() { TestObservable f = new TestObservable("one"); Observable w = Observable.create(f); - final AtomicReference capturedException = new AtomicReference<>(); + final AtomicReference capturedException = new AtomicReference(); Observable observable = w.onErrorReturn(new Function() { @@ -130,7 +130,7 @@ public String apply(Throwable t1) { @SuppressWarnings("unchecked") Observer observer = mock(Observer.class); - TestSubscriber ts = new TestSubscriber<>(observer, Long.MAX_VALUE); + TestSubscriber ts = new TestSubscriber(observer, Long.MAX_VALUE); observable.subscribe(ts); ts.awaitTerminalEvent(); @@ -144,7 +144,7 @@ public String apply(Throwable t1) { @Test public void testBackpressure() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); Observable.range(0, 100000) .onErrorReturn(new Function() { diff --git a/src/test/java/io/reactivex/internal/operators/OperatorOnExceptionResumeNextViaObservableTest.java b/src/test/java/io/reactivex/internal/operators/OperatorOnExceptionResumeNextViaObservableTest.java index 602a9d36d8..9faed28124 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorOnExceptionResumeNextViaObservableTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorOnExceptionResumeNextViaObservableTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -17,13 +17,12 @@ import static org.mockito.Matchers.any; import static org.mockito.Mockito.*; -import java.util.function.Function; - import org.junit.Test; import org.mockito.Mockito; import org.reactivestreams.*; import io.reactivex.*; +import io.reactivex.functions.Function; import io.reactivex.internal.subscriptions.EmptySubscription; import io.reactivex.schedulers.Schedulers; import io.reactivex.subscribers.TestSubscriber; @@ -47,7 +46,7 @@ public void testResumeNextWithException() { fail(e.getMessage()); } - verify(observer).onSubscribe(any()); + verify(observer).onSubscribe((Subscription)any()); verify(observer, times(1)).onNext("one"); verify(observer, Mockito.never()).onNext("two"); verify(observer, Mockito.never()).onNext("three"); @@ -75,7 +74,7 @@ public void testResumeNextWithRuntimeException() { fail(e.getMessage()); } - verify(observer).onSubscribe(any()); + verify(observer).onSubscribe((Subscription)any()); verify(observer, times(1)).onNext("one"); verify(observer, Mockito.never()).onNext("two"); verify(observer, Mockito.never()).onNext("three"); @@ -103,7 +102,7 @@ public void testThrowablePassesThru() { fail(e.getMessage()); } - verify(observer).onSubscribe(any()); + verify(observer).onSubscribe((Subscription)any()); verify(observer, times(1)).onNext("one"); verify(observer, never()).onNext("two"); verify(observer, never()).onNext("three"); @@ -131,7 +130,7 @@ public void testErrorPassesThru() { fail(e.getMessage()); } - verify(observer).onSubscribe(any()); + verify(observer).onSubscribe((Subscription)any()); verify(observer, times(1)).onNext("one"); verify(observer, never()).onNext("two"); verify(observer, never()).onNext("three"); @@ -188,7 +187,7 @@ public String apply(String s) { @Test public void testBackpressure() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); Observable.range(0, 100000) .onExceptionResumeNext(Observable.just(1)) .observeOn(Schedulers.computation()) diff --git a/src/test/java/io/reactivex/internal/operators/OperatorPublishTest.java b/src/test/java/io/reactivex/internal/operators/OperatorPublishTest.java index fc17665e3f..e75375d392 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorPublishTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorPublishTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -18,13 +18,14 @@ import java.util.*; import java.util.concurrent.*; import java.util.concurrent.atomic.*; -import java.util.function.*; import org.junit.Test; import org.reactivestreams.*; import io.reactivex.Observable; import io.reactivex.disposables.Disposable; +import io.reactivex.functions.*; +import io.reactivex.internal.operators.OperatorPublish; import io.reactivex.internal.subscriptions.EmptySubscription; import io.reactivex.observables.ConnectableObservable; import io.reactivex.schedulers.*; @@ -89,7 +90,12 @@ public void accept(String v) { public void testBackpressureFastSlow() { ConnectableObservable is = Observable.range(1, Observable.bufferSize() * 2).publish(); Observable fast = is.observeOn(Schedulers.computation()) - .doOnComplete(() -> System.out.println("^^^^^^^^^^^^^ completed FAST")); + .doOnComplete(new Runnable() { + @Override + public void run() { + System.out.println("^^^^^^^^^^^^^ completed FAST"); + } + }); Observable slow = is.observeOn(Schedulers.computation()).map(new Function() { int c = 0; @@ -115,7 +121,7 @@ public void run() { }); - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); Observable.merge(fast, slow).subscribe(ts); is.connect(); ts.awaitTerminalEvent(); @@ -135,7 +141,7 @@ public void accept(Integer t1) { } }); - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); xs.publish(new Function, Observable>() { @Override @@ -162,7 +168,7 @@ public boolean test(Integer i) { @Test public void testTakeUntilWithPublishedStream() { Observable xs = Observable.range(0, Observable.bufferSize() * 2); - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); ConnectableObservable xsp = xs.publish(); xsp.takeUntil(xsp.skipWhile(new Predicate() { @@ -198,7 +204,7 @@ public void run() { final AtomicBoolean child1Unsubscribed = new AtomicBoolean(); final AtomicBoolean child2Unsubscribed = new AtomicBoolean(); - final TestSubscriber ts2 = new TestSubscriber<>(); + final TestSubscriber ts2 = new TestSubscriber(); final TestSubscriber ts1 = new TestSubscriber() { @Override @@ -246,7 +252,7 @@ public void testConnectWithNoSubscriber() { co.connect(); // Emit 0 scheduler.advanceTimeBy(15, TimeUnit.MILLISECONDS); - TestSubscriber subscriber = new TestSubscriber<>(); + TestSubscriber subscriber = new TestSubscriber(); co.subscribe(subscriber); // Emit 1 and 2 scheduler.advanceTimeBy(50, TimeUnit.MILLISECONDS); @@ -259,7 +265,7 @@ public void testConnectWithNoSubscriber() { public void testSubscribeAfterDisconnectThenConnect() { ConnectableObservable source = Observable.just(1).publish(); - TestSubscriber ts1 = new TestSubscriber<>(); + TestSubscriber ts1 = new TestSubscriber(); source.subscribe(ts1); @@ -269,7 +275,7 @@ public void testSubscribeAfterDisconnectThenConnect() { ts1.assertNoErrors(); ts1.assertTerminated(); - TestSubscriber ts2 = new TestSubscriber<>(); + TestSubscriber ts2 = new TestSubscriber(); source.subscribe(ts2); @@ -287,7 +293,7 @@ public void testSubscribeAfterDisconnectThenConnect() { public void testNoSubscriberRetentionOnCompleted() { OperatorPublish source = (OperatorPublish)Observable.just(1).publish(); - TestSubscriber ts1 = new TestSubscriber<>(); + TestSubscriber ts1 = new TestSubscriber(); source.unsafeSubscribe(ts1); @@ -339,7 +345,7 @@ static boolean checkPublishDisposed(Disposable d) { public void testZeroRequested() { ConnectableObservable source = Observable.just(1).publish(); - TestSubscriber ts = new TestSubscriber<>((Long)null); + TestSubscriber ts = new TestSubscriber((Long)null); source.subscribe(ts); @@ -392,9 +398,9 @@ public void testObserveOn() { Observable obs = co.observeOn(Schedulers.computation()); for (int i = 0; i < 1000; i++) { for (int j = 1; j < 6; j++) { - List> tss = new ArrayList<>(); + List> tss = new ArrayList>(); for (int k = 1; k < j; k++) { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); tss.add(ts); obs.subscribe(ts); } diff --git a/src/test/java/io/reactivex/internal/operators/OperatorReduceTest.java b/src/test/java/io/reactivex/internal/operators/OperatorReduceTest.java index 52efec118b..93e28b0d09 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorReduceTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorReduceTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -17,13 +17,12 @@ import static org.mockito.Matchers.any; import static org.mockito.Mockito.*; -import java.util.function.*; - import org.junit.*; import org.reactivestreams.Subscriber; import io.reactivex.*; import io.reactivex.exceptions.TestException; +import io.reactivex.functions.*; public class OperatorReduceTest { Subscriber observer; @@ -44,7 +43,12 @@ public Integer apply(Integer t1, Integer t2) { public void testAggregateAsIntSum() { Observable result = Observable.just(1, 2, 3, 4, 5).reduce(0, sum) - .map(v -> v); + .map(new Function() { + @Override + public Integer apply(Integer v) { + return v; + } + }); result.subscribe(observer); @@ -57,7 +61,12 @@ public void testAggregateAsIntSum() { public void testAggregateAsIntSumSourceThrows() { Observable result = Observable.concat(Observable.just(1, 2, 3, 4, 5), Observable. error(new TestException())) - .reduce(0, sum).map(v -> v); + .reduce(0, sum).map(new Function() { + @Override + public Integer apply(Integer v) { + return v; + } + }); result.subscribe(observer); @@ -76,7 +85,12 @@ public Integer apply(Integer t1, Integer t2) { }; Observable result = Observable.just(1, 2, 3, 4, 5) - .reduce(0, sumErr).map(v -> v); + .reduce(0, sumErr).map(new Function() { + @Override + public Integer apply(Integer v) { + return v; + } + }); result.subscribe(observer); diff --git a/src/test/java/io/reactivex/internal/operators/OperatorRepeatTest.java b/src/test/java/io/reactivex/internal/operators/OperatorRepeatTest.java index bff14db296..64f306e148 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorRepeatTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorRepeatTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -20,7 +20,6 @@ import java.util.*; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.Function; import org.junit.Test; import org.reactivestreams.*; @@ -28,6 +27,7 @@ import io.reactivex.Observable; import io.reactivex.TestHelper; import io.reactivex.exceptions.TestException; +import io.reactivex.functions.Function; import io.reactivex.internal.subscriptions.EmptySubscription; import io.reactivex.schedulers.Schedulers; import io.reactivex.subscribers.TestSubscriber; @@ -161,7 +161,7 @@ public void testRepeatAndDistinctUnbounded() { .repeat(3) .distinct(); - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); src.subscribe(ts); @@ -173,8 +173,8 @@ public void testRepeatAndDistinctUnbounded() { /** Issue #2844: wrong target of request. */ @Test(timeout = 3000) public void testRepeatRetarget() { - final List concatBase = new ArrayList<>(); - TestSubscriber ts = new TestSubscriber<>(); + final List concatBase = new ArrayList(); + TestSubscriber ts = new TestSubscriber(); Observable.just(1, 2) .repeat(5) .concatMap(new Function>() { diff --git a/src/test/java/io/reactivex/internal/operators/OperatorReplayTest.java b/src/test/java/io/reactivex/internal/operators/OperatorReplayTest.java index 7ec556ded0..af3796b781 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorReplayTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorReplayTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -20,17 +20,17 @@ import java.util.*; import java.util.concurrent.*; import java.util.concurrent.atomic.*; -import java.util.function.*; import org.junit.*; import org.mockito.InOrder; import org.reactivestreams.*; -import io.reactivex.*; import io.reactivex.Observable; +import io.reactivex.*; import io.reactivex.Scheduler.Worker; import io.reactivex.disposables.Disposable; import io.reactivex.exceptions.TestException; +import io.reactivex.functions.*; import io.reactivex.internal.operators.OperatorReplay.*; import io.reactivex.internal.subscriptions.EmptySubscription; import io.reactivex.observables.ConnectableObservable; @@ -532,8 +532,8 @@ public void testIssue2191_UnsubscribeSource() { replay.subscribe(spiedSubscriberAfterConnect); replay.subscribe(spiedSubscriberAfterConnect); - verify(spiedSubscriberBeforeConnect, times(2)).onSubscribe(any()); - verify(spiedSubscriberAfterConnect, times(2)).onSubscribe(any()); + verify(spiedSubscriberBeforeConnect, times(2)).onSubscribe((Subscription)any()); + verify(spiedSubscriberAfterConnect, times(2)).onSubscribe((Subscription)any()); // verify interactions verify(sourceNext, times(1)).accept(1); @@ -585,8 +585,8 @@ public void testIssue2191_SchedulerUnsubscribe() throws Exception { replay.subscribe(mockObserverAfterConnect); replay.subscribe(mockObserverAfterConnect); - verify(mockObserverBeforeConnect, times(2)).onSubscribe(any()); - verify(mockObserverAfterConnect, times(2)).onSubscribe(any()); + verify(mockObserverBeforeConnect, times(2)).onSubscribe((Subscription)any()); + verify(mockObserverAfterConnect, times(2)).onSubscribe((Subscription)any()); // verify interactions verify(sourceNext, times(1)).accept(1); @@ -653,8 +653,8 @@ public void testIssue2191_SchedulerUnsubscribeOnError() throws Exception { replay.subscribe(mockObserverAfterConnect); replay.subscribe(mockObserverAfterConnect); - verify(mockObserverBeforeConnect, times(2)).onSubscribe(any()); - verify(mockObserverAfterConnect, times(2)).onSubscribe(any()); + verify(mockObserverBeforeConnect, times(2)).onSubscribe((Subscription)any()); + verify(mockObserverAfterConnect, times(2)).onSubscribe((Subscription)any()); // verify interactions verify(mockScheduler, times(1)).createWorker(); @@ -732,14 +732,14 @@ public void dispose() { @Test public void testBoundedReplayBuffer() { - BoundedReplayBuffer buf = new BoundedReplayBuffer<>(); - buf.addLast(new Node(1)); - buf.addLast(new Node(2)); - buf.addLast(new Node(3)); - buf.addLast(new Node(4)); - buf.addLast(new Node(5)); - - List values = new ArrayList<>(); + BoundedReplayBuffer buf = new BoundedReplayBuffer(); + buf.addLast(new Node(1, 0)); + buf.addLast(new Node(2, 1)); + buf.addLast(new Node(3, 2)); + buf.addLast(new Node(4, 3)); + buf.addLast(new Node(5, 4)); + + List values = new ArrayList(); buf.collect(values); Assert.assertEquals(Arrays.asList(1, 2, 3, 4, 5), values); @@ -752,8 +752,8 @@ public void testBoundedReplayBuffer() { buf.collect(values); Assert.assertTrue(values.isEmpty()); - buf.addLast(new Node(5)); - buf.addLast(new Node(6)); + buf.addLast(new Node(5, 5)); + buf.addLast(new Node(6, 6)); buf.collect(values); Assert.assertEquals(Arrays.asList(5, 6), values); @@ -763,8 +763,8 @@ public void testBoundedReplayBuffer() { @Test public void testTimedAndSizedTruncation() { TestScheduler test = Schedulers.test(); - SizeAndTimeBoundReplayBuffer buf = new SizeAndTimeBoundReplayBuffer<>(2, 2000, TimeUnit.MILLISECONDS, test); - List values = new ArrayList<>(); + SizeAndTimeBoundReplayBuffer buf = new SizeAndTimeBoundReplayBuffer(2, 2000, TimeUnit.MILLISECONDS, test); + List values = new ArrayList(); buf.next(1); test.advanceTimeBy(1, TimeUnit.SECONDS); @@ -809,8 +809,8 @@ public void accept(long t) { }); ConnectableObservable co = source.replay(); - TestSubscriber ts1 = new TestSubscriber<>(10L); - TestSubscriber ts2 = new TestSubscriber<>(90L); + TestSubscriber ts1 = new TestSubscriber(10L); + TestSubscriber ts2 = new TestSubscriber(90L); co.subscribe(ts1); co.subscribe(ts2); @@ -840,8 +840,8 @@ public void accept(long t) { }); ConnectableObservable co = source.replay(50); - TestSubscriber ts1 = new TestSubscriber<>(10L); - TestSubscriber ts2 = new TestSubscriber<>(90L); + TestSubscriber ts1 = new TestSubscriber(10L); + TestSubscriber ts2 = new TestSubscriber(90L); co.subscribe(ts1); co.subscribe(ts2); @@ -863,7 +863,7 @@ public void accept(long t) { public void testColdReplayNoBackpressure() { Observable source = Observable.range(0, 1000).replay().autoConnect(); - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); source.subscribe(ts); @@ -880,7 +880,7 @@ public void testColdReplayNoBackpressure() { public void testColdReplayBackpressure() { Observable source = Observable.range(0, 1000).replay().autoConnect(); - TestSubscriber ts = new TestSubscriber<>((Long)null); + TestSubscriber ts = new TestSubscriber((Long)null); ts.request(10); source.subscribe(ts); @@ -961,7 +961,7 @@ public void testUnsubscribeSource() { @Test public void testTake() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); Observable cached = Observable.range(1, 100).replay().autoConnect(); cached.take(10).subscribe(ts); @@ -977,7 +977,7 @@ public void testTake() { public void testAsync() { Observable source = Observable.range(1, 10000); for (int i = 0; i < 100; i++) { - TestSubscriber ts1 = new TestSubscriber<>(); + TestSubscriber ts1 = new TestSubscriber(); Observable cached = source.replay().autoConnect(); @@ -988,7 +988,7 @@ public void testAsync() { ts1.assertTerminated(); assertEquals(10000, ts1.values().size()); - TestSubscriber ts2 = new TestSubscriber<>(); + TestSubscriber ts2 = new TestSubscriber(); cached.observeOn(Schedulers.computation()).subscribe(ts2); ts2.awaitTerminalEvent(2, TimeUnit.SECONDS); @@ -1006,14 +1006,14 @@ public void testAsyncComeAndGo() { Observable output = cached.observeOn(Schedulers.computation()); - List> list = new ArrayList<>(100); + List> list = new ArrayList>(100); for (int i = 0; i < 100; i++) { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); list.add(ts); output.skip(i * 10).take(10).subscribe(ts); } - List expected = new ArrayList<>(); + List expected = new ArrayList(); for (int i = 0; i < 10; i++) { expected.add((long)(i - 10)); } @@ -1047,7 +1047,7 @@ public void subscribe(Subscriber t) { } }); - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); firehose.replay().autoConnect().observeOn(Schedulers.computation()).takeLast(100).subscribe(ts); ts.awaitTerminalEvent(3, TimeUnit.SECONDS); @@ -1064,14 +1064,14 @@ public void testValuesAndThenError() { .replay().autoConnect(); - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); source.subscribe(ts); ts.assertValues(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); ts.assertNotComplete(); Assert.assertEquals(1, ts.errors().size()); - TestSubscriber ts2 = new TestSubscriber<>(); + TestSubscriber ts2 = new TestSubscriber(); source.subscribe(ts2); ts2.assertValues(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); @@ -1112,7 +1112,7 @@ public void onNext(Integer t) { public void unboundedLeavesEarly() { PublishSubject source = PublishSubject.create(); - final List requests = new ArrayList<>(); + final List requests = new ArrayList(); Observable out = source .doOnRequest(new LongConsumer() { @@ -1122,8 +1122,8 @@ public void accept(long t) { } }).replay().autoConnect(); - TestSubscriber ts1 = new TestSubscriber<>(5L); - TestSubscriber ts2 = new TestSubscriber<>(10L); + TestSubscriber ts1 = new TestSubscriber(5L); + TestSubscriber ts2 = new TestSubscriber(10L); out.subscribe(ts1); out.subscribe(ts2); @@ -1131,5 +1131,109 @@ public void accept(long t) { Assert.assertEquals(Arrays.asList(5L, 5L), requests); } + + @Test + public void testSubscribersComeAndGoAtRequestBoundaries() { + ConnectableObservable source = Observable.range(1, 10).replay(1); + source.connect(); + + TestSubscriber ts1 = new TestSubscriber(2L); + + source.subscribe(ts1); + + ts1.assertValues(1, 2); + ts1.assertNoErrors(); + ts1.dispose(); + + TestSubscriber ts2 = new TestSubscriber(2L); + + source.subscribe(ts2); + + ts2.assertValues(2, 3); + ts2.assertNoErrors(); + ts2.dispose(); + + TestSubscriber ts21 = new TestSubscriber(1L); + + source.subscribe(ts21); + + ts21.assertValues(3); + ts21.assertNoErrors(); + ts21.dispose(); + + TestSubscriber ts22 = new TestSubscriber(1L); + + source.subscribe(ts22); + + ts22.assertValues(3); + ts22.assertNoErrors(); + ts22.dispose(); + + + TestSubscriber ts3 = new TestSubscriber(); + + source.subscribe(ts3); + + ts3.assertNoErrors(); + System.out.println(ts3.values()); + ts3.assertValues(3, 4, 5, 6, 7, 8, 9, 10); + ts3.assertComplete(); + } + @Test + public void testSubscribersComeAndGoAtRequestBoundaries2() { + ConnectableObservable source = Observable.range(1, 10).replay(2); + source.connect(); + + TestSubscriber ts1 = new TestSubscriber(2L); + + source.subscribe(ts1); + + ts1.assertValues(1, 2); + ts1.assertNoErrors(); + ts1.dispose(); + + TestSubscriber ts11 = new TestSubscriber(2L); + + source.subscribe(ts11); + + ts11.assertValues(1, 2); + ts11.assertNoErrors(); + ts11.dispose(); + + TestSubscriber ts2 = new TestSubscriber(3L); + + source.subscribe(ts2); + + ts2.assertValues(1, 2, 3); + ts2.assertNoErrors(); + ts2.dispose(); + + TestSubscriber ts21 = new TestSubscriber(1L); + + source.subscribe(ts21); + + ts21.assertValues(2); + ts21.assertNoErrors(); + ts21.dispose(); + + TestSubscriber ts22 = new TestSubscriber(1L); + + source.subscribe(ts22); + + ts22.assertValues(2); + ts22.assertNoErrors(); + ts22.dispose(); + + + TestSubscriber ts3 = new TestSubscriber(); + + source.subscribe(ts3); + + ts3.assertNoErrors(); + System.out.println(ts3.values()); + ts3.assertValues(2, 3, 4, 5, 6, 7, 8, 9, 10); + ts3.assertComplete(); + } + } \ No newline at end of file diff --git a/src/test/java/io/reactivex/internal/operators/OperatorRetryTest.java b/src/test/java/io/reactivex/internal/operators/OperatorRetryTest.java index d9cdb9bdb0..d84833be7d 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorRetryTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorRetryTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -14,13 +14,12 @@ package io.reactivex.internal.operators; import static org.junit.Assert.*; -import static org.mockito.Matchers.any; +import static org.mockito.Matchers.*; import static org.mockito.Mockito.*; import java.util.*; import java.util.concurrent.*; import java.util.concurrent.atomic.*; -import java.util.function.*; import org.junit.Test; import org.mockito.*; @@ -28,8 +27,9 @@ import io.reactivex.Observable; import io.reactivex.Observer; -import io.reactivex.TestHelper; +import io.reactivex.*; import io.reactivex.disposables.Disposable; +import io.reactivex.functions.*; import io.reactivex.internal.subscriptions.*; import io.reactivex.observables.GroupedObservable; import io.reactivex.schedulers.Schedulers; @@ -61,11 +61,11 @@ public void subscribe(Subscriber t1) { } }); - TestSubscriber ts = new TestSubscriber<>(consumer); - producer.retryWhen(new Function, Observable>() { + TestSubscriber ts = new TestSubscriber(consumer); + producer.retryWhen(new Function, Observable>() { @Override - public Observable apply(Observable attempts) { + public Observable apply(Observable attempts) { // Worker w = Schedulers.computation().createWorker(); return attempts .map(new Function() { @@ -78,13 +78,14 @@ public Tuple apply(Throwable n) { public Tuple apply(Tuple t, Tuple n) { return new Tuple(t.count + n.count, n.n); }}) - .flatMap(new Function>() { + .flatMap(new Function>() { @Override - public Observable apply(Tuple t) { + public Observable apply(Tuple t) { System.out.println("Retry # "+t.count); return t.count > 20 ? - Observable.error(t.n) : - Observable.timer(t.count *1L, TimeUnit.MILLISECONDS); + Observable.error(t.n) : + Observable.timer(t.count *1L, TimeUnit.MILLISECONDS) + .cast(Object.class); }}); } }).subscribe(ts); @@ -114,7 +115,7 @@ public void testRetryIndefinitely() { Subscriber observer = TestHelper.mockSubscriber(); int NUM_RETRIES = 20; Observable origin = Observable.create(new FuncWithErrors(NUM_RETRIES)); - origin.retry().unsafeSubscribe(new TestSubscriber<>(observer)); + origin.retry().unsafeSubscribe(new TestSubscriber(observer)); InOrder inOrder = inOrder(observer); // should show 3 attempts @@ -133,19 +134,24 @@ public void testSchedulingNotificationHandler() { Subscriber observer = TestHelper.mockSubscriber(); int NUM_RETRIES = 2; Observable origin = Observable.create(new FuncWithErrors(NUM_RETRIES)); - TestSubscriber subscriber = new TestSubscriber<>(observer); - origin.retryWhen(new Function, Observable>() { + TestSubscriber subscriber = new TestSubscriber(observer); + origin.retryWhen(new Function, Observable>() { @Override - public Observable apply(Observable t1) { + public Observable apply(Observable t1) { return t1.observeOn(Schedulers.computation()).map(new Function() { @Override public Integer apply(Throwable t1) { return 1; } - }).startWith(1); + }).startWith(1).cast(Object.class); + } + }) + .doOnError(new Consumer() { + @Override + public void accept(Throwable e) { + e.printStackTrace(); } }) - .doOnError(Throwable::printStackTrace) .subscribe(subscriber); subscriber.awaitTerminalEvent(); @@ -166,16 +172,16 @@ public void testOnNextFromNotificationHandler() { Subscriber observer = TestHelper.mockSubscriber(); int NUM_RETRIES = 2; Observable origin = Observable.create(new FuncWithErrors(NUM_RETRIES)); - origin.retryWhen(new Function, Observable>() { + origin.retryWhen(new Function, Observable>() { @Override - public Observable apply(Observable t1) { + public Observable apply(Observable t1) { return t1.map(new Function() { @Override public Integer apply(Throwable t1) { return 0; } - }).startWith(0); + }).startWith(0).cast(Object.class); } }).subscribe(observer); @@ -195,10 +201,10 @@ public Integer apply(Throwable t1) { public void testOnCompletedFromNotificationHandler() { Subscriber observer = TestHelper.mockSubscriber(); Observable origin = Observable.create(new FuncWithErrors(1)); - TestSubscriber subscriber = new TestSubscriber<>(observer); - origin.retryWhen(new Function, Observable>() { + TestSubscriber subscriber = new TestSubscriber(observer); + origin.retryWhen(new Function, Observable>() { @Override - public Observable apply(Observable t1) { + public Observable apply(Observable t1) { return Observable.empty(); } }).subscribe(subscriber); @@ -216,9 +222,9 @@ public Observable apply(Observable t1) { public void testOnErrorFromNotificationHandler() { Subscriber observer = TestHelper.mockSubscriber(); Observable origin = Observable.create(new FuncWithErrors(2)); - origin.retryWhen(new Function, Observable>() { + origin.retryWhen(new Function, Observable>() { @Override - public Observable apply(Observable t1) { + public Observable apply(Observable t1) { return Observable.error(new RuntimeException()); } }).subscribe(observer); @@ -246,13 +252,13 @@ public void subscribe(Subscriber subscriber) { }; int first = Observable.create(onSubscribe) - .retryWhen(new Function, Observable>() { + .retryWhen(new Function, Observable>() { @Override - public Observable apply(Observable attempt) { - return attempt.zipWith(Observable.just(1), new BiFunction() { + public Observable apply(Observable attempt) { + return attempt.zipWith(Observable.just(1), new BiFunction() { @Override - public Void apply(Throwable o, Integer integer) { - return null; + public Object apply(Throwable o, Integer integer) { + return 0; } }); } @@ -490,7 +496,7 @@ public void cancel() { public void testSourceObservableCallsUnsubscribe() throws InterruptedException { final AtomicInteger subsCount = new AtomicInteger(0); - final TestSubscriber ts = new TestSubscriber<>(); + final TestSubscriber ts = new TestSubscriber(); Publisher onSubscribe = new Publisher() { @Override @@ -521,7 +527,7 @@ public void subscribe(Subscriber s) { public void testSourceObservableRetry1() throws InterruptedException { final AtomicInteger subsCount = new AtomicInteger(0); - final TestSubscriber ts = new TestSubscriber<>(); + final TestSubscriber ts = new TestSubscriber(); Publisher onSubscribe = new Publisher() { @Override @@ -540,7 +546,7 @@ public void subscribe(Subscriber s) { public void testSourceObservableRetry0() throws InterruptedException { final AtomicInteger subsCount = new AtomicInteger(0); - final TestSubscriber ts = new TestSubscriber<>(); + final TestSubscriber ts = new TestSubscriber(); Publisher onSubscribe = new Publisher() { @Override @@ -615,7 +621,10 @@ static final class AsyncObserver extends Observer { protected Subscriber target; - /** Wrap existing Observer */ + /** + * Wrap existing Observer + * @param target the target subscriber + */ public AsyncObserver(Subscriber target) { this.target = target; } @@ -659,7 +668,7 @@ public void testUnsubscribeAfterError() { SlowObservable so = new SlowObservable(100, 0); Observable o = Observable.create(so).retry(5); - AsyncObserver async = new AsyncObserver<>(observer); + AsyncObserver async = new AsyncObserver(observer); o.subscribe(async); @@ -684,7 +693,7 @@ public void testTimeoutWithRetry() { SlowObservable so = new SlowObservable(100, 10); Observable o = Observable.create(so).timeout(80, TimeUnit.MILLISECONDS).retry(5); - AsyncObserver async = new AsyncObserver<>(observer); + AsyncObserver async = new AsyncObserver(observer); o.subscribe(async); @@ -706,7 +715,7 @@ public void testRetryWithBackpressure() throws InterruptedException { for (int i = 0; i < 400; i++) { Subscriber observer = TestHelper.mockSubscriber(); Observable origin = Observable.create(new FuncWithErrors(NUM_RETRIES)); - TestSubscriber ts = new TestSubscriber<>(observer); + TestSubscriber ts = new TestSubscriber(observer); origin.retry().observeOn(Schedulers.computation()).unsafeSubscribe(ts); ts.awaitTerminalEvent(5, TimeUnit.SECONDS); @@ -737,7 +746,7 @@ public void testRetryWithBackpressureParallel() throws InterruptedException { } final AtomicInteger timeouts = new AtomicInteger(); - final Map> data = new ConcurrentHashMap<>(); + final Map> data = new ConcurrentHashMap>(); int m = 5000; final CountDownLatch cdl = new CountDownLatch(m); @@ -749,11 +758,11 @@ public void run() { final AtomicInteger nexts = new AtomicInteger(); try { Observable origin = Observable.create(new FuncWithErrors(NUM_RETRIES)); - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); origin.retry() .observeOn(Schedulers.computation()).unsafeSubscribe(ts); ts.awaitTerminalEvent(2500, TimeUnit.MILLISECONDS); - List onNextEvents = new ArrayList<>(ts.values()); + List onNextEvents = new ArrayList(ts.values()); if (onNextEvents.size() != NUM_RETRIES + 2) { for (Throwable t : ts.errors()) { onNextEvents.add(t.toString()); @@ -850,7 +859,7 @@ public Observable apply(GroupedObservable t1) { return t1.take(1); } }) - .unsafeSubscribe(new TestSubscriber<>(observer)); + .unsafeSubscribe(new TestSubscriber(observer)); InOrder inOrder = inOrder(observer); // should show 3 attempts @@ -894,7 +903,7 @@ public Observable apply(GroupedObservable t1) { return t1.take(1); } }) - .unsafeSubscribe(new TestSubscriber<>(observer)); + .unsafeSubscribe(new TestSubscriber(observer)); InOrder inOrder = inOrder(observer); // should show 3 attempts diff --git a/src/test/java/io/reactivex/internal/operators/OperatorRetryWithPredicateTest.java b/src/test/java/io/reactivex/internal/operators/OperatorRetryWithPredicateTest.java index b7c2b9d49b..9161d388fb 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorRetryWithPredicateTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorRetryWithPredicateTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -21,20 +21,20 @@ import java.util.*; import java.util.concurrent.*; import java.util.concurrent.atomic.*; -import java.util.function.*; import org.junit.Test; import org.mockito.InOrder; import org.reactivestreams.*; -import io.reactivex.Observable; -import io.reactivex.Observer; -import io.reactivex.TestHelper; +import io.reactivex.*; import io.reactivex.disposables.Disposable; import io.reactivex.exceptions.TestException; +import io.reactivex.functions.*; import io.reactivex.internal.subscriptions.EmptySubscription; import io.reactivex.subjects.PublishSubject; import io.reactivex.subscribers.TestSubscriber; +import io.reactivex.Observable; +import io.reactivex.Observer; public class OperatorRetryWithPredicateTest { BiPredicate retryTwice = new BiPredicate() { @@ -235,7 +235,7 @@ public void testUnsubscribeAfterError() { .create(so) .retry(retry5); - OperatorRetryTest.AsyncObserver async = new OperatorRetryTest.AsyncObserver<>(observer); + OperatorRetryTest.AsyncObserver async = new OperatorRetryTest.AsyncObserver(observer); o.subscribe(async); @@ -262,7 +262,7 @@ public void testTimeoutWithRetry() { .timeout(80, TimeUnit.MILLISECONDS) .retry(retry5); - OperatorRetryTest.AsyncObserver async = new OperatorRetryTest.AsyncObserver<>(observer); + OperatorRetryTest.AsyncObserver async = new OperatorRetryTest.AsyncObserver(observer); o.subscribe(async); @@ -278,7 +278,7 @@ public void testTimeoutWithRetry() { @Test public void testIssue2826() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); final RuntimeException e = new RuntimeException("You shall not pass"); final AtomicInteger c = new AtomicInteger(); Observable.just(1).map(new Function() { @@ -311,7 +311,7 @@ public Integer apply(Integer t1) { @Test public void testIssue3008RetryWithPredicate() { - final List list = new CopyOnWriteArrayList<>(); + final List list = new CopyOnWriteArrayList(); final AtomicBoolean isFirst = new AtomicBoolean(true); Observable. just(1L, 2L, 3L).map(new Function(){ @Override @@ -339,7 +339,7 @@ public void accept(Long t) { @Test public void testIssue3008RetryInfinite() { - final List list = new CopyOnWriteArrayList<>(); + final List list = new CopyOnWriteArrayList(); final AtomicBoolean isFirst = new AtomicBoolean(true); Observable. just(1L, 2L, 3L).map(new Function(){ @Override @@ -363,7 +363,7 @@ public void accept(Long t) { @Test public void testBackpressure() { - final List requests = new ArrayList<>(); + final List requests = new ArrayList(); Observable source = Observable .just(1) @@ -375,7 +375,7 @@ public void accept(long t) { } }); - TestSubscriber ts = new TestSubscriber<>(3L); + TestSubscriber ts = new TestSubscriber(3L); source .retry(new BiPredicate() { @Override diff --git a/src/test/java/io/reactivex/internal/operators/OperatorSampleTest.java b/src/test/java/io/reactivex/internal/operators/OperatorSampleTest.java index 67be8508d6..2e886d07c3 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorSampleTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorSampleTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 diff --git a/src/test/java/io/reactivex/internal/operators/OperatorScanTest.java b/src/test/java/io/reactivex/internal/operators/OperatorScanTest.java index 76305a7cc8..e38f3162c7 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorScanTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorScanTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,22 +13,22 @@ package io.reactivex.internal.operators; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; import static org.mockito.Matchers.*; import static org.mockito.Mockito.*; import java.util.*; import java.util.concurrent.atomic.*; -import java.util.function.*; -import org.junit.Test; +import org.junit.*; import org.reactivestreams.*; -import io.reactivex.Observable; -import io.reactivex.Observer; -import io.reactivex.TestHelper; +import io.reactivex.*; +import io.reactivex.functions.*; import io.reactivex.subjects.PublishSubject; import io.reactivex.subscribers.TestSubscriber; +import io.reactivex.Observable; +import io.reactivex.Observer; public class OperatorScanTest { @@ -110,7 +110,7 @@ public Integer apply(Integer t1, Integer t2) { @Test public void shouldNotEmitUntilAfterSubscription() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); Observable.range(1, 100).scan(0, new BiFunction() { @Override @@ -157,7 +157,7 @@ public void onComplete() { @Override public void onError(Throwable e) { - fail(e.getMessage()); + Assert.fail(e.getMessage()); e.printStackTrace(); } @@ -198,7 +198,7 @@ public void onComplete() { @Override public void onError(Throwable e) { - fail(e.getMessage()); + Assert.fail(e.getMessage()); e.printStackTrace(); } @@ -234,7 +234,7 @@ public void onComplete() { @Override public void onError(Throwable e) { - fail(e.getMessage()); + Assert.fail(e.getMessage()); e.printStackTrace(); } @@ -259,7 +259,7 @@ public void testSeedFactory() { @Override public List get() { - return new ArrayList<>(); + return new ArrayList(); } }, new BiConsumer, Integer>() { @@ -285,7 +285,7 @@ public Integer apply(Integer t1, Integer t2) { } }).take(1); - TestSubscriber subscriber = new TestSubscriber<>(); + TestSubscriber subscriber = new TestSubscriber(); o.subscribe(subscriber); subscriber.assertValue(0); subscriber.assertTerminated(); @@ -294,7 +294,7 @@ public Integer apply(Integer t1, Integer t2) { @Test public void testScanShouldNotRequestZero() { - final AtomicReference producer = new AtomicReference<>(); + final AtomicReference producer = new AtomicReference(); Observable o = Observable.create(new Publisher() { @Override public void subscribe(final Subscriber subscriber) { @@ -343,7 +343,7 @@ public void onNext(Integer integer) { public void testInitialValueEmittedNoProducer() { PublishSubject source = PublishSubject.create(); - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); source.scan(0, new BiFunction() { @Override @@ -361,7 +361,7 @@ public Integer apply(Integer t1, Integer t2) { public void testInitialValueEmittedWithProducer() { Observable source = Observable.never(); - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); source.scan(0, new BiFunction() { @Override diff --git a/src/test/java/io/reactivex/internal/operators/OperatorSequenceEqualTest.java b/src/test/java/io/reactivex/internal/operators/OperatorSequenceEqualTest.java index 431561504b..6ff76ae95e 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorSequenceEqualTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorSequenceEqualTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -16,14 +16,13 @@ import static org.mockito.Matchers.isA; import static org.mockito.Mockito.*; -import java.util.function.BiPredicate; - import org.junit.*; import org.mockito.InOrder; import org.reactivestreams.Subscriber; import io.reactivex.*; import io.reactivex.exceptions.TestException; +import io.reactivex.functions.BiPredicate; public class OperatorSequenceEqualTest { diff --git a/src/test/java/io/reactivex/internal/operators/OperatorSerializeTest.java b/src/test/java/io/reactivex/internal/operators/OperatorSerializeTest.java index 38930cc4c3..7a0eacd934 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorSerializeTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorSerializeTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 diff --git a/src/test/java/io/reactivex/internal/operators/OperatorSingleTest.java b/src/test/java/io/reactivex/internal/operators/OperatorSingleTest.java index 0d54ae5a1b..b2f0178d81 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorSingleTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorSingleTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -19,15 +19,15 @@ import java.util.*; import java.util.concurrent.atomic.AtomicLong; -import java.util.function.*; import org.junit.Test; import org.mockito.InOrder; import org.reactivestreams.Subscriber; +import io.reactivex.*; +import io.reactivex.functions.*; import io.reactivex.Observable; import io.reactivex.Observer; -import io.reactivex.TestHelper; public class OperatorSingleTest { @@ -117,7 +117,7 @@ public void accept(long n) { @Test public void testSingleDoesNotRequestMoreThanItNeedsIf1Then2Requested() { - final List requests = new ArrayList<>(); + final List requests = new ArrayList(); Observable.just(1) // .doOnRequest(new LongConsumer() { @@ -157,7 +157,7 @@ public void onNext(Integer t) { @Test public void testSingleDoesNotRequestMoreThanItNeedsIf3Requested() { - final List requests = new ArrayList<>(); + final List requests = new ArrayList(); Observable.just(1) // .doOnRequest(new LongConsumer() { @@ -196,7 +196,7 @@ public void onNext(Integer t) { @Test public void testSingleRequestsExactlyWhatItNeedsIf1Requested() { - final List requests = new ArrayList<>(); + final List requests = new ArrayList(); Observable.just(1) // .doOnRequest(new LongConsumer() { @@ -342,7 +342,12 @@ public void testSingleOrDefaultWithEmpty() { @Test public void testSingleOrDefaultWithPredicate() { Observable observable = Observable.just(1, 2) - .filter(t1 -> t1 % 2 == 0) + .filter(new Predicate() { + @Override + public boolean test(Integer t1) { + return t1 % 2 == 0; + } + }) .single(4); Subscriber observer = TestHelper.mockSubscriber(); @@ -357,7 +362,12 @@ public void testSingleOrDefaultWithPredicate() { @Test public void testSingleOrDefaultWithPredicateAndTooManyElements() { Observable observable = Observable.just(1, 2, 3, 4) - .filter(t1 -> t1 % 2 == 0) + .filter(new Predicate() { + @Override + public boolean test(Integer t1) { + return t1 % 2 == 0; + } + }) .single(6); Subscriber observer = TestHelper.mockSubscriber(); @@ -372,7 +382,12 @@ public void testSingleOrDefaultWithPredicateAndTooManyElements() { @Test public void testSingleOrDefaultWithPredicateAndEmpty() { Observable observable = Observable.just(1) - .filter(t1 -> t1 % 2 == 0) + .filter(new Predicate() { + @Override + public boolean test(Integer t1) { + return t1 % 2 == 0; + } + }) .single(2); Subscriber observer = TestHelper.mockSubscriber(); @@ -421,7 +436,12 @@ public void onNext(Integer integer) { public void testIssue1527() throws InterruptedException { //https://github.com/ReactiveX/RxJava/pull/1527 Observable source = Observable.just(1, 2, 3, 4, 5, 6); - Observable reduced = source.reduce((i1, i2) -> i1 + i2); + Observable reduced = source.reduce(new BiFunction() { + @Override + public Integer apply(Integer i1, Integer i2) { + return i1 + i2; + } + }); Integer r = reduced.toBlocking().first(); assertEquals(21, r.intValue()); diff --git a/src/test/java/io/reactivex/internal/operators/OperatorSkipLastTest.java b/src/test/java/io/reactivex/internal/operators/OperatorSkipLastTest.java index f5c22e6517..fe88d86257 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorSkipLastTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorSkipLastTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -95,7 +95,7 @@ public void testSkipLastWithNull() { @Test public void testSkipLastWithBackpressure() { Observable o = Observable.range(0, Observable.bufferSize() * 2).skipLast(Observable.bufferSize() + 10); - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); o.observeOn(Schedulers.computation()).subscribe(ts); ts.awaitTerminalEvent(); ts.assertNoErrors(); diff --git a/src/test/java/io/reactivex/internal/operators/OperatorSkipLastTimedTest.java b/src/test/java/io/reactivex/internal/operators/OperatorSkipLastTimedTest.java index ba53ece362..a65f4c15a1 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorSkipLastTimedTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorSkipLastTimedTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 diff --git a/src/test/java/io/reactivex/internal/operators/OperatorSkipTest.java b/src/test/java/io/reactivex/internal/operators/OperatorSkipTest.java index 0a565c1ed0..629be744d7 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorSkipTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorSkipTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -20,12 +20,13 @@ import java.util.Arrays; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicLong; -import java.util.function.LongConsumer; import org.junit.Test; import org.reactivestreams.Subscriber; import io.reactivex.*; +import io.reactivex.functions.LongConsumer; +import io.reactivex.internal.operators.OperatorSkip; import io.reactivex.subscribers.TestSubscriber; public class OperatorSkipTest { @@ -142,7 +143,7 @@ public void testSkipError() { @Test public void testBackpressureMultipleSmallAsyncRequests() throws InterruptedException { final AtomicLong requests = new AtomicLong(0); - TestSubscriber ts = new TestSubscriber<>((Long)null); + TestSubscriber ts = new TestSubscriber((Long)null); Observable.interval(100, TimeUnit.MILLISECONDS) .doOnRequest(new LongConsumer() { @Override @@ -163,7 +164,7 @@ public void accept(long n) { @Test public void testRequestOverflowDoesNotOccur() { - TestSubscriber ts = new TestSubscriber<>(Long.MAX_VALUE-1); + TestSubscriber ts = new TestSubscriber(Long.MAX_VALUE-1); Observable.range(1, 10).skip(5).subscribe(ts); ts.assertTerminated(); ts.assertComplete(); diff --git a/src/test/java/io/reactivex/internal/operators/OperatorSkipTimedTest.java b/src/test/java/io/reactivex/internal/operators/OperatorSkipTimedTest.java index 64e55f4a89..3904afb81f 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorSkipTimedTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorSkipTimedTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 diff --git a/src/test/java/io/reactivex/internal/operators/OperatorSkipUntilTest.java b/src/test/java/io/reactivex/internal/operators/OperatorSkipUntilTest.java index cb978073e8..56a09e97a4 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorSkipUntilTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorSkipUntilTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 diff --git a/src/test/java/io/reactivex/internal/operators/OperatorSkipWhileTest.java b/src/test/java/io/reactivex/internal/operators/OperatorSkipWhileTest.java index c1db8537fc..355ff08231 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorSkipWhileTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorSkipWhileTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -16,13 +16,12 @@ import static org.mockito.Matchers.*; import static org.mockito.Mockito.*; -import java.util.function.Predicate; - import org.junit.Test; import org.mockito.InOrder; import org.reactivestreams.Subscriber; import io.reactivex.*; +import io.reactivex.functions.Predicate; public class OperatorSkipWhileTest { diff --git a/src/test/java/io/reactivex/internal/operators/OperatorSubscribeOnTest.java b/src/test/java/io/reactivex/internal/operators/OperatorSubscribeOnTest.java index 0199c8207f..d796b4a52a 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorSubscribeOnTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorSubscribeOnTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -37,7 +37,7 @@ public void testIssue813() throws InterruptedException { final CountDownLatch latch = new CountDownLatch(1); final CountDownLatch doneLatch = new CountDownLatch(1); - TestSubscriber observer = new TestSubscriber<>(); + TestSubscriber observer = new TestSubscriber(); Observable .create(new Publisher() { @@ -76,7 +76,7 @@ public void subscribe( @Test @Ignore("Publisher.subscribe can't throw") public void testThrownErrorHandling() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); Observable.create(new Publisher() { @Override @@ -91,7 +91,7 @@ public void subscribe(Subscriber s) { @Test public void testOnError() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); Observable.create(new Publisher() { @Override @@ -162,7 +162,7 @@ public Disposable schedule(final Runnable action, final long delayTime, final Ti @Test(timeout = 5000) public void testUnsubscribeInfiniteStream() throws InterruptedException { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); final AtomicInteger count = new AtomicInteger(); Observable.create(new Publisher() { @@ -188,7 +188,7 @@ public void subscribe(Subscriber sub) { @Test public void testBackpressureReschedulesCorrectly() throws InterruptedException { final CountDownLatch latch = new CountDownLatch(10); - TestSubscriber ts = new TestSubscriber<>(new Observer() { + TestSubscriber ts = new TestSubscriber(new Observer() { @Override public void onComplete() { @@ -218,7 +218,7 @@ public void onNext(Integer t) { @Test public void testSetProducerSynchronousRequest() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); Observable.just(1, 2, 3).lift(new Operator() { @Override diff --git a/src/test/java/io/reactivex/internal/operators/OperatorSwitchIfEmptyTest.java b/src/test/java/io/reactivex/internal/operators/OperatorSwitchIfEmptyTest.java index 758dc24948..906f9c621a 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorSwitchIfEmptyTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorSwitchIfEmptyTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -22,9 +22,9 @@ import org.junit.Test; import org.reactivestreams.*; - import io.reactivex.*; -import io.reactivex.internal.subscriptions.*; +import io.reactivex.functions.Consumer; +import io.reactivex.internal.subscriptions.BooleanSubscription; import io.reactivex.schedulers.Schedulers; import io.reactivex.subscribers.TestSubscriber; @@ -36,7 +36,12 @@ public void testSwitchWhenNotEmpty() throws Exception { final AtomicBoolean subscribed = new AtomicBoolean(false); final Observable observable = Observable.just(4) .switchIfEmpty(Observable.just(2) - .doOnSubscribe(s -> subscribed.set(true))); + .doOnSubscribe(new Consumer() { + @Override + public void accept(Subscription s) { + subscribed.set(true); + } + })); assertEquals(4, observable.toBlocking().single().intValue()); assertFalse(subscribed.get()); @@ -81,7 +86,7 @@ public void cancel() { @Test public void testSwitchTriggerUnsubscribe() throws Exception { - BooleanSubscription bs = new BooleanSubscription(); + final BooleanSubscription bs = new BooleanSubscription(); Observable withProducer = Observable.create(new Publisher() { @Override @@ -124,7 +129,7 @@ public void onNext(Long aLong) { @Test public void testSwitchShouldTriggerUnsubscribe() { - BooleanSubscription bs = new BooleanSubscription(); + final BooleanSubscription bs = new BooleanSubscription(); Observable.create(new Publisher() { @Override @@ -139,7 +144,7 @@ public void subscribe(final Subscriber subscriber) { @Test public void testSwitchRequestAlternativeObservableWithBackpressure() { - TestSubscriber ts = new TestSubscriber<>(1L); + TestSubscriber ts = new TestSubscriber(1L); Observable.empty().switchIfEmpty(Observable.just(1, 2, 3)).subscribe(ts); @@ -152,7 +157,7 @@ public void testSwitchRequestAlternativeObservableWithBackpressure() { } @Test public void testBackpressureNoRequest() { - TestSubscriber ts = new TestSubscriber<>((Long)null); + TestSubscriber ts = new TestSubscriber((Long)null); Observable.empty().switchIfEmpty(Observable.just(1, 2, 3)).subscribe(ts); ts.assertNoValues(); ts.assertNoErrors(); @@ -160,7 +165,7 @@ public void testBackpressureNoRequest() { @Test public void testBackpressureOnFirstObservable() { - TestSubscriber ts = new TestSubscriber<>((Long)null); + TestSubscriber ts = new TestSubscriber((Long)null); Observable.just(1,2,3).switchIfEmpty(Observable.just(4, 5, 6)).subscribe(ts); ts.assertNotComplete(); ts.assertNoErrors(); @@ -169,7 +174,7 @@ public void testBackpressureOnFirstObservable() { @Test(timeout = 10000) public void testRequestsNotLost() throws InterruptedException { - final TestSubscriber ts = new TestSubscriber<>((Long)null); + final TestSubscriber ts = new TestSubscriber((Long)null); Observable.create(new Publisher() { @Override diff --git a/src/test/java/io/reactivex/internal/operators/OperatorSwitchTest.java b/src/test/java/io/reactivex/internal/operators/OperatorSwitchTest.java index 7aab5f369d..e61c191562 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorSwitchTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorSwitchTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -20,20 +20,20 @@ import java.util.*; import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicBoolean; -import java.util.function.Function; import org.junit.*; import org.mockito.InOrder; import org.reactivestreams.*; import io.reactivex.*; -import io.reactivex.Observable; -import io.reactivex.Observer; import io.reactivex.exceptions.TestException; +import io.reactivex.functions.*; import io.reactivex.internal.subscriptions.*; import io.reactivex.schedulers.TestScheduler; import io.reactivex.subjects.PublishSubject; import io.reactivex.subscribers.TestSubscriber; +import io.reactivex.Observable; +import io.reactivex.Observer; public class OperatorSwitchTest { @@ -449,7 +449,7 @@ public void testBackpressure() { publishCompleted(o3, 55); - final TestSubscriber testSubscriber = new TestSubscriber<>(); + final TestSubscriber testSubscriber = new TestSubscriber(); Observable.switchOnNext(o).subscribe(new Observer() { private int requested = 0; @@ -458,6 +458,7 @@ public void testBackpressure() { public void onStart() { requested = 3; request(3); + testSubscriber.onSubscribe(EmptySubscription.INSTANCE); } @Override @@ -547,7 +548,7 @@ public void onNext(String t) { @Test(timeout = 10000) public void testInitialRequestsAreAdditive() { - TestSubscriber ts = new TestSubscriber<>((Long)null); + TestSubscriber ts = new TestSubscriber((Long)null); Observable.switchOnNext( Observable.interval(100, TimeUnit.MILLISECONDS) .map( @@ -566,7 +567,7 @@ public Observable apply(Long t) { @Test(timeout = 10000) public void testInitialRequestsDontOverflow() { - TestSubscriber ts = new TestSubscriber<>((Long)null); + TestSubscriber ts = new TestSubscriber((Long)null); Observable.switchOnNext( Observable.interval(100, TimeUnit.MILLISECONDS) .map(new Function>() { @@ -584,7 +585,7 @@ public Observable apply(Long t) { @Test(timeout = 10000) public void testSecondaryRequestsDontOverflow() throws InterruptedException { - TestSubscriber ts = new TestSubscriber<>((Long)null); + TestSubscriber ts = new TestSubscriber((Long)null); Observable.switchOnNext( Observable.interval(100, TimeUnit.MILLISECONDS) .map(new Function>() { @@ -606,16 +607,21 @@ public Observable apply(Long t) { @Ignore("Request pattern changed and I can't decide if this is okay or not") public void testSecondaryRequestsAdditivelyAreMoreThanLongMaxValueInducesMaxValueRequestFromUpstream() throws InterruptedException { - final List requests = new CopyOnWriteArrayList<>(); + final List requests = new CopyOnWriteArrayList(); - TestSubscriber ts = new TestSubscriber<>(1L); + TestSubscriber ts = new TestSubscriber(1L); Observable.switchOnNext( Observable.interval(100, TimeUnit.MILLISECONDS) .map(new Function>() { @Override public Observable apply(Long t) { return Observable.fromIterable(Arrays.asList(1L, 2L, 3L)) - .doOnRequest(v -> requests.add(v)); + .doOnRequest(new LongConsumer() { + @Override + public void accept(long v) { + requests.add(v); + } + }); } }).take(3)).subscribe(ts); // we will miss two of the first observables diff --git a/src/test/java/io/reactivex/internal/operators/OperatorTakeLastOneTest.java b/src/test/java/io/reactivex/internal/operators/OperatorTakeLastOneTest.java index dde6930ccf..7814126317 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorTakeLastOneTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorTakeLastOneTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -17,19 +17,19 @@ import java.util.*; import java.util.concurrent.atomic.*; -import java.util.function.Consumer; import org.junit.Test; +import io.reactivex.functions.Consumer; +import io.reactivex.subscribers.TestSubscriber; import io.reactivex.Observable; import io.reactivex.Observer; -import io.reactivex.subscribers.TestSubscriber; public class OperatorTakeLastOneTest { @Test public void testLastOfManyReturnsLast() { - TestSubscriber s = new TestSubscriber<>(); + TestSubscriber s = new TestSubscriber(); Observable.range(1, 10).takeLast(1).subscribe(s); s.assertValue(10); s.assertNoErrors(); @@ -40,7 +40,7 @@ public void testLastOfManyReturnsLast() { @Test public void testLastOfEmptyReturnsEmpty() { - TestSubscriber s = new TestSubscriber<>(); + TestSubscriber s = new TestSubscriber(); Observable.empty().takeLast(1).subscribe(s); s.assertNoValues(); s.assertNoErrors(); @@ -51,7 +51,7 @@ public void testLastOfEmptyReturnsEmpty() { @Test public void testLastOfOneReturnsLast() { - TestSubscriber s = new TestSubscriber<>(); + TestSubscriber s = new TestSubscriber(); Observable.just(1).takeLast(1).subscribe(s); s.assertValue(1); s.assertNoErrors(); @@ -76,7 +76,7 @@ public void run() { @Test public void testLastWithBackpressure() { - MySubscriber s = new MySubscriber<>(0); + MySubscriber s = new MySubscriber(0); Observable.just(1).takeLast(1).subscribe(s); assertEquals(0, s.list.size()); s.requestMore(1); @@ -106,7 +106,7 @@ private static class MySubscriber extends Observer { this.initialRequest = initialRequest; } - final List list = new ArrayList<>(); + final List list = new ArrayList(); public void requestMore(long n) { request(n); diff --git a/src/test/java/io/reactivex/internal/operators/OperatorTakeLastTest.java b/src/test/java/io/reactivex/internal/operators/OperatorTakeLastTest.java index 5878556eff..64ebbf1fee 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorTakeLastTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorTakeLastTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -19,17 +19,17 @@ import java.util.*; import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.Function; import org.junit.*; import org.mockito.InOrder; import org.reactivestreams.Subscriber; -import io.reactivex.Observable; -import io.reactivex.Observer; -import io.reactivex.TestHelper; +import io.reactivex.*; +import io.reactivex.functions.*; import io.reactivex.schedulers.Schedulers; import io.reactivex.subscribers.TestSubscriber; +import io.reactivex.Observable; +import io.reactivex.Observer; public class OperatorTakeLastTest { @@ -106,7 +106,7 @@ public void testTakeLastWithNegativeCount() { @Test public void testBackpressure1() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); Observable.range(1, 100000).takeLast(1) .observeOn(Schedulers.newThread()) .map(newSlowProcessor()).subscribe(ts); @@ -117,7 +117,7 @@ public void testBackpressure1() { @Test public void testBackpressure2() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); Observable.range(1, 100000).takeLast(Observable.bufferSize() * 4) .observeOn(Schedulers.newThread()).map(newSlowProcessor()).subscribe(ts); ts.awaitTerminalEvent(); @@ -149,7 +149,12 @@ public void testIssue1522() { assertEquals(0, Observable .empty() .count() - .filter(v -> false) + .filter(new Predicate() { + @Override + public boolean test(Long v) { + return false; + } + }) .toList() .toBlocking().single().size()); } @@ -288,7 +293,7 @@ public void onNext(Integer integer) { @Test(timeout=10000) public void testRequestOverflow() { - final List list = new ArrayList<>(); + final List list = new ArrayList(); Observable.range(1, 100).takeLast(50).subscribe(new Observer() { @Override diff --git a/src/test/java/io/reactivex/internal/operators/OperatorTakeLastTimedTest.java b/src/test/java/io/reactivex/internal/operators/OperatorTakeLastTimedTest.java index e72b6bc95c..df65395427 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorTakeLastTimedTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorTakeLastTimedTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -24,8 +24,9 @@ import io.reactivex.*; import io.reactivex.exceptions.TestException; -import io.reactivex.schedulers.TestScheduler; +import io.reactivex.schedulers.*; import io.reactivex.subjects.PublishSubject; +import io.reactivex.subscribers.TestSubscriber; public class OperatorTakeLastTimedTest { @@ -200,4 +201,40 @@ public void takeLastTimedWithZeroCapacity() { verify(o, never()).onNext(any()); verify(o, never()).onError(any(Throwable.class)); } + + @Test + public void testContinuousDelivery() { + TestScheduler scheduler = Schedulers.test(); + + TestSubscriber ts = new TestSubscriber((Long)null); + + PublishSubject ps = PublishSubject.create(); + + ps.takeLast(1000, TimeUnit.MILLISECONDS, scheduler).subscribe(ts); + + ps.onNext(1); + scheduler.advanceTimeBy(500, TimeUnit.MILLISECONDS); + ps.onNext(2); + scheduler.advanceTimeBy(500, TimeUnit.MILLISECONDS); + ps.onNext(3); + scheduler.advanceTimeBy(500, TimeUnit.MILLISECONDS); + ps.onNext(4); + scheduler.advanceTimeBy(500, TimeUnit.MILLISECONDS); + ps.onComplete(); + scheduler.advanceTimeBy(500, TimeUnit.MILLISECONDS); + + ts.assertNoValues(); + + ts.request(1); + + ts.assertValue(3); + + scheduler.advanceTimeBy(500, TimeUnit.MILLISECONDS); + ts.request(1); + + ts.assertValues(3, 4); + ts.assertComplete(); + ts.assertNoErrors(); + + } } \ No newline at end of file diff --git a/src/test/java/io/reactivex/internal/operators/OperatorTakeTest.java b/src/test/java/io/reactivex/internal/operators/OperatorTakeTest.java index 9d3c8a77d7..f0bd83f101 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorTakeTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorTakeTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -20,7 +20,6 @@ import java.util.Arrays; import java.util.concurrent.*; import java.util.concurrent.atomic.*; -import java.util.function.*; import org.junit.*; import org.mockito.InOrder; @@ -28,6 +27,7 @@ import io.reactivex.*; import io.reactivex.exceptions.TestException; +import io.reactivex.functions.*; import io.reactivex.internal.subscriptions.*; import io.reactivex.schedulers.Schedulers; import io.reactivex.subjects.PublishSubject; @@ -134,7 +134,7 @@ public void subscribe(Subscriber observer) { @Ignore("take(0) is now empty() and doesn't even subscribe to the original source") public void testTakeZeroDoesntLeakError() { final AtomicBoolean subscribed = new AtomicBoolean(false); - BooleanSubscription bs = new BooleanSubscription(); + final BooleanSubscription bs = new BooleanSubscription(); Observable source = Observable.create(new Publisher() { @Override public void subscribe(Subscriber observer) { @@ -283,7 +283,7 @@ public void subscribe(Subscriber op) { @Test(timeout = 2000) public void testTakeObserveOn() { Subscriber o = TestHelper.mockSubscriber(); - TestSubscriber ts = new TestSubscriber<>(o); + TestSubscriber ts = new TestSubscriber(o); INFINITE_OBSERVABLE.onBackpressureDrop() .observeOn(Schedulers.newThread()).take(1).subscribe(ts); @@ -298,7 +298,7 @@ public void testTakeObserveOn() { @Test public void testProducerRequestThroughTake() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); ts.request(3); final AtomicLong requested = new AtomicLong(); Observable.create(new Publisher() { @@ -326,7 +326,7 @@ public void cancel() { @Test public void testProducerRequestThroughTakeIsModified() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); ts.request(3); final AtomicLong requested = new AtomicLong(); Observable.create(new Publisher() { @@ -354,7 +354,7 @@ public void cancel() { @Test public void testInterrupt() throws InterruptedException { - final AtomicReference exception = new AtomicReference<>(); + final AtomicReference exception = new AtomicReference(); final CountDownLatch latch = new CountDownLatch(1); Observable.just(1).subscribeOn(Schedulers.computation()).take(1) .subscribe(new Consumer() { @@ -380,7 +380,7 @@ public void accept(Integer t1) { @Test public void testDoesntRequestMoreThanNeededFromUpstream() throws InterruptedException { final AtomicLong requests = new AtomicLong(); - TestSubscriber ts = new TestSubscriber<>((Long)null); + TestSubscriber ts = new TestSubscriber((Long)null); Observable.interval(100, TimeUnit.MILLISECONDS) // .doOnRequest(new LongConsumer() { @@ -424,11 +424,16 @@ public void onNext(Integer t) { @Test public void testReentrantTake() { - PublishSubject source = PublishSubject.create(); + final PublishSubject source = PublishSubject.create(); - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); - source.take(1).doOnNext(v -> source.onNext(2)).subscribe(ts); + source.take(1).doOnNext(new Consumer() { + @Override + public void accept(Integer v) { + source.onNext(2); + } + }).subscribe(ts); source.onNext(1); diff --git a/src/test/java/io/reactivex/internal/operators/OperatorTakeTimedTest.java b/src/test/java/io/reactivex/internal/operators/OperatorTakeTimedTest.java index f584adb464..738de4eb79 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorTakeTimedTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorTakeTimedTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 diff --git a/src/test/java/io/reactivex/internal/operators/OperatorTakeUntilPredicateTest.java b/src/test/java/io/reactivex/internal/operators/OperatorTakeUntilPredicateTest.java index eb006c7269..857b5af916 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorTakeUntilPredicateTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorTakeUntilPredicateTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -16,13 +16,12 @@ import static org.mockito.Matchers.any; import static org.mockito.Mockito.*; -import java.util.function.Predicate; - import org.junit.Test; import org.reactivestreams.Subscriber; import io.reactivex.*; import io.reactivex.exceptions.TestException; +import io.reactivex.functions.Predicate; import io.reactivex.subscribers.TestSubscriber; ; @@ -31,7 +30,12 @@ public class OperatorTakeUntilPredicateTest { public void takeEmpty() { Subscriber o = TestHelper.mockSubscriber(); - Observable.empty().takeUntil(v -> true).subscribe(o); + Observable.empty().takeUntil(new Predicate() { + @Override + public boolean test(Object v) { + return true; + } + }).subscribe(o); verify(o, never()).onNext(any()); verify(o, never()).onError(any(Throwable.class)); @@ -41,7 +45,12 @@ public void takeEmpty() { public void takeAll() { Subscriber o = TestHelper.mockSubscriber(); - Observable.just(1, 2).takeUntil(v -> false).subscribe(o); + Observable.just(1, 2).takeUntil(new Predicate() { + @Override + public boolean test(Integer v) { + return false; + } + }).subscribe(o); verify(o).onNext(1); verify(o).onNext(2); @@ -52,7 +61,12 @@ public void takeAll() { public void takeFirst() { Subscriber o = TestHelper.mockSubscriber(); - Observable.just(1, 2).takeUntil(v -> true).subscribe(o); + Observable.just(1, 2).takeUntil(new Predicate() { + @Override + public boolean test(Integer v) { + return true; + } + }).subscribe(o); verify(o).onNext(1); verify(o, never()).onNext(2); @@ -63,7 +77,12 @@ public void takeFirst() { public void takeSome() { Subscriber o = TestHelper.mockSubscriber(); - Observable.just(1, 2, 3).takeUntil(t1 -> t1 == 2) + Observable.just(1, 2, 3).takeUntil(new Predicate() { + @Override + public boolean test(Integer t1) { + return t1 == 2; + } + }) .subscribe(o); verify(o).onNext(1); @@ -76,9 +95,13 @@ public void takeSome() { public void functionThrows() { Subscriber o = TestHelper.mockSubscriber(); - Observable.just(1, 2, 3).takeUntil((Predicate)(t1 -> { - throw new TestException("Forced failure"); - })).subscribe(o); + Predicate predicate = new Predicate() { + @Override + public boolean test(Integer t1) { + throw new TestException("Forced failure"); + } + }; + Observable.just(1, 2, 3).takeUntil(predicate).subscribe(o); verify(o).onNext(1); verify(o, never()).onNext(2); @@ -93,7 +116,12 @@ public void sourceThrows() { Observable.just(1) .concatWith(Observable.error(new TestException())) .concatWith(Observable.just(2)) - .takeUntil(v -> false).subscribe(o); + .takeUntil(new Predicate() { + @Override + public boolean test(Integer v) { + return false; + } + }).subscribe(o); verify(o).onNext(1); verify(o, never()).onNext(2); @@ -102,9 +130,14 @@ public void sourceThrows() { } @Test public void backpressure() { - TestSubscriber ts = new TestSubscriber<>(5L); + TestSubscriber ts = new TestSubscriber(5L); - Observable.range(1, 1000).takeUntil(v -> false).subscribe(ts); + Observable.range(1, 1000).takeUntil(new Predicate() { + @Override + public boolean test(Integer v) { + return false; + } + }).subscribe(ts); ts.assertNoErrors(); ts.assertValues(1, 2, 3, 4, 5); @@ -113,11 +146,15 @@ public void backpressure() { @Test public void testErrorIncludesLastValueAsCause() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); final TestException e = new TestException("Forced failure"); - Observable.just("abc").takeUntil((Predicate)(t -> { - throw e; - })).subscribe(ts); + Predicate predicate = new Predicate() { + @Override + public boolean test(String t) { + throw e; + } + }; + Observable.just("abc").takeUntil(predicate).subscribe(ts); ts.assertTerminated(); ts.assertNotComplete(); diff --git a/src/test/java/io/reactivex/internal/operators/OperatorTakeUntilTest.java b/src/test/java/io/reactivex/internal/operators/OperatorTakeUntilTest.java index 015d8657a2..6ac26e91cc 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorTakeUntilTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorTakeUntilTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -187,7 +187,7 @@ public void testUntilFires() { PublishSubject source = PublishSubject.create(); PublishSubject until = PublishSubject.create(); - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); source.takeUntil(until).unsafeSubscribe(ts); @@ -212,7 +212,7 @@ public void testMainCompletes() { PublishSubject source = PublishSubject.create(); PublishSubject until = PublishSubject.create(); - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); source.takeUntil(until).unsafeSubscribe(ts); @@ -235,7 +235,7 @@ public void testDownstreamUnsubscribes() { PublishSubject source = PublishSubject.create(); PublishSubject until = PublishSubject.create(); - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); source.takeUntil(until).take(1).unsafeSubscribe(ts); @@ -255,7 +255,7 @@ public void testDownstreamUnsubscribes() { public void testBackpressure() { PublishSubject until = PublishSubject.create(); - TestSubscriber ts = new TestSubscriber<>((Long)null); + TestSubscriber ts = new TestSubscriber((Long)null); Observable.range(1, 10).takeUntil(until).unsafeSubscribe(ts); diff --git a/src/test/java/io/reactivex/internal/operators/OperatorTakeWhileTest.java b/src/test/java/io/reactivex/internal/operators/OperatorTakeWhileTest.java index e7a2b70c27..a0a3936792 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorTakeWhileTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorTakeWhileTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -17,13 +17,12 @@ import static org.mockito.Matchers.any; import static org.mockito.Mockito.*; -import java.util.function.Predicate; - import org.junit.*; import org.reactivestreams.*; import io.reactivex.*; import io.reactivex.exceptions.TestException; +import io.reactivex.functions.Predicate; import io.reactivex.internal.subscriptions.EmptySubscription; import io.reactivex.subjects.*; import io.reactivex.subscribers.TestSubscriber; @@ -223,7 +222,7 @@ public boolean test(Integer t1) { return t1 < 100; } }); - TestSubscriber ts = new TestSubscriber<>(5L); + TestSubscriber ts = new TestSubscriber(5L); source.subscribe(ts); @@ -244,7 +243,7 @@ public boolean test(Integer t1) { return t1 < 2; } }); - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); source.unsafeSubscribe(ts); @@ -256,7 +255,7 @@ public boolean test(Integer t1) { @Test public void testErrorCauseIncludesLastValue() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); Observable.just("abc").takeWhile(new Predicate() { @Override public boolean test(String t1) { diff --git a/src/test/java/io/reactivex/internal/operators/OperatorThrottleFirstTest.java b/src/test/java/io/reactivex/internal/operators/OperatorThrottleFirstTest.java index 62286d0321..3c15bf0369 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorThrottleFirstTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorThrottleFirstTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 diff --git a/src/test/java/io/reactivex/internal/operators/OperatorTimeIntervalTest.java b/src/test/java/io/reactivex/internal/operators/OperatorTimeIntervalTest.java index 7d4884b42b..e39b43fa50 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorTimeIntervalTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorTimeIntervalTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -57,11 +57,11 @@ public void testTimeInterval() { subject.onComplete(); inOrder.verify(observer, times(1)).onNext( - new Timed<>(1, 1000, TIME_UNIT)); + new Timed(1, 1000, TIME_UNIT)); inOrder.verify(observer, times(1)).onNext( - new Timed<>(2, 2000, TIME_UNIT)); + new Timed(2, 2000, TIME_UNIT)); inOrder.verify(observer, times(1)).onNext( - new Timed<>(3, 3000, TIME_UNIT)); + new Timed(3, 3000, TIME_UNIT)); inOrder.verify(observer, times(1)).onComplete(); inOrder.verifyNoMoreInteractions(); } diff --git a/src/test/java/io/reactivex/internal/operators/OperatorTimeoutTests.java b/src/test/java/io/reactivex/internal/operators/OperatorTimeoutTests.java index a58396462e..d9978c50cb 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorTimeoutTests.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorTimeoutTests.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -47,7 +47,7 @@ public void setUp() { @Test public void shouldNotTimeoutIfOnNextWithinTimeout() { Subscriber observer = TestHelper.mockSubscriber(); - TestSubscriber ts = new TestSubscriber<>(observer); + TestSubscriber ts = new TestSubscriber(observer); withTimeout.subscribe(ts); @@ -62,7 +62,7 @@ public void shouldNotTimeoutIfOnNextWithinTimeout() { @Test public void shouldNotTimeoutIfSecondOnNextWithinTimeout() { Subscriber observer = TestHelper.mockSubscriber(); - TestSubscriber ts = new TestSubscriber<>(observer); + TestSubscriber ts = new TestSubscriber(observer); withTimeout.subscribe(ts); @@ -79,7 +79,7 @@ public void shouldNotTimeoutIfSecondOnNextWithinTimeout() { @Test public void shouldTimeoutIfOnNextNotWithinTimeout() { Subscriber observer = TestHelper.mockSubscriber(); - TestSubscriber ts = new TestSubscriber<>(observer); + TestSubscriber ts = new TestSubscriber(observer); withTimeout.subscribe(ts); @@ -91,7 +91,7 @@ public void shouldTimeoutIfOnNextNotWithinTimeout() { @Test public void shouldTimeoutIfSecondOnNextNotWithinTimeout() { Subscriber observer = TestHelper.mockSubscriber(); - TestSubscriber ts = new TestSubscriber<>(observer); + TestSubscriber ts = new TestSubscriber(observer); withTimeout.subscribe(observer); testScheduler.advanceTimeBy(2, TimeUnit.SECONDS); underlyingSubject.onNext("One"); @@ -104,7 +104,7 @@ public void shouldTimeoutIfSecondOnNextNotWithinTimeout() { @Test public void shouldCompleteIfUnderlyingComletes() { Subscriber observer = TestHelper.mockSubscriber(); - TestSubscriber ts = new TestSubscriber<>(observer); + TestSubscriber ts = new TestSubscriber(observer); withTimeout.subscribe(observer); testScheduler.advanceTimeBy(2, TimeUnit.SECONDS); underlyingSubject.onComplete(); @@ -117,7 +117,7 @@ public void shouldCompleteIfUnderlyingComletes() { @Test public void shouldErrorIfUnderlyingErrors() { Subscriber observer = TestHelper.mockSubscriber(); - TestSubscriber ts = new TestSubscriber<>(observer); + TestSubscriber ts = new TestSubscriber(observer); withTimeout.subscribe(observer); testScheduler.advanceTimeBy(2, TimeUnit.SECONDS); underlyingSubject.onError(new UnsupportedOperationException()); @@ -132,7 +132,7 @@ public void shouldSwitchToOtherIfOnNextNotWithinTimeout() { Observable source = underlyingSubject.timeout(TIMEOUT, TIME_UNIT, other, testScheduler); Subscriber observer = TestHelper.mockSubscriber(); - TestSubscriber ts = new TestSubscriber<>(observer); + TestSubscriber ts = new TestSubscriber(observer); source.subscribe(ts); testScheduler.advanceTimeBy(2, TimeUnit.SECONDS); @@ -155,7 +155,7 @@ public void shouldSwitchToOtherIfOnErrorNotWithinTimeout() { Observable source = underlyingSubject.timeout(TIMEOUT, TIME_UNIT, other, testScheduler); Subscriber observer = TestHelper.mockSubscriber(); - TestSubscriber ts = new TestSubscriber<>(observer); + TestSubscriber ts = new TestSubscriber(observer); source.subscribe(ts); testScheduler.advanceTimeBy(2, TimeUnit.SECONDS); @@ -178,7 +178,7 @@ public void shouldSwitchToOtherIfOnCompletedNotWithinTimeout() { Observable source = underlyingSubject.timeout(TIMEOUT, TIME_UNIT, other, testScheduler); Subscriber observer = TestHelper.mockSubscriber(); - TestSubscriber ts = new TestSubscriber<>(observer); + TestSubscriber ts = new TestSubscriber(observer); source.subscribe(ts); testScheduler.advanceTimeBy(2, TimeUnit.SECONDS); @@ -201,7 +201,7 @@ public void shouldSwitchToOtherAndCanBeUnsubscribedIfOnNextNotWithinTimeout() { Observable source = underlyingSubject.timeout(TIMEOUT, TIME_UNIT, other, testScheduler); Subscriber observer = TestHelper.mockSubscriber(); - TestSubscriber ts = new TestSubscriber<>(observer); + TestSubscriber ts = new TestSubscriber(observer); source.subscribe(ts); testScheduler.advanceTimeBy(2, TimeUnit.SECONDS); @@ -232,7 +232,7 @@ public void shouldTimeoutIfSynchronizedObservableEmitFirstOnNextNotWithinTimeout final CountDownLatch timeoutSetuped = new CountDownLatch(1); final Subscriber observer = TestHelper.mockSubscriber(); - TestSubscriber ts = new TestSubscriber<>(observer); + final TestSubscriber ts = new TestSubscriber(observer); new Thread(new Runnable() { @@ -284,7 +284,7 @@ public void subscribe(Subscriber subscriber) { Observable observableWithTimeout = never.timeout(1000, TimeUnit.MILLISECONDS, testScheduler); Subscriber observer = TestHelper.mockSubscriber(); - TestSubscriber ts = new TestSubscriber<>(observer); + TestSubscriber ts = new TestSubscriber(observer); observableWithTimeout.subscribe(ts); testScheduler.advanceTimeBy(2000, TimeUnit.MILLISECONDS); @@ -315,7 +315,7 @@ public void subscribe(Subscriber subscriber) { testScheduler); Subscriber observer = TestHelper.mockSubscriber(); - TestSubscriber ts = new TestSubscriber<>(observer); + TestSubscriber ts = new TestSubscriber(observer); observableWithTimeout.subscribe(ts); testScheduler.advanceTimeBy(2000, TimeUnit.MILLISECONDS); @@ -346,7 +346,7 @@ public void subscribe(Subscriber subscriber) { testScheduler); Subscriber observer = TestHelper.mockSubscriber(); - TestSubscriber ts = new TestSubscriber<>(observer); + TestSubscriber ts = new TestSubscriber(observer); observableWithTimeout.subscribe(ts); testScheduler.advanceTimeBy(2000, TimeUnit.MILLISECONDS); diff --git a/src/test/java/io/reactivex/internal/operators/OperatorTimeoutWithSelectorTest.java b/src/test/java/io/reactivex/internal/operators/OperatorTimeoutWithSelectorTest.java index 69586d5fdd..0a3d30a651 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorTimeoutWithSelectorTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorTimeoutWithSelectorTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -20,7 +20,6 @@ import java.util.Arrays; import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicBoolean; -import java.util.function.*; import org.junit.Test; import org.mockito.InOrder; @@ -30,6 +29,7 @@ import io.reactivex.*; import io.reactivex.exceptions.TestException; +import io.reactivex.functions.*; import io.reactivex.internal.subscriptions.EmptySubscription; import io.reactivex.schedulers.Schedulers; import io.reactivex.subjects.PublishSubject; @@ -320,34 +320,37 @@ public void testTimeoutSelectorWithTimeoutAndOnNextRaceCondition() throws Interr final CountDownLatch enteredTimeoutOne = new CountDownLatch(1); final AtomicBoolean latchTimeout = new AtomicBoolean(false); - final Function> timeoutFunc = t1 -> { - if (t1 == 1) { - // Force "unsubscribe" run on another thread - return Observable.create(new Publisher() { - @Override - public void subscribe(Subscriber subscriber) { - subscriber.onSubscribe(EmptySubscription.INSTANCE); - enteredTimeoutOne.countDown(); - // force the timeout message be sent after observer.onNext(2) - while (true) { - try { - if (!observerReceivedTwo.await(30, TimeUnit.SECONDS)) { - // CountDownLatch timeout - // There should be something wrong - latchTimeout.set(true); + final Function> timeoutFunc = new Function>() { + @Override + public Observable apply(Integer t1) { + if (t1 == 1) { + // Force "unsubscribe" run on another thread + return Observable.create(new Publisher() { + @Override + public void subscribe(Subscriber subscriber) { + subscriber.onSubscribe(EmptySubscription.INSTANCE); + enteredTimeoutOne.countDown(); + // force the timeout message be sent after observer.onNext(2) + while (true) { + try { + if (!observerReceivedTwo.await(30, TimeUnit.SECONDS)) { + // CountDownLatch timeout + // There should be something wrong + latchTimeout.set(true); + } + break; + } catch (InterruptedException e) { + // Since we just want to emulate a busy method, + // we ignore the interrupt signal from Scheduler. } - break; - } catch (InterruptedException e) { - // Since we just want to emulate a busy method, - // we ignore the interrupt signal from Scheduler. } + subscriber.onNext(1); + timeoutEmittedOne.countDown(); } - subscriber.onNext(1); - timeoutEmittedOne.countDown(); - } - }).subscribeOn(Schedulers.newThread()); - } else { - return PublishSubject.create(); + }).subscribeOn(Schedulers.newThread()); + } else { + return PublishSubject.create(); + } } }; @@ -371,7 +374,7 @@ public Void answer(InvocationOnMock invocation) throws Throwable { }).when(o).onComplete(); - final TestSubscriber ts = new TestSubscriber<>(o); + final TestSubscriber ts = new TestSubscriber(o); new Thread(new Runnable() { diff --git a/src/test/java/io/reactivex/internal/operators/OperatorTimestampTest.java b/src/test/java/io/reactivex/internal/operators/OperatorTimestampTest.java index 4478e0f1f1..302a53202a 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorTimestampTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorTimestampTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -50,9 +50,9 @@ public void timestampWithScheduler() { InOrder inOrder = inOrder(observer); - inOrder.verify(observer, times(1)).onNext(new Timed<>(1, 0, TimeUnit.MILLISECONDS)); - inOrder.verify(observer, times(1)).onNext(new Timed<>(2, 100, TimeUnit.MILLISECONDS)); - inOrder.verify(observer, times(1)).onNext(new Timed<>(3, 200, TimeUnit.MILLISECONDS)); + inOrder.verify(observer, times(1)).onNext(new Timed(1, 0, TimeUnit.MILLISECONDS)); + inOrder.verify(observer, times(1)).onNext(new Timed(2, 100, TimeUnit.MILLISECONDS)); + inOrder.verify(observer, times(1)).onNext(new Timed(3, 200, TimeUnit.MILLISECONDS)); verify(observer, never()).onError(any(Throwable.class)); verify(observer, never()).onComplete(); @@ -74,9 +74,9 @@ public void timestampWithScheduler2() { InOrder inOrder = inOrder(observer); - inOrder.verify(observer, times(1)).onNext(new Timed<>(1, 0, TimeUnit.MILLISECONDS)); - inOrder.verify(observer, times(1)).onNext(new Timed<>(2, 0, TimeUnit.MILLISECONDS)); - inOrder.verify(observer, times(1)).onNext(new Timed<>(3, 200, TimeUnit.MILLISECONDS)); + inOrder.verify(observer, times(1)).onNext(new Timed(1, 0, TimeUnit.MILLISECONDS)); + inOrder.verify(observer, times(1)).onNext(new Timed(2, 0, TimeUnit.MILLISECONDS)); + inOrder.verify(observer, times(1)).onNext(new Timed(3, 200, TimeUnit.MILLISECONDS)); verify(observer, never()).onError(any(Throwable.class)); verify(observer, never()).onComplete(); diff --git a/src/test/java/io/reactivex/internal/operators/OperatorToMapTest.java b/src/test/java/io/reactivex/internal/operators/OperatorToMapTest.java index 0f22e4ea0e..ba8ee122eb 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorToMapTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorToMapTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -17,13 +17,13 @@ import static org.mockito.Mockito.*; import java.util.*; -import java.util.function.*; import org.junit.*; import org.reactivestreams.Subscriber; import io.reactivex.Observable; import io.reactivex.TestHelper; +import io.reactivex.functions.*; public class OperatorToMapTest { Subscriber objectObserver; @@ -52,7 +52,7 @@ public void testToMap() { Observable> mapped = source.toMap(lengthFunc); - Map expected = new HashMap<>(); + Map expected = new HashMap(); expected.put(1, "a"); expected.put(2, "bb"); expected.put(3, "ccc"); @@ -71,7 +71,7 @@ public void testToMapWithValueSelector() { Observable> mapped = source.toMap(lengthFunc, duplicate); - Map expected = new HashMap<>(); + Map expected = new HashMap(); expected.put(1, "aa"); expected.put(2, "bbbb"); expected.put(3, "cccccc"); @@ -99,7 +99,7 @@ public Integer apply(String t1) { }; Observable> mapped = source.toMap(lengthFuncErr); - Map expected = new HashMap<>(); + Map expected = new HashMap(); expected.put(1, "a"); expected.put(2, "bb"); expected.put(3, "ccc"); @@ -129,7 +129,7 @@ public String apply(String t1) { Observable> mapped = source.toMap(lengthFunc, duplicateErr); - Map expected = new HashMap<>(); + Map expected = new HashMap(); expected.put(1, "aa"); expected.put(2, "bbbb"); expected.put(3, "cccccc"); @@ -168,9 +168,14 @@ public Integer apply(String t1) { return t1.length(); } }; - Observable> mapped = source.toMap(lengthFunc, v -> v, mapFactory); + Observable> mapped = source.toMap(lengthFunc, new Function() { + @Override + public String apply(String v) { + return v; + } + }, mapFactory); - Map expected = new LinkedHashMap<>(); + Map expected = new LinkedHashMap(); expected.put(2, "bb"); expected.put(3, "ccc"); expected.put(4, "dddd"); @@ -199,9 +204,14 @@ public Integer apply(String t1) { return t1.length(); } }; - Observable> mapped = source.toMap(lengthFunc, v -> v, mapFactory); + Observable> mapped = source.toMap(lengthFunc, new Function() { + @Override + public String apply(String v) { + return v; + } + }, mapFactory); - Map expected = new LinkedHashMap<>(); + Map expected = new LinkedHashMap(); expected.put(2, "bb"); expected.put(3, "ccc"); expected.put(4, "dddd"); diff --git a/src/test/java/io/reactivex/internal/operators/OperatorToMultimapTest.java b/src/test/java/io/reactivex/internal/operators/OperatorToMultimapTest.java index 3a8fb7916d..43b0a8f942 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorToMultimapTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorToMultimapTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -17,13 +17,13 @@ import static org.mockito.Mockito.*; import java.util.*; -import java.util.function.*; import org.junit.*; import org.reactivestreams.Subscriber; import io.reactivex.Observable; import io.reactivex.TestHelper; +import io.reactivex.functions.*; public class OperatorToMultimapTest { Subscriber objectObserver; @@ -33,8 +33,18 @@ public void before() { objectObserver = TestHelper.mockSubscriber(); } - Function lengthFunc = t1 -> t1.length(); - Function duplicate = t1 -> t1 + t1; + Function lengthFunc = new Function() { + @Override + public Integer apply(String t1) { + return t1.length(); + } + }; + Function duplicate = new Function() { + @Override + public String apply(String t1) { + return t1 + t1; + } + }; @Test public void testToMultimap() { @@ -42,7 +52,7 @@ public void testToMultimap() { Observable>> mapped = source.toMultimap(lengthFunc); - Map> expected = new HashMap<>(); + Map> expected = new HashMap>(); expected.put(1, Arrays.asList("a", "b")); expected.put(2, Arrays.asList("cc", "dd")); @@ -59,7 +69,7 @@ public void testToMultimapWithValueSelector() { Observable>> mapped = source.toMultimap(lengthFunc, duplicate); - Map> expected = new HashMap<>(); + Map> expected = new HashMap>(); expected.put(1, Arrays.asList("aa", "bb")); expected.put(2, Arrays.asList("cccc", "dddd")); @@ -89,13 +99,23 @@ protected boolean removeEldestEntry(Map.Entry> eldes } }; - Function identity = v -> v; + Function identity = new Function() { + @Override + public String apply(String v) { + return v; + } + }; Observable>> mapped = source.toMultimap( lengthFunc, identity, - mapFactory, ArrayList::new); + mapFactory, new Function>() { + @Override + public Collection apply(Integer e) { + return new ArrayList(); + } + }); - Map> expected = new HashMap<>(); + Map> expected = new HashMap>(); expected.put(2, Arrays.asList("cc", "dd")); expected.put(3, Arrays.asList("eee", "fff")); @@ -110,23 +130,36 @@ protected boolean removeEldestEntry(Map.Entry> eldes public void testToMultimapWithCollectionFactory() { Observable source = Observable.just("cc", "dd", "eee", "eee"); - Function> collectionFactory = t1 -> { - if (t1 == 2) { - return new ArrayList<>(); - } else { - return new HashSet<>(); + Function> collectionFactory = new Function>() { + @Override + public Collection apply(Integer t1) { + if (t1 == 2) { + return new ArrayList(); + } else { + return new HashSet(); + } } }; - Function identity = v -> v; - Supplier>> mapSupplier = HashMap::new; + Function identity = new Function() { + @Override + public String apply(String v) { + return v; + } + }; + Supplier>> mapSupplier = new Supplier>>() { + @Override + public Map> get() { + return new HashMap>(); + } + }; Observable>> mapped = source .toMultimap(lengthFunc, identity, mapSupplier, collectionFactory); - Map> expected = new HashMap<>(); + Map> expected = new HashMap>(); expected.put(2, Arrays.asList("cc", "dd")); - expected.put(3, new HashSet<>(Arrays.asList("eee"))); + expected.put(3, new HashSet(Arrays.asList("eee"))); mapped.subscribe(objectObserver); @@ -151,7 +184,7 @@ public Integer apply(String t1) { Observable>> mapped = source.toMultimap(lengthFuncErr); - Map> expected = new HashMap<>(); + Map> expected = new HashMap>(); expected.put(1, Arrays.asList("a", "b")); expected.put(2, Arrays.asList("cc", "dd")); @@ -178,7 +211,7 @@ public String apply(String t1) { Observable>> mapped = source.toMultimap(lengthFunc, duplicateErr); - Map> expected = new HashMap<>(); + Map> expected = new HashMap>(); expected.put(1, Arrays.asList("aa", "bb")); expected.put(2, Arrays.asList("cccc", "dddd")); @@ -201,9 +234,14 @@ public Map> get() { }; Observable>> mapped = source - .toMultimap(lengthFunc, v -> v, mapFactory); + .toMultimap(lengthFunc, new Function() { + @Override + public String apply(String v) { + return v; + } + }, mapFactory); - Map> expected = new HashMap<>(); + Map> expected = new HashMap>(); expected.put(2, Arrays.asList("cc", "dd")); expected.put(3, Arrays.asList("eee", "fff")); @@ -218,21 +256,34 @@ public Map> get() { public void testToMultimapWithThrowingCollectionFactory() { Observable source = Observable.just("cc", "cc", "eee", "eee"); - Function> collectionFactory = t1 -> { - if (t1 == 2) { - throw new RuntimeException("Forced failure"); - } else { - return new HashSet<>(); + Function> collectionFactory = new Function>() { + @Override + public Collection apply(Integer t1) { + if (t1 == 2) { + throw new RuntimeException("Forced failure"); + } else { + return new HashSet(); + } } }; - Function identity = v -> v; - Supplier>> mapSupplier = HashMap::new; + Function identity = new Function() { + @Override + public String apply(String v) { + return v; + } + }; + Supplier>> mapSupplier = new Supplier>>() { + @Override + public Map> get() { + return new HashMap>(); + } + }; Observable>> mapped = source.toMultimap(lengthFunc, identity, mapSupplier, collectionFactory); - Map> expected = new HashMap<>(); + Map> expected = new HashMap>(); expected.put(2, Arrays.asList("cc", "dd")); expected.put(3, Collections.singleton("eee")); diff --git a/src/test/java/io/reactivex/internal/operators/OperatorToObservableListTest.java b/src/test/java/io/reactivex/internal/operators/OperatorToObservableListTest.java index c275f044ec..660b4ae2f0 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorToObservableListTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorToObservableListTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -24,10 +24,10 @@ import org.reactivestreams.Subscriber; import io.reactivex.*; -import io.reactivex.Observable; import io.reactivex.schedulers.Schedulers; import io.reactivex.subjects.PublishSubject; import io.reactivex.subscribers.TestSubscriber; +import io.reactivex.Observable; public class OperatorToObservableListTest { @@ -99,7 +99,7 @@ public void testListWithBlockingFirst() { @Test public void testBackpressureHonored() { Observable> w = Observable.just(1, 2, 3, 4, 5).toList(); - TestSubscriber> ts = new TestSubscriber<>((Long)null); + TestSubscriber> ts = new TestSubscriber>((Long)null); w.subscribe(ts); @@ -132,7 +132,7 @@ public void testAsyncRequested() { Observable> sorted = source.toList(); final CyclicBarrier cb = new CyclicBarrier(2); - final TestSubscriber> ts = new TestSubscriber<>((Long)null); + final TestSubscriber> ts = new TestSubscriber>((Long)null); sorted.subscribe(ts); w.schedule(new Runnable() { diff --git a/src/test/java/io/reactivex/internal/operators/OperatorToObservableSortedListTest.java b/src/test/java/io/reactivex/internal/operators/OperatorToObservableSortedListTest.java index 0f565110bf..bf7d316178 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorToObservableSortedListTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorToObservableSortedListTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -25,10 +25,10 @@ import org.reactivestreams.Subscriber; import io.reactivex.*; -import io.reactivex.Observable; import io.reactivex.schedulers.Schedulers; import io.reactivex.subjects.PublishSubject; import io.reactivex.subscribers.TestSubscriber; +import io.reactivex.Observable; public class OperatorToObservableSortedListTest { @@ -71,7 +71,7 @@ public void testWithFollowingFirst() { @Test public void testBackpressureHonored() { Observable> w = Observable.just(1, 3, 2, 5, 4).toSortedList(); - TestSubscriber> ts = new TestSubscriber<>((Long)null); + TestSubscriber> ts = new TestSubscriber>((Long)null); w.subscribe(ts); @@ -104,7 +104,7 @@ public void testAsyncRequested() { Observable> sorted = source.toSortedList(); final CyclicBarrier cb = new CyclicBarrier(2); - final TestSubscriber> ts = new TestSubscriber<>((Long)null); + final TestSubscriber> ts = new TestSubscriber>((Long)null); sorted.subscribe(ts); w.schedule(new Runnable() { @Override diff --git a/src/test/java/io/reactivex/internal/operators/OperatorUnsubscribeOnTest.java b/src/test/java/io/reactivex/internal/operators/OperatorUnsubscribeOnTest.java index 332d93397b..48df08e311 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorUnsubscribeOnTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorUnsubscribeOnTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -32,7 +32,7 @@ public void testUnsubscribeWhenSubscribeOnAndUnsubscribeOnAreOnSameThread() thro UIEventLoopScheduler UI_EVENT_LOOP = new UIEventLoopScheduler(); try { final ThreadSubscription subscription = new ThreadSubscription(); - final AtomicReference subscribeThread = new AtomicReference<>(); + final AtomicReference subscribeThread = new AtomicReference(); Observable w = Observable.create(new Publisher() { @Override @@ -45,7 +45,7 @@ public void subscribe(Subscriber t1) { } }); - TestSubscriber observer = new TestSubscriber<>(); + TestSubscriber observer = new TestSubscriber(); w.subscribeOn(UI_EVENT_LOOP).observeOn(Schedulers.computation()).unsubscribeOn(UI_EVENT_LOOP).subscribe(observer); observer.awaitTerminalEvent(1, TimeUnit.SECONDS); @@ -76,7 +76,7 @@ public void testUnsubscribeWhenSubscribeOnAndUnsubscribeOnAreOnDifferentThreads( UIEventLoopScheduler UI_EVENT_LOOP = new UIEventLoopScheduler(); try { final ThreadSubscription subscription = new ThreadSubscription(); - final AtomicReference subscribeThread = new AtomicReference<>(); + final AtomicReference subscribeThread = new AtomicReference(); Observable w = Observable.create(new Publisher() { @Override @@ -89,7 +89,7 @@ public void subscribe(Subscriber t1) { } }); - TestSubscriber observer = new TestSubscriber<>(); + TestSubscriber observer = new TestSubscriber(); w.subscribeOn(Schedulers.newThread()).observeOn(Schedulers.computation()).unsubscribeOn(UI_EVENT_LOOP).subscribe(observer); observer.awaitTerminalEvent(1, TimeUnit.SECONDS); diff --git a/src/test/java/io/reactivex/internal/operators/OperatorWindowWithObservableTest.java b/src/test/java/io/reactivex/internal/operators/OperatorWindowWithObservableTest.java index f94926e563..1e3383abff 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorWindowWithObservableTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorWindowWithObservableTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -19,17 +19,17 @@ import java.util.*; import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.Supplier; import org.junit.Test; import org.reactivestreams.Subscriber; -import io.reactivex.Observable; -import io.reactivex.Observer; -import io.reactivex.TestHelper; +import io.reactivex.*; import io.reactivex.exceptions.TestException; +import io.reactivex.functions.Supplier; import io.reactivex.subjects.PublishSubject; import io.reactivex.subscribers.TestSubscriber; +import io.reactivex.Observable; +import io.reactivex.Observer; public class OperatorWindowWithObservableTest { @@ -40,7 +40,7 @@ public void testWindowViaObservableNormal1() { final Subscriber o = TestHelper.mockSubscriber(); - final List> values = new ArrayList<>(); + final List> values = new ArrayList>(); Subscriber> wo = new Observer>() { @Override @@ -98,7 +98,7 @@ public void testWindowViaObservableBoundaryCompletes() { final Subscriber o = TestHelper.mockSubscriber(); - final List> values = new ArrayList<>(); + final List> values = new ArrayList>(); Subscriber> wo = new Observer>() { @Override @@ -154,7 +154,7 @@ public void testWindowViaObservableBoundaryThrows() { final Subscriber o = TestHelper.mockSubscriber(); - final List> values = new ArrayList<>(); + final List> values = new ArrayList>(); Subscriber> wo = new Observer>() { @Override @@ -204,7 +204,7 @@ public void testWindowViaObservableSourceThrows() { final Subscriber o = TestHelper.mockSubscriber(); - final List> values = new ArrayList<>(); + final List> values = new ArrayList>(); Subscriber> wo = new Observer>() { @Override @@ -292,7 +292,7 @@ public Observable get() { } }; - TestSubscriber> ts = new TestSubscriber<>(); + TestSubscriber> ts = new TestSubscriber>(); source.window(boundary).unsafeSubscribe(ts); assertFalse(ts.isCancelled()); @@ -309,7 +309,7 @@ public Observable get() { } }; - TestSubscriber> ts = new TestSubscriber<>(); + TestSubscriber> ts = new TestSubscriber>(); source.window(boundaryFunc).subscribe(ts); assertTrue(source.hasSubscribers()); @@ -335,7 +335,7 @@ public Observable get() { } }; - TestSubscriber> ts = new TestSubscriber<>(); + TestSubscriber> ts = new TestSubscriber>(); source.window(boundaryFunc).subscribe(ts); assertTrue(source.hasSubscribers()); @@ -363,7 +363,7 @@ public Observable get() { } }; - TestSubscriber> ts = new TestSubscriber<>(); + TestSubscriber> ts = new TestSubscriber>(); source.window(boundaryFunc).subscribe(ts); assertTrue(source.hasSubscribers()); @@ -391,7 +391,7 @@ public Observable get() { } }; - final TestSubscriber ts = new TestSubscriber<>(1L); + final TestSubscriber ts = new TestSubscriber(1L); final TestSubscriber> ts1 = new TestSubscriber>(1L) { @Override public void onNext(Observable t) { @@ -430,7 +430,7 @@ public Observable get() { } }; - TestSubscriber> ts = new TestSubscriber<>(); + TestSubscriber> ts = new TestSubscriber>(); source.window(boundaryFunc).subscribe(ts); source.onNext(1); diff --git a/src/test/java/io/reactivex/internal/operators/OperatorWindowWithSizeTest.java b/src/test/java/io/reactivex/internal/operators/OperatorWindowWithSizeTest.java index 89e671e617..4bb9200414 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorWindowWithSizeTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorWindowWithSizeTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -20,23 +20,23 @@ import java.util.*; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.*; import org.junit.Test; import org.reactivestreams.*; -import io.reactivex.Observable; -import io.reactivex.Observer; -import io.reactivex.TestHelper; +import io.reactivex.*; +import io.reactivex.functions.*; import io.reactivex.internal.subscriptions.BooleanSubscription; import io.reactivex.schedulers.Schedulers; import io.reactivex.subscribers.TestSubscriber; +import io.reactivex.Observable; +import io.reactivex.Observer; public class OperatorWindowWithSizeTest { private static List> toLists(Observable> observables) { - final List> lists = new ArrayList<>(); + final List> lists = new ArrayList>(); Observable.concat(observables.map(new Function, Observable>>() { @Override public Observable> apply(Observable xs) { @@ -107,7 +107,7 @@ public void testSkipAndCountWindowsWithGaps() { @Test public void testWindowUnsubscribeNonOverlapping() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); final AtomicInteger count = new AtomicInteger(); Observable.merge(Observable.range(1, 10000).doOnNext(new Consumer() { @@ -126,7 +126,7 @@ public void accept(Integer t1) { @Test public void testWindowUnsubscribeNonOverlappingAsyncSource() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); final AtomicInteger count = new AtomicInteger(); Observable.merge(Observable.range(1, 100000) .doOnNext(new Consumer() { @@ -150,7 +150,7 @@ public void accept(Integer t1) { @Test public void testWindowUnsubscribeOverlapping() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); final AtomicInteger count = new AtomicInteger(); Observable.merge(Observable.range(1, 10000).doOnNext(new Consumer() { @@ -169,7 +169,7 @@ public void accept(Integer t1) { @Test public void testWindowUnsubscribeOverlappingAsyncSource() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); final AtomicInteger count = new AtomicInteger(); Observable.merge(Observable.range(1, 100000) .doOnNext(new Consumer() { @@ -182,7 +182,7 @@ public void accept(Integer t1) { }) .observeOn(Schedulers.computation()) .window(5, 4) - .take(2)) + .take(2), 128) .subscribe(ts); ts.awaitTerminalEvent(500, TimeUnit.MILLISECONDS); ts.assertTerminated(); @@ -192,7 +192,7 @@ public void accept(Integer t1) { } private List list(String... args) { - List list = new ArrayList<>(); + List list = new ArrayList(); for (String arg : args) { list.add(arg); } @@ -203,7 +203,7 @@ private List list(String... args) { public void testBackpressureOuter() { Observable> source = Observable.range(1, 10).window(3); - final List list = new ArrayList<>(); + final List list = new ArrayList(); final Subscriber o = TestHelper.mockSubscriber(); @@ -271,7 +271,7 @@ public void subscribe(Subscriber s) { @Test public void testTakeFlatMapCompletes() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); final int indicator = 999999999; @@ -290,9 +290,10 @@ public Observable apply(Observable w) { ts.assertValueCount(22); } + @SuppressWarnings("unchecked") @Test public void testBackpressureOuterInexact() { - TestSubscriber> ts = new TestSubscriber<>((Long)null); + TestSubscriber> ts = new TestSubscriber>((Long)null); Observable.range(1, 5).window(2, 1) .map(new Function, Observable>>() { @@ -300,7 +301,12 @@ public void testBackpressureOuterInexact() { public Observable> apply(Observable t) { return t.toList(); } - }).concatMap(v -> v) + }).concatMap(new Function>, Publisher>>() { + @Override + public Publisher> apply(Observable> v) { + return v; + } + }) .subscribe(ts); ts.assertNoErrors(); diff --git a/src/test/java/io/reactivex/internal/operators/OperatorWindowWithStartEndObservableTest.java b/src/test/java/io/reactivex/internal/operators/OperatorWindowWithStartEndObservableTest.java index 2d2990a7dc..4e430c9172 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorWindowWithStartEndObservableTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorWindowWithStartEndObservableTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -17,18 +17,18 @@ import java.util.*; import java.util.concurrent.TimeUnit; -import java.util.function.*; import org.junit.*; import org.reactivestreams.*; -import io.reactivex.Observable; -import io.reactivex.Observer; -import io.reactivex.Scheduler; +import io.reactivex.*; +import io.reactivex.functions.*; import io.reactivex.internal.subscriptions.EmptySubscription; import io.reactivex.schedulers.TestScheduler; import io.reactivex.subjects.PublishSubject; import io.reactivex.subscribers.TestSubscriber; +import io.reactivex.Observable; +import io.reactivex.Observer; public class OperatorWindowWithStartEndObservableTest { @@ -43,8 +43,8 @@ public void before() { @Test public void testObservableBasedOpenerAndCloser() { - final List list = new ArrayList<>(); - final List> lists = new ArrayList<>(); + final List list = new ArrayList(); + final List> lists = new ArrayList>(); Observable source = Observable.create(new Publisher() { @Override @@ -94,8 +94,8 @@ public void subscribe(Subscriber observer) { @Test public void testObservableBasedCloser() { - final List list = new ArrayList<>(); - final List> lists = new ArrayList<>(); + final List list = new ArrayList(); + final List> lists = new ArrayList>(); Observable source = Observable.create(new Publisher() { @Override @@ -143,7 +143,7 @@ public void subscribe(Subscriber observer) { } private List list(String... args) { - List list = new ArrayList<>(); + List list = new ArrayList(); for (String arg : args) { list.add(arg); } @@ -175,7 +175,7 @@ public void accept(Observable stringObservable) { stringObservable.subscribe(new Observer() { @Override public void onComplete() { - lists.add(new ArrayList<>(list)); + lists.add(new ArrayList(list)); list.clear(); } @@ -200,7 +200,7 @@ public void testNoUnsubscribeAndNoLeak() { PublishSubject open = PublishSubject.create(); final PublishSubject close = PublishSubject.create(); - TestSubscriber> ts = new TestSubscriber<>(); + TestSubscriber> ts = new TestSubscriber>(); source.window(open, new Function>() { @Override @@ -237,7 +237,7 @@ public void testUnsubscribeAll() { PublishSubject open = PublishSubject.create(); final PublishSubject close = PublishSubject.create(); - TestSubscriber> ts = new TestSubscriber<>(); + TestSubscriber> ts = new TestSubscriber>(); source.window(open, new Function>() { @Override diff --git a/src/test/java/io/reactivex/internal/operators/OperatorWindowWithTimeTest.java b/src/test/java/io/reactivex/internal/operators/OperatorWindowWithTimeTest.java index 887326faa2..46d976992d 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorWindowWithTimeTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorWindowWithTimeTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,22 +13,22 @@ package io.reactivex.internal.operators; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; import java.util.*; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.*; import org.junit.*; import org.reactivestreams.*; -import io.reactivex.Observable; -import io.reactivex.Observer; -import io.reactivex.Scheduler; +import io.reactivex.*; +import io.reactivex.functions.*; import io.reactivex.internal.subscriptions.EmptySubscription; import io.reactivex.schedulers.TestScheduler; import io.reactivex.subscribers.TestSubscriber; +import io.reactivex.Observable; +import io.reactivex.Observer; public class OperatorWindowWithTimeTest { @@ -44,8 +44,8 @@ public void before() { @Test public void testTimedAndCount() { - final List list = new ArrayList<>(); - final List> lists = new ArrayList<>(); + final List list = new ArrayList(); + final List> lists = new ArrayList>(); Observable source = Observable.create(new Publisher() { @Override @@ -78,8 +78,8 @@ public void subscribe(Subscriber observer) { @Test public void testTimed() { - final List list = new ArrayList<>(); - final List> lists = new ArrayList<>(); + final List list = new ArrayList(); + final List> lists = new ArrayList>(); Observable source = Observable.create(new Publisher() { @Override @@ -107,7 +107,7 @@ public void subscribe(Subscriber observer) { } private List list(String... args) { - List list = new ArrayList<>(); + List list = new ArrayList(); for (String arg : args) { list.add(arg); } @@ -139,13 +139,13 @@ public void accept(Observable stringObservable) { stringObservable.subscribe(new Observer() { @Override public void onComplete() { - lists.add(new ArrayList<>(list)); + lists.add(new ArrayList(list)); list.clear(); } @Override public void onError(Throwable e) { - fail(e.getMessage()); + Assert.fail(e.getMessage()); } @Override @@ -161,8 +161,8 @@ public void testExactWindowSize() { Observable> source = Observable.range(1, 10) .window(1, TimeUnit.MINUTES, scheduler, 3); - final List list = new ArrayList<>(); - final List> lists = new ArrayList<>(); + final List list = new ArrayList(); + final List> lists = new ArrayList>(); source.subscribe(observeWindow(list, lists)); @@ -179,25 +179,40 @@ public void testExactWindowSize() { @Test public void testTakeFlatMapCompletes() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); - AtomicInteger wip = new AtomicInteger(); + final AtomicInteger wip = new AtomicInteger(); final int indicator = 999999999; OperatorWindowWithSizeTest.hotStream() .window(300, TimeUnit.MILLISECONDS) .take(10) - .doOnComplete(() -> System.out.println("Main done!")) + .doOnComplete(new Runnable() { + @Override + public void run() { + System.out.println("Main done!"); + } + }) .flatMap(new Function, Observable>() { @Override public Observable apply(Observable w) { return w.startWith(indicator) - .doOnComplete(() -> System.out.println("inner done: " + wip.incrementAndGet())) + .doOnComplete(new Runnable() { + @Override + public void run() { + System.out.println("inner done: " + wip.incrementAndGet()); + } + }) ; } }) - .doOnNext(System.out::println) + .doOnNext(new Consumer() { + @Override + public void accept(Integer pv) { + System.out.println(pv); + } + }) .subscribe(ts); ts.awaitTerminalEvent(5, TimeUnit.SECONDS); diff --git a/src/test/java/io/reactivex/internal/operators/OperatorWithLatestFromTest.java b/src/test/java/io/reactivex/internal/operators/OperatorWithLatestFromTest.java index 8c9fbd9aab..f5f62d2ad8 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorWithLatestFromTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorWithLatestFromTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -17,14 +17,13 @@ import static org.mockito.Matchers.*; import static org.mockito.Mockito.*; -import java.util.function.BiFunction; - import org.junit.Test; import org.mockito.InOrder; import org.reactivestreams.Subscriber; import io.reactivex.*; import io.reactivex.exceptions.TestException; +import io.reactivex.functions.BiFunction; import io.reactivex.subjects.PublishSubject; import io.reactivex.subscribers.TestSubscriber; @@ -84,7 +83,7 @@ public void testEmptySource() { Observable result = source.withLatestFrom(other, COMBINER); - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); result.subscribe(ts); @@ -110,7 +109,7 @@ public void testEmptyOther() { Observable result = source.withLatestFrom(other, COMBINER); - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); result.subscribe(ts); @@ -137,7 +136,7 @@ public void testUnsubscription() { Observable result = source.withLatestFrom(other, COMBINER); - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); result.subscribe(ts); @@ -164,7 +163,7 @@ public void testSourceThrows() { Observable result = source.withLatestFrom(other, COMBINER); - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); result.subscribe(ts); @@ -191,7 +190,7 @@ public void testOtherThrows() { Observable result = source.withLatestFrom(other, COMBINER); - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); result.subscribe(ts); @@ -219,7 +218,7 @@ public void testFunctionThrows() { Observable result = source.withLatestFrom(other, COMBINER_ERROR); - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); result.subscribe(ts); @@ -245,7 +244,7 @@ public void testNoDownstreamUnsubscribe() { Observable result = source.withLatestFrom(other, COMBINER); - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); result.unsafeSubscribe(ts); @@ -261,7 +260,7 @@ public void testBackpressure() { Observable result = source.withLatestFrom(other, COMBINER); - TestSubscriber ts = new TestSubscriber<>((Long)null); + TestSubscriber ts = new TestSubscriber((Long)null); result.subscribe(ts); diff --git a/src/test/java/io/reactivex/internal/operators/OperatorZipCompletionTest.java b/src/test/java/io/reactivex/internal/operators/OperatorZipCompletionTest.java index 4f74b0bce5..c2f74d843f 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorZipCompletionTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorZipCompletionTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -15,13 +15,12 @@ import static org.mockito.Mockito.*; -import java.util.function.BiFunction; - import org.junit.*; import org.mockito.InOrder; import org.reactivestreams.Subscriber; import io.reactivex.*; +import io.reactivex.functions.BiFunction; import io.reactivex.subjects.PublishSubject; /** diff --git a/src/test/java/io/reactivex/internal/operators/OperatorZipIterableTest.java b/src/test/java/io/reactivex/internal/operators/OperatorZipIterableTest.java index a5cabd68c9..f2e8b407e0 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorZipIterableTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorZipIterableTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -19,7 +19,6 @@ import java.util.*; import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.*; import org.junit.*; import org.mockito.InOrder; @@ -28,7 +27,7 @@ import io.reactivex.Observable; import io.reactivex.TestHelper; import io.reactivex.exceptions.TestException; -import io.reactivex.functions.Function3; +import io.reactivex.functions.*; import io.reactivex.subjects.PublishSubject; public class OperatorZipIterableTest { @@ -333,7 +332,12 @@ public void remove() { } - Consumer printer = System.out::println; + Consumer printer = new Consumer() { + @Override + public void accept(String pv) { + System.out.println(pv); + } + }; static final class SquareStr implements Function { final AtomicInteger counter = new AtomicInteger(); diff --git a/src/test/java/io/reactivex/internal/operators/OperatorZipTest.java b/src/test/java/io/reactivex/internal/operators/OperatorZipTest.java index 7c7f4f594c..660679191f 100644 --- a/src/test/java/io/reactivex/internal/operators/OperatorZipTest.java +++ b/src/test/java/io/reactivex/internal/operators/OperatorZipTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -20,20 +20,21 @@ import java.util.*; import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.*; import org.junit.*; import org.mockito.InOrder; import org.reactivestreams.*; import io.reactivex.*; -import io.reactivex.Observable; -import io.reactivex.Observer; -import io.reactivex.functions.Function3; +import io.reactivex.functions.*; +import io.reactivex.internal.functions.Functions; import io.reactivex.internal.subscriptions.*; import io.reactivex.schedulers.Schedulers; import io.reactivex.subjects.PublishSubject; import io.reactivex.subscribers.TestSubscriber; +import io.reactivex.Optional; +import io.reactivex.Observable; +import io.reactivex.Observer; public class OperatorZipTest { BiFunction concat2Strings; @@ -66,7 +67,7 @@ public String apply(String t1, String t2) { @SuppressWarnings("unchecked") @Test public void testCollectionSizeDifferentThanFunction() { - Function zipr = getConcatStringIntegerIntArrayZipr(); + Function zipr = Functions.toFunction(getConcatStringIntegerIntArrayZipr()); //Function3 /* define a Subscriber to receive aggregated events */ @@ -349,7 +350,7 @@ public void testAggregatorUnsubscribe() { PublishSubject r2 = PublishSubject.create(); /* define a Subscriber to receive aggregated events */ Subscriber observer = TestHelper.mockSubscriber(); - TestSubscriber ts = new TestSubscriber<>(observer); + TestSubscriber ts = new TestSubscriber(observer); Observable.zip(r1, r2, zipr2).subscribe(ts); @@ -767,7 +768,7 @@ public String apply(Integer a, Integer b) { } }); - final ArrayList list = new ArrayList<>(); + final ArrayList list = new ArrayList(); os.subscribe(new Consumer() { @Override @@ -794,7 +795,7 @@ public String apply(Integer a, Integer b) { } }).take(5); - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); os.subscribe(ts); ts.awaitTerminalEvent(); @@ -819,7 +820,7 @@ public String apply(Integer a, Integer b) { } }); - final ArrayList list = new ArrayList<>(); + final ArrayList list = new ArrayList(); os.subscribe(new Observer() { @Override @@ -865,7 +866,7 @@ public String apply(Integer t1, String t2) { }); - final ArrayList list = new ArrayList<>(); + final ArrayList list = new ArrayList(); o.subscribe(new Consumer() { @Override @@ -914,7 +915,7 @@ public String apply(Try> t1, Try> t2) { }); - final ArrayList list = new ArrayList<>(); + final ArrayList list = new ArrayList(); o.subscribe(new Consumer() { @Override @@ -943,7 +944,7 @@ public String apply(Integer t1, String t2) { }); - final ArrayList list = new ArrayList<>(); + final ArrayList list = new ArrayList(); o.subscribe(new Consumer() { @Override @@ -970,7 +971,7 @@ public Object apply(final Object[] args) { } }); - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); o.subscribe(ts); ts.awaitTerminalEvent(200, TimeUnit.MILLISECONDS); ts.assertNoValues(); @@ -1004,7 +1005,7 @@ public void testBackpressureSync() { Observable o1 = createInfiniteObservable(generatedA); Observable o2 = createInfiniteObservable(generatedB); - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); Observable.zip(o1, o2, new BiFunction() { @Override @@ -1028,7 +1029,7 @@ public void testBackpressureAsync() { Observable o1 = createInfiniteObservable(generatedA).subscribeOn(Schedulers.computation()); Observable o2 = createInfiniteObservable(generatedB).subscribeOn(Schedulers.computation()); - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); Observable.zip(o1, o2, new BiFunction() { @Override @@ -1052,7 +1053,7 @@ public void testDownstreamBackpressureRequestsWithFiniteSyncObservables() { Observable o1 = createInfiniteObservable(generatedA).take(Observable.bufferSize() * 2); Observable o2 = createInfiniteObservable(generatedB).take(Observable.bufferSize() * 2); - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); Observable.zip(o1, o2, new BiFunction() { @Override @@ -1077,7 +1078,7 @@ public void testDownstreamBackpressureRequestsWithInfiniteAsyncObservables() { Observable o1 = createInfiniteObservable(generatedA).subscribeOn(Schedulers.computation()); Observable o2 = createInfiniteObservable(generatedB).subscribeOn(Schedulers.computation()); - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); Observable.zip(o1, o2, new BiFunction() { @Override @@ -1102,7 +1103,7 @@ public void testDownstreamBackpressureRequestsWithInfiniteSyncObservables() { Observable o1 = createInfiniteObservable(generatedA); Observable o2 = createInfiniteObservable(generatedB); - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); Observable.zip(o1, o2, new BiFunction() { @Override @@ -1173,7 +1174,7 @@ Observable ASYNC_OBSERVABLE_OF_INFINITE_INTEGERS(final CountDownLatch l @Override public void subscribe(final Subscriber o) { - BooleanSubscription bs = new BooleanSubscription(); + final BooleanSubscription bs = new BooleanSubscription(); o.onSubscribe(bs); Thread t = new Thread(new Runnable() { @@ -1217,7 +1218,7 @@ public Integer apply(Integer i1, Integer i2) { return i1 + i2; } }); - List expected = new ArrayList<>(); + List expected = new ArrayList(); for (int i = 0; i < 1026; i++) { expected.add(i * 3); } @@ -1273,7 +1274,7 @@ public Integer apply(Integer t1, Integer t2) { @Test public void testZipRequest1() { Observable src = Observable.just(1).subscribeOn(Schedulers.computation()); - TestSubscriber ts = new TestSubscriber<>(1L); + TestSubscriber ts = new TestSubscriber(1L); Observable.zip(src, src, new BiFunction() { @Override diff --git a/src/test/java/io/reactivex/internal/operators/PublisherDelaySubscriptionOtherTest.java b/src/test/java/io/reactivex/internal/operators/PublisherDelaySubscriptionOtherTest.java new file mode 100644 index 0000000000..a3631ed02a --- /dev/null +++ b/src/test/java/io/reactivex/internal/operators/PublisherDelaySubscriptionOtherTest.java @@ -0,0 +1,243 @@ +/** + * 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.internal.operators; + +import java.util.concurrent.atomic.AtomicInteger; + +import org.junit.*; +import org.reactivestreams.Subscription; + +import io.reactivex.Observable; +import io.reactivex.exceptions.TestException; +import io.reactivex.functions.Consumer; +import io.reactivex.subjects.PublishSubject; +import io.reactivex.subscribers.TestSubscriber; + +public class PublisherDelaySubscriptionOtherTest { + @Test + public void testNoPrematureSubscription() { + PublishSubject other = PublishSubject.create(); + + TestSubscriber ts = new TestSubscriber(); + + final AtomicInteger subscribed = new AtomicInteger(); + + Observable.just(1) + .doOnSubscribe(new Consumer() { + @Override + public void accept(Subscription s) { + subscribed.getAndIncrement(); + } + }) + .delaySubscription(other) + .subscribe(ts); + + ts.assertNotComplete(); + ts.assertNoErrors(); + ts.assertNoValues(); + + Assert.assertEquals("Premature subscription", 0, subscribed.get()); + + other.onNext(1); + + Assert.assertEquals("No subscription", 1, subscribed.get()); + + ts.assertValue(1); + ts.assertNoErrors(); + ts.assertComplete(); + } + + @Test + public void testNoMultipleSubscriptions() { + PublishSubject other = PublishSubject.create(); + + TestSubscriber ts = new TestSubscriber(); + + final AtomicInteger subscribed = new AtomicInteger(); + + Observable.just(1) + .doOnSubscribe(new Consumer() { + @Override + public void accept(Subscription s) { + subscribed.getAndIncrement(); + } + }) + .delaySubscription(other) + .subscribe(ts); + + ts.assertNotComplete(); + ts.assertNoErrors(); + ts.assertNoValues(); + + Assert.assertEquals("Premature subscription", 0, subscribed.get()); + + other.onNext(1); + other.onNext(2); + + Assert.assertEquals("No subscription", 1, subscribed.get()); + + ts.assertValue(1); + ts.assertNoErrors(); + ts.assertComplete(); + } + + @Test + public void testCompleteTriggersSubscription() { + PublishSubject other = PublishSubject.create(); + + TestSubscriber ts = new TestSubscriber(); + + final AtomicInteger subscribed = new AtomicInteger(); + + Observable.just(1) + .doOnSubscribe(new Consumer() { + @Override + public void accept(Subscription s) { + subscribed.getAndIncrement(); + } + }) + .delaySubscription(other) + .subscribe(ts); + + ts.assertNotComplete(); + ts.assertNoErrors(); + ts.assertNoValues(); + + Assert.assertEquals("Premature subscription", 0, subscribed.get()); + + other.onComplete(); + + Assert.assertEquals("No subscription", 1, subscribed.get()); + + ts.assertValue(1); + ts.assertNoErrors(); + ts.assertComplete(); + } + + @Test + public void testNoPrematureSubscriptionToError() { + PublishSubject other = PublishSubject.create(); + + TestSubscriber ts = new TestSubscriber(); + + final AtomicInteger subscribed = new AtomicInteger(); + + Observable.error(new TestException()) + .doOnSubscribe(new Consumer() { + @Override + public void accept(Subscription s) { + subscribed.getAndIncrement(); + } + }) + .delaySubscription(other) + .subscribe(ts); + + ts.assertNotComplete(); + ts.assertNoErrors(); + ts.assertNoValues(); + + Assert.assertEquals("Premature subscription", 0, subscribed.get()); + + other.onComplete(); + + Assert.assertEquals("No subscription", 1, subscribed.get()); + + ts.assertNoValues(); + ts.assertNotComplete(); + ts.assertError(TestException.class); + } + + @Test + public void testNoSubscriptionIfOtherErrors() { + PublishSubject other = PublishSubject.create(); + + TestSubscriber ts = new TestSubscriber(); + + final AtomicInteger subscribed = new AtomicInteger(); + + Observable.error(new TestException()) + .doOnSubscribe(new Consumer() { + @Override + public void accept(Subscription s) { + subscribed.getAndIncrement(); + } + }) + .delaySubscription(other) + .subscribe(ts); + + ts.assertNotComplete(); + ts.assertNoErrors(); + ts.assertNoValues(); + + Assert.assertEquals("Premature subscription", 0, subscribed.get()); + + other.onError(new TestException()); + + Assert.assertEquals("Premature subscription", 0, subscribed.get()); + + ts.assertNoValues(); + ts.assertNotComplete(); + ts.assertError(TestException.class); + } + + @Test + public void testBackpressurePassesThrough() { + + PublishSubject other = PublishSubject.create(); + + TestSubscriber ts = new TestSubscriber((Long)null); + + final AtomicInteger subscribed = new AtomicInteger(); + + Observable.just(1, 2, 3, 4, 5) + .doOnSubscribe(new Consumer() { + @Override + public void accept(Subscription s) { + subscribed.getAndIncrement(); + } + }) + .delaySubscription(other) + .subscribe(ts); + + ts.assertNotComplete(); + ts.assertNoErrors(); + ts.assertNoValues(); + + Assert.assertEquals("Premature subscription", 0, subscribed.get()); + + other.onNext(1); + + Assert.assertEquals("No subscription", 1, subscribed.get()); + + Assert.assertFalse("Not unsubscribed from other", other.hasSubscribers()); + + ts.assertNotComplete(); + ts.assertNoErrors(); + ts.assertNoValues(); + + ts.request(1); + ts.assertValue(1); + ts.assertNoErrors(); + ts.assertNotComplete(); + + ts.request(2); + ts.assertValues(1, 2, 3); + ts.assertNoErrors(); + ts.assertNotComplete(); + + ts.request(10); + ts.assertValues(1, 2, 3, 4, 5); + ts.assertNoErrors(); + ts.assertComplete(); + } +} \ No newline at end of file diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpBlockingOperatorLatestTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpBlockingOperatorLatestTest.java index 00c9d9dc6b..67b34f2d6d 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpBlockingOperatorLatestTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpBlockingOperatorLatestTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpBlockingOperatorMostRecentTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpBlockingOperatorMostRecentTest.java index bb169413e4..e4d18cf4ab 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpBlockingOperatorMostRecentTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpBlockingOperatorMostRecentTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpBlockingOperatorNextTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpBlockingOperatorNextTest.java index 0d60e1385f..258e777de3 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpBlockingOperatorNextTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpBlockingOperatorNextTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -26,6 +26,7 @@ import io.reactivex.NbpObservable.*; import io.reactivex.exceptions.TestException; import io.reactivex.internal.disposables.EmptyDisposable; +import io.reactivex.internal.operators.nbp.NbpBlockingOperatorNext; import io.reactivex.observables.nbp.NbpBlockingObservable; import io.reactivex.schedulers.Schedulers; import io.reactivex.subjects.BehaviorSubject; diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpBlockingOperatorToIteratorTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpBlockingOperatorToIteratorTest.java index ae186cfa4f..020b72c4c7 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpBlockingOperatorToIteratorTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpBlockingOperatorToIteratorTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpBufferUntilSubscriberTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpBufferUntilSubscriberTest.java index 1e04f7cc14..585afa1a9f 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpBufferUntilSubscriberTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpBufferUntilSubscriberTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,12 +13,14 @@ package io.reactivex.internal.operators.nbp; +import java.util.List; import java.util.concurrent.*; import java.util.concurrent.atomic.*; import org.junit.*; import io.reactivex.NbpObservable; +import io.reactivex.functions.*; import io.reactivex.schedulers.Schedulers; import io.reactivex.subjects.nbp.NbpPublishSubject; @@ -39,23 +41,32 @@ public void testIssue1677() throws InterruptedException { NbpObservable.fromArray(numbers) .takeUntil(s) .window(50) - .flatMap(integerObservable -> { - return integerObservable - .subscribeOn(Schedulers.computation()) - .map(integer -> { - if (integer >= 5 && completed.compareAndSet(false, true)) { - s.onComplete(); + .flatMap(new Function, NbpObservable>() { + @Override + public NbpObservable apply(NbpObservable integerObservable) { + return integerObservable + .subscribeOn(Schedulers.computation()) + .map(new Function() { + @Override + public Object apply(Integer integer) { + if (integer >= 5 && completed.compareAndSet(false, true)) { + s.onComplete(); + } + // do some work + Math.pow(Math.random(), Math.random()); + return integer * 2; } - // do some work - Math.pow(Math.random(), Math.random()); - return integer * 2; - }); + }); + } }) .toList() - .doOnNext(integers -> { - counter.incrementAndGet(); - latch.countDown(); - innerLatch.countDown(); + .doOnNext(new Consumer>() { + @Override + public void accept(List integers) { + counter.incrementAndGet(); + latch.countDown(); + innerLatch.countDown(); + } }) .subscribe(); if (!innerLatch.await(30, TimeUnit.SECONDS)) diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpCachedObservableTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpCachedObservableTest.java index bafd9465d2..b84f28bbb0 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpCachedObservableTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpCachedObservableTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -25,7 +25,9 @@ import io.reactivex.NbpObservable; import io.reactivex.NbpObservable.*; import io.reactivex.exceptions.TestException; +import io.reactivex.functions.Consumer; import io.reactivex.internal.disposables.EmptyDisposable; +import io.reactivex.internal.operators.nbp.NbpCachedObservable; import io.reactivex.schedulers.Schedulers; import io.reactivex.subscribers.nbp.NbpTestSubscriber; @@ -36,7 +38,7 @@ public void testColdReplayNoBackpressure() { assertFalse("Source is connected!", source.isConnected()); - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); source.subscribe(ts); @@ -78,17 +80,23 @@ public void run() { final CountDownLatch latch = new CountDownLatch(2); // subscribe once - o.subscribe(v -> { - assertEquals("one", v); - System.out.println("v: " + v); - latch.countDown(); + o.subscribe(new Consumer() { + @Override + public void accept(String v) { + assertEquals("one", v); + System.out.println("v: " + v); + latch.countDown(); + } }); // subscribe again - o.subscribe(v -> { - assertEquals("one", v); - System.out.println("v: " + v); - latch.countDown(); + o.subscribe(new Consumer() { + @Override + public void accept(String v) { + assertEquals("one", v); + System.out.println("v: " + v); + latch.countDown(); + } }); if (!latch.await(1000, TimeUnit.MILLISECONDS)) { @@ -109,7 +117,7 @@ public void testUnsubscribeSource() { @Test public void testTake() { - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); NbpCachedObservable cached = NbpCachedObservable.from(NbpObservable.range(1, 100)); cached.take(10).subscribe(ts); @@ -125,7 +133,7 @@ public void testTake() { public void testAsync() { NbpObservable source = NbpObservable.range(1, 10000); for (int i = 0; i < 100; i++) { - NbpTestSubscriber ts1 = new NbpTestSubscriber<>(); + NbpTestSubscriber ts1 = new NbpTestSubscriber(); NbpCachedObservable cached = NbpCachedObservable.from(source); @@ -136,7 +144,7 @@ public void testAsync() { ts1.assertComplete(); assertEquals(10000, ts1.values().size()); - NbpTestSubscriber ts2 = new NbpTestSubscriber<>(); + NbpTestSubscriber ts2 = new NbpTestSubscriber(); cached.observeOn(Schedulers.computation()).subscribe(ts2); ts2.awaitTerminalEvent(2, TimeUnit.SECONDS); @@ -154,14 +162,14 @@ public void testAsyncComeAndGo() { NbpObservable output = cached.observeOn(Schedulers.computation()); - List> list = new ArrayList<>(100); + List> list = new ArrayList>(100); for (int i = 0; i < 100; i++) { - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); list.add(ts); output.skip(i * 10).take(10).subscribe(ts); } - List expected = new ArrayList<>(); + List expected = new ArrayList(); for (int i = 0; i < 10; i++) { expected.add((long)(i - 10)); } @@ -195,7 +203,7 @@ public void accept(NbpSubscriber t) { } }); - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); firehose.cache().observeOn(Schedulers.computation()).takeLast(100).subscribe(ts); ts.awaitTerminalEvent(3, TimeUnit.SECONDS); @@ -212,14 +220,14 @@ public void testValuesAndThenError() { .cache(); - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); source.subscribe(ts); ts.assertValues(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); ts.assertNotComplete(); ts.assertError(TestException.class); - NbpTestSubscriber ts2 = new NbpTestSubscriber<>(); + NbpTestSubscriber ts2 = new NbpTestSubscriber(); source.subscribe(ts2); ts2.assertValues(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); @@ -232,7 +240,12 @@ public void unsafeChildThrows() { final AtomicInteger count = new AtomicInteger(); NbpObservable source = NbpObservable.range(1, 100) - .doOnNext(t -> count.getAndIncrement()) + .doOnNext(new Consumer() { + @Override + public void accept(Integer t) { + count.getAndIncrement(); + } + }) .cache(); NbpTestSubscriber ts = new NbpTestSubscriber() { diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeAmbTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeAmbTest.java index b35466cb28..b4b7516993 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeAmbTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeAmbTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,13 +13,12 @@ package io.reactivex.internal.operators.nbp; -import static org.junit.Assert.assertEquals; +import static org.junit.Assert.*; import static org.mockito.Mockito.*; import java.io.IOException; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicLong; -import java.util.function.Consumer; import org.junit.*; import org.mockito.InOrder; @@ -27,7 +26,9 @@ import io.reactivex.*; import io.reactivex.NbpObservable.*; import io.reactivex.disposables.*; +import io.reactivex.functions.Consumer; import io.reactivex.schedulers.*; +import io.reactivex.subjects.nbp.NbpPublishSubject; import io.reactivex.subscribers.nbp.NbpTestSubscriber; public class NbpOnSubscribeAmbTest { @@ -53,17 +54,24 @@ public void accept(final NbpSubscriber NbpSubscriber) { long delay = interval; for (final String value : values) { - parentSubscription.add(innerScheduler.schedule(() -> - NbpSubscriber.onNext(value) + parentSubscription.add(innerScheduler.schedule(new Runnable() { + @Override + public void run() { + NbpSubscriber.onNext(value); + } + } , delay, TimeUnit.MILLISECONDS)); delay += interval; } - parentSubscription.add(innerScheduler.schedule(() -> { - if (e == null) { - NbpSubscriber.onComplete(); - } else { - NbpSubscriber.onError(e); - } + parentSubscription.add(innerScheduler.schedule(new Runnable() { + @Override + public void run() { + if (e == null) { + NbpSubscriber.onComplete(); + } else { + NbpSubscriber.onError(e); + } + } }, delay, TimeUnit.MILLISECONDS)); } }); @@ -78,6 +86,7 @@ public void testAmb() { NbpObservable observable3 = createObservable(new String[] { "3", "33", "333", "3333" }, 3000, null); + @SuppressWarnings("unchecked") NbpObservable o = NbpObservable.amb(observable1, observable2, observable3); @@ -106,6 +115,7 @@ public void testAmb2() { NbpObservable observable3 = createObservable(new String[] {}, 3000, new IOException("fake exception")); + @SuppressWarnings("unchecked") NbpObservable o = NbpObservable.amb(observable1, observable2, observable3); @@ -132,6 +142,7 @@ public void testAmb3() { NbpObservable observable3 = createObservable(new String[] { "3" }, 3000, null); + @SuppressWarnings("unchecked") NbpObservable o = NbpObservable.amb(observable1, observable2, observable3); @@ -144,10 +155,16 @@ public void testAmb3() { inOrder.verifyNoMoreInteractions(); } + @SuppressWarnings("unchecked") @Test public void testSubscriptionOnlyHappensOnce() throws InterruptedException { final AtomicLong count = new AtomicLong(); - Consumer incrementer = s -> count.incrementAndGet(); + Consumer incrementer = new Consumer() { + @Override + public void accept(Disposable s) { + count.incrementAndGet(); + } + }; //this aync stream should emit first NbpObservable o1 = NbpObservable.just(1).doOnSubscribe(incrementer) @@ -155,7 +172,7 @@ public void testSubscriptionOnlyHappensOnce() throws InterruptedException { //this stream emits second NbpObservable o2 = NbpObservable.just(1).doOnSubscribe(incrementer) .delay(100, TimeUnit.MILLISECONDS).subscribeOn(Schedulers.computation()); - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); NbpObservable.amb(o1, o2).subscribe(ts); ts.awaitTerminalEvent(5, TimeUnit.SECONDS); ts.assertNoErrors(); @@ -169,14 +186,39 @@ public void testSynchronousSources() { // then second NbpObservable does not get subscribed to before first // subscription completes hence first NbpObservable emits result through // amb - int result = NbpObservable.just(1).doOnNext(t -> { - try { - Thread.sleep(100); - } catch (InterruptedException e) { - // - } + int result = NbpObservable.just(1).doOnNext(new Consumer() { + @Override + public void accept(Integer t) { + try { + Thread.sleep(100); + } catch (InterruptedException e) { + // + } + } }).ambWith(NbpObservable.just(2)).toBlocking().single(); assertEquals(1, result); } - + + @SuppressWarnings("unchecked") + @Test + public void testAmbCancelsOthers() { + NbpPublishSubject source1 = NbpPublishSubject.create(); + NbpPublishSubject source2 = NbpPublishSubject.create(); + NbpPublishSubject source3 = NbpPublishSubject.create(); + + NbpTestSubscriber ts = new NbpTestSubscriber(); + + NbpObservable.amb(source1, source2, source3).subscribe(ts); + + assertTrue("Source 1 doesn't have subscribers!", source1.hasSubscribers()); + assertTrue("Source 2 doesn't have subscribers!", source2.hasSubscribers()); + assertTrue("Source 3 doesn't have subscribers!", source3.hasSubscribers()); + + source1.onNext(1); + + assertTrue("Source 1 doesn't have subscribers!", source1.hasSubscribers()); + assertFalse("Source 2 still has subscribers!", source2.hasSubscribers()); + assertFalse("Source 2 still has subscribers!", source3.hasSubscribers()); + + } } \ No newline at end of file diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeCombineLatestTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeCombineLatestTest.java index f5389ab061..4e6fd54f81 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeCombineLatestTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeCombineLatestTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -20,7 +20,6 @@ import java.util.*; import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.*; import org.junit.Test; import org.mockito.*; @@ -31,6 +30,7 @@ import io.reactivex.schedulers.Schedulers; import io.reactivex.subjects.nbp.NbpPublishSubject; import io.reactivex.subscribers.nbp.NbpTestSubscriber; +import io.reactivex.Optional; public class NbpOnSubscribeCombineLatestTest { @@ -41,8 +41,11 @@ public void testCombineLatestWithFunctionThatThrowsAnException() { NbpPublishSubject w1 = NbpPublishSubject.create(); NbpPublishSubject w2 = NbpPublishSubject.create(); - NbpObservable combined = NbpObservable.combineLatest(w1, w2, (v1, v2) -> { - throw new RuntimeException("I don't work."); + NbpObservable combined = NbpObservable.combineLatest(w1, w2, new BiFunction() { + @Override + public String apply(String v1, String v2) { + throw new RuntimeException("I don't work."); + } }); combined.subscribe(w); @@ -214,28 +217,41 @@ public void testCombineLatest3TypesB() { } private Function3 getConcat3StringsCombineLatestFunction() { - Function3 combineLatestFunction = (a1, a2, a3) -> { - if (a1 == null) { - a1 = ""; - } - if (a2 == null) { - a2 = ""; - } - if (a3 == null) { - a3 = ""; + Function3 combineLatestFunction = new Function3() { + @Override + public String apply(String a1, String a2, String a3) { + if (a1 == null) { + a1 = ""; + } + if (a2 == null) { + a2 = ""; + } + if (a3 == null) { + a3 = ""; + } + return a1 + a2 + a3; } - return a1 + a2 + a3; }; return combineLatestFunction; } private BiFunction getConcatStringIntegerCombineLatestFunction() { - BiFunction combineLatestFunction = (s, i) -> getStringValue(s) + getStringValue(i); + BiFunction combineLatestFunction = new BiFunction() { + @Override + public String apply(String s, Integer i) { + return getStringValue(s) + getStringValue(i); + } + }; return combineLatestFunction; } private Function3 getConcatStringIntegerIntArrayCombineLatestFunction() { - return (s, i, iArray) -> getStringValue(s) + getStringValue(i) + getStringValue(iArray); + return new Function3() { + @Override + public String apply(String s, Integer i, int[] iArray) { + return getStringValue(s) + getStringValue(i) + getStringValue(iArray); + } + }; } private static String getStringValue(Object o) { @@ -250,7 +266,12 @@ private static String getStringValue(Object o) { } } - BiFunction or = (t1, t2) -> t1 | t2; + BiFunction or = new BiFunction() { + @Override + public Integer apply(Integer t1, Integer t2) { + return t1 | t2; + } + }; @Test public void combineSimple() { @@ -414,8 +435,8 @@ public List apply(Object[] args) { }; for (int i = 1; i <= n; i++) { System.out.println("test1ToNSources: " + i + " sources"); - List> sources = new ArrayList<>(); - List values = new ArrayList<>(); + List> sources = new ArrayList>(); + List values = new ArrayList(); for (int j = 0; j < i; j++) { sources.add(NbpObservable.just(j)); values.add(j); @@ -445,8 +466,8 @@ public List apply(Object[] args) { }; for (int i = 1; i <= n; i++) { System.out.println("test1ToNSourcesScheduled: " + i + " sources"); - List> sources = new ArrayList<>(); - List values = new ArrayList<>(); + List> sources = new ArrayList>(); + List values = new ArrayList(); for (int j = 0; j < i; j++) { sources.add(NbpObservable.just(j).subscribeOn(Schedulers.io())); values.add(j); @@ -494,7 +515,12 @@ public void test2SourcesOverload() { NbpObservable s2 = NbpObservable.just(2); NbpObservable> result = NbpObservable.combineLatest(s1, s2, - (t1, t2) -> Arrays.asList(t1, t2)); + new BiFunction>() { + @Override + public List apply(Integer t1, Integer t2) { + return Arrays.asList(t1, t2); + } + }); NbpSubscriber o = TestHelper.mockNbpSubscriber(); @@ -512,7 +538,12 @@ public void test3SourcesOverload() { NbpObservable s3 = NbpObservable.just(3); NbpObservable> result = NbpObservable.combineLatest(s1, s2, s3, - (Function3>) (t1, t2, t3) -> Arrays.asList(t1, t2, t3)); + new Function3>() { + @Override + public List apply(Integer t1, Integer t2, Integer t3) { + return Arrays.asList(t1, t2, t3); + } + }); NbpSubscriber o = TestHelper.mockNbpSubscriber(); @@ -711,16 +742,24 @@ public void testWithCombineLatestIssue1717() throws InterruptedException { final int SIZE = 2000; NbpObservable timer = NbpObservable.interval(0, 1, TimeUnit.MILLISECONDS) .observeOn(Schedulers.newThread()) - .doOnEach(n -> { - // System.out.println(n); - if (count.incrementAndGet() >= SIZE) { - latch.countDown(); - } + .doOnEach(new Consumer>>() { + @Override + public void accept(Try> n) { + // System.out.println(n); + if (count.incrementAndGet() >= SIZE) { + latch.countDown(); + } + } }).take(SIZE); - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); - NbpObservable.combineLatest(timer, NbpObservable. never(), (t1, t2) -> t1).subscribe(ts); + NbpObservable.combineLatest(timer, NbpObservable. never(), new BiFunction() { + @Override + public Long apply(Long t1, Integer t2) { + return t1; + } + }).subscribe(ts); if (!latch.await(SIZE + 1000, TimeUnit.MILLISECONDS)) { fail("timed out"); diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeDeferTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeDeferTest.java index 2ab57d39fb..1bd59fe27c 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeDeferTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeDeferTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -16,13 +16,12 @@ import static org.mockito.Matchers.any; import static org.mockito.Mockito.*; -import java.util.function.Supplier; - import org.junit.Test; import io.reactivex.*; import io.reactivex.NbpObservable.NbpSubscriber; import io.reactivex.exceptions.TestException; +import io.reactivex.functions.Supplier; @SuppressWarnings("unchecked") public class NbpOnSubscribeDeferTest { diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeDelaySubscriptionOtherTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeDelaySubscriptionOtherTest.java new file mode 100644 index 0000000000..7e633495f5 --- /dev/null +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeDelaySubscriptionOtherTest.java @@ -0,0 +1,193 @@ +/** + * 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.internal.operators.nbp; + +import java.util.concurrent.atomic.AtomicInteger; + +import org.junit.*; + +import io.reactivex.NbpObservable; +import io.reactivex.disposables.Disposable; +import io.reactivex.exceptions.TestException; +import io.reactivex.functions.Consumer; +import io.reactivex.subjects.nbp.NbpPublishSubject; +import io.reactivex.subscribers.nbp.NbpTestSubscriber; + +public class NbpOnSubscribeDelaySubscriptionOtherTest { + @Test + public void testNoPrematureSubscription() { + NbpPublishSubject other = NbpPublishSubject.create(); + + NbpTestSubscriber ts = new NbpTestSubscriber(); + + final AtomicInteger subscribed = new AtomicInteger(); + + NbpObservable.just(1) + .doOnSubscribe(new Consumer() { + @Override + public void accept(Disposable d) { + subscribed.getAndIncrement(); + } + }) + .delaySubscription(other) + .subscribe(ts); + + ts.assertNotComplete(); + ts.assertNoErrors(); + ts.assertNoValues(); + + Assert.assertEquals("Premature subscription", 0, subscribed.get()); + + other.onNext(1); + + Assert.assertEquals("No subscription", 1, subscribed.get()); + + ts.assertValue(1); + ts.assertNoErrors(); + ts.assertComplete(); + } + + @Test + public void testNoMultipleSubscriptions() { + NbpPublishSubject other = NbpPublishSubject.create(); + + NbpTestSubscriber ts = new NbpTestSubscriber(); + + final AtomicInteger subscribed = new AtomicInteger(); + + NbpObservable.just(1) + .doOnSubscribe(new Consumer() { + @Override + public void accept(Disposable d) { + subscribed.getAndIncrement(); + } + }) + .delaySubscription(other) + .subscribe(ts); + + ts.assertNotComplete(); + ts.assertNoErrors(); + ts.assertNoValues(); + + Assert.assertEquals("Premature subscription", 0, subscribed.get()); + + other.onNext(1); + other.onNext(2); + + Assert.assertEquals("No subscription", 1, subscribed.get()); + + ts.assertValue(1); + ts.assertNoErrors(); + ts.assertComplete(); + } + + @Test + public void testCompleteTriggersSubscription() { + NbpPublishSubject other = NbpPublishSubject.create(); + + NbpTestSubscriber ts = new NbpTestSubscriber(); + + final AtomicInteger subscribed = new AtomicInteger(); + + NbpObservable.just(1) + .doOnSubscribe(new Consumer() { + @Override + public void accept(Disposable d) { + subscribed.getAndIncrement(); + } + }) + .delaySubscription(other) + .subscribe(ts); + + ts.assertNotComplete(); + ts.assertNoErrors(); + ts.assertNoValues(); + + Assert.assertEquals("Premature subscription", 0, subscribed.get()); + + other.onComplete(); + + Assert.assertEquals("No subscription", 1, subscribed.get()); + + ts.assertValue(1); + ts.assertNoErrors(); + ts.assertComplete(); + } + + @Test + public void testNoPrematureSubscriptionToError() { + NbpPublishSubject other = NbpPublishSubject.create(); + + NbpTestSubscriber ts = new NbpTestSubscriber(); + + final AtomicInteger subscribed = new AtomicInteger(); + + NbpObservable.error(new TestException()) + .doOnSubscribe(new Consumer() { + @Override + public void accept(Disposable d) { + subscribed.getAndIncrement(); + } + }) + .delaySubscription(other) + .subscribe(ts); + + ts.assertNotComplete(); + ts.assertNoErrors(); + ts.assertNoValues(); + + Assert.assertEquals("Premature subscription", 0, subscribed.get()); + + other.onComplete(); + + Assert.assertEquals("No subscription", 1, subscribed.get()); + + ts.assertNoValues(); + ts.assertNotComplete(); + ts.assertError(TestException.class); + } + + @Test + public void testNoSubscriptionIfOtherErrors() { + NbpPublishSubject other = NbpPublishSubject.create(); + + NbpTestSubscriber ts = new NbpTestSubscriber(); + + final AtomicInteger subscribed = new AtomicInteger(); + + NbpObservable.error(new TestException()) + .doOnSubscribe(new Consumer() { + @Override + public void accept(Disposable d) { + subscribed.getAndIncrement(); + } + }) + .delaySubscription(other) + .subscribe(ts); + + ts.assertNotComplete(); + ts.assertNoErrors(); + ts.assertNoValues(); + + Assert.assertEquals("Premature subscription", 0, subscribed.get()); + + other.onError(new TestException()); + + Assert.assertEquals("Premature subscription", 0, subscribed.get()); + + ts.assertNoValues(); + ts.assertNotComplete(); + ts.assertError(TestException.class); + } +} \ No newline at end of file diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeFromIterableTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeFromIterableTest.java index 77887da2cd..6c5b9fcbaf 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeFromIterableTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeFromIterableTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -112,7 +112,7 @@ public void testObservableFromIterable() { public void testNoBackpressure() { NbpObservable o = NbpObservable.fromIterable(Arrays.asList(1, 2, 3, 4, 5)); - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); o.subscribe(ts); @@ -125,7 +125,7 @@ public void testSubscribeMultipleTimes() { NbpObservable o = NbpObservable.fromIterable(Arrays.asList(1, 2, 3)); for (int i = 0; i < 10; i++) { - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); o.subscribe(ts); diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeRangeTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeRangeTest.java index b353d2e874..4b4f5ed449 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeRangeTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeRangeTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -23,6 +23,7 @@ import io.reactivex.*; import io.reactivex.NbpObservable.NbpSubscriber; +import io.reactivex.functions.Consumer; import io.reactivex.subscribers.nbp.NbpTestSubscriber; public class NbpOnSubscribeRangeTest { @@ -47,7 +48,12 @@ public void testRangeUnsubscribe() { final AtomicInteger count = new AtomicInteger(); - NbpObservable.range(1, 1000).doOnNext(t1 -> count.incrementAndGet()) + NbpObservable.range(1, 1000).doOnNext(new Consumer() { + @Override + public void accept(Integer t1) { + count.incrementAndGet(); + } + }) .take(3).subscribe(NbpObserver); verify(NbpObserver, times(1)).onNext(1); @@ -86,14 +92,14 @@ public void testRangeWithOverflow5() { @Test public void testNoBackpressure() { - ArrayList list = new ArrayList<>(Observable.bufferSize() * 2); + ArrayList list = new ArrayList(Observable.bufferSize() * 2); for (int i = 1; i <= Observable.bufferSize() * 2 + 1; i++) { list.add(i); } NbpObservable o = NbpObservable.range(1, list.size()); - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); o.subscribe(ts); @@ -130,7 +136,7 @@ public void onNext(Integer t) { @Test(timeout = 1000) public void testNearMaxValueWithoutBackpressure() { - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); NbpObservable.range(Integer.MAX_VALUE - 1, 2).subscribe(ts); ts.assertComplete(); diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeRefCountTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeRefCountTest.java index cb2947b30d..d0c57576ec 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeRefCountTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeRefCountTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -27,6 +27,7 @@ import io.reactivex.*; import io.reactivex.NbpObservable.*; import io.reactivex.disposables.Disposable; +import io.reactivex.functions.*; import io.reactivex.internal.subscribers.nbp.NbpCancelledSubscriber; import io.reactivex.schedulers.*; import io.reactivex.subjects.nbp.NbpReplaySubject; @@ -39,12 +40,27 @@ public void testRefCountAsync() { final AtomicInteger subscribeCount = new AtomicInteger(); final AtomicInteger nextCount = new AtomicInteger(); NbpObservable r = NbpObservable.interval(0, 5, TimeUnit.MILLISECONDS) - .doOnSubscribe(s -> subscribeCount.incrementAndGet()) - .doOnNext(l -> nextCount.incrementAndGet()) + .doOnSubscribe(new Consumer() { + @Override + public void accept(Disposable s) { + subscribeCount.incrementAndGet(); + } + }) + .doOnNext(new Consumer() { + @Override + public void accept(Long l) { + nextCount.incrementAndGet(); + } + }) .publish().refCount(); final AtomicInteger receivedCount = new AtomicInteger(); - Disposable s1 = r.subscribe(l -> receivedCount.incrementAndGet()); + Disposable s1 = r.subscribe(new Consumer() { + @Override + public void accept(Long l) { + receivedCount.incrementAndGet(); + } + }); Disposable s2 = r.subscribe(); @@ -71,12 +87,27 @@ public void testRefCountSynchronous() { final AtomicInteger subscribeCount = new AtomicInteger(); final AtomicInteger nextCount = new AtomicInteger(); NbpObservable r = NbpObservable.just(1, 2, 3, 4, 5, 6, 7, 8, 9) - .doOnSubscribe(s -> subscribeCount.incrementAndGet()) - .doOnNext(l -> nextCount.incrementAndGet()) + .doOnSubscribe(new Consumer() { + @Override + public void accept(Disposable s) { + subscribeCount.incrementAndGet(); + } + }) + .doOnNext(new Consumer() { + @Override + public void accept(Integer l) { + nextCount.incrementAndGet(); + } + }) .publish().refCount(); final AtomicInteger receivedCount = new AtomicInteger(); - Disposable s1 = r.subscribe(l -> receivedCount.incrementAndGet()); + Disposable s1 = r.subscribe(new Consumer() { + @Override + public void accept(Integer l) { + receivedCount.incrementAndGet(); + } + }); Disposable s2 = r.subscribe(); @@ -102,15 +133,23 @@ public void testRefCountSynchronous() { public void testRefCountSynchronousTake() { final AtomicInteger nextCount = new AtomicInteger(); NbpObservable r = NbpObservable.just(1, 2, 3, 4, 5, 6, 7, 8, 9) - .doOnNext(l -> { - System.out.println("onNext --------> " + l); - nextCount.incrementAndGet(); + .doOnNext(new Consumer() { + @Override + public void accept(Integer l) { + System.out.println("onNext --------> " + l); + nextCount.incrementAndGet(); + } }) .take(4) .publish().refCount(); final AtomicInteger receivedCount = new AtomicInteger(); - r.subscribe(l -> receivedCount.incrementAndGet()); + r.subscribe(new Consumer() { + @Override + public void accept(Integer l) { + receivedCount.incrementAndGet(); + } + }); System.out.println("onNext: " + nextCount.get()); @@ -123,21 +162,27 @@ public void testRepeat() { final AtomicInteger subscribeCount = new AtomicInteger(); final AtomicInteger unsubscribeCount = new AtomicInteger(); NbpObservable r = NbpObservable.interval(0, 1, TimeUnit.MILLISECONDS) - .doOnSubscribe(s -> { - System.out.println("******************************* Subscribe received"); - // when we are subscribed - subscribeCount.incrementAndGet(); + .doOnSubscribe(new Consumer() { + @Override + public void accept(Disposable s) { + System.out.println("******************************* Subscribe received"); + // when we are subscribed + subscribeCount.incrementAndGet(); + } }) - .doOnCancel(() -> { - System.out.println("******************************* Unsubscribe received"); - // when we are unsubscribed - unsubscribeCount.incrementAndGet(); + .doOnCancel(new Runnable() { + @Override + public void run() { + System.out.println("******************************* Unsubscribe received"); + // when we are unsubscribed + unsubscribeCount.incrementAndGet(); + } }) .publish().refCount(); for (int i = 0; i < 10; i++) { - NbpTestSubscriber ts1 = new NbpTestSubscriber<>(); - NbpTestSubscriber ts2 = new NbpTestSubscriber<>(); + NbpTestSubscriber ts1 = new NbpTestSubscriber(); + NbpTestSubscriber ts2 = new NbpTestSubscriber(); r.subscribe(ts1); r.subscribe(ts2); try { @@ -162,18 +207,24 @@ public void testConnectUnsubscribe() throws InterruptedException { final CountDownLatch subscribeLatch = new CountDownLatch(1); NbpObservable o = synchronousInterval() - .doOnSubscribe(s -> { - System.out.println("******************************* Subscribe received"); - // when we are subscribed - subscribeLatch.countDown(); + .doOnSubscribe(new Consumer() { + @Override + public void accept(Disposable s) { + System.out.println("******************************* Subscribe received"); + // when we are subscribed + subscribeLatch.countDown(); + } }) - .doOnCancel(() -> { - System.out.println("******************************* Unsubscribe received"); - // when we are unsubscribed - unsubscribeLatch.countDown(); + .doOnCancel(new Runnable() { + @Override + public void run() { + System.out.println("******************************* Unsubscribe received"); + // when we are unsubscribed + unsubscribeLatch.countDown(); + } }); - NbpTestSubscriber s = new NbpTestSubscriber<>(); + NbpTestSubscriber s = new NbpTestSubscriber(); o.publish().refCount().subscribeOn(Schedulers.newThread()).subscribe(s); System.out.println("send unsubscribe"); // wait until connected @@ -202,17 +253,23 @@ public void testConnectUnsubscribeRaceConditionLoop() throws InterruptedExceptio public void testConnectUnsubscribeRaceCondition() throws InterruptedException { final AtomicInteger subUnsubCount = new AtomicInteger(); NbpObservable o = synchronousInterval() - .doOnCancel(() -> { - System.out.println("******************************* Unsubscribe received"); - // when we are unsubscribed - subUnsubCount.decrementAndGet(); + .doOnCancel(new Runnable() { + @Override + public void run() { + System.out.println("******************************* Unsubscribe received"); + // when we are unsubscribed + subUnsubCount.decrementAndGet(); + } }) - .doOnSubscribe(s -> { - System.out.println("******************************* SUBSCRIBE received"); - subUnsubCount.incrementAndGet(); + .doOnSubscribe(new Consumer() { + @Override + public void accept(Disposable s) { + System.out.println("******************************* SUBSCRIBE received"); + subUnsubCount.incrementAndGet(); + } }); - NbpTestSubscriber s = new NbpTestSubscriber<>(); + NbpTestSubscriber s = new NbpTestSubscriber(); o.publish().refCount().subscribeOn(Schedulers.computation()).subscribe(s); System.out.println("send unsubscribe"); @@ -233,18 +290,26 @@ public void testConnectUnsubscribeRaceCondition() throws InterruptedException { } private NbpObservable synchronousInterval() { - return NbpObservable.create(NbpSubscriber -> { - AtomicBoolean cancel = new AtomicBoolean(); - NbpSubscriber.onSubscribe(() -> cancel.set(true)); - for (;;) { - if (cancel.get()) { - break; - } - try { - Thread.sleep(100); - } catch (InterruptedException e) { + return NbpObservable.create(new NbpOnSubscribe() { + @Override + public void accept(NbpSubscriber NbpSubscriber) { + final AtomicBoolean cancel = new AtomicBoolean(); + NbpSubscriber.onSubscribe(new Disposable() { + @Override + public void dispose() { + cancel.set(true); + } + }); + for (;;) { + if (cancel.get()) { + break; + } + try { + Thread.sleep(100); + } catch (InterruptedException e) { + } + NbpSubscriber.onNext(1L); } - NbpSubscriber.onNext(1L); } }); } @@ -257,8 +322,11 @@ public void onlyFirstShouldSubscribeAndLastUnsubscribe() { @Override public void accept(NbpSubscriber NbpObserver) { subscriptionCount.incrementAndGet(); - NbpObserver.onSubscribe(() -> { - unsubscriptionCount.incrementAndGet(); + NbpObserver.onSubscribe(new Disposable() { + @Override + public void dispose() { + unsubscriptionCount.incrementAndGet(); + } }); } }); @@ -283,8 +351,13 @@ public void testRefCount() { NbpObservable interval = NbpObservable.interval(100, TimeUnit.MILLISECONDS, s).publish().refCount(); // subscribe list1 - final List list1 = new ArrayList<>(); - Disposable s1 = interval.subscribe(t1 -> list1.add(t1)); + final List list1 = new ArrayList(); + Disposable s1 = interval.subscribe(new Consumer() { + @Override + public void accept(Long t1) { + list1.add(t1); + } + }); s.advanceTimeBy(200, TimeUnit.MILLISECONDS); @@ -293,8 +366,13 @@ public void testRefCount() { assertEquals(1L, list1.get(1).longValue()); // subscribe list2 - final List list2 = new ArrayList<>(); - Disposable s2 = interval.subscribe(t1 -> list2.add(t1)); + final List list2 = new ArrayList(); + Disposable s2 = interval.subscribe(new Consumer() { + @Override + public void accept(Long t1) { + list2.add(t1); + } + }); s.advanceTimeBy(300, TimeUnit.MILLISECONDS); @@ -333,8 +411,13 @@ public void testRefCount() { // subscribing a new one should start over because the source should have been unsubscribed // subscribe list3 - final List list3 = new ArrayList<>(); - interval.subscribe(t1 -> list3.add(t1)); + final List list3 = new ArrayList(); + interval.subscribe(new Consumer() { + @Override + public void accept(Long t1) { + list3.add(t1); + } + }); s.advanceTimeBy(200, TimeUnit.MILLISECONDS); @@ -391,11 +474,16 @@ public void testAlreadyUnsubscribedInterleavesWithClient() { public void testConnectDisconnectConnectAndSubjectState() { NbpObservable o1 = NbpObservable.just(10); NbpObservable o2 = NbpObservable.just(20); - NbpObservable combined = NbpObservable.combineLatest(o1, o2, (t1, t2) -> t1 + t2) - .publish().refCount(); + NbpObservable combined = NbpObservable.combineLatest(o1, o2, new BiFunction() { + @Override + public Integer apply(Integer t1, Integer t2) { + return t1 + t2; + } + }) + .publish().refCount(); - NbpTestSubscriber ts1 = new NbpTestSubscriber<>(); - NbpTestSubscriber ts2 = new NbpTestSubscriber<>(); + NbpTestSubscriber ts1 = new NbpTestSubscriber(); + NbpTestSubscriber ts2 = new NbpTestSubscriber(); combined.subscribe(ts1); combined.subscribe(ts2); @@ -414,37 +502,61 @@ public void testUpstreamErrorAllowsRetry() throws InterruptedException { final AtomicInteger intervalSubscribed = new AtomicInteger(); NbpObservable interval = NbpObservable.interval(200,TimeUnit.MILLISECONDS) - .doOnSubscribe(s -> { - System.out.println("Subscribing to interval " + intervalSubscribed.incrementAndGet()); - } + .doOnSubscribe(new Consumer() { + @Override + public void accept(Disposable s) { + System.out.println("Subscribing to interval " + intervalSubscribed.incrementAndGet()); + } + } ) - .flatMap(t1 -> { - return NbpObservable.defer(() -> { - return NbpObservable.error(new Exception("Some exception")); - }); + .flatMap(new Function>() { + @Override + public NbpObservable apply(Long t1) { + return NbpObservable.defer(new Supplier>() { + @Override + public NbpObservable get() { + return NbpObservable.error(new Exception("Some exception")); + } + }); + } }) - .onErrorResumeNext(t1 -> { - return NbpObservable.error(t1); + .onErrorResumeNext(new Function>() { + @Override + public NbpObservable apply(Throwable t1) { + return NbpObservable.error(t1); + } }) .publish() .refCount(); interval - .doOnError(t1 -> { - System.out.println("NbpSubscriber 1 onError: " + t1); + .doOnError(new Consumer() { + @Override + public void accept(Throwable t1) { + System.out.println("NbpSubscriber 1 onError: " + t1); + } }) .retry(5) - .subscribe(t1 -> { - System.out.println("NbpSubscriber 1: " + t1); + .subscribe(new Consumer() { + @Override + public void accept(String t1) { + System.out.println("NbpSubscriber 1: " + t1); + } }); Thread.sleep(100); interval - .doOnError(t1 -> { - System.out.println("NbpSubscriber 2 onError: " + t1); + .doOnError(new Consumer() { + @Override + public void accept(Throwable t1) { + System.out.println("NbpSubscriber 2 onError: " + t1); + } }) .retry(5) - .subscribe(t1 -> { - System.out.println("NbpSubscriber 2: " + t1); + .subscribe(new Consumer() { + @Override + public void accept(String t1) { + System.out.println("NbpSubscriber 2: " + t1); + } }); Thread.sleep(1300); diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeTimerTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeTimerTest.java index 8f258334ed..3dd4b1761f 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeTimerTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeTimerTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -57,7 +57,7 @@ public void testTimerOnce() { @Test public void testTimerPeriodically() { - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); NbpObservable.interval(100, 100, TimeUnit.MILLISECONDS, scheduler).subscribe(ts); @@ -84,7 +84,7 @@ public void testTimerPeriodically() { @Test public void testInterval() { NbpObservable w = NbpObservable.interval(1, TimeUnit.SECONDS, scheduler); - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); w.subscribe(ts); ts.assertNoValues(); @@ -109,8 +109,8 @@ public void testInterval() { public void testWithMultipleSubscribersStartingAtSameTime() { NbpObservable w = NbpObservable.interval(1, TimeUnit.SECONDS, scheduler); - NbpTestSubscriber ts1 = new NbpTestSubscriber<>(); - NbpTestSubscriber ts2 = new NbpTestSubscriber<>(); + NbpTestSubscriber ts1 = new NbpTestSubscriber(); + NbpTestSubscriber ts2 = new NbpTestSubscriber(); w.subscribe(ts1); w.subscribe(ts2); @@ -146,7 +146,7 @@ public void testWithMultipleSubscribersStartingAtSameTime() { public void testWithMultipleStaggeredSubscribers() { NbpObservable w = NbpObservable.interval(1, TimeUnit.SECONDS, scheduler); - NbpTestSubscriber ts1 = new NbpTestSubscriber<>(); + NbpTestSubscriber ts1 = new NbpTestSubscriber(); w.subscribe(ts1); @@ -154,7 +154,7 @@ public void testWithMultipleStaggeredSubscribers() { scheduler.advanceTimeTo(2, TimeUnit.SECONDS); - NbpTestSubscriber ts2 = new NbpTestSubscriber<>(); + NbpTestSubscriber ts2 = new NbpTestSubscriber(); w.subscribe(ts2); @@ -186,7 +186,7 @@ public void testWithMultipleStaggeredSubscribers() { public void testWithMultipleStaggeredSubscribersAndPublish() { NbpConnectableObservable w = NbpObservable.interval(1, TimeUnit.SECONDS, scheduler).publish(); - NbpTestSubscriber ts1 = new NbpTestSubscriber<>(); + NbpTestSubscriber ts1 = new NbpTestSubscriber(); w.subscribe(ts1); w.connect(); @@ -195,7 +195,7 @@ public void testWithMultipleStaggeredSubscribersAndPublish() { scheduler.advanceTimeTo(2, TimeUnit.SECONDS); - NbpTestSubscriber ts2 = new NbpTestSubscriber<>(); + NbpTestSubscriber ts2 = new NbpTestSubscriber(); w.subscribe(ts2); ts1.assertValues(0L, 1L); diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeToObservableFutureTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeToObservableFutureTest.java index 6719f664c0..c67b253b48 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeToObservableFutureTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeToObservableFutureTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -37,7 +37,7 @@ public void testSuccess() throws Exception { NbpSubscriber o = TestHelper.mockNbpSubscriber(); - NbpTestSubscriber ts = new NbpTestSubscriber<>(o); + NbpTestSubscriber ts = new NbpTestSubscriber(o); NbpObservable.fromFuture(future).subscribe(ts); @@ -58,7 +58,7 @@ public void testFailure() throws Exception { NbpSubscriber o = TestHelper.mockNbpSubscriber(); - NbpTestSubscriber ts = new NbpTestSubscriber<>(o); + NbpTestSubscriber ts = new NbpTestSubscriber(o); NbpObservable.fromFuture(future).subscribe(ts); @@ -79,7 +79,7 @@ public void testCancelledBeforeSubscribe() throws Exception { NbpSubscriber o = TestHelper.mockNbpSubscriber(); - NbpTestSubscriber ts = new NbpTestSubscriber<>(o); + NbpTestSubscriber ts = new NbpTestSubscriber(o); ts.dispose(); NbpObservable.fromFuture(future).subscribe(ts); @@ -125,7 +125,7 @@ public Object get(long timeout, TimeUnit unit) throws InterruptedException, Exec NbpSubscriber o = TestHelper.mockNbpSubscriber(); - NbpTestSubscriber ts = new NbpTestSubscriber<>(o); + NbpTestSubscriber ts = new NbpTestSubscriber(o); NbpObservable futureObservable = NbpObservable.fromFuture(future); futureObservable.subscribeOn(Schedulers.computation()).subscribe(ts); diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeUsingTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeUsingTest.java index d806259a1d..a223107dac 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeUsingTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOnSubscribeUsingTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -17,15 +17,15 @@ import static org.mockito.Mockito.*; import java.util.*; -import java.util.function.*; import org.junit.*; import org.mockito.InOrder; import io.reactivex.*; -import io.reactivex.NbpObservable.NbpSubscriber; +import io.reactivex.NbpObservable.*; import io.reactivex.disposables.*; import io.reactivex.exceptions.TestException; +import io.reactivex.functions.*; public class NbpOnSubscribeUsingTest { @@ -67,10 +67,18 @@ private void performTestUsing(boolean disposeEagerly) { final Resource resource = mock(Resource.class); when(resource.getTextFromWeb()).thenReturn("Hello world!"); - Supplier resourceFactory = () -> resource; + Supplier resourceFactory = new Supplier() { + @Override + public Resource get() { + return resource; + } + }; - Function> observableFactory = res -> { - return NbpObservable.fromArray(res.getTextFromWeb().split(" ")); + Function> observableFactory = new Function>() { + @Override + public NbpObservable apply(Resource res) { + return NbpObservable.fromArray(res.getTextFromWeb().split(" ")); + } }; NbpSubscriber NbpObserver = TestHelper.mockNbpSubscriber(); @@ -126,8 +134,11 @@ public void dispose() { } }; - Function> observableFactory = res -> { - return NbpObservable.fromArray(res.getTextFromWeb().split(" ")); + Function> observableFactory = new Function>() { + @Override + public NbpObservable apply(Resource res) { + return NbpObservable.fromArray(res.getTextFromWeb().split(" ")); + } }; NbpSubscriber NbpObserver = TestHelper.mockNbpSubscriber(); @@ -160,11 +171,19 @@ public void testUsingWithResourceFactoryErrorDisposeEagerly() { } private void performTestUsingWithResourceFactoryError(boolean disposeEagerly) { - Supplier resourceFactory = () -> { - throw new TestException(); + Supplier resourceFactory = new Supplier() { + @Override + public Disposable get() { + throw new TestException(); + } }; - Function> observableFactory = s -> NbpObservable.empty(); + Function> observableFactory = new Function>() { + @Override + public NbpObservable apply(Disposable s) { + return NbpObservable.empty(); + } + }; NbpObservable.using(resourceFactory, observableFactory, disposeSubscription) .toBlocking() @@ -183,10 +202,18 @@ public void testUsingWithObservableFactoryErrorDisposeEagerly() { private void performTestUsingWithObservableFactoryError(boolean disposeEagerly) { final Runnable unsubscribe = mock(Runnable.class); - Supplier resourceFactory = () -> Disposables.from(unsubscribe); + Supplier resourceFactory = new Supplier() { + @Override + public Disposable get() { + return Disposables.from(unsubscribe); + } + }; - Function> observableFactory = subscription -> { - throw new TestException(); + Function> observableFactory = new Function>() { + @Override + public NbpObservable apply(Disposable subscription) { + throw new TestException(); + } }; try { @@ -221,10 +248,16 @@ public Disposable get() { } }; - Function> observableFactory = subscription -> { - return NbpObservable.create(t1 -> { - throw new TestException(); - }); + Function> observableFactory = new Function>() { + @Override + public NbpObservable apply(Disposable subscription) { + return NbpObservable.create(new NbpOnSubscribe() { + @Override + public void accept(NbpSubscriber t1) { + throw new TestException(); + } + }); + } }; try { @@ -242,12 +275,17 @@ public Disposable get() { @Test public void testUsingDisposesEagerlyBeforeCompletion() { - final List events = new ArrayList<>(); + final List events = new ArrayList(); Supplier resourceFactory = createResourceFactory(events); final Runnable completion = createOnCompletedAction(events); final Runnable unsub =createUnsubAction(events); - Function> observableFactory = resource -> NbpObservable.fromArray(resource.getTextFromWeb().split(" ")); + Function> observableFactory = new Function>() { + @Override + public NbpObservable apply(Resource resource) { + return NbpObservable.fromArray(resource.getTextFromWeb().split(" ")); + } + }; NbpSubscriber NbpObserver = TestHelper.mockNbpSubscriber(); @@ -264,7 +302,7 @@ public void testUsingDisposesEagerlyBeforeCompletion() { @Test public void testUsingDoesNotDisposesEagerlyBeforeCompletion() { - final List events = new ArrayList<>(); + final List events = new ArrayList(); Supplier resourceFactory = createResourceFactory(events); final Runnable completion = createOnCompletedAction(events); final Runnable unsub = createUnsubAction(events); @@ -293,7 +331,7 @@ public NbpObservable apply(Resource resource) { @Test public void testUsingDisposesEagerlyBeforeError() { - final List events = new ArrayList<>(); + final List events = new ArrayList(); Supplier resourceFactory = createResourceFactory(events); final Consumer onError = createOnErrorAction(events); final Runnable unsub = createUnsubAction(events); @@ -321,14 +359,17 @@ public NbpObservable apply(Resource resource) { @Test public void testUsingDoesNotDisposesEagerlyBeforeError() { - final List events = new ArrayList<>(); + final List events = new ArrayList(); final Supplier resourceFactory = createResourceFactory(events); final Consumer onError = createOnErrorAction(events); final Runnable unsub = createUnsubAction(events); - Function> observableFactory = resource -> { - return NbpObservable.fromArray(resource.getTextFromWeb().split(" ")) - .concatWith(NbpObservable.error(new RuntimeException())); + Function> observableFactory = new Function>() { + @Override + public NbpObservable apply(Resource resource) { + return NbpObservable.fromArray(resource.getTextFromWeb().split(" ")) + .concatWith(NbpObservable.error(new RuntimeException())); + } }; NbpSubscriber NbpObserver = TestHelper.mockNbpSubscriber(); @@ -344,30 +385,50 @@ public void testUsingDoesNotDisposesEagerlyBeforeError() { } private static Runnable createUnsubAction(final List events) { - return () -> events.add("unsub"); + return new Runnable() { + @Override + public void run() { + events.add("unsub"); + } + }; } private static Consumer createOnErrorAction(final List events) { - return t -> events.add("error"); + return new Consumer() { + @Override + public void accept(Throwable t) { + events.add("error"); + } + }; } private static Supplier createResourceFactory(final List events) { - return () -> new Resource() { - + return new Supplier() { @Override - public String getTextFromWeb() { - return "hello world"; - } + public Resource get() { + return new Resource() { - @Override - public void dispose() { - events.add("disposed"); + @Override + public String getTextFromWeb() { + return "hello world"; + } + + @Override + public void dispose() { + events.add("disposed"); + } + }; } }; } private static Runnable createOnCompletedAction(final List events) { - return () -> events.add("completed"); + return new Runnable() { + @Override + public void run() { + events.add("completed"); + } + }; } } \ No newline at end of file diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorAllTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorAllTest.java index 4f16fde827..2a391cbf57 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorAllTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorAllTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -23,6 +23,8 @@ import io.reactivex.*; import io.reactivex.NbpObservable.NbpSubscriber; +import io.reactivex.disposables.Disposable; +import io.reactivex.functions.*; import io.reactivex.subscribers.nbp.NbpTestSubscriber; public class NbpOperatorAllTest { @@ -33,10 +35,15 @@ public void testAll() { NbpSubscriber NbpObserver = TestHelper.mockNbpSubscriber(); - obs.all(s -> s.length() == 3) + obs.all(new Predicate() { + @Override + public boolean test(String s) { + return s.length() == 3; + } + }) .subscribe(NbpObserver); - verify(NbpObserver).onSubscribe(any()); + verify(NbpObserver).onSubscribe((Disposable)any()); verify(NbpObserver).onNext(true); verify(NbpObserver).onComplete(); verifyNoMoreInteractions(NbpObserver); @@ -48,10 +55,15 @@ public void testNotAll() { NbpSubscriber NbpObserver = TestHelper.mockNbpSubscriber(); - obs.all(s -> s.length() == 3) + obs.all(new Predicate() { + @Override + public boolean test(String s) { + return s.length() == 3; + } + }) .subscribe(NbpObserver); - verify(NbpObserver).onSubscribe(any()); + verify(NbpObserver).onSubscribe((Disposable)any()); verify(NbpObserver).onNext(false); verify(NbpObserver).onComplete(); verifyNoMoreInteractions(NbpObserver); @@ -63,10 +75,15 @@ public void testEmpty() { NbpSubscriber NbpObserver = TestHelper.mockNbpSubscriber(); - obs.all(s -> s.length() == 3) + obs.all(new Predicate() { + @Override + public boolean test(String s) { + return s.length() == 3; + } + }) .subscribe(NbpObserver); - verify(NbpObserver).onSubscribe(any()); + verify(NbpObserver).onSubscribe((Disposable)any()); verify(NbpObserver).onNext(true); verify(NbpObserver).onComplete(); verifyNoMoreInteractions(NbpObserver); @@ -79,10 +96,15 @@ public void testError() { NbpSubscriber NbpObserver = TestHelper.mockNbpSubscriber(); - obs.all(s -> s.length() == 3) + obs.all(new Predicate() { + @Override + public boolean test(String s) { + return s.length() == 3; + } + }) .subscribe(NbpObserver); - verify(NbpObserver).onSubscribe(any()); + verify(NbpObserver).onSubscribe((Disposable)any()); verify(NbpObserver).onError(error); verifyNoMoreInteractions(NbpObserver); } @@ -90,15 +112,30 @@ public void testError() { @Test public void testFollowingFirst() { NbpObservable o = NbpObservable.fromArray(1, 3, 5, 6); - NbpObservable allOdd = o.all(i -> i % 2 == 1); + NbpObservable allOdd = o.all(new Predicate() { + @Override + public boolean test(Integer i) { + return i % 2 == 1; + } + }); assertFalse(allOdd.toBlocking().first()); } @Test(timeout = 5000) public void testIssue1935NoUnsubscribeDownstream() { NbpObservable source = NbpObservable.just(1) - .all(t1 -> false) - .flatMap(t1 -> NbpObservable.just(2).delay(500, TimeUnit.MILLISECONDS)); + .all(new Predicate() { + @Override + public boolean test(Integer t1) { + return false; + } + }) + .flatMap(new Function>() { + @Override + public NbpObservable apply(Boolean t1) { + return NbpObservable.just(2).delay(500, TimeUnit.MILLISECONDS); + } + }); assertEquals((Object)2, source.toBlocking().first()); } @@ -106,12 +143,15 @@ public void testIssue1935NoUnsubscribeDownstream() { @Test public void testPredicateThrowsExceptionAndValueInCauseMessage() { - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); final IllegalArgumentException ex = new IllegalArgumentException(); - NbpObservable.just("Boo!").all(v -> { - throw ex; + NbpObservable.just("Boo!").all(new Predicate() { + @Override + public boolean test(String v) { + throw ex; + } }) .subscribe(ts); diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorAnyTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorAnyTest.java index d5c6edf899..0fe1aca1e3 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorAnyTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorAnyTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -22,6 +22,7 @@ import io.reactivex.*; import io.reactivex.NbpObservable.NbpSubscriber; +import io.reactivex.functions.*; import io.reactivex.subscribers.nbp.NbpTestSubscriber; public class NbpOperatorAnyTest { @@ -29,7 +30,12 @@ public class NbpOperatorAnyTest { @Test public void testAnyWithTwoItems() { NbpObservable w = NbpObservable.just(1, 2); - NbpObservable NbpObservable = w.any(v -> true); + NbpObservable NbpObservable = w.any(new Predicate() { + @Override + public boolean test(Integer v) { + return true; + } + }); NbpSubscriber NbpObserver = TestHelper.mockNbpSubscriber(); @@ -59,7 +65,12 @@ public void testIsEmptyWithTwoItems() { @Test public void testAnyWithOneItem() { NbpObservable w = NbpObservable.just(1); - NbpObservable NbpObservable = w.any(v -> true); + NbpObservable NbpObservable = w.any(new Predicate() { + @Override + public boolean test(Integer v) { + return true; + } + }); NbpSubscriber NbpObserver = TestHelper.mockNbpSubscriber(); @@ -89,7 +100,12 @@ public void testIsEmptyWithOneItem() { @Test public void testAnyWithEmpty() { NbpObservable w = NbpObservable.empty(); - NbpObservable NbpObservable = w.any(v -> true); + NbpObservable NbpObservable = w.any(new Predicate() { + @Override + public boolean test(Integer v) { + return true; + } + }); NbpSubscriber NbpObserver = TestHelper.mockNbpSubscriber(); @@ -119,7 +135,12 @@ public void testIsEmptyWithEmpty() { @Test public void testAnyWithPredicate1() { NbpObservable w = NbpObservable.just(1, 2, 3); - NbpObservable NbpObservable = w.any(t1 -> t1 < 2); + NbpObservable NbpObservable = w.any(new Predicate() { + @Override + public boolean test(Integer t1) { + return t1 < 2; + } + }); NbpSubscriber NbpObserver = TestHelper.mockNbpSubscriber(); @@ -134,7 +155,12 @@ public void testAnyWithPredicate1() { @Test public void testExists1() { NbpObservable w = NbpObservable.just(1, 2, 3); - NbpObservable NbpObservable = w.any(t1 -> t1 < 2); + NbpObservable NbpObservable = w.any(new Predicate() { + @Override + public boolean test(Integer t1) { + return t1 < 2; + } + }); NbpSubscriber NbpObserver = TestHelper.mockNbpSubscriber(); @@ -149,7 +175,12 @@ public void testExists1() { @Test public void testAnyWithPredicate2() { NbpObservable w = NbpObservable.just(1, 2, 3); - NbpObservable NbpObservable = w.any(t1 -> t1 < 1); + NbpObservable NbpObservable = w.any(new Predicate() { + @Override + public boolean test(Integer t1) { + return t1 < 1; + } + }); NbpSubscriber NbpObserver = TestHelper.mockNbpSubscriber(); @@ -165,7 +196,12 @@ public void testAnyWithPredicate2() { public void testAnyWithEmptyAndPredicate() { // If the source is empty, always output false. NbpObservable w = NbpObservable.empty(); - NbpObservable NbpObservable = w.any(t -> true); + NbpObservable NbpObservable = w.any(new Predicate() { + @Override + public boolean test(Integer t) { + return true; + } + }); NbpSubscriber NbpObserver = TestHelper.mockNbpSubscriber(); @@ -180,25 +216,38 @@ public void testAnyWithEmptyAndPredicate() { @Test public void testWithFollowingFirst() { NbpObservable o = NbpObservable.fromArray(1, 3, 5, 6); - NbpObservable anyEven = o.any(i -> i % 2 == 0); + NbpObservable anyEven = o.any(new Predicate() { + @Override + public boolean test(Integer i) { + return i % 2 == 0; + } + }); assertTrue(anyEven.toBlocking().first()); } @Test(timeout = 5000) public void testIssue1935NoUnsubscribeDownstream() { NbpObservable source = NbpObservable.just(1).isEmpty() - .flatMap(t1 -> NbpObservable.just(2).delay(500, TimeUnit.MILLISECONDS)); + .flatMap(new Function>() { + @Override + public NbpObservable apply(Boolean t1) { + return NbpObservable.just(2).delay(500, TimeUnit.MILLISECONDS); + } + }); assertEquals((Object)2, source.toBlocking().first()); } @Test public void testPredicateThrowsExceptionAndValueInCauseMessage() { - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); final IllegalArgumentException ex = new IllegalArgumentException(); - NbpObservable.just("Boo!").any(v -> { - throw ex; + NbpObservable.just("Boo!").any(new Predicate() { + @Override + public boolean test(String v) { + throw ex; + } }).subscribe(ts); ts.assertTerminated(); diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorAsObservableTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorAsObservableTest.java index af533418d9..98c06894d4 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorAsObservableTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorAsObservableTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorBufferTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorBufferTest.java index 6c39a60347..badd79c735 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorBufferTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorBufferTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -19,7 +19,6 @@ import java.util.*; import java.util.concurrent.*; -import java.util.function.*; import org.junit.*; import org.mockito.*; @@ -27,6 +26,7 @@ import io.reactivex.*; import io.reactivex.NbpObservable.*; import io.reactivex.exceptions.TestException; +import io.reactivex.functions.*; import io.reactivex.internal.disposables.EmptyDisposable; import io.reactivex.schedulers.TestScheduler; import io.reactivex.subjects.nbp.NbpPublishSubject; @@ -309,7 +309,7 @@ public void accept(List t1) { } private List list(String... args) { - List list = new ArrayList<>(); + List list = new ArrayList(); for (String arg : args) { list.add(arg); } @@ -317,11 +317,21 @@ private List list(String... args) { } private void push(final NbpSubscriber NbpObserver, final T value, int delay) { - innerScheduler.schedule(() -> NbpObserver.onNext(value), delay, TimeUnit.MILLISECONDS); + innerScheduler.schedule(new Runnable() { + @Override + public void run() { + NbpObserver.onNext(value); + } + }, delay, TimeUnit.MILLISECONDS); } private void complete(final NbpSubscriber NbpObserver, int delay) { - innerScheduler.schedule(NbpObserver::onComplete, delay, TimeUnit.MILLISECONDS); + innerScheduler.schedule(new Runnable() { + @Override + public void run() { + NbpObserver.onComplete(); + } + }, delay, TimeUnit.MILLISECONDS); } @Test @@ -329,10 +339,15 @@ public void testBufferStopsWhenUnsubscribed1() { NbpObservable source = NbpObservable.never(); NbpSubscriber> o = TestHelper.mockNbpSubscriber(); - NbpTestSubscriber> ts = new NbpTestSubscriber<>(o); + NbpTestSubscriber> ts = new NbpTestSubscriber>(o); source.buffer(100, 200, TimeUnit.MILLISECONDS, scheduler) - .doOnNext(System.out::println) + .doOnNext(new Consumer>() { + @Override + public void accept(List pv) { + System.out.println(pv); + } + }) .subscribe(ts); InOrder inOrder = Mockito.inOrder(o); @@ -575,7 +590,12 @@ public NbpObservable apply(Long t1) { InOrder inOrder = inOrder(o); result - .doOnNext(System.out::println) + .doOnNext(new Consumer>() { + @Override + public void accept(List pv) { + System.out.println(pv); + } + }) .subscribe(o); scheduler.advanceTimeBy(5, TimeUnit.SECONDS); diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorCastTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorCastTest.java index 8134d60ab9..708b4f76bc 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorCastTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorCastTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorConcatTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorConcatTest.java index aa61ce969d..8581fe9dd2 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorConcatTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorConcatTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -20,7 +20,6 @@ import java.util.*; import java.util.concurrent.*; import java.util.concurrent.atomic.*; -import java.util.function.Function; import org.junit.Test; import org.mockito.InOrder; @@ -28,6 +27,7 @@ import io.reactivex.*; import io.reactivex.NbpObservable.*; import io.reactivex.disposables.*; +import io.reactivex.functions.Function; import io.reactivex.internal.disposables.EmptyDisposable; import io.reactivex.schedulers.*; import io.reactivex.subjects.nbp.*; @@ -60,7 +60,7 @@ public void testConcatWithList() { final NbpObservable odds = NbpObservable.fromArray(o); final NbpObservable even = NbpObservable.fromArray(e); - final List> list = new ArrayList<>(); + final List> list = new ArrayList>(); list.add(odds); list.add(even); NbpObservable concat = NbpObservable.concat(NbpObservable.fromIterable(list)); @@ -105,8 +105,8 @@ public void accept(NbpSubscriber> NbpObserver) { public void testSimpleAsyncConcat() { NbpSubscriber NbpObserver = TestHelper.mockNbpSubscriber(); - TestObservable o1 = new TestObservable<>("one", "two", "three"); - TestObservable o2 = new TestObservable<>("four", "five", "six"); + TestObservable o1 = new TestObservable("one", "two", "three"); + TestObservable o2 = new TestObservable("four", "five", "six"); NbpObservable.concat(NbpObservable.create(o1), NbpObservable.create(o2)).subscribe(NbpObserver); @@ -139,17 +139,18 @@ public void testNestedAsyncConcatLoop() throws Throwable { /** * Test an async NbpObservable that emits more async Observables + * @throws InterruptedException if the test is interrupted */ @Test - public void testNestedAsyncConcat() throws Throwable { + public void testNestedAsyncConcat() throws InterruptedException { NbpSubscriber NbpObserver = TestHelper.mockNbpSubscriber(); - final TestObservable o1 = new TestObservable<>("one", "two", "three"); - final TestObservable o2 = new TestObservable<>("four", "five", "six"); - final TestObservable o3 = new TestObservable<>("seven", "eight", "nine"); + final TestObservable o1 = new TestObservable("one", "two", "three"); + final TestObservable o2 = new TestObservable("four", "five", "six"); + final TestObservable o3 = new TestObservable("seven", "eight", "nine"); final CountDownLatch allowThird = new CountDownLatch(1); - final AtomicReference parent = new AtomicReference<>(); + final AtomicReference parent = new AtomicReference(); final CountDownLatch parentHasStarted = new CountDownLatch(1); final CountDownLatch parentHasFinished = new CountDownLatch(1); @@ -268,7 +269,8 @@ public void testBlockedObservableOfObservables() { final NbpObservable even = NbpObservable.fromArray(e); final CountDownLatch callOnce = new CountDownLatch(1); final CountDownLatch okToContinue = new CountDownLatch(1); - TestObservable> observableOfObservables = new TestObservable<>(callOnce, okToContinue, odds, even); + @SuppressWarnings("unchecked") + TestObservable> observableOfObservables = new TestObservable>(callOnce, okToContinue, odds, even); NbpObservable concatF = NbpObservable.concat(NbpObservable.create(observableOfObservables)); concatF.subscribe(NbpObserver); try { @@ -300,13 +302,14 @@ public void testBlockedObservableOfObservables() { @Test public void testConcatConcurrentWithInfinity() { - final TestObservable w1 = new TestObservable<>("one", "two", "three"); + final TestObservable w1 = new TestObservable("one", "two", "three"); //This NbpObservable will send "hello" MAX_VALUE time. - final TestObservable w2 = new TestObservable<>("hello", Integer.MAX_VALUE); + final TestObservable w2 = new TestObservable("hello", Integer.MAX_VALUE); NbpSubscriber NbpObserver = TestHelper.mockNbpSubscriber(); - TestObservable> observableOfObservables = new TestObservable<>(NbpObservable.create(w1), NbpObservable.create(w2)); + @SuppressWarnings("unchecked") + TestObservable> observableOfObservables = new TestObservable>(NbpObservable.create(w1), NbpObservable.create(w2)); NbpObservable concatF = NbpObservable.concat(NbpObservable.create(observableOfObservables)); concatF.take(50).subscribe(NbpObserver); @@ -334,8 +337,8 @@ public void testConcatNonBlockingObservables() { final CountDownLatch okToContinueW1 = new CountDownLatch(1); final CountDownLatch okToContinueW2 = new CountDownLatch(1); - final TestObservable w1 = new TestObservable<>(null, okToContinueW1, "one", "two", "three"); - final TestObservable w2 = new TestObservable<>(null, okToContinueW2, "four", "five", "six"); + final TestObservable w1 = new TestObservable(null, okToContinueW1, "one", "two", "three"); + final TestObservable w2 = new TestObservable(null, okToContinueW2, "four", "five", "six"); NbpSubscriber NbpObserver = TestHelper.mockNbpSubscriber(); @@ -385,11 +388,11 @@ public void accept(NbpSubscriber> NbpObserver) { public void testConcatUnsubscribe() { final CountDownLatch callOnce = new CountDownLatch(1); final CountDownLatch okToContinue = new CountDownLatch(1); - final TestObservable w1 = new TestObservable<>("one", "two", "three"); - final TestObservable w2 = new TestObservable<>(callOnce, okToContinue, "four", "five", "six"); + final TestObservable w1 = new TestObservable("one", "two", "three"); + final TestObservable w2 = new TestObservable(callOnce, okToContinue, "four", "five", "six"); NbpSubscriber NbpObserver = TestHelper.mockNbpSubscriber(); - NbpTestSubscriber ts = new NbpTestSubscriber<>(NbpObserver); + NbpTestSubscriber ts = new NbpTestSubscriber(NbpObserver); final NbpObservable concat = NbpObservable.concat(NbpObservable.create(w1), NbpObservable.create(w2)); @@ -427,13 +430,14 @@ public void testConcatUnsubscribe() { public void testConcatUnsubscribeConcurrent() { final CountDownLatch callOnce = new CountDownLatch(1); final CountDownLatch okToContinue = new CountDownLatch(1); - final TestObservable w1 = new TestObservable<>("one", "two", "three"); - final TestObservable w2 = new TestObservable<>(callOnce, okToContinue, "four", "five", "six"); + final TestObservable w1 = new TestObservable("one", "two", "three"); + final TestObservable w2 = new TestObservable(callOnce, okToContinue, "four", "five", "six"); NbpSubscriber NbpObserver = TestHelper.mockNbpSubscriber(); - NbpTestSubscriber ts = new NbpTestSubscriber<>(NbpObserver); + NbpTestSubscriber ts = new NbpTestSubscriber(NbpObserver); - TestObservable> observableOfObservables = new TestObservable<>(NbpObservable.create(w1), NbpObservable.create(w2)); + @SuppressWarnings("unchecked") + TestObservable> observableOfObservables = new TestObservable>(NbpObservable.create(w1), NbpObservable.create(w2)); NbpObservable concatF = NbpObservable.concat(NbpObservable.create(observableOfObservables)); concatF.subscribe(ts); @@ -466,8 +470,11 @@ public void testConcatUnsubscribeConcurrent() { private static class TestObservable implements NbpOnSubscribe { - private final Disposable s = () -> { - subscribed = false; + private final Disposable s = new Disposable() { + @Override + public void dispose() { + subscribed = false; + } }; private final List values; private Thread t = null; @@ -479,12 +486,10 @@ private static class TestObservable implements NbpOnSubscribe { private final T seed; private final int size; - @SafeVarargs public TestObservable(T... values) { this(null, null, values); } - @SafeVarargs public TestObservable(CountDownLatch once, CountDownLatch okToContinue, T... values) { this.values = Arrays.asList(values); this.size = this.values.size(); @@ -587,7 +592,12 @@ public void testMultipleObservers() { @Test public void concatVeryLongObservableOfObservables() { final int n = 10000; - NbpObservable> source = NbpObservable.range(0, n).map(NbpObservable::just); + NbpObservable> source = NbpObservable.range(0, n).map(new Function>() { + @Override + public NbpObservable apply(Integer v) { + return NbpObservable.just(v); + } + }); NbpObservable> result = NbpObservable.concat(source).toList(); @@ -596,7 +606,7 @@ public void concatVeryLongObservableOfObservables() { result.subscribe(o); - List list = new ArrayList<>(n); + List list = new ArrayList(n); for (int i = 0; i < n; i++) { list.add(i); } @@ -607,7 +617,12 @@ public void concatVeryLongObservableOfObservables() { @Test public void concatVeryLongObservableOfObservablesTakeHalf() { final int n = 10000; - NbpObservable> source = NbpObservable.range(0, n).map(NbpObservable::just); + NbpObservable> source = NbpObservable.range(0, n).map(new Function>() { + @Override + public NbpObservable apply(Integer v) { + return NbpObservable.just(v); + } + }); NbpObservable> result = NbpObservable.concat(source).take(n / 2).toList(); @@ -616,7 +631,7 @@ public void concatVeryLongObservableOfObservablesTakeHalf() { result.subscribe(o); - List list = new ArrayList<>(n); + List list = new ArrayList(n); for (int i = 0; i < n / 2; i++) { list.add(i); } @@ -649,7 +664,7 @@ public void accept(NbpSubscriber s) { }); - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); NbpObservable.concat(o, o).subscribe(ts); ts.awaitTerminalEvent(500, TimeUnit.MILLISECONDS); ts.assertTerminated(); @@ -719,7 +734,7 @@ public void concatMapRangeAsyncLoopIssue2876() { if (i % 1000 == 0) { System.out.println("concatMapRangeAsyncLoop > " + i); } - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); NbpObservable.range(0, 1000) .concatMap(new Function>() { @Override diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorDebounceTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorDebounceTest.java index 8707670930..e0abb8a422 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorDebounceTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorDebounceTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -17,7 +17,6 @@ import static org.mockito.Mockito.*; import java.util.concurrent.TimeUnit; -import java.util.function.Function; import org.junit.*; import org.mockito.InOrder; @@ -25,6 +24,7 @@ import io.reactivex.*; import io.reactivex.NbpObservable.*; import io.reactivex.exceptions.TestException; +import io.reactivex.functions.Function; import io.reactivex.internal.disposables.EmptyDisposable; import io.reactivex.schedulers.TestScheduler; import io.reactivex.subjects.nbp.NbpPublishSubject; @@ -279,7 +279,7 @@ public NbpObservable apply(Integer t1) { @Test public void debounceWithTimeBackpressure() throws InterruptedException { TestScheduler scheduler = new TestScheduler(); - NbpTestSubscriber NbpSubscriber = new NbpTestSubscriber<>(); + NbpTestSubscriber NbpSubscriber = new NbpTestSubscriber(); NbpObservable.merge( NbpObservable.just(1), NbpObservable.just(2).delay(10, TimeUnit.MILLISECONDS, scheduler) diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorDefaultIfEmptyTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorDefaultIfEmptyTest.java index 864bccdc17..e2949eecb0 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorDefaultIfEmptyTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorDefaultIfEmptyTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -58,7 +58,7 @@ public void testDefaultIfEmptyWithEmpty() { @Test @Ignore("Subscribers should not throw") public void testEmptyButClientThrows() { - NbpSubscriber o = TestHelper.mockNbpSubscriber(); + final NbpSubscriber o = TestHelper.mockNbpSubscriber(); NbpObservable.empty().defaultIfEmpty(1).subscribe(new NbpObserver() { @Override diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorDelayTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorDelayTest.java index 670d37feed..4527b0264b 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorDelayTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorDelayTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -19,18 +19,19 @@ import java.util.*; import java.util.concurrent.TimeUnit; -import java.util.function.*; import org.junit.*; import org.mockito.InOrder; import io.reactivex.*; import io.reactivex.NbpObservable.NbpSubscriber; -import io.reactivex.Observable; import io.reactivex.exceptions.TestException; +import io.reactivex.functions.*; import io.reactivex.schedulers.*; import io.reactivex.subjects.nbp.NbpPublishSubject; import io.reactivex.subscribers.nbp.NbpTestSubscriber; +import io.reactivex.Optional; +import io.reactivex.Observable; public class NbpOperatorDelayTest { private NbpSubscriber NbpObserver; @@ -216,7 +217,7 @@ public void testDelaySubscriptionCancelBeforeTime() { NbpObservable result = NbpObservable.just(1, 2, 3).delaySubscription(100, TimeUnit.MILLISECONDS, scheduler); NbpSubscriber o = TestHelper.mockNbpSubscriber(); - NbpTestSubscriber ts = new NbpTestSubscriber<>(o); + NbpTestSubscriber ts = new NbpTestSubscriber(o); result.subscribe(ts); ts.dispose(); @@ -230,7 +231,7 @@ public void testDelaySubscriptionCancelBeforeTime() { @Test public void testDelayWithObservableNormal1() { NbpPublishSubject source = NbpPublishSubject.create(); - final List> delays = new ArrayList<>(); + final List> delays = new ArrayList>(); final int n = 10; for (int i = 0; i < n; i++) { NbpPublishSubject delay = NbpPublishSubject.create(); @@ -581,7 +582,7 @@ public void testDelayWithObservableReorder() { int n = 3; NbpPublishSubject source = NbpPublishSubject.create(); - final List> subjects = new ArrayList<>(); + final List> subjects = new ArrayList>(); for (int i = 0; i < n; i++) { subjects.add(NbpPublishSubject. create()); } @@ -629,7 +630,7 @@ public void accept(Try> t1) { } }); - NbpTestSubscriber NbpObserver = new NbpTestSubscriber<>(); + NbpTestSubscriber NbpObserver = new NbpTestSubscriber(); delayed.subscribe(NbpObserver); // all will be delivered after 500ms since range does not delay between them scheduler.advanceTimeBy(500L, TimeUnit.MILLISECONDS); @@ -638,7 +639,7 @@ public void accept(Try> t1) { @Test public void testBackpressureWithTimedDelay() { - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); NbpObservable.range(1, Observable.bufferSize() * 2) .delay(100, TimeUnit.MILLISECONDS) .observeOn(Schedulers.computation()) @@ -666,7 +667,7 @@ public Integer apply(Integer t) { @Test public void testBackpressureWithSubscriptionTimedDelay() { - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); NbpObservable.range(1, Observable.bufferSize() * 2) .delaySubscription(100, TimeUnit.MILLISECONDS) .delay(100, TimeUnit.MILLISECONDS) @@ -695,7 +696,7 @@ public Integer apply(Integer t) { @Test public void testBackpressureWithSelectorDelay() { - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); NbpObservable.range(1, Observable.bufferSize() * 2) .delay(new Function>() { @@ -730,7 +731,7 @@ public Integer apply(Integer t) { @Test public void testBackpressureWithSelectorDelayAndSubscriptionDelay() { - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); NbpObservable.range(1, Observable.bufferSize() * 2) .delay(new Supplier>() { @@ -775,7 +776,7 @@ public void testErrorRunsBeforeOnNext() { NbpPublishSubject ps = NbpPublishSubject.create(); - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); ps.delay(1, TimeUnit.SECONDS, test).subscribe(ts); @@ -791,4 +792,83 @@ public void testErrorRunsBeforeOnNext() { ts.assertError(TestException.class); ts.assertNotComplete(); } + + public void testDelaySupplierSimple() { + final NbpPublishSubject ps = NbpPublishSubject.create(); + + NbpObservable source = NbpObservable.range(1, 5); + + NbpTestSubscriber ts = new NbpTestSubscriber(); + + source.delaySubscription(new Supplier>() { + @Override + public NbpObservable get() { + return ps; + } + }).subscribe(ts); + + ts.assertNoValues(); + ts.assertNoErrors(); + ts.assertNotComplete(); + + ps.onNext(1); + + ts.assertValues(1, 2, 3, 4, 5); + ts.assertComplete(); + ts.assertNoErrors(); + } + + @Test + public void testDelaySupplierCompletes() { + final NbpPublishSubject ps = NbpPublishSubject.create(); + + NbpObservable source = NbpObservable.range(1, 5); + + NbpTestSubscriber ts = new NbpTestSubscriber(); + + source.delaySubscription(new Supplier>() { + @Override + public NbpObservable get() { + return ps; + } + }).subscribe(ts); + + ts.assertNoValues(); + ts.assertNoErrors(); + ts.assertNotComplete(); + + // FIXME should this complete the source instead of consuming it? + ps.onComplete(); + + ts.assertValues(1, 2, 3, 4, 5); + ts.assertComplete(); + ts.assertNoErrors(); + } + + @Test + public void testDelaySupplierErrors() { + final NbpPublishSubject ps = NbpPublishSubject.create(); + + NbpObservable source = NbpObservable.range(1, 5); + + NbpTestSubscriber ts = new NbpTestSubscriber(); + + source.delaySubscription(new Supplier>() { + @Override + public NbpObservable get() { + return ps; + } + }).subscribe(ts); + + ts.assertNoValues(); + ts.assertNoErrors(); + ts.assertNotComplete(); + + ps.onError(new TestException()); + + ts.assertNoValues(); + ts.assertNotComplete(); + ts.assertError(TestException.class); + } + } \ No newline at end of file diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorDematerializeTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorDematerializeTest.java index 650927a425..db62043d16 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorDematerializeTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorDematerializeTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -16,8 +16,6 @@ import static org.mockito.Matchers.any; import static org.mockito.Mockito.*; -import java.util.Optional; - import org.junit.Test; import io.reactivex.*; @@ -94,7 +92,7 @@ public void testCompletePassThru() { NbpSubscriber NbpObserver = TestHelper.mockNbpSubscriber(); - NbpTestSubscriber ts = new NbpTestSubscriber<>(NbpObserver); + NbpTestSubscriber ts = new NbpTestSubscriber(NbpObserver); dematerialize.subscribe(ts); System.out.println(ts.errors()); diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorDistinctTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorDistinctTest.java index 3316c8477f..e68a0f6ea9 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorDistinctTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorDistinctTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -16,13 +16,12 @@ import static org.mockito.Matchers.*; import static org.mockito.Mockito.*; -import java.util.function.Function; - import org.junit.*; import org.mockito.InOrder; import io.reactivex.*; import io.reactivex.NbpObservable.NbpSubscriber; +import io.reactivex.functions.Function; public class NbpOperatorDistinctTest { diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorDistinctUntilChangedTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorDistinctUntilChangedTest.java index 8e070f99fd..162f486769 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorDistinctUntilChangedTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorDistinctUntilChangedTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -16,13 +16,12 @@ import static org.mockito.Matchers.*; import static org.mockito.Mockito.*; -import java.util.function.Function; - import org.junit.*; import org.mockito.InOrder; import io.reactivex.*; import io.reactivex.NbpObservable.NbpSubscriber; +import io.reactivex.functions.Function; public class NbpOperatorDistinctUntilChangedTest { diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorDoOnEachTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorDoOnEachTest.java index 4564dbf85c..150859106d 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorDoOnEachTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorDoOnEachTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -19,12 +19,12 @@ import java.util.List; import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.*; import org.junit.*; import io.reactivex.*; import io.reactivex.NbpObservable.NbpSubscriber; +import io.reactivex.functions.*; public class NbpOperatorDoOnEachTest { diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorDoOnSubscribeTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorDoOnSubscribeTest.java index 764aabed0d..12432c66a9 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorDoOnSubscribeTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorDoOnSubscribeTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -21,6 +21,8 @@ import io.reactivex.NbpObservable; import io.reactivex.NbpObservable.*; +import io.reactivex.disposables.Disposable; +import io.reactivex.functions.Consumer; import io.reactivex.internal.disposables.EmptyDisposable; public class NbpOperatorDoOnSubscribeTest { @@ -28,8 +30,11 @@ public class NbpOperatorDoOnSubscribeTest { @Test public void testDoOnSubscribe() throws Exception { final AtomicInteger count = new AtomicInteger(); - NbpObservable o = NbpObservable.just(1).doOnSubscribe(s -> { - count.incrementAndGet(); + NbpObservable o = NbpObservable.just(1).doOnSubscribe(new Consumer() { + @Override + public void accept(Disposable s) { + count.incrementAndGet(); + } }); o.subscribe(); @@ -41,10 +46,16 @@ public void testDoOnSubscribe() throws Exception { @Test public void testDoOnSubscribe2() throws Exception { final AtomicInteger count = new AtomicInteger(); - NbpObservable o = NbpObservable.just(1).doOnSubscribe(s -> { - count.incrementAndGet(); - }).take(1).doOnSubscribe(s -> { - count.incrementAndGet(); + NbpObservable o = NbpObservable.just(1).doOnSubscribe(new Consumer() { + @Override + public void accept(Disposable s) { + count.incrementAndGet(); + } + }).take(1).doOnSubscribe(new Consumer() { + @Override + public void accept(Disposable s) { + count.incrementAndGet(); + } }); o.subscribe(); @@ -56,7 +67,7 @@ public void testDoOnUnSubscribeWorksWithRefCount() throws Exception { final AtomicInteger onSubscribed = new AtomicInteger(); final AtomicInteger countBefore = new AtomicInteger(); final AtomicInteger countAfter = new AtomicInteger(); - final AtomicReference> sref = new AtomicReference<>(); + final AtomicReference> sref = new AtomicReference>(); NbpObservable o = NbpObservable.create(new NbpOnSubscribe() { @Override @@ -66,11 +77,17 @@ public void accept(NbpSubscriber s) { sref.set(s); } - }).doOnSubscribe(s -> { - countBefore.incrementAndGet(); + }).doOnSubscribe(new Consumer() { + @Override + public void accept(Disposable s) { + countBefore.incrementAndGet(); + } }).publish().refCount() - .doOnSubscribe(s -> { - countAfter.incrementAndGet(); + .doOnSubscribe(new Consumer() { + @Override + public void accept(Disposable s) { + countAfter.incrementAndGet(); + } }); o.subscribe(); diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorDoOnUnsubscribeTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorDoOnUnsubscribeTest.java index 93db351aca..20385b5b41 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorDoOnUnsubscribeTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorDoOnUnsubscribeTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -23,6 +23,7 @@ import io.reactivex.NbpObservable; import io.reactivex.disposables.Disposable; +import io.reactivex.functions.Consumer; import io.reactivex.subscribers.nbp.NbpTestSubscriber; public class NbpOperatorDoOnUnsubscribeTest { @@ -40,27 +41,36 @@ public void testDoOnUnsubscribe() throws Exception { // The stream needs to be infinite to ensure the stream does not terminate // before it is unsubscribed .interval(50, TimeUnit.MILLISECONDS) - .doOnCancel(() -> { - // Test that upper stream will be notified for un-subscription - // from a child NbpSubscriber - upperLatch.countDown(); - upperCount.incrementAndGet(); + .doOnCancel(new Runnable() { + @Override + public void run() { + // Test that upper stream will be notified for un-subscription + // from a child NbpSubscriber + upperLatch.countDown(); + upperCount.incrementAndGet(); + } }) - .doOnNext(aLong -> { - // Ensure there is at least some onNext events before un-subscription happens - onNextLatch.countDown(); + .doOnNext(new Consumer() { + @Override + public void accept(Long aLong) { + // Ensure there is at least some onNext events before un-subscription happens + onNextLatch.countDown(); + } }) - .doOnCancel(() -> { - // Test that lower stream will be notified for a direct un-subscription - lowerLatch.countDown(); - lowerCount.incrementAndGet(); + .doOnCancel(new Runnable() { + @Override + public void run() { + // Test that lower stream will be notified for a direct un-subscription + lowerLatch.countDown(); + lowerCount.incrementAndGet(); + } }); - List subscriptions = new ArrayList<>(); - List> subscribers = new ArrayList<>(); + List subscriptions = new ArrayList(); + List> subscribers = new ArrayList>(); for (int i = 0; i < subCount; ++i) { - NbpTestSubscriber NbpSubscriber = new NbpTestSubscriber<>(); + NbpTestSubscriber NbpSubscriber = new NbpTestSubscriber(); subscriptions.add(NbpSubscriber); longs.subscribe(NbpSubscriber); subscribers.add(NbpSubscriber); @@ -93,28 +103,37 @@ public void testDoOnUnSubscribeWorksWithRefCount() throws Exception { // The stream needs to be infinite to ensure the stream does not terminate // before it is unsubscribed .interval(50, TimeUnit.MILLISECONDS) - .doOnCancel(() -> { - // Test that upper stream will be notified for un-subscription - upperLatch.countDown(); - upperCount.incrementAndGet(); + .doOnCancel(new Runnable() { + @Override + public void run() { + // Test that upper stream will be notified for un-subscription + upperLatch.countDown(); + upperCount.incrementAndGet(); + } }) - .doOnNext(aLong -> { - // Ensure there is at least some onNext events before un-subscription happens - onNextLatch.countDown(); + .doOnNext(new Consumer() { + @Override + public void accept(Long aLong) { + // Ensure there is at least some onNext events before un-subscription happens + onNextLatch.countDown(); + } }) - .doOnCancel(() -> { - // Test that lower stream will be notified for un-subscription - lowerLatch.countDown(); - lowerCount.incrementAndGet(); + .doOnCancel(new Runnable() { + @Override + public void run() { + // Test that lower stream will be notified for un-subscription + lowerLatch.countDown(); + lowerCount.incrementAndGet(); + } }) .publish() .refCount(); - List subscriptions = new ArrayList<>(); - List> subscribers = new ArrayList<>(); + List subscriptions = new ArrayList(); + List> subscribers = new ArrayList>(); for (int i = 0; i < subCount; ++i) { - NbpTestSubscriber NbpSubscriber = new NbpTestSubscriber<>(); + NbpTestSubscriber NbpSubscriber = new NbpTestSubscriber(); longs.subscribe(NbpSubscriber); subscriptions.add(NbpSubscriber); subscribers.add(NbpSubscriber); diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorElementAtTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorElementAtTest.java index 37f58719b8..5db709e74a 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorElementAtTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorElementAtTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorFilterTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorFilterTest.java index 726befa437..d3e931fa6b 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorFilterTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorFilterTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -16,13 +16,12 @@ import static org.mockito.Matchers.any; import static org.mockito.Mockito.*; -import java.util.function.Predicate; - import org.junit.Test; import org.mockito.Mockito; import io.reactivex.*; import io.reactivex.NbpObservable.NbpSubscriber; +import io.reactivex.functions.Predicate; public class NbpOperatorFilterTest { diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorFinallyTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorFinallyTest.java index cac21f9960..054ad8ca3f 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorFinallyTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorFinallyTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorFirstTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorFirstTest.java index b2ea78448b..1df49e7b32 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorFirstTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorFirstTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -17,13 +17,13 @@ import static org.mockito.Mockito.*; import java.util.NoSuchElementException; -import java.util.function.Predicate; import org.junit.*; import org.mockito.InOrder; import io.reactivex.*; import io.reactivex.NbpObservable.NbpSubscriber; +import io.reactivex.functions.Predicate; public class NbpOperatorFirstTest { @@ -127,7 +127,12 @@ public void testFirstWithEmpty() { @Test public void testFirstWithPredicate() { NbpObservable o = NbpObservable.just(1, 2, 3, 4, 5, 6) - .filter(t1 -> t1 % 2 == 0) + .filter(new Predicate() { + @Override + public boolean test(Integer t1) { + return t1 % 2 == 0; + } + }) .first(); NbpSubscriber NbpObserver = TestHelper.mockNbpSubscriber(); @@ -142,7 +147,12 @@ public void testFirstWithPredicate() { @Test public void testFirstWithPredicateAndOneElement() { NbpObservable o = NbpObservable.just(1, 2) - .filter(t1 -> t1 % 2 == 0) + .filter(new Predicate() { + @Override + public boolean test(Integer t1) { + return t1 % 2 == 0; + } + }) .first(); NbpSubscriber NbpObserver = TestHelper.mockNbpSubscriber(); @@ -157,7 +167,12 @@ public void testFirstWithPredicateAndOneElement() { @Test public void testFirstWithPredicateAndEmpty() { NbpObservable o = NbpObservable.just(1) - .filter(t1 -> t1 % 2 == 0) + .filter(new Predicate() { + @Override + public boolean test(Integer t1) { + return t1 % 2 == 0; + } + }) .first(); NbpSubscriber NbpObserver = TestHelper.mockNbpSubscriber(); @@ -213,7 +228,12 @@ public void testFirstOrDefaultWithEmpty() { @Test public void testFirstOrDefaultWithPredicate() { NbpObservable o = NbpObservable.just(1, 2, 3, 4, 5, 6) - .filter(t1 -> t1 % 2 == 0) + .filter(new Predicate() { + @Override + public boolean test(Integer t1) { + return t1 % 2 == 0; + } + }) .first(8); NbpSubscriber NbpObserver = TestHelper.mockNbpSubscriber(); @@ -228,7 +248,12 @@ public void testFirstOrDefaultWithPredicate() { @Test public void testFirstOrDefaultWithPredicateAndOneElement() { NbpObservable o = NbpObservable.just(1, 2) - .filter(t1 -> t1 % 2 == 0) + .filter(new Predicate() { + @Override + public boolean test(Integer t1) { + return t1 % 2 == 0; + } + }) .first(4); NbpSubscriber NbpObserver = TestHelper.mockNbpSubscriber(); @@ -243,7 +268,12 @@ public void testFirstOrDefaultWithPredicateAndOneElement() { @Test public void testFirstOrDefaultWithPredicateAndEmpty() { NbpObservable o = NbpObservable.just(1) - .filter(t1 -> t1 % 2 == 0) + .filter(new Predicate() { + @Override + public boolean test(Integer t1) { + return t1 % 2 == 0; + } + }) .first(2); NbpSubscriber NbpObserver = TestHelper.mockNbpSubscriber(); diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorFlatMapTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorFlatMapTest.java index 2417241ed4..bc00b25f4a 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorFlatMapTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorFlatMapTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -20,13 +20,14 @@ import java.util.*; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.*; import org.junit.*; import io.reactivex.*; import io.reactivex.NbpObservable.NbpSubscriber; +import io.reactivex.disposables.Disposable; import io.reactivex.exceptions.TestException; +import io.reactivex.functions.*; import io.reactivex.schedulers.Schedulers; import io.reactivex.subscribers.nbp.NbpTestSubscriber; @@ -301,16 +302,22 @@ public void testFlatMapTransformsMergeException() { } private static NbpObservable composer(NbpObservable source, final AtomicInteger subscriptionCount, final int m) { - return source.doOnSubscribe(s -> { - int n = subscriptionCount.getAndIncrement(); - if (n >= m) { - Assert.fail("Too many subscriptions! " + (n + 1)); - } - }).doOnComplete(() -> { - int n = subscriptionCount.decrementAndGet(); - if (n < 0) { - Assert.fail("Too many unsubscriptions! " + (n - 1)); - } + return source.doOnSubscribe(new Consumer() { + @Override + public void accept(Disposable s) { + int n = subscriptionCount.getAndIncrement(); + if (n >= m) { + Assert.fail("Too many subscriptions! " + (n + 1)); + } + } + }).doOnComplete(new Runnable() { + @Override + public void run() { + int n = subscriptionCount.decrementAndGet(); + if (n < 0) { + Assert.fail("Too many unsubscriptions! " + (n - 1)); + } + } }); } @@ -327,13 +334,13 @@ public NbpObservable apply(Integer t1) { } }, m); - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); source.subscribe(ts); ts.awaitTerminalEvent(); ts.assertNoErrors(); - Set expected = new HashSet<>(Arrays.asList( + Set expected = new HashSet(Arrays.asList( 10, 11, 20, 21, 30, 31, 40, 41, 50, 51, 60, 61, 70, 71, 80, 81, 90, 91, 100, 101 )); Assert.assertEquals(expected.size(), ts.valueCount()); @@ -357,13 +364,13 @@ public Integer apply(Integer t1, Integer t2) { } }, m); - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); source.subscribe(ts); ts.awaitTerminalEvent(); ts.assertNoErrors(); - Set expected = new HashSet<>(Arrays.asList( + Set expected = new HashSet(Arrays.asList( 1010, 1011, 2020, 2021, 3030, 3031, 4040, 4041, 5050, 5051, 6060, 6061, 7070, 7071, 8080, 8081, 9090, 9091, 10100, 10101 )); @@ -403,9 +410,10 @@ public void testFlatMapTransformsMaxConcurrentNormal() { NbpObservable source = NbpObservable.fromIterable(Arrays.asList(10, 20, 30)); NbpSubscriber o = TestHelper.mockNbpSubscriber(); - NbpTestSubscriber ts = new NbpTestSubscriber<>(o); + NbpTestSubscriber ts = new NbpTestSubscriber(o); - source.flatMap(just(onNext), just(onError), just0(onCompleted), m).subscribe(ts); + Function> just = just(onError); + source.flatMap(just(onNext), just, just0(onCompleted), m).subscribe(ts); ts.awaitTerminalEvent(1, TimeUnit.SECONDS); ts.assertNoErrors(); @@ -428,7 +436,7 @@ public void flatMapRangeAsyncLoop() { if (i % 10 == 0) { System.out.println("flatMapRangeAsyncLoop > " + i); } - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); NbpObservable.range(0, 1000) .flatMap(new Function>() { @Override @@ -465,7 +473,7 @@ public void flatMapRangeMixedAsyncLoop() { if (i % 10 == 0) { System.out.println("flatMapRangeAsyncLoop > " + i); } - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); NbpObservable.range(0, 1000) .flatMap(new Function>() { final Random rnd = new Random(); @@ -489,7 +497,7 @@ public NbpObservable apply(Integer t) { ts.assertNoErrors(); List list = ts.values(); if (list.size() < 1000) { - Set set = new HashSet<>(list); + Set set = new HashSet(list); for (int j = 0; j < 1000; j++) { if (!set.contains(j)) { System.out.println(j + " missing"); @@ -503,7 +511,7 @@ public NbpObservable apply(Integer t) { @Test public void flatMapIntPassthruAsync() { for (int i = 0;i < 1000; i++) { - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); NbpObservable.range(1, 1000).flatMap(new Function>() { @Override @@ -521,7 +529,7 @@ public NbpObservable apply(Integer t) { @Test public void flatMapTwoNestedSync() { for (final int n : new int[] { 1, 1000, 1000000 }) { - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); NbpObservable.just(1, 2).flatMap(new Function>() { @Override diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorGroupByTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorGroupByTest.java index 2e0613ceee..bcbfb4878b 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorGroupByTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorGroupByTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -20,7 +20,6 @@ import java.util.*; import java.util.concurrent.*; import java.util.concurrent.atomic.*; -import java.util.function.*; import org.junit.Test; import org.mockito.Matchers; @@ -29,14 +28,21 @@ import io.reactivex.NbpObservable.*; import io.reactivex.disposables.*; import io.reactivex.exceptions.TestException; +import io.reactivex.functions.*; import io.reactivex.internal.disposables.EmptyDisposable; import io.reactivex.observables.nbp.NbpGroupedObservable; import io.reactivex.schedulers.Schedulers; import io.reactivex.subscribers.nbp.NbpTestSubscriber; +import io.reactivex.Optional; public class NbpOperatorGroupByTest { - final Function length = String::length; + final Function length = new Function() { + @Override + public Integer apply(String s) { + return s.length(); + } + }; @Test public void testGroupBy() { @@ -97,7 +103,7 @@ public void testError() { final AtomicInteger groupCounter = new AtomicInteger(); final AtomicInteger eventCounter = new AtomicInteger(); - final AtomicReference error = new AtomicReference<>(); + final AtomicReference error = new AtomicReference(); grouped.flatMap(new Function, NbpObservable>() { @@ -140,7 +146,7 @@ public void onNext(String v) { private static Map> toMap(NbpObservable> NbpObservable) { - final ConcurrentHashMap> result = new ConcurrentHashMap<>(); + final ConcurrentHashMap> result = new ConcurrentHashMap>(); NbpObservable.toBlocking().forEach(new Consumer>() { @@ -550,7 +556,12 @@ public NbpObservable apply(NbpGroupedObservable eventGro NbpObservable eventStream = eventGroupedObservable; if (eventGroupedObservable.getKey() >= 2) { // filter these - eventStream = eventGroupedObservable.filter(t1 -> false); + eventStream = eventGroupedObservable.filter(new Predicate() { + @Override + public boolean test(Event t1) { + return false; + } + }); } return eventStream @@ -582,7 +593,7 @@ public void accept(String s) { @Test public void testFirstGroupsCompleteAndParentSlowToThenEmitFinalGroupsAndThenComplete() throws InterruptedException { final CountDownLatch first = new CountDownLatch(2); // there are two groups to first complete - final ArrayList results = new ArrayList<>(); + final ArrayList results = new ArrayList(); NbpObservable.create(new NbpOnSubscribe() { @Override @@ -661,7 +672,7 @@ public void accept(String s) { public void testFirstGroupsCompleteAndParentSlowToThenEmitFinalGroupsWhichThenSubscribesOnAndDelaysAndThenCompletes() throws InterruptedException { System.err.println("----------------------------------------------------------------------------------------------"); final CountDownLatch first = new CountDownLatch(2); // there are two groups to first complete - final ArrayList results = new ArrayList<>(); + final ArrayList results = new ArrayList(); NbpObservable.create(new NbpOnSubscribe() { @Override @@ -753,7 +764,7 @@ public void accept(String s) { @Test public void testFirstGroupsCompleteAndParentSlowToThenEmitFinalGroupsWhichThenObservesOnAndDelaysAndThenCompletes() throws InterruptedException { final CountDownLatch first = new CountDownLatch(2); // there are two groups to first complete - final ArrayList results = new ArrayList<>(); + final ArrayList results = new ArrayList(); NbpObservable.create(new NbpOnSubscribe() { @Override @@ -830,7 +841,7 @@ public void accept(String s) { @Test public void testGroupsWithNestedSubscribeOn() throws InterruptedException { - final ArrayList results = new ArrayList<>(); + final ArrayList results = new ArrayList(); NbpObservable.create(new NbpOnSubscribe() { @Override @@ -887,7 +898,7 @@ public void accept(String s) { @Test public void testGroupsWithNestedObserveOn() throws InterruptedException { - final ArrayList results = new ArrayList<>(); + final ArrayList results = new ArrayList(); NbpObservable.create(new NbpOnSubscribe() { @Override @@ -1014,7 +1025,7 @@ public Boolean apply(Integer n) { @Test public void testGroupByBackpressure() throws InterruptedException { - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); NbpObservable.range(1, 4000) .groupBy(IS_EVEN2) @@ -1078,7 +1089,12 @@ public Integer apply(Integer t1) { return t1 * 2; } }; - Function identity = v -> v; + Function identity = new Function() { + @Override + public Integer apply(Integer v) { + return v; + } + }; @Test public void normalBehavior() { @@ -1118,22 +1134,25 @@ public String apply(String t1) { }; NbpObservable m = source.groupBy(keysel, valuesel) - .flatMap(g -> { - System.out.println("-----------> NEXT: " + g.getKey()); - return g.take(2).map(new Function() { + .flatMap(new Function, NbpObservable>() { + @Override + public NbpObservable apply(final NbpGroupedObservable g) { + System.out.println("-----------> NEXT: " + g.getKey()); + return g.take(2).map(new Function() { - int count = 0; + int count = 0; - @Override - public String apply(String v) { - System.out.println(v); - return g.getKey() + "-" + count++; - } + @Override + public String apply(String v) { + System.out.println(v); + return g.getKey() + "-" + count++; + } - }); + }); + } }); - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); m.subscribe(ts); ts.awaitTerminalEvent(); System.out.println("ts .get " + ts.values()); @@ -1149,7 +1168,7 @@ public void keySelectorThrows() { NbpObservable m = source.groupBy(fail(0), dbl).flatMap(FLATTEN_INTEGER); - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); m.subscribe(ts); ts.awaitTerminalEvent(); assertEquals(1, ts.errorCount()); @@ -1161,7 +1180,7 @@ public void valueSelectorThrows() { NbpObservable source = NbpObservable.just(0, 1, 2, 3, 4, 5, 6); NbpObservable m = source.groupBy(identity, fail(0)).flatMap(FLATTEN_INTEGER); - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); m.subscribe(ts); ts.awaitTerminalEvent(); assertEquals(1, ts.errorCount()); @@ -1175,7 +1194,7 @@ public void innerEscapeCompleted() { NbpObservable m = source.groupBy(identity, dbl).flatMap(FLATTEN_INTEGER); - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); m.subscribe(ts); ts.awaitTerminalEvent(); ts.assertNoErrors(); @@ -1189,7 +1208,7 @@ public void innerEscapeCompleted() { public void testExceptionIfSubscribeToChildMoreThanOnce() { NbpObservable source = NbpObservable.just(0); - final AtomicReference> inner = new AtomicReference<>(); + final AtomicReference> inner = new AtomicReference>(); NbpObservable> m = source.groupBy(identity, dbl); @@ -1219,7 +1238,7 @@ public void testError2() { NbpObservable m = source.groupBy(identity, dbl).flatMap(FLATTEN_INTEGER); - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); m.subscribe(ts); ts.awaitTerminalEvent(); assertEquals(1, ts.errorCount()); @@ -1228,7 +1247,7 @@ public void testError2() { @Test public void testgroupByBackpressure() throws InterruptedException { - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); NbpObservable.range(1, 4000).groupBy(IS_EVEN2).flatMap(new Function, NbpObservable>() { @@ -1285,7 +1304,7 @@ public void accept(Try> t1) { @Test public void testgroupByBackpressure2() throws InterruptedException { - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); NbpObservable.range(1, 4000).groupBy(IS_EVEN2).flatMap(new Function, NbpObservable>() { @@ -1326,7 +1345,7 @@ public NbpObservable apply(NbpGroupedObservable t) { @Test public void testGroupByWithNullKey() { final String[] key = new String[]{"uninitialized"}; - final List values = new ArrayList<>(); + final List values = new ArrayList(); NbpObservable.just("a", "b", "c").groupBy(new Function() { @Override @@ -1362,7 +1381,7 @@ public void accept(NbpSubscriber NbpSubscriber) { } } ); - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); o.groupBy(new Function() { @@ -1380,11 +1399,11 @@ public Integer apply(Integer integer) { @Test public void testGroupByShouldPropagateError() { final Throwable e = new RuntimeException("Oops"); - final NbpTestSubscriber inner1 = new NbpTestSubscriber<>(); - final NbpTestSubscriber inner2 = new NbpTestSubscriber<>(); + final NbpTestSubscriber inner1 = new NbpTestSubscriber(); + final NbpTestSubscriber inner2 = new NbpTestSubscriber(); final NbpTestSubscriber> outer - = new NbpTestSubscriber<>(new NbpObserver>() { + = new NbpTestSubscriber>(new NbpObserver>() { @Override public void onComplete() { diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorIgnoreElementsTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorIgnoreElementsTest.java index 9a67657308..0677eeaeec 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorIgnoreElementsTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorIgnoreElementsTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -16,12 +16,12 @@ import static org.junit.Assert.*; import java.util.concurrent.atomic.*; -import java.util.function.Consumer; import org.junit.Test; import io.reactivex.NbpObservable; import io.reactivex.exceptions.TestException; +import io.reactivex.functions.Consumer; import io.reactivex.subscribers.nbp.NbpTestSubscriber; public class NbpOperatorIgnoreElementsTest { @@ -55,7 +55,7 @@ public void accept(Integer t) { @Test public void testCompletedOk() { - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); NbpObservable.range(1, 10).ignoreElements().subscribe(ts); ts.assertNoErrors(); ts.assertNoValues(); @@ -66,7 +66,7 @@ public void testCompletedOk() { @Test public void testErrorReceived() { - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); TestException ex = new TestException("boo"); NbpObservable.error(ex).ignoreElements().subscribe(ts); ts.assertNoValues(); diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorLastTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorLastTest.java index 84e98b16a8..c8d199e342 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorLastTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorLastTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -18,13 +18,13 @@ import static org.mockito.Mockito.*; import java.util.NoSuchElementException; -import java.util.function.Predicate; import org.junit.Test; import org.mockito.InOrder; import io.reactivex.*; import io.reactivex.NbpObservable.NbpSubscriber; +import io.reactivex.functions.Predicate; public class NbpOperatorLastTest { diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorMapNotificationTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorMapNotificationTest.java index 6cde2d628e..85a4a0e519 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorMapNotificationTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorMapNotificationTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,17 +13,16 @@ package io.reactivex.internal.operators.nbp; -import java.util.function.*; - import org.junit.Test; import io.reactivex.NbpObservable; +import io.reactivex.functions.*; import io.reactivex.subscribers.nbp.NbpTestSubscriber; public class NbpOperatorMapNotificationTest { @Test public void testJust() { - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); NbpObservable.just(1) .flatMap( new Function>() { diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorMapTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorMapTest.java index 837d1deb8e..d7f0b0ad6b 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorMapTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorMapTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -17,12 +17,12 @@ import static org.mockito.Mockito.*; import java.util.*; -import java.util.function.*; import org.junit.*; import io.reactivex.*; import io.reactivex.NbpObservable.NbpSubscriber; +import io.reactivex.functions.*; import io.reactivex.schedulers.Schedulers; public class NbpOperatorMapTest { @@ -49,7 +49,12 @@ public void testMap() { Map m2 = getMap("Two"); NbpObservable> o = NbpObservable.just(m1, m2); - NbpObservable m = o.map(map -> map.get("firstName")); + NbpObservable m = o.map(new Function, String>() { + @Override + public String apply(Map map) { + return map.get("firstName"); + } + }); m.subscribe(stringObserver); @@ -295,7 +300,7 @@ public Integer apply(Integer i) { // } private static Map getMap(String prefix) { - Map m = new HashMap<>(); + Map m = new HashMap(); m.put("firstName", prefix + "First"); m.put("lastName", prefix + "Last"); return m; diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorMaterializeTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorMaterializeTest.java index 705a9e26b7..22fc568875 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorMaterializeTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorMaterializeTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -17,14 +17,15 @@ import java.util.*; import java.util.concurrent.ExecutionException; -import java.util.function.Consumer; import org.junit.Test; import io.reactivex.*; import io.reactivex.NbpObservable.*; +import io.reactivex.functions.Consumer; import io.reactivex.internal.disposables.EmptyDisposable; import io.reactivex.subscribers.nbp.NbpTestSubscriber; +import io.reactivex.Optional; public class NbpOperatorMaterializeTest { @@ -94,7 +95,7 @@ public void testMultipleSubscribes() throws InterruptedException, ExecutionExcep @Test public void testWithCompletionCausingError() { - NbpTestSubscriber>> ts = new NbpTestSubscriber<>(); + NbpTestSubscriber>> ts = new NbpTestSubscriber>>(); final RuntimeException ex = new RuntimeException("boo"); NbpObservable.empty().materialize().doOnNext(new Consumer() { @Override @@ -111,7 +112,7 @@ private static class TestObserver extends NbpObserver>> { boolean onCompleted = false; boolean onError = false; - List>> notifications = new Vector<>(); + List>> notifications = new Vector>>(); @Override public void onComplete() { diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorMergeDelayErrorTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorMergeDelayErrorTest.java index 6b310a3f94..1b9cc17d22 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorMergeDelayErrorTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorMergeDelayErrorTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -25,7 +25,7 @@ import io.reactivex.*; import io.reactivex.NbpObservable.*; -import io.reactivex.exceptions.TestException; +import io.reactivex.exceptions.*; import io.reactivex.internal.disposables.EmptyDisposable; import io.reactivex.subscribers.nbp.NbpTestSubscriber; @@ -194,7 +194,7 @@ public void testCompositeErrorDelayed2() { assertNotNull(w.e); - assertEquals(1, w.e.getSuppressed().length); + assertEquals(2, ((CompositeException)w.e).size()); // if (w.e instanceof CompositeException) { // assertEquals(2, ((CompositeException) w.e).getExceptions().size()); @@ -251,7 +251,7 @@ public void testMergeArray() { public void testMergeList() { final NbpObservable o1 = NbpObservable.create(new TestSynchronousObservable()); final NbpObservable o2 = NbpObservable.create(new TestSynchronousObservable()); - List> listOfObservables = new ArrayList<>(); + List> listOfObservables = new ArrayList>(); listOfObservables.add(o1); listOfObservables.add(o2); @@ -487,7 +487,7 @@ public void onComplete() { @Test public void testErrorInParentObservable() { - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); NbpObservable.mergeDelayError( NbpObservable.just(NbpObservable.just(1), NbpObservable.just(2)) .startWith(NbpObservable. error(new RuntimeException())) @@ -516,7 +516,7 @@ public void accept(NbpSubscriber> op) { NbpSubscriber stringObserver = TestHelper.mockNbpSubscriber(); - NbpTestSubscriber ts = new NbpTestSubscriber<>(stringObserver); + NbpTestSubscriber ts = new NbpTestSubscriber(stringObserver); NbpObservable m = NbpObservable.mergeDelayError(parentObservable); m.subscribe(ts); System.out.println("testErrorInParentObservableDelayed | " + i); diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorMergeMaxConcurrentTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorMergeMaxConcurrentTest.java index cd32f18f57..e8da9ca6cf 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorMergeMaxConcurrentTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorMergeMaxConcurrentTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -16,7 +16,7 @@ import static org.junit.Assert.*; import java.util.*; -import java.util.concurrent.*; +import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import org.junit.*; @@ -40,14 +40,14 @@ public void before() { @Test public void testWhenMaxConcurrentIsOne() { for (int i = 0; i < 100; i++) { - List> os = new ArrayList<>(); + List> os = new ArrayList>(); os.add(NbpObservable.just("one", "two", "three", "four", "five").subscribeOn(Schedulers.newThread())); os.add(NbpObservable.just("one", "two", "three", "four", "five").subscribeOn(Schedulers.newThread())); os.add(NbpObservable.just("one", "two", "three", "four", "five").subscribeOn(Schedulers.newThread())); List expected = Arrays.asList("one", "two", "three", "four", "five", "one", "two", "three", "four", "five", "one", "two", "three", "four", "five"); Iterator iter = NbpObservable.merge(os, 1).toBlocking().iterator(); - List actual = new ArrayList<>(); + List actual = new ArrayList(); while (iter.hasNext()) { actual.add(iter.next()); } @@ -63,8 +63,8 @@ public void testMaxConcurrent() { int maxConcurrent = 2 + (times % 10); AtomicInteger subscriptionCount = new AtomicInteger(0); - List> os = new ArrayList<>(); - List scos = new ArrayList<>(); + List> os = new ArrayList>(); + List scos = new ArrayList(); for (int i = 0; i < observableCount; i++) { SubscriptionCheckObservable sco = new SubscriptionCheckObservable(subscriptionCount, maxConcurrent); scos.add(sco); @@ -72,7 +72,7 @@ public void testMaxConcurrent() { } Iterator iter = NbpObservable.merge(os, maxConcurrent).toBlocking().iterator(); - List actual = new ArrayList<>(); + List actual = new ArrayList(); while (iter.hasNext()) { actual.add(iter.next()); } @@ -124,7 +124,7 @@ public void run() { @Test public void testMergeALotOfSourcesOneByOneSynchronously() { int n = 10000; - List> sourceList = new ArrayList<>(n); + List> sourceList = new ArrayList>(n); for (int i = 0; i < n; i++) { sourceList.add(NbpObservable.just(i)); } @@ -139,7 +139,7 @@ public void testMergeALotOfSourcesOneByOneSynchronously() { @Test public void testMergeALotOfSourcesOneByOneSynchronouslyTakeHalf() { int n = 10000; - List> sourceList = new ArrayList<>(n); + List> sourceList = new ArrayList>(n); for (int i = 0; i < n; i++) { sourceList.add(NbpObservable.just(i)); } @@ -155,9 +155,9 @@ public void testMergeALotOfSourcesOneByOneSynchronouslyTakeHalf() { @Test public void testSimple() { for (int i = 1; i < 100; i++) { - NbpTestSubscriber ts = new NbpTestSubscriber<>(); - List> sourceList = new ArrayList<>(i); - List result = new ArrayList<>(i); + NbpTestSubscriber ts = new NbpTestSubscriber(); + List> sourceList = new ArrayList>(i); + List result = new ArrayList(i); for (int j = 1; j <= i; j++) { sourceList.add(NbpObservable.just(j)); result.add(j); @@ -173,9 +173,9 @@ public void testSimple() { @Test public void testSimpleOneLess() { for (int i = 2; i < 100; i++) { - NbpTestSubscriber ts = new NbpTestSubscriber<>(); - List> sourceList = new ArrayList<>(i); - List result = new ArrayList<>(i); + NbpTestSubscriber ts = new NbpTestSubscriber(); + List> sourceList = new ArrayList>(i); + List result = new ArrayList(i); for (int j = 1; j <= i; j++) { sourceList.add(NbpObservable.just(j)); result.add(j); @@ -203,9 +203,9 @@ public void testSimpleAsyncLoop() { @Test(timeout = 10000) public void testSimpleAsync() { for (int i = 1; i < 50; i++) { - NbpTestSubscriber ts = new NbpTestSubscriber<>(); - List> sourceList = new ArrayList<>(i); - Set expected = new HashSet<>(i); + NbpTestSubscriber ts = new NbpTestSubscriber(); + List> sourceList = new ArrayList>(i); + Set expected = new HashSet(i); for (int j = 1; j <= i; j++) { sourceList.add(NbpObservable.just(j).subscribeOn(Schedulers.io())); expected.add(j); @@ -215,7 +215,7 @@ public void testSimpleAsync() { ts.awaitTerminalEvent(1, TimeUnit.SECONDS); ts.assertNoErrors(); - Set actual = new HashSet<>(ts.values()); + Set actual = new HashSet(ts.values()); assertEquals(expected, actual); } @@ -233,9 +233,9 @@ public void testSimpleOneLessAsync() { if (System.currentTimeMillis() - t > TimeUnit.SECONDS.toMillis(9)) { break; } - NbpTestSubscriber ts = new NbpTestSubscriber<>(); - List> sourceList = new ArrayList<>(i); - Set expected = new HashSet<>(i); + NbpTestSubscriber ts = new NbpTestSubscriber(); + List> sourceList = new ArrayList>(i); + Set expected = new HashSet(i); for (int j = 1; j <= i; j++) { sourceList.add(NbpObservable.just(j).subscribeOn(Schedulers.io())); expected.add(j); @@ -245,7 +245,7 @@ public void testSimpleOneLessAsync() { ts.awaitTerminalEvent(1, TimeUnit.SECONDS); ts.assertNoErrors(); - Set actual = new HashSet<>(ts.values()); + Set actual = new HashSet(ts.values()); assertEquals(expected, actual); } @@ -253,13 +253,13 @@ public void testSimpleOneLessAsync() { @Test(timeout = 5000) public void testTake() throws Exception { - List> sourceList = new ArrayList<>(3); + List> sourceList = new ArrayList>(3); sourceList.add(NbpObservable.range(0, 100000).subscribeOn(Schedulers.io())); sourceList.add(NbpObservable.range(0, 100000).subscribeOn(Schedulers.io())); sourceList.add(NbpObservable.range(0, 100000).subscribeOn(Schedulers.io())); - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); NbpObservable.merge(sourceList, 2).take(5).subscribe(ts); diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorMergeTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorMergeTest.java index d09fa82cea..a30b0f4492 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorMergeTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorMergeTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -20,18 +20,18 @@ import java.util.*; import java.util.concurrent.*; import java.util.concurrent.atomic.*; -import java.util.function.*; import org.junit.*; import io.reactivex.*; import io.reactivex.NbpObservable.*; -import io.reactivex.Observable; import io.reactivex.Scheduler.Worker; import io.reactivex.disposables.*; +import io.reactivex.functions.*; import io.reactivex.internal.disposables.EmptyDisposable; import io.reactivex.schedulers.*; import io.reactivex.subscribers.nbp.NbpTestSubscriber; +import io.reactivex.Observable; public class NbpOperatorMergeTest { @@ -110,7 +110,7 @@ public void testMergeArray() { public void testMergeList() { final NbpObservable o1 = NbpObservable.create(new TestSynchronousObservable()); final NbpObservable o2 = NbpObservable.create(new TestSynchronousObservable()); - List> listOfObservables = new ArrayList<>(); + List> listOfObservables = new ArrayList>(); listOfObservables.add(o1); listOfObservables.add(o2); @@ -133,9 +133,12 @@ public void testUnSubscribeObservableOfObservables() throws InterruptedException @Override public void accept(final NbpSubscriber> NbpObserver) { // verbose on purpose so I can track the inside of it - final Disposable s = () -> { - System.out.println("*** unsubscribed"); - unsubscribed.set(true); + final Disposable s = new Disposable() { + @Override + public void dispose() { + System.out.println("*** unsubscribed"); + unsubscribed.set(true); + } }; NbpObserver.onSubscribe(s); @@ -186,7 +189,7 @@ public void testMergeArrayWithThreading() { final TestASynchronousObservable o2 = new TestASynchronousObservable(); NbpObservable m = NbpObservable.merge(NbpObservable.create(o1), NbpObservable.create(o2)); - NbpTestSubscriber ts = new NbpTestSubscriber<>(stringObserver); + NbpTestSubscriber ts = new NbpTestSubscriber(stringObserver); m.subscribe(ts); ts.awaitTerminalEvent(); @@ -332,7 +335,7 @@ public void testError2() { @Test @Ignore("Subscribe should not throw") public void testThrownErrorHandling() { - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); NbpObservable o1 = NbpObservable.create(new NbpOnSubscribe() { @Override @@ -418,7 +421,7 @@ public void testUnsubscribeAsObservablesComplete() { AtomicBoolean os2 = new AtomicBoolean(false); NbpObservable o2 = createObservableOf5IntervalsOf1SecondIncrementsWithSubscriptionHook(scheduler2, os2); - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); NbpObservable.merge(o1, o2).subscribe(ts); // we haven't incremented time so nothing should be received yet @@ -460,7 +463,7 @@ public void testEarlyUnsubscribe() { AtomicBoolean os2 = new AtomicBoolean(false); NbpObservable o2 = createObservableOf5IntervalsOf1SecondIncrementsWithSubscriptionHook(scheduler2, os2); - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); NbpObservable.merge(o1, o2).subscribe(ts); // we haven't incremented time so nothing should be received yet @@ -490,15 +493,18 @@ private NbpObservable createObservableOf5IntervalsOf1SecondIncrementsWithS return NbpObservable.create(new NbpOnSubscribe() { @Override - public void accept(NbpSubscriber child) { + public void accept(final NbpSubscriber child) { NbpObservable.interval(1, TimeUnit.SECONDS, scheduler) .take(5) .subscribe(new NbpSubscriber() { @Override - public void onSubscribe(Disposable s) { - child.onSubscribe(() -> { - unsubscribed.set(true); - s.dispose(); + public void onSubscribe(final Disposable s) { + child.onSubscribe(new Disposable() { + @Override + public void dispose() { + unsubscribed.set(true); + s.dispose(); + } }); } @@ -530,7 +536,7 @@ public void testConcurrency() { for (int i = 0; i < 10; i++) { NbpObservable merge = NbpObservable.merge(o, o, o); - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); merge.subscribe(ts); ts.awaitTerminalEvent(3, TimeUnit.SECONDS); @@ -551,7 +557,7 @@ public void testConcurrencyWithSleeping() { @Override public void accept(final NbpSubscriber s) { Worker inner = Schedulers.newThread().createWorker(); - CompositeDisposable as = new CompositeDisposable(); + final CompositeDisposable as = new CompositeDisposable(); as.add(EmptyDisposable.INSTANCE); as.add(inner); @@ -583,7 +589,7 @@ public void run() { for (int i = 0; i < 10; i++) { NbpObservable merge = NbpObservable.merge(o, o, o); - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); merge.subscribe(ts); ts.awaitTerminalEvent(); @@ -601,7 +607,7 @@ public void testConcurrencyWithBrokenOnCompleteContract() { @Override public void accept(final NbpSubscriber s) { Worker inner = Schedulers.newThread().createWorker(); - CompositeDisposable as = new CompositeDisposable(); + final CompositeDisposable as = new CompositeDisposable(); as.add(EmptyDisposable.INSTANCE); as.add(inner); @@ -630,7 +636,7 @@ public void run() { for (int i = 0; i < 10; i++) { NbpObservable merge = NbpObservable.merge(o, o, o); - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); merge.subscribe(ts); ts.awaitTerminalEvent(); @@ -715,6 +721,7 @@ public void onNext(Integer t) { * This is the same as the upstreams ones, but now adds the downstream as well by using observeOn. * * This requires merge to also obey the Product.request values coming from it's child NbpSubscriber. + * @throws InterruptedException if the test is interrupted */ @Test(timeout = 10000) public void testBackpressureDownstreamWithConcurrentStreams() throws InterruptedException { @@ -812,7 +819,7 @@ public void onNext(Integer t) { @Ignore("Null values not permitted") public void mergeWithNullValues() { System.out.println("mergeWithNullValues"); - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); NbpObservable.merge(NbpObservable.just(null, "one"), NbpObservable.just("two", null)).subscribe(ts); ts.assertTerminated(); ts.assertNoErrors(); @@ -823,7 +830,7 @@ public void mergeWithNullValues() { @Ignore("Null values are no longer permitted") public void mergeWithTerminalEventAfterUnsubscribe() { System.out.println("mergeWithTerminalEventAfterUnsubscribe"); - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); NbpObservable bad = NbpObservable.create(new NbpOnSubscribe() { @Override @@ -843,7 +850,7 @@ public void accept(NbpSubscriber s) { @Test @Ignore("Null values are not permitted") public void mergingNullObservable() { - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); NbpObservable.merge(NbpObservable.just("one"), null).subscribe(ts); ts.assertNoErrors(); ts.assertValue("one"); @@ -851,7 +858,7 @@ public void mergingNullObservable() { @Test public void merge1AsyncStreamOf1() { - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); mergeNAsyncStreamsOfN(1, 1).subscribe(ts); ts.awaitTerminalEvent(); ts.assertNoErrors(); @@ -860,7 +867,7 @@ public void merge1AsyncStreamOf1() { @Test public void merge1AsyncStreamOf1000() { - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); mergeNAsyncStreamsOfN(1, 1000).subscribe(ts); ts.awaitTerminalEvent(); ts.assertNoErrors(); @@ -869,7 +876,7 @@ public void merge1AsyncStreamOf1000() { @Test public void merge10AsyncStreamOf1000() { - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); mergeNAsyncStreamsOfN(10, 1000).subscribe(ts); ts.awaitTerminalEvent(); ts.assertNoErrors(); @@ -878,7 +885,7 @@ public void merge10AsyncStreamOf1000() { @Test public void merge1000AsyncStreamOf1000() { - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); mergeNAsyncStreamsOfN(1000, 1000).subscribe(ts); ts.awaitTerminalEvent(); ts.assertNoErrors(); @@ -887,7 +894,7 @@ public void merge1000AsyncStreamOf1000() { @Test public void merge2000AsyncStreamOf100() { - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); mergeNAsyncStreamsOfN(2000, 100).subscribe(ts); ts.awaitTerminalEvent(); ts.assertNoErrors(); @@ -896,7 +903,7 @@ public void merge2000AsyncStreamOf100() { @Test public void merge100AsyncStreamOf1() { - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); mergeNAsyncStreamsOfN(100, 1).subscribe(ts); ts.awaitTerminalEvent(); ts.assertNoErrors(); @@ -918,7 +925,7 @@ public NbpObservable apply(Integer i) { @Test public void merge1SyncStreamOf1() { - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); mergeNSyncStreamsOfN(1, 1).subscribe(ts); ts.awaitTerminalEvent(); ts.assertNoErrors(); @@ -927,7 +934,7 @@ public void merge1SyncStreamOf1() { @Test public void merge1SyncStreamOf1000000() { - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); mergeNSyncStreamsOfN(1, 1000000).subscribe(ts); ts.awaitTerminalEvent(); ts.assertNoErrors(); @@ -936,7 +943,7 @@ public void merge1SyncStreamOf1000000() { @Test public void merge1000SyncStreamOf1000() { - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); mergeNSyncStreamsOfN(1000, 1000).subscribe(ts); ts.awaitTerminalEvent(); ts.assertNoErrors(); @@ -945,7 +952,7 @@ public void merge1000SyncStreamOf1000() { @Test public void merge10000SyncStreamOf10() { - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); mergeNSyncStreamsOfN(10000, 10).subscribe(ts); ts.awaitTerminalEvent(); ts.assertNoErrors(); @@ -954,7 +961,7 @@ public void merge10000SyncStreamOf10() { @Test public void merge1000000SyncStreamOf1() { - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); mergeNSyncStreamsOfN(1000000, 1).subscribe(ts); ts.awaitTerminalEvent(); ts.assertNoErrors(); @@ -1001,7 +1008,7 @@ public boolean hasNext() { @Test public void mergeManyAsyncSingle() { - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); NbpObservable> os = NbpObservable.range(1, 10000) .map(new Function>() { @@ -1033,14 +1040,23 @@ public void accept(NbpSubscriber s) { assertEquals(10000, ts.values().size()); } - Function> toScalar = NbpObservable::just; + Function> toScalar = new Function>() { + @Override + public NbpObservable apply(Integer v) { + return NbpObservable.just(v); + } + }; - Function> toHiddenScalar = t -> - NbpObservable.just(t).asObservable(); + Function> toHiddenScalar = new Function>() { + @Override + public NbpObservable apply(Integer t) { + return NbpObservable.just(t).asObservable(); + } + }; ; void runMerge(Function> func, NbpTestSubscriber ts) { - List list = new ArrayList<>(); + List list = new ArrayList(); for (int i = 0; i < 1000; i++) { list.add(i); } diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorMulticastTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorMulticastTest.java index d358236525..eaafb17382 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorMulticastTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorMulticastTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorObserveOnTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorObserveOnTest.java index b648f5241d..ce71c8df07 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorObserveOnTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorObserveOnTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -20,7 +20,6 @@ import java.util.Iterator; import java.util.concurrent.*; import java.util.concurrent.atomic.*; -import java.util.function.*; import org.junit.*; import org.mockito.InOrder; @@ -28,6 +27,7 @@ import io.reactivex.*; import io.reactivex.NbpObservable.NbpSubscriber; import io.reactivex.exceptions.TestException; +import io.reactivex.functions.*; import io.reactivex.schedulers.*; import io.reactivex.subscribers.nbp.NbpTestSubscriber; @@ -58,7 +58,7 @@ public void testOrdering() throws InterruptedException { NbpSubscriber NbpObserver = TestHelper.mockNbpSubscriber(); InOrder inOrder = inOrder(NbpObserver); - NbpTestSubscriber ts = new NbpTestSubscriber<>(NbpObserver); + NbpTestSubscriber ts = new NbpTestSubscriber(NbpObserver); obs.observeOn(Schedulers.computation()).subscribe(ts); @@ -384,7 +384,7 @@ public void testAfterUnsubscribeCalledThenObserverOnNextNeverCalled() { final TestScheduler testScheduler = new TestScheduler(); final NbpSubscriber NbpObserver = TestHelper.mockNbpSubscriber(); - NbpTestSubscriber ts = new NbpTestSubscriber<>(NbpObserver); + NbpTestSubscriber ts = new NbpTestSubscriber(NbpObserver); NbpObservable.just(1, 2, 3) .observeOn(testScheduler) @@ -425,7 +425,7 @@ public boolean hasNext() { } }); - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); o .take(7) .observeOn(Schedulers.newThread()) @@ -438,7 +438,7 @@ public boolean hasNext() { @Test public void testAsyncChild() { - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); NbpObservable.range(0, 100000).observeOn(Schedulers.newThread()).observeOn(Schedulers.newThread()).subscribe(ts); ts.awaitTerminalEvent(); ts.assertNoErrors(); diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorOnErrorResumeNextViaFunctionTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorOnErrorResumeNextViaFunctionTest.java index e02cd053f0..5003b4f988 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorOnErrorResumeNextViaFunctionTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorOnErrorResumeNextViaFunctionTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -18,7 +18,6 @@ import static org.mockito.Mockito.*; import java.util.concurrent.atomic.AtomicReference; -import java.util.function.Function; import org.junit.*; import org.mockito.Mockito; @@ -27,6 +26,7 @@ import io.reactivex.*; import io.reactivex.NbpObservable.*; import io.reactivex.disposables.Disposable; +import io.reactivex.functions.Function; import io.reactivex.internal.disposables.EmptyDisposable; import io.reactivex.schedulers.Schedulers; import io.reactivex.subscribers.nbp.NbpTestSubscriber; @@ -35,7 +35,7 @@ public class NbpOperatorOnErrorResumeNextViaFunctionTest { @Test public void testResumeNextWithSynchronousExecution() { - final AtomicReference receivedException = new AtomicReference<>(); + final AtomicReference receivedException = new AtomicReference(); NbpObservable w = NbpObservable.create(new NbpOnSubscribe() { @Override @@ -75,7 +75,7 @@ public NbpObservable apply(Throwable t1) { @Test public void testResumeNextWithAsyncExecution() { - final AtomicReference receivedException = new AtomicReference<>(); + final AtomicReference receivedException = new AtomicReference(); Subscription s = mock(Subscription.class); TestObservable w = new TestObservable(s, "one"); Function> resume = new Function>() { @@ -151,7 +151,7 @@ public NbpObservable apply(Throwable t1) { @Test @Ignore("Failed operator may leave the child NbpSubscriber in an inconsistent state which prevents further error delivery.") public void testOnErrorResumeReceivesErrorFromPreviousNonProtectedOperator() { - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); NbpObservable.just(1).lift(new NbpOperator() { @Override @@ -184,11 +184,11 @@ public NbpObservable apply(Throwable t1) { @Test @Ignore("A crashing operator may leave the downstream in an inconsistent state and not suitable for event delivery") public void testOnErrorResumeReceivesErrorFromPreviousNonProtectedOperatorOnNext() { - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); NbpObservable.just(1).lift(new NbpOperator() { @Override - public NbpSubscriber apply(NbpSubscriber t1) { + public NbpSubscriber apply(final NbpSubscriber t1) { return new NbpSubscriber() { @Override @@ -261,7 +261,7 @@ public NbpObservable apply(Throwable t1) { @SuppressWarnings("unchecked") NbpObserver NbpObserver = mock(NbpObserver.class); - NbpTestSubscriber ts = new NbpTestSubscriber<>(NbpObserver); + NbpTestSubscriber ts = new NbpTestSubscriber(NbpObserver); o.subscribe(ts); ts.awaitTerminalEvent(); @@ -313,7 +313,7 @@ public void run() { @Test public void testBackpressure() { - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); NbpObservable.range(0, 100000) .onErrorResumeNext(new Function>() { diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorOnErrorResumeNextViaObservableTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorOnErrorResumeNextViaObservableTest.java index e60becf48d..c68b728f34 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorOnErrorResumeNextViaObservableTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorOnErrorResumeNextViaObservableTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -17,14 +17,13 @@ import static org.mockito.Matchers.any; import static org.mockito.Mockito.*; -import java.util.function.Function; - import org.junit.*; import org.mockito.Mockito; import io.reactivex.*; import io.reactivex.NbpObservable.*; import io.reactivex.disposables.Disposable; +import io.reactivex.functions.Function; import io.reactivex.schedulers.Schedulers; import io.reactivex.subscribers.nbp.NbpTestSubscriber; @@ -137,7 +136,7 @@ public void accept(NbpSubscriber t1) { @SuppressWarnings("unchecked") NbpObserver NbpObserver = mock(NbpObserver.class); - NbpTestSubscriber ts = new NbpTestSubscriber<>(NbpObserver); + NbpTestSubscriber ts = new NbpTestSubscriber(NbpObserver); NbpObservable.subscribe(ts); ts.awaitTerminalEvent(); @@ -191,7 +190,7 @@ public void run() { @Test public void testBackpressure() { - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); NbpObservable.range(0, 100000) .onErrorResumeNext(NbpObservable.just(1)) .observeOn(Schedulers.computation()) diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorOnErrorReturnTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorOnErrorReturnTest.java index 1ebb9957ba..ed2b423f33 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorOnErrorReturnTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorOnErrorReturnTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -18,13 +18,13 @@ import static org.mockito.Mockito.*; import java.util.concurrent.atomic.AtomicReference; -import java.util.function.Function; import org.junit.Test; import org.mockito.Mockito; import io.reactivex.*; import io.reactivex.NbpObservable.*; +import io.reactivex.functions.Function; import io.reactivex.internal.disposables.EmptyDisposable; import io.reactivex.schedulers.Schedulers; import io.reactivex.subscribers.nbp.NbpTestSubscriber; @@ -35,7 +35,7 @@ public class NbpOperatorOnErrorReturnTest { public void testResumeNext() { TestObservable f = new TestObservable("one"); NbpObservable w = NbpObservable.create(f); - final AtomicReference capturedException = new AtomicReference<>(); + final AtomicReference capturedException = new AtomicReference(); NbpObservable NbpObservable = w.onErrorReturn(new Function() { @@ -71,7 +71,7 @@ public String apply(Throwable e) { public void testFunctionThrowsError() { TestObservable f = new TestObservable("one"); NbpObservable w = NbpObservable.create(f); - final AtomicReference capturedException = new AtomicReference<>(); + final AtomicReference capturedException = new AtomicReference(); NbpObservable NbpObservable = w.onErrorReturn(new Function() { @@ -130,7 +130,7 @@ public String apply(Throwable t1) { @SuppressWarnings("unchecked") NbpObserver NbpObserver = mock(NbpObserver.class); - NbpTestSubscriber ts = new NbpTestSubscriber<>(NbpObserver); + NbpTestSubscriber ts = new NbpTestSubscriber(NbpObserver); NbpObservable.subscribe(ts); ts.awaitTerminalEvent(); @@ -144,7 +144,7 @@ public String apply(Throwable t1) { @Test public void testBackpressure() { - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); NbpObservable.range(0, 100000) .onErrorReturn(new Function() { diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorOnExceptionResumeNextViaObservableTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorOnExceptionResumeNextViaObservableTest.java index 3682979188..4f95e6ac9b 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorOnExceptionResumeNextViaObservableTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorOnExceptionResumeNextViaObservableTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -17,13 +17,13 @@ import static org.mockito.Matchers.any; import static org.mockito.Mockito.*; -import java.util.function.Function; - import org.junit.Test; import org.mockito.Mockito; import io.reactivex.*; import io.reactivex.NbpObservable.*; +import io.reactivex.disposables.Disposable; +import io.reactivex.functions.Function; import io.reactivex.internal.disposables.EmptyDisposable; import io.reactivex.schedulers.Schedulers; import io.reactivex.subscribers.nbp.NbpTestSubscriber; @@ -47,7 +47,7 @@ public void testResumeNextWithException() { fail(e.getMessage()); } - verify(NbpObserver).onSubscribe(any()); + verify(NbpObserver).onSubscribe((Disposable)any()); verify(NbpObserver, times(1)).onNext("one"); verify(NbpObserver, Mockito.never()).onNext("two"); verify(NbpObserver, Mockito.never()).onNext("three"); @@ -75,7 +75,7 @@ public void testResumeNextWithRuntimeException() { fail(e.getMessage()); } - verify(NbpObserver).onSubscribe(any()); + verify(NbpObserver).onSubscribe((Disposable)any()); verify(NbpObserver, times(1)).onNext("one"); verify(NbpObserver, Mockito.never()).onNext("two"); verify(NbpObserver, Mockito.never()).onNext("three"); @@ -103,7 +103,7 @@ public void testThrowablePassesThru() { fail(e.getMessage()); } - verify(NbpObserver).onSubscribe(any()); + verify(NbpObserver).onSubscribe((Disposable)any()); verify(NbpObserver, times(1)).onNext("one"); verify(NbpObserver, never()).onNext("two"); verify(NbpObserver, never()).onNext("three"); @@ -131,7 +131,7 @@ public void testErrorPassesThru() { fail(e.getMessage()); } - verify(NbpObserver).onSubscribe(any()); + verify(NbpObserver).onSubscribe((Disposable)any()); verify(NbpObserver, times(1)).onNext("one"); verify(NbpObserver, never()).onNext("two"); verify(NbpObserver, never()).onNext("three"); @@ -188,7 +188,7 @@ public String apply(String s) { @Test public void testBackpressure() { - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); NbpObservable.range(0, 100000) .onExceptionResumeNext(NbpObservable.just(1)) .observeOn(Schedulers.computation()) diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorPublishTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorPublishTest.java index 9479b110a1..f86c7e9472 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorPublishTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorPublishTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -18,18 +18,19 @@ import java.util.*; import java.util.concurrent.*; import java.util.concurrent.atomic.*; -import java.util.function.*; import org.junit.Test; -import io.reactivex.NbpObservable; +import io.reactivex.*; import io.reactivex.NbpObservable.*; -import io.reactivex.Observable; import io.reactivex.disposables.Disposable; +import io.reactivex.functions.*; import io.reactivex.internal.disposables.EmptyDisposable; +import io.reactivex.internal.operators.nbp.NbpOperatorPublish; import io.reactivex.observables.nbp.NbpConnectableObservable; import io.reactivex.schedulers.*; import io.reactivex.subscribers.nbp.NbpTestSubscriber; +import io.reactivex.Observable; public class NbpOperatorPublishTest { @@ -90,7 +91,12 @@ public void accept(String v) { public void testBackpressureFastSlow() { NbpConnectableObservable is = NbpObservable.range(1, Observable.bufferSize() * 2).publish(); NbpObservable fast = is.observeOn(Schedulers.computation()) - .doOnComplete(() -> System.out.println("^^^^^^^^^^^^^ completed FAST")); + .doOnComplete(new Runnable() { + @Override + public void run() { + System.out.println("^^^^^^^^^^^^^ completed FAST"); + } + }); NbpObservable slow = is.observeOn(Schedulers.computation()).map(new Function() { int c = 0; @@ -116,7 +122,7 @@ public void run() { }); - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); NbpObservable.merge(fast, slow).subscribe(ts); is.connect(); ts.awaitTerminalEvent(); @@ -136,7 +142,7 @@ public void accept(Integer t1) { } }); - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); xs.publish(new Function, NbpObservable>() { @Override @@ -163,7 +169,7 @@ public boolean test(Integer i) { @Test public void testTakeUntilWithPublishedStream() { NbpObservable xs = NbpObservable.range(0, Observable.bufferSize() * 2); - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); NbpConnectableObservable xsp = xs.publish(); xsp.takeUntil(xsp.skipWhile(new Predicate() { @@ -199,7 +205,7 @@ public void run() { final AtomicBoolean child1Unsubscribed = new AtomicBoolean(); final AtomicBoolean child2Unsubscribed = new AtomicBoolean(); - final NbpTestSubscriber ts2 = new NbpTestSubscriber<>(); + final NbpTestSubscriber ts2 = new NbpTestSubscriber(); final NbpTestSubscriber ts1 = new NbpTestSubscriber() { @Override @@ -247,7 +253,7 @@ public void testConnectWithNoSubscriber() { co.connect(); // Emit 0 scheduler.advanceTimeBy(15, TimeUnit.MILLISECONDS); - NbpTestSubscriber NbpSubscriber = new NbpTestSubscriber<>(); + NbpTestSubscriber NbpSubscriber = new NbpTestSubscriber(); co.subscribe(NbpSubscriber); // Emit 1 and 2 scheduler.advanceTimeBy(50, TimeUnit.MILLISECONDS); @@ -260,7 +266,7 @@ public void testConnectWithNoSubscriber() { public void testSubscribeAfterDisconnectThenConnect() { NbpConnectableObservable source = NbpObservable.just(1).publish(); - NbpTestSubscriber ts1 = new NbpTestSubscriber<>(); + NbpTestSubscriber ts1 = new NbpTestSubscriber(); source.subscribe(ts1); @@ -270,7 +276,7 @@ public void testSubscribeAfterDisconnectThenConnect() { ts1.assertNoErrors(); ts1.assertTerminated(); - NbpTestSubscriber ts2 = new NbpTestSubscriber<>(); + NbpTestSubscriber ts2 = new NbpTestSubscriber(); source.subscribe(ts2); @@ -288,7 +294,7 @@ public void testSubscribeAfterDisconnectThenConnect() { public void testNoSubscriberRetentionOnCompleted() { NbpOperatorPublish source = (NbpOperatorPublish)NbpObservable.just(1).publish(); - NbpTestSubscriber ts1 = new NbpTestSubscriber<>(); + NbpTestSubscriber ts1 = new NbpTestSubscriber(); source.unsafeSubscribe(ts1); @@ -369,9 +375,9 @@ public void testObserveOn() { NbpObservable obs = co.observeOn(Schedulers.computation()); for (int i = 0; i < 1000; i++) { for (int j = 1; j < 6; j++) { - List> tss = new ArrayList<>(); + List> tss = new ArrayList>(); for (int k = 1; k < j; k++) { - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); tss.add(ts); obs.subscribe(ts); } diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorReduceTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorReduceTest.java index 499fb83f7f..057671c140 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorReduceTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorReduceTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -17,13 +17,12 @@ import static org.mockito.Matchers.any; import static org.mockito.Mockito.*; -import java.util.function.*; - import org.junit.*; import io.reactivex.*; import io.reactivex.NbpObservable.NbpSubscriber; import io.reactivex.exceptions.TestException; +import io.reactivex.functions.*; public class NbpOperatorReduceTest { NbpSubscriber NbpObserver; @@ -44,7 +43,12 @@ public Integer apply(Integer t1, Integer t2) { public void testAggregateAsIntSum() { NbpObservable result = NbpObservable.just(1, 2, 3, 4, 5).reduce(0, sum) - .map(v -> v); + .map(new Function() { + @Override + public Integer apply(Integer v) { + return v; + } + }); result.subscribe(NbpObserver); @@ -57,7 +61,12 @@ public void testAggregateAsIntSum() { public void testAggregateAsIntSumSourceThrows() { NbpObservable result = NbpObservable.concat(NbpObservable.just(1, 2, 3, 4, 5), NbpObservable. error(new TestException())) - .reduce(0, sum).map(v -> v); + .reduce(0, sum).map(new Function() { + @Override + public Integer apply(Integer v) { + return v; + } + }); result.subscribe(NbpObserver); @@ -76,7 +85,12 @@ public Integer apply(Integer t1, Integer t2) { }; NbpObservable result = NbpObservable.just(1, 2, 3, 4, 5) - .reduce(0, sumErr).map(v -> v); + .reduce(0, sumErr).map(new Function() { + @Override + public Integer apply(Integer v) { + return v; + } + }); result.subscribe(NbpObserver); diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorRepeatTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorRepeatTest.java index 64fc9c88a2..271c76d19d 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorRepeatTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorRepeatTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -20,13 +20,13 @@ import java.util.*; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.Function; import org.junit.Test; import io.reactivex.*; import io.reactivex.NbpObservable.*; import io.reactivex.exceptions.TestException; +import io.reactivex.functions.Function; import io.reactivex.internal.disposables.EmptyDisposable; import io.reactivex.schedulers.Schedulers; import io.reactivex.subscribers.nbp.NbpTestSubscriber; @@ -160,7 +160,7 @@ public void testRepeatAndDistinctUnbounded() { .repeat(3) .distinct(); - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); src.subscribe(ts); @@ -172,8 +172,8 @@ public void testRepeatAndDistinctUnbounded() { /** Issue #2844: wrong target of request. */ @Test(timeout = 3000) public void testRepeatRetarget() { - final List concatBase = new ArrayList<>(); - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + final List concatBase = new ArrayList(); + NbpTestSubscriber ts = new NbpTestSubscriber(); NbpObservable.just(1, 2) .repeat(5) .concatMap(new Function>() { diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorReplayTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorReplayTest.java index 089e518785..e7412b1e81 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorReplayTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorReplayTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -19,8 +19,7 @@ import java.util.*; import java.util.concurrent.*; -import java.util.concurrent.atomic.*; -import java.util.function.*; +import java.util.concurrent.atomic.AtomicInteger; import org.junit.*; import org.mockito.InOrder; @@ -30,6 +29,7 @@ import io.reactivex.Scheduler.Worker; import io.reactivex.disposables.Disposable; import io.reactivex.exceptions.TestException; +import io.reactivex.functions.*; import io.reactivex.internal.disposables.EmptyDisposable; import io.reactivex.internal.operators.nbp.NbpOperatorReplay.*; import io.reactivex.observables.nbp.NbpConnectableObservable; @@ -531,8 +531,8 @@ public void testIssue2191_UnsubscribeSource() { replay.subscribe(spiedSubscriberAfterConnect); replay.subscribe(spiedSubscriberAfterConnect); - verify(spiedSubscriberBeforeConnect, times(2)).onSubscribe(any()); - verify(spiedSubscriberAfterConnect, times(2)).onSubscribe(any()); + verify(spiedSubscriberBeforeConnect, times(2)).onSubscribe((Disposable)any()); + verify(spiedSubscriberAfterConnect, times(2)).onSubscribe((Disposable)any()); // verify interactions verify(sourceNext, times(1)).accept(1); @@ -579,8 +579,8 @@ public void testIssue2191_SchedulerUnsubscribe() throws Exception { replay.connect(); replay.subscribe(mockObserverAfterConnect); - verify(mockObserverBeforeConnect).onSubscribe(any()); - verify(mockObserverAfterConnect).onSubscribe(any()); + verify(mockObserverBeforeConnect).onSubscribe((Disposable)any()); + verify(mockObserverAfterConnect).onSubscribe((Disposable)any()); mockScheduler.advanceTimeBy(1, TimeUnit.SECONDS); @@ -637,8 +637,8 @@ public void testIssue2191_SchedulerUnsubscribeOnError() throws Exception { replay.connect(); replay.subscribe(mockObserverAfterConnect); - verify(mockObserverBeforeConnect).onSubscribe(any()); - verify(mockObserverAfterConnect).onSubscribe(any()); + verify(mockObserverBeforeConnect).onSubscribe((Disposable)any()); + verify(mockObserverAfterConnect).onSubscribe((Disposable)any()); mockScheduler.advanceTimeBy(1, TimeUnit.SECONDS); @@ -712,14 +712,14 @@ public void dispose() { @Test public void testBoundedReplayBuffer() { - BoundedReplayBuffer buf = new BoundedReplayBuffer<>(); + BoundedReplayBuffer buf = new BoundedReplayBuffer(); buf.addLast(new Node(1)); buf.addLast(new Node(2)); buf.addLast(new Node(3)); buf.addLast(new Node(4)); buf.addLast(new Node(5)); - List values = new ArrayList<>(); + List values = new ArrayList(); buf.collect(values); Assert.assertEquals(Arrays.asList(1, 2, 3, 4, 5), values); @@ -743,8 +743,8 @@ public void testBoundedReplayBuffer() { @Test public void testTimedAndSizedTruncation() { TestScheduler test = Schedulers.test(); - SizeAndTimeBoundReplayBuffer buf = new SizeAndTimeBoundReplayBuffer<>(2, 2000, TimeUnit.MILLISECONDS, test); - List values = new ArrayList<>(); + SizeAndTimeBoundReplayBuffer buf = new SizeAndTimeBoundReplayBuffer(2, 2000, TimeUnit.MILLISECONDS, test); + List values = new ArrayList(); buf.next(1); test.advanceTimeBy(1, TimeUnit.SECONDS); @@ -781,7 +781,7 @@ public void testTimedAndSizedTruncation() { public void testColdReplayNoBackpressure() { NbpObservable source = NbpObservable.range(0, 1000).replay().autoConnect(); - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); source.subscribe(ts); @@ -859,7 +859,7 @@ public void testUnsubscribeSource() { @Test public void testTake() { - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); NbpObservable cached = NbpObservable.range(1, 100).replay().autoConnect(); cached.take(10).subscribe(ts); @@ -875,7 +875,7 @@ public void testTake() { public void testAsync() { NbpObservable source = NbpObservable.range(1, 10000); for (int i = 0; i < 100; i++) { - NbpTestSubscriber ts1 = new NbpTestSubscriber<>(); + NbpTestSubscriber ts1 = new NbpTestSubscriber(); NbpObservable cached = source.replay().autoConnect(); @@ -886,7 +886,7 @@ public void testAsync() { ts1.assertTerminated(); assertEquals(10000, ts1.values().size()); - NbpTestSubscriber ts2 = new NbpTestSubscriber<>(); + NbpTestSubscriber ts2 = new NbpTestSubscriber(); cached.observeOn(Schedulers.computation()).subscribe(ts2); ts2.awaitTerminalEvent(2, TimeUnit.SECONDS); @@ -904,14 +904,14 @@ public void testAsyncComeAndGo() { NbpObservable output = cached.observeOn(Schedulers.computation()); - List> list = new ArrayList<>(100); + List> list = new ArrayList>(100); for (int i = 0; i < 100; i++) { - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); list.add(ts); output.skip(i * 10).take(10).subscribe(ts); } - List expected = new ArrayList<>(); + List expected = new ArrayList(); for (int i = 0; i < 10; i++) { expected.add((long)(i - 10)); } @@ -945,7 +945,7 @@ public void accept(NbpSubscriber t) { } }); - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); firehose.replay().autoConnect().observeOn(Schedulers.computation()).takeLast(100).subscribe(ts); ts.awaitTerminalEvent(3, TimeUnit.SECONDS); @@ -962,14 +962,14 @@ public void testValuesAndThenError() { .replay().autoConnect(); - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); source.subscribe(ts); ts.assertValues(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); ts.assertNotComplete(); Assert.assertEquals(1, ts.errors().size()); - NbpTestSubscriber ts2 = new NbpTestSubscriber<>(); + NbpTestSubscriber ts2 = new NbpTestSubscriber(); source.subscribe(ts2); ts2.assertValues(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorRetryTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorRetryTest.java index 9f9fbad4cd..01e9790ed5 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorRetryTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorRetryTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -20,21 +20,21 @@ import java.util.*; import java.util.concurrent.*; import java.util.concurrent.atomic.*; -import java.util.function.*; import org.junit.Test; import org.mockito.*; import io.reactivex.*; import io.reactivex.NbpObservable.*; -import io.reactivex.Observable; import io.reactivex.disposables.Disposable; +import io.reactivex.functions.*; import io.reactivex.internal.disposables.EmptyDisposable; import io.reactivex.internal.subscriptions.BooleanSubscription; import io.reactivex.observables.nbp.NbpGroupedObservable; import io.reactivex.schedulers.Schedulers; import io.reactivex.subjects.nbp.NbpPublishSubject; import io.reactivex.subscribers.nbp.NbpTestSubscriber; +import io.reactivex.Observable; public class NbpOperatorRetryTest { @@ -61,11 +61,11 @@ public void accept(NbpSubscriber t1) { } }); - NbpTestSubscriber ts = new NbpTestSubscriber<>(consumer); - producer.retryWhen(new Function, NbpObservable>() { + NbpTestSubscriber ts = new NbpTestSubscriber(consumer); + producer.retryWhen(new Function, NbpObservable>() { @Override - public NbpObservable apply(NbpObservable attempts) { + public NbpObservable apply(NbpObservable attempts) { // Worker w = Schedulers.computation().createWorker(); return attempts .map(new Function() { @@ -85,7 +85,7 @@ public NbpObservable apply(Tuple t) { return t.count > 20 ? NbpObservable.error(t.n) : NbpObservable.timer(t.count *1L, TimeUnit.MILLISECONDS); - }}); + }}).cast(Object.class); } }).subscribe(ts); ts.awaitTerminalEvent(); @@ -114,7 +114,7 @@ public void testRetryIndefinitely() { NbpSubscriber NbpObserver = TestHelper.mockNbpSubscriber(); int NUM_RETRIES = 20; NbpObservable origin = NbpObservable.create(new FuncWithErrors(NUM_RETRIES)); - origin.retry().unsafeSubscribe(new NbpTestSubscriber<>(NbpObserver)); + origin.retry().unsafeSubscribe(new NbpTestSubscriber(NbpObserver)); InOrder inOrder = inOrder(NbpObserver); // should show 3 attempts @@ -133,19 +133,26 @@ public void testSchedulingNotificationHandler() { NbpSubscriber NbpObserver = TestHelper.mockNbpSubscriber(); int NUM_RETRIES = 2; NbpObservable origin = NbpObservable.create(new FuncWithErrors(NUM_RETRIES)); - NbpTestSubscriber NbpSubscriber = new NbpTestSubscriber<>(NbpObserver); - origin.retryWhen(new Function, NbpObservable>() { + NbpTestSubscriber NbpSubscriber = new NbpTestSubscriber(NbpObserver); + origin.retryWhen(new Function, NbpObservable>() { @Override - public NbpObservable apply(NbpObservable t1) { - return t1.observeOn(Schedulers.computation()).map(new Function() { + public NbpObservable apply(NbpObservable t1) { + return t1 + .observeOn(Schedulers.computation()) + .map(new Function() { @Override - public Integer apply(Throwable t1) { + public Object apply(Throwable t1) { return 1; } }).startWith(1); } }) - .doOnError(Throwable::printStackTrace) + .doOnError(new Consumer() { + @Override + public void accept(Throwable e) { + e.printStackTrace(); + } + }) .subscribe(NbpSubscriber); NbpSubscriber.awaitTerminalEvent(); @@ -166,16 +173,16 @@ public void testOnNextFromNotificationHandler() { NbpSubscriber NbpObserver = TestHelper.mockNbpSubscriber(); int NUM_RETRIES = 2; NbpObservable origin = NbpObservable.create(new FuncWithErrors(NUM_RETRIES)); - origin.retryWhen(new Function, NbpObservable>() { + origin.retryWhen(new Function, NbpObservable>() { @Override - public NbpObservable apply(NbpObservable t1) { + public NbpObservable apply(NbpObservable t1) { return t1.map(new Function() { @Override public Integer apply(Throwable t1) { return 0; } - }).startWith(0); + }).startWith(0).cast(Object.class); } }).subscribe(NbpObserver); @@ -195,7 +202,7 @@ public Integer apply(Throwable t1) { public void testOnCompletedFromNotificationHandler() { NbpSubscriber NbpObserver = TestHelper.mockNbpSubscriber(); NbpObservable origin = NbpObservable.create(new FuncWithErrors(1)); - NbpTestSubscriber NbpSubscriber = new NbpTestSubscriber<>(NbpObserver); + NbpTestSubscriber NbpSubscriber = new NbpTestSubscriber(NbpObserver); origin.retryWhen(new Function, NbpObservable>() { @Override public NbpObservable apply(NbpObservable t1) { @@ -423,8 +430,11 @@ public void testRetryAllowsSubscriptionAfterAllSubscriptionsUnsubscribed() throw @Override public void accept(NbpSubscriber s) { subsCount.incrementAndGet(); - s.onSubscribe(() -> { - subsCount.decrementAndGet(); + s.onSubscribe(new Disposable() { + @Override + public void dispose() { + subsCount.decrementAndGet(); + } }); } @@ -443,7 +453,7 @@ public void accept(NbpSubscriber s) { public void testSourceObservableCallsUnsubscribe() throws InterruptedException { final AtomicInteger subsCount = new AtomicInteger(0); - final NbpTestSubscriber ts = new NbpTestSubscriber<>(); + final NbpTestSubscriber ts = new NbpTestSubscriber(); NbpOnSubscribe onSubscribe = new NbpOnSubscribe() { @Override @@ -474,7 +484,7 @@ public void accept(NbpSubscriber s) { public void testSourceObservableRetry1() throws InterruptedException { final AtomicInteger subsCount = new AtomicInteger(0); - final NbpTestSubscriber ts = new NbpTestSubscriber<>(); + final NbpTestSubscriber ts = new NbpTestSubscriber(); NbpOnSubscribe onSubscribe = new NbpOnSubscribe() { @Override @@ -493,7 +503,7 @@ public void accept(NbpSubscriber s) { public void testSourceObservableRetry0() throws InterruptedException { final AtomicInteger subsCount = new AtomicInteger(0); - final NbpTestSubscriber ts = new NbpTestSubscriber<>(); + final NbpTestSubscriber ts = new NbpTestSubscriber(); NbpOnSubscribe onSubscribe = new NbpOnSubscribe() { @Override @@ -524,9 +534,12 @@ public SlowObservable(int emitDelay, int countNext) { @Override public void accept(final NbpSubscriber NbpSubscriber) { final AtomicBoolean terminate = new AtomicBoolean(false); - NbpSubscriber.onSubscribe(() -> { - terminate.set(true); - active.decrementAndGet(); + NbpSubscriber.onSubscribe(new Disposable() { + @Override + public void dispose() { + terminate.set(true); + active.decrementAndGet(); + } }); efforts.getAndIncrement(); active.getAndIncrement(); @@ -559,7 +572,10 @@ static final class AsyncObserver extends NbpObserver { protected NbpSubscriber target; - /** Wrap existing NbpObserver */ + /** + * Wrap existing NbpObserver + * @param target the target nbp subscriber + */ public AsyncObserver(NbpSubscriber target) { this.target = target; } @@ -602,7 +618,7 @@ public void testUnsubscribeAfterError() { SlowObservable so = new SlowObservable(100, 0); NbpObservable o = NbpObservable.create(so).retry(5); - AsyncObserver async = new AsyncObserver<>(NbpObserver); + AsyncObserver async = new AsyncObserver(NbpObserver); o.subscribe(async); @@ -627,7 +643,7 @@ public void testTimeoutWithRetry() { SlowObservable so = new SlowObservable(100, 10); NbpObservable o = NbpObservable.create(so).timeout(80, TimeUnit.MILLISECONDS).retry(5); - AsyncObserver async = new AsyncObserver<>(NbpObserver); + AsyncObserver async = new AsyncObserver(NbpObserver); o.subscribe(async); @@ -649,7 +665,7 @@ public void testRetryWithBackpressure() throws InterruptedException { for (int i = 0; i < 400; i++) { NbpSubscriber NbpObserver = TestHelper.mockNbpSubscriber(); NbpObservable origin = NbpObservable.create(new FuncWithErrors(NUM_RETRIES)); - NbpTestSubscriber ts = new NbpTestSubscriber<>(NbpObserver); + NbpTestSubscriber ts = new NbpTestSubscriber(NbpObserver); origin.retry().observeOn(Schedulers.computation()).unsafeSubscribe(ts); ts.awaitTerminalEvent(5, TimeUnit.SECONDS); @@ -680,7 +696,7 @@ public void testRetryWithBackpressureParallel() throws InterruptedException { } final AtomicInteger timeouts = new AtomicInteger(); - final Map> data = new ConcurrentHashMap<>(); + final Map> data = new ConcurrentHashMap>(); int m = 5000; final CountDownLatch cdl = new CountDownLatch(m); @@ -692,11 +708,11 @@ public void run() { final AtomicInteger nexts = new AtomicInteger(); try { NbpObservable origin = NbpObservable.create(new FuncWithErrors(NUM_RETRIES)); - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); origin.retry() .observeOn(Schedulers.computation()).unsafeSubscribe(ts); ts.awaitTerminalEvent(2500, TimeUnit.MILLISECONDS); - List onNextEvents = new ArrayList<>(ts.values()); + List onNextEvents = new ArrayList(ts.values()); if (onNextEvents.size() != NUM_RETRIES + 2) { for (Throwable t : ts.errors()) { onNextEvents.add(t.toString()); @@ -793,7 +809,7 @@ public NbpObservable apply(NbpGroupedObservable t1) { return t1.take(1); } }) - .unsafeSubscribe(new NbpTestSubscriber<>(NbpObserver)); + .unsafeSubscribe(new NbpTestSubscriber(NbpObserver)); InOrder inOrder = inOrder(NbpObserver); // should show 3 attempts @@ -837,7 +853,7 @@ public NbpObservable apply(NbpGroupedObservable t1) { return t1.take(1); } }) - .unsafeSubscribe(new NbpTestSubscriber<>(NbpObserver)); + .unsafeSubscribe(new NbpTestSubscriber(NbpObserver)); InOrder inOrder = inOrder(NbpObserver); // should show 3 attempts diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorRetryWithPredicateTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorRetryWithPredicateTest.java index e4ee560996..8ab79a2aaf 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorRetryWithPredicateTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorRetryWithPredicateTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -21,7 +21,6 @@ import java.util.*; import java.util.concurrent.*; import java.util.concurrent.atomic.*; -import java.util.function.*; import org.junit.Test; import org.mockito.InOrder; @@ -30,6 +29,7 @@ import io.reactivex.NbpObservable.*; import io.reactivex.disposables.Disposable; import io.reactivex.exceptions.TestException; +import io.reactivex.functions.*; import io.reactivex.internal.disposables.EmptyDisposable; import io.reactivex.subjects.nbp.NbpPublishSubject; import io.reactivex.subscribers.nbp.NbpTestSubscriber; @@ -233,7 +233,7 @@ public void testUnsubscribeAfterError() { .create(so) .retry(retry5); - NbpOperatorRetryTest.AsyncObserver async = new NbpOperatorRetryTest.AsyncObserver<>(NbpObserver); + NbpOperatorRetryTest.AsyncObserver async = new NbpOperatorRetryTest.AsyncObserver(NbpObserver); o.subscribe(async); @@ -260,7 +260,7 @@ public void testTimeoutWithRetry() { .timeout(80, TimeUnit.MILLISECONDS) .retry(retry5); - NbpOperatorRetryTest.AsyncObserver async = new NbpOperatorRetryTest.AsyncObserver<>(NbpObserver); + NbpOperatorRetryTest.AsyncObserver async = new NbpOperatorRetryTest.AsyncObserver(NbpObserver); o.subscribe(async); @@ -276,7 +276,7 @@ public void testTimeoutWithRetry() { @Test public void testIssue2826() { - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); final RuntimeException e = new RuntimeException("You shall not pass"); final AtomicInteger c = new AtomicInteger(); NbpObservable.just(1).map(new Function() { @@ -309,7 +309,7 @@ public Integer apply(Integer t1) { @Test public void testIssue3008RetryWithPredicate() { - final List list = new CopyOnWriteArrayList<>(); + final List list = new CopyOnWriteArrayList(); final AtomicBoolean isFirst = new AtomicBoolean(true); NbpObservable. just(1L, 2L, 3L).map(new Function(){ @Override @@ -337,7 +337,7 @@ public void accept(Long t) { @Test public void testIssue3008RetryInfinite() { - final List list = new CopyOnWriteArrayList<>(); + final List list = new CopyOnWriteArrayList(); final AtomicBoolean isFirst = new AtomicBoolean(true); NbpObservable. just(1L, 2L, 3L).map(new Function(){ @Override diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorSampleTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorSampleTest.java index 3045ce5b2f..3626ea6759 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorSampleTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorSampleTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorScanTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorScanTest.java index 5eb499a097..3e0bb925d6 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorScanTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorScanTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -19,12 +19,12 @@ import java.util.*; import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.*; import org.junit.Test; import io.reactivex.*; import io.reactivex.NbpObservable.NbpSubscriber; +import io.reactivex.functions.*; import io.reactivex.subjects.nbp.NbpPublishSubject; import io.reactivex.subscribers.nbp.NbpTestSubscriber; @@ -108,7 +108,7 @@ public Integer apply(Integer t1, Integer t2) { @Test public void shouldNotEmitUntilAfterSubscription() { - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); NbpObservable.range(1, 100).scan(0, new BiFunction() { @Override @@ -175,7 +175,7 @@ public void testSeedFactory() { @Override public List get() { - return new ArrayList<>(); + return new ArrayList(); } }, new BiConsumer, Integer>() { @@ -201,7 +201,7 @@ public Integer apply(Integer t1, Integer t2) { } }).take(1); - NbpTestSubscriber NbpSubscriber = new NbpTestSubscriber<>(); + NbpTestSubscriber NbpSubscriber = new NbpTestSubscriber(); o.subscribe(NbpSubscriber); NbpSubscriber.assertValue(0); NbpSubscriber.assertTerminated(); @@ -212,7 +212,7 @@ public Integer apply(Integer t1, Integer t2) { public void testInitialValueEmittedNoProducer() { NbpPublishSubject source = NbpPublishSubject.create(); - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); source.scan(0, new BiFunction() { @Override diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorSequenceEqualTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorSequenceEqualTest.java index 1102b9edaf..725889e7db 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorSequenceEqualTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorSequenceEqualTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -16,14 +16,13 @@ import static org.mockito.Matchers.isA; import static org.mockito.Mockito.*; -import java.util.function.BiPredicate; - import org.junit.*; import org.mockito.InOrder; import io.reactivex.*; import io.reactivex.NbpObservable.NbpSubscriber; import io.reactivex.exceptions.TestException; +import io.reactivex.functions.BiPredicate; public class NbpOperatorSequenceEqualTest { diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorSerializeTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorSerializeTest.java index 5d912fa2fd..5158644866 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorSerializeTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorSerializeTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorSingleTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorSingleTest.java index d7e70a01b7..2c112e4d3f 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorSingleTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorSingleTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -18,13 +18,13 @@ import static org.mockito.Mockito.*; import java.util.NoSuchElementException; -import java.util.function.Predicate; import org.junit.Test; import org.mockito.InOrder; import io.reactivex.*; import io.reactivex.NbpObservable.NbpSubscriber; +import io.reactivex.functions.*; public class NbpOperatorSingleTest { @@ -175,7 +175,12 @@ public void testSingleOrDefaultWithEmpty() { @Test public void testSingleOrDefaultWithPredicate() { NbpObservable o = NbpObservable.just(1, 2) - .filter(t1 -> t1 % 2 == 0) + .filter(new Predicate() { + @Override + public boolean test(Integer t1) { + return t1 % 2 == 0; + } + }) .single(4); NbpSubscriber NbpObserver = TestHelper.mockNbpSubscriber(); @@ -190,7 +195,12 @@ public void testSingleOrDefaultWithPredicate() { @Test public void testSingleOrDefaultWithPredicateAndTooManyElements() { NbpObservable o = NbpObservable.just(1, 2, 3, 4) - .filter(t1 -> t1 % 2 == 0) + .filter(new Predicate() { + @Override + public boolean test(Integer t1) { + return t1 % 2 == 0; + } + }) .single(6); NbpSubscriber NbpObserver = TestHelper.mockNbpSubscriber(); @@ -205,7 +215,12 @@ public void testSingleOrDefaultWithPredicateAndTooManyElements() { @Test public void testSingleOrDefaultWithPredicateAndEmpty() { NbpObservable o = NbpObservable.just(1) - .filter(t1 -> t1 % 2 == 0) + .filter(new Predicate() { + @Override + public boolean test(Integer t1) { + return t1 % 2 == 0; + } + }) .single(2); NbpSubscriber NbpObserver = TestHelper.mockNbpSubscriber(); @@ -221,7 +236,12 @@ public void testSingleOrDefaultWithPredicateAndEmpty() { public void testIssue1527() throws InterruptedException { //https://github.com/ReactiveX/RxJava/pull/1527 NbpObservable source = NbpObservable.just(1, 2, 3, 4, 5, 6); - NbpObservable reduced = source.reduce((i1, i2) -> i1 + i2); + NbpObservable reduced = source.reduce(new BiFunction() { + @Override + public Integer apply(Integer i1, Integer i2) { + return i1 + i2; + } + }); Integer r = reduced.toBlocking().first(); assertEquals(21, r.intValue()); diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorSkipLastTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorSkipLastTest.java index f40d3c913c..b5c4932e34 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorSkipLastTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorSkipLastTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -95,7 +95,7 @@ public void testSkipLastWithNull() { @Test public void testSkipLastWithBackpressure() { NbpObservable o = NbpObservable.range(0, Observable.bufferSize() * 2).skipLast(Observable.bufferSize() + 10); - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); o.observeOn(Schedulers.computation()).subscribe(ts); ts.awaitTerminalEvent(); ts.assertNoErrors(); diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorSkipLastTimedTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorSkipLastTimedTest.java index 377bfcb0b2..5670bda448 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorSkipLastTimedTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorSkipLastTimedTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorSkipTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorSkipTest.java index 266c9797cd..78b2430cff 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorSkipTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorSkipTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -138,7 +138,7 @@ public void testSkipError() { @Test public void testRequestOverflowDoesNotOccur() { - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); NbpObservable.range(1, 10).skip(5).subscribe(ts); ts.assertTerminated(); ts.assertComplete(); diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorSkipTimedTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorSkipTimedTest.java index 58b4f0f55e..aa203a5f63 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorSkipTimedTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorSkipTimedTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorSkipUntilTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorSkipUntilTest.java index 9821e538ff..92a776acac 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorSkipUntilTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorSkipUntilTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorSkipWhileTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorSkipWhileTest.java index e4d082785b..986b015b92 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorSkipWhileTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorSkipWhileTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -16,13 +16,12 @@ import static org.mockito.Matchers.*; import static org.mockito.Mockito.*; -import java.util.function.Predicate; - import org.junit.Test; import org.mockito.InOrder; import io.reactivex.*; import io.reactivex.NbpObservable.NbpSubscriber; +import io.reactivex.functions.Predicate; public class NbpOperatorSkipWhileTest { diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorSubscribeOnTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorSubscribeOnTest.java index 98e3a7ba1e..ea04f1adb2 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorSubscribeOnTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorSubscribeOnTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -36,7 +36,7 @@ public void testIssue813() throws InterruptedException { final CountDownLatch latch = new CountDownLatch(1); final CountDownLatch doneLatch = new CountDownLatch(1); - NbpTestSubscriber NbpObserver = new NbpTestSubscriber<>(); + NbpTestSubscriber NbpObserver = new NbpTestSubscriber(); NbpObservable .create(new NbpOnSubscribe() { @@ -75,7 +75,7 @@ public void accept( @Test @Ignore("NbpOnSubscribe.subscribe can't throw") public void testThrownErrorHandling() { - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); NbpObservable.create(new NbpOnSubscribe() { @Override @@ -90,7 +90,7 @@ public void accept(NbpSubscriber s) { @Test public void testOnError() { - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); NbpObservable.create(new NbpOnSubscribe() { @Override @@ -161,7 +161,7 @@ public Disposable schedule(final Runnable action, final long delayTime, final Ti @Test(timeout = 5000) public void testUnsubscribeInfiniteStream() throws InterruptedException { - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); final AtomicInteger count = new AtomicInteger(); NbpObservable.create(new NbpOnSubscribe() { diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorSwitchIfEmptyTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorSwitchIfEmptyTest.java index 1f5d9b2383..e33c39d8df 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorSwitchIfEmptyTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorSwitchIfEmptyTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -22,7 +22,8 @@ import io.reactivex.*; import io.reactivex.NbpObservable.*; -import io.reactivex.disposables.BooleanDisposable; +import io.reactivex.disposables.*; +import io.reactivex.functions.Consumer; public class NbpOperatorSwitchIfEmptyTest { @@ -32,7 +33,12 @@ public void testSwitchWhenNotEmpty() throws Exception { final AtomicBoolean subscribed = new AtomicBoolean(false); final NbpObservable o = NbpObservable.just(4) .switchIfEmpty(NbpObservable.just(2) - .doOnSubscribe(s -> subscribed.set(true))); + .doOnSubscribe(new Consumer() { + @Override + public void accept(Disposable s) { + subscribed.set(true); + } + })); assertEquals(4, o.toBlocking().single().intValue()); assertFalse(subscribed.get()); @@ -49,7 +55,7 @@ public void testSwitchWhenEmpty() throws Exception { @Test public void testSwitchTriggerUnsubscribe() throws Exception { - BooleanDisposable bs = new BooleanDisposable(); + final BooleanDisposable bs = new BooleanDisposable(); NbpObservable withProducer = NbpObservable.create(new NbpOnSubscribe() { @Override @@ -92,7 +98,7 @@ public void onNext(Long aLong) { @Test public void testSwitchShouldTriggerUnsubscribe() { - BooleanDisposable bs = new BooleanDisposable(); + final BooleanDisposable bs = new BooleanDisposable(); NbpObservable.create(new NbpOnSubscribe() { @Override diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorSwitchTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorSwitchTest.java index 3adfb61d2d..e51c516ee2 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorSwitchTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorSwitchTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -19,7 +19,6 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; -import java.util.function.Function; import org.junit.*; import org.mockito.InOrder; @@ -28,6 +27,7 @@ import io.reactivex.NbpObservable.*; import io.reactivex.disposables.BooleanDisposable; import io.reactivex.exceptions.TestException; +import io.reactivex.functions.Function; import io.reactivex.internal.disposables.EmptyDisposable; import io.reactivex.schedulers.TestScheduler; import io.reactivex.subscribers.nbp.NbpTestSubscriber; diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorTakeLastOneTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorTakeLastOneTest.java index f345cdbd56..f533cfc741 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorTakeLastOneTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorTakeLastOneTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -16,18 +16,18 @@ import static org.junit.Assert.*; import java.util.concurrent.atomic.*; -import java.util.function.Consumer; import org.junit.Test; import io.reactivex.NbpObservable; +import io.reactivex.functions.Consumer; import io.reactivex.subscribers.nbp.NbpTestSubscriber; public class NbpOperatorTakeLastOneTest { @Test public void testLastOfManyReturnsLast() { - NbpTestSubscriber s = new NbpTestSubscriber<>(); + NbpTestSubscriber s = new NbpTestSubscriber(); NbpObservable.range(1, 10).takeLast(1).subscribe(s); s.assertValue(10); s.assertNoErrors(); @@ -38,7 +38,7 @@ public void testLastOfManyReturnsLast() { @Test public void testLastOfEmptyReturnsEmpty() { - NbpTestSubscriber s = new NbpTestSubscriber<>(); + NbpTestSubscriber s = new NbpTestSubscriber(); NbpObservable.empty().takeLast(1).subscribe(s); s.assertNoValues(); s.assertNoErrors(); @@ -49,7 +49,7 @@ public void testLastOfEmptyReturnsEmpty() { @Test public void testLastOfOneReturnsLast() { - NbpTestSubscriber s = new NbpTestSubscriber<>(); + NbpTestSubscriber s = new NbpTestSubscriber(); NbpObservable.just(1).takeLast(1).subscribe(s); s.assertValue(1); s.assertNoErrors(); diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorTakeLastTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorTakeLastTest.java index f11baddf01..caacf7b866 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorTakeLastTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorTakeLastTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -18,13 +18,13 @@ import static org.mockito.Mockito.*; import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.Function; import org.junit.*; import org.mockito.InOrder; import io.reactivex.*; import io.reactivex.NbpObservable.NbpSubscriber; +import io.reactivex.functions.*; import io.reactivex.schedulers.Schedulers; import io.reactivex.subscribers.nbp.NbpTestSubscriber; @@ -103,7 +103,7 @@ public void testTakeLastWithNegativeCount() { @Test public void testBackpressure1() { - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); NbpObservable.range(1, 100000).takeLast(1) .observeOn(Schedulers.newThread()) .map(newSlowProcessor()).subscribe(ts); @@ -114,7 +114,7 @@ public void testBackpressure1() { @Test public void testBackpressure2() { - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); NbpObservable.range(1, 100000).takeLast(Observable.bufferSize() * 4) .observeOn(Schedulers.newThread()).map(newSlowProcessor()).subscribe(ts); ts.awaitTerminalEvent(); @@ -146,7 +146,12 @@ public void testIssue1522() { assertEquals(0, NbpObservable .empty() .count() - .filter(v -> false) + .filter(new Predicate() { + @Override + public boolean test(Long v) { + return false; + } + }) .toList() .toBlocking().single().size()); } diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorTakeLastTimedTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorTakeLastTimedTest.java index 3a84f6f0f7..e3e3b6d810 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorTakeLastTimedTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorTakeLastTimedTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorTakeTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorTakeTest.java index 7f0187d9c3..48e4bffd69 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorTakeTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorTakeTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -20,7 +20,6 @@ import java.util.Arrays; import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.*; -import java.util.function.*; import org.junit.*; import org.mockito.InOrder; @@ -29,6 +28,7 @@ import io.reactivex.NbpObservable.*; import io.reactivex.disposables.*; import io.reactivex.exceptions.TestException; +import io.reactivex.functions.*; import io.reactivex.internal.disposables.EmptyDisposable; import io.reactivex.schedulers.Schedulers; import io.reactivex.subjects.nbp.NbpPublishSubject; @@ -135,7 +135,7 @@ public void accept(NbpSubscriber NbpObserver) { @Ignore("take(0) is now empty() and doesn't even subscribe to the original source") public void testTakeZeroDoesntLeakError() { final AtomicBoolean subscribed = new AtomicBoolean(false); - BooleanDisposable bs = new BooleanDisposable(); + final BooleanDisposable bs = new BooleanDisposable(); NbpObservable source = NbpObservable.create(new NbpOnSubscribe() { @Override public void accept(NbpSubscriber NbpObserver) { @@ -284,7 +284,7 @@ public void accept(NbpSubscriber op) { @Test(timeout = 2000) public void testTakeObserveOn() { NbpSubscriber o = TestHelper.mockNbpSubscriber(); - NbpTestSubscriber ts = new NbpTestSubscriber<>(o); + NbpTestSubscriber ts = new NbpTestSubscriber(o); INFINITE_OBSERVABLE .observeOn(Schedulers.newThread()).take(1).subscribe(ts); @@ -299,7 +299,7 @@ public void testTakeObserveOn() { @Test public void testInterrupt() throws InterruptedException { - final AtomicReference exception = new AtomicReference<>(); + final AtomicReference exception = new AtomicReference(); final CountDownLatch latch = new CountDownLatch(1); NbpObservable.just(1).subscribeOn(Schedulers.computation()).take(1) .subscribe(new Consumer() { @@ -342,11 +342,16 @@ public void onNext(Integer t) { @Test public void testReentrantTake() { - NbpPublishSubject source = NbpPublishSubject.create(); + final NbpPublishSubject source = NbpPublishSubject.create(); - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); - source.take(1).doOnNext(v -> source.onNext(2)).subscribe(ts); + source.take(1).doOnNext(new Consumer() { + @Override + public void accept(Integer v) { + source.onNext(2); + } + }).subscribe(ts); source.onNext(1); diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorTakeTimedTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorTakeTimedTest.java index efd80bf717..39b0a91a89 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorTakeTimedTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorTakeTimedTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorTakeUntilPredicateTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorTakeUntilPredicateTest.java index e4a7674a95..0b2b83aedb 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorTakeUntilPredicateTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorTakeUntilPredicateTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -16,13 +16,12 @@ import static org.mockito.Matchers.any; import static org.mockito.Mockito.*; -import java.util.function.Predicate; - import org.junit.Test; import io.reactivex.*; import io.reactivex.NbpObservable.NbpSubscriber; import io.reactivex.exceptions.TestException; +import io.reactivex.functions.Predicate; import io.reactivex.subscribers.nbp.NbpTestSubscriber; ; @@ -31,7 +30,12 @@ public class NbpOperatorTakeUntilPredicateTest { public void takeEmpty() { NbpSubscriber o = TestHelper.mockNbpSubscriber(); - NbpObservable.empty().takeUntil(v -> true).subscribe(o); + NbpObservable.empty().takeUntil(new Predicate() { + @Override + public boolean test(Object v) { + return true; + } + }).subscribe(o); verify(o, never()).onNext(any()); verify(o, never()).onError(any(Throwable.class)); @@ -41,7 +45,12 @@ public void takeEmpty() { public void takeAll() { NbpSubscriber o = TestHelper.mockNbpSubscriber(); - NbpObservable.just(1, 2).takeUntil(v -> false).subscribe(o); + NbpObservable.just(1, 2).takeUntil(new Predicate() { + @Override + public boolean test(Integer v) { + return false; + } + }).subscribe(o); verify(o).onNext(1); verify(o).onNext(2); @@ -52,7 +61,12 @@ public void takeAll() { public void takeFirst() { NbpSubscriber o = TestHelper.mockNbpSubscriber(); - NbpObservable.just(1, 2).takeUntil(v -> true).subscribe(o); + NbpObservable.just(1, 2).takeUntil(new Predicate() { + @Override + public boolean test(Integer v) { + return true; + } + }).subscribe(o); verify(o).onNext(1); verify(o, never()).onNext(2); @@ -63,7 +77,12 @@ public void takeFirst() { public void takeSome() { NbpSubscriber o = TestHelper.mockNbpSubscriber(); - NbpObservable.just(1, 2, 3).takeUntil(t1 -> t1 == 2) + NbpObservable.just(1, 2, 3).takeUntil(new Predicate() { + @Override + public boolean test(Integer t1) { + return t1 == 2; + } + }) .subscribe(o); verify(o).onNext(1); @@ -76,9 +95,13 @@ public void takeSome() { public void functionThrows() { NbpSubscriber o = TestHelper.mockNbpSubscriber(); - NbpObservable.just(1, 2, 3).takeUntil((Predicate)(t1 -> { - throw new TestException("Forced failure"); - })).subscribe(o); + Predicate predicate = (new Predicate() { + @Override + public boolean test(Integer t1) { + throw new TestException("Forced failure"); + } + }); + NbpObservable.just(1, 2, 3).takeUntil(predicate).subscribe(o); verify(o).onNext(1); verify(o, never()).onNext(2); @@ -93,7 +116,12 @@ public void sourceThrows() { NbpObservable.just(1) .concatWith(NbpObservable.error(new TestException())) .concatWith(NbpObservable.just(2)) - .takeUntil(v -> false).subscribe(o); + .takeUntil(new Predicate() { + @Override + public boolean test(Integer v) { + return false; + } + }).subscribe(o); verify(o).onNext(1); verify(o, never()).onNext(2); @@ -103,11 +131,15 @@ public void sourceThrows() { @Test public void testErrorIncludesLastValueAsCause() { - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); final TestException e = new TestException("Forced failure"); - NbpObservable.just("abc").takeUntil((Predicate)(t -> { - throw e; - })).subscribe(ts); + Predicate predicate = (new Predicate() { + @Override + public boolean test(String t) { + throw e; + } + }); + NbpObservable.just("abc").takeUntil(predicate).subscribe(ts); ts.assertTerminated(); ts.assertNotComplete(); diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorTakeUntilTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorTakeUntilTest.java index 979ed7f221..9e1ca94aca 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorTakeUntilTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorTakeUntilTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -188,7 +188,7 @@ public void testUntilFires() { NbpPublishSubject source = NbpPublishSubject.create(); NbpPublishSubject until = NbpPublishSubject.create(); - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); source.takeUntil(until).unsafeSubscribe(ts); @@ -213,7 +213,7 @@ public void testMainCompletes() { NbpPublishSubject source = NbpPublishSubject.create(); NbpPublishSubject until = NbpPublishSubject.create(); - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); source.takeUntil(until).unsafeSubscribe(ts); @@ -236,7 +236,7 @@ public void testDownstreamUnsubscribes() { NbpPublishSubject source = NbpPublishSubject.create(); NbpPublishSubject until = NbpPublishSubject.create(); - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); source.takeUntil(until).take(1).unsafeSubscribe(ts); diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorTakeWhileTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorTakeWhileTest.java index aafb372c0a..f4c55b370f 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorTakeWhileTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorTakeWhileTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -17,14 +17,13 @@ import static org.mockito.Matchers.any; import static org.mockito.Mockito.*; -import java.util.function.Predicate; - import org.junit.*; import io.reactivex.*; import io.reactivex.NbpObservable.*; import io.reactivex.disposables.Disposable; import io.reactivex.exceptions.TestException; +import io.reactivex.functions.Predicate; import io.reactivex.internal.disposables.EmptyDisposable; import io.reactivex.subjects.nbp.*; import io.reactivex.subscribers.nbp.NbpTestSubscriber; @@ -224,7 +223,7 @@ public boolean test(Integer t1) { return t1 < 2; } }); - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); source.unsafeSubscribe(ts); @@ -236,7 +235,7 @@ public boolean test(Integer t1) { @Test public void testErrorCauseIncludesLastValue() { - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); NbpObservable.just("abc").takeWhile(new Predicate() { @Override public boolean test(String t1) { diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorThrottleFirstTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorThrottleFirstTest.java index 6a42169b97..38115f1829 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorThrottleFirstTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorThrottleFirstTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorTimeIntervalTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorTimeIntervalTest.java index 2e84b3ad8d..75bc01a448 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorTimeIntervalTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorTimeIntervalTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -57,11 +57,11 @@ public void testTimeInterval() { subject.onComplete(); inOrder.verify(NbpObserver, times(1)).onNext( - new Timed<>(1, 1000, TIME_UNIT)); + new Timed(1, 1000, TIME_UNIT)); inOrder.verify(NbpObserver, times(1)).onNext( - new Timed<>(2, 2000, TIME_UNIT)); + new Timed(2, 2000, TIME_UNIT)); inOrder.verify(NbpObserver, times(1)).onNext( - new Timed<>(3, 3000, TIME_UNIT)); + new Timed(3, 3000, TIME_UNIT)); inOrder.verify(NbpObserver, times(1)).onComplete(); inOrder.verifyNoMoreInteractions(); } diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorTimeoutTests.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorTimeoutTests.java index 9ea6c493ef..9dc6ba7fc9 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorTimeoutTests.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorTimeoutTests.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -48,7 +48,7 @@ public void setUp() { @Test public void shouldNotTimeoutIfOnNextWithinTimeout() { NbpSubscriber NbpObserver = TestHelper.mockNbpSubscriber(); - NbpTestSubscriber ts = new NbpTestSubscriber<>(NbpObserver); + NbpTestSubscriber ts = new NbpTestSubscriber(NbpObserver); withTimeout.subscribe(ts); @@ -63,7 +63,7 @@ public void shouldNotTimeoutIfOnNextWithinTimeout() { @Test public void shouldNotTimeoutIfSecondOnNextWithinTimeout() { NbpSubscriber NbpObserver = TestHelper.mockNbpSubscriber(); - NbpTestSubscriber ts = new NbpTestSubscriber<>(NbpObserver); + NbpTestSubscriber ts = new NbpTestSubscriber(NbpObserver); withTimeout.subscribe(ts); @@ -80,7 +80,7 @@ public void shouldNotTimeoutIfSecondOnNextWithinTimeout() { @Test public void shouldTimeoutIfOnNextNotWithinTimeout() { NbpSubscriber NbpObserver = TestHelper.mockNbpSubscriber(); - NbpTestSubscriber ts = new NbpTestSubscriber<>(NbpObserver); + NbpTestSubscriber ts = new NbpTestSubscriber(NbpObserver); withTimeout.subscribe(ts); @@ -92,7 +92,7 @@ public void shouldTimeoutIfOnNextNotWithinTimeout() { @Test public void shouldTimeoutIfSecondOnNextNotWithinTimeout() { NbpSubscriber NbpObserver = TestHelper.mockNbpSubscriber(); - NbpTestSubscriber ts = new NbpTestSubscriber<>(NbpObserver); + NbpTestSubscriber ts = new NbpTestSubscriber(NbpObserver); withTimeout.subscribe(NbpObserver); testScheduler.advanceTimeBy(2, TimeUnit.SECONDS); underlyingSubject.onNext("One"); @@ -105,7 +105,7 @@ public void shouldTimeoutIfSecondOnNextNotWithinTimeout() { @Test public void shouldCompleteIfUnderlyingComletes() { NbpSubscriber NbpObserver = TestHelper.mockNbpSubscriber(); - NbpTestSubscriber ts = new NbpTestSubscriber<>(NbpObserver); + NbpTestSubscriber ts = new NbpTestSubscriber(NbpObserver); withTimeout.subscribe(NbpObserver); testScheduler.advanceTimeBy(2, TimeUnit.SECONDS); underlyingSubject.onComplete(); @@ -118,7 +118,7 @@ public void shouldCompleteIfUnderlyingComletes() { @Test public void shouldErrorIfUnderlyingErrors() { NbpSubscriber NbpObserver = TestHelper.mockNbpSubscriber(); - NbpTestSubscriber ts = new NbpTestSubscriber<>(NbpObserver); + NbpTestSubscriber ts = new NbpTestSubscriber(NbpObserver); withTimeout.subscribe(NbpObserver); testScheduler.advanceTimeBy(2, TimeUnit.SECONDS); underlyingSubject.onError(new UnsupportedOperationException()); @@ -133,7 +133,7 @@ public void shouldSwitchToOtherIfOnNextNotWithinTimeout() { NbpObservable source = underlyingSubject.timeout(TIMEOUT, TIME_UNIT, other, testScheduler); NbpSubscriber NbpObserver = TestHelper.mockNbpSubscriber(); - NbpTestSubscriber ts = new NbpTestSubscriber<>(NbpObserver); + NbpTestSubscriber ts = new NbpTestSubscriber(NbpObserver); source.subscribe(ts); testScheduler.advanceTimeBy(2, TimeUnit.SECONDS); @@ -156,7 +156,7 @@ public void shouldSwitchToOtherIfOnErrorNotWithinTimeout() { NbpObservable source = underlyingSubject.timeout(TIMEOUT, TIME_UNIT, other, testScheduler); NbpSubscriber NbpObserver = TestHelper.mockNbpSubscriber(); - NbpTestSubscriber ts = new NbpTestSubscriber<>(NbpObserver); + NbpTestSubscriber ts = new NbpTestSubscriber(NbpObserver); source.subscribe(ts); testScheduler.advanceTimeBy(2, TimeUnit.SECONDS); @@ -179,7 +179,7 @@ public void shouldSwitchToOtherIfOnCompletedNotWithinTimeout() { NbpObservable source = underlyingSubject.timeout(TIMEOUT, TIME_UNIT, other, testScheduler); NbpSubscriber NbpObserver = TestHelper.mockNbpSubscriber(); - NbpTestSubscriber ts = new NbpTestSubscriber<>(NbpObserver); + NbpTestSubscriber ts = new NbpTestSubscriber(NbpObserver); source.subscribe(ts); testScheduler.advanceTimeBy(2, TimeUnit.SECONDS); @@ -202,7 +202,7 @@ public void shouldSwitchToOtherAndCanBeUnsubscribedIfOnNextNotWithinTimeout() { NbpObservable source = underlyingSubject.timeout(TIMEOUT, TIME_UNIT, other, testScheduler); NbpSubscriber NbpObserver = TestHelper.mockNbpSubscriber(); - NbpTestSubscriber ts = new NbpTestSubscriber<>(NbpObserver); + NbpTestSubscriber ts = new NbpTestSubscriber(NbpObserver); source.subscribe(ts); testScheduler.advanceTimeBy(2, TimeUnit.SECONDS); @@ -233,7 +233,7 @@ public void shouldTimeoutIfSynchronizedObservableEmitFirstOnNextNotWithinTimeout final CountDownLatch timeoutSetuped = new CountDownLatch(1); final NbpSubscriber NbpObserver = TestHelper.mockNbpSubscriber(); - NbpTestSubscriber ts = new NbpTestSubscriber<>(NbpObserver); + final NbpTestSubscriber ts = new NbpTestSubscriber(NbpObserver); new Thread(new Runnable() { @@ -285,7 +285,7 @@ public void accept(NbpSubscriber NbpSubscriber) { NbpObservable observableWithTimeout = never.timeout(1000, TimeUnit.MILLISECONDS, testScheduler); NbpSubscriber NbpObserver = TestHelper.mockNbpSubscriber(); - NbpTestSubscriber ts = new NbpTestSubscriber<>(NbpObserver); + NbpTestSubscriber ts = new NbpTestSubscriber(NbpObserver); observableWithTimeout.subscribe(ts); testScheduler.advanceTimeBy(2000, TimeUnit.MILLISECONDS); @@ -316,7 +316,7 @@ public void accept(NbpSubscriber NbpSubscriber) { testScheduler); NbpSubscriber NbpObserver = TestHelper.mockNbpSubscriber(); - NbpTestSubscriber ts = new NbpTestSubscriber<>(NbpObserver); + NbpTestSubscriber ts = new NbpTestSubscriber(NbpObserver); observableWithTimeout.subscribe(ts); testScheduler.advanceTimeBy(2000, TimeUnit.MILLISECONDS); @@ -347,7 +347,7 @@ public void accept(NbpSubscriber NbpSubscriber) { testScheduler); NbpSubscriber NbpObserver = TestHelper.mockNbpSubscriber(); - NbpTestSubscriber ts = new NbpTestSubscriber<>(NbpObserver); + NbpTestSubscriber ts = new NbpTestSubscriber(NbpObserver); observableWithTimeout.subscribe(ts); testScheduler.advanceTimeBy(2000, TimeUnit.MILLISECONDS); diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorTimeoutWithSelectorTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorTimeoutWithSelectorTest.java index 3492df943c..2867268eee 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorTimeoutWithSelectorTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorTimeoutWithSelectorTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -20,7 +20,6 @@ import java.util.Arrays; import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicBoolean; -import java.util.function.*; import org.junit.Test; import org.mockito.InOrder; @@ -31,6 +30,7 @@ import io.reactivex.NbpObservable.*; import io.reactivex.disposables.Disposable; import io.reactivex.exceptions.TestException; +import io.reactivex.functions.*; import io.reactivex.internal.disposables.EmptyDisposable; import io.reactivex.schedulers.Schedulers; import io.reactivex.subjects.nbp.NbpPublishSubject; @@ -321,34 +321,37 @@ public void testTimeoutSelectorWithTimeoutAndOnNextRaceCondition() throws Interr final CountDownLatch enteredTimeoutOne = new CountDownLatch(1); final AtomicBoolean latchTimeout = new AtomicBoolean(false); - final Function> timeoutFunc = t1 -> { - if (t1 == 1) { - // Force "unsubscribe" run on another thread - return NbpObservable.create(new NbpOnSubscribe() { - @Override - public void accept(NbpSubscriber NbpSubscriber) { - NbpSubscriber.onSubscribe(EmptyDisposable.INSTANCE); - enteredTimeoutOne.countDown(); - // force the timeout message be sent after NbpObserver.onNext(2) - while (true) { - try { - if (!observerReceivedTwo.await(30, TimeUnit.SECONDS)) { - // CountDownLatch timeout - // There should be something wrong - latchTimeout.set(true); + final Function> timeoutFunc = new Function>() { + @Override + public NbpObservable apply(Integer t1) { + if (t1 == 1) { + // Force "unsubscribe" run on another thread + return NbpObservable.create(new NbpOnSubscribe() { + @Override + public void accept(NbpSubscriber NbpSubscriber) { + NbpSubscriber.onSubscribe(EmptyDisposable.INSTANCE); + enteredTimeoutOne.countDown(); + // force the timeout message be sent after NbpObserver.onNext(2) + while (true) { + try { + if (!observerReceivedTwo.await(30, TimeUnit.SECONDS)) { + // CountDownLatch timeout + // There should be something wrong + latchTimeout.set(true); + } + break; + } catch (InterruptedException e) { + // Since we just want to emulate a busy method, + // we ignore the interrupt signal from Scheduler. } - break; - } catch (InterruptedException e) { - // Since we just want to emulate a busy method, - // we ignore the interrupt signal from Scheduler. } + NbpSubscriber.onNext(1); + timeoutEmittedOne.countDown(); } - NbpSubscriber.onNext(1); - timeoutEmittedOne.countDown(); - } - }).subscribeOn(Schedulers.newThread()); - } else { - return NbpPublishSubject.create(); + }).subscribeOn(Schedulers.newThread()); + } else { + return NbpPublishSubject.create(); + } } }; @@ -372,7 +375,7 @@ public Void answer(InvocationOnMock invocation) throws Throwable { }).when(o).onComplete(); - final NbpTestSubscriber ts = new NbpTestSubscriber<>(o); + final NbpTestSubscriber ts = new NbpTestSubscriber(o); new Thread(new Runnable() { diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorTimestampTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorTimestampTest.java index 2f9d2c5632..750f2f7b19 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorTimestampTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorTimestampTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -50,9 +50,9 @@ public void timestampWithScheduler() { InOrder inOrder = inOrder(NbpObserver); - inOrder.verify(NbpObserver, times(1)).onNext(new Timed<>(1, 0, TimeUnit.MILLISECONDS)); - inOrder.verify(NbpObserver, times(1)).onNext(new Timed<>(2, 100, TimeUnit.MILLISECONDS)); - inOrder.verify(NbpObserver, times(1)).onNext(new Timed<>(3, 200, TimeUnit.MILLISECONDS)); + inOrder.verify(NbpObserver, times(1)).onNext(new Timed(1, 0, TimeUnit.MILLISECONDS)); + inOrder.verify(NbpObserver, times(1)).onNext(new Timed(2, 100, TimeUnit.MILLISECONDS)); + inOrder.verify(NbpObserver, times(1)).onNext(new Timed(3, 200, TimeUnit.MILLISECONDS)); verify(NbpObserver, never()).onError(any(Throwable.class)); verify(NbpObserver, never()).onComplete(); @@ -74,9 +74,9 @@ public void timestampWithScheduler2() { InOrder inOrder = inOrder(NbpObserver); - inOrder.verify(NbpObserver, times(1)).onNext(new Timed<>(1, 0, TimeUnit.MILLISECONDS)); - inOrder.verify(NbpObserver, times(1)).onNext(new Timed<>(2, 0, TimeUnit.MILLISECONDS)); - inOrder.verify(NbpObserver, times(1)).onNext(new Timed<>(3, 200, TimeUnit.MILLISECONDS)); + inOrder.verify(NbpObserver, times(1)).onNext(new Timed(1, 0, TimeUnit.MILLISECONDS)); + inOrder.verify(NbpObserver, times(1)).onNext(new Timed(2, 0, TimeUnit.MILLISECONDS)); + inOrder.verify(NbpObserver, times(1)).onNext(new Timed(3, 200, TimeUnit.MILLISECONDS)); verify(NbpObserver, never()).onError(any(Throwable.class)); verify(NbpObserver, never()).onComplete(); diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorToMapTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorToMapTest.java index 0d16ebddbc..54f11be314 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorToMapTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorToMapTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -17,12 +17,12 @@ import static org.mockito.Mockito.*; import java.util.*; -import java.util.function.*; import org.junit.*; import io.reactivex.*; import io.reactivex.NbpObservable.NbpSubscriber; +import io.reactivex.functions.*; public class NbpOperatorToMapTest { NbpSubscriber objectObserver; @@ -51,7 +51,7 @@ public void testToMap() { NbpObservable> mapped = source.toMap(lengthFunc); - Map expected = new HashMap<>(); + Map expected = new HashMap(); expected.put(1, "a"); expected.put(2, "bb"); expected.put(3, "ccc"); @@ -70,7 +70,7 @@ public void testToMapWithValueSelector() { NbpObservable> mapped = source.toMap(lengthFunc, duplicate); - Map expected = new HashMap<>(); + Map expected = new HashMap(); expected.put(1, "aa"); expected.put(2, "bbbb"); expected.put(3, "cccccc"); @@ -98,7 +98,7 @@ public Integer apply(String t1) { }; NbpObservable> mapped = source.toMap(lengthFuncErr); - Map expected = new HashMap<>(); + Map expected = new HashMap(); expected.put(1, "a"); expected.put(2, "bb"); expected.put(3, "ccc"); @@ -128,7 +128,7 @@ public String apply(String t1) { NbpObservable> mapped = source.toMap(lengthFunc, duplicateErr); - Map expected = new HashMap<>(); + Map expected = new HashMap(); expected.put(1, "aa"); expected.put(2, "bbbb"); expected.put(3, "cccccc"); @@ -167,9 +167,14 @@ public Integer apply(String t1) { return t1.length(); } }; - NbpObservable> mapped = source.toMap(lengthFunc, v -> v, mapFactory); + NbpObservable> mapped = source.toMap(lengthFunc, new Function() { + @Override + public String apply(String v) { + return v; + } + }, mapFactory); - Map expected = new LinkedHashMap<>(); + Map expected = new LinkedHashMap(); expected.put(2, "bb"); expected.put(3, "ccc"); expected.put(4, "dddd"); @@ -198,9 +203,14 @@ public Integer apply(String t1) { return t1.length(); } }; - NbpObservable> mapped = source.toMap(lengthFunc, v -> v, mapFactory); + NbpObservable> mapped = source.toMap(lengthFunc, new Function() { + @Override + public String apply(String v) { + return v; + } + }, mapFactory); - Map expected = new LinkedHashMap<>(); + Map expected = new LinkedHashMap(); expected.put(2, "bb"); expected.put(3, "ccc"); expected.put(4, "dddd"); diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorToMultimapTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorToMultimapTest.java index 42669746b1..4530788860 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorToMultimapTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorToMultimapTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -17,12 +17,12 @@ import static org.mockito.Mockito.*; import java.util.*; -import java.util.function.*; import org.junit.*; import io.reactivex.*; import io.reactivex.NbpObservable.NbpSubscriber; +import io.reactivex.functions.*; public class NbpOperatorToMultimapTest { NbpSubscriber objectObserver; @@ -32,8 +32,18 @@ public void before() { objectObserver = TestHelper.mockNbpSubscriber(); } - Function lengthFunc = t1 -> t1.length(); - Function duplicate = t1 -> t1 + t1; + Function lengthFunc = new Function() { + @Override + public Integer apply(String t1) { + return t1.length(); + } + }; + Function duplicate = new Function() { + @Override + public String apply(String t1) { + return t1 + t1; + } + }; @Test public void testToMultimap() { @@ -41,7 +51,7 @@ public void testToMultimap() { NbpObservable>> mapped = source.toMultimap(lengthFunc); - Map> expected = new HashMap<>(); + Map> expected = new HashMap>(); expected.put(1, Arrays.asList("a", "b")); expected.put(2, Arrays.asList("cc", "dd")); @@ -58,7 +68,7 @@ public void testToMultimapWithValueSelector() { NbpObservable>> mapped = source.toMultimap(lengthFunc, duplicate); - Map> expected = new HashMap<>(); + Map> expected = new HashMap>(); expected.put(1, Arrays.asList("aa", "bb")); expected.put(2, Arrays.asList("cccc", "dddd")); @@ -88,13 +98,23 @@ protected boolean removeEldestEntry(Map.Entry> eldes } }; - Function identity = v -> v; + Function identity = new Function() { + @Override + public String apply(String v) { + return v; + } + }; NbpObservable>> mapped = source.toMultimap( lengthFunc, identity, - mapFactory, ArrayList::new); + mapFactory, new Function>() { + @Override + public Collection apply(Integer v) { + return new ArrayList(); + } + }); - Map> expected = new HashMap<>(); + Map> expected = new HashMap>(); expected.put(2, Arrays.asList("cc", "dd")); expected.put(3, Arrays.asList("eee", "fff")); @@ -109,23 +129,36 @@ protected boolean removeEldestEntry(Map.Entry> eldes public void testToMultimapWithCollectionFactory() { NbpObservable source = NbpObservable.just("cc", "dd", "eee", "eee"); - Function> collectionFactory = t1 -> { - if (t1 == 2) { - return new ArrayList<>(); - } else { - return new HashSet<>(); + Function> collectionFactory = new Function>() { + @Override + public Collection apply(Integer t1) { + if (t1 == 2) { + return new ArrayList(); + } else { + return new HashSet(); + } } }; - Function identity = v -> v; - Supplier>> mapSupplier = HashMap::new; + Function identity = new Function() { + @Override + public String apply(String v) { + return v; + } + }; + Supplier>> mapSupplier = new Supplier>>() { + @Override + public Map> get() { + return new HashMap>(); + } + }; NbpObservable>> mapped = source .toMultimap(lengthFunc, identity, mapSupplier, collectionFactory); - Map> expected = new HashMap<>(); + Map> expected = new HashMap>(); expected.put(2, Arrays.asList("cc", "dd")); - expected.put(3, new HashSet<>(Arrays.asList("eee"))); + expected.put(3, new HashSet(Arrays.asList("eee"))); mapped.subscribe(objectObserver); @@ -150,7 +183,7 @@ public Integer apply(String t1) { NbpObservable>> mapped = source.toMultimap(lengthFuncErr); - Map> expected = new HashMap<>(); + Map> expected = new HashMap>(); expected.put(1, Arrays.asList("a", "b")); expected.put(2, Arrays.asList("cc", "dd")); @@ -177,7 +210,7 @@ public String apply(String t1) { NbpObservable>> mapped = source.toMultimap(lengthFunc, duplicateErr); - Map> expected = new HashMap<>(); + Map> expected = new HashMap>(); expected.put(1, Arrays.asList("aa", "bb")); expected.put(2, Arrays.asList("cccc", "dddd")); @@ -200,9 +233,14 @@ public Map> get() { }; NbpObservable>> mapped = source - .toMultimap(lengthFunc, v -> v, mapFactory); + .toMultimap(lengthFunc, new Function() { + @Override + public String apply(String v) { + return v; + } + }, mapFactory); - Map> expected = new HashMap<>(); + Map> expected = new HashMap>(); expected.put(2, Arrays.asList("cc", "dd")); expected.put(3, Arrays.asList("eee", "fff")); @@ -217,21 +255,34 @@ public Map> get() { public void testToMultimapWithThrowingCollectionFactory() { NbpObservable source = NbpObservable.just("cc", "cc", "eee", "eee"); - Function> collectionFactory = t1 -> { - if (t1 == 2) { - throw new RuntimeException("Forced failure"); - } else { - return new HashSet<>(); + Function> collectionFactory = new Function>() { + @Override + public Collection apply(Integer t1) { + if (t1 == 2) { + throw new RuntimeException("Forced failure"); + } else { + return new HashSet(); + } } }; - Function identity = v -> v; - Supplier>> mapSupplier = HashMap::new; + Function identity = new Function() { + @Override + public String apply(String v) { + return v; + } + }; + Supplier>> mapSupplier = new Supplier>>() { + @Override + public Map> get() { + return new HashMap>(); + } + }; NbpObservable>> mapped = source.toMultimap(lengthFunc, identity, mapSupplier, collectionFactory); - Map> expected = new HashMap<>(); + Map> expected = new HashMap>(); expected.put(2, Arrays.asList("cc", "dd")); expected.put(3, Collections.singleton("eee")); diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorToObservableListTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorToObservableListTest.java index caa0130730..cd0f8ecfc0 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorToObservableListTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorToObservableListTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorToObservableSortedListTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorToObservableSortedListTest.java index e4960cbf4d..7998113777 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorToObservableSortedListTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorToObservableSortedListTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorUnsubscribeOnTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorUnsubscribeOnTest.java index c937526dba..5b59133dd1 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorUnsubscribeOnTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorUnsubscribeOnTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -33,7 +33,7 @@ public void testUnsubscribeWhenSubscribeOnAndUnsubscribeOnAreOnSameThread() thro UIEventLoopScheduler UI_EVENT_LOOP = new UIEventLoopScheduler(); try { final ThreadSubscription subscription = new ThreadSubscription(); - final AtomicReference subscribeThread = new AtomicReference<>(); + final AtomicReference subscribeThread = new AtomicReference(); NbpObservable w = NbpObservable.create(new NbpOnSubscribe() { @Override @@ -46,7 +46,7 @@ public void accept(NbpSubscriber t1) { } }); - NbpTestSubscriber NbpObserver = new NbpTestSubscriber<>(); + NbpTestSubscriber NbpObserver = new NbpTestSubscriber(); w.subscribeOn(UI_EVENT_LOOP).observeOn(Schedulers.computation()).unsubscribeOn(UI_EVENT_LOOP).subscribe(NbpObserver); NbpObserver.awaitTerminalEvent(1, TimeUnit.SECONDS); @@ -77,7 +77,7 @@ public void testUnsubscribeWhenSubscribeOnAndUnsubscribeOnAreOnDifferentThreads( UIEventLoopScheduler UI_EVENT_LOOP = new UIEventLoopScheduler(); try { final ThreadSubscription subscription = new ThreadSubscription(); - final AtomicReference subscribeThread = new AtomicReference<>(); + final AtomicReference subscribeThread = new AtomicReference(); NbpObservable w = NbpObservable.create(new NbpOnSubscribe() { @Override @@ -90,7 +90,7 @@ public void accept(NbpSubscriber t1) { } }); - NbpTestSubscriber NbpObserver = new NbpTestSubscriber<>(); + NbpTestSubscriber NbpObserver = new NbpTestSubscriber(); w.subscribeOn(Schedulers.newThread()).observeOn(Schedulers.computation()).unsubscribeOn(UI_EVENT_LOOP).subscribe(NbpObserver); NbpObserver.awaitTerminalEvent(1, TimeUnit.SECONDS); diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorWindowWithObservableTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorWindowWithObservableTest.java index 0b0e32f671..feab752c65 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorWindowWithObservableTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorWindowWithObservableTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -19,13 +19,13 @@ import java.util.*; import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.Supplier; import org.junit.Test; import io.reactivex.*; import io.reactivex.NbpObservable.NbpSubscriber; import io.reactivex.exceptions.TestException; +import io.reactivex.functions.Supplier; import io.reactivex.subjects.nbp.NbpPublishSubject; import io.reactivex.subscribers.nbp.NbpTestSubscriber; @@ -38,7 +38,7 @@ public void testWindowViaObservableNormal1() { final NbpSubscriber o = TestHelper.mockNbpSubscriber(); - final List> values = new ArrayList<>(); + final List> values = new ArrayList>(); NbpSubscriber> wo = new NbpObserver>() { @Override @@ -96,7 +96,7 @@ public void testWindowViaObservableBoundaryCompletes() { final NbpSubscriber o = TestHelper.mockNbpSubscriber(); - final List> values = new ArrayList<>(); + final List> values = new ArrayList>(); NbpSubscriber> wo = new NbpObserver>() { @Override @@ -152,7 +152,7 @@ public void testWindowViaObservableBoundaryThrows() { final NbpSubscriber o = TestHelper.mockNbpSubscriber(); - final List> values = new ArrayList<>(); + final List> values = new ArrayList>(); NbpSubscriber> wo = new NbpObserver>() { @Override @@ -202,7 +202,7 @@ public void testWindowViaObservableSourceThrows() { final NbpSubscriber o = TestHelper.mockNbpSubscriber(); - final List> values = new ArrayList<>(); + final List> values = new ArrayList>(); NbpSubscriber> wo = new NbpObserver>() { @Override @@ -290,7 +290,7 @@ public NbpObservable get() { } }; - NbpTestSubscriber> ts = new NbpTestSubscriber<>(); + NbpTestSubscriber> ts = new NbpTestSubscriber>(); source.window(boundary).unsafeSubscribe(ts); assertFalse(ts.isCancelled()); @@ -307,7 +307,7 @@ public NbpObservable get() { } }; - NbpTestSubscriber> ts = new NbpTestSubscriber<>(); + NbpTestSubscriber> ts = new NbpTestSubscriber>(); source.window(boundaryFunc).subscribe(ts); assertTrue(source.hasSubscribers()); @@ -333,7 +333,7 @@ public NbpObservable get() { } }; - NbpTestSubscriber> ts = new NbpTestSubscriber<>(); + NbpTestSubscriber> ts = new NbpTestSubscriber>(); source.window(boundaryFunc).subscribe(ts); assertTrue(source.hasSubscribers()); @@ -361,7 +361,7 @@ public NbpObservable get() { } }; - NbpTestSubscriber> ts = new NbpTestSubscriber<>(); + NbpTestSubscriber> ts = new NbpTestSubscriber>(); source.window(boundaryFunc).subscribe(ts); assertTrue(source.hasSubscribers()); @@ -392,7 +392,7 @@ public NbpObservable get() { } }; - NbpTestSubscriber> ts = new NbpTestSubscriber<>(); + NbpTestSubscriber> ts = new NbpTestSubscriber>(); source.window(boundaryFunc).subscribe(ts); source.onNext(1); diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorWindowWithSizeTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorWindowWithSizeTest.java index e201097009..f361c79b3e 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorWindowWithSizeTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorWindowWithSizeTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -18,13 +18,13 @@ import java.util.*; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.*; import org.junit.Test; import io.reactivex.NbpObservable; import io.reactivex.NbpObservable.*; import io.reactivex.disposables.BooleanDisposable; +import io.reactivex.functions.*; import io.reactivex.schedulers.Schedulers; import io.reactivex.subscribers.nbp.NbpTestSubscriber; @@ -32,7 +32,7 @@ public class NbpOperatorWindowWithSizeTest { private static List> toLists(NbpObservable> observables) { - final List> lists = new ArrayList<>(); + final List> lists = new ArrayList>(); NbpObservable.concat(observables.map(new Function, NbpObservable>>() { @Override public NbpObservable> apply(NbpObservable xs) { @@ -103,7 +103,7 @@ public void testSkipAndCountWindowsWithGaps() { @Test public void testWindowUnsubscribeNonOverlapping() { - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); final AtomicInteger count = new AtomicInteger(); NbpObservable.merge(NbpObservable.range(1, 10000).doOnNext(new Consumer() { @@ -122,7 +122,7 @@ public void accept(Integer t1) { @Test public void testWindowUnsubscribeNonOverlappingAsyncSource() { - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); final AtomicInteger count = new AtomicInteger(); NbpObservable.merge(NbpObservable.range(1, 100000) .doOnNext(new Consumer() { @@ -146,7 +146,7 @@ public void accept(Integer t1) { @Test public void testWindowUnsubscribeOverlapping() { - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); final AtomicInteger count = new AtomicInteger(); NbpObservable.merge(NbpObservable.range(1, 10000).doOnNext(new Consumer() { @@ -165,7 +165,7 @@ public void accept(Integer t1) { @Test public void testWindowUnsubscribeOverlappingAsyncSource() { - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); final AtomicInteger count = new AtomicInteger(); NbpObservable.merge(NbpObservable.range(1, 100000) .doOnNext(new Consumer() { @@ -178,7 +178,7 @@ public void accept(Integer t1) { }) .observeOn(Schedulers.computation()) .window(5, 4) - .take(2)) + .take(2), 128) .subscribe(ts); ts.awaitTerminalEvent(500, TimeUnit.MILLISECONDS); ts.assertTerminated(); @@ -188,7 +188,7 @@ public void accept(Integer t1) { } private List list(String... args) { - List list = new ArrayList<>(); + List list = new ArrayList(); for (String arg : args) { list.add(arg); } @@ -222,7 +222,7 @@ public void accept(NbpSubscriber s) { @Test public void testTakeFlatMapCompletes() { - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); final int indicator = 999999999; diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorWindowWithStartEndObservableTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorWindowWithStartEndObservableTest.java index 66bfda72ca..80a1af0a69 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorWindowWithStartEndObservableTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorWindowWithStartEndObservableTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -17,12 +17,12 @@ import java.util.*; import java.util.concurrent.TimeUnit; -import java.util.function.*; import org.junit.*; import io.reactivex.*; import io.reactivex.NbpObservable.*; +import io.reactivex.functions.*; import io.reactivex.internal.disposables.EmptyDisposable; import io.reactivex.schedulers.TestScheduler; import io.reactivex.subjects.nbp.NbpPublishSubject; @@ -41,8 +41,8 @@ public void before() { @Test public void testObservableBasedOpenerAndCloser() { - final List list = new ArrayList<>(); - final List> lists = new ArrayList<>(); + final List list = new ArrayList(); + final List> lists = new ArrayList>(); NbpObservable source = NbpObservable.create(new NbpOnSubscribe() { @Override @@ -92,8 +92,8 @@ public void accept(NbpSubscriber NbpObserver) { @Test public void testObservableBasedCloser() { - final List list = new ArrayList<>(); - final List> lists = new ArrayList<>(); + final List list = new ArrayList(); + final List> lists = new ArrayList>(); NbpObservable source = NbpObservable.create(new NbpOnSubscribe() { @Override @@ -141,7 +141,7 @@ public void accept(NbpSubscriber NbpObserver) { } private List list(String... args) { - List list = new ArrayList<>(); + List list = new ArrayList(); for (String arg : args) { list.add(arg); } @@ -173,7 +173,7 @@ public void accept(NbpObservable stringObservable) { stringObservable.subscribe(new NbpObserver() { @Override public void onComplete() { - lists.add(new ArrayList<>(list)); + lists.add(new ArrayList(list)); list.clear(); } @@ -198,7 +198,7 @@ public void testNoUnsubscribeAndNoLeak() { NbpPublishSubject open = NbpPublishSubject.create(); final NbpPublishSubject close = NbpPublishSubject.create(); - NbpTestSubscriber> ts = new NbpTestSubscriber<>(); + NbpTestSubscriber> ts = new NbpTestSubscriber>(); source.window(open, new Function>() { @Override @@ -235,7 +235,7 @@ public void testUnsubscribeAll() { NbpPublishSubject open = NbpPublishSubject.create(); final NbpPublishSubject close = NbpPublishSubject.create(); - NbpTestSubscriber> ts = new NbpTestSubscriber<>(); + NbpTestSubscriber> ts = new NbpTestSubscriber>(); source.window(open, new Function>() { @Override diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorWindowWithTimeTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorWindowWithTimeTest.java index dabbcb89a1..3be973df40 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorWindowWithTimeTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorWindowWithTimeTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -18,12 +18,12 @@ import java.util.*; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.*; import org.junit.*; import io.reactivex.*; import io.reactivex.NbpObservable.*; +import io.reactivex.functions.*; import io.reactivex.internal.disposables.EmptyDisposable; import io.reactivex.schedulers.TestScheduler; import io.reactivex.subscribers.nbp.NbpTestSubscriber; @@ -42,8 +42,8 @@ public void before() { @Test public void testTimedAndCount() { - final List list = new ArrayList<>(); - final List> lists = new ArrayList<>(); + final List list = new ArrayList(); + final List> lists = new ArrayList>(); NbpObservable source = NbpObservable.create(new NbpOnSubscribe() { @Override @@ -76,8 +76,8 @@ public void accept(NbpSubscriber NbpObserver) { @Test public void testTimed() { - final List list = new ArrayList<>(); - final List> lists = new ArrayList<>(); + final List list = new ArrayList(); + final List> lists = new ArrayList>(); NbpObservable source = NbpObservable.create(new NbpOnSubscribe() { @Override @@ -105,7 +105,7 @@ public void accept(NbpSubscriber NbpObserver) { } private List list(String... args) { - List list = new ArrayList<>(); + List list = new ArrayList(); for (String arg : args) { list.add(arg); } @@ -137,7 +137,7 @@ public void accept(NbpObservable stringObservable) { stringObservable.subscribe(new NbpObserver() { @Override public void onComplete() { - lists.add(new ArrayList<>(list)); + lists.add(new ArrayList(list)); list.clear(); } @@ -159,8 +159,8 @@ public void testExactWindowSize() { NbpObservable> source = NbpObservable.range(1, 10) .window(1, TimeUnit.MINUTES, scheduler, 3); - final List list = new ArrayList<>(); - final List> lists = new ArrayList<>(); + final List list = new ArrayList(); + final List> lists = new ArrayList>(); source.subscribe(observeWindow(list, lists)); @@ -177,25 +177,40 @@ public void testExactWindowSize() { @Test public void testTakeFlatMapCompletes() { - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); - AtomicInteger wip = new AtomicInteger(); + final AtomicInteger wip = new AtomicInteger(); final int indicator = 999999999; NbpOperatorWindowWithSizeTest.hotStream() .window(300, TimeUnit.MILLISECONDS) .take(10) - .doOnComplete(() -> System.out.println("Main done!")) + .doOnComplete(new Runnable() { + @Override + public void run() { + System.out.println("Main done!"); + } + }) .flatMap(new Function, NbpObservable>() { @Override public NbpObservable apply(NbpObservable w) { return w.startWith(indicator) - .doOnComplete(() -> System.out.println("inner done: " + wip.incrementAndGet())) + .doOnComplete(new Runnable() { + @Override + public void run() { + System.out.println("inner done: " + wip.incrementAndGet()); + } + }) ; } }) - .doOnNext(System.out::println) + .doOnNext(new Consumer() { + @Override + public void accept(Integer pv) { + System.out.println(pv); + } + }) .subscribe(ts); ts.awaitTerminalEvent(5, TimeUnit.SECONDS); diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorWithLatestFromTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorWithLatestFromTest.java index 3c9c5c85aa..9053e9d063 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorWithLatestFromTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorWithLatestFromTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -17,14 +17,13 @@ import static org.mockito.Matchers.*; import static org.mockito.Mockito.*; -import java.util.function.BiFunction; - import org.junit.Test; import org.mockito.InOrder; import io.reactivex.*; import io.reactivex.NbpObservable.NbpSubscriber; import io.reactivex.exceptions.TestException; +import io.reactivex.functions.BiFunction; import io.reactivex.subjects.nbp.NbpPublishSubject; import io.reactivex.subscribers.nbp.NbpTestSubscriber; @@ -84,7 +83,7 @@ public void testEmptySource() { NbpObservable result = source.withLatestFrom(other, COMBINER); - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); result.subscribe(ts); @@ -110,7 +109,7 @@ public void testEmptyOther() { NbpObservable result = source.withLatestFrom(other, COMBINER); - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); result.subscribe(ts); @@ -137,7 +136,7 @@ public void testUnsubscription() { NbpObservable result = source.withLatestFrom(other, COMBINER); - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); result.subscribe(ts); @@ -164,7 +163,7 @@ public void testSourceThrows() { NbpObservable result = source.withLatestFrom(other, COMBINER); - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); result.subscribe(ts); @@ -191,7 +190,7 @@ public void testOtherThrows() { NbpObservable result = source.withLatestFrom(other, COMBINER); - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); result.subscribe(ts); @@ -219,7 +218,7 @@ public void testFunctionThrows() { NbpObservable result = source.withLatestFrom(other, COMBINER_ERROR); - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); result.subscribe(ts); @@ -245,7 +244,7 @@ public void testNoDownstreamUnsubscribe() { NbpObservable result = source.withLatestFrom(other, COMBINER); - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); result.unsafeSubscribe(ts); diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorZipCompletionTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorZipCompletionTest.java index f135b99656..7e201c1512 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorZipCompletionTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorZipCompletionTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -15,13 +15,12 @@ import static org.mockito.Mockito.*; -import java.util.function.BiFunction; - import org.junit.*; import org.mockito.InOrder; import io.reactivex.*; import io.reactivex.NbpObservable.NbpSubscriber; +import io.reactivex.functions.BiFunction; import io.reactivex.subjects.nbp.NbpPublishSubject; /** diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorZipIterableTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorZipIterableTest.java index 0908e76ad9..7fef53ded1 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorZipIterableTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorZipIterableTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -19,7 +19,6 @@ import java.util.*; import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.*; import org.junit.*; import org.mockito.InOrder; @@ -27,7 +26,7 @@ import io.reactivex.*; import io.reactivex.NbpObservable.NbpSubscriber; import io.reactivex.exceptions.TestException; -import io.reactivex.functions.Function3; +import io.reactivex.functions.*; import io.reactivex.subjects.nbp.NbpPublishSubject; public class NbpOperatorZipIterableTest { @@ -332,7 +331,12 @@ public void remove() { } - Consumer printer = System.out::println; + Consumer printer = new Consumer() { + @Override + public void accept(String pv) { + System.out.println(pv); + } + }; static final class SquareStr implements Function { final AtomicInteger counter = new AtomicInteger(); diff --git a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorZipTest.java b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorZipTest.java index eebb3245dd..60b755ea42 100644 --- a/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorZipTest.java +++ b/src/test/java/io/reactivex/internal/operators/nbp/NbpOperatorZipTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -20,20 +20,21 @@ import java.util.*; import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.*; import org.junit.*; import org.mockito.InOrder; import io.reactivex.*; import io.reactivex.NbpObservable.*; -import io.reactivex.Observable; import io.reactivex.disposables.BooleanDisposable; -import io.reactivex.functions.Function3; +import io.reactivex.functions.*; import io.reactivex.internal.disposables.EmptyDisposable; +import io.reactivex.internal.functions.Functions; import io.reactivex.schedulers.Schedulers; import io.reactivex.subjects.nbp.NbpPublishSubject; import io.reactivex.subscribers.nbp.NbpTestSubscriber; +import io.reactivex.Optional; +import io.reactivex.Observable; public class NbpOperatorZipTest { BiFunction concat2Strings; @@ -66,7 +67,7 @@ public String apply(String t1, String t2) { @SuppressWarnings("unchecked") @Test public void testCollectionSizeDifferentThanFunction() { - Function zipr = getConcatStringIntegerIntArrayZipr(); + Function zipr = Functions.toFunction(getConcatStringIntegerIntArrayZipr()); //Function3 /* define a NbpSubscriber to receive aggregated events */ @@ -349,7 +350,7 @@ public void testAggregatorUnsubscribe() { NbpPublishSubject r2 = NbpPublishSubject.create(); /* define a NbpSubscriber to receive aggregated events */ NbpSubscriber NbpObserver = TestHelper.mockNbpSubscriber(); - NbpTestSubscriber ts = new NbpTestSubscriber<>(NbpObserver); + NbpTestSubscriber ts = new NbpTestSubscriber(NbpObserver); NbpObservable.zip(r1, r2, zipr2).subscribe(ts); @@ -767,7 +768,7 @@ public String apply(Integer a, Integer b) { } }); - final ArrayList list = new ArrayList<>(); + final ArrayList list = new ArrayList(); os.subscribe(new Consumer() { @Override @@ -794,7 +795,7 @@ public String apply(Integer a, Integer b) { } }).take(5); - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); os.subscribe(ts); ts.awaitTerminalEvent(); @@ -819,7 +820,7 @@ public String apply(Integer a, Integer b) { } }); - final ArrayList list = new ArrayList<>(); + final ArrayList list = new ArrayList(); os.subscribe(new NbpObserver() { @Override @@ -865,7 +866,7 @@ public String apply(Integer t1, String t2) { }); - final ArrayList list = new ArrayList<>(); + final ArrayList list = new ArrayList(); o.subscribe(new Consumer() { @Override @@ -914,7 +915,7 @@ public String apply(Try> t1, Try> t2) { }); - final ArrayList list = new ArrayList<>(); + final ArrayList list = new ArrayList(); o.subscribe(new Consumer() { @Override @@ -943,7 +944,7 @@ public String apply(Integer t1, String t2) { }); - final ArrayList list = new ArrayList<>(); + final ArrayList list = new ArrayList(); o.subscribe(new Consumer() { @Override @@ -970,7 +971,7 @@ public Object apply(final Object[] args) { } }); - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); o.subscribe(ts); ts.awaitTerminalEvent(200, TimeUnit.MILLISECONDS); ts.assertNoValues(); @@ -1004,7 +1005,7 @@ public void testDownstreamBackpressureRequestsWithFiniteSyncObservables() { NbpObservable o1 = createInfiniteObservable(generatedA).take(Observable.bufferSize() * 2); NbpObservable o2 = createInfiniteObservable(generatedB).take(Observable.bufferSize() * 2); - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); NbpObservable.zip(o1, o2, new BiFunction() { @Override @@ -1075,7 +1076,7 @@ NbpObservable ASYNC_OBSERVABLE_OF_INFINITE_INTEGERS(final CountDownLatc @Override public void accept(final NbpSubscriber o) { - BooleanDisposable bs = new BooleanDisposable(); + final BooleanDisposable bs = new BooleanDisposable(); o.onSubscribe(bs); Thread t = new Thread(new Runnable() { @@ -1119,7 +1120,7 @@ public Integer apply(Integer i1, Integer i2) { return i1 + i2; } }); - List expected = new ArrayList<>(); + List expected = new ArrayList(); for (int i = 0; i < 1026; i++) { expected.add(i * 3); } diff --git a/src/test/java/io/reactivex/internal/subscriptions/AsyncSubscriptionTest.java b/src/test/java/io/reactivex/internal/subscriptions/AsyncSubscriptionTest.java index dfb02eafc5..b90f2d5051 100644 --- a/src/test/java/io/reactivex/internal/subscriptions/AsyncSubscriptionTest.java +++ b/src/test/java/io/reactivex/internal/subscriptions/AsyncSubscriptionTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,13 +13,15 @@ package io.reactivex.internal.subscriptions; -import static org.mockito.Mockito.*; import static org.junit.Assert.*; +import static org.mockito.Matchers.anyLong; +import static org.mockito.Mockito.*; import org.junit.Test; import org.reactivestreams.Subscription; import io.reactivex.disposables.Disposable; +import io.reactivex.internal.subscriptions.AsyncSubscription; public class AsyncSubscriptionTest { @Test @@ -81,7 +83,7 @@ public void testSingleSet() { assertTrue(as.setSubscription(s1)); - assertSame(as.actual, s); + assertSame(as.actual.get(), s); verify(s1).cancel(); } diff --git a/src/test/java/io/reactivex/nbp/NbpCombineLatestTests.java b/src/test/java/io/reactivex/nbp/NbpCombineLatestTests.java index d76ad53b07..163140323e 100644 --- a/src/test/java/io/reactivex/nbp/NbpCombineLatestTests.java +++ b/src/test/java/io/reactivex/nbp/NbpCombineLatestTests.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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. @@ -17,11 +17,10 @@ import static io.reactivex.NbpObservable.combineLatest; -import java.util.function.*; - import org.junit.*; import io.reactivex.NbpObservable; +import io.reactivex.functions.*; import io.reactivex.nbp.NbpCovarianceTest.*; import io.reactivex.subjects.nbp.NbpBehaviorSubject; @@ -43,11 +42,26 @@ public void testCovarianceOfCombineLatest() { NbpObservable. combineLatest(horrors, ratings, combine); } - BiFunction combine = (m, r) -> new ExtendedResult(); + BiFunction combine = new BiFunction() { + @Override + public ExtendedResult apply(Media m, Rating r) { + return new ExtendedResult(); + } + }; - Consumer action = t1 -> System.out.println("Result: " + t1); + Consumer action = new Consumer() { + @Override + public void accept(Result t1) { + System.out.println("Result: " + t1); + } + }; - Consumer extendedAction = t1 -> System.out.println("Result: " + t1); + Consumer extendedAction = new Consumer() { + @Override + public void accept(ExtendedResult t1) { + System.out.println("Result: " + t1); + } + }; @Ignore @Test @@ -62,6 +76,11 @@ public Boolean apply(Boolean bool1, Boolean bool2) { return bool1 == null ? null : bool2; } }); - combined.subscribe(aBoolean -> Assert.assertNull(aBoolean)); + combined.subscribe(new Consumer() { + @Override + public void accept(Boolean aBoolean) { + Assert.assertNull(aBoolean); + } + }); } } \ No newline at end of file diff --git a/src/test/java/io/reactivex/nbp/NbpConcatTests.java b/src/test/java/io/reactivex/nbp/NbpConcatTests.java index 24a02644f7..40f5cbfdf8 100644 --- a/src/test/java/io/reactivex/nbp/NbpConcatTests.java +++ b/src/test/java/io/reactivex/nbp/NbpConcatTests.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -19,6 +19,7 @@ import org.junit.Test; import io.reactivex.NbpObservable; +import io.reactivex.NbpObservable.*; import io.reactivex.nbp.NbpCovarianceTest.*; public class NbpConcatTests { @@ -60,6 +61,7 @@ public void testConcatWithIterableOfNbpObservable() { NbpObservable o2 = NbpObservable.just("three", "four"); NbpObservable o3 = NbpObservable.just("five", "six"); + @SuppressWarnings("unchecked") Iterable> is = Arrays.asList(o1, o2, o3); List values = NbpObservable.concat(NbpObservable.fromIterable(is)).toList().toBlocking().single(); @@ -142,11 +144,14 @@ public void testConcatCovariance4() { Media media = new Media(); HorrorMovie horrorMovie2 = new HorrorMovie(); - NbpObservable o1 = NbpObservable.create(o -> { - o.onNext(horrorMovie1); - o.onNext(movie); - // o.onNext(new Media()); // correctly doesn't compile - o.onComplete(); + NbpObservable o1 = NbpObservable.create(new NbpOnSubscribe() { + @Override + public void accept(NbpSubscriber o) { + o.onNext(horrorMovie1); + o.onNext(movie); + // o.onNext(new Media()); // correctly doesn't compile + o.onComplete(); + } }); NbpObservable o2 = NbpObservable.just(media, horrorMovie2); diff --git a/src/test/java/io/reactivex/nbp/NbpCovarianceTest.java b/src/test/java/io/reactivex/nbp/NbpCovarianceTest.java index 501d8f2a0f..a3c96343ce 100644 --- a/src/test/java/io/reactivex/nbp/NbpCovarianceTest.java +++ b/src/test/java/io/reactivex/nbp/NbpCovarianceTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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. @@ -19,12 +19,13 @@ import static org.junit.Assert.assertEquals; import java.util.*; -import java.util.function.Function; import org.junit.Test; import io.reactivex.NbpObservable; import io.reactivex.NbpObservable.NbpTransformer; +import io.reactivex.functions.*; +import io.reactivex.observables.nbp.NbpGroupedObservable; import io.reactivex.subscribers.nbp.NbpTestSubscriber; /** @@ -46,7 +47,12 @@ public void testCovarianceOfFrom() { @Test public void testSortedList() { - Comparator SORT_FUNCTION = (t1, t2) -> 1; + Comparator SORT_FUNCTION = new Comparator() { + @Override + public int compare(Media t1, Media t2) { + return 1; + } + }; // this one would work without the covariance generics NbpObservable o = NbpObservable.just(new Movie(), new TVSeason(), new Album()); @@ -60,16 +66,45 @@ public void testSortedList() { @Test public void testGroupByCompose() { NbpObservable movies = NbpObservable.just(new HorrorMovie(), new ActionMovie(), new Movie()); - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); movies - .groupBy(Object::getClass) - .doOnNext(g -> System.out.println(g.key())) - .flatMap(g -> - g - .doOnNext(System.out::println) - .compose(m -> m.concatWith(NbpObservable.just(new ActionMovie())) - ) - .map(Object::toString)) + .groupBy(new Function() { + @Override + public Object apply(Movie v) { + return v.getClass(); + } + }) + .doOnNext(new Consumer>() { + @Override + public void accept(NbpGroupedObservable g) { + System.out.println(g.key()); + } + }) + .flatMap(new Function, NbpObservable>() { + @Override + public NbpObservable apply(NbpGroupedObservable g) { + return g + .doOnNext(new Consumer() { + @Override + public void accept(Movie pv) { + System.out.println(pv); + } + }) + .compose(new Function, NbpObservable>() { + @Override + public NbpObservable apply(NbpObservable m) { + return m.concatWith(NbpObservable.just(new ActionMovie())); + } + } + ) + .map(new Function() { + @Override + public String apply(Movie v) { + return v.toString(); + } + }); + } + }) .subscribe(ts); ts.assertTerminated(); ts.assertNoErrors(); @@ -81,22 +116,41 @@ public void testGroupByCompose() { @Test public void testCovarianceOfCompose() { NbpObservable movie = NbpObservable.just(new HorrorMovie()); - NbpObservable movie2 = movie.compose(t -> NbpObservable.just(new Movie())); + NbpObservable movie2 = movie.compose(new Function, NbpObservable>() { + @Override + public NbpObservable apply(NbpObservable t) { + return NbpObservable.just(new Movie()); + } + }); } @SuppressWarnings("unused") @Test public void testCovarianceOfCompose2() { NbpObservable movie = NbpObservable. just(new HorrorMovie()); - NbpObservable movie2 = movie.compose(t -> NbpObservable.just(new HorrorMovie())); + NbpObservable movie2 = movie.compose(new Function, NbpObservable>() { + @Override + public NbpObservable apply(NbpObservable t) { + return NbpObservable.just(new HorrorMovie()); + } + }); } @SuppressWarnings("unused") @Test public void testCovarianceOfCompose3() { NbpObservable movie = NbpObservable.just(new HorrorMovie()); - NbpObservable movie2 = movie.compose(t -> - NbpObservable.just(new HorrorMovie()).map(v -> v) + NbpObservable movie2 = movie.compose(new Function, NbpObservable>() { + @Override + public NbpObservable apply(NbpObservable t) { + return NbpObservable.just(new HorrorMovie()).map(new Function() { + @Override + public HorrorMovie apply(HorrorMovie v) { + return v; + } + }); + } + } ); } @@ -104,7 +158,17 @@ public void testCovarianceOfCompose3() { @Test public void testCovarianceOfCompose4() { NbpObservable movie = NbpObservable.just(new HorrorMovie()); - NbpObservable movie2 = movie.compose(t1 -> t1.map(v -> v)); + NbpObservable movie2 = movie.compose(new Function, NbpObservable>() { + @Override + public NbpObservable apply(NbpObservable t1) { + return t1.map(new Function() { + @Override + public HorrorMovie apply(HorrorMovie v) { + return v; + } + }); + } + }); } @Test @@ -115,37 +179,43 @@ public void testComposeWithDeltaLogic() { movies.compose(deltaTransformer); } - static Function>, NbpObservable> calculateDelta = listOfLists -> { - if (listOfLists.size() == 1) { - return NbpObservable.fromIterable(listOfLists.get(0)); - } else { - // diff the two - List newList = listOfLists.get(1); - List oldList = new ArrayList<>(listOfLists.get(0)); + static Function>, NbpObservable> calculateDelta = new Function>, NbpObservable>() { + @Override + public NbpObservable apply(List> listOfLists) { + if (listOfLists.size() == 1) { + return NbpObservable.fromIterable(listOfLists.get(0)); + } else { + // diff the two + List newList = listOfLists.get(1); + List oldList = new ArrayList(listOfLists.get(0)); - Set delta = new LinkedHashSet<>(); - delta.addAll(newList); - // remove all that match in old - delta.removeAll(oldList); + Set delta = new LinkedHashSet(); + delta.addAll(newList); + // remove all that match in old + delta.removeAll(oldList); - // filter oldList to those that aren't in the newList - oldList.removeAll(newList); + // filter oldList to those that aren't in the newList + oldList.removeAll(newList); - // for all left in the oldList we'll create DROP events - for (@SuppressWarnings("unused") Movie old : oldList) { - delta.add(new Movie()); - } + // for all left in the oldList we'll create DROP events + for (@SuppressWarnings("unused") Movie old : oldList) { + delta.add(new Movie()); + } - return NbpObservable.fromIterable(delta); + return NbpObservable.fromIterable(delta); + } } }; - static NbpTransformer, Movie> deltaTransformer = movieList -> { - return movieList - .startWith(new ArrayList()) - .buffer(2, 1) - .skip(1) - .flatMap(calculateDelta); + static NbpTransformer, Movie> deltaTransformer = new NbpTransformer, Movie>() { + @Override + public NbpObservable apply(NbpObservable> movieList) { + return movieList + .startWith(new ArrayList()) + .buffer(2, 1) + .skip(1) + .flatMap(calculateDelta); + } }; /* diff --git a/src/test/java/io/reactivex/nbp/NbpErrorHandlingTests.java b/src/test/java/io/reactivex/nbp/NbpErrorHandlingTests.java index d208488d64..6a095691ec 100644 --- a/src/test/java/io/reactivex/nbp/NbpErrorHandlingTests.java +++ b/src/test/java/io/reactivex/nbp/NbpErrorHandlingTests.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -28,11 +28,12 @@ public class NbpErrorHandlingTests { /** * Test that an error from a user provided Observer.onNext is handled and emitted to the onError + * @throws InterruptedException if the test is interrupted */ @Test public void testOnNextError() throws InterruptedException { final CountDownLatch latch = new CountDownLatch(1); - final AtomicReference caughtError = new AtomicReference<>(); + final AtomicReference caughtError = new AtomicReference(); NbpObservable o = NbpObservable.interval(50, TimeUnit.MILLISECONDS); NbpSubscriber observer = new NbpObserver() { @@ -63,11 +64,12 @@ public void onNext(Long args) { /** * Test that an error from a user provided Observer.onNext is handled and emitted to the onError * even when done across thread boundaries with observeOn + * @throws InterruptedException if the test is interrupted */ @Test public void testOnNextErrorAcrossThread() throws InterruptedException { final CountDownLatch latch = new CountDownLatch(1); - final AtomicReference caughtError = new AtomicReference<>(); + final AtomicReference caughtError = new AtomicReference(); NbpObservable o = NbpObservable.interval(50, TimeUnit.MILLISECONDS); NbpSubscriber observer = new NbpObserver() { diff --git a/src/test/java/io/reactivex/nbp/NbpEventStream.java b/src/test/java/io/reactivex/nbp/NbpEventStream.java index ced3bc03b6..2515f35d33 100644 --- a/src/test/java/io/reactivex/nbp/NbpEventStream.java +++ b/src/test/java/io/reactivex/nbp/NbpEventStream.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -16,6 +16,8 @@ import java.util.*; import io.reactivex.NbpObservable; +import io.reactivex.NbpObservable.NbpSubscriber; +import io.reactivex.functions.Consumer; import io.reactivex.schedulers.Schedulers; /** @@ -27,20 +29,23 @@ private NbpEventStream() { } public static NbpObservable getEventStream(final String type, final int numInstances) { - return NbpObservable.generate(s -> { - s.onNext(randomEvent(type, numInstances)); - try { - // slow it down somewhat - Thread.sleep(50); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - s.onError(e); + return NbpObservable.generate(new Consumer>() { + @Override + public void accept(NbpSubscriber s) { + s.onNext(randomEvent(type, numInstances)); + try { + // slow it down somewhat + Thread.sleep(50); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + s.onError(e); + } } }).subscribeOn(Schedulers.newThread()); } public static Event randomEvent(String type, int numInstances) { - Map values = new LinkedHashMap<>(); + Map values = new LinkedHashMap(); values.put("count200", randomIntFrom0to(4000)); values.put("count4xx", randomIntFrom0to(300)); values.put("count5xx", randomIntFrom0to(500)); diff --git a/src/test/java/io/reactivex/nbp/NbpGroupByTests.java b/src/test/java/io/reactivex/nbp/NbpGroupByTests.java index 33ecf4ff51..57fc9bc838 100644 --- a/src/test/java/io/reactivex/nbp/NbpGroupByTests.java +++ b/src/test/java/io/reactivex/nbp/NbpGroupByTests.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -16,6 +16,9 @@ import org.junit.Test; import io.reactivex.NbpObservable; +import io.reactivex.functions.*; +import io.reactivex.nbp.NbpEventStream.Event; +import io.reactivex.observables.nbp.NbpGroupedObservable; public class NbpGroupByTests { @@ -26,12 +29,20 @@ public void testTakeUnsubscribesOnGroupBy() { NbpEventStream.getEventStream("HTTP-ClusterB", 20) ) // group by type (2 clusters) - .groupBy(event -> event.type) + .groupBy(new Function() { + @Override + public String apply(Event event) { + return event.type; + } + }) .take(1) .toBlocking() - .forEach(v -> { - System.out.println(v); - v.take(1).subscribe(); // FIXME groups need consumption to a certain degree to cancel upstream + .forEach(new Consumer>() { + @Override + public void accept(NbpGroupedObservable v) { + System.out.println(v); + v.take(1).subscribe(); // FIXME groups need consumption to a certain degree to cancel upstream + } }); System.out.println("**** finished"); @@ -44,11 +55,31 @@ public void testTakeUnsubscribesOnFlatMapOfGroupBy() { NbpEventStream.getEventStream("HTTP-ClusterB", 20) ) // group by type (2 clusters) - .groupBy(event -> event.type) - .flatMap(g -> g.map(event -> event.instanceId + " - " + event.values.get("count200"))) + .groupBy(new Function() { + @Override + public String apply(Event event) { + return event.type; + } + }) + .flatMap(new Function, NbpObservable>() { + @Override + public NbpObservable apply(NbpGroupedObservable g) { + return g.map(new Function() { + @Override + public Object apply(Event event) { + return event.instanceId + " - " + event.values.get("count200"); + } + }); + } + }) .take(20) .toBlocking() - .forEach(System.out::println); + .forEach(new Consumer() { + @Override + public void accept(Object pv) { + System.out.println(pv); + } + }); System.out.println("**** finished"); } diff --git a/src/test/java/io/reactivex/nbp/NbpMergeTests.java b/src/test/java/io/reactivex/nbp/NbpMergeTests.java index 8493135e85..2c01b3a7f6 100644 --- a/src/test/java/io/reactivex/nbp/NbpMergeTests.java +++ b/src/test/java/io/reactivex/nbp/NbpMergeTests.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -20,6 +20,7 @@ import org.junit.Test; import io.reactivex.NbpObservable; +import io.reactivex.functions.Supplier; import io.reactivex.nbp.NbpCovarianceTest.*; public class NbpMergeTests { @@ -74,10 +75,15 @@ public void testMergeCovariance3() { @Test public void testMergeCovariance4() { - NbpObservable o1 = NbpObservable.defer(() -> NbpObservable.just( - new HorrorMovie(), - new Movie() - )); + NbpObservable o1 = NbpObservable.defer(new Supplier>() { + @Override + public NbpObservable get() { + return NbpObservable.just( + new HorrorMovie(), + new Movie() + ); + } + }); NbpObservable o2 = NbpObservable.just(new Media(), new HorrorMovie()); diff --git a/src/test/java/io/reactivex/nbp/NbpObservableDoOnTest.java b/src/test/java/io/reactivex/nbp/NbpObservableDoOnTest.java index 99478c2389..02a5c9bf56 100644 --- a/src/test/java/io/reactivex/nbp/NbpObservableDoOnTest.java +++ b/src/test/java/io/reactivex/nbp/NbpObservableDoOnTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -20,13 +20,19 @@ import org.junit.Test; import io.reactivex.NbpObservable; +import io.reactivex.functions.Consumer; public class NbpObservableDoOnTest { @Test public void testDoOnEach() { - final AtomicReference r = new AtomicReference<>(); - String output = NbpObservable.just("one").doOnNext(r::set).toBlocking().single(); + final AtomicReference r = new AtomicReference(); + String output = NbpObservable.just("one").doOnNext(new Consumer() { + @Override + public void accept(String v) { + r.set(v); + } + }).toBlocking().single(); assertEquals("one", output); assertEquals("one", r.get()); @@ -34,11 +40,16 @@ public void testDoOnEach() { @Test public void testDoOnError() { - final AtomicReference r = new AtomicReference<>(); + final AtomicReference r = new AtomicReference(); Throwable t = null; try { NbpObservable. error(new RuntimeException("an error")) - .doOnError(r::set).toBlocking().single(); + .doOnError(new Consumer() { + @Override + public void accept(Throwable v) { + r.set(v); + } + }).toBlocking().single(); fail("expected exception, not a return value"); } catch (Throwable e) { t = e; @@ -51,7 +62,12 @@ NbpObservable. error(new RuntimeException("an error")) @Test public void testDoOnCompleted() { final AtomicBoolean r = new AtomicBoolean(); - String output = NbpObservable.just("one").doOnComplete(() -> r.set(true)).toBlocking().single(); + String output = NbpObservable.just("one").doOnComplete(new Runnable() { + @Override + public void run() { + r.set(true); + } + }).toBlocking().single(); assertEquals("one", output); assertTrue(r.get()); diff --git a/src/test/java/io/reactivex/nbp/NbpObservableTest.java b/src/test/java/io/reactivex/nbp/NbpObservableTest.java index a2be6b7981..626440961e 100644 --- a/src/test/java/io/reactivex/nbp/NbpObservableTest.java +++ b/src/test/java/io/reactivex/nbp/NbpObservableTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -18,11 +18,17 @@ import org.junit.*; import io.reactivex.NbpObservable; +import io.reactivex.functions.Function; public class NbpObservableTest { @Test public void testFlatMap() { - List list = NbpObservable.range(1, 5).flatMap(v -> NbpObservable.range(v, 2)).getList(); + List list = NbpObservable.range(1, 5).flatMap(new Function>() { + @Override + public NbpObservable apply(Integer v) { + return NbpObservable.range(v, 2); + } + }).getList(); Assert.assertEquals(Arrays.asList(1, 2, 2, 3, 3, 4, 4, 5, 5, 6), list); } diff --git a/src/test/java/io/reactivex/nbp/NbpObservableTests.java b/src/test/java/io/reactivex/nbp/NbpObservableTests.java index b7d94a2f5e..87889e9a02 100644 --- a/src/test/java/io/reactivex/nbp/NbpObservableTests.java +++ b/src/test/java/io/reactivex/nbp/NbpObservableTests.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -20,14 +20,14 @@ import java.util.*; import java.util.concurrent.*; import java.util.concurrent.atomic.*; -import java.util.function.Predicate; import org.junit.*; import org.mockito.InOrder; import io.reactivex.*; -import io.reactivex.NbpObservable.NbpSubscriber; +import io.reactivex.NbpObservable.*; import io.reactivex.disposables.Disposable; +import io.reactivex.functions.*; import io.reactivex.internal.disposables.EmptyDisposable; import io.reactivex.observables.nbp.NbpConnectableObservable; import io.reactivex.schedulers.*; @@ -38,7 +38,12 @@ public class NbpObservableTests { NbpSubscriber w; - private static final Predicate IS_EVEN = v -> v % 2 == 0; + private static final Predicate IS_EVEN = new Predicate() { + @Override + public boolean test(Integer v) { + return v % 2 == 0; + } + }; @Before public void before() { @@ -55,7 +60,7 @@ public void fromArray() { @Test public void fromIterable() { - ArrayList items = new ArrayList<>(); + ArrayList items = new ArrayList(); items.add("one"); items.add("two"); items.add("three"); @@ -124,7 +129,12 @@ public void testCountZeroItems() { @Test public void testCountError() { - NbpObservable o = NbpObservable.error(() -> new RuntimeException()); + NbpObservable o = NbpObservable.error(new Supplier() { + @Override + public Throwable get() { + return new RuntimeException(); + } + }); o.count().subscribe(w); verify(w, never()).onNext(anyInt()); @@ -190,7 +200,12 @@ public void testFirstWithPredicateOfNoneMatchingThePredicate() { @Test public void testReduce() { NbpObservable o = NbpObservable.just(1, 2, 3, 4); - o.reduce((t1, t2) -> t1 + t2) + o.reduce(new BiFunction() { + @Override + public Integer apply(Integer t1, Integer t2) { + return t1 + t2; + } + }) .subscribe(w); // we should be called only once verify(w, times(1)).onNext(anyInt()); @@ -203,9 +218,17 @@ public void testReduce() { @Test(expected = NoSuchElementException.class) public void testReduceWithEmptyNbpObservable() { NbpObservable o = NbpObservable.range(1, 0); - o.reduce((t1, t2) -> t1 + t2) - .toBlocking().forEach(t1 -> { - // do nothing ... we expect an exception instead + o.reduce(new BiFunction() { + @Override + public Integer apply(Integer t1, Integer t2) { + return t1 + t2; + } + }) + .toBlocking().forEach(new Consumer() { + @Override + public void accept(Integer t1) { + // do nothing ... we expect an exception instead + } }); fail("Expected an exception to be thrown"); @@ -219,7 +242,12 @@ public void testReduceWithEmptyNbpObservable() { @Test public void testReduceWithEmptyNbpObservableAndSeed() { NbpObservable o = NbpObservable.range(1, 0); - int value = o.reduce(1, (t1, t2) -> t1 + t2) + int value = o.reduce(1, new BiFunction() { + @Override + public Integer apply(Integer t1, Integer t2) { + return t1 + t2; + } + }) .toBlocking().last(); assertEquals(1, value); @@ -228,7 +256,12 @@ public void testReduceWithEmptyNbpObservableAndSeed() { @Test public void testReduceWithInitialValue() { NbpObservable o = NbpObservable.just(1, 2, 3, 4); - o.reduce(50, (t1, t2) -> t1 + t2) + o.reduce(50, new BiFunction() { + @Override + public Integer apply(Integer t1, Integer t2) { + return t1 + t2; + } + }) .subscribe(w); // we should be called only once verify(w, times(1)).onNext(anyInt()); @@ -241,7 +274,10 @@ public void testOnSubscribeFails() { NbpSubscriber observer = TestHelper.mockNbpSubscriber(); final RuntimeException re = new RuntimeException("bad impl"); - NbpObservable o = NbpObservable.create(s -> { throw re; }); + NbpObservable o = NbpObservable.create(new NbpOnSubscribe() { + @Override + public void accept(NbpSubscriber s) { throw re; } + }); o.subscribe(observer); verify(observer, times(0)).onNext(anyString()); @@ -269,12 +305,13 @@ public void testMaterializeDematerializeChaining() { * It is handled by the AtomicObserver that wraps the provided Observer. * * Result: Passes (if AtomicObserver functionality exists) + * @throws InterruptedException if the test is interrupted */ @Test public void testCustomNbpObservableWithErrorInObserverAsynchronous() throws InterruptedException { final CountDownLatch latch = new CountDownLatch(1); final AtomicInteger count = new AtomicInteger(); - final AtomicReference error = new AtomicReference<>(); + final AtomicReference error = new AtomicReference(); // FIXME custom built??? NbpObservable.just("1", "2", "three", "4") @@ -322,7 +359,7 @@ public void onNext(String v) { @Test public void testCustomNbpObservableWithErrorInObserverSynchronous() { final AtomicInteger count = new AtomicInteger(); - final AtomicReference error = new AtomicReference<>(); + final AtomicReference error = new AtomicReference(); // FIXME custom built??? NbpObservable.just("1", "2", "three", "4") @@ -365,9 +402,14 @@ public void onNext(String v) { @Test public void testCustomNbpObservableWithErrorInNbpObservableSynchronous() { final AtomicInteger count = new AtomicInteger(); - final AtomicReference error = new AtomicReference<>(); + final AtomicReference error = new AtomicReference(); // FIXME custom built??? - NbpObservable.just("1", "2").concatWith(NbpObservable.error(() -> new NumberFormatException())) + NbpObservable.just("1", "2").concatWith(NbpObservable.error(new Supplier() { + @Override + public Throwable get() { + return new NumberFormatException(); + } + })) .subscribe(new NbpObserver() { @Override @@ -399,21 +441,30 @@ public void onNext(String v) { @Test public void testPublishLast() throws InterruptedException { final AtomicInteger count = new AtomicInteger(); - NbpConnectableObservable connectable = NbpObservable.create(observer -> { - observer.onSubscribe(EmptyDisposable.INSTANCE); - count.incrementAndGet(); - new Thread(() -> { - observer.onNext("first"); - observer.onNext("last"); - observer.onComplete(); - }).start(); + NbpConnectableObservable connectable = NbpObservable.create(new NbpOnSubscribe() { + @Override + public void accept(final NbpSubscriber observer) { + observer.onSubscribe(EmptyDisposable.INSTANCE); + count.incrementAndGet(); + new Thread(new Runnable() { + @Override + public void run() { + observer.onNext("first"); + observer.onNext("last"); + observer.onComplete(); + } + }).start(); + } }).takeLast(1).publish(); // subscribe once final CountDownLatch latch = new CountDownLatch(1); - connectable.subscribe(value -> { - assertEquals("last", value); - latch.countDown(); + connectable.subscribe(new Consumer() { + @Override + public void accept(String value) { + assertEquals("last", value); + latch.countDown(); + } }); // subscribe twice @@ -428,17 +479,20 @@ public void testPublishLast() throws InterruptedException { @Test public void testReplay() throws InterruptedException { final AtomicInteger counter = new AtomicInteger(); - NbpConnectableObservable o = NbpObservable.create(observer -> { - observer.onSubscribe(EmptyDisposable.INSTANCE); - new Thread(new Runnable() { - - @Override - public void run() { - counter.incrementAndGet(); - observer.onNext("one"); - observer.onComplete(); - } - }).start(); + NbpConnectableObservable o = NbpObservable.create(new NbpOnSubscribe() { + @Override + public void accept(final NbpSubscriber observer) { + observer.onSubscribe(EmptyDisposable.INSTANCE); + new Thread(new Runnable() { + + @Override + public void run() { + counter.incrementAndGet(); + observer.onNext("one"); + observer.onComplete(); + } + }).start(); + } }).replay(); // we connect immediately and it will emit the value @@ -449,15 +503,21 @@ public void run() { final CountDownLatch latch = new CountDownLatch(2); // subscribe once - o.subscribe(v -> { - assertEquals("one", v); - latch.countDown(); + o.subscribe(new Consumer() { + @Override + public void accept(String v) { + assertEquals("one", v); + latch.countDown(); + } }); // subscribe again - o.subscribe(v -> { - assertEquals("one", v); - latch.countDown(); + o.subscribe(new Consumer() { + @Override + public void accept(String v) { + assertEquals("one", v); + latch.countDown(); + } }); if (!latch.await(1000, TimeUnit.MILLISECONDS)) { @@ -472,28 +532,40 @@ public void run() { @Test public void testCache() throws InterruptedException { final AtomicInteger counter = new AtomicInteger(); - NbpObservable o = NbpObservable.create(observer -> { - observer.onSubscribe(EmptyDisposable.INSTANCE); - new Thread(() -> { - counter.incrementAndGet(); - observer.onNext("one"); - observer.onComplete(); - }).start(); + NbpObservable o = NbpObservable.create(new NbpOnSubscribe() { + @Override + public void accept(final NbpSubscriber observer) { + observer.onSubscribe(EmptyDisposable.INSTANCE); + new Thread(new Runnable() { + @Override + public void run() { + counter.incrementAndGet(); + observer.onNext("one"); + observer.onComplete(); + } + }).start(); + } }).cache(); // we then expect the following 2 subscriptions to get that same value final CountDownLatch latch = new CountDownLatch(2); // subscribe once - o.subscribe(v -> { - assertEquals("one", v); - latch.countDown(); + o.subscribe(new Consumer() { + @Override + public void accept(String v) { + assertEquals("one", v); + latch.countDown(); + } }); // subscribe again - o.subscribe(v -> { - assertEquals("one", v); - latch.countDown(); + o.subscribe(new Consumer() { + @Override + public void accept(String v) { + assertEquals("one", v); + latch.countDown(); + } }); if (!latch.await(1000, TimeUnit.MILLISECONDS)) { @@ -505,28 +577,40 @@ public void testCache() throws InterruptedException { @Test public void testCacheWithCapacity() throws InterruptedException { final AtomicInteger counter = new AtomicInteger(); - NbpObservable o = NbpObservable.create(observer -> { - observer.onSubscribe(EmptyDisposable.INSTANCE); - new Thread(() -> { - counter.incrementAndGet(); - observer.onNext("one"); - observer.onComplete(); - }).start(); + NbpObservable o = NbpObservable.create(new NbpOnSubscribe() { + @Override + public void accept(final NbpSubscriber observer) { + observer.onSubscribe(EmptyDisposable.INSTANCE); + new Thread(new Runnable() { + @Override + public void run() { + counter.incrementAndGet(); + observer.onNext("one"); + observer.onComplete(); + } + }).start(); + } }).cache(1); // we then expect the following 2 subscriptions to get that same value final CountDownLatch latch = new CountDownLatch(2); // subscribe once - o.subscribe(v -> { - assertEquals("one", v); - latch.countDown(); + o.subscribe(new Consumer() { + @Override + public void accept(String v) { + assertEquals("one", v); + latch.countDown(); + } }); // subscribe again - o.subscribe(v -> { - assertEquals("one", v); - latch.countDown(); + o.subscribe(new Consumer() { + @Override + public void accept(String v) { + assertEquals("one", v); + latch.countDown(); + } }); if (!latch.await(1000, TimeUnit.MILLISECONDS)) { @@ -571,17 +655,23 @@ public void testErrorThrownWithoutErrorHandlerSynchronous() { @Ignore("Subscribers can't throw") public void testErrorThrownWithoutErrorHandlerAsynchronous() throws InterruptedException { final CountDownLatch latch = new CountDownLatch(1); - final AtomicReference exception = new AtomicReference<>(); - NbpObservable.create(observer -> { - new Thread(() -> { - try { - observer.onError(new Error("failure")); - } catch (Throwable e) { - // without an onError handler it has to just throw on whatever thread invokes it - exception.set(e); - } - latch.countDown(); - }).start(); + final AtomicReference exception = new AtomicReference(); + NbpObservable.create(new NbpOnSubscribe() { + @Override + public void accept(final NbpSubscriber observer) { + new Thread(new Runnable() { + @Override + public void run() { + try { + observer.onError(new Error("failure")); + } catch (Throwable e) { + // without an onError handler it has to just throw on whatever thread invokes it + exception.set(e); + } + latch.countDown(); + } + }).start(); + } }).subscribe(); // wait for exception latch.await(3000, TimeUnit.MILLISECONDS); @@ -592,7 +682,7 @@ public void testErrorThrownWithoutErrorHandlerAsynchronous() throws InterruptedE @Test public void testTakeWithErrorInObserver() { final AtomicInteger count = new AtomicInteger(); - final AtomicReference error = new AtomicReference<>(); + final AtomicReference error = new AtomicReference(); NbpObservable.just("1", "2", "three", "4").take(3) .safeSubscribe(new NbpObserver() { @@ -643,9 +733,9 @@ public void testOfType() { @Test public void testOfTypeWithPolymorphism() { - ArrayList l1 = new ArrayList<>(); + ArrayList l1 = new ArrayList(); l1.add(1); - LinkedList l2 = new LinkedList<>(); + LinkedList l2 = new LinkedList(); l2.add(2); @SuppressWarnings("rawtypes") @@ -798,7 +888,17 @@ public void testRangeWithScheduler() { @Test public void testCollectToList() { NbpObservable> o = NbpObservable.just(1, 2, 3) - .collect(ArrayList::new, (list, v) -> list.add(v)); + .collect(new Supplier>() { + @Override + public List get() { + return new ArrayList(); + } + }, new BiConsumer, Integer>() { + @Override + public void accept(List list, Integer v) { + list.add(v); + } + }); List list = o.toBlocking().last(); @@ -818,34 +918,42 @@ public void testCollectToList() { @Test public void testCollectToString() { - String value = NbpObservable.just(1, 2, 3).collect(StringBuilder::new, - (sb, v) -> { - if (sb.length() > 0) { - sb.append("-"); + String value = NbpObservable.just(1, 2, 3).collect(new Supplier() { + @Override + public StringBuilder get() { + return new StringBuilder(); } - sb.append(v); - }).toBlocking().last().toString(); + }, + new BiConsumer() { + @Override + public void accept(StringBuilder sb, Integer v) { + if (sb.length() > 0) { + sb.append("-"); + } + sb.append(v); + } + }).toBlocking().last().toString(); assertEquals("1-2-3", value); } @Test public void testMergeWith() { - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); NbpObservable.just(1).mergeWith(NbpObservable.just(2)).subscribe(ts); ts.assertValues(1, 2); } @Test public void testConcatWith() { - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); NbpObservable.just(1).concatWith(NbpObservable.just(2)).subscribe(ts); ts.assertValues(1, 2); } @Test public void testAmbWith() { - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpTestSubscriber ts = new NbpTestSubscriber(); NbpObservable.just(1).ambWith(NbpObservable.just(2)).subscribe(ts); ts.assertValue(1); } @@ -868,9 +976,19 @@ public void testTakeWhileToList() { for (int i = 0;i < expectedCount; i++) { NbpObservable .just(Boolean.TRUE, Boolean.FALSE) - .takeWhile(v -> v) + .takeWhile(new Predicate() { + @Override + public boolean test(Boolean v) { + return v; + } + }) .toList() - .doOnNext(booleans -> count.incrementAndGet()) + .doOnNext(new Consumer>() { + @Override + public void accept(List booleans) { + count.incrementAndGet(); + } + }) .subscribe(); } assertEquals(expectedCount, count.get()); @@ -878,8 +996,18 @@ public void testTakeWhileToList() { @Test public void testCompose() { - NbpTestSubscriber ts = new NbpTestSubscriber<>(); - NbpObservable.just(1, 2, 3).compose(t1 ->t1.map(String::valueOf)) + NbpTestSubscriber ts = new NbpTestSubscriber(); + NbpObservable.just(1, 2, 3).compose(new Function, NbpObservable>() { + @Override + public NbpObservable apply(NbpObservable t1) { + return t1.map(new Function() { + @Override + public String apply(Integer v) { + return String.valueOf(v); + } + }); + } + }) .subscribe(ts); ts.assertTerminated(); ts.assertNoErrors(); @@ -919,7 +1047,7 @@ public void testEmptyIsEmpty() { // FIXME this test doesn't make sense // @Test // cf. https://github.com/ReactiveX/RxJava/issues/2599 // public void testSubscribingSubscriberAsObserverMaintainsSubscriptionChain() { -// NbpTestSubscriber subscriber = new NbpTestSubscriber<>(); +// NbpTestSubscriber subscriber = new NbpTestSubscriber(); // Subscription subscription = NbpObservable.just("event").subscribe((Observer) subscriber); // subscription.unsubscribe(); // @@ -947,14 +1075,17 @@ public void testForEachWithNull() { @Test public void testExtend() { - final NbpTestSubscriber subscriber = new NbpTestSubscriber<>(); + final NbpTestSubscriber subscriber = new NbpTestSubscriber(); final Object value = new Object(); - NbpObservable.just(value).to(onSubscribe -> { - onSubscribe.subscribe(subscriber); - subscriber.assertNoErrors(); - subscriber.assertComplete(); - subscriber.assertValue(value); - return subscriber.values().get(0); - }); + NbpObservable.just(value).to(new Function, Object>() { + @Override + public Object apply(NbpObservable onSubscribe) { + onSubscribe.subscribe(subscriber); + subscriber.assertNoErrors(); + subscriber.assertComplete(); + subscriber.assertValue(value); + return subscriber.values().get(0); + } + }); } } \ No newline at end of file diff --git a/src/test/java/io/reactivex/nbp/NbpObservableWindowTests.java b/src/test/java/io/reactivex/nbp/NbpObservableWindowTests.java index 392de78020..cc6f09e9ba 100644 --- a/src/test/java/io/reactivex/nbp/NbpObservableWindowTests.java +++ b/src/test/java/io/reactivex/nbp/NbpObservableWindowTests.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -20,19 +20,30 @@ import org.junit.Test; import io.reactivex.NbpObservable; +import io.reactivex.functions.*; public class NbpObservableWindowTests { @Test public void testWindow() { - final ArrayList> lists = new ArrayList<>(); + final ArrayList> lists = new ArrayList>(); NbpObservable.concat( NbpObservable.just(1, 2, 3, 4, 5, 6) .window(3) - .map(xs -> xs.toList()) + .map(new Function, NbpObservable>>() { + @Override + public NbpObservable> apply(NbpObservable xs) { + return xs.toList(); + } + }) ) - .toBlocking().forEach(xs -> lists.add(xs)); + .toBlocking().forEach(new Consumer>() { + @Override + public void accept(List xs) { + lists.add(xs); + } + }); assertArrayEquals(lists.get(0).toArray(new Integer[3]), new Integer[] { 1, 2, 3 }); assertArrayEquals(lists.get(1).toArray(new Integer[3]), new Integer[] { 4, 5, 6 }); diff --git a/src/test/java/io/reactivex/nbp/NbpReduceTests.java b/src/test/java/io/reactivex/nbp/NbpReduceTests.java index 3671152953..b467e4e635 100644 --- a/src/test/java/io/reactivex/nbp/NbpReduceTests.java +++ b/src/test/java/io/reactivex/nbp/NbpReduceTests.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -18,6 +18,7 @@ import org.junit.Test; import io.reactivex.NbpObservable; +import io.reactivex.functions.BiFunction; import io.reactivex.nbp.NbpCovarianceTest.*; public class NbpReduceTests { @@ -25,7 +26,12 @@ public class NbpReduceTests { @Test public void reduceInts() { NbpObservable o = NbpObservable.just(1, 2, 3); - int value = o.reduce((t1, t2) -> t1 + t2).toBlocking().single(); + int value = o.reduce(new BiFunction() { + @Override + public Integer apply(Integer t1, Integer t2) { + return t1 + t2; + } + }).toBlocking().single(); assertEquals(6, value); } @@ -35,9 +41,19 @@ public void reduceInts() { public void reduceWithObjects() { NbpObservable horrorMovies = NbpObservable. just(new HorrorMovie()); - NbpObservable reduceResult = horrorMovies.scan((t1, t2) -> t2).takeLast(1); - - NbpObservable reduceResult2 = horrorMovies.reduce((t1, t2) -> t2); + NbpObservable reduceResult = horrorMovies.scan(new BiFunction() { + @Override + public Movie apply(Movie t1, Movie t2) { + return t2; + } + }).takeLast(1); + + NbpObservable reduceResult2 = horrorMovies.reduce(new BiFunction() { + @Override + public Movie apply(Movie t1, Movie t2) { + return t2; + } + }); } /** @@ -50,7 +66,12 @@ public void reduceWithObjects() { public void reduceWithCovariantObjects() { NbpObservable horrorMovies = NbpObservable. just(new HorrorMovie()); - NbpObservable reduceResult2 = horrorMovies.reduce((t1, t2) -> t2); + NbpObservable reduceResult2 = horrorMovies.reduce(new BiFunction() { + @Override + public Movie apply(Movie t1, Movie t2) { + return t2; + } + }); } /** @@ -70,7 +91,12 @@ public void reduceCovariance() { */ public void libraryFunctionActingOnMovieNbpObservables(NbpObservable obs) { - obs.reduce((t1, t2) -> t2); + obs.reduce(new BiFunction() { + @Override + public Movie apply(Movie t1, Movie t2) { + return t2; + } + }); } } \ No newline at end of file diff --git a/src/test/java/io/reactivex/nbp/NbpScanTests.java b/src/test/java/io/reactivex/nbp/NbpScanTests.java index 2be11a97cf..5192061b28 100644 --- a/src/test/java/io/reactivex/nbp/NbpScanTests.java +++ b/src/test/java/io/reactivex/nbp/NbpScanTests.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -17,18 +17,29 @@ import org.junit.Test; +import io.reactivex.functions.*; +import io.reactivex.nbp.NbpEventStream.Event; + public class NbpScanTests { @Test public void testUnsubscribeScan() { NbpEventStream.getEventStream("HTTP-ClusterB", 20) - .scan(new HashMap(), (accum, perInstanceEvent) -> { - accum.put("instance", perInstanceEvent.instanceId); - return accum; + .scan(new HashMap(), new BiFunction, Event, HashMap>() { + @Override + public HashMap apply(HashMap accum, Event perInstanceEvent) { + accum.put("instance", perInstanceEvent.instanceId); + return accum; + } }) .take(10) .toBlocking() - .forEach(System.out::println); + .forEach(new Consumer>() { + @Override + public void accept(HashMap pv) { + System.out.println(pv); + } + }); } } \ No newline at end of file diff --git a/src/test/java/io/reactivex/nbp/NbpStartWithTests.java b/src/test/java/io/reactivex/nbp/NbpStartWithTests.java index ae6e903129..8bdd2e3a1a 100644 --- a/src/test/java/io/reactivex/nbp/NbpStartWithTests.java +++ b/src/test/java/io/reactivex/nbp/NbpStartWithTests.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -34,7 +34,7 @@ public void startWith1() { @Test public void startWithIterable() { - List li = new ArrayList<>(); + List li = new ArrayList(); li.add("alpha"); li.add("beta"); List values = NbpObservable.just("one", "two").startWith(li).toList().toBlocking().single(); @@ -47,7 +47,7 @@ public void startWithIterable() { @Test public void startWithObservable() { - List li = new ArrayList<>(); + List li = new ArrayList(); li.add("alpha"); li.add("beta"); List values = NbpObservable.just("one", "two") diff --git a/src/test/java/io/reactivex/nbp/NbpSubscriberTest.java b/src/test/java/io/reactivex/nbp/NbpSubscriberTest.java index ef1dee0756..024aaa38c6 100644 --- a/src/test/java/io/reactivex/nbp/NbpSubscriberTest.java +++ b/src/test/java/io/reactivex/nbp/NbpSubscriberTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 diff --git a/src/test/java/io/reactivex/nbp/NbpThrottleLastTests.java b/src/test/java/io/reactivex/nbp/NbpThrottleLastTests.java index 3b24b3bb4d..984e7d4ddf 100644 --- a/src/test/java/io/reactivex/nbp/NbpThrottleLastTests.java +++ b/src/test/java/io/reactivex/nbp/NbpThrottleLastTests.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -20,8 +20,8 @@ import org.junit.Test; import org.mockito.InOrder; -import io.reactivex.NbpObservable.NbpSubscriber; import io.reactivex.TestHelper; +import io.reactivex.NbpObservable.NbpSubscriber; import io.reactivex.schedulers.TestScheduler; import io.reactivex.subjects.nbp.NbpPublishSubject; diff --git a/src/test/java/io/reactivex/nbp/NbpThrottleWithTimeoutTests.java b/src/test/java/io/reactivex/nbp/NbpThrottleWithTimeoutTests.java index bcfb994d90..d8f1eb7eee 100644 --- a/src/test/java/io/reactivex/nbp/NbpThrottleWithTimeoutTests.java +++ b/src/test/java/io/reactivex/nbp/NbpThrottleWithTimeoutTests.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -20,8 +20,8 @@ import org.junit.Test; import org.mockito.InOrder; -import io.reactivex.NbpObservable.NbpSubscriber; import io.reactivex.TestHelper; +import io.reactivex.NbpObservable.NbpSubscriber; import io.reactivex.schedulers.TestScheduler; import io.reactivex.subjects.nbp.NbpPublishSubject; diff --git a/src/test/java/io/reactivex/nbp/NbpZipTests.java b/src/test/java/io/reactivex/nbp/NbpZipTests.java index ebe74fc445..cd63343db1 100644 --- a/src/test/java/io/reactivex/nbp/NbpZipTests.java +++ b/src/test/java/io/reactivex/nbp/NbpZipTests.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -16,28 +16,47 @@ import static org.junit.Assert.assertSame; import java.util.*; -import java.util.function.*; import org.junit.*; import io.reactivex.NbpObservable; +import io.reactivex.functions.*; import io.reactivex.nbp.NbpCovarianceTest.*; +import io.reactivex.nbp.NbpEventStream.Event; +import io.reactivex.observables.nbp.NbpGroupedObservable; public class NbpZipTests { @Test public void testZipNbpObservableOfNbpObservables() { NbpEventStream.getEventStream("HTTP-ClusterB", 20) - .groupBy(e -> e.instanceId) + .groupBy(new Function() { + @Override + public String apply(Event e) { + return e.instanceId; + } + }) // now we have streams of cluster+instanceId - .flatMap(ge -> { - return ge.scan(new HashMap(), (accum, perInstanceEvent) -> { - accum.put("instance", ge.key()); - return accum; - }); + .flatMap(new Function, NbpObservable>>() { + @Override + public NbpObservable> apply(final NbpGroupedObservable ge) { + return ge.scan(new HashMap(), new BiFunction, Event, HashMap>() { + @Override + public HashMap apply(HashMap accum, + Event perInstanceEvent) { + accum.put("instance", ge.key()); + return accum; + } + }); + } }) .take(10) - .toBlocking().forEach(System.out::println); + .toBlocking().forEach(new Consumer() { + @Override + public void accept(Object pv) { + System.out.println(pv); + } + }); System.out.println("**** finished"); } @@ -72,20 +91,36 @@ public void nonBlockingNbpObservable() { Collection> NbpObservables = Collections.emptyList(); - NbpObservable result = NbpObservable.zip(NbpObservables, args -> { - System.out.println("received: " + args); - Assert.assertEquals("No argument should have been passed", 0, args.length); - return invoked; + NbpObservable result = NbpObservable.zip(NbpObservables, new Function() { + @Override + public Object apply(Object[] args) { + System.out.println("received: " + args); + Assert.assertEquals("No argument should have been passed", 0, args.length); + return invoked; + } }); assertSame(invoked, result.toBlocking().last()); } - BiFunction combine = (m, r) -> { - return new ExtendedResult(); + BiFunction combine = new BiFunction() { + @Override + public ExtendedResult apply(Media m, Rating r) { + return new ExtendedResult(); + } }; - Consumer action = t1 -> System.out.println("Result: " + t1); + Consumer action = new Consumer() { + @Override + public void accept(Result t1) { + System.out.println("Result: " + t1); + } + }; - Consumer extendedAction = t1 -> System.out.println("Result: " + t1); + Consumer extendedAction = new Consumer() { + @Override + public void accept(ExtendedResult t1) { + System.out.println("Result: " + t1); + } + }; } \ No newline at end of file diff --git a/src/test/java/io/reactivex/schedulers/AbstractSchedulerConcurrencyTests.java b/src/test/java/io/reactivex/schedulers/AbstractSchedulerConcurrencyTests.java index b9c33554fa..3b96eb32dc 100644 --- a/src/test/java/io/reactivex/schedulers/AbstractSchedulerConcurrencyTests.java +++ b/src/test/java/io/reactivex/schedulers/AbstractSchedulerConcurrencyTests.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -17,13 +17,13 @@ import java.util.concurrent.*; import java.util.concurrent.atomic.*; -import java.util.function.*; import org.junit.Test; import org.reactivestreams.*; import io.reactivex.*; import io.reactivex.Scheduler.Worker; +import io.reactivex.functions.*; import io.reactivex.subscribers.AsyncObserver; /** @@ -37,6 +37,7 @@ public abstract class AbstractSchedulerConcurrencyTests extends AbstractSchedule /** * Bug report: https://github.com/ReactiveX/RxJava/issues/431 + * @throws InterruptedException if the test is interrupted */ @Test public final void testUnSubscribeForScheduler() throws InterruptedException { diff --git a/src/test/java/io/reactivex/schedulers/AbstractSchedulerTests.java b/src/test/java/io/reactivex/schedulers/AbstractSchedulerTests.java index 6b40c3fc32..1c765153cd 100644 --- a/src/test/java/io/reactivex/schedulers/AbstractSchedulerTests.java +++ b/src/test/java/io/reactivex/schedulers/AbstractSchedulerTests.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -19,7 +19,6 @@ import java.util.*; import java.util.concurrent.*; import java.util.concurrent.atomic.*; -import java.util.function.*; import org.junit.Test; import org.mockito.InOrder; @@ -27,10 +26,11 @@ import org.mockito.stubbing.Answer; import org.reactivestreams.*; +import io.reactivex.*; +import io.reactivex.functions.*; +import io.reactivex.internal.subscriptions.*; import io.reactivex.Observable; import io.reactivex.Observer; -import io.reactivex.Scheduler; -import io.reactivex.internal.subscriptions.*; /** * Base tests for all schedulers including Immediate/Current. @@ -385,7 +385,7 @@ public void run() { } }); - ConcurrentObserverValidator observer = new ConcurrentObserverValidator<>(); + ConcurrentObserverValidator observer = new ConcurrentObserverValidator(); // this should call onNext concurrently o.subscribe(observer); @@ -404,7 +404,7 @@ public final void testObserveOn() throws InterruptedException { Observable o = Observable.fromArray("one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"); - ConcurrentObserverValidator observer = new ConcurrentObserverValidator<>(); + ConcurrentObserverValidator observer = new ConcurrentObserverValidator(); o.observeOn(scheduler).subscribe(observer); @@ -439,7 +439,7 @@ public void subscribe(Subscriber observer) { } }); - ConcurrentObserverValidator observer = new ConcurrentObserverValidator<>(); + ConcurrentObserverValidator observer = new ConcurrentObserverValidator(); o.subscribe(observer); @@ -461,7 +461,7 @@ public void subscribe(Subscriber observer) { private static class ConcurrentObserverValidator extends Observer { final AtomicInteger concurrentCounter = new AtomicInteger(); - final AtomicReference error = new AtomicReference<>(); + final AtomicReference error = new AtomicReference(); final CountDownLatch completed = new CountDownLatch(1); @Override diff --git a/src/test/java/io/reactivex/schedulers/CachedThreadSchedulerTest.java b/src/test/java/io/reactivex/schedulers/CachedThreadSchedulerTest.java index b2d3091055..1db6d57cb3 100644 --- a/src/test/java/io/reactivex/schedulers/CachedThreadSchedulerTest.java +++ b/src/test/java/io/reactivex/schedulers/CachedThreadSchedulerTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -15,12 +15,12 @@ import static org.junit.Assert.assertTrue; -import java.util.function.*; - import org.junit.*; import io.reactivex.*; import io.reactivex.Scheduler.Worker; +import io.reactivex.functions.*; +import io.reactivex.schedulers.Schedulers; public class CachedThreadSchedulerTest extends AbstractSchedulerConcurrencyTests { @@ -66,7 +66,7 @@ public final void testHandledErrorIsNotDeliveredToThreadHandler() throws Interru SchedulerTests.testHandledErrorIsNotDeliveredToThreadHandler(getScheduler()); } - @Test(timeout = 30000) + @Test(timeout = 60000) public void testCancelledTaskRetention() throws InterruptedException { Worker w = Schedulers.io().createWorker(); try { diff --git a/src/test/java/io/reactivex/schedulers/ComputationSchedulerTests.java b/src/test/java/io/reactivex/schedulers/ComputationSchedulerTests.java index 7ed0644185..1a6f780163 100644 --- a/src/test/java/io/reactivex/schedulers/ComputationSchedulerTests.java +++ b/src/test/java/io/reactivex/schedulers/ComputationSchedulerTests.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -17,12 +17,13 @@ import java.util.HashMap; import java.util.concurrent.CountDownLatch; -import java.util.function.*; import org.junit.*; import io.reactivex.*; import io.reactivex.Scheduler.Worker; +import io.reactivex.functions.*; +import io.reactivex.schedulers.Schedulers; public class ComputationSchedulerTests extends AbstractSchedulerConcurrencyTests { @@ -37,7 +38,7 @@ public void testThreadSafetyWhenSchedulerIsHoppingBetweenThreads() { final int NUM = 1000000; final CountDownLatch latch = new CountDownLatch(1); - final HashMap map = new HashMap<>(); + final HashMap map = new HashMap(); final Scheduler.Worker inner = Schedulers.computation().createWorker(); @@ -147,7 +148,7 @@ public final void testHandledErrorIsNotDeliveredToThreadHandler() throws Interru SchedulerTests.testHandledErrorIsNotDeliveredToThreadHandler(getScheduler()); } - @Test(timeout = 30000) + @Test(timeout = 60000) public void testCancelledTaskRetention() throws InterruptedException { Worker w = Schedulers.computation().createWorker(); try { diff --git a/src/test/java/io/reactivex/schedulers/ExecutorSchedulerTest.java b/src/test/java/io/reactivex/schedulers/ExecutorSchedulerTest.java index ef53811add..10c087f873 100644 --- a/src/test/java/io/reactivex/schedulers/ExecutorSchedulerTest.java +++ b/src/test/java/io/reactivex/schedulers/ExecutorSchedulerTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -24,7 +24,9 @@ import io.reactivex.Scheduler; import io.reactivex.Scheduler.Worker; import io.reactivex.disposables.Disposable; -import io.reactivex.internal.schedulers.RxThreadFactory; +import io.reactivex.internal.functions.Functions; +import io.reactivex.internal.schedulers.*; +import io.reactivex.schedulers.Schedulers; public class ExecutorSchedulerTest extends AbstractSchedulerConcurrencyTests { @@ -62,7 +64,7 @@ public static void testCancelledRetention(Scheduler.Worker w, boolean periodic) System.out.printf("Starting: %.3f MB%n", initial / 1024.0 / 1024.0); - int n = 500 * 1000; + int n = 100 * 1000; if (periodic) { final CountDownLatch cdl = new CountDownLatch(n); final Runnable action = new Runnable() { @@ -85,7 +87,7 @@ public void run() { if (i % 50000 == 0) { System.out.println(" -> still scheduling: " + i); } - w.schedule(() -> { }, 1, TimeUnit.DAYS); + w.schedule(Functions.emptyRunnable(), 1, TimeUnit.DAYS); } } @@ -96,7 +98,13 @@ public void run() { w.dispose(); System.out.println("Wait before second GC"); - Thread.sleep(1000 + 2000); + System.out.println("JDK 6 purge is N log N because it removes and shifts one by one"); + int t = (int)(n * Math.log(n) / 100) + SchedulerPoolFactory.PURGE_PERIOD_SECONDS * 1000; + while (t > 0) { + System.out.printf(" >> Waiting for purge: %.2f s remaining%n", t / 1000d); + Thread.sleep(1000); + t -= 1000; + } System.out.println("Second GC"); System.gc(); @@ -112,7 +120,7 @@ public void run() { } } - @Test(timeout = 30000) + @Test(timeout = 60000) public void testCancelledTaskRetention() throws InterruptedException { ExecutorService exec = Executors.newSingleThreadExecutor(); Scheduler s = Schedulers.from(exec); @@ -137,7 +145,7 @@ public void testCancelledTaskRetention() throws InterruptedException { /** A simple executor which queues tasks and executes them one-by-one if executeOne() is called. */ static final class TestExecutor implements Executor { - final ConcurrentLinkedQueue queue = new ConcurrentLinkedQueue<>(); + final ConcurrentLinkedQueue queue = new ConcurrentLinkedQueue(); @Override public void execute(Runnable command) { queue.offer(command); @@ -219,7 +227,7 @@ public void run() { // }; // ExecutorWorker w = (ExecutorWorker)Schedulers.from(e).createWorker(); // -// w.schedule(() -> { }, 50, TimeUnit.MILLISECONDS); +// w.schedule(Functions.emptyRunnable(), 50, TimeUnit.MILLISECONDS); // // assertTrue(w.tasks.hasSubscriptions()); // @@ -238,7 +246,7 @@ public void run() { // }; // ExecutorWorker w = (ExecutorWorker)Schedulers.from(e).createWorker(); // -// Disposable s = w.schedule(() -> { }, 1, TimeUnit.DAYS); +// Disposable s = w.schedule(Functions.emptyRunnable(), 1, TimeUnit.DAYS); // // assertTrue(w.tasks.hasSubscriptions()); // diff --git a/src/test/java/io/reactivex/schedulers/NewThreadSchedulerTest.java b/src/test/java/io/reactivex/schedulers/NewThreadSchedulerTest.java index 3ec60e9742..ed379213c6 100644 --- a/src/test/java/io/reactivex/schedulers/NewThreadSchedulerTest.java +++ b/src/test/java/io/reactivex/schedulers/NewThreadSchedulerTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -16,6 +16,7 @@ import org.junit.*; import io.reactivex.Scheduler; +import io.reactivex.schedulers.Schedulers; public class NewThreadSchedulerTest extends AbstractSchedulerConcurrencyTests { @@ -42,7 +43,7 @@ public final void testHandledErrorIsNotDeliveredToThreadHandler() throws Interru // try { // final CountDownLatch run = new CountDownLatch(1); // final CountDownLatch done = new CountDownLatch(1); -// final AtomicReference exception = new AtomicReference<>(); +// final AtomicReference exception = new AtomicReference(); // final AtomicBoolean interruptFlag = new AtomicBoolean(); // // ScheduledRunnable sa = (ScheduledRunnable)worker.schedule(new Runnable() { diff --git a/src/test/java/io/reactivex/schedulers/SchedulerLifecycleTest.java b/src/test/java/io/reactivex/schedulers/SchedulerLifecycleTest.java index fbdfba5e81..ef4a5adc0d 100644 --- a/src/test/java/io/reactivex/schedulers/SchedulerLifecycleTest.java +++ b/src/test/java/io/reactivex/schedulers/SchedulerLifecycleTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -22,6 +22,7 @@ import io.reactivex.Scheduler.Worker; import io.reactivex.disposables.CompositeDisposable; +import io.reactivex.schedulers.Schedulers; public class SchedulerLifecycleTest { @Test @@ -31,7 +32,7 @@ public void testShutdown() throws InterruptedException { System.out.println("testShutdown >> Giving time threads to spin-up"); Thread.sleep(500); - Set rxThreads = new HashSet<>(); + Set rxThreads = new HashSet(); for (Thread t : Thread.getAllStackTraces().keySet()) { if (t.getName().startsWith("Rx")) { rxThreads.add(t); @@ -108,7 +109,7 @@ public void testStartIdempotence() throws InterruptedException { System.out.println("testStartIdempotence >> giving some time"); Thread.sleep(500); - Set rxThreads = new HashSet<>(); + Set rxThreads = new HashSet(); for (Thread t : Thread.getAllStackTraces().keySet()) { if (t.getName().startsWith("Rx")) { rxThreads.add(t); @@ -120,7 +121,7 @@ public void testStartIdempotence() throws InterruptedException { System.out.println("testStartIdempotence >> giving some time again"); Thread.sleep(500); - Set rxThreads2 = new HashSet<>(); + Set rxThreads2 = new HashSet(); for (Thread t : Thread.getAllStackTraces().keySet()) { if (t.getName().startsWith("Rx")) { rxThreads2.add(t); diff --git a/src/test/java/io/reactivex/schedulers/SchedulerTests.java b/src/test/java/io/reactivex/schedulers/SchedulerTests.java index 6bbfd468f7..972fefb0ad 100644 --- a/src/test/java/io/reactivex/schedulers/SchedulerTests.java +++ b/src/test/java/io/reactivex/schedulers/SchedulerTests.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -69,7 +69,7 @@ static void testHandledErrorIsNotDeliveredToThreadHandler(Scheduler scheduler) t Thread.UncaughtExceptionHandler originalHandler = Thread.getDefaultUncaughtExceptionHandler(); try { CapturingUncaughtExceptionHandler handler = new CapturingUncaughtExceptionHandler(); - CapturingObserver observer = new CapturingObserver<>(); + CapturingObserver observer = new CapturingObserver(); Thread.setDefaultUncaughtExceptionHandler(handler); IllegalStateException error = new IllegalStateException("Should be delivered to handler"); Observable.error(error) diff --git a/src/test/java/io/reactivex/schedulers/TestSchedulerTest.java b/src/test/java/io/reactivex/schedulers/TestSchedulerTest.java index 0489a55ffb..c33a847f92 100644 --- a/src/test/java/io/reactivex/schedulers/TestSchedulerTest.java +++ b/src/test/java/io/reactivex/schedulers/TestSchedulerTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -19,7 +19,6 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.Function; import org.junit.Test; import org.mockito.*; @@ -27,7 +26,9 @@ import io.reactivex.*; import io.reactivex.disposables.Disposable; +import io.reactivex.functions.Function; import io.reactivex.internal.subscriptions.BooleanSubscription; +import io.reactivex.schedulers.TestScheduler; public class TestSchedulerTest { @@ -183,7 +184,7 @@ public final void testNestedSchedule() { poller = Observable.create(new Publisher() { @Override public void subscribe(final Subscriber aSubscriber) { - BooleanSubscription bs = new BooleanSubscription(); + final BooleanSubscription bs = new BooleanSubscription(); aSubscriber.onSubscribe(bs); inner.schedule(new Runnable() { @Override diff --git a/src/test/java/io/reactivex/schedulers/TrampolineSchedulerTest.java b/src/test/java/io/reactivex/schedulers/TrampolineSchedulerTest.java index 8f8d190344..8d04ec12ee 100644 --- a/src/test/java/io/reactivex/schedulers/TrampolineSchedulerTest.java +++ b/src/test/java/io/reactivex/schedulers/TrampolineSchedulerTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -17,16 +17,18 @@ import java.util.*; import java.util.concurrent.TimeUnit; -import java.util.function.*; import org.junit.Test; -import org.reactivestreams.Subscriber; +import org.reactivestreams.*; import io.reactivex.*; -import io.reactivex.Observable; import io.reactivex.Scheduler.Worker; import io.reactivex.disposables.*; +import io.reactivex.functions.*; +import io.reactivex.internal.functions.Functions; +import io.reactivex.schedulers.Schedulers; import io.reactivex.subscribers.TestSubscriber; +import io.reactivex.Observable; public class TrampolineSchedulerTest extends AbstractSchedulerTests { @@ -62,7 +64,7 @@ public void accept(String t) { @Test public void testNestedTrampolineWithUnsubscribe() { - final ArrayList workDone = new ArrayList<>(); + final ArrayList workDone = new ArrayList(); final CompositeDisposable workers = new CompositeDisposable(); Worker worker = Schedulers.trampoline().createWorker(); try { @@ -106,12 +108,23 @@ public void run() { public void testTrampolineWorkerHandlesConcurrentScheduling() { final Worker trampolineWorker = Schedulers.trampoline().createWorker(); final Subscriber observer = TestHelper.mockSubscriber(); - final TestSubscriber ts = new TestSubscriber<>(observer); + final TestSubscriber ts = new TestSubscriber(observer); // Spam the trampoline with actions. Observable.range(0, 50) - .flatMap(count -> Observable.interval(1, TimeUnit.MICROSECONDS).map( - count1 -> trampolineWorker.schedule(() -> {})).take(100)) + .flatMap(new Function>() { + @Override + public Publisher apply(Integer count) { + return Observable + .interval(1, TimeUnit.MICROSECONDS) + .map(new Function() { + @Override + public Disposable apply(Long ount1) { + return trampolineWorker.schedule(Functions.emptyRunnable()); + } + }).take(100); + } + }) .subscribeOn(Schedulers.computation()) .subscribe(ts); ts.awaitTerminalEvent(); diff --git a/src/test/java/io/reactivex/subjects/AsyncSubjectTest.java b/src/test/java/io/reactivex/subjects/AsyncSubjectTest.java index a1bb4db56b..e0258061ed 100644 --- a/src/test/java/io/reactivex/subjects/AsyncSubjectTest.java +++ b/src/test/java/io/reactivex/subjects/AsyncSubjectTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -19,7 +19,6 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; -import java.util.function.Consumer; import org.junit.*; import org.mockito.*; @@ -27,6 +26,8 @@ import io.reactivex.TestHelper; import io.reactivex.exceptions.TestException; +import io.reactivex.functions.Consumer; +import io.reactivex.subjects.AsyncSubject; import io.reactivex.subscribers.TestSubscriber; public class AsyncSubjectTest { @@ -145,7 +146,7 @@ public void testUnsubscribeBeforeCompleted() { AsyncSubject subject = AsyncSubject.create(); Subscriber observer = TestHelper.mockSubscriber(); - TestSubscriber ts = new TestSubscriber<>(observer); + TestSubscriber ts = new TestSubscriber(observer); subject.subscribe(ts); subject.onNext("one"); @@ -194,7 +195,7 @@ public void testSubscribeCompletionRaceCondition() { */ for (int i = 0; i < 50; i++) { final AsyncSubject subject = AsyncSubject.create(); - final AtomicReference value1 = new AtomicReference<>(); + final AtomicReference value1 = new AtomicReference(); subject.subscribe(new Consumer() { @@ -252,7 +253,7 @@ public void run() { private static class SubjectSubscriberThread extends Thread { private final AsyncSubject subject; - private final AtomicReference value = new AtomicReference<>(); + private final AtomicReference value = new AtomicReference(); public SubjectSubscriberThread(AsyncSubject subject) { this.subject = subject; @@ -276,7 +277,7 @@ public void run() { // AsyncSubject ps = AsyncSubject.create(); // // ps.subscribe(); -// TestSubscriber ts = new TestSubscriber<>(); +// TestSubscriber ts = new TestSubscriber(); // ps.subscribe(ts); // // try { @@ -300,7 +301,7 @@ public void run() { // // ps.subscribe(); // ps.subscribe(); -// TestSubscriber ts = new TestSubscriber<>(); +// TestSubscriber ts = new TestSubscriber(); // ps.subscribe(ts); // ps.subscribe(); // ps.subscribe(); diff --git a/src/test/java/io/reactivex/subjects/BehaviorSubjectTest.java b/src/test/java/io/reactivex/subjects/BehaviorSubjectTest.java index f7d66d6b0e..3f77f941f9 100644 --- a/src/test/java/io/reactivex/subjects/BehaviorSubjectTest.java +++ b/src/test/java/io/reactivex/subjects/BehaviorSubjectTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -19,7 +19,6 @@ import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicReference; -import java.util.function.Function; import org.junit.*; import org.mockito.*; @@ -27,7 +26,9 @@ import io.reactivex.*; import io.reactivex.exceptions.TestException; +import io.reactivex.functions.Function; import io.reactivex.schedulers.Schedulers; +import io.reactivex.subjects.BehaviorSubject; import io.reactivex.subscribers.TestSubscriber; public class BehaviorSubjectTest { @@ -127,7 +128,7 @@ public void testCompletedStopsEmittingData() { Subscriber observerB = TestHelper.mockSubscriber(); Subscriber observerC = TestHelper.mockSubscriber(); - TestSubscriber ts = new TestSubscriber<>(observerA); + TestSubscriber ts = new TestSubscriber(observerA); channel.subscribe(ts); channel.subscribe(observerB); @@ -358,7 +359,7 @@ public void testTakeOneSubscriber() { // BehaviorSubject ps = BehaviorSubject.create(); // // ps.subscribe(); -// TestSubscriber ts = new TestSubscriber<>(); +// TestSubscriber ts = new TestSubscriber(); // ps.subscribe(ts); // // try { @@ -423,7 +424,7 @@ public void run() { } }); - final AtomicReference o = new AtomicReference<>(); + final AtomicReference o = new AtomicReference(); rs.subscribeOn(s).observeOn(Schedulers.io()) .subscribe(new Observer() { diff --git a/src/test/java/io/reactivex/subjects/PublishSubjectTest.java b/src/test/java/io/reactivex/subjects/PublishSubjectTest.java index 3d9ee4464e..f7e9343d5b 100644 --- a/src/test/java/io/reactivex/subjects/PublishSubjectTest.java +++ b/src/test/java/io/reactivex/subjects/PublishSubjectTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -19,14 +19,15 @@ import java.util.ArrayList; import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.*; import org.junit.Test; import org.mockito.*; -import org.reactivestreams.*; +import org.reactivestreams.Subscriber; import io.reactivex.*; import io.reactivex.exceptions.TestException; +import io.reactivex.functions.*; +import io.reactivex.subjects.PublishSubject; import io.reactivex.subscribers.TestSubscriber; public class PublishSubjectTest { @@ -61,7 +62,7 @@ public void testCompletedStopsEmittingData() { Subscriber observerB = TestHelper.mockSubscriber(); Subscriber observerC = TestHelper.mockSubscriber(); - TestSubscriber ts = new TestSubscriber<>(observerA); + TestSubscriber ts = new TestSubscriber(observerA); channel.subscribe(ts); channel.subscribe(observerB); @@ -170,7 +171,7 @@ public void testUnsubscribeFirstSubscriber() { PublishSubject subject = PublishSubject.create(); Subscriber observer = TestHelper.mockSubscriber(); - TestSubscriber ts = new TestSubscriber<>(observer); + TestSubscriber ts = new TestSubscriber(observer); subject.subscribe(ts); subject.onNext("one"); @@ -205,7 +206,7 @@ public void testNestedSubscribe() { final AtomicInteger countChildren = new AtomicInteger(); final AtomicInteger countTotal = new AtomicInteger(); - final ArrayList list = new ArrayList<>(); + final ArrayList list = new ArrayList(); s.flatMap(new Function>() { @@ -256,7 +257,7 @@ public void testReSubscribe() { final PublishSubject ps = PublishSubject.create(); Subscriber o1 = TestHelper.mockSubscriber(); - TestSubscriber ts = new TestSubscriber<>(o1); + TestSubscriber ts = new TestSubscriber(o1); ps.subscribe(ts); // emit @@ -274,7 +275,7 @@ public void testReSubscribe() { ps.onNext(2); Subscriber o2 = TestHelper.mockSubscriber(); - TestSubscriber ts2 = new TestSubscriber<>(o2); + TestSubscriber ts2 = new TestSubscriber(o2); ps.subscribe(ts2); // emit @@ -338,7 +339,7 @@ public void onComplete() { // PublishSubject ps = PublishSubject.create(); // // ps.subscribe(); -// TestSubscriber ts = new TestSubscriber<>(); +// TestSubscriber ts = new TestSubscriber(); // ps.subscribe(ts); // // try { diff --git a/src/test/java/io/reactivex/subjects/ReplaySubjectBoundedConcurrencyTest.java b/src/test/java/io/reactivex/subjects/ReplaySubjectBoundedConcurrencyTest.java index 9427771162..aeb728ec75 100644 --- a/src/test/java/io/reactivex/subjects/ReplaySubjectBoundedConcurrencyTest.java +++ b/src/test/java/io/reactivex/subjects/ReplaySubjectBoundedConcurrencyTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -18,16 +18,17 @@ import java.util.*; import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicReference; -import java.util.function.Consumer; import org.junit.*; import org.reactivestreams.*; -import io.reactivex.Observable; -import io.reactivex.Observer; -import io.reactivex.Scheduler; +import io.reactivex.*; +import io.reactivex.functions.Consumer; import io.reactivex.schedulers.Schedulers; +import io.reactivex.subjects.ReplaySubject; import io.reactivex.subscribers.TestSubscriber; +import io.reactivex.Observable; +import io.reactivex.Observer; public class ReplaySubjectBoundedConcurrencyTest { @@ -197,7 +198,7 @@ public void run() { } // assert all threads got the same results - List sums = new ArrayList<>(); + List sums = new ArrayList(); for (List values : listOfListsOfValues) { long v = 0; for (long l : values) { @@ -230,7 +231,7 @@ public void run() { public void testSubscribeCompletionRaceCondition() { for (int i = 0; i < 50; i++) { final ReplaySubject subject = ReplaySubject.createUnbounded(); - final AtomicReference value1 = new AtomicReference<>(); + final AtomicReference value1 = new AtomicReference(); subject.subscribe(new Consumer() { @@ -292,7 +293,7 @@ public void run() { public void testRaceForTerminalState() { final List expected = Arrays.asList(1); for (int i = 0; i < 100000; i++) { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); Observable.just(1).subscribeOn(Schedulers.computation()).cache().subscribe(ts); ts.awaitTerminalEvent(); ts.assertValueSequence(expected); @@ -303,7 +304,7 @@ public void testRaceForTerminalState() { private static class SubjectObserverThread extends Thread { private final ReplaySubject subject; - private final AtomicReference value = new AtomicReference<>(); + private final AtomicReference value = new AtomicReference(); public SubjectObserverThread(ReplaySubject subject) { this.subject = subject; @@ -325,7 +326,7 @@ public void testReplaySubjectEmissionSubscriptionRace() throws Exception { Scheduler s = Schedulers.io(); Scheduler.Worker worker = Schedulers.io().createWorker(); try { - for (int i = 0; i < 50_000; i++) { + for (int i = 0; i < 50000; i++) { if (i % 1000 == 0) { System.out.println(i); } @@ -349,7 +350,7 @@ public void run() { } }); - final AtomicReference o = new AtomicReference<>(); + final AtomicReference o = new AtomicReference(); rs // .doOnSubscribe(v -> System.out.println("!! " + j)) diff --git a/src/test/java/io/reactivex/subjects/ReplaySubjectConcurrencyTest.java b/src/test/java/io/reactivex/subjects/ReplaySubjectConcurrencyTest.java index 11ff488b03..316f7dff1a 100644 --- a/src/test/java/io/reactivex/subjects/ReplaySubjectConcurrencyTest.java +++ b/src/test/java/io/reactivex/subjects/ReplaySubjectConcurrencyTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -18,16 +18,17 @@ import java.util.*; import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicReference; -import java.util.function.Consumer; import org.junit.*; import org.reactivestreams.*; -import io.reactivex.Observable; -import io.reactivex.Observer; -import io.reactivex.Scheduler; +import io.reactivex.*; +import io.reactivex.functions.Consumer; import io.reactivex.schedulers.Schedulers; +import io.reactivex.subjects.ReplaySubject; import io.reactivex.subscribers.TestSubscriber; +import io.reactivex.Observable; +import io.reactivex.Observer; public class ReplaySubjectConcurrencyTest { @@ -197,7 +198,7 @@ public void run() { } // assert all threads got the same results - List sums = new ArrayList<>(); + List sums = new ArrayList(); for (List values : listOfListsOfValues) { long v = 0; for (long l : values) { @@ -230,7 +231,7 @@ public void run() { public void testSubscribeCompletionRaceCondition() { for (int i = 0; i < 50; i++) { final ReplaySubject subject = ReplaySubject.create(); - final AtomicReference value1 = new AtomicReference<>(); + final AtomicReference value1 = new AtomicReference(); subject.subscribe(new Consumer() { @@ -292,7 +293,7 @@ public void run() { public void testRaceForTerminalState() { final List expected = Arrays.asList(1); for (int i = 0; i < 100000; i++) { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); Observable.just(1).subscribeOn(Schedulers.computation()).cache().subscribe(ts); ts.awaitTerminalEvent(); ts.assertValueSequence(expected); @@ -303,7 +304,7 @@ public void testRaceForTerminalState() { private static class SubjectObserverThread extends Thread { private final ReplaySubject subject; - private final AtomicReference value = new AtomicReference<>(); + private final AtomicReference value = new AtomicReference(); public SubjectObserverThread(ReplaySubject subject) { this.subject = subject; @@ -346,7 +347,7 @@ public void run() { } }); - final AtomicReference o = new AtomicReference<>(); + final AtomicReference o = new AtomicReference(); rs.subscribeOn(s).observeOn(Schedulers.io()) .subscribe(new Observer() { diff --git a/src/test/java/io/reactivex/subjects/ReplaySubjectTest.java b/src/test/java/io/reactivex/subjects/ReplaySubjectTest.java index c34ee59266..c57ac99509 100644 --- a/src/test/java/io/reactivex/subjects/ReplaySubjectTest.java +++ b/src/test/java/io/reactivex/subjects/ReplaySubjectTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -20,7 +20,6 @@ import java.util.Arrays; import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicReference; -import java.util.function.Function; import org.junit.Test; import org.mockito.*; @@ -29,7 +28,9 @@ import io.reactivex.*; import io.reactivex.disposables.Disposable; import io.reactivex.exceptions.TestException; +import io.reactivex.functions.Function; import io.reactivex.schedulers.*; +import io.reactivex.subjects.ReplaySubject; import io.reactivex.subscribers.TestSubscriber; public class ReplaySubjectTest { @@ -67,7 +68,7 @@ public void testCompletedStopsEmittingData() { Subscriber observerB = TestHelper.mockSubscriber(); Subscriber observerC = TestHelper.mockSubscriber(); Subscriber observerD = TestHelper.mockSubscriber(); - TestSubscriber ts = new TestSubscriber<>(observerA); + TestSubscriber ts = new TestSubscriber(observerA); channel.subscribe(ts); channel.subscribe(observerB); @@ -218,7 +219,7 @@ public void testUnsubscribeFirstSubscriber() { ReplaySubject subject = ReplaySubject.create(); Subscriber observer = TestHelper.mockSubscriber(); - TestSubscriber ts = new TestSubscriber<>(observer); + TestSubscriber ts = new TestSubscriber(observer); subject.subscribe(ts); subject.onNext("one"); @@ -249,7 +250,7 @@ private void assertObservedUntilTwo(Subscriber observer) { @Test(timeout = 2000) public void testNewSubscriberDoesntBlockExisting() throws InterruptedException { - final AtomicReference lastValueForSubscriber1 = new AtomicReference<>(); + final AtomicReference lastValueForSubscriber1 = new AtomicReference(); Subscriber observer1 = new Observer() { @Override @@ -270,7 +271,7 @@ public void onNext(String v) { }; - final AtomicReference lastValueForSubscriber2 = new AtomicReference<>(); + final AtomicReference lastValueForSubscriber2 = new AtomicReference(); final CountDownLatch oneReceived = new CountDownLatch(1); final CountDownLatch makeSlow = new CountDownLatch(1); final CountDownLatch completed = new CountDownLatch(1); @@ -535,7 +536,7 @@ public void testReplayTimestampedDirectly() { // ReplaySubject ps = ReplaySubject.create(); // // ps.subscribe(); -// TestSubscriber ts = new TestSubscriber<>(); +// TestSubscriber ts = new TestSubscriber(); // ps.subscribe(ts); // // try { @@ -820,4 +821,91 @@ public void testGetValuesUnbounded() { assertArrayEquals(expected, rs.getValues()); } + + @Test + public void testBackpressureHonored() { + ReplaySubject rs = ReplaySubject.create(); + rs.onNext(1); + rs.onNext(2); + rs.onNext(3); + rs.onComplete(); + + TestSubscriber ts = new TestSubscriber((Long)null); + + rs.subscribe(ts); + + ts.request(1); + ts.assertValue(1); + ts.assertNotComplete(); + ts.assertNoErrors(); + + + ts.request(1); + ts.assertValues(1, 2); + ts.assertNotComplete(); + ts.assertNoErrors(); + + ts.request(1); + ts.assertValues(1, 2, 3); + ts.assertComplete(); + ts.assertNoErrors(); + } + + @Test + public void testBackpressureHonoredSizeBound() { + ReplaySubject rs = ReplaySubject.createWithSize(100); + rs.onNext(1); + rs.onNext(2); + rs.onNext(3); + rs.onComplete(); + + TestSubscriber ts = new TestSubscriber((Long)null); + + rs.subscribe(ts); + + ts.request(1); + ts.assertValue(1); + ts.assertNotComplete(); + ts.assertNoErrors(); + + + ts.request(1); + ts.assertValues(1, 2); + ts.assertNotComplete(); + ts.assertNoErrors(); + + ts.request(1); + ts.assertValues(1, 2, 3); + ts.assertComplete(); + ts.assertNoErrors(); + } + + @Test + public void testBackpressureHonoredTimeBound() { + ReplaySubject rs = ReplaySubject.createWithTime(1, TimeUnit.DAYS); + rs.onNext(1); + rs.onNext(2); + rs.onNext(3); + rs.onComplete(); + + TestSubscriber ts = new TestSubscriber((Long)null); + + rs.subscribe(ts); + + ts.request(1); + ts.assertValue(1); + ts.assertNotComplete(); + ts.assertNoErrors(); + + + ts.request(1); + ts.assertValues(1, 2); + ts.assertNotComplete(); + ts.assertNoErrors(); + + ts.request(1); + ts.assertValues(1, 2, 3); + ts.assertComplete(); + ts.assertNoErrors(); + } } \ No newline at end of file diff --git a/src/test/java/io/reactivex/subjects/SerializedSubjectTest.java b/src/test/java/io/reactivex/subjects/SerializedSubjectTest.java index 1b428c03a8..9e45fadc8a 100644 --- a/src/test/java/io/reactivex/subjects/SerializedSubjectTest.java +++ b/src/test/java/io/reactivex/subjects/SerializedSubjectTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -24,8 +24,8 @@ public class SerializedSubjectTest { @Test public void testBasic() { - SerializedSubject subject = new SerializedSubject<>(PublishSubject. create()); - TestSubscriber ts = new TestSubscriber<>(); + SerializedSubject subject = new SerializedSubject(PublishSubject. create()); + TestSubscriber ts = new TestSubscriber(); subject.subscribe(ts); subject.onNext("hello"); subject.onComplete(); diff --git a/src/test/java/io/reactivex/subjects/nbp/NbpAsyncSubjectTest.java b/src/test/java/io/reactivex/subjects/nbp/NbpAsyncSubjectTest.java index d3b60683b6..c39c56cc3e 100644 --- a/src/test/java/io/reactivex/subjects/nbp/NbpAsyncSubjectTest.java +++ b/src/test/java/io/reactivex/subjects/nbp/NbpAsyncSubjectTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -19,14 +19,15 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; -import java.util.function.Consumer; import org.junit.*; import org.mockito.*; -import io.reactivex.NbpObservable.NbpSubscriber; import io.reactivex.TestHelper; +import io.reactivex.NbpObservable.NbpSubscriber; import io.reactivex.exceptions.TestException; +import io.reactivex.functions.Consumer; +import io.reactivex.subjects.nbp.NbpAsyncSubject; import io.reactivex.subscribers.nbp.NbpTestSubscriber; public class NbpAsyncSubjectTest { @@ -145,7 +146,7 @@ public void testUnsubscribeBeforeCompleted() { NbpAsyncSubject subject = NbpAsyncSubject.create(); NbpSubscriber observer = TestHelper.mockNbpSubscriber(); - NbpTestSubscriber ts = new NbpTestSubscriber<>(observer); + NbpTestSubscriber ts = new NbpTestSubscriber(observer); subject.subscribe(ts); subject.onNext("one"); @@ -194,7 +195,7 @@ public void testSubscribeCompletionRaceCondition() { */ for (int i = 0; i < 50; i++) { final NbpAsyncSubject subject = NbpAsyncSubject.create(); - final AtomicReference value1 = new AtomicReference<>(); + final AtomicReference value1 = new AtomicReference(); subject.subscribe(new Consumer() { @@ -252,7 +253,7 @@ public void run() { private static class SubjectSubscriberThread extends Thread { private final NbpAsyncSubject subject; - private final AtomicReference value = new AtomicReference<>(); + private final AtomicReference value = new AtomicReference(); public SubjectSubscriberThread(NbpAsyncSubject subject) { this.subject = subject; @@ -276,7 +277,7 @@ public void run() { // NbpAsyncSubject ps = NbpAsyncSubject.create(); // // ps.subscribe(); -// TestSubscriber ts = new TestSubscriber<>(); +// TestSubscriber ts = new TestSubscriber(); // ps.subscribe(ts); // // try { @@ -300,7 +301,7 @@ public void run() { // // ps.subscribe(); // ps.subscribe(); -// TestSubscriber ts = new TestSubscriber<>(); +// TestSubscriber ts = new TestSubscriber(); // ps.subscribe(ts); // ps.subscribe(); // ps.subscribe(); diff --git a/src/test/java/io/reactivex/subjects/nbp/NbpBehaviorSubjectTest.java b/src/test/java/io/reactivex/subjects/nbp/NbpBehaviorSubjectTest.java index f559d252ad..5aa64e0b85 100644 --- a/src/test/java/io/reactivex/subjects/nbp/NbpBehaviorSubjectTest.java +++ b/src/test/java/io/reactivex/subjects/nbp/NbpBehaviorSubjectTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -19,7 +19,6 @@ import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicReference; -import java.util.function.Function; import org.junit.*; import org.mockito.*; @@ -27,7 +26,9 @@ import io.reactivex.*; import io.reactivex.NbpObservable.NbpSubscriber; import io.reactivex.exceptions.TestException; +import io.reactivex.functions.Function; import io.reactivex.schedulers.Schedulers; +import io.reactivex.subjects.nbp.NbpBehaviorSubject; import io.reactivex.subscribers.nbp.NbpTestSubscriber; public class NbpBehaviorSubjectTest { @@ -127,7 +128,7 @@ public void testCompletedStopsEmittingData() { NbpSubscriber observerB = TestHelper.mockNbpSubscriber(); NbpSubscriber observerC = TestHelper.mockNbpSubscriber(); - NbpTestSubscriber ts = new NbpTestSubscriber<>(observerA); + NbpTestSubscriber ts = new NbpTestSubscriber(observerA); channel.subscribe(ts); channel.subscribe(observerB); @@ -358,7 +359,7 @@ public void testTakeOneSubscriber() { // NbpBehaviorSubject ps = NbpBehaviorSubject.create(); // // ps.subscribe(); -// TestNbpSubscriber ts = new TestNbpSubscriber<>(); +// TestNbpSubscriber ts = new TestNbpSubscriber(); // ps.subscribe(ts); // // try { @@ -423,7 +424,7 @@ public void run() { } }); - final AtomicReference o = new AtomicReference<>(); + final AtomicReference o = new AtomicReference(); rs.subscribeOn(s).observeOn(Schedulers.io()) .subscribe(new NbpObserver() { diff --git a/src/test/java/io/reactivex/subjects/nbp/NbpPublishSubjectTest.java b/src/test/java/io/reactivex/subjects/nbp/NbpPublishSubjectTest.java index 5bb8a7d90d..69e0d4b2e8 100644 --- a/src/test/java/io/reactivex/subjects/nbp/NbpPublishSubjectTest.java +++ b/src/test/java/io/reactivex/subjects/nbp/NbpPublishSubjectTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -19,7 +19,6 @@ import java.util.ArrayList; import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.*; import org.junit.Test; import org.mockito.*; @@ -27,7 +26,9 @@ import io.reactivex.*; import io.reactivex.NbpObservable.NbpSubscriber; import io.reactivex.exceptions.TestException; +import io.reactivex.functions.*; import io.reactivex.subjects.PublishSubject; +import io.reactivex.subjects.nbp.NbpPublishSubject; import io.reactivex.subscribers.nbp.NbpTestSubscriber; public class NbpPublishSubjectTest { @@ -62,7 +63,7 @@ public void testCompletedStopsEmittingData() { NbpSubscriber observerB = TestHelper.mockNbpSubscriber(); NbpSubscriber observerC = TestHelper.mockNbpSubscriber(); - NbpTestSubscriber ts = new NbpTestSubscriber<>(observerA); + NbpTestSubscriber ts = new NbpTestSubscriber(observerA); channel.subscribe(ts); channel.subscribe(observerB); @@ -171,7 +172,7 @@ public void testUnsubscribeFirstSubscriber() { NbpPublishSubject subject = NbpPublishSubject.create(); NbpSubscriber observer = TestHelper.mockNbpSubscriber(); - NbpTestSubscriber ts = new NbpTestSubscriber<>(observer); + NbpTestSubscriber ts = new NbpTestSubscriber(observer); subject.subscribe(ts); subject.onNext("one"); @@ -206,7 +207,7 @@ public void testNestedSubscribe() { final AtomicInteger countChildren = new AtomicInteger(); final AtomicInteger countTotal = new AtomicInteger(); - final ArrayList list = new ArrayList<>(); + final ArrayList list = new ArrayList(); s.flatMap(new Function>() { @@ -257,7 +258,7 @@ public void testReSubscribe() { final NbpPublishSubject ps = NbpPublishSubject.create(); NbpSubscriber o1 = TestHelper.mockNbpSubscriber(); - NbpTestSubscriber ts = new NbpTestSubscriber<>(o1); + NbpTestSubscriber ts = new NbpTestSubscriber(o1); ps.subscribe(ts); // emit @@ -275,7 +276,7 @@ public void testReSubscribe() { ps.onNext(2); NbpSubscriber o2 = TestHelper.mockNbpSubscriber(); - NbpTestSubscriber ts2 = new NbpTestSubscriber<>(o2); + NbpTestSubscriber ts2 = new NbpTestSubscriber(o2); ps.subscribe(ts2); // emit @@ -339,7 +340,7 @@ public void onComplete() { // PublishSubject ps = PublishSubject.create(); // // ps.subscribe(); -// TestSubscriber ts = new TestSubscriber<>(); +// TestSubscriber ts = new TestSubscriber(); // ps.subscribe(ts); // // try { diff --git a/src/test/java/io/reactivex/subjects/nbp/NbpReplaySubjectBoundedConcurrencyTest.java b/src/test/java/io/reactivex/subjects/nbp/NbpReplaySubjectBoundedConcurrencyTest.java index 370c16f73f..287c19851f 100644 --- a/src/test/java/io/reactivex/subjects/nbp/NbpReplaySubjectBoundedConcurrencyTest.java +++ b/src/test/java/io/reactivex/subjects/nbp/NbpReplaySubjectBoundedConcurrencyTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -18,16 +18,16 @@ import java.util.*; import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicReference; -import java.util.function.Consumer; import org.junit.*; import io.reactivex.*; import io.reactivex.NbpObservable.*; -import io.reactivex.Observable; +import io.reactivex.functions.Consumer; import io.reactivex.internal.disposables.EmptyDisposable; import io.reactivex.schedulers.Schedulers; -import io.reactivex.subscribers.TestSubscriber; +import io.reactivex.subjects.nbp.NbpReplaySubject; +import io.reactivex.subscribers.nbp.NbpTestSubscriber; public class NbpReplaySubjectBoundedConcurrencyTest { @@ -199,7 +199,7 @@ public void run() { } // assert all threads got the same results - List sums = new ArrayList<>(); + List sums = new ArrayList(); for (List values : listOfListsOfValues) { long v = 0; for (long l : values) { @@ -232,7 +232,7 @@ public void run() { public void testSubscribeCompletionRaceCondition() { for (int i = 0; i < 50; i++) { final NbpReplaySubject subject = NbpReplaySubject.createUnbounded(); - final AtomicReference value1 = new AtomicReference<>(); + final AtomicReference value1 = new AtomicReference(); subject.subscribe(new Consumer() { @@ -294,8 +294,8 @@ public void run() { public void testRaceForTerminalState() { final List expected = Arrays.asList(1); for (int i = 0; i < 100000; i++) { - TestSubscriber ts = new TestSubscriber<>(); - Observable.just(1).subscribeOn(Schedulers.computation()).cache().subscribe(ts); + NbpTestSubscriber ts = new NbpTestSubscriber(); + NbpObservable.just(1).subscribeOn(Schedulers.computation()).cache().subscribe(ts); ts.awaitTerminalEvent(); ts.assertValueSequence(expected); ts.assertTerminated(); @@ -305,7 +305,7 @@ public void testRaceForTerminalState() { private static class SubjectObserverThread extends Thread { private final NbpReplaySubject subject; - private final AtomicReference value = new AtomicReference<>(); + private final AtomicReference value = new AtomicReference(); public SubjectObserverThread(NbpReplaySubject subject) { this.subject = subject; @@ -327,7 +327,7 @@ public void testReplaySubjectEmissionSubscriptionRace() throws Exception { Scheduler s = Schedulers.io(); Scheduler.Worker worker = Schedulers.io().createWorker(); try { - for (int i = 0; i < 50_000; i++) { + for (int i = 0; i < 50000; i++) { if (i % 1000 == 0) { System.out.println(i); } @@ -351,7 +351,7 @@ public void run() { } }); - final AtomicReference o = new AtomicReference<>(); + final AtomicReference o = new AtomicReference(); rs // .doOnSubscribe(v -> System.out.println("!! " + j)) diff --git a/src/test/java/io/reactivex/subjects/nbp/NbpReplaySubjectConcurrencyTest.java b/src/test/java/io/reactivex/subjects/nbp/NbpReplaySubjectConcurrencyTest.java index b9e4acbd41..150e4a9371 100644 --- a/src/test/java/io/reactivex/subjects/nbp/NbpReplaySubjectConcurrencyTest.java +++ b/src/test/java/io/reactivex/subjects/nbp/NbpReplaySubjectConcurrencyTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -18,16 +18,16 @@ import java.util.*; import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicReference; -import java.util.function.Consumer; import org.junit.*; import io.reactivex.*; import io.reactivex.NbpObservable.*; -import io.reactivex.Observable; +import io.reactivex.functions.Consumer; import io.reactivex.internal.disposables.EmptyDisposable; import io.reactivex.schedulers.Schedulers; -import io.reactivex.subscribers.TestSubscriber; +import io.reactivex.subjects.nbp.NbpReplaySubject; +import io.reactivex.subscribers.nbp.NbpTestSubscriber; public class NbpReplaySubjectConcurrencyTest { @@ -199,7 +199,7 @@ public void run() { } // assert all threads got the same results - List sums = new ArrayList<>(); + List sums = new ArrayList(); for (List values : listOfListsOfValues) { long v = 0; for (long l : values) { @@ -232,7 +232,7 @@ public void run() { public void testSubscribeCompletionRaceCondition() { for (int i = 0; i < 50; i++) { final NbpReplaySubject subject = NbpReplaySubject.create(); - final AtomicReference value1 = new AtomicReference<>(); + final AtomicReference value1 = new AtomicReference(); subject.subscribe(new Consumer() { @@ -294,8 +294,8 @@ public void run() { public void testRaceForTerminalState() { final List expected = Arrays.asList(1); for (int i = 0; i < 100000; i++) { - TestSubscriber ts = new TestSubscriber<>(); - Observable.just(1).subscribeOn(Schedulers.computation()).cache().subscribe(ts); + NbpTestSubscriber ts = new NbpTestSubscriber(); + NbpObservable.just(1).subscribeOn(Schedulers.computation()).cache().subscribe(ts); ts.awaitTerminalEvent(); ts.assertValueSequence(expected); ts.assertTerminated(); @@ -305,7 +305,7 @@ public void testRaceForTerminalState() { private static class SubjectObserverThread extends Thread { private final NbpReplaySubject subject; - private final AtomicReference value = new AtomicReference<>(); + private final AtomicReference value = new AtomicReference(); public SubjectObserverThread(NbpReplaySubject subject) { this.subject = subject; @@ -348,7 +348,7 @@ public void run() { } }); - final AtomicReference o = new AtomicReference<>(); + final AtomicReference o = new AtomicReference(); rs.subscribeOn(s).observeOn(Schedulers.io()) .subscribe(new NbpObserver() { diff --git a/src/test/java/io/reactivex/subjects/nbp/NbpReplaySubjectTest.java b/src/test/java/io/reactivex/subjects/nbp/NbpReplaySubjectTest.java index 709af9c7cb..71f84fd97f 100644 --- a/src/test/java/io/reactivex/subjects/nbp/NbpReplaySubjectTest.java +++ b/src/test/java/io/reactivex/subjects/nbp/NbpReplaySubjectTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -20,7 +20,6 @@ import java.util.Arrays; import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicReference; -import java.util.function.Function; import org.junit.Test; import org.mockito.*; @@ -29,7 +28,9 @@ import io.reactivex.NbpObservable.NbpSubscriber; import io.reactivex.disposables.Disposable; import io.reactivex.exceptions.TestException; +import io.reactivex.functions.Function; import io.reactivex.schedulers.*; +import io.reactivex.subjects.nbp.NbpReplaySubject; import io.reactivex.subscribers.nbp.NbpTestSubscriber; public class NbpReplaySubjectTest { @@ -67,7 +68,7 @@ public void testCompletedStopsEmittingData() { NbpSubscriber observerB = TestHelper.mockNbpSubscriber(); NbpSubscriber observerC = TestHelper.mockNbpSubscriber(); NbpSubscriber observerD = TestHelper.mockNbpSubscriber(); - NbpTestSubscriber ts = new NbpTestSubscriber<>(observerA); + NbpTestSubscriber ts = new NbpTestSubscriber(observerA); channel.subscribe(ts); channel.subscribe(observerB); @@ -218,7 +219,7 @@ public void testUnsubscribeFirstSubscriber() { NbpReplaySubject subject = NbpReplaySubject.create(); NbpSubscriber observer = TestHelper.mockNbpSubscriber(); - NbpTestSubscriber ts = new NbpTestSubscriber<>(observer); + NbpTestSubscriber ts = new NbpTestSubscriber(observer); subject.subscribe(ts); subject.onNext("one"); @@ -249,7 +250,7 @@ private void assertObservedUntilTwo(NbpSubscriber observer) { @Test(timeout = 2000) public void testNewSubscriberDoesntBlockExisting() throws InterruptedException { - final AtomicReference lastValueForSubscriber1 = new AtomicReference<>(); + final AtomicReference lastValueForSubscriber1 = new AtomicReference(); NbpSubscriber observer1 = new NbpObserver() { @Override @@ -270,7 +271,7 @@ public void onNext(String v) { }; - final AtomicReference lastValueForSubscriber2 = new AtomicReference<>(); + final AtomicReference lastValueForSubscriber2 = new AtomicReference(); final CountDownLatch oneReceived = new CountDownLatch(1); final CountDownLatch makeSlow = new CountDownLatch(1); final CountDownLatch completed = new CountDownLatch(1); @@ -535,7 +536,7 @@ public void testReplayTimestampedDirectly() { // NbpReplaySubject ps = NbpReplaySubject.create(); // // ps.subscribe(); -// NbpTestSubscriber ts = new NbpTestSubscriber<>(); +// NbpTestSubscriber ts = new NbpTestSubscriber(); // ps.subscribe(ts); // // try { diff --git a/src/test/java/io/reactivex/subjects/nbp/NbpSerializedSubjectTest.java b/src/test/java/io/reactivex/subjects/nbp/NbpSerializedSubjectTest.java index fbb0a8a037..a915349029 100644 --- a/src/test/java/io/reactivex/subjects/nbp/NbpSerializedSubjectTest.java +++ b/src/test/java/io/reactivex/subjects/nbp/NbpSerializedSubjectTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -24,8 +24,8 @@ public class NbpSerializedSubjectTest { @Test public void testBasic() { - NbpSerializedSubject subject = new NbpSerializedSubject<>(NbpPublishSubject. create()); - NbpTestSubscriber ts = new NbpTestSubscriber<>(); + NbpSerializedSubject subject = new NbpSerializedSubject(NbpPublishSubject. create()); + NbpTestSubscriber ts = new NbpTestSubscriber(); subject.subscribe(ts); subject.onNext("hello"); subject.onComplete(); diff --git a/src/test/java/io/reactivex/subscribers/ObserversTest.java b/src/test/java/io/reactivex/subscribers/ObserversTest.java index 098e1063c2..95b9051367 100644 --- a/src/test/java/io/reactivex/subscribers/ObserversTest.java +++ b/src/test/java/io/reactivex/subscribers/ObserversTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -18,11 +18,13 @@ import java.lang.reflect.*; import java.util.concurrent.atomic.*; -import java.util.function.Consumer; import org.junit.Test; import io.reactivex.exceptions.TestException; +import io.reactivex.functions.Consumer; +import io.reactivex.internal.functions.Functions; +import io.reactivex.subscribers.Observers; public class ObserversTest { @Test @@ -60,7 +62,7 @@ public void testNotInstantiable() { // @Test // public void testCreate1OnErrorNotImplemented() { // try { -// Observers.create(() -> { }).onError(new TestException()); +// Observers.create(Functions.emptyRunnable()).onError(new TestException()); // fail("OnErrorNotImplementedException not thrown!"); // } catch (OnErrorNotImplementedException ex) { // if (!(ex.getCause() instanceof TestException)) { @@ -75,27 +77,30 @@ public void testCreate1Null() { } @Test(expected = NullPointerException.class) public void testCreate2Null() { - Consumer throwAction = e -> { }; + Consumer throwAction = new Consumer() { + @Override + public void accept(Throwable e) { } + }; Observers.create(null, throwAction); } @Test(expected = NullPointerException.class) public void testCreate3Null() { - Observers.create(v -> { }, null); + Observers.create(Functions.emptyConsumer(), null); } @Test(expected = NullPointerException.class) public void testCreate4Null() { - Consumer throwAction = v -> { }; - Observers.create(null, throwAction, () -> { }); + Consumer throwAction = Functions.emptyConsumer(); + Observers.create(null, throwAction, Functions.emptyRunnable()); } @Test(expected = NullPointerException.class) public void testCreate5Null() { - Observers.create(v -> { }, null, () -> { }); + Observers.create(Functions.emptyConsumer(), null, Functions.emptyRunnable()); } @Test(expected = NullPointerException.class) public void testCreate6Null() { - Consumer throwAction = v -> { }; - Observers.create(v -> { }, throwAction, null); + Consumer throwAction = Functions.emptyConsumer(); + Observers.create(Functions.emptyConsumer(), throwAction, null); } @Test @@ -120,7 +125,7 @@ public void accept(Integer t) { value.set(t); } }; - Consumer throwAction = v -> { }; + Consumer throwAction = Functions.emptyConsumer(); Observers.create(action, throwAction).onNext(1); assertEquals(1, value.get()); @@ -135,15 +140,15 @@ public void accept(Integer t) { value.set(t); } }; - Consumer throwAction = v -> { }; - Observers.create(action, throwAction, () -> { }).onNext(1); + Consumer throwAction = Functions.emptyConsumer(); + Observers.create(action, throwAction, Functions.emptyRunnable()).onNext(1); assertEquals(1, value.get()); } @Test public void testError2() { - final AtomicReference value = new AtomicReference<>(); + final AtomicReference value = new AtomicReference(); Consumer action = new Consumer() { @Override public void accept(Throwable t) { @@ -151,14 +156,14 @@ public void accept(Throwable t) { } }; TestException exception = new TestException(); - Observers.create(v -> { }, action).onError(exception); + Observers.create(Functions.emptyConsumer(), action).onError(exception); assertEquals(exception, value.get()); } @Test public void testError3() { - final AtomicReference value = new AtomicReference<>(); + final AtomicReference value = new AtomicReference(); Consumer action = new Consumer() { @Override public void accept(Throwable t) { @@ -166,7 +171,7 @@ public void accept(Throwable t) { } }; TestException exception = new TestException(); - Observers.create(v -> { }, action, () -> { }).onError(exception); + Observers.create(Functions.emptyConsumer(), action, Functions.emptyRunnable()).onError(exception); assertEquals(exception, value.get()); } @@ -175,17 +180,17 @@ public void accept(Throwable t) { public void testCompleted() { Runnable action = mock(Runnable.class); - Consumer throwAction = v -> { }; - Observers.create(v -> { }, throwAction, action).onComplete(); + Consumer throwAction = Functions.emptyConsumer(); + Observers.create(Functions.emptyConsumer(), throwAction, action).onComplete(); verify(action).run(); } @Test public void testEmptyCompleted() { - Observers.create(v -> { }).onComplete(); + Observers.create(Functions.emptyConsumer()).onComplete(); - Consumer throwAction = v -> { }; - Observers.create(v -> { }, throwAction).onComplete(); + Consumer throwAction = Functions.emptyConsumer(); + Observers.create(Functions.emptyConsumer(), throwAction).onComplete(); } } \ No newline at end of file diff --git a/src/test/java/io/reactivex/subscribers/SafeObserverTest.java b/src/test/java/io/reactivex/subscribers/SafeObserverTest.java index 4a6cf47f1f..3d36e9c3a6 100644 --- a/src/test/java/io/reactivex/subscribers/SafeObserverTest.java +++ b/src/test/java/io/reactivex/subscribers/SafeObserverTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -24,12 +24,13 @@ import io.reactivex.Observer; import io.reactivex.exceptions.*; import io.reactivex.internal.subscriptions.EmptySubscription; +import io.reactivex.subscribers.SafeSubscriber; public class SafeObserverTest { @Test public void onNextFailure() { - AtomicReference onError = new AtomicReference<>(); + AtomicReference onError = new AtomicReference(); try { OBSERVER_ONNEXT_FAIL(onError).onNext("one"); fail("expects exception to be thrown"); @@ -42,9 +43,9 @@ public void onNextFailure() { @Test public void onNextFailureSafe() { - AtomicReference onError = new AtomicReference<>(); + AtomicReference onError = new AtomicReference(); try { - SafeSubscriber safeSubscriber = new SafeSubscriber<>(OBSERVER_ONNEXT_FAIL(onError)); + SafeSubscriber safeSubscriber = new SafeSubscriber(OBSERVER_ONNEXT_FAIL(onError)); safeSubscriber.onSubscribe(EmptySubscription.INSTANCE); safeSubscriber.onNext("one"); assertNotNull(onError.get()); @@ -57,7 +58,7 @@ public void onNextFailureSafe() { @Test public void onCompletedFailure() { - AtomicReference onError = new AtomicReference<>(); + AtomicReference onError = new AtomicReference(); try { OBSERVER_ONCOMPLETED_FAIL(onError).onComplete(); fail("expects exception to be thrown"); @@ -83,7 +84,7 @@ public void onErrorFailure() { @Ignore("Subscribers can't throw") public void onErrorFailureSafe() { try { - new SafeSubscriber<>(OBSERVER_ONERROR_FAIL()).onError(new SafeObserverTestException("error!")); + new SafeSubscriber(OBSERVER_ONERROR_FAIL()).onError(new SafeObserverTestException("error!")); fail("expects exception to be thrown"); } catch (Exception e) { e.printStackTrace(); @@ -109,7 +110,7 @@ public void onErrorFailureSafe() { @Ignore("Subscribers can't throw") public void onErrorNotImplementedFailureSafe() { try { - new SafeSubscriber<>(OBSERVER_ONERROR_NOTIMPLEMENTED()).onError(new SafeObserverTestException("error!")); + new SafeSubscriber(OBSERVER_ONERROR_NOTIMPLEMENTED()).onError(new SafeObserverTestException("error!")); fail("expects exception to be thrown"); } catch (Exception e) { assertTrue(e instanceof OnErrorNotImplementedException); @@ -134,7 +135,7 @@ public void onNextOnErrorFailure() { @Ignore("Subscribers can't throw") public void onNextOnErrorFailureSafe() { try { - new SafeSubscriber<>(OBSERVER_ONNEXT_ONERROR_FAIL()).onNext("one"); + new SafeSubscriber(OBSERVER_ONNEXT_ONERROR_FAIL()).onNext("one"); fail("expects exception to be thrown"); } catch (Exception e) { e.printStackTrace(); @@ -174,7 +175,7 @@ public void request(long n) { } }); - new SafeSubscriber<>(o).onComplete(); + new SafeSubscriber(o).onComplete(); fail("expects exception to be thrown"); } catch (Exception e) { e.printStackTrace(); @@ -191,7 +192,7 @@ public void request(long n) { @Test @Ignore("Subscribers can't throw") public void onErrorSuccessWithUnsubscribeFailure() { - AtomicReference onError = new AtomicReference<>(); + AtomicReference onError = new AtomicReference(); Subscriber o = OBSERVER_SUCCESS(onError); try { o.onSubscribe(new Subscription() { @@ -207,7 +208,7 @@ public void request(long n) { } }); - new SafeSubscriber<>(o).onError(new SafeObserverTestException("failed")); + new SafeSubscriber(o).onError(new SafeObserverTestException("failed")); fail("we expect the unsubscribe failure to cause an exception to be thrown"); } catch (Exception e) { e.printStackTrace(); @@ -245,7 +246,7 @@ public void request(long n) { } }); - new SafeSubscriber<>(o).onError(new SafeObserverTestException("onError failure")); + new SafeSubscriber(o).onError(new SafeObserverTestException("onError failure")); fail("expects exception to be thrown"); } catch (Exception e) { e.printStackTrace(); @@ -294,7 +295,7 @@ public void request(long n) { } }); - new SafeSubscriber<>(o).onError(new SafeObserverTestException("error!")); + new SafeSubscriber(o).onError(new SafeObserverTestException("error!")); fail("expects exception to be thrown"); } catch (Exception e) { e.printStackTrace(); @@ -478,8 +479,8 @@ public SafeObserverTestException(String message) { @Test @Ignore("Subscribers can't throw") public void testOnCompletedThrows() { - final AtomicReference error = new AtomicReference<>(); - SafeSubscriber s = new SafeSubscriber<>(new Observer() { + final AtomicReference error = new AtomicReference(); + SafeSubscriber s = new SafeSubscriber(new Observer() { @Override public void onNext(Integer t) { @@ -515,7 +516,7 @@ public void onError(Throwable e) { public void onComplete() { } }; - SafeSubscriber s = new SafeSubscriber<>(actual); + SafeSubscriber s = new SafeSubscriber(actual); assertSame(actual, s.actual()); } diff --git a/src/test/java/io/reactivex/subscribers/SafeSubscriberTest.java b/src/test/java/io/reactivex/subscribers/SafeSubscriberTest.java index b709a0b796..85b7ea4b36 100644 --- a/src/test/java/io/reactivex/subscribers/SafeSubscriberTest.java +++ b/src/test/java/io/reactivex/subscribers/SafeSubscriberTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -33,7 +33,7 @@ public void testOnNextAfterOnError() { Observable st = Observable.create(t); Subscriber w = TestHelper.mockSubscriber(); - st.subscribe(new SafeSubscriber<>(new TestSubscriber<>(w))); + st.subscribe(new SafeSubscriber(new TestSubscriber(w))); t.sendOnNext("one"); t.sendOnError(new RuntimeException("bad")); @@ -54,7 +54,7 @@ public void testOnCompletedAfterOnError() { Subscriber w = TestHelper.mockSubscriber(); - st.subscribe(new SafeSubscriber<>(new TestSubscriber<>(w))); + st.subscribe(new SafeSubscriber(new TestSubscriber(w))); t.sendOnNext("one"); t.sendOnError(new RuntimeException("bad")); @@ -74,7 +74,7 @@ public void testOnNextAfterOnCompleted() { Observable st = Observable.create(t); Subscriber w = TestHelper.mockSubscriber(); - st.subscribe(new SafeSubscriber<>(new TestSubscriber<>(w))); + st.subscribe(new SafeSubscriber(new TestSubscriber(w))); t.sendOnNext("one"); t.sendOnCompleted(); @@ -95,7 +95,7 @@ public void testOnErrorAfterOnCompleted() { Observable st = Observable.create(t); Subscriber w = TestHelper.mockSubscriber(); - st.subscribe(new SafeSubscriber<>(new TestSubscriber<>(w))); + st.subscribe(new SafeSubscriber(new TestSubscriber(w))); t.sendOnNext("one"); t.sendOnCompleted(); diff --git a/src/test/java/io/reactivex/subscribers/SafeSubscriberWithPluginTest.java b/src/test/java/io/reactivex/subscribers/SafeSubscriberWithPluginTest.java index 6c4ba51f27..db308867c2 100644 --- a/src/test/java/io/reactivex/subscribers/SafeSubscriberWithPluginTest.java +++ b/src/test/java/io/reactivex/subscribers/SafeSubscriberWithPluginTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -13,17 +13,17 @@ package io.reactivex.subscribers; +import static org.junit.Assert.assertEquals; + import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.Consumer; import org.junit.*; import org.reactivestreams.Subscription; import io.reactivex.exceptions.*; +import io.reactivex.functions.Consumer; import io.reactivex.plugins.RxJavaPlugins; -import static org.junit.Assert.*; - public class SafeSubscriberWithPluginTest { private final class SubscriptionCancelThrows implements Subscription { @Override @@ -52,7 +52,7 @@ public void onComplete() { throw new TestException(); } }; - SafeSubscriber safe = new SafeSubscriber<>(ts); + SafeSubscriber safe = new SafeSubscriber(ts); try { safe.onComplete(); Assert.fail(); @@ -70,7 +70,7 @@ public void onComplete() { throw new OnErrorNotImplementedException(new TestException()); } }; - SafeSubscriber safe = new SafeSubscriber<>(ts); + SafeSubscriber safe = new SafeSubscriber(ts); try { safe.onComplete(); @@ -85,8 +85,11 @@ public void onComplete() { @Test(expected = OnCompleteFailedException.class) @Ignore("Subscribers can't throw") public void testPluginException() { - RxJavaPlugins.setErrorHandler(e -> { - throw new RuntimeException(); + RxJavaPlugins.setErrorHandler(new Consumer() { + @Override + public void accept(Throwable e) { + throw new RuntimeException(); + } }); TestSubscriber ts = new TestSubscriber() { @@ -95,7 +98,7 @@ public void onComplete() { throw new TestException(); } }; - SafeSubscriber safe = new SafeSubscriber<>(ts); + SafeSubscriber safe = new SafeSubscriber(ts); safe.onComplete(); } @@ -113,8 +116,8 @@ public void accept(Throwable e) { } }); - TestSubscriber ts = new TestSubscriber<>(); - SafeSubscriber safe = new SafeSubscriber<>(ts); + TestSubscriber ts = new TestSubscriber(); + SafeSubscriber safe = new SafeSubscriber(ts); safe.onSubscribe(new SubscriptionCancelThrows()); safe.onError(new TestException()); @@ -139,7 +142,7 @@ public void onError(Throwable e) { throw new OnErrorNotImplementedException(e); } }; - SafeSubscriber safe = new SafeSubscriber<>(ts); + SafeSubscriber safe = new SafeSubscriber(ts); safe.onSubscribe(new SubscriptionCancelThrows()); safe.onError(new TestException()); @@ -164,7 +167,7 @@ public void onError(Throwable e) { throw new RuntimeException(e); } }; - SafeSubscriber safe = new SafeSubscriber<>(ts); + SafeSubscriber safe = new SafeSubscriber(ts); safe.onError(new TestException()); } @@ -187,7 +190,7 @@ public void onError(Throwable e) { throw new RuntimeException(e); } }; - SafeSubscriber safe = new SafeSubscriber<>(ts); + SafeSubscriber safe = new SafeSubscriber(ts); safe.onSubscribe(new SubscriptionCancelThrows()); safe.onError(new TestException()); @@ -211,7 +214,7 @@ public void onError(Throwable e) { throw new RuntimeException(e); } }; - SafeSubscriber safe = new SafeSubscriber<>(ts); + SafeSubscriber safe = new SafeSubscriber(ts); safe.onSubscribe(new SubscriptionCancelThrows()); safe.onError(new TestException()); @@ -236,7 +239,7 @@ public void onError(Throwable e) { } }; final RuntimeException ex = new RuntimeException(); - SafeSubscriber safe = new SafeSubscriber<>(ts); + SafeSubscriber safe = new SafeSubscriber(ts); safe.onSubscribe(new Subscription() { @Override public void cancel() { @@ -262,8 +265,11 @@ public void request(long n) { @Ignore("Subscribers can't throw") public void testPluginErrorHandlerReceivesExceptionFromFailingUnsubscribeAfterCompletionThrows() { final AtomicInteger calls = new AtomicInteger(); - RxJavaPlugins.setErrorHandler(e -> { - calls.incrementAndGet(); + RxJavaPlugins.setErrorHandler(new Consumer() { + @Override + public void accept(Throwable e) { + calls.incrementAndGet(); + } }); final AtomicInteger errors = new AtomicInteger(); @@ -279,7 +285,7 @@ public void onError(Throwable e) { errors.incrementAndGet(); } }; - SafeSubscriber safe = new SafeSubscriber<>(ts); + SafeSubscriber safe = new SafeSubscriber(ts); safe.onSubscribe(new SubscriptionCancelThrows()); try { diff --git a/src/test/java/io/reactivex/subscribers/SerializedObserverTest.java b/src/test/java/io/reactivex/subscribers/SerializedObserverTest.java index 8a3a243e0b..b24f057c15 100644 --- a/src/test/java/io/reactivex/subscribers/SerializedObserverTest.java +++ b/src/test/java/io/reactivex/subscribers/SerializedObserverTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -25,6 +25,7 @@ import io.reactivex.*; import io.reactivex.exceptions.TestException; +import io.reactivex.functions.Consumer; import io.reactivex.internal.subscriptions.*; import io.reactivex.schedulers.Schedulers; @@ -38,7 +39,7 @@ public void before() { } private Subscriber serializedSubscriber(Subscriber o) { - return new SerializedSubscriber<>(o); + return new SerializedSubscriber(o); } @Test @@ -159,7 +160,7 @@ public void runOutOfOrderConcurrencyTest() { try { TestConcurrencySubscriber tw = new TestConcurrencySubscriber(); // we need Synchronized + SafeSubscriber to handle synchronization plus life-cycle - Subscriber w = serializedSubscriber(new SafeSubscriber<>(tw)); + Subscriber w = serializedSubscriber(new SafeSubscriber(tw)); Future f1 = tp.submit(new OnNextThread(w, 12000)); Future f2 = tp.submit(new OnNextThread(w, 5000)); @@ -209,7 +210,7 @@ public void runConcurrencyTest() { try { TestConcurrencySubscriber tw = new TestConcurrencySubscriber(); // we need Synchronized + SafeSubscriber to handle synchronization plus life-cycle - Subscriber w = serializedSubscriber(new SafeSubscriber<>(tw)); + Subscriber w = serializedSubscriber(new SafeSubscriber(tw)); w.onSubscribe(EmptySubscription.INSTANCE); Future f1 = tp.submit(new OnNextThread(w, 12000)); @@ -266,7 +267,7 @@ public void testNotificationDelay() throws InterruptedException { final CountDownLatch latch = new CountDownLatch(1); final CountDownLatch running = new CountDownLatch(2); - TestSubscriber to = new TestSubscriber<>(new Observer() { + TestSubscriber to = new TestSubscriber(new Observer() { @Override public void onComplete() { @@ -347,7 +348,7 @@ public void onNext(String t) { @Test public void testThreadStarvation() throws InterruptedException { - TestSubscriber to = new TestSubscriber<>(new Observer() { + TestSubscriber to = new TestSubscriber(new Observer() { @Override public void onComplete() { @@ -369,14 +370,24 @@ public void onNext(String t) { } }); - Subscriber o = serializedSubscriber(to); + final Subscriber o = serializedSubscriber(to); AtomicInteger p1 = new AtomicInteger(); AtomicInteger p2 = new AtomicInteger(); o.onSubscribe(EmptySubscription.INSTANCE); - AsyncObserver as1 = Observers.createAsync(o::onNext); - AsyncObserver as2 = Observers.createAsync(o::onNext); + AsyncObserver as1 = Observers.createAsync(new Consumer() { + @Override + public void accept(String v) { + o.onNext(v); + } + }); + AsyncObserver as2 = Observers.createAsync(new Consumer() { + @Override + public void accept(String v) { + o.onNext(v); + } + }); infinite(p1).subscribe(as1); infinite(p2).subscribe(as2); @@ -512,7 +523,7 @@ private static class TestConcurrencySubscriber extends Observer { /** * used to store the order and number of events received */ - private final LinkedBlockingQueue events = new LinkedBlockingQueue<>(); + private final LinkedBlockingQueue events = new LinkedBlockingQueue(); private final int waitTime; @SuppressWarnings("unused") @@ -807,7 +818,7 @@ protected void captureMaxThreads() { @Test @Ignore("Null values not permitted") public void testSerializeNull() { - final AtomicReference> serial = new AtomicReference<>(); + final AtomicReference> serial = new AtomicReference>(); TestSubscriber to = new TestSubscriber() { @Override public void onNext(Integer t) { @@ -818,7 +829,7 @@ public void onNext(Integer t) { } }; - SerializedSubscriber sobs = new SerializedSubscriber<>(to); + SerializedSubscriber sobs = new SerializedSubscriber(to); serial.set(sobs); sobs.onNext(0); @@ -836,7 +847,7 @@ public void onNext(Integer t) { } }; - SerializedSubscriber sobs = new SerializedSubscriber<>(to); + SerializedSubscriber sobs = new SerializedSubscriber(to); try { sobs.onNext(0); @@ -850,7 +861,7 @@ public void onNext(Integer t) { @Test @Ignore("Null values no longer permitted") public void testSerializeReentrantNullAndComplete() { - final AtomicReference> serial = new AtomicReference<>(); + final AtomicReference> serial = new AtomicReference>(); TestSubscriber to = new TestSubscriber() { @Override public void onNext(Integer t) { @@ -859,7 +870,7 @@ public void onNext(Integer t) { } }; - SerializedSubscriber sobs = new SerializedSubscriber<>(to); + SerializedSubscriber sobs = new SerializedSubscriber(to); serial.set(sobs); try { @@ -875,7 +886,7 @@ public void onNext(Integer t) { @Test @Ignore("Subscribers can't throw") public void testSerializeReentrantNullAndError() { - final AtomicReference> serial = new AtomicReference<>(); + final AtomicReference> serial = new AtomicReference>(); TestSubscriber to = new TestSubscriber() { @Override public void onNext(Integer t) { @@ -884,7 +895,7 @@ public void onNext(Integer t) { } }; - SerializedSubscriber sobs = new SerializedSubscriber<>(to); + SerializedSubscriber sobs = new SerializedSubscriber(to); serial.set(sobs); try { @@ -900,7 +911,7 @@ public void onNext(Integer t) { @Test @Ignore("Null values no longer permitted") public void testSerializeDrainPhaseThrows() { - final AtomicReference> serial = new AtomicReference<>(); + final AtomicReference> serial = new AtomicReference>(); TestSubscriber to = new TestSubscriber() { @Override public void onNext(Integer t) { @@ -914,7 +925,7 @@ public void onNext(Integer t) { } }; - SerializedSubscriber sobs = new SerializedSubscriber<>(to); + SerializedSubscriber sobs = new SerializedSubscriber(to); serial.set(sobs); sobs.onNext(0); @@ -925,7 +936,7 @@ public void onNext(Integer t) { @Test public void testErrorReentry() { - final AtomicReference> serial = new AtomicReference<>(); + final AtomicReference> serial = new AtomicReference>(); TestSubscriber ts = new TestSubscriber() { @Override @@ -935,7 +946,8 @@ public void onNext(Integer v) { super.onNext(v); } }; - SerializedSubscriber sobs = new SerializedSubscriber<>(ts); + SerializedSubscriber sobs = new SerializedSubscriber(ts); + sobs.onSubscribe(EmptySubscription.INSTANCE); serial.set(sobs); sobs.onNext(1); @@ -945,7 +957,7 @@ public void onNext(Integer v) { } @Test public void testCompleteReentry() { - final AtomicReference> serial = new AtomicReference<>(); + final AtomicReference> serial = new AtomicReference>(); TestSubscriber ts = new TestSubscriber() { @Override @@ -955,7 +967,8 @@ public void onNext(Integer v) { super.onNext(v); } }; - SerializedSubscriber sobs = new SerializedSubscriber<>(ts); + SerializedSubscriber sobs = new SerializedSubscriber(ts); + sobs.onSubscribe(EmptySubscription.INSTANCE); serial.set(sobs); sobs.onNext(1); diff --git a/src/test/java/io/reactivex/subscribers/SubscribersTest.java b/src/test/java/io/reactivex/subscribers/SubscribersTest.java index f7c9362c57..d941b775a3 100644 --- a/src/test/java/io/reactivex/subscribers/SubscribersTest.java +++ b/src/test/java/io/reactivex/subscribers/SubscribersTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -18,11 +18,13 @@ import java.lang.reflect.*; import java.util.concurrent.atomic.*; -import java.util.function.Consumer; import org.junit.*; import io.reactivex.exceptions.*; +import io.reactivex.functions.Consumer; +import io.reactivex.internal.functions.Functions; +import io.reactivex.subscribers.Subscribers; public class SubscribersTest { @Test @@ -59,7 +61,10 @@ public void testEmptyOnErrorNotImplemented() { @Ignore("Subscribers can't throw OnErrorNotImplementedException") public void testCreate1OnErrorNotImplemented() { try { - Subscribers.create(v -> { }).onError(new TestException()); + Subscribers.create(new Consumer() { + @Override + public void accept(Object v) { } + }).onError(new TestException()); fail("OnErrorNotImplementedException not thrown!"); } catch (OnErrorNotImplementedException ex) { if (!(ex.getCause() instanceof TestException)) { @@ -73,27 +78,45 @@ public void testCreate1Null() { } @Test(expected = NullPointerException.class) public void testCreate2Null() { - Consumer throwAction = e -> { }; + Consumer throwAction = new Consumer() { + @Override + public void accept(Throwable e) { } + }; Subscribers.create(null, throwAction); } @Test(expected = NullPointerException.class) public void testCreate3Null() { - Subscribers.create(e -> { }, null); + Subscribers.create(new Consumer() { + @Override + public void accept(Object e) { } + }, null); } @Test(expected = NullPointerException.class) public void testCreate4Null() { - Consumer throwAction = e -> { }; - Subscribers.create(null, throwAction, () -> { }); + Consumer throwAction = new Consumer() { + @Override + public void accept(Throwable e) { } + }; + Subscribers.create(null, throwAction, Functions.emptyRunnable()); } @Test(expected = NullPointerException.class) public void testCreate5Null() { - Subscribers.create(e -> { }, null, () -> { }); + Subscribers.create(new Consumer() { + @Override + public void accept(Object e) { } + }, null, Functions.emptyRunnable()); } @Test(expected = NullPointerException.class) public void testCreate6Null() { - Consumer throwAction = e -> { }; - Subscribers.create(e -> { }, throwAction, null); + Consumer throwAction = new Consumer() { + @Override + public void accept(Throwable e) { } + }; + Subscribers.create(new Consumer() { + @Override + public void accept(Object e) { } + }, throwAction, null); } @Test @@ -118,7 +141,10 @@ public void accept(Integer t) { value.set(t); } }; - Consumer throwAction = e -> { }; + Consumer throwAction = new Consumer() { + @Override + public void accept(Throwable e) { } + }; Subscribers.create(action, throwAction).onNext(1); assertEquals(1, value.get()); @@ -133,15 +159,18 @@ public void accept(Integer t) { value.set(t); } }; - Consumer throwAction = e -> { }; - Subscribers.create(action, throwAction, () -> { }).onNext(1); + Consumer throwAction = new Consumer() { + @Override + public void accept(Throwable e) { } + }; + Subscribers.create(action, throwAction, Functions.emptyRunnable()).onNext(1); assertEquals(1, value.get()); } @Test public void testError2() { - final AtomicReference value = new AtomicReference<>(); + final AtomicReference value = new AtomicReference(); Consumer action = new Consumer() { @Override public void accept(Throwable t) { @@ -149,14 +178,17 @@ public void accept(Throwable t) { } }; TestException exception = new TestException(); - Subscribers.create(e -> { }, action).onError(exception); + Subscribers.create(new Consumer() { + @Override + public void accept(Object e) { } + }, action).onError(exception); assertEquals(exception, value.get()); } @Test public void testError3() { - final AtomicReference value = new AtomicReference<>(); + final AtomicReference value = new AtomicReference(); Consumer action = new Consumer() { @Override public void accept(Throwable t) { @@ -164,7 +196,10 @@ public void accept(Throwable t) { } }; TestException exception = new TestException(); - Subscribers.create(e -> { }, action, () -> { }).onError(exception); + Subscribers.create(new Consumer() { + @Override + public void accept(Object e) { } + }, action, Functions.emptyRunnable()).onError(exception); assertEquals(exception, value.get()); } @@ -173,16 +208,31 @@ public void accept(Throwable t) { public void testCompleted() { Runnable action = mock(Runnable.class); - Consumer throwAction = e -> { }; - Subscribers.create(e -> { }, throwAction, action).onComplete(); + Consumer throwAction = new Consumer() { + @Override + public void accept(Throwable e) { } + }; + Subscribers.create(new Consumer() { + @Override + public void accept(Object e) { } + }, throwAction, action).onComplete(); verify(action).run(); } @Test public void testEmptyCompleted() { - Subscribers.create(e -> { }).onComplete(); + Subscribers.create(new Consumer() { + @Override + public void accept(Object e) { } + }).onComplete(); - Consumer throwAction = e -> { }; - Subscribers.create(e -> { }, throwAction).onComplete(); + Consumer throwAction = new Consumer() { + @Override + public void accept(Throwable e) { } + }; + Subscribers.create(new Consumer() { + @Override + public void accept(Object e) { } + }, throwAction).onComplete(); } } \ No newline at end of file diff --git a/src/test/java/io/reactivex/subscribers/TestObserverTest.java b/src/test/java/io/reactivex/subscribers/TestObserverTest.java index a6585536b5..7299f82938 100644 --- a/src/test/java/io/reactivex/subscribers/TestObserverTest.java +++ b/src/test/java/io/reactivex/subscribers/TestObserverTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -24,9 +24,11 @@ import org.reactivestreams.Subscriber; import io.reactivex.*; -import io.reactivex.Observable; import io.reactivex.exceptions.TestException; +import io.reactivex.internal.subscriptions.EmptySubscription; import io.reactivex.subjects.PublishSubject; +import io.reactivex.subscribers.TestSubscriber; +import io.reactivex.Observable; public class TestObserverTest { @@ -36,7 +38,7 @@ public class TestObserverTest { @Test public void testAssert() { Observable oi = Observable.fromIterable(Arrays.asList(1, 2)); - TestSubscriber o = new TestSubscriber<>(); + TestSubscriber o = new TestSubscriber(); oi.subscribe(o); o.assertValues(1, 2); @@ -47,7 +49,7 @@ public void testAssert() { @Test public void testAssertNotMatchCount() { Observable oi = Observable.fromIterable(Arrays.asList(1, 2)); - TestSubscriber o = new TestSubscriber<>(); + TestSubscriber o = new TestSubscriber(); oi.subscribe(o); thrown.expect(AssertionError.class); @@ -62,7 +64,7 @@ public void testAssertNotMatchCount() { @Test public void testAssertNotMatchValue() { Observable oi = Observable.fromIterable(Arrays.asList(1, 2)); - TestSubscriber o = new TestSubscriber<>(); + TestSubscriber o = new TestSubscriber(); oi.subscribe(o); thrown.expect(AssertionError.class); @@ -77,7 +79,7 @@ public void testAssertNotMatchValue() { @Test public void testAssertTerminalEventNotReceived() { PublishSubject p = PublishSubject.create(); - TestSubscriber o = new TestSubscriber<>(); + TestSubscriber o = new TestSubscriber(); p.subscribe(o); p.onNext(1); @@ -98,7 +100,7 @@ public void testWrappingMock() { Subscriber mockObserver = TestHelper.mockSubscriber(); - oi.subscribe(new TestSubscriber<>(mockObserver)); + oi.subscribe(new TestSubscriber(mockObserver)); InOrder inOrder = inOrder(mockObserver); inOrder.verify(mockObserver, times(1)).onNext(1); @@ -111,7 +113,7 @@ public void testWrappingMock() { public void testWrappingMockWhenUnsubscribeInvolved() { Observable oi = Observable.fromIterable(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9)).take(2); Subscriber mockObserver = TestHelper.mockSubscriber(); - oi.subscribe(new TestSubscriber<>(mockObserver)); + oi.subscribe(new TestSubscriber(mockObserver)); InOrder inOrder = inOrder(mockObserver); inOrder.verify(mockObserver, times(1)).onNext(1); @@ -122,12 +124,13 @@ public void testWrappingMockWhenUnsubscribeInvolved() { @Test public void testErrorSwallowed() { - Observable.error(new RuntimeException()).subscribe(new TestSubscriber<>()); + Observable.error(new RuntimeException()).subscribe(new TestSubscriber()); } @Test public void testGetEvents() { - TestSubscriber to = new TestSubscriber<>(); + TestSubscriber to = new TestSubscriber(); + to.onSubscribe(EmptySubscription.INSTANCE); to.onNext(1); to.onNext(2); @@ -141,7 +144,8 @@ public void testGetEvents() { Collections.singletonList(Notification.complete())), to.getEvents()); TestException ex = new TestException(); - TestSubscriber to2 = new TestSubscriber<>(); + TestSubscriber to2 = new TestSubscriber(); + to2.onSubscribe(EmptySubscription.INSTANCE); to2.onNext(1); to2.onNext(2); @@ -160,7 +164,7 @@ public void testGetEvents() { @Test public void testNullExpected() { - TestSubscriber to = new TestSubscriber<>(); + TestSubscriber to = new TestSubscriber(); to.onNext(1); try { @@ -174,7 +178,7 @@ public void testNullExpected() { @Test public void testNullActual() { - TestSubscriber to = new TestSubscriber<>(); + TestSubscriber to = new TestSubscriber(); to.onNext(null); try { @@ -188,7 +192,7 @@ public void testNullActual() { @Test public void testTerminalErrorOnce() { - TestSubscriber to = new TestSubscriber<>(); + TestSubscriber to = new TestSubscriber(); to.onError(new TestException()); to.onError(new TestException()); @@ -202,7 +206,7 @@ public void testTerminalErrorOnce() { } @Test public void testTerminalCompletedOnce() { - TestSubscriber to = new TestSubscriber<>(); + TestSubscriber to = new TestSubscriber(); to.onComplete(); to.onComplete(); @@ -217,7 +221,7 @@ public void testTerminalCompletedOnce() { @Test public void testTerminalOneKind() { - TestSubscriber to = new TestSubscriber<>(); + TestSubscriber to = new TestSubscriber(); to.onError(new TestException()); to.onComplete(); diff --git a/src/test/java/io/reactivex/subscribers/TestSubscriberTest.java b/src/test/java/io/reactivex/subscribers/TestSubscriberTest.java index 3d02a470d8..47a705384a 100644 --- a/src/test/java/io/reactivex/subscribers/TestSubscriberTest.java +++ b/src/test/java/io/reactivex/subscribers/TestSubscriberTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2015 Netflix, Inc. + * 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 @@ -28,8 +28,10 @@ import io.reactivex.*; import io.reactivex.Scheduler.Worker; import io.reactivex.exceptions.*; +import io.reactivex.internal.subscriptions.EmptySubscription; import io.reactivex.schedulers.Schedulers; import io.reactivex.subjects.PublishSubject; +import io.reactivex.subscribers.TestSubscriber; public class TestSubscriberTest { @@ -39,7 +41,7 @@ public class TestSubscriberTest { @Test public void testAssert() { Observable oi = Observable.fromIterable(Arrays.asList(1, 2)); - TestSubscriber o = new TestSubscriber<>(); + TestSubscriber o = new TestSubscriber(); oi.subscribe(o); o.assertValues(1, 2); @@ -50,7 +52,7 @@ public void testAssert() { @Test public void testAssertNotMatchCount() { Observable oi = Observable.fromIterable(Arrays.asList(1, 2)); - TestSubscriber o = new TestSubscriber<>(); + TestSubscriber o = new TestSubscriber(); oi.subscribe(o); thrown.expect(AssertionError.class); @@ -65,7 +67,7 @@ public void testAssertNotMatchCount() { @Test public void testAssertNotMatchValue() { Observable oi = Observable.fromIterable(Arrays.asList(1, 2)); - TestSubscriber o = new TestSubscriber<>(); + TestSubscriber o = new TestSubscriber(); oi.subscribe(o); thrown.expect(AssertionError.class); @@ -81,7 +83,7 @@ public void testAssertNotMatchValue() { @Test public void testAssertTerminalEventNotReceived() { PublishSubject p = PublishSubject.create(); - TestSubscriber o = new TestSubscriber<>(); + TestSubscriber o = new TestSubscriber(); p.subscribe(o); p.onNext(1); @@ -101,7 +103,7 @@ public void testWrappingMock() { Observable oi = Observable.fromIterable(Arrays.asList(1, 2)); Subscriber mockObserver = TestHelper.mockSubscriber(); - oi.subscribe(new TestSubscriber<>(mockObserver)); + oi.subscribe(new TestSubscriber(mockObserver)); InOrder inOrder = inOrder(mockObserver); inOrder.verify(mockObserver, times(1)).onNext(1); @@ -114,7 +116,7 @@ public void testWrappingMock() { public void testWrappingMockWhenUnsubscribeInvolved() { Observable oi = Observable.fromIterable(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9)).take(2); Subscriber mockObserver = TestHelper.mockSubscriber(); - oi.subscribe(new TestSubscriber<>(mockObserver)); + oi.subscribe(new TestSubscriber(mockObserver)); InOrder inOrder = inOrder(mockObserver); inOrder.verify(mockObserver, times(1)).onNext(1); @@ -126,14 +128,14 @@ public void testWrappingMockWhenUnsubscribeInvolved() { @Test public void testAssertError() { RuntimeException e = new RuntimeException("Oops"); - TestSubscriber subscriber = new TestSubscriber<>(); + TestSubscriber subscriber = new TestSubscriber(); Observable.error(e).subscribe(subscriber); subscriber.assertError(e); } @Test public void testAwaitTerminalEventWithDuration() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); Observable.just(1).subscribe(ts); ts.awaitTerminalEvent(1, TimeUnit.SECONDS); ts.assertTerminated(); @@ -141,7 +143,7 @@ public void testAwaitTerminalEventWithDuration() { @Test public void testAwaitTerminalEventWithDurationAndUnsubscribeOnTimeout() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); final AtomicBoolean unsub = new AtomicBoolean(false); Observable.just(1) // @@ -160,26 +162,28 @@ public void run() { @Test(expected = NullPointerException.class) public void testNullDelegate1() { - TestSubscriber ts = new TestSubscriber<>((Observer)null); + TestSubscriber ts = new TestSubscriber((Observer)null); ts.onComplete(); } @Test(expected = NullPointerException.class) public void testNullDelegate2() { - TestSubscriber ts = new TestSubscriber<>((Subscriber)null); + TestSubscriber ts = new TestSubscriber((Subscriber)null); ts.onComplete(); } @Test(expected = NullPointerException.class) public void testNullDelegate3() { - TestSubscriber ts = new TestSubscriber<>((Subscriber)null, null); + TestSubscriber ts = new TestSubscriber((Subscriber)null, null); ts.onComplete(); } @Test public void testDelegate1() { - TestSubscriber to = new TestSubscriber<>(); - TestSubscriber ts = new TestSubscriber<>(to); + TestSubscriber to = new TestSubscriber(); + to.onSubscribe(EmptySubscription.INSTANCE); + + TestSubscriber ts = new TestSubscriber(to); ts.onComplete(); to.assertTerminated(); @@ -187,8 +191,8 @@ public void testDelegate1() { @Test public void testDelegate2() { - TestSubscriber ts1 = new TestSubscriber<>(); - TestSubscriber ts2 = new TestSubscriber<>(ts1); + TestSubscriber ts1 = new TestSubscriber(); + TestSubscriber ts2 = new TestSubscriber(ts1); ts2.onComplete(); ts1.assertComplete(); @@ -196,21 +200,21 @@ public void testDelegate2() { @Test public void testDelegate3() { - TestSubscriber ts1 = new TestSubscriber<>(); - TestSubscriber ts2 = new TestSubscriber<>(ts1, null); + TestSubscriber ts1 = new TestSubscriber(); + TestSubscriber ts2 = new TestSubscriber(ts1, null); ts2.onComplete(); ts1.assertComplete(); } @Test public void testUnsubscribed() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); assertFalse(ts.isCancelled()); } @Test public void testNoErrors() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); ts.onError(new TestException()); try { ts.assertNoErrors(); @@ -223,7 +227,7 @@ public void testNoErrors() { @Test public void testNotCompleted() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); try { ts.assertComplete(); } catch (AssertionError ex) { @@ -235,7 +239,7 @@ public void testNotCompleted() { @Test public void testMultipleCompletions() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); ts.onComplete(); ts.onComplete(); try { @@ -249,7 +253,7 @@ public void testMultipleCompletions() { @Test public void testCompleted() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); ts.onComplete(); try { ts.assertNotComplete(); @@ -262,7 +266,7 @@ public void testCompleted() { @Test public void testMultipleCompletions2() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); ts.onComplete(); ts.onComplete(); try { @@ -276,15 +280,22 @@ public void testMultipleCompletions2() { @Test public void testMultipleErrors() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); + ts.onSubscribe(EmptySubscription.INSTANCE); ts.onError(new TestException()); ts.onError(new TestException()); try { ts.assertNoErrors(); } catch (AssertionError ex) { - if (ex.getSuppressed().length != 2) { + Throwable e = ex.getCause(); + if (!(e instanceof CompositeException)) { fail("Multiple Error present but the reported error doesn't have a composite cause!"); } + CompositeException ce = (CompositeException)e; + if (ce.size() != 2) { + ce.printStackTrace(); + } + assertEquals(2, ce.size()); // expected return; } @@ -293,15 +304,19 @@ public void testMultipleErrors() { @Test public void testMultipleErrors2() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); + ts.onSubscribe(EmptySubscription.INSTANCE); ts.onError(new TestException()); ts.onError(new TestException()); try { ts.assertError(TestException.class); } catch (AssertionError ex) { - if (ex.getSuppressed().length != 2) { + Throwable e = ex.getCause(); + if (!(e instanceof CompositeException)) { fail("Multiple Error present but the reported error doesn't have a composite cause!"); } + CompositeException ce = (CompositeException)e; + assertEquals(2, ce.size()); // expected return; } @@ -310,15 +325,19 @@ public void testMultipleErrors2() { @Test public void testMultipleErrors3() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); + ts.onSubscribe(EmptySubscription.INSTANCE); ts.onError(new TestException()); ts.onError(new TestException()); try { ts.assertError(new TestException()); } catch (AssertionError ex) { - if (ex.getSuppressed().length != 2) { + Throwable e = ex.getCause(); + if (!(e instanceof CompositeException)) { fail("Multiple Error present but the reported error doesn't have a composite cause!"); } + CompositeException ce = (CompositeException)e; + assertEquals(2, ce.size()); // expected return; } @@ -327,7 +346,7 @@ public void testMultipleErrors3() { @Test public void testDifferentError() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); ts.onError(new TestException()); try { ts.assertError(new TestException()); @@ -340,7 +359,7 @@ public void testDifferentError() { @Test public void testDifferentError2() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); ts.onError(new RuntimeException()); try { ts.assertError(new TestException()); @@ -353,7 +372,7 @@ public void testDifferentError2() { @Test public void testDifferentError3() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); ts.onError(new RuntimeException()); try { ts.assertError(TestException.class); @@ -366,7 +385,7 @@ public void testDifferentError3() { @Test public void testNoError() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); try { ts.assertError(TestException.class); } catch (AssertionError ex) { @@ -378,7 +397,7 @@ public void testNoError() { @Test public void testNoError2() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); try { ts.assertError(new TestException()); } catch (AssertionError ex) { @@ -390,7 +409,7 @@ public void testNoError2() { @Test public void testInterruptTerminalEventAwait() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); final Thread t0 = Thread.currentThread(); Worker w = Schedulers.computation().createWorker(); @@ -418,7 +437,7 @@ public void run() { @Test public void testInterruptTerminalEventAwaitTimed() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); final Thread t0 = Thread.currentThread(); Worker w = Schedulers.computation().createWorker(); @@ -447,7 +466,7 @@ public void run() { @Test public void testInterruptTerminalEventAwaitAndUnsubscribe() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); final Thread t0 = Thread.currentThread(); Worker w = Schedulers.computation().createWorker(); @@ -471,7 +490,7 @@ public void run() { @Test public void testNoTerminalEventBut1Completed() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); ts.onComplete(); @@ -485,7 +504,7 @@ public void testNoTerminalEventBut1Completed() { @Test public void testNoTerminalEventBut1Error() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); ts.onError(new TestException()); @@ -499,7 +518,7 @@ public void testNoTerminalEventBut1Error() { @Test public void testNoTerminalEventBut1Error1Completed() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); ts.onComplete(); ts.onError(new TestException()); @@ -514,7 +533,8 @@ public void testNoTerminalEventBut1Error1Completed() { @Test public void testNoTerminalEventBut2Errors() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); + ts.onSubscribe(EmptySubscription.INSTANCE); ts.onError(new TestException()); ts.onError(new TestException()); @@ -524,15 +544,18 @@ public void testNoTerminalEventBut2Errors() { fail("Failed to report there were terminal event(s)!"); } catch (AssertionError ex) { // expected - if (ex.getSuppressed().length != 2) { - fail("Did not report a composite exception cause: " + ex.getCause()); + Throwable e = ex.getCause(); + if (!(e instanceof CompositeException)) { + fail("Multiple Error present but the reported error doesn't have a composite cause!"); } + CompositeException ce = (CompositeException)e; + assertEquals(2, ce.size()); } } @Test public void testNoValues() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); ts.onNext(1); try { @@ -545,7 +568,7 @@ public void testNoValues() { @Test public void testValueCount() { - TestSubscriber ts = new TestSubscriber<>(); + TestSubscriber ts = new TestSubscriber(); ts.onNext(1); ts.onNext(2); @@ -565,7 +588,7 @@ public void onComplete() { throw new TestException(); } }; - TestSubscriber ts = new TestSubscriber<>(to); + TestSubscriber ts = new TestSubscriber(to); try { ts.onComplete(); @@ -584,7 +607,7 @@ public void onError(Throwable e) { throw new TestException(); } }; - TestSubscriber ts = new TestSubscriber<>(to); + TestSubscriber ts = new TestSubscriber(to); try { ts.onError(new RuntimeException());