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

io.github.oliviercailloux.jaris.exceptions.Unchecker Maven / Gradle / Ivy

package io.github.oliviercailloux.jaris.exceptions;

import static com.google.common.base.Preconditions.checkNotNull;

import com.google.common.base.VerifyException;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.net.URISyntaxException;
import java.util.Comparator;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.BinaryOperator;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;

/**
 * 

* An object able to transform functional interfaces that throw checked exceptions into functional * interfaces that throw only runtime exceptions; and able to invoke functional interfaces that * throw checked exceptions. *

*

* Instances of this class hold a function that transforms any checked exception to an unchecked * exception. *

*

* Instances of this class are immutable. *

*

* Heavily inspired by the durian library. *

* * @param the type of checked exception that this object accepts; must be a checked * exception type (may not extend {@link RuntimeException}), otherwise the wrapper will never * be used (and hence such an object has no use) * @param the type of unchecked exception that this object throws in place of the checked * exception */ public class Unchecker { /** * An object that accepts functional interfaces that throw {@link IOException} instances; and that * will throw {@link UncheckedIOException} instances instead. */ public static final Unchecker IO_UNCHECKER = Unchecker.wrappingWith(UncheckedIOException::new); /** * An object that accepts functional interfaces that throw {@link URISyntaxException} instances; * and that will throw {@link VerifyException} instances instead. */ public static final Unchecker URI_UNCHECKER = Unchecker.wrappingWith(VerifyException::new); /** * Returns an object that will use the given wrapper function to transform checked exceptions to * unchecked ones, if any checked exception happens. * * @param the type of checked exception that the returned instance accepts * @param the type of unchecked exception that the returned instance throws in place of the * checked exception * @param wrapper the function used to transform checked expections to unchecked ones * @return an unchecker instance */ public static Unchecker wrappingWith(Function wrapper) { return new Unchecker<>(wrapper); } private final Function wrapper; private Unchecker(Function wrapper) { this.wrapper = checkNotNull(wrapper); } /** * Calls the given runnable; if it throws a checked exception, throws an unchecked exception * instead, applying the wrapper; if the runnable throws an unchecked exception, the exception is * thrown unchanged. * * @param runnable the runnable to call * @throws Y iff the runnable throws a checked exception (or an unchecked exception of type Y) */ public void call(Throwing.Runnable runnable) throws Y { try { runnable.run(); } catch (RuntimeException e) { throw e; } catch (Exception e) { @SuppressWarnings("unchecked") final X ef = (X) e; throw wrapper.apply(ef); } } /** * Attempts to get and return a result from the given supplier; if the supplier throws a checked * exception, throws an unchecked exception instead, applying the wrapper; if the supplier throws * an unchecked exception, the exception is thrown unchanged. * * @param the type returned by the supplier * @param supplier the supplier to invoke * @return the result obtained from the supplier * @throws Y iff the supplier throws a checked exception (or an unchecked exception of type Y) */ public T getUsing(Throwing.Supplier supplier) throws Y { try { return supplier.get(); } catch (RuntimeException e) { throw e; } catch (Exception e) { @SuppressWarnings("unchecked") final X ef = (X) e; throw wrapper.apply(ef); } } /** * Returns a runnable that delegates to the given runnable, except that any checked exception * thrown by the given runnable is instead thrown by the returned runnable as an unchecked * exception, applying the wrapper to transform it. * * @param runnable the instance that is delegated to * @return a delegating runnable */ public Runnable wrapRunnable(Throwing.Runnable runnable) { return () -> { try { runnable.run(); } catch (RuntimeException e) { throw e; } catch (Exception e) { @SuppressWarnings("unchecked") final X ef = (X) e; throw wrapper.apply(ef); } }; } /** * Returns a supplier that simply delegates to the given supplier, except that any checked * exception thrown by the given supplier is instead thrown by the returned supplier as an * unchecked exception, applying the wrapper to transform it. * * @param the type that the resulting instance will supply * @param supplier the instance that is delegated to * @return a delegating supplier */ public Supplier wrapSupplier(Throwing.Supplier supplier) { return () -> { try { return supplier.get(); } catch (RuntimeException e) { throw e; } catch (Exception e) { @SuppressWarnings("unchecked") final X ef = (X) e; throw wrapper.apply(ef); } }; } /** * Returns a comparator that simply delegates to the given comparator, except that any checked * exception thrown by the given comparator is instead thrown by the returned comparator as an * unchecked exception, applying the wrapper to transform it. * * @param the type of objects that the returned comparator may compare * @param comparator the instance that is delegated to * @return a delegating comparator */ public Comparator wrapComparator(Throwing.Comparator comparator) { return (t1, t2) -> { try { return comparator.compare(t1, t2); } catch (RuntimeException e) { throw e; } catch (Exception e) { @SuppressWarnings("unchecked") final X ef = (X) e; throw wrapper.apply(ef); } }; } /** * Returns a consumer that simply delegates to the given consumer, except that any checked * exception thrown by the given consumer is instead thrown by the returned consumer as an * unchecked exception, applying the wrapper to transform it. * * @param the type of objects that the resulting instance may consume * @param consumer the instance that is delegated to * @return a delegating consumer */ public Consumer wrapConsumer(Throwing.Consumer consumer) { return t -> { try { consumer.accept(t); } catch (RuntimeException e) { throw e; } catch (Exception e) { @SuppressWarnings("unchecked") final X ef = (X) e; throw wrapper.apply(ef); } }; } /** * Returns a bi consumer that simply delegates to the given bi consumer, except that any checked * exception thrown by the given consumer is instead thrown by the returned consumer as an * unchecked exception, applying the wrapper to transform it. * * @param the “left” type of objects that the resulting instance may consume * @param the “right” type of objects that the resulting instance may consume * @param consumer the instance that is delegated to * @return a delegating bi consumer */ public BiConsumer wrapBiConsumer(Throwing.BiConsumer consumer) { return (t, u) -> { try { consumer.accept(t, u); } catch (RuntimeException e) { throw e; } catch (Exception e) { @SuppressWarnings("unchecked") final X ef = (X) e; throw wrapper.apply(ef); } }; } /** * Returns a function that simply delegates to the given function, except that any checked * exception thrown by the given function is instead thrown by the returned function as an * unchecked exception, applying the wrapper to transform it. * * @param the type of objects that the resulting function accepts * @param the type of objects that the resulting function produces * @param function the instance that is delegated to * @return a delegating function */ public Function wrapFunction(Throwing.Function function) { return arg -> { try { return function.apply(arg); } catch (RuntimeException e) { throw e; } catch (Exception e) { @SuppressWarnings("unchecked") final X ef = (X) e; throw wrapper.apply(ef); } }; } /** * Returns a bi function that simply delegates to the given bi function, except that any checked * exception thrown by the given bi function is instead thrown by the returned bi function as an * unchecked exception, applying the wrapper to transform it. * * @param the “left” type of objects that the resulting function accepts * @param the “right” type of objects that the resulting function accepts * @param the type of objects that the resulting function produces * @param function the instance that is delegated to * @return a delegating bi function */ public BiFunction wrapBiFunction( Throwing.BiFunction function) { return (t, u) -> { try { return function.apply(t, u); } catch (RuntimeException e) { throw e; } catch (Exception e) { @SuppressWarnings("unchecked") final X ef = (X) e; throw wrapper.apply(ef); } }; } /** * Returns a binary operator that simply delegates to the given binary operator, except that any * checked exception thrown by the given binary operator is instead thrown by the returned binary * operator as an unchecked exception, applying the wrapper to transform it. * * @param the type of objects that the resulting binary operator works on * @param operator the instance that is delegated to * @return a delegating binary operator */ public BinaryOperator wrapBinaryOperator(Throwing.BinaryOperator operator) { return (t, u) -> { try { return operator.apply(t, u); } catch (RuntimeException e) { throw e; } catch (Exception e) { @SuppressWarnings("unchecked") final X ef = (X) e; throw wrapper.apply(ef); } }; } /** * Returns a predicate that simply delegates to the given predicate, except that any checked * exception thrown by the given predicate is instead thrown by the returned predicate as an * unchecked exception, applying the wrapper to transform it. * * @param the type of objects that the resulting predicate accepts * @param predicate the instance that is delegated to * @return a delegating predicate */ public Predicate wrapPredicate(Throwing.Predicate predicate) { return (arg) -> { try { return predicate.test(arg); } catch (RuntimeException e) { throw e; } catch (Exception e) { @SuppressWarnings("unchecked") final X ef = (X) e; throw wrapper.apply(ef); } }; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy