1 package org.apache.lucene.util;
4 * Licensed to the Apache Software Foundation (ASF) under one or more
5 * contributor license agreements. See the NOTICE file distributed with
6 * this work for additional information regarding copyright ownership.
7 * The ASF licenses this file to You under the Apache License, Version 2.0
8 * (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
20 import java.io.Closeable;
21 import java.io.IOException;
22 import java.lang.reflect.Method;
24 /** This class emulates the new Java 7 "Try-With-Resources" statement.
25 * Remove once Lucene is on Java 7.
27 public final class IOUtils {
29 private IOUtils() {} // no instance
32 * <p>Closes all given <tt>Closeable</tt>s, suppressing all thrown exceptions. Some of the <tt>Closeable</tt>s
33 * may be null, they are ignored. After everything is closed, method either throws <tt>priorException</tt>,
34 * if one is supplied, or the first of suppressed exceptions, or completes normally.</p>
35 * <p>Sample usage:<br/>
37 * Closeable resource1 = null, resource2 = null, resource3 = null;
38 * ExpectedException priorE = null;
40 * resource1 = ...; resource2 = ...; resource3 = ...; // Acquisition may throw ExpectedException
41 * ..do..stuff.. // May throw ExpectedException
42 * } catch (ExpectedException e) {
45 * closeSafely(priorE, resource1, resource2, resource3);
49 * @param priorException <tt>null</tt> or an exception that will be rethrown after method completion
50 * @param objects objects to call <tt>close()</tt> on
52 public static <E extends Exception> void closeWhileHandlingException(E priorException, Closeable... objects) throws E, IOException {
55 for (Closeable object : objects) {
60 } catch (Throwable t) {
61 addSuppressed((priorException == null) ? th : priorException, t);
68 if (priorException != null) {
70 } else if (th != null) {
71 if (th instanceof IOException) throw (IOException) th;
72 if (th instanceof RuntimeException) throw (RuntimeException) th;
73 if (th instanceof Error) throw (Error) th;
74 throw new RuntimeException(th);
78 /** @see #closeWhileHandlingException(Exception, Closeable...) */
79 public static <E extends Exception> void closeWhileHandlingException(E priorException, Iterable<Closeable> objects) throws E, IOException {
82 for (Closeable object : objects) {
87 } catch (Throwable t) {
88 addSuppressed((priorException == null) ? th : priorException, t);
95 if (priorException != null) {
97 } else if (th != null) {
98 if (th instanceof IOException) throw (IOException) th;
99 if (th instanceof RuntimeException) throw (RuntimeException) th;
100 if (th instanceof Error) throw (Error) th;
101 throw new RuntimeException(th);
106 * Closes all given <tt>Closeable</tt>s. Some of the
107 * <tt>Closeable</tt>s may be null; they are
108 * ignored. After everything is closed, the method either
109 * throws the first exception it hit while closing, or
110 * completes normally if there were no exceptions.
113 * objects to call <tt>close()</tt> on
115 public static void close(Closeable... objects) throws IOException {
118 for (Closeable object : objects) {
120 if (object != null) {
123 } catch (Throwable t) {
124 addSuppressed(th, t);
132 if (th instanceof IOException) throw (IOException) th;
133 if (th instanceof RuntimeException) throw (RuntimeException) th;
134 if (th instanceof Error) throw (Error) th;
135 throw new RuntimeException(th);
140 * @see #close(Closeable...)
142 public static void close(Iterable<? extends Closeable> objects) throws IOException {
145 for (Closeable object : objects) {
147 if (object != null) {
150 } catch (Throwable t) {
151 addSuppressed(th, t);
159 if (th instanceof IOException) throw (IOException) th;
160 if (th instanceof RuntimeException) throw (RuntimeException) th;
161 if (th instanceof Error) throw (Error) th;
162 throw new RuntimeException(th);
167 * Closes all given <tt>Closeable</tt>s, suppressing all thrown exceptions.
168 * Some of the <tt>Closeable</tt>s may be null, they are ignored.
171 * objects to call <tt>close()</tt> on
173 public static void closeWhileHandlingException(Closeable... objects) throws IOException {
174 for (Closeable object : objects) {
176 if (object != null) {
179 } catch (Throwable t) {
185 * @see #closeWhileHandlingException(Closeable...)
187 public static void closeWhileHandlingException(Iterable<? extends Closeable> objects) throws IOException {
188 for (Closeable object : objects) {
190 if (object != null) {
193 } catch (Throwable t) {
198 /** This reflected {@link Method} is {@code null} before Java 7 */
199 private static final Method SUPPRESS_METHOD;
203 m = Throwable.class.getMethod("addSuppressed", Throwable.class);
204 } catch (Exception e) {
210 /** adds a Throwable to the list of suppressed Exceptions of the first Throwable (if Java 7 is detected)
211 * @param exception this exception should get the suppressed one added
212 * @param suppressed the suppressed exception
214 private static final void addSuppressed(Throwable exception, Throwable suppressed) {
215 if (SUPPRESS_METHOD != null && exception != null && suppressed != null) {
217 SUPPRESS_METHOD.invoke(exception, suppressed);
218 } catch (Exception e) {
219 // ignore any exceptions caused by invoking (e.g. security constraints)