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

javax0.Exceptional Maven / Gradle / Ivy

The newest version!
package javax0;

import java.util.Objects;
import java.util.Optional;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.Stream;

public class Exceptional {
    private static final Exceptional EMPTY = new Exceptional<>();
    private final Optional optional;

    private Exceptional() {
        this.optional = Optional.empty();
    }

    private Exceptional(Optional optional) {
        this.optional = optional;
    }

    public static  Exceptional empty() {
        //noinspection unchecked
        return (Exceptional) EMPTY;
    }

    public static  Exceptional of(ThrowingSupplier s) {
        final T value;
        try {
            value = s.get();
        } catch (Exception e) {
            return empty();
        }
        return new Exceptional<>(Optional.of(value));
    }

    public static  Exceptional ofNullable(ThrowingSupplier s) {
        try {
            T value = s.get();
            return new Exceptional<>(Optional.ofNullable(value));
        } catch (Exception e) {
            return empty();
        }
    }

    public H get() {
        return optional.get();
    }

    public boolean isPresent() {
        return optional.isPresent();
    }

    public boolean isEmpty() {
        return optional.isEmpty();
    }

    public void ifPresent(Consumer action) {
        optional.ifPresent(action);
    }

    public void ifPresentOrElse(Consumer action, Runnable emptyAction) {
        optional.ifPresentOrElse(action, emptyAction);
    }

    public Exceptional filter(Predicate predicate) {
        return new Exceptional<>(optional.filter(predicate));
    }

    public  Exceptional map(ThrowingFunction mapper) {
        return new Exceptional<>(optional.map(mapper.lame()));
    }

    public  Exceptional flatMap(ThrowingFunction> mapper) {
        Objects.requireNonNull(mapper);
        if (!isPresent()) {
            return empty();
        } else {
            @SuppressWarnings("unchecked")
            Exceptional r = (Exceptional) mapper.lame().apply(optional.get());
            return r == null ? empty() : r;
        }
    }

    public Exceptional or(ThrowingSupplier supplier) {
        Objects.requireNonNull(supplier);
        if (isPresent()) {
            return this;
        } else {
            return Exceptional.of(supplier);
        }
    }

    public Exceptional orNullable(ThrowingSupplier supplier) {
        Objects.requireNonNull(supplier);
        if (isPresent()) {
            return this;
        } else {
            return Exceptional.ofNullable(supplier);
        }
    }

    public Stream stream() {
        return optional.stream();
    }

    public H orElse(H other) {
        return optional.orElse(other);
    }

    public H orElseGet(Supplier supplier) {
        return optional.orElseGet(supplier);
    }

    public H orElseThrow() {
        return optional.orElseThrow();
    }

    public  H orElseThrow(Supplier exceptionSupplier) throws X {
        return optional.orElseThrow(exceptionSupplier);
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }

        if (!(obj instanceof Exceptional)) {
            return false;
        }

        Exceptional other = (Exceptional) obj;
        return Objects.equals(optional, other.optional);
    }

    @Override
    public int hashCode() {
        return Objects.hashCode(optional);
    }

    @Override
    public String toString() {
        return optional.isPresent()
                ? String.format("Exceptional[%s]", optional.get())
                : "Exceptional.empty";
    }

    @FunctionalInterface
    public interface ThrowingSupplier {
        Z get() throws Exception;
    }

    @FunctionalInterface
    public interface ThrowingFunction {
        static  ThrowingFunction identity() {
            return t -> t;
        }

        R apply(T t) throws Exception;

        default Function lame() {
            return (T t) -> {
                try {
                    return apply(t);
                } catch (Exception e) {
                    return null;
                }
            };
        }

        default  ThrowingFunction compose(ThrowingFunction before) {
            Objects.requireNonNull(before);
            return (V v) -> apply(before.apply(v));
        }

        default  ThrowingFunction andThen(ThrowingFunction after) {
            Objects.requireNonNull(after);
            return (T t) -> after.apply(apply(t));
        }
    }
}