This is an automated email from the ASF dual-hosted git repository.

ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-io.git

commit 0ad02f84986f7fe0341410a37a8e11a9a8a8cda1
Author: Gary Gregory <garydgreg...@gmail.com>
AuthorDate: Sat Nov 9 10:56:55 2024 -0500

    Add support to AutoCloseInputStream for setting a consumer for
    ProxyInputStream.afterRead(int)
---
 src/changes/changes.xml                            |  2 ++
 .../commons/io/input/AutoCloseInputStream.java     | 12 +++++----
 .../commons/io/input/AutoCloseInputStreamTest.java | 31 ++++++++++++++++++++++
 3 files changed, 40 insertions(+), 5 deletions(-)

diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 181c94dea..1a2c7ec77 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -65,6 +65,8 @@ The <action> type attribute can be add,update,fix,remove.
       <action dev="ggregory" type="add"                due-to="Gary 
Gregory">Add RandomAccessFileMode.accept(Path, 
IOConsumer&lt;RandomAccessFile&gt;).</action>
       <action dev="ggregory" type="add"                due-to="Gary 
Gregory">Add RandomAccessFileMode.apply(Path, 
IOFunction&lt;RandomAccessFile&gt;, T).</action>
       <action dev="ggregory" type="add"                due-to="Gary 
Gregory">Add IOIntConsumer.</action>
+      <action dev="ggregory" type="add" issue="IO-861" due-to="Gary 
Gregory">Add ProxyInputStream.AbstractBuilder. Supports setting a consumer for 
ProxyInputStream.afterRead(int).</action>
+      <action dev="ggregory" type="add"                due-to="Gary 
Gregory">Add support to AutoCloseInputStream for setting a consumer for 
ProxyInputStream.afterRead(int).</action>
       <!-- UPDATE -->
       <action dev="ggregory" type="update"             due-to="Gary 
Gregory">Bump org.apache.commons:commons-parent from 74 to 78 #670, #676, #679, 
#688.</action>
       <action dev="ggregory" type="update"             due-to="Gary 
Gregory">Bump commons.bytebuddy.version from 1.15.1 to 1.15.10 #672, #673, 
#685, #686, #694, #696, #698.</action>
diff --git 
a/src/main/java/org/apache/commons/io/input/AutoCloseInputStream.java 
b/src/main/java/org/apache/commons/io/input/AutoCloseInputStream.java
index aad0fd5e7..2f70b6d2b 100644
--- a/src/main/java/org/apache/commons/io/input/AutoCloseInputStream.java
+++ b/src/main/java/org/apache/commons/io/input/AutoCloseInputStream.java
@@ -21,8 +21,6 @@ import static org.apache.commons.io.IOUtils.EOF;
 import java.io.IOException;
 import java.io.InputStream;
 
-import org.apache.commons.io.build.AbstractStreamBuilder;
-
 /**
  * Proxy stream that closes and discards the underlying stream as soon as the 
end of input has been reached or when the stream is explicitly closed. Not even 
a
  * reference to the underlying stream is kept after it has been closed, so any 
allocated in-memory buffers can be freed even if the client application still
@@ -62,7 +60,7 @@ public class AutoCloseInputStream extends ProxyInputStream {
      * @since 2.13.0
      */
     // @formatter:on
-    public static class Builder extends 
AbstractStreamBuilder<AutoCloseInputStream, Builder> {
+    public static class Builder extends AbstractBuilder<AutoCloseInputStream, 
Builder> {
 
         /**
          * Builds a new {@link AutoCloseInputStream}.
@@ -82,10 +80,9 @@ public class AutoCloseInputStream extends ProxyInputStream {
          * @throws IOException                   if an I/O error occurs.
          * @see #getInputStream()
          */
-        @SuppressWarnings("resource") // Caller closes
         @Override
         public AutoCloseInputStream get() throws IOException {
-            return new AutoCloseInputStream(getInputStream());
+            return new AutoCloseInputStream(this);
         }
 
     }
@@ -112,6 +109,10 @@ public class AutoCloseInputStream extends ProxyInputStream 
{
         super(ClosedInputStream.ifNull(in));
     }
 
+    private AutoCloseInputStream(final Builder builder) throws IOException {
+        super(builder);
+    }
+
     /**
      * Automatically closes the stream if the end of stream was reached.
      *
@@ -124,6 +125,7 @@ public class AutoCloseInputStream extends ProxyInputStream {
         if (n == EOF) {
             close();
         }
+        super.afterRead(n);
     }
 
     /**
diff --git 
a/src/test/java/org/apache/commons/io/input/AutoCloseInputStreamTest.java 
b/src/test/java/org/apache/commons/io/input/AutoCloseInputStreamTest.java
index cff14e648..dbcc27355 100644
--- a/src/test/java/org/apache/commons/io/input/AutoCloseInputStreamTest.java
+++ b/src/test/java/org/apache/commons/io/input/AutoCloseInputStreamTest.java
@@ -19,13 +19,17 @@ package org.apache.commons.io.input;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertFalse;
 import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertThrowsExactly;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+import java.util.concurrent.atomic.AtomicBoolean;
 
 import org.apache.commons.io.IOUtils;
+import org.apache.commons.io.test.CustomIOException;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
@@ -45,6 +49,33 @@ public class AutoCloseInputStreamTest {
         stream = new AutoCloseInputStream(new ByteArrayInputStream(data));
     }
 
+    @Test
+    public void testAfterReadConsumer() throws Exception {
+        final byte[] hello = "Hello".getBytes(StandardCharsets.UTF_8);
+        final AtomicBoolean boolRef = new AtomicBoolean();
+        // @formatter:off
+        try (InputStream bounded = AutoCloseInputStream.builder()
+                .setInputStream(new ByteArrayInputStream(hello))
+                .setAfterRead(i -> boolRef.set(true))
+                .get()) {
+            IOUtils.consume(bounded);
+        }
+        // @formatter:on
+        assertTrue(boolRef.get());
+        // Throwing
+        final String message = "test exception message";
+        // @formatter:off
+        try (InputStream bounded = AutoCloseInputStream.builder()
+                .setInputStream(new ByteArrayInputStream(hello))
+                .setAfterRead(i -> {
+                    throw new CustomIOException(message);
+                })
+                .get()) {
+            assertEquals(message, assertThrowsExactly(CustomIOException.class, 
() -> IOUtils.consume(bounded)).getMessage());
+        }
+        // @formatter:on
+    }
+
     @Test
     public void testAvailableAfterClose() throws IOException {
         final InputStream shadow;

Reply via email to