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

io.reactivex.plugins.RxJavaPlugins Maven / Gradle / Ivy

There is a newer version: 2.2.21
Show newest version
/**
 * Copyright 2016 Netflix, Inc.
 *
 * Licensed under the Apache License, Version 2.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.plugins;

import java.lang.Thread.UncaughtExceptionHandler;
import java.util.concurrent.Callable;

import io.reactivex.internal.functions.ObjectHelper;
import org.reactivestreams.Subscriber;

import io.reactivex.*;
import io.reactivex.flowables.ConnectableFlowable;
import io.reactivex.functions.*;
import io.reactivex.internal.util.ExceptionHelper;
import io.reactivex.observables.ConnectableObservable;

/**
 * Utility class to inject handlers to certain standard RxJava operations.
 */
public final class RxJavaPlugins {

    static volatile Consumer errorHandler;

    static volatile Function onScheduleHandler;

    static volatile Function, Scheduler> onInitComputationHandler;

    static volatile Function, Scheduler> onInitSingleHandler;

    static volatile Function, Scheduler> onInitIoHandler;

    static volatile Function, Scheduler> onInitNewThreadHandler;

    static volatile Function onComputationHandler;

    static volatile Function onSingleHandler;

    static volatile Function onIoHandler;

    static volatile Function onNewThreadHandler;

    @SuppressWarnings("rawtypes")
    static volatile Function onFlowableAssembly;

    @SuppressWarnings("rawtypes")
    static volatile Function onConnectableFlowableAssembly;

    @SuppressWarnings("rawtypes")
    static volatile Function onObservableAssembly;

    @SuppressWarnings("rawtypes")
    static volatile Function onConnectableObservableAssembly;

    @SuppressWarnings("rawtypes")
    static volatile Function onMaybeAssembly;

    @SuppressWarnings("rawtypes")
    static volatile Function onSingleAssembly;

    static volatile Function onCompletableAssembly;

    @SuppressWarnings("rawtypes")
    static volatile BiFunction onFlowableSubscribe;

    @SuppressWarnings("rawtypes")
    static volatile BiFunction onMaybeSubscribe;

    @SuppressWarnings("rawtypes")
    static volatile BiFunction onObservableSubscribe;

    @SuppressWarnings("rawtypes")
    static volatile BiFunction onSingleSubscribe;

    static volatile BiFunction onCompletableSubscribe;

    /** Prevents changing the plugins. */
    static volatile boolean lockdown;

    /**
     * Prevents changing the plugins from then on.
     * 

This allows container-like environments to prevent clients * messing with plugins. */ public static void lockdown() { lockdown = true; } /** * Returns true if the plugins were locked down. * @return true if the plugins were locked down */ public static boolean isLockdown() { return lockdown; } /** * Returns the current hook function. * @return the hook function, may be null */ public static Function getComputationSchedulerHandler() { return onComputationHandler; } /** * Returns the a hook consumer. * @return the hook consumer, may be null */ public static Consumer getErrorHandler() { return errorHandler; } /** * Returns the current hook function. * @return the hook function, may be null */ public static Function, Scheduler> getInitComputationSchedulerHandler() { return onInitComputationHandler; } /** * Returns the current hook function. * @return the hook function, may be null */ public static Function, Scheduler> getInitIoSchedulerHandler() { return onInitIoHandler; } /** * Returns the current hook function. * @return the hook function, may be null */ public static Function, Scheduler> getInitNewThreadSchedulerHandler() { return onInitNewThreadHandler; } /** * Returns the current hook function. * @return the hook function, may be null */ public static Function, Scheduler> getInitSingleSchedulerHandler() { return onInitSingleHandler; } /** * Returns the current hook function. * @return the hook function, may be null */ public static Function getIoSchedulerHandler() { return onIoHandler; } /** * Returns the current hook function. * @return the hook function, may be null */ public static Function getNewThreadSchedulerHandler() { return onNewThreadHandler; } /** * Returns the current hook function. * @return the hook function, may be null */ public static Function getScheduleHandler() { return onScheduleHandler; } /** * Returns the current hook function. * @return the hook function, may be null */ public static Function getSingleSchedulerHandler() { return onSingleHandler; } /** * Calls the associated hook function. * @param defaultScheduler a {@link Callable} which returns the hook's input value * @return the value returned by the hook, not null * @throws NullPointerException if the callable parameter or its result are null */ public static Scheduler initComputationScheduler(Callable defaultScheduler) { ObjectHelper.requireNonNull(defaultScheduler, "Scheduler Callable can't be null"); Function, Scheduler> f = onInitComputationHandler; if (f == null) { return callRequireNonNull(defaultScheduler); } return applyRequireNonNull(f, defaultScheduler); // JIT will skip this } /** * Calls the associated hook function. * @param defaultScheduler a {@link Callable} which returns the hook's input value * @return the value returned by the hook, not null * @throws NullPointerException if the callable parameter or its result are null */ public static Scheduler initIoScheduler(Callable defaultScheduler) { ObjectHelper.requireNonNull(defaultScheduler, "Scheduler Callable can't be null"); Function, Scheduler> f = onInitIoHandler; if (f == null) { return callRequireNonNull(defaultScheduler); } return applyRequireNonNull(f, defaultScheduler); } /** * Calls the associated hook function. * @param defaultScheduler a {@link Callable} which returns the hook's input value * @return the value returned by the hook, not null * @throws NullPointerException if the callable parameter or its result are null */ public static Scheduler initNewThreadScheduler(Callable defaultScheduler) { ObjectHelper.requireNonNull(defaultScheduler, "Scheduler Callable can't be null"); Function, Scheduler> f = onInitNewThreadHandler; if (f == null) { return callRequireNonNull(defaultScheduler); } return applyRequireNonNull(f, defaultScheduler); } /** * Calls the associated hook function. * @param defaultScheduler a {@link Callable} which returns the hook's input value * @return the value returned by the hook, not null * @throws NullPointerException if the callable parameter or its result are null */ public static Scheduler initSingleScheduler(Callable defaultScheduler) { ObjectHelper.requireNonNull(defaultScheduler, "Scheduler Callable can't be null"); Function, Scheduler> f = onInitSingleHandler; if (f == null) { return callRequireNonNull(defaultScheduler); } return applyRequireNonNull(f, defaultScheduler); } /** * Calls the associated hook function. * @param defaultScheduler the hook's input value * @return the value returned by the hook */ public static Scheduler onComputationScheduler(Scheduler defaultScheduler) { Function f = onComputationHandler; if (f == null) { return defaultScheduler; } return apply(f, defaultScheduler); } /** * Called when an undeliverable error occurs. * @param error the error to report */ public static void onError(Throwable error) { Consumer f = errorHandler; if (error == null) { error = new NullPointerException("onError called with null. Null values are generally not allowed in 2.x operators and sources."); } if (f != null) { try { f.accept(error); return; } catch (Throwable e) { // Exceptions.throwIfFatal(e); TODO decide e.printStackTrace(); // NOPMD uncaught(e); } } error.printStackTrace(); // NOPMD uncaught(error); } static void uncaught(Throwable error) { Thread currentThread = Thread.currentThread(); UncaughtExceptionHandler handler = currentThread.getUncaughtExceptionHandler(); handler.uncaughtException(currentThread, error); } /** * Calls the associated hook function. * @param defaultScheduler the hook's input value * @return the value returned by the hook */ public static Scheduler onIoScheduler(Scheduler defaultScheduler) { Function f = onIoHandler; if (f == null) { return defaultScheduler; } return apply(f, defaultScheduler); } /** * Calls the associated hook function. * @param defaultScheduler the hook's input value * @return the value returned by the hook */ public static Scheduler onNewThreadScheduler(Scheduler defaultScheduler) { Function f = onNewThreadHandler; if (f == null) { return defaultScheduler; } return apply(f, defaultScheduler); } /** * Called when a task is scheduled. * @param run the runnable instance * @return the replacement runnable */ public static Runnable onSchedule(Runnable run) { Function f = onScheduleHandler; if (f == null) { return run; } return apply(f, run); } /** * Calls the associated hook function. * @param defaultScheduler the hook's input value * @return the value returned by the hook */ public static Scheduler onSingleScheduler(Scheduler defaultScheduler) { Function f = onSingleHandler; if (f == null) { return defaultScheduler; } return apply(f, defaultScheduler); } /** * Removes all handlers and resets to default behavior. */ public static void reset() { setErrorHandler(null); setScheduleHandler(null); setComputationSchedulerHandler(null); setInitComputationSchedulerHandler(null); setIoSchedulerHandler(null); setInitIoSchedulerHandler(null); setSingleSchedulerHandler(null); setInitSingleSchedulerHandler(null); setNewThreadSchedulerHandler(null); setInitNewThreadSchedulerHandler(null); setOnFlowableAssembly(null); setOnFlowableSubscribe(null); setOnObservableAssembly(null); setOnObservableSubscribe(null); setOnSingleAssembly(null); setOnSingleSubscribe(null); setOnCompletableAssembly(null); setOnCompletableSubscribe(null); setOnConnectableFlowableAssembly(null); setOnConnectableObservableAssembly(null); setOnMaybeAssembly(null); setOnMaybeSubscribe(null); } /** * Sets the specific hook function. * @param handler the hook function to set, null allowed */ public static void setComputationSchedulerHandler(Function handler) { if (lockdown) { throw new IllegalStateException("Plugins can't be changed anymore"); } onComputationHandler = handler; } /** * Sets the specific hook function. * @param handler the hook function to set, null allowed */ public static void setErrorHandler(Consumer handler) { if (lockdown) { throw new IllegalStateException("Plugins can't be changed anymore"); } errorHandler = handler; } /** * Sets the specific hook function. * @param handler the hook function to set, null allowed, but the function may not return null */ public static void setInitComputationSchedulerHandler(Function, Scheduler> handler) { if (lockdown) { throw new IllegalStateException("Plugins can't be changed anymore"); } onInitComputationHandler = handler; } /** * Sets the specific hook function. * @param handler the hook function to set, null allowed, but the function may not return null */ public static void setInitIoSchedulerHandler(Function, Scheduler> handler) { if (lockdown) { throw new IllegalStateException("Plugins can't be changed anymore"); } onInitIoHandler = handler; } /** * Sets the specific hook function. * @param handler the hook function to set, null allowed, but the function may not return null */ public static void setInitNewThreadSchedulerHandler(Function, Scheduler> handler) { if (lockdown) { throw new IllegalStateException("Plugins can't be changed anymore"); } onInitNewThreadHandler = handler; } /** * Sets the specific hook function. * @param handler the hook function to set, null allowed, but the function may not return null */ public static void setInitSingleSchedulerHandler(Function, Scheduler> handler) { if (lockdown) { throw new IllegalStateException("Plugins can't be changed anymore"); } onInitSingleHandler = handler; } /** * Sets the specific hook function. * @param handler the hook function to set, null allowed */ public static void setIoSchedulerHandler(Function handler) { if (lockdown) { throw new IllegalStateException("Plugins can't be changed anymore"); } onIoHandler = handler; } /** * Sets the specific hook function. * @param handler the hook function to set, null allowed */ public static void setNewThreadSchedulerHandler(Function handler) { if (lockdown) { throw new IllegalStateException("Plugins can't be changed anymore"); } onNewThreadHandler = handler; } /** * Sets the specific hook function. * @param handler the hook function to set, null allowed */ public static void setScheduleHandler(Function handler) { if (lockdown) { throw new IllegalStateException("Plugins can't be changed anymore"); } onScheduleHandler = handler; } /** * Sets the specific hook function. * @param handler the hook function to set, null allowed */ public static void setSingleSchedulerHandler(Function handler) { if (lockdown) { throw new IllegalStateException("Plugins can't be changed anymore"); } onSingleHandler = handler; } /** * Revokes the lockdown, only for testing purposes. */ /* test. */static void unlock() { lockdown = false; } /** * Returns the current hook function. * @return the hook function, may be null */ public static Function getOnCompletableAssembly() { return onCompletableAssembly; } /** * Returns the current hook function. * @return the hook function, may be null */ public static BiFunction getOnCompletableSubscribe() { return onCompletableSubscribe; } /** * Returns the current hook function. * @return the hook function, may be null */ @SuppressWarnings("rawtypes") public static Function getOnFlowableAssembly() { return onFlowableAssembly; } /** * Returns the current hook function. * @return the hook function, may be null */ @SuppressWarnings("rawtypes") public static Function getOnConnectableFlowableAssembly() { return onConnectableFlowableAssembly; } /** * Returns the current hook function. * @return the hook function, may be null */ @SuppressWarnings("rawtypes") public static BiFunction getOnFlowableSubscribe() { return onFlowableSubscribe; } /** * Returns the current hook function. * @return the hook function, may be null */ @SuppressWarnings("rawtypes") public static BiFunction getOnMaybeSubscribe() { return onMaybeSubscribe; } /** * Returns the current hook function. * @return the hook function, may be null */ @SuppressWarnings("rawtypes") public static Function getOnMaybeAssembly() { return onMaybeAssembly; } /** * Returns the current hook function. * @return the hook function, may be null */ @SuppressWarnings("rawtypes") public static Function getOnSingleAssembly() { return onSingleAssembly; } /** * Returns the current hook function. * @return the hook function, may be null */ @SuppressWarnings("rawtypes") public static BiFunction getOnSingleSubscribe() { return onSingleSubscribe; } /** * Returns the current hook function. * @return the hook function, may be null */ @SuppressWarnings("rawtypes") public static Function getOnObservableAssembly() { return onObservableAssembly; } /** * Returns the current hook function. * @return the hook function, may be null */ @SuppressWarnings("rawtypes") public static Function getOnConnectableObservableAssembly() { return onConnectableObservableAssembly; } /** * Returns the current hook function. * @return the hook function, may be null */ @SuppressWarnings("rawtypes") public static BiFunction getOnObservableSubscribe() { return onObservableSubscribe; } /** * Sets the specific hook function. * @param onCompletableAssembly the hook function to set, null allowed */ public static void setOnCompletableAssembly(Function onCompletableAssembly) { if (lockdown) { throw new IllegalStateException("Plugins can't be changed anymore"); } RxJavaPlugins.onCompletableAssembly = onCompletableAssembly; } /** * Sets the specific hook function. * @param onCompletableSubscribe the hook function to set, null allowed */ public static void setOnCompletableSubscribe( BiFunction onCompletableSubscribe) { if (lockdown) { throw new IllegalStateException("Plugins can't be changed anymore"); } RxJavaPlugins.onCompletableSubscribe = onCompletableSubscribe; } /** * Sets the specific hook function. * @param onFlowableAssembly the hook function to set, null allowed */ @SuppressWarnings("rawtypes") public static void setOnFlowableAssembly(Function onFlowableAssembly) { if (lockdown) { throw new IllegalStateException("Plugins can't be changed anymore"); } RxJavaPlugins.onFlowableAssembly = onFlowableAssembly; } /** * Sets the specific hook function. * @param onMaybeAssembly the hook function to set, null allowed */ @SuppressWarnings("rawtypes") public static void setOnMaybeAssembly(Function onMaybeAssembly) { if (lockdown) { throw new IllegalStateException("Plugins can't be changed anymore"); } RxJavaPlugins.onMaybeAssembly = onMaybeAssembly; } /** * Sets the specific hook function. * @param onConnectableFlowableAssembly the hook function to set, null allowed */ @SuppressWarnings("rawtypes") public static void setOnConnectableFlowableAssembly(Function onConnectableFlowableAssembly) { if (lockdown) { throw new IllegalStateException("Plugins can't be changed anymore"); } RxJavaPlugins.onConnectableFlowableAssembly = onConnectableFlowableAssembly; } /** * Sets the specific hook function. * @param onFlowableSubscribe the hook function to set, null allowed */ @SuppressWarnings("rawtypes") public static void setOnFlowableSubscribe(BiFunction onFlowableSubscribe) { if (lockdown) { throw new IllegalStateException("Plugins can't be changed anymore"); } RxJavaPlugins.onFlowableSubscribe = onFlowableSubscribe; } /** * Sets the specific hook function. * @param onMaybeSubscribe the hook function to set, null allowed */ @SuppressWarnings("rawtypes") public static void setOnMaybeSubscribe(BiFunction onMaybeSubscribe) { if (lockdown) { throw new IllegalStateException("Plugins can't be changed anymore"); } RxJavaPlugins.onMaybeSubscribe = onMaybeSubscribe; } /** * Sets the specific hook function. * @param onObservableAssembly the hook function to set, null allowed */ @SuppressWarnings("rawtypes") public static void setOnObservableAssembly(Function onObservableAssembly) { if (lockdown) { throw new IllegalStateException("Plugins can't be changed anymore"); } RxJavaPlugins.onObservableAssembly = onObservableAssembly; } /** * Sets the specific hook function. * @param onConnectableObservableAssembly the hook function to set, null allowed */ @SuppressWarnings("rawtypes") public static void setOnConnectableObservableAssembly(Function onConnectableObservableAssembly) { if (lockdown) { throw new IllegalStateException("Plugins can't be changed anymore"); } RxJavaPlugins.onConnectableObservableAssembly = onConnectableObservableAssembly; } /** * Sets the specific hook function. * @param onObservableSubscribe the hook function to set, null allowed */ @SuppressWarnings("rawtypes") public static void setOnObservableSubscribe( BiFunction onObservableSubscribe) { if (lockdown) { throw new IllegalStateException("Plugins can't be changed anymore"); } RxJavaPlugins.onObservableSubscribe = onObservableSubscribe; } /** * Sets the specific hook function. * @param onSingleAssembly the hook function to set, null allowed */ @SuppressWarnings("rawtypes") public static void setOnSingleAssembly(Function onSingleAssembly) { if (lockdown) { throw new IllegalStateException("Plugins can't be changed anymore"); } RxJavaPlugins.onSingleAssembly = onSingleAssembly; } /** * Sets the specific hook function. * @param onSingleSubscribe the hook function to set, null allowed */ @SuppressWarnings("rawtypes") public static void setOnSingleSubscribe(BiFunction onSingleSubscribe) { if (lockdown) { throw new IllegalStateException("Plugins can't be changed anymore"); } RxJavaPlugins.onSingleSubscribe = onSingleSubscribe; } /** * Calls the associated hook function. * @param the value type * @param source the hook's input value * @param subscriber the subscriber * @return the value returned by the hook */ @SuppressWarnings({ "rawtypes", "unchecked" }) public static Subscriber onSubscribe(Flowable source, Subscriber subscriber) { BiFunction f = onFlowableSubscribe; if (f != null) { return apply(f, source, subscriber); } return subscriber; } /** * Calls the associated hook function. * @param the value type * @param source the hook's input value * @param observer the observer * @return the value returned by the hook */ @SuppressWarnings({ "rawtypes", "unchecked" }) public static Observer onSubscribe(Observable source, Observer observer) { BiFunction f = onObservableSubscribe; if (f != null) { return apply(f, source, observer); } return observer; } /** * Calls the associated hook function. * @param the value type * @param source the hook's input value * @param observer the observer * @return the value returned by the hook */ @SuppressWarnings({ "rawtypes", "unchecked" }) public static SingleObserver onSubscribe(Single source, SingleObserver observer) { BiFunction f = onSingleSubscribe; if (f != null) { return apply(f, source, observer); } return observer; } /** * Calls the associated hook function. * @param source the hook's input value * @param observer the observer * @return the value returned by the hook */ public static CompletableObserver onSubscribe(Completable source, CompletableObserver observer) { BiFunction f = onCompletableSubscribe; if (f != null) { return apply(f, source, observer); } return observer; } /** * Calls the associated hook function. * @param the value type * @param source the hook's input value * @param subscriber the subscriber * @return the value returned by the hook */ @SuppressWarnings({ "rawtypes", "unchecked" }) public static MaybeObserver onSubscribe(Maybe source, MaybeObserver subscriber) { BiFunction f = onMaybeSubscribe; if (f != null) { return apply(f, source, subscriber); } return subscriber; } /** * Calls the associated hook function. * @param the value type * @param source the hook's input value * @return the value returned by the hook */ @SuppressWarnings({ "rawtypes", "unchecked" }) public static Maybe onAssembly(Maybe source) { Function f = onMaybeAssembly; if (f != null) { return apply(f, source); } return source; } /** * Calls the associated hook function. * @param the value type * @param source the hook's input value * @return the value returned by the hook */ @SuppressWarnings({ "rawtypes", "unchecked" }) public static Flowable onAssembly(Flowable source) { Function f = onFlowableAssembly; if (f != null) { return apply(f, source); } return source; } /** * Calls the associated hook function. * @param the value type * @param source the hook's input value * @return the value returned by the hook */ @SuppressWarnings({ "rawtypes", "unchecked" }) public static ConnectableFlowable onAssembly(ConnectableFlowable source) { Function f = onConnectableFlowableAssembly; if (f != null) { return apply(f, source); } return source; } /** * Calls the associated hook function. * @param the value type * @param source the hook's input value * @return the value returned by the hook */ @SuppressWarnings({ "rawtypes", "unchecked" }) public static Observable onAssembly(Observable source) { Function f = onObservableAssembly; if (f != null) { return apply(f, source); } return source; } /** * Calls the associated hook function. * @param the value type * @param source the hook's input value * @return the value returned by the hook */ @SuppressWarnings({ "rawtypes", "unchecked" }) public static ConnectableObservable onAssembly(ConnectableObservable source) { Function f = onConnectableObservableAssembly; if (f != null) { return apply(f, source); } return source; } /** * Calls the associated hook function. * @param the value type * @param source the hook's input value * @return the value returned by the hook */ @SuppressWarnings({ "rawtypes", "unchecked" }) public static Single onAssembly(Single source) { Function f = onSingleAssembly; if (f != null) { return apply(f, source); } return source; } /** * Calls the associated hook function. * @param source the hook's input value * @return the value returned by the hook */ public static Completable onAssembly(Completable source) { Function f = onCompletableAssembly; if (f != null) { return apply(f, source); } return source; } /** * Wraps the call to the function in try-catch and propagates thrown * checked exceptions as RuntimeException. * @param the input type * @param the output type * @param f the function to call, not null (not verified) * @param t the parameter value to the function * @return the result of the function call */ static R apply(Function f, T t) { try { return f.apply(t); } catch (Throwable ex) { throw ExceptionHelper.wrapOrThrow(ex); } } /** * Wraps the call to the function in try-catch and propagates thrown * checked exceptions as RuntimeException. * @param the first input type * @param the second input type * @param the output type * @param f the function to call, not null (not verified) * @param t the first parameter value to the function * @param u the second parameter value to the function * @return the result of the function call */ static R apply(BiFunction f, T t, U u) { try { return f.apply(t, u); } catch (Throwable ex) { throw ExceptionHelper.wrapOrThrow(ex); } } /** * Wraps the call to the Scheduler creation callable in try-catch and propagates thrown * checked exceptions as RuntimeException and enforces that result is not null. * @param s the {@link Callable} which returns a {@link Scheduler}, not null (not verified). Cannot return null * @return the result of the callable call, not null * @throws NullPointerException if the callable parameter returns null */ static Scheduler callRequireNonNull(Callable s) { try { return ObjectHelper.requireNonNull(s.call(), "Scheduler Callable result can't be null"); } catch (Throwable ex) { throw ExceptionHelper.wrapOrThrow(ex); } } /** * Wraps the call to the Scheduler creation function in try-catch and propagates thrown * checked exceptions as RuntimeException and enforces that result is not null. * @param f the function to call, not null (not verified). Cannot return null * @param s the parameter value to the function * @return the result of the function call, not null * @throws NullPointerException if the function parameter returns null */ static Scheduler applyRequireNonNull(Function, Scheduler> f, Callable s) { return ObjectHelper.requireNonNull(apply(f, s), "Scheduler Callable result can't be null"); } /** Helper class, no instances. */ private RxJavaPlugins() { throw new IllegalStateException("No instances!"); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy