package org.ehcache.jsr107;
import java.io.Closeable;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collection;
import java.util.Optional;
import java.util.stream.Stream;
public class CloseUtil {
public static <T extends Throwable> T closeAllAfter(T failure, Object ... objects) {
Optional<Closeable> closeable = extractCloseables(Stream.of(objects)).reduce(CloseUtil::composeCloseables);
if (closeable.isPresent()) {
try {
closeable.get().close();
} catch (Throwable t) {
failure.addSuppressed(t);
}
}
return failure;
}
static void closeAll(Object ... objects) throws IOException {
closeAll(Stream.of(objects));
}
static void closeAll(Stream<Object> objects) throws IOException {
chain(extractCloseables(objects));
}
static void chain(Closeable ... objects) throws IOException {
chain(Stream.of(objects));
}
public static void chain(Stream<Closeable> objects) throws IOException {
Optional<Closeable> closeable = objects.reduce(CloseUtil::composeCloseables);
if (closeable.isPresent()) {
closeable.get().close();
}
}
private static Stream<Closeable> (Stream<Object> objects) {
return objects.filter(o -> o != null).flatMap(o -> {
if (o instanceof Collection<?>) {
return ((Collection<?>) o).stream();
} else if (o.getClass().isArray()) {
return Arrays.stream((Object[]) o);
} else {
return Stream.of(o);
}
}).filter(o -> o != null).filter(Closeable.class::isInstance).map(Closeable.class::cast);
}
private static Closeable composeCloseables(Closeable a, Closeable b) {
return () -> {
try {
a.close();
} catch (Throwable t1) {
try {
b.close();
} catch (Throwable t2) {
t1.addSuppressed(t2);
}
throw t1;
}
b.close();
};
}
}