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