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