import static java.util.Objects.requireNonNull;
import com.google.common.annotations.Beta;
+import com.google.common.util.concurrent.FluentFuture;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.SettableFuture;
+import java.util.concurrent.CompletableFuture;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
-import javax.annotation.concurrent.ThreadSafe;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
*/
@Beta
@NonNullByDefault
-@ThreadSafe
-public final class CheckedValue<T, E extends Exception> extends Variant<T, E> {
- private CheckedValue(final T value) {
+public class CheckedValue<T, E extends Exception> extends Either<T, E> {
+ protected CheckedValue(final T value) {
super(value);
}
- private CheckedValue(final E violation, final @Nullable Void dummy) {
+ protected CheckedValue(final E violation, final @Nullable Void dummy) {
super(violation, dummy);
}
* Create a new instance containing an {@link Exception}.
*
* @param cause Throwable
+ * @param <T> Value type
+ * @param <E> Exception type
* @return A new instance
* @throws NullPointerException if {@code cause} is null
*/
* Create a new instance containing specified value.
*
* @param value Value
+ * @param <T> Value type
+ * @param <E> Exception type
* @return A new instance
* @throws NullPointerException if {@code value} is null
*/
* Convert a Variant into a {@link CheckedValue}, converting the second value into an exception.
*
* @param variant Input variant
+ * @param mapper Mapping function from second alternative to an exception
+ * @param <T> First alternative type
+ * @param <U> Second alternative type
+ * @param <E> Exception type
* @return Resulting {@link CheckedValue}
*/
- public static <T, U, E extends Exception> CheckedValue<T, E> ofVariant(final Variant<T, U> variant,
+ public static <T, U, E extends Exception> CheckedValue<T, E> ofVariant(final Either<T, U> variant,
final Function<U, E> mapper) {
requireNonNull(mapper);
- return variant.isFirst() ? new CheckedValue(variant.first())
- : new CheckedValue(mapper.apply(variant.second()), null);
+ return variant.isFirst() ? new CheckedValue<>(variant.first())
+ : new CheckedValue<>(mapper.apply(variant.second()), null);
}
/**
* @return Contained value
* @throws IllegalStateException if an error string is present.
*/
- public T get() {
+ public final T get() {
if (isFirst()) {
return first();
}
* string.
* @throws IllegalStateException if a value is present.
*/
- public E getException() {
+ public final E getException() {
if (isSecond()) {
return second();
}
*
* @return True if a value is present.
*/
- public boolean isPresent() {
+ public final boolean isPresent() {
return isFirst();
}
* @param consumer block to be executed if a value is present
* @throws NullPointerException if value is present and {@code consumer} is null
*/
- public void ifPresent(final Consumer<? super T> consumer) {
+ public final void ifPresent(final Consumer<? super T> consumer) {
if (isFirst()) {
consumer.accept(first());
}
@SuppressWarnings("unchecked")
public <X extends Exception> CheckedValue<T, X> mapException(final Function<? super E, X> mapper) {
requireNonNull(mapper);
- if (isFirst()) {
- return (CheckedValue<T, X>) this;
- }
- return new CheckedValue<>(mapper.apply(second()), null);
+ return isFirst() ? (CheckedValue<T, X>) this : new CheckedValue<>(mapper.apply(second()), null);
}
-
@SuppressWarnings("unchecked")
public <U> CheckedValue<U, E> flatMap(final Function<? super T, CheckedValue<U, E>> mapper) {
requireNonNull(mapper);
* @param other Replacement value
* @return Contained value or {code other}
*/
- public T orElse(final T other) {
+ public final T orElse(final T other) {
return isFirst() ? first() : other;
}
* @return Contained value or supplier's value
* @throws NullPointerException if {@code supplier} is null
*/
- public T orElseGet(final Supplier<T> supplier) {
+ public final T orElseGet(final Supplier<T> supplier) {
requireNonNull(supplier);
return isFirst() ? first() : supplier.get();
}
- public <X extends Throwable> T orElseThrow() throws E {
+ /**
+ * Return contained value if present or throw the exception alternative.
+ *
+ * @return Contained value
+ * @throws E When there is no contained value
+ */
+ public final T orElseThrow() throws E {
if (isFirst()) {
return first();
}
throw second();
}
- public <X extends Throwable> T orElseThrow(final Function<E, X> exceptionMapper) throws X {
+ /**
+ * Return contained value if present or throw the exception alternative mapped through provided mapper.
+ *
+ * @param exceptionMapper Exception mapper
+ * @param <X> Thrown exception type
+ * @return Contained value
+ * @throws NullPointerException if {@code exceptionMapper} is null
+ * @throws X When there is no contained value
+ */
+ public final <X extends Throwable> T orElseThrow(final Function<E, X> exceptionMapper) throws X {
requireNonNull(exceptionMapper);
if (isFirst()) {
return first();
throw exceptionMapper.apply(second());
}
- public <X extends Throwable> T orElseThrow(final Supplier<X> supplier) throws X {
+ /**
+ * Return contained value if present or throw the exception supplied by supplier.
+ *
+ * @param supplier Exception supplier
+ * @param <X> Thrown exception type
+ * @return Contained value
+ * @throws NullPointerException if {@code exceptionMapper} is null
+ * @throws X When there is no contained value
+ */
+ public final <X extends Throwable> T orElseThrow(final Supplier<X> supplier) throws X {
requireNonNull(supplier);
if (isFirst()) {
return first();
}
throw supplier.get();
}
+
+ /**
+ * Complete target {@link CompletableFuture} either successfully or exceptionally based on the state of this object.
+ *
+ * @param future Future to complete
+ * @return True if this call has transitioned the future to a completed state, false otherwise.
+ * @throws NullPointerException if {code future} is null
+ */
+ public final boolean completeFuture(final CompletableFuture<T> future) {
+ return isFirst() ? future.complete(first()) : future.completeExceptionally(second());
+ }
+
+ /**
+ * Complete target {@link SettableFuture} either successfully or exceptionally based on the state of this object.
+ *
+ * @param future Future to complete
+ * @return True if this call has transitioned the future to a completed state, false otherwise.
+ * @throws NullPointerException if {code future} is null
+ */
+ public final boolean completeFuture(final SettableFuture<T> future) {
+ return isFirst() ? future.set(first()) : future.setException(second());
+ }
+
+ /**
+ * Transform this object into an immediately-completed {@link CompletableFuture}. The future will be successful
+ * if this object has a contained value or unsuccessful if this objects contains an exception.
+ *
+ * @return A {@link CompletableFuture}.
+ */
+ public final CompletableFuture<T> toCompletableFuture() {
+ return isFirst() ? CompletableFuture.completedFuture(first()) : CompletableFuture.failedFuture(second());
+ }
+
+ /**
+ * Transform this object into an immediately-completed {@link FluentFuture}. The future will be successful
+ * if this object has a contained value or unsuccessful if this objects contains an exception.
+ *
+ * @return A {@link FluentFuture}.
+ */
+ public final FluentFuture<T> toFluentFuture() {
+ return FluentFuture.from(isFirst() ? Futures.immediateFuture(first())
+ : Futures.immediateFailedFuture(second()));
+ }
}