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

eu.lunisolar.magma.basics.exceptions.Handler Maven / Gradle / Ivy

There is a newer version: 3.0.0
Show newest version
/*
 * This file is part of "lunisolar-magma".
 *
 * (C) Copyright 2014-2019 Lunisolar (http://lunisolar.eu/).
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package eu.lunisolar.magma.basics.exceptions;

import eu.lunisolar.magma.basics.fluent.Fluent;
import eu.lunisolar.magma.basics.probing.Probe;
import eu.lunisolar.magma.basics.probing.ThrowableProbe;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.annotation.concurrent.NotThreadSafe;
import java.util.function.*;

import static eu.lunisolar.magma.basics.exceptions.Handling.*;
import static java.util.Objects.*;

/**
 * It should never be treated as replacement for TRY-CATCH. It is intended to be a sugar in places where generic exception are being handled.
 */
@SuppressWarnings({"ThrowableResultOfMethodCallIgnored", "unchecked", "unused"})
@NotThreadSafe
public interface Handler, X extends Throwable, Y extends Throwable> extends Fluent, ThrowableProbe {

    static  Handler.The handler(@Nonnull X throwable) {
        return new The(throwable);
    }

    /**
     * Executes instructions, if none of them wil throw or rethrow exception this method will fail with exception that throwable was not handled.
     * Errors will be rethrow immediately.
     *
     * @return There is nothing ever returned - however return value of method signature can be used in statement: _throw handleOrFail(..)_
     */
    static  RuntimeException handleOrFail(
            @Nonnull X throwable, @Nullable HandlingInstructions instructions) throws Y {

        handleErrors(throwable);

        if (instructions != null) {
            handleInstructions(throwable, instructions);
        }

        throwFailure(throwable);
        throw shouldNeverBeenHere();
    }

    /**
     * Executes instructions, if none of them wil throw or rethrow exception this method will rethrow RuntimeExceptions and nest checked exceptions.
     * Errors will be rethrow immediately.
     *
     * @return There is nothing ever returned - however return value of method signature can be used in statement: _throw handleOrFail(..)_
     */
    static  RuntimeException handleOrNest(
            @Nonnull X throwable, @Nullable HandlingInstructions instructions) throws Y {

        handleErrors(throwable);

        if (instructions != null) {
            handleInstructions(throwable, instructions);
        }

        nestCheckedAndThrow(throwable);
        throw shouldNeverBeenHere();
    }

    /**
     * Executes instructions, if none of them wil throw or rethrow exception this method will rethrow original exception regardless it is checked or not.
     * Errors will be rethrow immediately.
     *
     * @return There is nothing ever returned - however return value of method signature can be used in statement: _throw handleOrFail(..)_
     */
    static  RuntimeException handleOrPropagate(
            @Nonnull X throwable, @Nullable HandlingInstructions instructions) throws Y {

        handleErrors(throwable);

        if (instructions != null) {
            handleInstructions(throwable, instructions);
        }

        throw shoveIt(throwable);
    }

    default  SELF throwIf(Class yClass) throws Z {
        X throwable = target();
        if (yClass.isInstance(throwable)) {
            throw yClass.cast(throwable);
        }

        return self();
    }

    default  SELF replaceIf(
            @Nonnull Predicate condition, @Nonnull ExMF factory,
            @Nonnull String newMessage, @Nullable Object... messageParams) throws Z {
        Handling.throwReplacementIf(condition, target(), factory, newMessage, messageParams);
        return self();
    }

    default  SELF wrapIf(@Nonnull Predicate condition, @Nonnull ExWF factory) throws Z {
        Handling.throwWrapperIf(condition, target(), factory);
        return self();
    }

    default  SELF wrapIf(
            @Nonnull Predicate condition, @Nonnull ExWMF factory,
            @Nonnull String newMessage, @Nullable Object... messageParams) throws Z {
        Handling.throwWrapperIf(condition, nonNullTarget(), factory, newMessage, messageParams);
        return self();
    }

    default  SELF replaceWhen(
            @Nonnull Predicate> condition, @Nonnull ExMF factory,
            @Nonnull String newMessage, @Nullable Object... messageParams) throws Z {

        Handling.throwReplacementIf(condition.test(this), factory, newMessage, messageParams);
        return self();
    }

    default  SELF wrapWhen(@Nonnull Predicate> condition, @Nonnull ExWF factory) throws Z {
        Handling.throwWrapperIf(condition.test(this), nonNullTarget(), factory);
        return self();
    }

    default  SELF wrapWhen(
            @Nonnull Predicate> condition, @Nonnull ExWMF factory,
            @Nonnull String newMessage, @Nullable Object... messageParams) throws Z {

        Handling.throwWrapperIf(condition.test(this), nonNullTarget(), factory, newMessage, messageParams);
        return self();
    }

    default SELF nestIfChecked() {
        X throwable = target();
        if (throwable instanceof RuntimeException) {
            return self();
        } else if (throwable instanceof Error) {
            return self();
        } else {
            throw new NestedException(throwable);
        }
    }

    default  void throwReplacement(
            @Nonnull ExMF factory,
            @Nonnull String newMessage, @Nullable Object... messageParams) throws Z {
        throw Handling.throwReplacement(factory, newMessage, messageParams);
    }

    default  void throwWrapper(@Nonnull ExWF factory) throws Z {
        throw Handling.throwWrapper(nonNullTarget(), factory);
    }

    default  void throwWrapper(
            @Nonnull ExWMF factory,
            @Nonnull String newMessage, @Nullable Object... messageParams) throws Z {
        throw Handling.throwWrapper(nonNullTarget(), factory, newMessage, messageParams);
    }

    default void throwFailure() {
        throwFailure(target());
    }

    static void throwFailure(Throwable throwable) {
        throw new ExceptionNotHandled("Exception has not been handled.", throwable);
    }

    default void throwAsIs() throws X {
        throw nonNullTarget();
    }

    default void handleRest() {
        X throwable = target();
        nestCheckedAndThrow(throwable);
    }

    final class The extends Probe.Base implements Handler, X, Y> {
        public The(@Nonnull X throwable) {
            super(requireNonNull(throwable));
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy