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.verifyConsumer;
023import static ch.powerunit.extensions.exceptions.Constants.verifyFunction;
024import static ch.powerunit.extensions.exceptions.Constants.verifyPredicate;
025import static ch.powerunit.extensions.exceptions.Constants.verifySupplier;
026import static ch.powerunit.extensions.exceptions.ExceptionMapper.forException;
027import static ch.powerunit.extensions.exceptions.ExceptionMapper.forExceptions;
028
029import java.util.function.Function;
030
031import org.apache.commons.collections4.Closure;
032import org.apache.commons.collections4.Factory;
033import org.apache.commons.collections4.FunctorException;
034import org.apache.commons.collections4.Transformer;
035
036/**
037 * This class provides several helper methods for the functional interface of
038 * the <a href=
039 * "https://commons.apache.org/proper/commons-collections">commons-collections4</a>.
040 * <p>
041 * <b>This class is only available if commons-collections4 is available</b>
042 * <p>
043 * The mapping between the interface from <i>commons-collections4</i> and this
044 * library is the following :
045 *
046 * <table border="1">
047 * <caption>Mapping between interfaces</caption>
048 * <tr>
049 * <th>commons-collections4</th>
050 * <th>powerunit-extensions-exceptions</th>
051 * </tr>
052 * <tr>
053 * <td>Predicate</td>
054 * <td>PredicateWithException</td>
055 * </tr>
056 * <tr>
057 * <td>Factory</td>
058 * <td>SupplierWithException</td>
059 * </tr>
060 * <tr>
061 * <td>Transformer</td>
062 * <td>FunctionWithException</td>
063 * </tr>
064 * <tr>
065 * <td>Closure</td>
066 * <td>ConsumerWithException</td>
067 * </tr>
068 * </table>
069 *
070 * @since 2.2.0
071 *
072 */
073public final class CommonsCollections4Helper {
074
075        private static final Function<Exception, RuntimeException> DEFAULT_EXCEPTION_MAPPER = forExceptions(
076                        forException(ClassCastException.class, e -> e), forException(IllegalArgumentException.class, e -> e),
077                        forException(Exception.class, FunctorException::new));
078
079        private CommonsCollections4Helper() {
080        }
081
082        /**
083         * Transforms a {@link PredicateWithException} to the one from
084         * commons-collections.
085         *
086         * @param predicate
087         *            the {@link PredicateWithException} to be transformed to the one
088         *            from commons-collections.
089         * @param <T>
090         *            the type of the input argument for the predicate
091         * @return the {@link org.apache.commons.collections4.Predicate predicate} from
092         *         commons-collections. The ClassCastException and
093         *         IllegalArgumentException are not wrapped and the other exception are
094         *         wrapped in a FunctorException.
095         * @throws NoClassDefFoundError
096         *             In case the commons-collections4 library is not available.
097         * @throws NullPointerException
098         *             if predicate is null.
099         * @see org.apache.commons.collections4.Predicate
100         */
101        public static <T> org.apache.commons.collections4.Predicate<T> asPredicate(PredicateWithException<T, ?> predicate) {
102                return PredicateWithException.unchecked(verifyPredicate(predicate), DEFAULT_EXCEPTION_MAPPER)::test;
103        }
104
105        /**
106         * Transforms a {@link SupplierWithException} to the one from
107         * commons-collections.
108         *
109         * @param supplier
110         *            the {@link SupplierWithException} to be transformed to the one
111         *            from commons-collections.
112         * @param <T>
113         *            the type of the result of the supplier
114         * @return the {@link Factory factory} from commons-collections. The exception
115         *         are wrapped in a FunctorException.
116         * @throws NoClassDefFoundError
117         *             In case the commons-collections4 library is not available.
118         * @throws NullPointerException
119         *             if supplier is null.
120         * @see org.apache.commons.collections4.Factory
121         */
122        public static <T> Factory<T> asFactory(SupplierWithException<T, ?> supplier) {
123                return SupplierWithException.unchecked(verifySupplier(supplier), FunctorException::new)::get;
124        }
125
126        /**
127         * Transforms a {@link FunctionWithException} to the one from
128         * commons-collections.
129         *
130         * @param function
131         *            the {@link FunctionWithException} to be transformed to the one
132         *            from commons-collections.
133         * @param <I>
134         *            the input argument type of the function
135         * @param <O>
136         *            the result type of the function
137         * @return the {@link Transformer transformer} from commons-collections. The
138         *         ClassCastException and IllegalArgumentException are not wrapped and
139         *         the other exception are wrapped in a FunctorException.
140         * @throws NoClassDefFoundError
141         *             In case the commons-collections4 library is not available.
142         * @throws NullPointerException
143         *             if function is null.
144         * @see org.apache.commons.collections4.Transformer
145         */
146        public static <I, O> Transformer<I, O> asTransformer(FunctionWithException<I, O, ?> function) {
147                return FunctionWithException.unchecked(verifyFunction(function), DEFAULT_EXCEPTION_MAPPER)::apply;
148        }
149
150        /**
151         * Transforms a {@link ConsumerWithException} to the one from
152         * commons-collections.
153         *
154         * @param consumer
155         *            the {@link ConsumerWithException} to be transformed to the one
156         *            from commons-collections.
157         * @param <T>
158         *            the type of the input argument for the consumer
159         * @return the {@link Closure closure} from commons-collections. The
160         *         ClassCastException and IllegalArgumentException are not wrapped and
161         *         the other exception are wrapped in a FunctorException.
162         * @throws NoClassDefFoundError
163         *             In case the commons-collections4 library is not available.
164         * @throws NullPointerException
165         *             if consumer is null.
166         * @see org.apache.commons.collections4.Closure
167         */
168        public static <T> Closure<T> asClosure(ConsumerWithException<T, ?> consumer) {
169                return ConsumerWithException.unchecked(verifyConsumer(consumer), DEFAULT_EXCEPTION_MAPPER)::accept;
170        }
171}