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.Optional; 026import java.util.concurrent.CompletionStage; 027import java.util.function.Function; 028import java.util.function.LongFunction; 029import java.util.function.Supplier; 030 031/** 032 * Represents a function that accepts a long-valued argument, may throw 033 * exception and produces a result. This is the {@code long}-consuming primitive 034 * specialization for {@link FunctionWithException}. 035 * <h3>General contract</h3> 036 * <ul> 037 * <li><b>{@link #apply(long) R apply(long value) throws E}</b> - The 038 * functional method.</li> 039 * <li><b>uncheck</b> - Return a {@code LongFunction<R>}</li> 040 * <li><b>lift</b> - Return a {@code LongFunction<Optional<R>>}</li> 041 * <li><b>ignore</b> - Return a {@code LongFunction<R>}</li> 042 * </ul> 043 * 044 * @see LongFunction 045 * @param <R> 046 * the type of the result of the function 047 * @param <E> 048 * the type of the potential exception of the function 049 */ 050@FunctionalInterface 051public interface LongFunctionWithException<R, E extends Exception> extends 052 ObjectReturnExceptionHandlerSupport<LongFunction<R>, LongFunction<Optional<R>>, LongFunction<CompletionStage<R>>, R, LongFunctionWithException<R, E>> { 053 054 /** 055 * Applies this function to the given argument. 056 * 057 * @param value 058 * the function argument 059 * @return the function result 060 * @throws E 061 * any exception 062 * @see LongFunction#apply(long) 063 */ 064 R apply(long value) throws E; 065 066 /** 067 * Converts this {@code LongFunctionWithException} to a {@code LongFunction} 068 * that wraps exception to {@code RuntimeException}. 069 * 070 * @return the unchecked function 071 * @see #unchecked(LongFunctionWithException) 072 * @see #unchecked(LongFunctionWithException, Function) 073 */ 074 @Override 075 default LongFunction<R> uncheck() { 076 return t -> ObjectReturnExceptionHandlerSupport.unchecked(() -> apply(t), throwingHandler()); 077 } 078 079 /** 080 * Converts this {@code LongFunctionWithException} to a lifted 081 * {@code LongFunction} using {@code Optional} as return value. 082 * 083 * @return the lifted function 084 * @see #lifted(LongFunctionWithException) 085 */ 086 @Override 087 default LongFunction<Optional<R>> lift() { 088 return t -> ObjectReturnExceptionHandlerSupport.unchecked(() -> Optional.ofNullable(apply(t)), 089 notThrowingHandler()); 090 } 091 092 /** 093 * Converts this {@code LongFunctionWithException} to a lifted 094 * {@code LongFunction} returning {@code null} (or the value redefined by the 095 * method {@link #defaultValue()}) in case of exception. 096 * 097 * @return the function that ignore error 098 * @see #ignored(LongFunctionWithException) 099 */ 100 @Override 101 default LongFunction<R> ignore() { 102 return t -> ObjectReturnExceptionHandlerSupport.unchecked(() -> apply(t), e -> defaultValue()); 103 } 104 105 /** 106 * Convert this {@code LongFunctionWithException} to a lifted 107 * {@code LongFunction} returning {@code CompletionStage} as return value. 108 * 109 * @return the lifted function 110 * @see #staged(LongFunctionWithException) 111 */ 112 @Override 113 default LongFunction<CompletionStage<R>> stage() { 114 return t -> ObjectReturnExceptionHandlerSupport.staged(() -> apply(t)); 115 } 116 117 /** 118 * Returns a function that always throw exception. 119 * 120 * @param exceptionBuilder 121 * the supplier to create the exception 122 * @param <R> 123 * the type of the result of the function 124 * @param <E> 125 * the type of the exception 126 * @return a function that always throw exception 127 */ 128 static <R, E extends Exception> LongFunctionWithException<R, E> failing(Supplier<E> exceptionBuilder) { 129 return t -> { 130 throw exceptionBuilder.get(); 131 }; 132 } 133 134 /** 135 * Converts a {@code FunctionWithException} to a {@code LongFunction} that wraps 136 * to {@code RuntimeException}. 137 * 138 * @param function 139 * to be unchecked 140 * @param <R> 141 * the type of the output object to the function 142 * @param <E> 143 * the type of the potential exception 144 * @return the unchecked exception 145 * @see #uncheck() 146 * @see #unchecked(LongFunctionWithException, Function) 147 * @throws NullPointerException 148 * if function is null 149 */ 150 static <R, E extends Exception> LongFunction<R> unchecked(LongFunctionWithException<R, E> function) { 151 return verifyFunction(function).uncheck(); 152 } 153 154 /** 155 * Converts a {@code LongFunctionWithException} to a {@code LongFunction} that 156 * wraps exception to {@code RuntimeException} by using the provided mapping 157 * function. 158 * 159 * @param function 160 * the be unchecked 161 * @param exceptionMapper 162 * a function to convert the exception to the runtime exception. 163 * @param <R> 164 * the type of the result of the function 165 * @param <E> 166 * the type of the potential exception 167 * @return the unchecked function 168 * @see #uncheck() 169 * @see #unchecked(LongFunctionWithException) 170 * @throws NullPointerException 171 * if function or exceptionMapper is null 172 */ 173 static <R, E extends Exception> LongFunction<R> unchecked(LongFunctionWithException<R, E> function, 174 Function<Exception, RuntimeException> exceptionMapper) { 175 verifyFunction(function); 176 verifyExceptionMapper(exceptionMapper); 177 return new LongFunctionWithException<R, E>() { 178 179 @Override 180 public R apply(long value) throws E { 181 return function.apply(value); 182 } 183 184 @Override 185 public Function<Exception, RuntimeException> exceptionMapper() { 186 return exceptionMapper; 187 } 188 189 }.uncheck(); 190 } 191 192 /** 193 * Converts a {@code LongFunctionWithException} to a lifted {@code Function} 194 * using {@code Optional} as return value. 195 * 196 * @param function 197 * to be lifted 198 * @param <R> 199 * the type of the result of the function 200 * @param <E> 201 * the type of the potential exception 202 * @return the lifted function 203 * @see #lift() 204 * @throws NullPointerException 205 * if function is null 206 */ 207 static <R, E extends Exception> LongFunction<Optional<R>> lifted(LongFunctionWithException<R, E> function) { 208 return verifyFunction(function).lift(); 209 } 210 211 /** 212 * Converts a {@code LongFunctionWithException} to a lifted {@code LongFunction} 213 * returning {@code null} in case of exception. 214 * 215 * @param function 216 * to be lifted 217 * @param <R> 218 * the type of the result of the function 219 * @param <E> 220 * the type of the potential exception 221 * @return the lifted function 222 * @see #ignore() 223 * @throws NullPointerException 224 * if function is null 225 */ 226 static <R, E extends Exception> LongFunction<R> ignored(LongFunctionWithException<R, E> function) { 227 return verifyFunction(function).ignore(); 228 } 229 230 /** 231 * Converts a {@code LongFunctionWithException} to a lifted {@code LongFunction} 232 * returning a default value in case of exception. 233 * 234 * @param function 235 * to be lifted 236 * @param defaultValue 237 * the value to be returned in case of exception 238 * @param <R> 239 * the type of the result of the function 240 * @param <E> 241 * the type of the potential exception 242 * @return the lifted function 243 * @see #ignore() 244 * @see #ignored(LongFunctionWithException) 245 * @throws NullPointerException 246 * if function is null 247 * @since 3.0.0 248 */ 249 static <R, E extends Exception> LongFunction<R> ignored(LongFunctionWithException<R, E> function, R defaultValue) { 250 verifyFunction(function); 251 return new LongFunctionWithException<R, E>() { 252 253 @Override 254 public R apply(long value) throws E { 255 return function.apply(value); 256 } 257 258 @Override 259 public R defaultValue() { 260 return defaultValue; 261 } 262 263 }.ignore(); 264 } 265 266 /** 267 * Convert this {@code LongFunctionWithException} to a lifted 268 * {@code LongFunction} return {@code CompletionStage} as return value. 269 * 270 * @param function 271 * to be lifted 272 * @param <R> 273 * the type of the result of the function 274 * @param <E> 275 * the type of the potential exception 276 * @return the lifted function 277 * @see #stage() 278 * @throws NullPointerException 279 * if function is null 280 */ 281 static <R, E extends Exception> LongFunction<CompletionStage<R>> staged(LongFunctionWithException<R, E> function) { 282 return verifyFunction(function).stage(); 283 } 284 285}