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