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