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 static ch.powerunit.extensions.exceptions.Constants.verifyExceptionMapper;
023import static ch.powerunit.extensions.exceptions.Constants.verifyFunction;
024
025import java.util.function.Function;
026import java.util.function.IntToLongFunction;
027import java.util.function.Supplier;
028
029/**
030 * Represents a function that accepts an int-valued argument, may thrown
031 * exception and produces a long-valued result. This is the
032 * {@code int}-to-{@code long} primitive specialization for
033 * {@link FunctionWithException}.
034 * <h3>General contract</h3>
035 * <ul>
036 * <li><b>{@link #applyAsLong(int) long applyAsLong(int value) throws
037 * E}</b>&nbsp;-&nbsp;The functional method.</li>
038 * <li><b>uncheck</b>&nbsp;-&nbsp;Return a {@code IntToLongFunction}</li>
039 * <li><b>lift</b>&nbsp;-&nbsp;Return a {@code IntToLongFunction}</li>
040 * <li><b>ignore</b>&nbsp;-&nbsp;Return a {@code IntToLongFunction}</li>
041 * </ul>
042 *
043 * @see IntToLongFunction
044 * @param <E>
045 *            the type of the potential exception of the function
046 */
047@FunctionalInterface
048public interface IntToLongFunctionWithException<E extends Exception> extends
049                PrimitiveReturnExceptionHandlerSupport<IntToLongFunction, IntToLongFunctionWithException<E>>, LongDefaultValue {
050
051        /**
052         * Applies this function to the given argument.
053         *
054         * @param value
055         *            the function argument
056         * @return the function result
057         * @throws E
058         *             any exception
059         * @see IntToLongFunction#applyAsLong(int)
060         */
061        long applyAsLong(int value) throws E;
062
063        @Override
064        default IntToLongFunction uncheckOrIgnore(boolean uncheck) {
065                return value -> {
066                        try {
067                                return applyAsLong(value);
068                        } catch (Exception e) {
069                                PrimitiveReturnExceptionHandlerSupport.handleException(uncheck, e, exceptionMapper());
070                                return defaultValue();
071                        }
072                };
073        }
074
075        /**
076         * Returns a function that always throw exception.
077         *
078         * @param exceptionBuilder
079         *            the supplier to create the exception
080         * @param <E>
081         *            the type of the exception
082         * @return a function that always throw exception
083         */
084        static <E extends Exception> IntToLongFunctionWithException<E> failing(Supplier<E> exceptionBuilder) {
085                return t -> {
086                        throw exceptionBuilder.get();
087                };
088        }
089
090        /**
091         * Converts a {@code IntToLongFunctionWithException} to a
092         * {@code IntToLongFunction} that wraps exception to {@code RuntimeException}.
093         *
094         * @param function
095         *            to be unchecked
096         * @param <E>
097         *            the type of the potential exception
098         * @return the unchecked function
099         * @see #uncheck()
100         * @see #unchecked(IntToLongFunctionWithException, Function)
101         * @throws NullPointerException
102         *             if function is null
103         */
104        static <E extends Exception> IntToLongFunction unchecked(IntToLongFunctionWithException<E> function) {
105                return verifyFunction(function).uncheck();
106        }
107
108        /**
109         * Converts a {@code IntToLongFunctionWithException} to a
110         * {@code IntToLongFunction} that wraps exception to {@code RuntimeException} by
111         * using the provided mapping function.
112         *
113         * @param function
114         *            the be unchecked
115         * @param exceptionMapper
116         *            a function to convert the exception to the runtime exception.
117         * @param <E>
118         *            the type of the potential exception
119         * @return the unchecked function
120         * @see #uncheck()
121         * @see #unchecked(IntToLongFunctionWithException)
122         * @throws NullPointerException
123         *             if function or exceptionMapper is null
124         */
125        static <E extends Exception> IntToLongFunction unchecked(IntToLongFunctionWithException<E> function,
126                        Function<Exception, RuntimeException> exceptionMapper) {
127                verifyFunction(function);
128                verifyExceptionMapper(exceptionMapper);
129                return new IntToLongFunctionWithException<E>() {
130
131                        @Override
132                        public long applyAsLong(int value) throws E {
133                                return function.applyAsLong(value);
134                        }
135
136                        @Override
137                        public Function<Exception, RuntimeException> exceptionMapper() {
138                                return exceptionMapper;
139                        }
140
141                }.uncheck();
142        }
143
144        /**
145         * Converts a {@code IntToLongFunctionWithException} to a lifted
146         * {@code IntToLongFunction} returning {@code 0} in case of exception.
147         *
148         * @param function
149         *            to be lifted
150         * @param <E>
151         *            the type of the potential exception
152         * @return the lifted function
153         * @see #lift()
154         * @throws NullPointerException
155         *             if function is null
156         */
157        static <E extends Exception> IntToLongFunction lifted(IntToLongFunctionWithException<E> function) {
158                return verifyFunction(function).lift();
159        }
160
161        /**
162         * Converts a {@code IntToLongFunctionWithException} to a lifted
163         * {@code IntToLongFunction} returning {@code 0} in case of exception.
164         *
165         * @param function
166         *            to be lifted
167         * @param <E>
168         *            the type of the potential exception
169         * @return the lifted function
170         * @see #ignore()
171         * @throws NullPointerException
172         *             if function is null
173         */
174        static <E extends Exception> IntToLongFunction ignored(IntToLongFunctionWithException<E> function) {
175                return verifyFunction(function).ignore();
176        }
177
178        /**
179         * Converts a {@code IntToLongFunctionWithException} to a lifted
180         * {@code IntToLongFunction} returning a default value in case of exception.
181         *
182         * @param function
183         *            to be lifted
184         * @param defaultValue
185         *            value in case of exception
186         * @param <E>
187         *            the type of the potential exception
188         * @return the lifted function
189         * @see #ignore()
190         * @see #ignored(IntToLongFunctionWithException)
191         * @throws NullPointerException
192         *             if function is null
193         * @since 3.0.0
194         */
195        static <E extends Exception> IntToLongFunction ignored(IntToLongFunctionWithException<E> function,
196                        long defaultValue) {
197                verifyFunction(function);
198                return new IntToLongFunctionWithException<E>() {
199
200                        @Override
201                        public long applyAsLong(int value) throws E {
202                                return function.applyAsLong(value);
203                        }
204
205                        @Override
206                        public long defaultValue() {
207                                return defaultValue;
208                        }
209
210                }.ignore();
211        }
212
213}