001/* 002 * Copyright 2016 Anyware Services 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.ametys.core.util; 017 018import java.util.function.Consumer; 019import java.util.function.Function; 020import java.util.function.Predicate; 021 022/** 023 * Helper for lambda expressions. 024 */ 025public final class LambdaUtils 026{ 027 private LambdaUtils() 028 { 029 // empty constructor 030 } 031 032 /** 033 * Function allowed to throw checked {@link Exception}. <br> 034 * It allows to build one-line lambda for methods throwing checked exceptions. 035 * @param <T> the type of the input to the function. 036 * @param <R> the type of the result of the function. 037 */ 038 @FunctionalInterface 039 public interface ThrowingFunction<T, R> 040 { 041 /** 042 * Applies this function to the given argument. 043 * @param t the function argument 044 * @return the function result 045 * @throws Exception if something wrong occurs. 046 */ 047 R apply(T t) throws Exception; 048 } 049 050 /** 051 * Wraps a {@link Function} by catching its {@link Exception} and rethrowing them as {@link RuntimeException}. 052 * @param function the {@link Function} to wrap. 053 * @param <T> The type of input to the function 054 * @param <R> The type of result of the function 055 * @return the wrapped {@link Function}. 056 */ 057 public static <T, R> Function<T, R> wrap(ThrowingFunction<T, R> function) 058 { 059 return value -> 060 { 061 try 062 { 063 return function.apply(value); 064 } 065 catch (Exception e) 066 { 067 if (e instanceof RuntimeException) 068 { 069 throw (RuntimeException) e; 070 } 071 072 throw new RuntimeException(e); 073 } 074 }; 075 } 076 077 /** 078 * Predicate allowed to throw checked {@link Exception}. <br> 079 * It allows to build one-line lambda for methods throwing checked exceptions. 080 * @param <T> the type of the input to the predicate. 081 */ 082 @FunctionalInterface 083 public interface ThrowingPredicate<T> 084 { 085 /** 086 * Evaluates this predicate on the given argument. 087 * @param t the input argument 088 * @return {@code true} if the input argument matches the predicate, 089 * otherwise {@code false} 090 * @throws Exception if something wrong occurs. 091 */ 092 boolean test(T t) throws Exception; 093 } 094 095 /** 096 * Wraps a {@link Predicate} by catching its {@link Exception} and rethrowing them as {@link RuntimeException}. 097 * @param predicate the {@link Predicate} to wrap. 098 * @param <T> the type of the input to the predicate 099 * @return the wrapped {@link Predicate}. 100 */ 101 public static <T> Predicate<T> wrapPredicate(ThrowingPredicate<T> predicate) 102 { 103 return LambdaUtils.wrap(predicate::test)::apply; 104 105 } 106 107 /** 108 * Consumer allowed to throw checked {@link Exception}. <br> 109 * It allows to build one-line lambda for methods throwing checked exceptions. 110 * @param <T> the type of the input to the operation 111 */ 112 @FunctionalInterface 113 public interface ThrowingConsumer<T> 114 { 115 /** 116 * Performs this operation on the given argument. 117 * @param t the input argument 118 * @throws Exception if something wrong occurs. 119 */ 120 void accept(T t) throws Exception; 121 } 122 123 /** 124 * Wraps a {@link Consumer} by catching its {@link Exception} and rethrowing them as {@link RuntimeException}. 125 * @param consumer the {@link Consumer} to wrap. 126 * @param <T> The type of input to the operation 127 * @return the wrapped {@link Consumer}. 128 */ 129 public static <T> Consumer<T> wrapConsumer(ThrowingConsumer<T> consumer) 130 { 131 return value -> 132 { 133 try 134 { 135 consumer.accept(value); 136 } 137 catch (Exception e) 138 { 139 if (e instanceof RuntimeException) 140 { 141 throw (RuntimeException) e; 142 } 143 144 throw new RuntimeException(e); 145 } 146 }; 147 } 148}