Rewrite Closer to compile on Java 6 wrt Jar/ZipFile.

Dieser Commit ist enthalten in:
Kenzie Togami 2016-01-31 22:26:30 -08:00
Ursprung 9dac0b30db
Commit 982420369d

Datei anzeigen

@ -29,6 +29,7 @@ import java.util.ArrayDeque;
import java.util.Deque; import java.util.Deque;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import java.util.zip.ZipFile;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
@ -55,6 +56,7 @@ public final class Closer implements Closeable {
// only need space for 2 elements in most cases, so try to use the smallest array possible // only need space for 2 elements in most cases, so try to use the smallest array possible
private final Deque<Closeable> stack = new ArrayDeque<Closeable>(4); private final Deque<Closeable> stack = new ArrayDeque<Closeable>(4);
private final Deque<ZipFile> zipStack = new ArrayDeque<ZipFile>(4);
private Throwable thrown; private Throwable thrown;
@VisibleForTesting Closer(Suppressor suppressor) { @VisibleForTesting Closer(Suppressor suppressor) {
@ -73,6 +75,17 @@ public final class Closer implements Closeable {
return closeable; return closeable;
} }
/**
* Registers the given {@code zipFile} to be closed when this {@code Closer} is
* {@linkplain #close closed}.
*
* @return the given {@code closeable}
*/
public <Z extends ZipFile> Z register(Z zipFile) {
zipStack.push(zipFile);
return zipFile;
}
/** /**
* Stores the given throwable and rethrows it. It will be rethrown as is if it is an * Stores the given throwable and rethrows it. It will be rethrown as is if it is an
* {@code IOException}, {@code RuntimeException} or {@code Error}. Otherwise, it will be rethrown * {@code IOException}, {@code RuntimeException} or {@code Error}. Otherwise, it will be rethrown
@ -161,6 +174,18 @@ public final class Closer implements Closeable {
} }
} }
} }
while (!zipStack.isEmpty()) {
ZipFile zipFile = zipStack.pop();
try {
zipFile.close();
} catch (Throwable e) {
if (throwable == null) {
throwable = e;
} else {
suppressor.suppress(zipFile, throwable, e);
}
}
}
if (thrown == null && throwable != null) { if (thrown == null && throwable != null) {
Throwables.propagateIfPossible(throwable, IOException.class); Throwables.propagateIfPossible(throwable, IOException.class);
@ -177,7 +202,7 @@ public final class Closer implements Closeable {
* the given closeable. {@code thrown} is the exception that is actually being thrown from the * the given closeable. {@code thrown} is the exception that is actually being thrown from the
* method. Implementations of this method should not throw under any circumstances. * method. Implementations of this method should not throw under any circumstances.
*/ */
void suppress(Closeable closeable, Throwable thrown, Throwable suppressed); void suppress(Object closeable, Throwable thrown, Throwable suppressed);
} }
/** /**
@ -188,7 +213,7 @@ public final class Closer implements Closeable {
static final LoggingSuppressor INSTANCE = new LoggingSuppressor(); static final LoggingSuppressor INSTANCE = new LoggingSuppressor();
@Override @Override
public void suppress(Closeable closeable, Throwable thrown, Throwable suppressed) { public void suppress(Object closeable, Throwable thrown, Throwable suppressed) {
// log to the same place as Closeables // log to the same place as Closeables
logger.log(Level.WARNING, "Suppressing exception thrown when closing " + closeable, suppressed); logger.log(Level.WARNING, "Suppressing exception thrown when closing " + closeable, suppressed);
} }
@ -217,7 +242,7 @@ public final class Closer implements Closeable {
} }
@Override @Override
public void suppress(Closeable closeable, Throwable thrown, Throwable suppressed) { public void suppress(Object closeable, Throwable thrown, Throwable suppressed) {
// ensure no exceptions from addSuppressed // ensure no exceptions from addSuppressed
if (thrown == suppressed) { if (thrown == suppressed) {
return; return;