001/**
002 * Powerunit - A JDK1.8 test framework
003 * Copyright (C) 2014 Mathieu Boretti.
004 *
005 * This file is part of Powerunit
006 *
007 * Powerunit is free software: you can redistribute it and/or modify
008 * it under the terms of the GNU General Public License as published by
009 * the Free Software Foundation, either version 3 of the License, or
010 * (at your option) any later version.
011 *
012 * Powerunit is distributed in the hope that it will be useful,
013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
015 * GNU General Public License for more details.
016 *
017 * You should have received a copy of the GNU General Public License
018 * along with Powerunit. If not, see <http://www.gnu.org/licenses/>.
019 */
020package ch.powerunit.extensions.exceptions;
021
022import java.util.function.Function;
023
024/**
025 * Root interface to support global operations related to exception handling for
026 * functional interface with primitive return value.
027 *
028 * @param <F>
029 *            the type of the java standard functional interface. For example,
030 *            {@code Predicate<T>}. The same functional interface is also used
031 *            for the lifted and ignored version.
032 */
033public interface PrimitiveReturnExceptionHandlerSupport<F, Z extends PrimitiveReturnExceptionHandlerSupport<F, Z>>
034                extends ExceptionHandlerSupport<F, F, Z> {
035
036        /**
037         * Converts this functional interface to the corresponding one in java and wrap
038         * exception using {@link #exceptionMapper()}.
039         * <p>
040         * Conceptually, the exception encapsulation is done in the following way :
041         *
042         * <pre>
043         * (xxx) -&gt; {
044         *      try {
045         *              return realaction(xxx);
046         *      } catch (Exception e) {
047         *              throw new exceptionMapper().apply(e);
048         *      }
049         * }
050         * </pre>
051         *
052         * @return the unchecked operation
053         * @see #lift()
054         * @see #ignore()
055         */
056        @Override
057        default F uncheck() {
058                return uncheckOrIgnore(true);
059        }
060
061        /**
062         * Converts this functional interface to a lifted one. A lifted version return
063         * the same type as the original one, with a default value.
064         * <p>
065         * The concept is
066         *
067         * <pre>
068         * (xxx) -&gt; {
069         *      try {
070         *              return realaction(xxx);
071         *      } catch (Exception e) {
072         *              return defaultValue;
073         *      }
074         * }
075         * </pre>
076         *
077         * @return the lifted function
078         * @see #uncheck()
079         * @see #ignore()
080         */
081        @Override
082        default F lift() {
083                return ignore();
084        }
085
086        /**
087         * Converts this functional interface to a lifted one. A lifted version return
088         * the same type as the original one, with a default value.
089         * <p>
090         * The concept is
091         *
092         * <pre>
093         * (xxx) -&gt; {
094         *      try {
095         *              return realaction(xxx);
096         *      } catch (Exception e) {
097         *              return defaultValue;
098         *      }
099         * }
100         * </pre>
101         *
102         * @return the lifted function
103         * @see #uncheck()
104         * @see #lift()
105         */
106        @Override
107        default F ignore() {
108                return uncheckOrIgnore(false);
109        }
110
111        /**
112         * Used internally to implements the ignore or uncheck operation.
113         *
114         * @param uncheck
115         *            create unchecked version of the function when true, else ignored
116         *            version.
117         * @return the function
118         */
119        F uncheckOrIgnore(boolean uncheck);
120
121        /**
122         * Internal function to throw an exception in case of error and uncheck mode.
123         *
124         * @param uncheck
125         *            true if exception must be thrown.
126         * @param e
127         *            the current exception
128         * @param exceptionMapper
129         *            the mapper to create exception
130         */
131        static void handleException(boolean uncheck, Exception e, Function<Exception, RuntimeException> exceptionMapper) {
132                if (uncheck) {
133                        throw exceptionMapper.apply(e);
134                }
135        }
136
137}