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