Skip to content

Commit 3816c57

Browse files
author
Gary Gregory
committed
[IO-613] Add classes ClosedReader and CloseShieldReader. Closes #84.
Applied modified patch from Rob Spoor.
1 parent 5796c0c commit 3816c57

6 files changed

Lines changed: 211 additions & 1 deletion

File tree

src/changes/changes.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,9 @@ The <action> type attribute can be add,update,fix,remove.
113113
<action issue="IO-612" dev="ggregory" type="add" due-to="Rob Spoor, Gary Gregory">
114114
Add class TeeReader.
115115
</action>
116+
<action issue="IO-613" dev="ggregory" type="add" due-to="Rob Spoor, Gary Gregory">
117+
Add classes ClosedReader and CloseShieldReader. #84.
118+
</action>
116119
</release>
117120

118121
<release version="2.6" date="2017-10-15" description="Java 7 required, Java 9 supported.">

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
* This class is typically used in cases where an input stream needs to be
2525
* passed to a component that wants to explicitly close the stream even if
2626
* more input would still be available to other components.
27+
* </p>
2728
*
2829
* @since 1.4
2930
*/
@@ -46,7 +47,7 @@ public CloseShieldInputStream(final InputStream in) {
4647
*/
4748
@Override
4849
public void close() {
49-
in = new ClosedInputStream();
50+
in = ClosedInputStream.CLOSED_INPUT_STREAM;
5051
}
5152

5253
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package org.apache.commons.io.input;
18+
19+
import java.io.Reader;
20+
21+
/**
22+
* Proxy stream that prevents the underlying reader from being closed.
23+
* <p>
24+
* This class is typically used in cases where a reader needs to be
25+
* passed to a component that wants to explicitly close the reader even if
26+
* more input would still be available to other components.
27+
* <p>
28+
*
29+
* @since 2.7
30+
*/
31+
public class CloseShieldReader extends ProxyReader {
32+
33+
/**
34+
* Creates a proxy that shields the given reader from being
35+
* closed.
36+
*
37+
* @param in underlying reader
38+
*/
39+
public CloseShieldReader(final Reader in) {
40+
super(in);
41+
}
42+
43+
/**
44+
* Replaces the underlying reader with a {@link ClosedReader}
45+
* sentinel. The original reader will remain open, but this proxy
46+
* will appear closed.
47+
*/
48+
@Override
49+
public void close() {
50+
in = ClosedReader.CLOSED_READER;
51+
}
52+
53+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package org.apache.commons.io.input;
18+
19+
import static org.apache.commons.io.IOUtils.EOF;
20+
21+
import java.io.IOException;
22+
import java.io.Reader;
23+
24+
/**
25+
* Closed reader. This reader returns EOF to all attempts to read
26+
* something from it.
27+
* <p>
28+
* Typically uses of this class include testing for corner cases in methods
29+
* that accept readers and acting as a sentinel value instead of a
30+
* {@code null} reader.
31+
* </p>
32+
*
33+
* @since 2.7
34+
*/
35+
public class ClosedReader extends Reader {
36+
37+
/**
38+
* A singleton.
39+
*/
40+
public static final ClosedReader CLOSED_READER = new ClosedReader();
41+
42+
/**
43+
* Returns -1 to indicate that the stream is closed.
44+
*
45+
* @param cbuf ignored
46+
* @param off ignored
47+
* @param len ignored
48+
* @return always -1
49+
*/
50+
@Override
51+
public int read(final char[] cbuf, final int off, final int len) {
52+
return EOF;
53+
}
54+
55+
@Override
56+
public void close() throws IOException {
57+
// noop
58+
}
59+
60+
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package org.apache.commons.io.input;
18+
19+
import static org.junit.Assert.assertEquals;
20+
import static org.mockito.Mockito.never;
21+
import static org.mockito.Mockito.spy;
22+
import static org.mockito.Mockito.verify;
23+
24+
import java.io.IOException;
25+
import java.io.Reader;
26+
27+
import org.junit.Before;
28+
import org.junit.Test;
29+
30+
/**
31+
* JUnit Test Case for {@link CloseShieldReader}.
32+
*/
33+
public class CloseShieldReaderTest {
34+
35+
private String data;
36+
37+
private Reader original;
38+
39+
private Reader shielded;
40+
41+
@Before
42+
public void setUp() {
43+
data = "xyz";
44+
original = spy(new CharSequenceReader(data));
45+
shielded = new CloseShieldReader(original);
46+
}
47+
48+
@Test
49+
public void testClose() throws IOException {
50+
shielded.close();
51+
verify(original, never()).close();
52+
char[] cbuf = new char[10];
53+
assertEquals("read(cbuf, off, len)", -1, shielded.read(cbuf, 0, 10));
54+
assertEquals("read(cbuf, off, len)", data.length(), original.read(cbuf, 0, 10));
55+
assertEquals(data, new String(cbuf, 0, data.length()));
56+
}
57+
58+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package org.apache.commons.io.input;
18+
19+
import static org.junit.Assert.assertEquals;
20+
21+
import org.junit.Test;
22+
23+
/**
24+
* JUnit Test Case for {@link ClosedReader}.
25+
*/
26+
public class ClosedReaderTest {
27+
28+
@Test
29+
public void testRead() throws Exception {
30+
try (final ClosedReader cr = new ClosedReader()) {
31+
assertEquals("read(cbuf, off, len)", -1, cr.read(new char[10], 0, 10));
32+
}
33+
}
34+
35+
}

0 commit comments

Comments
 (0)