1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * https://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 package org.apache.commons.lang3;
19
20 import java.io.Closeable;
21 import java.util.function.Consumer;
22
23 import org.apache.commons.lang3.function.Consumers;
24 import org.apache.commons.lang3.function.FailableConsumer;
25
26 /**
27 * Static operations on {@link AutoCloseable}.
28 * <p>
29 * For {@link Closeable}-specific methods, see Apache Commons IO's
30 * <a href="https://commons.apache.org/proper/commons-io/apidocs/org/apache/commons/io/IOUtils.html">IOUtils</a>.
31 * </p>
32 *
33 * @since 3.21.0
34 */
35 public class AutoCloseables {
36
37 /**
38 * Closes the given {@link AutoCloseable} as a null-safe operation.
39 *
40 * @param closeable The resource to close, may be null.
41 * @throws Exception Thrown if an error occurs.
42 */
43 public static void close(final AutoCloseable closeable) throws Exception {
44 if (closeable != null) {
45 closeable.close();
46 }
47 }
48
49 /**
50 * Closes the given {@link AutoCloseable} as a null-safe operation.
51 *
52 * @param closeable The resource to close, may be null.
53 * @param consumer Consume the Exception thrown by {@link AutoCloseable#close()}.
54 * @throws Exception Thrown if the consumer throws an exception.
55 */
56 public static void close(final AutoCloseable closeable, final FailableConsumer<Exception, Exception> consumer) throws Exception {
57 if (closeable != null) {
58 try {
59 closeable.close();
60 } catch (final Exception e) {
61 FailableConsumer.accept(consumer, e);
62 }
63 }
64 }
65
66 /**
67 * Closes an {@link AutoCloseable}, never throwing an {@link Exception}.
68 * <p>
69 * Equivalent to {@link AutoCloseable#close()}, except any exceptions will be ignored.
70 * </p>
71 *
72 * @param closeable The objects to close, may be null or already closed.
73 * @see Throwable#addSuppressed(Throwable)
74 */
75 public static void closeQuietly(final AutoCloseable closeable) {
76 closeQuietly(closeable, (Consumer<Exception>) null);
77 }
78
79 /**
80 * Closes the given {@link AutoCloseable} as a null-safe operation while consuming Exception by the given {@code consumer}.
81 *
82 * @param closeable The resource to close, may be null.
83 * @param consumer Consumes the Exception thrown by {@link AutoCloseable#close()}.
84 */
85 public static void closeQuietly(final AutoCloseable closeable, final Consumer<Exception> consumer) {
86 if (closeable != null) {
87 try {
88 closeable.close();
89 } catch (final Exception e) {
90 Consumers.accept(consumer, e);
91 }
92 }
93 }
94
95 /**
96 * Closes an iterable of {@link AutoCloseable}, never throwing an {@link Exception}.
97 * <p>
98 * Equivalent calling {@link AutoCloseable#close()} on each element, except any exceptions will be ignored.
99 * </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 }