net.java.truevfs.kernel.impl.DisconnectingInputService Maven / Gradle / Ivy
/*
* Copyright © 2005 - 2021 Schlichtherle IT Services.
* All rights reserved. Use is subject to license terms.
*/
package net.java.truevfs.kernel.impl;
import edu.umd.cs.findbugs.annotations.DischargesObligation;
import net.java.truecommons.cio.*;
import net.java.truecommons.io.ClosedInputException;
import net.java.truecommons.io.ClosedStreamException;
import net.java.truecommons.io.DisconnectingInputStream;
import net.java.truecommons.io.DisconnectingSeekableChannel;
import javax.annotation.WillCloseWhenClosed;
import javax.annotation.concurrent.NotThreadSafe;
import java.io.IOException;
import java.io.InputStream;
import java.nio.channels.SeekableByteChannel;
import java.util.Iterator;
/**
* Decorates another input service in order to disconnect any resources when this input service gets closed.
* Once {@link #close()}d, all methods of all products of this service, including all sockets, streams etc. but
* excluding {@link #input(String)} and all {@code close()} methods of all products will throw a
* {@link net.java.truecommons.io.ClosedInputException} when called.
*
* @param the type of the entries.
* @author Christian Schlichtherle
* @see DisconnectingOutputService
*/
@NotThreadSafe
final class DisconnectingInputService extends DecoratingInputService {
private final CheckedCloseable cc = new CheckedCloseable(container) {
@Override
ClosedStreamException newClosedStreamException() {
return new ClosedInputException();
}
};
DisconnectingInputService(@WillCloseWhenClosed InputService input) {
super(input);
}
@DischargesObligation
@Override
public void close() throws IOException {
cc.close();
}
boolean isOpen() {
return cc.isOpen();
}
@Override
public int size() {
return cc.checked(new Op() {
@Override
public Integer call() {
return container.size();
}
});
}
@Override
public Iterator iterator() {
return cc.checked(new Op, RuntimeException>() {
@Override
public Iterator call() {
return container.iterator();
}
});
}
@Override
public E entry(String name) {
return cc.checked(new Op() {
@Override
public E call() {
return container.entry(name);
}
});
}
@Override
public InputSocket input(String name) {
return new AbstractInputSocket() {
private final InputSocket socket = container.input(name);
@Override
public E target() throws IOException {
return cc.checked(new Op() {
@Override
public E call() throws IOException {
return socket.target();
}
});
}
@Override
public InputStream stream(OutputSocket extends Entry> peer) throws IOException {
return new DisconnectingInputStreamImpl(cc.checked(new Op() {
@Override
public InputStream call() throws IOException {
return socket.stream(peer);
}
}));
}
@Override
public SeekableByteChannel channel(OutputSocket extends Entry> peer) throws IOException {
return new DisconnectingSeekableChannelImpl(cc.checked(new Op() {
@Override
public SeekableByteChannel call() throws IOException {
return socket.channel(peer);
}
}));
}
};
}
private final class DisconnectingInputStreamImpl extends DisconnectingInputStream {
DisconnectingInputStreamImpl(@WillCloseWhenClosed InputStream in) {
super(in);
}
@Override
public boolean isOpen() {
return cc.isOpen();
}
@DischargesObligation
@Override
public void close() throws IOException {
if (isOpen()) {
in.close();
}
}
}
private final class DisconnectingSeekableChannelImpl extends DisconnectingSeekableChannel {
DisconnectingSeekableChannelImpl(@WillCloseWhenClosed SeekableByteChannel channel) {
super(channel);
}
@Override
public boolean isOpen() {
return cc.isOpen();
}
@DischargesObligation
@Override
public void close() throws IOException {
if (isOpen()) {
channel.close();
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy