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

de.team33.patterns.exceptional.dione.WrappedException Maven / Gradle / Ivy

package de.team33.patterns.exceptional.dione;

import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/**
 * An unchecked exception dedicated to (temporarily) wrap checked exceptions.
 */
public class WrappedException extends RuntimeException {

    private static final String MISSING_EXCEPTION = "Missing: an exception to be wrapped in a " + WrappedException.class.getSimpleName();

    private WrappedException(final Throwable cause, final String message) {
        super(message, cause);
    }

    /**
     * Initializes a new instance with the given message and cause.
     */
    public WrappedException(final String message, final Throwable cause) {
        this(toCause(cause), toMessage(message, cause));
    }

    private Revision revision() {
        return Revision.of(getCause());
    }

    /**
     * Initializes a new instance with the given cause and its {@link Throwable#getMessage() message}.
     */
    public WrappedException(final Throwable cause) {
        this(toCause(cause), toMessage(null, cause));
    }

    private static String toMessage(final String message, final Throwable cause) {
        final boolean messageIsMissing = (null == message);
        final boolean causeIsMissing = (null == cause);
        final List result = Arrays.asList(
                (messageIsMissing || causeIsMissing) ? "Wrapped:" : null,
                causeIsMissing ? "nothing!?" : null,
                (causeIsMissing && !messageIsMissing) ? "Message:" : null,
                (messageIsMissing && !causeIsMissing) ? toMessage(cause) : null,
                message);
        return result.stream()
                     .filter(Objects::nonNull)
                     .collect(Collectors.joining(" "));
    }

    private static String toMessage(final Throwable cause) {
        return Optional.ofNullable(cause.getMessage()).orElseGet(() -> cause.getClass().getCanonicalName());
    }

    private static Throwable toCause(final Throwable cause) {
        return (null != cause) ? cause : new IllegalStateException(MISSING_EXCEPTION);
    }

    /**
     * Applies a given {@link Function mapping} to the {@linkplain #getCause() cause of this exception} if the given
     * {@link Predicate condition} applies and throws the result, otherwise this exception will be returned.
     *
     * @param condition A {@link Predicate} that is used to check the {@linkplain #getCause() cause of this exception}
     *                  for applicability.
     * @param mapping   A {@link Function} that converts the {@linkplain #getCause() cause of this exception} to a
     *                  specific type of exception to be thrown at that point.
     * @param        The exception type that is intended as a result of the given mapping and that is thrown by this
     *                  method, if applicable.
     * @return this exception.
     * @throws X The mapped exception, if present.
     */
    public final 
    WrappedException reThrowCauseIf(final Predicate condition,
                                    final Function mapping) throws X {
        return revision().throwIf(condition, mapping, this);
    }

    /**
     * Rethrows the {@linkplain #getCause() cause of this exception} if it matches the given exception type,
     * otherwise this exception will be returned.
     *
     * @param xClass The {@link Class} that represents the type of exception that is expected.
     * @param     The type of exception that is expected and, if applicable, thrown by this method.
     * @return this exception.
     * @throws X the {@linkplain #getCause() cause of this exception}, cast to the given type, if applicable.
     */
    public final  WrappedException reThrowCauseAs(final Class xClass) throws X {
        return revision().reThrow(xClass, this);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy