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 java.util.concurrent.CompletableFuture.completedFuture; 023import static java.util.concurrent.CompletableFuture.failedFuture; 024 025import java.util.concurrent.CompletionStage; 026import java.util.function.Consumer; 027 028/** 029 * Root interface to support global operations related to exception handling for 030 * functional interface without return value. 031 * 032 * @param <F> 033 * the type of the java standard functional interface. For example, 034 * {@code Consumer<T>}. The same functional interface is also used 035 * for the lifted and ignored version. 036 * @param <S> 037 * the type of a java standard function interface to return a 038 * {@code CompletionStage}. 039 */ 040public interface NoReturnExceptionHandlerSupport<F, S, Z extends NoReturnExceptionHandlerSupport<F, S, Z>> 041 extends ExceptionHandlerSupport<F, F, Z> { 042 043 /** 044 * Converts this functional interface to the corresponding one in java and wrap 045 * exception using {@link #exceptionMapper()}. 046 * <p> 047 * Conceptually, the exception encapsulation is done in the following way : 048 * 049 * <pre> 050 * (xxx) -> { 051 * try { 052 * // do the underlying functional interface action and return result if 053 * // applicable 054 * } catch (Exception e) { 055 * throw new exceptionMapper().apply(e); 056 * } 057 * } 058 * </pre> 059 * 060 * @return the unchecked operation 061 * @see #lift() 062 * @see #ignore() 063 */ 064 @Override 065 F uncheck(); 066 067 /** 068 * Converts this functional interface to a lifted one. 069 * <p> 070 * The concept is : 071 * 072 * <pre> 073 * (xxx) -> { 074 * try { 075 * realaction(xxx); 076 * } catch (Exception e) { 077 * // do nothing 078 * } 079 * } 080 * </pre> 081 * 082 * @return the lifted function 083 * @see #uncheck() 084 * @see #ignore() 085 */ 086 @Override 087 default F lift() { 088 return ignore(); 089 } 090 091 /** 092 * Converts this functional interface to a lifted one. 093 * <p> 094 * The concept is : 095 * 096 * <pre> 097 * (xxx) -> { 098 * try { 099 * realaction(xxx); 100 * } catch (Exception e) { 101 * // do nothing 102 * } 103 * } 104 * </pre> 105 * 106 * @return the lifted function 107 * @see #uncheck() 108 * @see #ignore() 109 */ 110 @Override 111 F ignore(); 112 113 /** 114 * Converts this functional interface to a lifted one, using a 115 * {@code CompletionStage} as a return value. 116 * 117 * @return the lifted function 118 * @since 1.1.0 119 */ 120 S stage(); 121 122 /** 123 * Used internally to support the exception interception. 124 * 125 * @param internal 126 * the call to be done 127 * @param exceptionhandler 128 * the exception handler. May throw RuntimeException.. 129 * @throws RuntimeException 130 * in case of error 131 */ 132 static void unchecked(RunnableWithException<?> internal, Consumer<Exception> exceptionhandler) { 133 try { 134 internal.run(); 135 } catch (Exception e) { 136 // exceptionhandler must throw the exception if needed 137 exceptionhandler.accept(e); 138 } 139 } 140 141 /** 142 * Used internally to support the exception interception. 143 * 144 * @param internal 145 * the call to be done 146 * @return the completion stage 147 * @throws RuntimeException 148 * in case of error 149 */ 150 static CompletionStage<Void> staged(RunnableWithException<?> internal) { 151 try { 152 internal.run(); 153 return completedFuture(null); 154 } catch (Exception e) { 155 return failedFuture(e); 156 } 157 } 158 159 /** 160 * Used internally to support the exception interception. 161 * 162 * @return exception handler to support exception control 163 */ 164 default Consumer<Exception> throwingHandler() { 165 return e -> { 166 throw exceptionMapper().apply(e); 167 }; 168 } 169 170 /** 171 * Used internally to support the exception interception. 172 * 173 * @return exception handler to ignore exception control 174 */ 175 default Consumer<Exception> notThrowingHandler() { 176 return e -> { 177 }; 178 } 179}