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

net.javacrumbs.futureconverter.guavacommon.GuavaFutureUtils Maven / Gradle / Ivy

There is a newer version: 5.0.7
Show newest version
/*
 * Copyright © 2014-2019 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.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 net.javacrumbs.futureconverter.guavacommon;

import org.apache.rocketmq.shaded.com.google.common.util.concurrent.FutureCallback;
import org.apache.rocketmq.shaded.com.google.common.util.concurrent.Futures;
import org.apache.rocketmq.shaded.com.google.common.util.concurrent.ListenableFuture;
import org.apache.rocketmq.shaded.com.google.common.util.concurrent.MoreExecutors;
import net.javacrumbs.futureconverter.common.internal.FutureWrapper;
import net.javacrumbs.futureconverter.common.internal.ValueSource;
import net.javacrumbs.futureconverter.common.internal.ValueSourceFuture;

import java.util.concurrent.Executor;
import java.util.function.Consumer;


public class GuavaFutureUtils {
    // *************************************** Converting to ListenableFuture ******************************************

    /**
     * Creates listenable future from ValueSourceFuture. We have to send all Future API calls to ValueSourceFuture.
     */
    public static  ListenableFuture createListenableFuture(ValueSourceFuture valueSourceFuture) {
        if (valueSourceFuture instanceof ListenableFutureBackedValueSourceFuture) {
            return ((ListenableFutureBackedValueSourceFuture) valueSourceFuture).getWrappedFuture();
        } else {
            return new ValueSourceFutureBackedListenableFuture<>(valueSourceFuture);
        }
    }

    public static  ListenableFuture createListenableFuture(ValueSource valueSource) {
        if (valueSource instanceof ListenableFutureBackedValueSourceFuture) {
            return ((ListenableFutureBackedValueSourceFuture) valueSource).getWrappedFuture();
        } else {
            return new ValueSourceBackedListenableFuture<>(valueSource);
        }
    }

    /**
     * If we have ValueSourceFuture, we can use it as the implementation and this class only converts
     * listener registration.
     */
    private static class ValueSourceFutureBackedListenableFuture extends FutureWrapper implements ListenableFuture {
        ValueSourceFutureBackedListenableFuture(ValueSourceFuture valueSourceFuture) {
            super(valueSourceFuture);
        }

        @Override
        protected ValueSourceFuture getWrappedFuture() {
            return (ValueSourceFuture) super.getWrappedFuture();
        }

        @Override
        public void addListener(Runnable listener, Executor executor) {
            getWrappedFuture().addCallbacks(value -> executor.execute(listener), ex -> executor.execute(listener));
        }
    }


    /**
     * If we only get ValueSource we have to create a ValueSourceFuture. Here we wrap Guavas SettableFuture
     * and use it for listener handling and value storage.
     */
    private static class ValueSourceBackedListenableFuture extends FutureWrapper implements ListenableFuture {
        private final ValueSource valueSource;

        private ValueSourceBackedListenableFuture(ValueSource valueSource) {
            super(org.apache.rocketmq.shaded.com.google.common.util.concurrent.SettableFuture.create());
            this.valueSource = valueSource;
            valueSource.addCallbacks(value -> getWrappedFuture().set(value), ex -> getWrappedFuture().setException(ex));
        }

        @Override
        public void addListener(Runnable listener, Executor executor) {
            getWrappedFuture().addListener(listener, executor);
        }

        @Override
        protected org.apache.rocketmq.shaded.com.google.common.util.concurrent.SettableFuture getWrappedFuture() {
            return (org.apache.rocketmq.shaded.com.google.common.util.concurrent.SettableFuture) super.getWrappedFuture();
        }


        @Override
        public boolean cancel(boolean mayInterruptIfRunning) {
            valueSource.cancel(mayInterruptIfRunning);
            return super.cancel(mayInterruptIfRunning);
        }

        private ValueSource getValueSource() {
            return valueSource;
        }
    }


    // *************************************** Converting from ListenableFuture ******************************************
    public static  ValueSourceFuture createValueSourceFuture(ListenableFuture listenableFuture) {
        if (listenableFuture instanceof ValueSourceFutureBackedListenableFuture) {
            return ((ValueSourceFutureBackedListenableFuture) listenableFuture).getWrappedFuture();
        } else {
            return new ListenableFutureBackedValueSourceFuture<>(listenableFuture);
        }
    }

    public static  ValueSource createValueSource(ListenableFuture listenableFuture) {
        if (listenableFuture instanceof ValueSourceBackedListenableFuture) {
            return ((ValueSourceBackedListenableFuture) listenableFuture).getValueSource();
        } else {
            return new ListenableFutureBackedValueSourceFuture<>(listenableFuture);
        }
    }

    /**
     * Wraps ListenableFuture and exposes it as ValueSourceFuture.
     */
    private static class ListenableFutureBackedValueSourceFuture extends ValueSourceFuture {
        private ListenableFutureBackedValueSourceFuture(ListenableFuture wrappedFuture) {
            super(wrappedFuture);
        }

        @Override
        public void addCallbacks(Consumer successCallback, Consumer failureCallback) {
            Futures.addCallback(getWrappedFuture(), new FutureCallback() {
                @Override
                public void onSuccess(T result) {
                    successCallback.accept(result);
                }

                @Override
                public void onFailure(Throwable t) {
                    failureCallback.accept(t);

                }
            }, MoreExecutors.directExecutor());
        }


        @Override
        protected ListenableFuture getWrappedFuture() {
            return (ListenableFuture) super.getWrappedFuture();
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy