org.openmetadata.service.util.LambdaExceptionUtil Maven / Gradle / Ivy
/*
* Copyright 2021 Collate
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openmetadata.service.util;
import java.util.Comparator;
import java.util.function.Consumer;
import java.util.function.Function;
/**
* Utility class for the streams API.
*
* Wraps consumers and functions into interfaces that can throw Checked Exceptions
*/
public final class LambdaExceptionUtil {
@FunctionalInterface
public interface ConsumerWithExceptions {
void accept(T t) throws E;
}
@FunctionalInterface
public interface FunctionWithExceptions {
R apply(T t) throws E;
}
@FunctionalInterface
public interface ComparatorWithExceptions {
int compare(T o1, T o2) throws E;
}
/**
* Wrap a standard {@link Consumer} in a {@link ConsumerWithExceptions}.
*
* This allows a consumer to throw Checked Exception that will be propagated to the context of the statement
* calling it
*
*
Example:
* Stream.of("java.lang.String", "java.bad.Class").forEach(rethrowConsumer(name -> System.out.println(Class.forName(name))));
*
throws checked {@link ClassNotFoundException}
*/
public static Consumer rethrowConsumer(
ConsumerWithExceptions consumer) {
return t -> {
try {
consumer.accept(t);
} catch (Exception exception) {
throwActualException(exception);
}
};
}
/**
* Wrap a standard {@link Function} in a {@link FunctionWithExceptions}.
*
* This allows a lambda function to throw Checked Exception that will be propagated to the context of the statement
* calling it
*
*
Example:
* Stream.of("java.lang.String", "java.bad.Class").map(rethrowFunction(Class::forName)));
*
throws checked {@link ClassNotFoundException}
*/
public static Function rethrowFunction(
FunctionWithExceptions function) {
return t -> {
try {
return function.apply(t);
} catch (Exception exception) {
throwActualException(exception);
return null;
}
};
}
/**
* Wrap a standard {@link Comparator} in a {@link ComparatorWithExceptions}.
*
* This allows a comparator to propagate a Checked Exception
*
*
Example:
* List.of("java.lang.String", "java.lang.Integer", "java.bad.Class").sorted((c1, c2) -> Class.forName(c1).getFields().length - Class.forName(c2).getFields().length
*
throws checked {@link ClassNotFoundException}
*/
public static Comparator rethrowComparator(
ComparatorWithExceptions comparator) {
return (t1, t2) -> {
try {
return comparator.compare(t1, t2);
} catch (Exception exception) {
throwActualException(exception);
return Integer.MIN_VALUE;
}
};
}
/**
* Wrap a standard {@link Comparator}, swallowing all {@link Exception}.
*
* WARNING! When {@link Comparator#compare} throws an exception the elements are treated as equal.
* This should only be used for ignoring checked exceptions that can never be throws.
*/
public static Comparator ignoringComparator(
ComparatorWithExceptions comparator) {
return (t1, t2) -> {
try {
return comparator.compare(t1, t2);
} catch (Exception ignored) {
return 0;
}
};
}
@SuppressWarnings("unchecked")
private static void throwActualException(Exception exception) throws E {
throw (E) exception;
}
}