001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * https://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 018package org.apache.commons.lang3; 019 020import java.io.Closeable; 021import java.util.function.Consumer; 022 023import org.apache.commons.lang3.function.Consumers; 024import org.apache.commons.lang3.function.FailableConsumer; 025 026/** 027 * Static operations on {@link AutoCloseable}. 028 * <p> 029 * For {@link Closeable}-specific methods, see Apache Commons IO's 030 * <a href="https://commons.apache.org/proper/commons-io/apidocs/org/apache/commons/io/IOUtils.html">IOUtils</a>. 031 * </p> 032 * 033 * @since 3.21.0 034 */ 035public class AutoCloseables { 036 037 /** 038 * Closes the given {@link AutoCloseable} as a null-safe operation. 039 * 040 * @param closeable The resource to close, may be null. 041 * @throws Exception Thrown if an error occurs. 042 */ 043 public static void close(final AutoCloseable closeable) throws Exception { 044 if (closeable != null) { 045 closeable.close(); 046 } 047 } 048 049 /** 050 * Closes the given {@link AutoCloseable} as a null-safe operation. 051 * 052 * @param closeable The resource to close, may be null. 053 * @param consumer Consume the Exception thrown by {@link AutoCloseable#close()}. 054 * @throws Exception Thrown if the consumer throws an exception. 055 */ 056 public static void close(final AutoCloseable closeable, final FailableConsumer<Exception, Exception> consumer) throws Exception { 057 if (closeable != null) { 058 try { 059 closeable.close(); 060 } catch (final Exception e) { 061 FailableConsumer.accept(consumer, e); 062 } 063 } 064 } 065 066 /** 067 * Closes an {@link AutoCloseable}, never throwing an {@link Exception}. 068 * <p> 069 * Equivalent to {@link AutoCloseable#close()}, except any exceptions will be ignored. 070 * </p> 071 * 072 * @param closeable The objects to close, may be null or already closed. 073 * @see Throwable#addSuppressed(Throwable) 074 */ 075 public static void closeQuietly(final AutoCloseable closeable) { 076 closeQuietly(closeable, (Consumer<Exception>) null); 077 } 078 079 /** 080 * Closes the given {@link AutoCloseable} as a null-safe operation while consuming Exception by the given {@code consumer}. 081 * 082 * @param closeable The resource to close, may be null. 083 * @param consumer Consumes the Exception thrown by {@link AutoCloseable#close()}. 084 */ 085 public static void closeQuietly(final AutoCloseable closeable, final Consumer<Exception> consumer) { 086 if (closeable != null) { 087 try { 088 closeable.close(); 089 } catch (final Exception e) { 090 Consumers.accept(consumer, e); 091 } 092 } 093 } 094 095 /** 096 * Closes an iterable of {@link AutoCloseable}, never throwing an {@link Exception}. 097 * <p> 098 * Equivalent calling {@link AutoCloseable#close()} on each element, except any exceptions will be ignored. 099 * </p> 100 * 101 * @param closeables The objects to close, may be null or already closed. 102 * @see #closeQuietly(AutoCloseable) 103 */ 104 public static void closeQuietly(final Iterable<AutoCloseable> closeables) { 105 if (closeables != null) { 106 closeables.forEach(AutoCloseables::closeQuietly); 107 } 108 } 109 110 /** 111 * Closes a {@link Closeable} unconditionally and adds any exception thrown by the {@code close()} to the given Throwable. 112 * <p> 113 * For example: 114 * </p> 115 * 116 * <pre> 117 * AutoCloseable autoCloseable = ...; 118 * try { 119 * // process autoCloseable. 120 * } catch (Exception e) { 121 * // Handle exception. 122 * throw AutoCloseables.closeQuietlySuppress(autoCloseable, e); 123 * } 124 * </pre> 125 * <p> 126 * Also consider using a try-with-resources statement where appropriate. 127 * </p> 128 * 129 * @param <T> The Throwable type. 130 * @param closeable The object to close, may be null or already closed. 131 * @param throwable Add the exception throw by the closeable to the given Throwable. 132 * @return The given Throwable. 133 * @see Throwable#addSuppressed(Throwable) 134 */ 135 public static <T extends Throwable> T closeQuietlySuppress(final Closeable closeable, final T throwable) { 136 closeQuietly(closeable, throwable::addSuppressed); 137 return throwable; 138 } 139 140 /** 141 * No instances needed. 142 */ 143 private AutoCloseables() { 144 // empty 145 } 146}