diff --git a/src/main/java/org/apache/commons/io/channels/ByteArraySeekableByteChannel.java b/src/main/java/org/apache/commons/io/channels/ByteArraySeekableByteChannel.java
index 3edfd3c0978..57c38124875 100644
--- a/src/main/java/org/apache/commons/io/channels/ByteArraySeekableByteChannel.java
+++ b/src/main/java/org/apache/commons/io/channels/ByteArraySeekableByteChannel.java
@@ -104,12 +104,14 @@ public static Builder builder() {
/**
* Constructs a new channel backed directly by the given byte array.
*
- *
The channel initially contains the full contents of the array, with its
- * size set to {@code bytes.length} and its position set to {@code 0}.
+ *
+ * The channel initially contains the full contents of the array, with its size set to {@code bytes.length} and its position set to {@code 0}.
+ *
*
- * Reads and writes operate on the shared array.
- * If a write operation extends beyond the current capacity, the channel will
- * automatically allocate a larger backing array and copy the existing contents.
+ *
+ * Reads and writes operate on the shared array. If a write operation extends beyond the current capacity, the channel will automatically allocate a larger
+ * backing array and copy the existing contents.
+ *
*
* @param bytes The byte array to wrap, must not be {@code null}
* @return A new channel that uses the given array as its initial backing store.
diff --git a/src/main/java/org/apache/commons/io/channels/CloseShieldChannel.java b/src/main/java/org/apache/commons/io/channels/CloseShieldChannel.java
index ba890d8a6a7..987e8427c7c 100644
--- a/src/main/java/org/apache/commons/io/channels/CloseShieldChannel.java
+++ b/src/main/java/org/apache/commons/io/channels/CloseShieldChannel.java
@@ -36,11 +36,13 @@
/**
* Creates a close-shielding proxy for a {@link Channel}.
*
- * The returned proxy implements all {@link Channel} sub-interfaces that are both supported by this implementation and actually implemented by the given
- * delegate.
- *
- * The following interfaces are supported:
- *
+ *
+ * The returned proxy implements all {@link Channel} sub-interfaces that are both supported by this implementation and actually implemented by the given
+ * delegate.
+ *
+ *
+ * The following interfaces are supported:
+ *
*
* - {@link AsynchronousChannel}
* - {@link ByteChannel}
diff --git a/src/main/java/org/apache/commons/io/channels/CloseShieldChannelHandler.java b/src/main/java/org/apache/commons/io/channels/CloseShieldChannelHandler.java
index fdafd544f07..822c6b6186b 100644
--- a/src/main/java/org/apache/commons/io/channels/CloseShieldChannelHandler.java
+++ b/src/main/java/org/apache/commons/io/channels/CloseShieldChannelHandler.java
@@ -37,6 +37,9 @@
import java.util.Objects;
import java.util.Set;
+/**
+ * An {@link InvocationHandler} supporting the implementation of {@link CloseShieldChannel}.
+ */
final class CloseShieldChannelHandler implements InvocationHandler {
private static final Set> SUPPORTED_INTERFACES;
@@ -154,7 +157,7 @@ private Object invokeObjectMethod(final Object proxy, final Method method, final
return false;
}
default:
- // Not possible, all non-final Object methods are handled above
+ // Not possible, all non-final Object methods are handled above.
return null;
}
}
diff --git a/src/main/java/org/apache/commons/io/channels/FilterByteChannel.java b/src/main/java/org/apache/commons/io/channels/FilterByteChannel.java
index 4bd17f2d0ce..bcce45486b5 100644
--- a/src/main/java/org/apache/commons/io/channels/FilterByteChannel.java
+++ b/src/main/java/org/apache/commons/io/channels/FilterByteChannel.java
@@ -31,6 +31,16 @@
/**
* A {@link ByteChannel} filter which delegates to the wrapped {@link ByteChannel}.
+ *
+ * A {@code FilterByteChannel} wraps some other channel, which it uses as its basic source of data, possibly transforming the data along the way or providing
+ * additional functionality. The class {@code FilterByteChannel} itself simply overrides methods of {@code ByteChannel} with versions that pass all requests to
+ * the wrapped channel. Subclasses of {@code FilterByteChannel} may of course override any methods declared or inherited by {@code FilterByteChannel}, and may
+ * also provide additional fields and methods.
+ *
+ *
+ * You construct s simple instance with the {@link FilterByteChannel#FilterByteChannel(ByteChannel) channel constructor} and more advanced instances through the
+ * {@link Builder}.
+ *
*
* @param the {@link ByteChannel} type.
* @see FilterInputStream
@@ -94,6 +104,15 @@ public static Builder forByteChannel() {
super(builder);
}
+ /**
+ * Constructs a new instance.
+ *
+ * @param byteChannel The channel to wrap.
+ */
+ public FilterByteChannel(final C byteChannel) {
+ super(byteChannel);
+ }
+
@Override
public int read(final ByteBuffer dst) throws IOException {
return channel.read(dst);
diff --git a/src/main/java/org/apache/commons/io/channels/FilterChannel.java b/src/main/java/org/apache/commons/io/channels/FilterChannel.java
index a77a4d45566..e76dd962082 100644
--- a/src/main/java/org/apache/commons/io/channels/FilterChannel.java
+++ b/src/main/java/org/apache/commons/io/channels/FilterChannel.java
@@ -31,6 +31,16 @@
/**
* A {@link Channel} filter which delegates to the wrapped {@link Channel}.
+ *
+ * A {@code FilterChannel} wraps some other channel, which it uses as its basic source of data, possibly transforming the data along the way or providing
+ * additional functionality. The class {@code FilterChannel} itself simply overrides methods of {@code Channel} with versions that pass all requests to the
+ * wrapped channel. Subclasses of {@code FilterChannel} may of course override any methods declared or inherited by {@code FilterChannel}, and may also provide
+ * additional fields and methods.
+ *
+ *
+ * You construct s simple instance with the {@link FilterChannel#FilterChannel(Channel) channel constructor} and more advanced instances through the
+ * {@link Builder}.
+ *
*
* @param the {@link Channel} type.
* @see FilterInputStream
@@ -103,6 +113,15 @@ public static Builder forChannel() {
channel = (C) builder.getChannel(Channel.class);
}
+ /**
+ * Constructs a new instance.
+ *
+ * @param channel The channel to wrap.
+ */
+ public FilterChannel(final C channel) {
+ this.channel = channel;
+ }
+
@Override
public void close() throws IOException {
channel.close();
diff --git a/src/main/java/org/apache/commons/io/channels/FilterFileChannel.java b/src/main/java/org/apache/commons/io/channels/FilterFileChannel.java
index f5861c0c970..c37d30dbf23 100644
--- a/src/main/java/org/apache/commons/io/channels/FilterFileChannel.java
+++ b/src/main/java/org/apache/commons/io/channels/FilterFileChannel.java
@@ -20,22 +20,89 @@
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
+import java.nio.channels.Channel;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;
import java.util.Objects;
+import org.apache.commons.io.build.AbstractStreamBuilder;
+
/**
* Filters a {@link FileChannel}.
+ *
+ * A {@code FilterFileChannel} wraps some other channel, which it uses as its basic source of data, possibly transforming the data along the way or providing
+ * additional functionality. The class {@code FilterFileChannel} itself simply overrides methods of {@code FileChannel} with versions that pass all requests to
+ * the wrapped channel. Subclasses of {@code FilterFileChannel} may of course override any methods declared or inherited by {@code FilterFileChannel}, and may
+ * also provide additional fields and methods.
+ *
+ *
+ * You construct s simple instance with the {@link FilterFileChannel#FilterFileChannel(FileChannel) channel constructor} and more advanced instances through the
+ * {@link Builder}.
+ *
*
* @since 2.22.0
*/
public class FilterFileChannel extends FileChannel {
+ /**
+ * Builds instances of {@link FilterFileChannel} for subclasses.
+ *
+ * @param The {@link FilterFileChannel} type.
+ * @param The {@link Channel} type wrapped by the FilterChannel.
+ * @param The builder type.
+ */
+ public abstract static class AbstractBuilder>
+ extends AbstractStreamBuilder> {
+
+ /**
+ * Constructs instance for subclasses.
+ */
+ protected AbstractBuilder() {
+ // empty
+ }
+ }
+
+ /**
+ * Builds instances of {@link FilterFileChannel}.
+ */
+ public static class Builder extends AbstractBuilder {
+
+ /**
+ * Builds instances of {@link FilterChannel}.
+ */
+ protected Builder() {
+ // empty
+ }
+
+ @Override
+ public FilterFileChannel get() throws IOException {
+ return new FilterFileChannel(this);
+ }
+ }
+
+ /**
+ * Creates a new {@link Builder}.
+ *
+ * @return a new {@link Builder}.
+ */
+ public static Builder forFilterFileChannel() {
+ return new Builder();
+ }
+
final FileChannel fileChannel;
- FilterFileChannel(final FileChannel fileChannel) {
+ private FilterFileChannel(final Builder builder) throws IOException {
+ this.fileChannel = builder.getChannel(FileChannel.class);
+ }
+
+ /**
+ * Constructs a new instance.
+ *
+ * @param fileChannel the file channel to wrap.
+ */
+ public FilterFileChannel(final FileChannel fileChannel) {
this.fileChannel = Objects.requireNonNull(fileChannel, "fileChannel");
}
diff --git a/src/main/java/org/apache/commons/io/channels/FilterReadableByteChannel.java b/src/main/java/org/apache/commons/io/channels/FilterReadableByteChannel.java
index d29ce815c3a..377d3b1d043 100644
--- a/src/main/java/org/apache/commons/io/channels/FilterReadableByteChannel.java
+++ b/src/main/java/org/apache/commons/io/channels/FilterReadableByteChannel.java
@@ -31,6 +31,16 @@
/**
* A {@link ReadableByteChannel} filter which delegates to the wrapped {@link ReadableByteChannel}.
+ *
+ * A {@code FilterReadableByteChannel} wraps some other channel, which it uses as its basic source of data, possibly transforming the data along the way or
+ * providing additional functionality. The class {@code FilterReadableByteChannel} itself simply overrides methods of {@code ReadableByteChannel} with versions
+ * that pass all requests to the wrapped channel. Subclasses of {@code FilterReadableByteChannel} may of course override any methods declared or inherited by
+ * {@code FilterReadableByteChannel}, and may also provide additional fields and methods.
+ *
+ *
+ * You construct s simple instance with the {@link FilterReadableByteChannel#FilterReadableByteChannel(ReadableByteChannel) channel constructor} and more
+ * advanced instances through the {@link Builder}.
+ *
*
* @param the {@link ReadableByteChannel} type.
* @see FilterInputStream
@@ -94,6 +104,15 @@ public static Builder forReadableByteChannel() {
super(builder);
}
+ /**
+ * Constructs a new instance.
+ *
+ * @param channel The channel to wrap.
+ */
+ public FilterReadableByteChannel(final C channel) {
+ super(channel);
+ }
+
@Override
public int read(final ByteBuffer dst) throws IOException {
return channel.read(dst);
diff --git a/src/main/java/org/apache/commons/io/channels/FilterSeekableByteChannel.java b/src/main/java/org/apache/commons/io/channels/FilterSeekableByteChannel.java
index b36d0b471a9..11fbadc2c15 100644
--- a/src/main/java/org/apache/commons/io/channels/FilterSeekableByteChannel.java
+++ b/src/main/java/org/apache/commons/io/channels/FilterSeekableByteChannel.java
@@ -30,6 +30,16 @@
/**
* A {@link SeekableByteChannel} filter which delegates to the wrapped {@link SeekableByteChannel}.
+ *
+ * A {@code FilterSeekableByteChannel} wraps some other channel, which it uses as its basic source of data, possibly transforming the data along the way or
+ * providing additional functionality. The class {@code FilterSeekableByteChannel} itself simply overrides methods of {@code SeekableByteChannel} with versions
+ * that pass all requests to the wrapped channel. Subclasses of {@code FilterSeekableByteChannel} may of course override any methods declared or inherited by
+ * {@code FilterSeekableByteChannel}, and may also provide additional fields and methods.
+ *
+ *
+ * You construct s simple instance with the {@link FilterSeekableByteChannel#FilterSeekableByteChannel(SeekableByteChannel) Channel constructor} and more
+ * advanced instances through the {@link Builder}.
+ *
*
* @param the {@link SeekableByteChannel} type.
* @see FilterInputStream
@@ -93,6 +103,15 @@ public static Builder forSeekableByteChannel() {
super(builder);
}
+ /**
+ * Constructs a new instance.
+ *
+ * @param channel The channel to wrap.
+ */
+ public FilterSeekableByteChannel(final C channel) {
+ super(channel);
+ }
+
@Override
public long position() throws IOException {
return channel.position();
diff --git a/src/main/java/org/apache/commons/io/channels/FilterWritableByteChannel.java b/src/main/java/org/apache/commons/io/channels/FilterWritableByteChannel.java
index da2f3381758..f07e8988c91 100644
--- a/src/main/java/org/apache/commons/io/channels/FilterWritableByteChannel.java
+++ b/src/main/java/org/apache/commons/io/channels/FilterWritableByteChannel.java
@@ -31,6 +31,16 @@
/**
* A {@link WritableByteChannel} filter which delegates to the wrapped {@link WritableByteChannel}.
+ *
+ * A {@code FilterWritableByteChannel} wraps some other channel, which it uses as its basic source of data, possibly transforming the data along the way or
+ * providing additional functionality. The class {@code FilterWritableByteChannel} itself simply overrides methods of {@code WritableByteChannel} with versions
+ * that pass all requests to the wrapped channel. Subclasses of {@code FilterWritableByteChannel} may of course override any methods declared or inherited by
+ * {@code WritableByteChannel}, and may also provide additional fields and methods.
+ *
+ *
+ * You construct s simple instance with the {@link FilterWritableByteChannel#FilterWritableByteChannel(WritableByteChannel) Channel constructor} and more
+ * advanced instances through the {@link Builder}.
+ *
*
* @param the {@link WritableByteChannel} type.
* @see FilterInputStream
@@ -94,6 +104,15 @@ public static Builder forWritableByteChannel() {
super(builder);
}
+ /**
+ * Constructs a new instance.
+ *
+ * @param channel The channel to wrap.
+ */
+ public FilterWritableByteChannel(final C channel) {
+ super(channel);
+ }
+
@Override
public int write(final ByteBuffer src) throws IOException {
return channel.write(src);
diff --git a/src/test/java/org/apache/commons/io/channels/CloseShieldChannelFilterByteChannelTest.java b/src/test/java/org/apache/commons/io/channels/CloseShieldChannelFilterByteChannelTest.java
index 3613edd3697..fb73a11dccc 100644
--- a/src/test/java/org/apache/commons/io/channels/CloseShieldChannelFilterByteChannelTest.java
+++ b/src/test/java/org/apache/commons/io/channels/CloseShieldChannelFilterByteChannelTest.java
@@ -55,7 +55,7 @@ class CloseShieldChannelFilterByteChannelTest {
@BeforeEach
void setUp() throws IOException {
mockChannel = mock(ByteChannel.class);
- filterChannel = FilterByteChannel.forByteChannel().setChannel(mockChannel).get();
+ filterChannel = new FilterByteChannel<>(mockChannel);
shield = CloseShieldChannel.wrap(filterChannel);
}
diff --git a/src/test/java/org/apache/commons/io/channels/FilterFileChannelTest.java b/src/test/java/org/apache/commons/io/channels/FilterFileChannelTest.java
index 9b539e4944d..cfd78ae3f00 100644
--- a/src/test/java/org/apache/commons/io/channels/FilterFileChannelTest.java
+++ b/src/test/java/org/apache/commons/io/channels/FilterFileChannelTest.java
@@ -53,9 +53,14 @@ private FileChannel mockFileChannel() {
return mock(FileChannel.class);
}
+ @Test
+ void testBuilderForNothing() throws IOException {
+ assertThrows(IllegalStateException.class, () -> FilterFileChannel.forFilterFileChannel().get());
+ }
+
@Test
void testConstructorRequiresNonNullChannel() {
- assertThrows(NullPointerException.class, () -> new FilterFileChannel(null));
+ assertThrows(NullPointerException.class, () -> new FilterFileChannel((FileChannel) null));
}
@Test
diff --git a/src/test/java/org/apache/commons/io/channels/FilterReadableByteChannelTest.java b/src/test/java/org/apache/commons/io/channels/FilterReadableByteChannelTest.java
index 48530546e4c..585b5e81da0 100644
--- a/src/test/java/org/apache/commons/io/channels/FilterReadableByteChannelTest.java
+++ b/src/test/java/org/apache/commons/io/channels/FilterReadableByteChannelTest.java
@@ -40,7 +40,7 @@
class FilterReadableByteChannelTest {
private FilterReadableByteChannel build(final ReadableByteChannel channel) throws IOException {
- return FilterReadableByteChannel.forReadableByteChannel().setChannel(channel).get();
+ return new FilterReadableByteChannel(channel);
}
@Test
diff --git a/src/test/java/org/apache/commons/io/channels/FilterSeekableByteChannelTest.java b/src/test/java/org/apache/commons/io/channels/FilterSeekableByteChannelTest.java
index 8f71c38d1f2..997eac4dd8c 100644
--- a/src/test/java/org/apache/commons/io/channels/FilterSeekableByteChannelTest.java
+++ b/src/test/java/org/apache/commons/io/channels/FilterSeekableByteChannelTest.java
@@ -40,7 +40,7 @@
class FilterSeekableByteChannelTest {
private FilterSeekableByteChannel build(final SeekableByteChannel channel) throws IOException {
- return FilterSeekableByteChannel.forSeekableByteChannel().setChannel(channel).get();
+ return new FilterSeekableByteChannel(channel);
}
@Test
diff --git a/src/test/java/org/apache/commons/io/channels/FilterWritableByteChannelTest.java b/src/test/java/org/apache/commons/io/channels/FilterWritableByteChannelTest.java
index 42ee4cb7251..a9dd60dc9a0 100644
--- a/src/test/java/org/apache/commons/io/channels/FilterWritableByteChannelTest.java
+++ b/src/test/java/org/apache/commons/io/channels/FilterWritableByteChannelTest.java
@@ -40,7 +40,7 @@
class FilterWritableByteChannelTest {
private FilterWritableByteChannel build(final WritableByteChannel channel) throws IOException {
- return FilterWritableByteChannel.forWritableByteChannel().setChannel(channel).get();
+ return new FilterWritableByteChannel(channel);
}
@Test