2 * Copyright (c) 2018 Pantheon Technologies, 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.yangtools.concepts;
10 import static java.util.Objects.requireNonNull;
12 import com.google.common.annotations.Beta;
13 import java.util.function.Consumer;
14 import java.util.function.Function;
15 import java.util.function.Supplier;
16 import javax.annotation.concurrent.ThreadSafe;
17 import org.eclipse.jdt.annotation.NonNullByDefault;
18 import org.eclipse.jdt.annotation.Nullable;
21 * Utility holder similar to {@link java.util.Optional}, except the empty case contains an Exception, which should be
22 * reported, for example via throwing it. It provides analogous methods such as {@link #isPresent()},
23 * {@link #ifPresent(Consumer)}, {@link #get()}, {@link #orElse(Object)}, {@link #orElseGet(Supplier)},
24 * {@link #orElseThrow(Function)}.
26 * @param <T> Value type
27 * @param <E> Exception type
28 * @author Robert Varga
33 public final class CheckedValue<T, E extends Exception> extends Variant<T, E> {
34 private CheckedValue(final T value) {
38 private CheckedValue(final E violation, final @Nullable Void dummy) {
39 super(violation, dummy);
43 * Create a new instance containing an {@link Exception}.
45 * @param cause Throwable
46 * @return A new instance
47 * @throws NullPointerException if {@code cause} is null
49 public static <T, E extends Exception> CheckedValue<T, E> ofException(final E cause) {
50 return new CheckedValue<>(cause, null);
54 * Create a new instance containing specified value.
57 * @return A new instance
58 * @throws NullPointerException if {@code value} is null
60 public static <T, E extends Exception> CheckedValue<T, E> ofValue(final T value) {
61 return new CheckedValue<>(value);
65 * Convert a Variant into a {@link CheckedValue}, converting the second value into an exception.
67 * @param variant Input variant
68 * @return Resulting {@link CheckedValue}
70 public static <T, U, E extends Exception> CheckedValue<T, E> ofVariant(final Variant<T, U> variant,
71 final Function<U, E> mapper) {
72 requireNonNull(mapper);
73 return variant.isFirst() ? new CheckedValue(variant.first())
74 : new CheckedValue(mapper.apply(variant.second()), null);
78 * Return the contained value if {@link #isPresent()} would return true, throws {@link IllegalStateException}
81 * @return Contained value
82 * @throws IllegalStateException if an error string is present.
88 throw new IllegalStateException("Value is not present", second());
92 * Return the contained error string if {@link #isPresent()} would return false, throws
93 * {@link IllegalStateException} otherwise.
95 * @return Throwable which was used to instantiate this object, or absent if it was instantiated using an error
97 * @throws IllegalStateException if a value is present.
99 public E getException() {
103 throw new IllegalStateException("Value " + first() + " is present");
107 * Return true if a value is present.
109 * @return True if a value is present.
111 public boolean isPresent() {
116 * If a value is present, invoke the specified consumer with the value, otherwise do nothing.
118 * @param consumer block to be executed if a value is present
119 * @throws NullPointerException if value is present and {@code consumer} is null
121 public void ifPresent(final Consumer<? super T> consumer) {
123 consumer.accept(first());
127 @SuppressWarnings("unchecked")
128 public <U> CheckedValue<U, E> map(final Function<? super T, U> mapper) {
129 requireNonNull(mapper);
130 return isFirst() ? new CheckedValue<>(mapper.apply(first())) : (CheckedValue<U, E>) this;
133 @SuppressWarnings("unchecked")
134 public <X extends Exception> CheckedValue<T, X> mapException(final Function<? super E, X> mapper) {
135 requireNonNull(mapper);
137 return (CheckedValue<T, X>) this;
139 return new CheckedValue<>(mapper.apply(second()), null);
143 @SuppressWarnings("unchecked")
144 public <U> CheckedValue<U, E> flatMap(final Function<? super T, CheckedValue<U, E>> mapper) {
145 requireNonNull(mapper);
146 return isFirst() ? requireNonNull(mapper.apply(first())) : (CheckedValue<U, E>) this;
150 * Return contained value if present, otherwise return supplied value.
152 * @param other Replacement value
153 * @return Contained value or {code other}
155 public T orElse(final T other) {
156 return isFirst() ? first() : other;
160 * Return contained value if present, otherwise return the value produced by a supplier.
162 * @param supplier Replacement value supplier
163 * @return Contained value or supplier's value
164 * @throws NullPointerException if {@code supplier} is null
166 public T orElseGet(final Supplier<T> supplier) {
167 requireNonNull(supplier);
168 return isFirst() ? first() : supplier.get();
171 public <X extends Throwable> T orElseThrow() throws E {
178 public <X extends Throwable> T orElseThrow(final Function<E, X> exceptionMapper) throws X {
179 requireNonNull(exceptionMapper);
183 throw exceptionMapper.apply(second());
186 public <X extends Throwable> T orElseThrow(final Supplier<X> supplier) throws X {
187 requireNonNull(supplier);
191 throw supplier.get();