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