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.function.Function; 027import java.util.function.Supplier; 028import java.util.function.UnaryOperator; 029 030/** 031 * Represents an operation on a single operand that produces a result of the 032 * same type as its operand. This is a specialization of 033 * {@code FunctionWithException} for the case where the operand and result are 034 * of the same type. 035 * <p> 036 * As this interface must return the same type of the input, a lifted version 037 * which returns {@code Optional} is not possible. 038 * <h3>General contract</h3> 039 * <ul> 040 * <li><b>{@link #apply(Object) T apply(T t) throws E}</b> - The 041 * functional method.</li> 042 * <li><b>uncheck</b> - Return a {@code UnaryOperator<T>}</li> 043 * <li><b>lift</b> - Return a {@code Function<T,Optional<T>}</li> 044 * <li><b>ignore</b> - Return a {@code UnaryOperator<T>}</li> 045 * </ul> 046 * 047 * @see FunctionWithException 048 * @see UnaryOperator 049 * @param <T> 050 * the type of the operand and result of the operator 051 */ 052@FunctionalInterface 053public interface UnaryOperatorWithException<T, E extends Exception> extends FunctionWithException<T, T, E> { 054 055 /** 056 * Converts this {@code UnaryOperatorWithException} to a {@code UnaryOperator} 057 * that wraps exception to {@code RuntimeException}. 058 * 059 * @return the unchecked function 060 * @see #unchecked(FunctionWithException) 061 * @see #unchecked(FunctionWithException, Function) 062 */ 063 @Override 064 default UnaryOperator<T> uncheck() { 065 return t -> ObjectReturnExceptionHandlerSupport.unchecked(() -> apply(t), throwingHandler()); 066 } 067 068 /** 069 * Converts this {@code UnaryOperatorWithException} to a lifted 070 * {@code UnaryOperator} returning {@code null} in case of exception. 071 * 072 * @return the function that ignore error 073 * @see #ignored(FunctionWithException) 074 */ 075 @Override 076 default UnaryOperator<T> ignore() { 077 return t -> ObjectReturnExceptionHandlerSupport.unchecked(() -> apply(t), e -> null); 078 } 079 080 @Override 081 default UnaryOperatorWithException<T, E> documented(Supplier<String> toString) { 082 return (UnaryOperatorWithException<T, E>) FunctionWithException.super.documented(toString); 083 } 084 085 /** 086 * Returns a unary operator that always returns its input argument. 087 * 088 * @param <T> 089 * the type of the input and output of the operator 090 * @param <E> 091 * the type of the potential exception 092 * @return a unary operator that always returns its input argument 093 * @see Function#identity() 094 */ 095 static <T, E extends Exception> UnaryOperatorWithException<T, E> identity() { 096 return t -> t; 097 } 098 099 /** 100 * Returns a unary operator that always throw exception. 101 * 102 * @param exceptionBuilder 103 * the supplier to create the exception 104 * @param <T> 105 * the type of the input and output of the operator 106 * @param <E> 107 * the type of the exception 108 * @return a function that always throw exception 109 */ 110 static <T, E extends Exception> UnaryOperatorWithException<T, E> failing(Supplier<E> exceptionBuilder) { 111 return t -> { 112 throw exceptionBuilder.get(); 113 }; 114 } 115 116 /** 117 * Converts a {@code UnaryOperatorWithException} to a {@code UnaryOperator} that 118 * wraps exception to {@code RuntimeException}. 119 * 120 * @param function 121 * to be unchecked 122 * @param <T> 123 * the type of the input and output of the operator 124 * @param <E> 125 * the type of the potential exception 126 * @return the unchecked exception 127 * @see #uncheck() 128 * @see #unchecked(UnaryOperatorWithException, Function) 129 * @throws NullPointerException 130 * if function is null 131 */ 132 static <T, E extends Exception> UnaryOperator<T> unchecked(UnaryOperatorWithException<T, E> function) { 133 return verifyFunction(function).uncheck(); 134 } 135 136 /** 137 * Converts a {@code UnaryOperatorWithException} to a {@code UnaryOperator} that 138 * wraps exception to {@code RuntimeException} by using the provided mapping 139 * function. 140 * 141 * @param function 142 * the be unchecked 143 * @param exceptionMapper 144 * a function to convert the exception to the runtime exception. 145 * @param <T> 146 * the type of the input and output of the operator 147 * @param <E> 148 * the type of the potential exception 149 * @return the unchecked exception 150 * @see #uncheck() 151 * @see #unchecked(UnaryOperatorWithException) 152 * @throws NullPointerException 153 * if function or exceptionMapper is null 154 */ 155 static <T, E extends Exception> UnaryOperator<T> unchecked(UnaryOperatorWithException<T, E> function, 156 Function<Exception, RuntimeException> exceptionMapper) { 157 verifyFunction(function); 158 verifyExceptionMapper(exceptionMapper); 159 return new UnaryOperatorWithException<T, E>() { 160 161 @Override 162 public T apply(T t) throws E { 163 return function.apply(t); 164 } 165 166 @Override 167 public Function<Exception, RuntimeException> exceptionMapper() { 168 return exceptionMapper; 169 } 170 171 }.uncheck(); 172 } 173 174 /** 175 * Converts a {@code UnaryOperatorWithException} to a lifted {@code Function} 176 * returning {@code Optional}. 177 * 178 * @param function 179 * to be lifted 180 * @param <T> 181 * the type of the input and output of the operator 182 * @param <E> 183 * the type of the potential exception 184 * @return the lifted function 185 * @see #ignore() 186 * @throws NullPointerException 187 * if function is null 188 */ 189 static <T, E extends Exception> Function<T, Optional<T>> lifted(UnaryOperatorWithException<T, E> function) { 190 return verifyFunction(function).lift(); 191 } 192 193 /** 194 * Converts a {@code UnaryOperatorWithException} to a lifted 195 * {@code UnaryOperator} returning {@code null} in case of exception. 196 * 197 * @param function 198 * to be lifted 199 * @param <T> 200 * the type of the input and output of the operator 201 * @param <E> 202 * the type of the potential exception 203 * @return the lifted function 204 * @see #ignore() 205 * @throws NullPointerException 206 * if function is null 207 */ 208 static <T, E extends Exception> UnaryOperator<T> ignored(UnaryOperatorWithException<T, E> function) { 209 return verifyFunction(function).ignore(); 210 } 211 212}