View Javadoc
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 }