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

org.opendaylight.restconf.common.errors.RestconfFuture Maven / Gradle / Ivy

/*
 * Copyright (c) 2023 PANTHEON.tech, s.r.o. and others.  All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
 * and is available at http://www.eclipse.org/legal/epl-v10.html
 */
package org.opendaylight.restconf.common.errors;

import static java.util.Objects.requireNonNull;

import com.google.common.base.Throwables;
import com.google.common.util.concurrent.AbstractFuture;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.MoreExecutors;
import java.util.concurrent.ExecutionException;
import java.util.function.Function;
import org.eclipse.jdt.annotation.NonNull;

/**
 * A {@link ListenableFuture} specialization, which fails only with {@link RestconfDocumentedException} and does not
 * produce {@code null} values.
 *
 * @param  resulting value type
 */
public sealed class RestconfFuture extends AbstractFuture<@NonNull V> permits SettableRestconfFuture {
    RestconfFuture() {
        // Hidden on purpose
    }

    public static  @NonNull RestconfFuture of(final V value) {
        final var future = new RestconfFuture();
        future.set(requireNonNull(value));
        return future;
    }

    public static  @NonNull RestconfFuture failed(final RestconfDocumentedException cause) {
        final var future = new RestconfFuture();
        future.setException(requireNonNull(cause));
        return future;
    }

    @Override
    public final boolean cancel(final boolean mayInterruptIfRunning) {
        return false;
    }

    /**
     * Add a callback to invoke when this future completes, or immediately if it is already complete.
     *
     * @param callback Callback to invoke
     * @return This future
     * @throws NullPointerException if {@code callback} is {@code null}
     */
    public final @NonNull RestconfFuture addCallback(final RestconfCallback callback) {
        Futures.addCallback(this, callback, MoreExecutors.directExecutor());
        return this;
    }

    /**
     * Transform the result of this future using the specified function.
     *
     * @param  Resulting type
     * @param function Function to apply
     * @return Transformed future
     * @throws NullPointerException if {@code function} is {@code null}
     */
    public final  @NonNull RestconfFuture transform(final Function<@NonNull V, @NonNull T> function) {
        final var fun = requireNonNull(function);
        final var ret = new RestconfFuture();
        addCallback(new RestconfCallback<>() {
            @Override
            public void onSuccess(final V result) {
                ret.set(requireNonNull(fun.apply(result)));
            }

            @Override
            protected void onFailure(final RestconfDocumentedException failure) {
                ret.setException(failure);
            }
        });
        return ret;
    }

    /**
     * Get the result.
     *
     * @return The result
     * @throws RestconfDocumentedException if this future failed or this call is interrupted.
     */
    public final @NonNull V getOrThrow() {
        try {
            return get();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            throw new RestconfDocumentedException("Interrupted while waiting", e);
        } catch (ExecutionException e) {
            Throwables.throwIfInstanceOf(e.getCause(), RestconfDocumentedException.class);
            throw new RestconfDocumentedException("Operation failed", e);
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy