Skip to content

Commit f79a3d6

Browse files
committed
Add support to ObservableInputStream for setting a consumer for
ProxyInputStream.afterRead(int)
1 parent 4c1e110 commit f79a3d6

3 files changed

Lines changed: 71 additions & 0 deletions

File tree

src/changes/changes.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ The <action> type attribute can be add,update,fix,remove.
7171
<action dev="ggregory" type="add" issue="IO-861" due-to="Gary Gregory">Add support to BoundedInputStream for setting a consumer for ProxyInputStream.afterRead(int).</action>
7272
<action dev="ggregory" type="add" due-to="Gary Gregory">Add support to ChecksumInputStream for setting a consumer for ProxyInputStream.afterRead(int).</action>
7373
<action dev="ggregory" type="add" due-to="Gary Gregory">Add support to ThrottledInputStream for setting a consumer for ProxyInputStream.afterRead(int).</action>
74+
<action dev="ggregory" type="add" due-to="Gary Gregory">Add support to ObservableInputStream for setting a consumer for ProxyInputStream.afterRead(int).</action>
7475
<!-- UPDATE -->
7576
<action dev="ggregory" type="update" due-to="Gary Gregory">Bump org.apache.commons:commons-parent from 74 to 78 #670, #676, #679, #688.</action>
7677
<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>

src/main/java/org/apache/commons/io/input/ObservableInputStream.java

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,42 @@
4343
*/
4444
public class ObservableInputStream extends ProxyInputStream {
4545

46+
/**
47+
* For subclassing builders from {@link BoundedInputStream} subclassses.
48+
*
49+
* @param <T> The subclass.
50+
* @since 2.18.0
51+
*/
52+
public static abstract class AbstractBuilder<T extends AbstractBuilder<T>> extends ProxyInputStream.AbstractBuilder<ObservableInputStream, T> {
53+
54+
private List<Observer> observers;
55+
56+
/**
57+
* Sets the list of observer callbacks.
58+
*
59+
* @param observers The list of observer callbacks.
60+
*/
61+
public void setObservers(final List<Observer> observers) {
62+
this.observers = observers;
63+
}
64+
65+
}
66+
67+
68+
/**
69+
* Builds instances of {@link ObservableInputStream}.
70+
*
71+
* @since 2.18.0
72+
*/
73+
public static class Builder extends AbstractBuilder<Builder> {
74+
75+
@Override
76+
public ObservableInputStream get() throws IOException {
77+
return new ObservableInputStream(this);
78+
}
79+
80+
}
81+
4682
/**
4783
* Abstracts observer callback for {@link ObservableInputStream}s.
4884
*/
@@ -109,6 +145,11 @@ public void finished() throws IOException {
109145

110146
private final List<Observer> observers;
111147

148+
ObservableInputStream(final AbstractBuilder builder) throws IOException {
149+
super(builder);
150+
this.observers = builder.observers;
151+
}
152+
112153
/**
113154
* Constructs a new ObservableInputStream for the given InputStream.
114155
*

src/test/java/org/apache/commons/io/input/ObservableInputStreamTest.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,17 +20,20 @@
2020
import static org.junit.jupiter.api.Assertions.assertNotEquals;
2121
import static org.junit.jupiter.api.Assertions.assertNull;
2222
import static org.junit.jupiter.api.Assertions.assertThrows;
23+
import static org.junit.jupiter.api.Assertions.assertThrowsExactly;
2324
import static org.junit.jupiter.api.Assertions.assertTrue;
2425

2526
import java.io.ByteArrayInputStream;
2627
import java.io.IOException;
2728
import java.io.InputStream;
2829
import java.nio.file.Files;
2930
import java.nio.file.Paths;
31+
import java.util.concurrent.atomic.AtomicBoolean;
3032

3133
import org.apache.commons.io.IOUtils;
3234
import org.apache.commons.io.input.ObservableInputStream.Observer;
3335
import org.apache.commons.io.output.NullOutputStream;
36+
import org.apache.commons.io.test.CustomIOException;
3437
import org.junit.jupiter.api.Test;
3538

3639
/**
@@ -143,6 +146,32 @@ private ObservableInputStream createInputStream(final InputStream origin) {
143146
return new ObservableInputStream(origin);
144147
}
145148

149+
@Test
150+
public void testAfterReadConsumer() throws Exception {
151+
final AtomicBoolean boolRef = new AtomicBoolean();
152+
// @formatter:off
153+
try (InputStream bounded = new ObservableInputStream.Builder()
154+
.setCharSequence("Hi")
155+
.setAfterRead(i -> boolRef.set(true))
156+
.get()) {
157+
IOUtils.consume(bounded);
158+
}
159+
// @formatter:on
160+
assertTrue(boolRef.get());
161+
// Throwing
162+
final String message = "test exception message";
163+
// @formatter:off
164+
try (InputStream bounded = new ObservableInputStream.Builder()
165+
.setCharSequence("Hi")
166+
.setAfterRead(i -> {
167+
throw new CustomIOException(message);
168+
})
169+
.get()) {
170+
assertEquals(message, assertThrowsExactly(CustomIOException.class, () -> IOUtils.consume(bounded)).getMessage());
171+
}
172+
// @formatter:on
173+
}
174+
146175
@SuppressWarnings("resource")
147176
@Test
148177
public void testAvailableAfterClose() throws Exception {

0 commit comments

Comments
 (0)