2 * Copyright (c) 2023 PANTHEON.tech, s.r.o. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.restconf.common.errors;
10 import static java.util.Objects.requireNonNull;
12 import com.google.common.base.Throwables;
13 import com.google.common.util.concurrent.AbstractFuture;
14 import com.google.common.util.concurrent.Futures;
15 import com.google.common.util.concurrent.ListenableFuture;
16 import com.google.common.util.concurrent.MoreExecutors;
17 import java.util.concurrent.ExecutionException;
18 import java.util.function.Function;
19 import org.eclipse.jdt.annotation.NonNull;
22 * A {@link ListenableFuture} specialization, which fails only with {@link RestconfDocumentedException} and does not
23 * produce {@code null} values.
25 * @param <V> resulting value type
27 public sealed class RestconfFuture<V> extends AbstractFuture<@NonNull V> permits SettableRestconfFuture {
32 public static <V> @NonNull RestconfFuture<V> of(final V value) {
33 final var future = new RestconfFuture<V>();
34 future.set(requireNonNull(value));
38 public static <V> @NonNull RestconfFuture<V> failed(final RestconfDocumentedException cause) {
39 final var future = new RestconfFuture<V>();
40 future.setException(requireNonNull(cause));
45 public final boolean cancel(final boolean mayInterruptIfRunning) {
50 * Add a callback to invoke when this future completes, or immediately if it is already complete.
52 * @param callback Callback to invoke
54 * @throws NullPointerException if {@code callback} is {@code null}
56 public final @NonNull RestconfFuture<V> addCallback(final RestconfCallback<? super V> callback) {
57 Futures.addCallback(this, callback, MoreExecutors.directExecutor());
62 * Transform the result of this future using the specified function.
64 * @param <T> Resulting type
65 * @param function Function to apply
66 * @return Transformed future
67 * @throws NullPointerException if {@code function} is {@code null}
69 public final <T> @NonNull RestconfFuture<T> transform(final Function<@NonNull V, @NonNull T> function) {
70 final var fun = requireNonNull(function);
71 final var ret = new RestconfFuture<T>();
72 addCallback(new RestconfCallback<>() {
74 public void onSuccess(final V result) {
75 ret.set(requireNonNull(fun.apply(result)));
79 protected void onFailure(final RestconfDocumentedException failure) {
80 ret.setException(failure);
90 * @throws RestconfDocumentedException if this future failed or this call is interrupted.
92 public final @NonNull V getOrThrow() {
95 } catch (InterruptedException e) {
96 Thread.currentThread().interrupt();
97 throw new RestconfDocumentedException("Interrupted while waiting", e);
98 } catch (ExecutionException e) {
99 Throwables.throwIfInstanceOf(e.getCause(), RestconfDocumentedException.class);
100 throw new RestconfDocumentedException("Operation failed", e);