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

com.hivemq.client.internal.rx.operators.FlowableWithSingleMap Maven / Gradle / Ivy

Go to download

HiveMQ MQTT Client is an MQTT 5.0 and MQTT 3.1.1 compatible and feature-rich high-performance Java client library with different API flavours and backpressure support

The newest version!
/*
 * Copyright 2018-present HiveMQ and the HiveMQ Community
 *
 * Licensed under the Apache License, Version 2.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 com.hivemq.client.internal.rx.operators;

import com.hivemq.client.internal.rx.WithSingleConditionalSubscriber;
import com.hivemq.client.internal.util.Checks;
import com.hivemq.client.rx.FlowableWithSingle;
import com.hivemq.client.rx.FlowableWithSingleSubscriber;
import com.hivemq.client.rx.reactivestreams.WithSingleSubscriber;
import io.reactivex.exceptions.Exceptions;
import io.reactivex.functions.Function;
import io.reactivex.internal.fuseable.ConditionalSubscriber;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.reactivestreams.Subscriber;
import org.reactivestreams.Subscription;

/**
 * @author Silvio Giebl
 */
public class FlowableWithSingleMap extends FlowableWithSingleOperator {

    public static  @NotNull FlowableWithSingleMap mapBoth(
            final @NotNull FlowableWithSingle source,
            final @Nullable Function flowableMapper,
            final @NotNull Function singleMapper) {

        return new FlowableWithSingleMap<>(source, flowableMapper, singleMapper);
    }

    public static  @NotNull FlowableWithSingleMap mapSingle(
            final @NotNull FlowableWithSingle source,
            final @NotNull Function singleMapper) {

        return new FlowableWithSingleMap<>(source, null, singleMapper);
    }

    private final @Nullable Function flowableMapper;
    private final @NotNull Function singleMapper;

    private FlowableWithSingleMap(
            final @NotNull FlowableWithSingle source,
            final @Nullable Function flowableMapper,
            final @NotNull Function singleMapper) {

        super(source);
        this.flowableMapper = flowableMapper;
        this.singleMapper = singleMapper;
    }

    @Override
    protected void subscribeActual(final @NotNull Subscriber subscriber) {
        if (subscriber instanceof ConditionalSubscriber) {
            //noinspection unchecked
            final ConditionalSubscriber conditional = (ConditionalSubscriber) subscriber;
            source.subscribeBoth(new MapSubscriber.Conditional<>(conditional, flowableMapper, singleMapper));
        } else {
            source.subscribeBoth(new MapSubscriber<>(subscriber, flowableMapper, singleMapper));
        }
    }

    @Override
    protected void subscribeBothActual(final @NotNull WithSingleSubscriber subscriber) {
        if (subscriber instanceof WithSingleConditionalSubscriber) {
            //noinspection unchecked
            final WithSingleConditionalSubscriber conditional =
                    (WithSingleConditionalSubscriber) subscriber;
            source.subscribeBoth(new WithSingleMapSubscriber.Conditional<>(conditional, flowableMapper, singleMapper));
        } else {
            source.subscribeBoth(new WithSingleMapSubscriber<>(subscriber, flowableMapper, singleMapper));
        }
    }

    private static class MapSubscriber>
            implements FlowableWithSingleSubscriber, Subscription {

        final @NotNull T subscriber;
        final @Nullable Function flowableMapper;
        private final @NotNull Function singleMapper;
        private @Nullable Subscription subscription;

        MapSubscriber(
                final @NotNull T subscriber,
                final @Nullable Function flowableMapper,
                final @NotNull Function singleMapper) {

            this.subscriber = subscriber;
            this.flowableMapper = flowableMapper;
            this.singleMapper = singleMapper;
        }

        @Override
        public void onSubscribe(final @NotNull Subscription subscription) {
            this.subscription = subscription;
            subscriber.onSubscribe(this);
        }

        @Override
        public void onSingle(final @NotNull S s) {
            final SM sm;
            try {
                sm = Checks.notNull(singleMapper.apply(s), "Mapped single value");
            } catch (final Throwable throwable) {
                fail(throwable);
                return;
            }
            onSingleMapped(sm);
        }

        void onSingleMapped(final @NotNull SM sm) {}

        @Override
        public void onNext(final @NotNull F f) {
            if (flowableMapper == null) {
                //noinspection unchecked
                subscriber.onNext((FM) f);
            } else {
                final FM fm;
                try {
                    fm = Checks.notNull(flowableMapper.apply(f), "Mapped value");
                } catch (final Throwable throwable) {
                    fail(throwable);
                    return;
                }
                subscriber.onNext(fm);
            }
        }

        void fail(final @NotNull Throwable throwable) {
            assert subscription != null;
            Exceptions.throwIfFatal(throwable);
            subscription.cancel();
            onError(throwable);
        }

        @Override
        public void onError(final @NotNull Throwable error) {
            subscriber.onError(error);
        }

        @Override
        public void onComplete() {
            subscriber.onComplete();
        }

        @Override
        public void request(final long n) {
            assert subscription != null;
            subscription.request(n);
        }

        @Override
        public void cancel() {
            assert subscription != null;
            subscription.cancel();
        }

        private static class Conditional>
                extends MapSubscriber implements WithSingleConditionalSubscriber {

            Conditional(
                    final @NotNull T subscriber,
                    final @Nullable Function flowableMapper,
                    final @NotNull Function singleMapper) {

                super(subscriber, flowableMapper, singleMapper);
            }

            @Override
            public boolean tryOnNext(final @NotNull F f) {
                if (flowableMapper == null) {
                    //noinspection unchecked
                    return subscriber.tryOnNext((FM) f);
                } else {
                    final FM fm;
                    try {
                        fm = Checks.notNull(flowableMapper.apply(f), "Mapped value");
                    } catch (final Throwable throwable) {
                        fail(throwable);
                        return false;
                    }
                    return subscriber.tryOnNext(fm);
                }
            }
        }
    }

    private static class WithSingleMapSubscriber
            extends MapSubscriber> {

        WithSingleMapSubscriber(
                final @NotNull WithSingleSubscriber subscriber,
                final @Nullable Function flowableMapper,
                final @NotNull Function singleMapper) {

            super(subscriber, flowableMapper, singleMapper);
        }

        @Override
        void onSingleMapped(final @NotNull SM sm) {
            subscriber.onSingle(sm);
        }

        private static class Conditional extends
                MapSubscriber.Conditional> {

            Conditional(
                    final @NotNull WithSingleConditionalSubscriber subscriber,
                    final @Nullable Function flowableMapper,
                    final @NotNull Function singleMapper) {

                super(subscriber, flowableMapper, singleMapper);
            }

            @Override
            void onSingleMapped(final @NotNull SM sm) {
                subscriber.onSingle(sm);
            }
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy