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