Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
de.schlichtherle.truezip.fs.FsFinalizeController Maven / Gradle / Ivy
/*
* Copyright (C) 2005-2015 Schlichtherle IT Services.
* All rights reserved. Use is subject to license terms.
*/
package de.schlichtherle.truezip.fs;
import de.schlichtherle.truezip.entry.Entry;
import de.schlichtherle.truezip.io.DecoratingInputStream;
import de.schlichtherle.truezip.io.DecoratingOutputStream;
import de.schlichtherle.truezip.io.DecoratingSeekableByteChannel;
import de.schlichtherle.truezip.rof.DecoratingReadOnlyFile;
import de.schlichtherle.truezip.rof.ReadOnlyFile;
import de.schlichtherle.truezip.socket.DecoratingInputSocket;
import de.schlichtherle.truezip.socket.DecoratingOutputSocket;
import de.schlichtherle.truezip.socket.InputSocket;
import de.schlichtherle.truezip.socket.OutputSocket;
import de.schlichtherle.truezip.util.BitField;
import de.schlichtherle.truezip.util.ControlFlowException;
import de.schlichtherle.truezip.util.JSE7;
import edu.umd.cs.findbugs.annotations.CreatesObligation;
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.channels.SeekableByteChannel;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.CheckForNull;
import javax.annotation.WillCloseWhenClosed;
import javax.annotation.concurrent.Immutable;
import javax.annotation.concurrent.ThreadSafe;
/**
* Finalizes unclosed resources returned by its decorated controller.
*
* @param the type of the file system model.
* @since TrueZIP 7.5
* @author Christian Schlichtherle
*/
@ThreadSafe
final class FsFinalizeController
extends FsDecoratingController> {
private static final Logger logger = Logger.getLogger(
FsFinalizeController.class.getName(),
FsFinalizeController.class.getName());
private static final SocketFactory SOCKET_FACTORY = JSE7.AVAILABLE
? SocketFactory.NIO2
: SocketFactory.OIO;
private static final IOException OK = new IOException((Throwable) null);
/**
* Constructs a new file system finalize controller.
*
* @param controller the decorated file system controller.
*/
FsFinalizeController(FsController extends M> controller) {
super(controller);
}
@Override
public InputSocket> getInputSocket( FsEntryName name,
BitField options) {
return SOCKET_FACTORY.newInputSocket(this, name, options);
}
@Override
public OutputSocket> getOutputSocket( FsEntryName name,
BitField options,
@CheckForNull Entry template) {
return SOCKET_FACTORY.newOutputSocket(this, name, options, template);
}
static void finalize( final Closeable delegate,
final @CheckForNull IOException close) {
if (OK == close) {
logger.log(Level.FINEST, "closeCleared");
} else if (null != close) {
logger.log(Level.FINEST, "closeFailed", close);
} else {
try {
delegate.close();
logger.log(Level.INFO, "finalizeCleared");
} catch (final ControlFlowException ex) { // log and swallow!
logger.log(Level.SEVERE, "finalizeFailed",
new AssertionError("Unexpected control flow exception!", ex));
} catch (final Throwable ex) { // log and swallow!
logger.log(Level.WARNING, "finalizeFailed", ex);
}
}
}
@Immutable
private enum SocketFactory {
NIO2() {
@Override
InputSocket> newInputSocket(
FsFinalizeController> controller,
FsEntryName name,
BitField options) {
return controller.new Nio2Input(name, options);
}
@Override
OutputSocket> newOutputSocket(
FsFinalizeController> controller,
FsEntryName name,
BitField options,
@CheckForNull Entry template) {
return controller.new Nio2Output(name, options, template);
}
},
OIO() {
@Override
InputSocket> newInputSocket(
FsFinalizeController> controller,
FsEntryName name,
BitField options) {
return controller.new Input(name, options);
}
@Override
OutputSocket> newOutputSocket(
FsFinalizeController> controller,
FsEntryName name,
BitField options,
@CheckForNull Entry template) {
return controller.new Output(name, options, template);
}
};
abstract InputSocket> newInputSocket(
FsFinalizeController> controller,
FsEntryName name,
BitField options);
abstract OutputSocket> newOutputSocket(
FsFinalizeController> controller,
FsEntryName name,
BitField options,
@CheckForNull Entry template);
} // SocketFactory
@Immutable
private final class Nio2Input extends Input {
Nio2Input( final FsEntryName name,
final BitField options) {
super(name, options);
}
@Override
public SeekableByteChannel newSeekableByteChannel() throws IOException {
return new FinalizeSeekableByteChannel(
getBoundSocket().newSeekableByteChannel());
}
} // Nio2Input
@Immutable
private class Input extends DecoratingInputSocket {
Input( final FsEntryName name,
final BitField options) {
super(FsFinalizeController.this.delegate
.getInputSocket(name, options));
}
@Override
public ReadOnlyFile newReadOnlyFile() throws IOException {
return new FinalizeReadOnlyFile(
getBoundSocket().newReadOnlyFile());
}
@Override
public InputStream newInputStream() throws IOException {
return new FinalizeInputStream(
getBoundSocket().newInputStream());
}
} // Input
@Immutable
private final class Nio2Output extends Output {
Nio2Output( final FsEntryName name,
final BitField options,
final @CheckForNull Entry template) {
super(name, options, template);
}
@Override
public SeekableByteChannel newSeekableByteChannel() throws IOException {
return new FinalizeSeekableByteChannel(
getBoundSocket().newSeekableByteChannel());
}
} // Nio2Output
@Immutable
private class Output extends DecoratingOutputSocket {
Output( final FsEntryName name,
final BitField options,
final @CheckForNull Entry template) {
super(FsFinalizeController.this.delegate
.getOutputSocket(name, options, template));
}
@Override
@edu.umd.cs.findbugs.annotations.SuppressWarnings("OBL_UNSATISFIED_OBLIGATION") // false positive
public OutputStream newOutputStream() throws IOException {
return new FinalizeOutputStream(
getBoundSocket().newOutputStream());
}
} // Output
private static final class FinalizeReadOnlyFile
extends DecoratingReadOnlyFile {
volatile IOException close; // accessed by finalizer thread!
@CreatesObligation
@edu.umd.cs.findbugs.annotations.SuppressWarnings("OBL_UNSATISFIED_OBLIGATION")
FinalizeReadOnlyFile(@WillCloseWhenClosed ReadOnlyFile rof) {
super(rof);
}
@Override
public void close() throws IOException {
try {
delegate.close();
close = OK;
} catch (final IOException ex) {
throw close = ex;
}
}
@Override
@SuppressWarnings("FinalizeDeclaration")
protected void finalize() throws Throwable {
try {
FsFinalizeController.finalize(delegate, close);
} finally {
super.finalize();
}
}
} // FinalizeReadOnlyFile
private static final class FinalizeSeekableByteChannel
extends DecoratingSeekableByteChannel {
volatile IOException close; // accessed by finalizer thread!
@CreatesObligation
@edu.umd.cs.findbugs.annotations.SuppressWarnings("OBL_UNSATISFIED_OBLIGATION")
FinalizeSeekableByteChannel(@WillCloseWhenClosed SeekableByteChannel sbc) {
super(sbc);
}
@Override
public void close() throws IOException {
try {
delegate.close();
close = OK;
} catch (final IOException ex) {
throw close = ex;
}
}
@Override
@SuppressWarnings("FinalizeDeclaration")
protected void finalize() throws Throwable {
try {
FsFinalizeController.finalize(delegate, close);
} finally {
super.finalize();
}
}
} // FinalizeSeekableByteChannel
private static final class FinalizeInputStream
extends DecoratingInputStream {
volatile IOException close; // accessed by finalizer thread!
@CreatesObligation
@edu.umd.cs.findbugs.annotations.SuppressWarnings("OBL_UNSATISFIED_OBLIGATION")
FinalizeInputStream(@WillCloseWhenClosed InputStream in) {
super(in);
}
@Override
public void close() throws IOException {
try {
delegate.close();
close = OK;
} catch (final IOException ex) {
throw close = ex;
}
}
@Override
@SuppressWarnings("FinalizeDeclaration")
protected void finalize() throws Throwable {
try {
FsFinalizeController.finalize(delegate, close);
} finally {
super.finalize();
}
}
} // FinalizeInputStream
private static final class FinalizeOutputStream
extends DecoratingOutputStream {
volatile IOException close; // accessed by finalizer thread!
@CreatesObligation
@edu.umd.cs.findbugs.annotations.SuppressWarnings("OBL_UNSATISFIED_OBLIGATION")
FinalizeOutputStream(@WillCloseWhenClosed OutputStream out) {
super(out);
}
@Override
public void close() throws IOException {
try {
delegate.close();
close = OK;
} catch (final IOException ex) {
throw close = ex;
}
}
@Override
@SuppressWarnings("FinalizeDeclaration")
protected void finalize() throws Throwable {
try {
FsFinalizeController.finalize(delegate, close);
} finally {
super.finalize();
}
}
} // FinalizeOutputStream
}