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

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

Go to download

Contains variants of basic functional constructs that can throw checked exceptions, tools for converting them to their more manageable counterparts, exception types useful for this, and some tools for exception handling.

There is a newer version: 1.20.0
Show newest version
package de.team33.patterns.exceptional.dione;

import java.util.function.Function;
import java.util.function.Predicate;

/**
 * A tool that supports a revision and handling of an exception.
 * 

* In general, there is little need for a special tool for differentiated handling of exceptions. * The possibilities of Java’s own language elements (try-catch) are compact, expressive and efficient. *

* The situation is different if the {@linkplain Throwable#getCause() cause of an exception} is to be handled * in a differentiated manner. This often results in extensive and sometimes difficult to read code. * In any case, the regular code takes a back seat. *

* For example, in order not to have to deal with it all the time, we would like to temporarily wrap * checked exceptions into unchecked exceptions. However, we would then like to bring the * checked exceptions back to the fore in order to enforce a structured approach. A {@link Revision} * supports the latter, as the following code example shows: *

 *         try {
 *             return somethingThatMayCauseAWrappedException();
 *         } catch (final WrappedException caught) {
 *             throw Revision.of(caught.getCause())
 *                           .reThrow(IOException.class)
 *                           .reThrow(SQLException.class)
 *                           .reThrow(URISyntaxException.class)
 *                           .close(ExpectationException::new);
 *         }
 * 
* * @see #of(Throwable) * @see #reThrow(Class) * @see #close(Function) */ public final class Revision { private final T subject; private Revision(final T subject) { this.subject = subject; } /** * Returns a new instance to review and handle a given exception. * * @param subject the exception to be handled * @param the type of the given exception */ public static Revision of(final T subject) { return new Revision<>(subject); } /** * Applies a given {@link Function mapping} to the {@linkplain #of(Throwable) associated exception} if the given * {@link Predicate condition} applies and throws the result, otherwise this {@link Revision} will be returned. * * @param condition A {@link Predicate} that is used to check the {@linkplain #of(Throwable) associated exception} * for applicability. * @param mapping A {@link Function} that converts the {@linkplain #of(Throwable) associated 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 {@link Revision}, which can be continued if no exception has been thrown. * @throws X The converted exception, if present. */ public final Revision throwIf(final Predicate condition, final Function mapping) throws X { return throwIf(condition, mapping, this); } /** * Applies a given {@link Function mapping} to the {@linkplain #of(Throwable) associated exception} if the given * {@link Predicate condition} applies and throws the result, otherwise a given result will be returned. * * @param condition A {@link Predicate} that is used to check the {@linkplain #of(Throwable) associated exception} * for applicability. * @param mapping A {@link Function} that converts the {@linkplain #of(Throwable) associated exception} to a * specific type of exception to be thrown at that point. * @param result A predefined regular result in case the condition is not true. * @param The result type in case of a regular result. * @param The exception type that is intended as a result of the given mapping and that is thrown by this * method, if applicable. * @return The predefined result. * @throws X The converted exception, if present. */ public final R throwIf(final Predicate condition, final Function mapping, final R result) throws X { if (condition.test(subject)) { throw mapping.apply(subject); } else { return result; } } /** * Rethrows the {@linkplain #of(Throwable) associated exception} if it matches the given exception type. * Otherwise, this {@link Revision} will be returned. Example: *
     *         try {
     *             return somethingThatMayCauseAWrappedException();
     *         } catch (final WrappedException caught) {
     *             throw Revision.of(caught.getCause())
     *                           .reThrow(IOException.class)
     *                           .reThrow(SQLException.class)
     *                           .reThrow(URISyntaxException.class)
     *                           .close(ExpectationException::new);
     *         }
     * 
* * @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 {@link Revision}, which can be continued if no exception has been thrown. * @throws X the {@linkplain #of(Throwable) associated exception}, cast to the expected type, if applicable. * @see #of(Throwable) * @see #close(Function) */ public final Revision reThrow(final Class xClass) throws X { return reThrow(xClass, this); } /** * Rethrows the {@linkplain #of(Throwable) associated exception} if it matches the given exception type, * otherwise a given result will be returned. * * @param xClass The {@link Class} that represents the type of exception that is expected. * @param result A predefined regular result in case the exception is not of that type. * @param The result type in case of a regular result. * @param The type of exception that is expected and, if applicable, thrown by this method. * @return The predefined result. * @throws X the {@linkplain #of(Throwable) associated exception}, cast to the expected type, if applicable. */ public final R reThrow(final Class xClass, final R result) throws X { return throwIf(xClass::isInstance, xClass::cast, result); } /** * Completes this revision, applies a given {@link Function mapping} to the * {@linkplain #of(Throwable) associated exception}, and returns its result. */ public final R close(final Function mapping) { return mapping.apply(subject); } /** * Completes this revision and returns the {@linkplain #of(Throwable) associated exception} unchanged. */ public final T close() { return subject; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy