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