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