Skip to content

Commit 8e6feab

Browse files
committed
Add IOBooleanSupplier
- Add Uncheck.getAsBoolean(IOBooleanSupplier) - Use Uncheck.getAsBoolean(IOBooleanSupplier) to avoid boxing and unboxing of boolean values
1 parent 041c4f5 commit 8e6feab

File tree

11 files changed

+176
-13
lines changed

11 files changed

+176
-13
lines changed

src/changes/changes.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ The <action> type attribute can be add,update,fix,remove.
5757
<action dev="ggregory" type="fix" issue="IO-868" due-to="Julian Reschke, Gary Gregory">Improve Javadoc for all implementations of AbstractOriginSupplier#get().</action>
5858
<action dev="ggregory" type="fix" due-to="Gary Gregory">The Consumer to IOUtils.closeQuietly(Closeable, Consumer) now accepts Exception, not just IOException.</action>
5959
<action dev="ggregory" type="fix" due-to="Gary Gregory">The Consumer to IOUtils.close(Closeable, IOConsumer) now accepts wrapped Exception, not just IOException.</action>
60+
<action dev="ggregory" type="fix" due-to="Gary Gregory">Use Uncheck.getAsBoolean(IOBooleanSupplier) to avoid boxing and unboxing of boolean values.</action>
6061
<!-- ADD -->
6162
<action dev="ggregory" type="add" issue="IO-860" due-to="Nico Strecker, Gary Gregory">Add ThrottledInputStream.Builder.setMaxBytes(long, ChronoUnit).</action>
6263
<action dev="ggregory" type="add" due-to="Gary Gregory">Add IOIterable.</action>
@@ -70,6 +71,8 @@ The <action> type attribute can be add,update,fix,remove.
7071
<action dev="ggregory" type="add" due-to="Gary Gregory">Add ProxyOutputStream.Builder.</action>
7172
<action dev="ggregory" type="add" due-to="Gary Gregory">Add ByteOrderMark.matches(int[]).</action>
7273
<action dev="ggregory" type="add" due-to="Gary Gregory">Add BrokenOutputStream.BrokenOutputStream(Function&lt;String&gt;, Throwable>) and deprecate Supplier&lt;String&gt; constructor.</action>
74+
<action dev="ggregory" type="add" due-to="Gary Gregory">Add IOBooleanSupplier.</action>
75+
<action dev="ggregory" type="add" due-to="Gary Gregory">Add Uncheck.getAsBoolean(IOBooleanSupplier).</action>
7376
<!-- UPDATE -->
7477
<action dev="ggregory" type="update" due-to="Dependabot, Gary Gregory">Bump commons.bytebuddy.version from 1.15.10 to 1.17.1 #710, #715, #720.</action>
7578
<action dev="ggregory" type="update" due-to="Gary Gregory">Bump commons-codec:commons-codec from 1.17.1 to 1.18.0. #717.</action>

src/main/java/org/apache/commons/io/FileUtils.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1729,7 +1729,7 @@ public static boolean isFileNewer(final File file, final ChronoLocalDateTime<?>
17291729
public static boolean isFileNewer(final File file, final ChronoZonedDateTime<?> chronoZonedDateTime) {
17301730
Objects.requireNonNull(file, PROTOCOL_FILE);
17311731
Objects.requireNonNull(chronoZonedDateTime, "chronoZonedDateTime");
1732-
return Uncheck.get(() -> PathUtils.isNewer(file.toPath(), chronoZonedDateTime));
1732+
return Uncheck.getAsBoolean(() -> PathUtils.isNewer(file.toPath(), chronoZonedDateTime));
17331733
}
17341734

17351735
/**
@@ -1758,7 +1758,7 @@ public static boolean isFileNewer(final File file, final Date date) {
17581758
* @throws UncheckedIOException if the reference file doesn't exist.
17591759
*/
17601760
public static boolean isFileNewer(final File file, final File reference) {
1761-
return Uncheck.get(() -> PathUtils.isNewer(file.toPath(), reference.toPath()));
1761+
return Uncheck.getAsBoolean(() -> PathUtils.isNewer(file.toPath(), reference.toPath()));
17621762
}
17631763

17641764
/**
@@ -1788,7 +1788,7 @@ public static boolean isFileNewer(final File file, final FileTime fileTime) thro
17881788
*/
17891789
public static boolean isFileNewer(final File file, final Instant instant) {
17901790
Objects.requireNonNull(instant, "instant");
1791-
return Uncheck.get(() -> PathUtils.isNewer(file.toPath(), instant));
1791+
return Uncheck.getAsBoolean(() -> PathUtils.isNewer(file.toPath(), instant));
17921792
}
17931793

17941794
/**
@@ -1803,7 +1803,7 @@ public static boolean isFileNewer(final File file, final Instant instant) {
18031803
*/
18041804
public static boolean isFileNewer(final File file, final long timeMillis) {
18051805
Objects.requireNonNull(file, PROTOCOL_FILE);
1806-
return Uncheck.get(() -> PathUtils.isNewer(file.toPath(), timeMillis));
1806+
return Uncheck.getAsBoolean(() -> PathUtils.isNewer(file.toPath(), timeMillis));
18071807
}
18081808

18091809
/**
@@ -1971,7 +1971,7 @@ public static boolean isFileOlder(final File file, final Date date) {
19711971
* @throws UncheckedIOException if an I/O error occurs
19721972
*/
19731973
public static boolean isFileOlder(final File file, final File reference) throws FileNotFoundException {
1974-
return Uncheck.get(() -> PathUtils.isOlder(file.toPath(), reference.toPath()));
1974+
return Uncheck.getAsBoolean(() -> PathUtils.isOlder(file.toPath(), reference.toPath()));
19751975
}
19761976

19771977
/**
@@ -2000,7 +2000,7 @@ public static boolean isFileOlder(final File file, final FileTime fileTime) thro
20002000
*/
20012001
public static boolean isFileOlder(final File file, final Instant instant) {
20022002
Objects.requireNonNull(instant, "instant");
2003-
return Uncheck.get(() -> PathUtils.isOlder(file.toPath(), instant));
2003+
return Uncheck.getAsBoolean(() -> PathUtils.isOlder(file.toPath(), instant));
20042004
}
20052005

20062006
/**
@@ -2015,7 +2015,7 @@ public static boolean isFileOlder(final File file, final Instant instant) {
20152015
*/
20162016
public static boolean isFileOlder(final File file, final long timeMillis) {
20172017
Objects.requireNonNull(file, PROTOCOL_FILE);
2018-
return Uncheck.get(() -> PathUtils.isOlder(file.toPath(), timeMillis));
2018+
return Uncheck.getAsBoolean(() -> PathUtils.isOlder(file.toPath(), timeMillis));
20192019
}
20202020

20212021
/**
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
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+
18+
package org.apache.commons.io.function;
19+
20+
import java.io.IOException;
21+
import java.io.UncheckedIOException;
22+
import java.util.function.BooleanSupplier;
23+
import java.util.function.Supplier;
24+
25+
/**
26+
* Like {@link BooleanSupplier} but throws {@link IOException}.
27+
*
28+
* @since 2.18.0
29+
*/
30+
@FunctionalInterface
31+
public interface IOBooleanSupplier {
32+
33+
/**
34+
* Creates a {@link Supplier} for this instance that throws {@link UncheckedIOException} instead of {@link IOException}.
35+
*
36+
* @return an UncheckedIOException Supplier.
37+
*/
38+
default BooleanSupplier asBooleanSupplier() {
39+
return () -> Uncheck.getAsBoolean(this);
40+
}
41+
42+
/**
43+
* Gets a result.
44+
*
45+
* @return a result
46+
* @throws IOException if an I/O error occurs.
47+
*/
48+
boolean getAsBoolean() throws IOException;
49+
}

src/main/java/org/apache/commons/io/function/Uncheck.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,22 @@ public static <T> T get(final IOSupplier<T> supplier, final Supplier<String> mes
233233
}
234234
}
235235

236+
/**
237+
* Gets the result from an IO boolean supplier.
238+
*
239+
* @param supplier Supplies the return value.
240+
* @return result from the supplier.
241+
* @throws UncheckedIOException if an I/O error occurs.
242+
* @since 2.18.0
243+
*/
244+
public static boolean getAsBoolean(final IOBooleanSupplier supplier) {
245+
try {
246+
return supplier.getAsBoolean();
247+
} catch (final IOException e) {
248+
throw wrap(e);
249+
}
250+
}
251+
236252
/**
237253
* Gets the result from an IO int supplier.
238254
*

src/main/java/org/apache/commons/io/function/UncheckedIOIterator.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ final class UncheckedIOIterator<E> implements Iterator<E> {
4545

4646
@Override
4747
public boolean hasNext() {
48-
return Uncheck.get(delegate::hasNext);
48+
return Uncheck.getAsBoolean(delegate::hasNext);
4949
}
5050

5151
@Override

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ public String readLine() throws UncheckedIOException {
188188
*/
189189
@Override
190190
public boolean ready() throws UncheckedIOException {
191-
return Uncheck.get(super::ready);
191+
return Uncheck.getAsBoolean(super::ready);
192192
}
193193

194194
/**

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ public int read(final CharBuffer target) throws UncheckedIOException {
172172
*/
173173
@Override
174174
public boolean ready() throws UncheckedIOException {
175-
return Uncheck.get(super::ready);
175+
return Uncheck.getAsBoolean(super::ready);
176176
}
177177

178178
/**
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
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+
18+
package org.apache.commons.io.function;
19+
20+
import static org.junit.jupiter.api.Assertions.assertEquals;
21+
import static org.junit.jupiter.api.Assertions.assertNotEquals;
22+
import static org.junit.jupiter.api.Assertions.assertThrows;
23+
24+
import java.io.IOException;
25+
import java.io.UncheckedIOException;
26+
import java.util.concurrent.atomic.AtomicBoolean;
27+
28+
import org.junit.jupiter.api.BeforeEach;
29+
import org.junit.jupiter.api.Test;
30+
31+
/**
32+
* Tests {@link IOBooleanSupplier}.
33+
*/
34+
public class IOBooleanSupplierTest {
35+
36+
private AtomicBoolean atomicBoolean;
37+
38+
@BeforeEach
39+
public void beforeEach() {
40+
atomicBoolean = new AtomicBoolean();
41+
}
42+
43+
private boolean getThrowsIO(final IOBooleanSupplier supplier) throws IOException {
44+
return supplier.getAsBoolean();
45+
}
46+
47+
private boolean getThrowsNone(final IOBooleanSupplier supplier) {
48+
return supplier.asBooleanSupplier().getAsBoolean();
49+
}
50+
51+
@Test
52+
public void testAsSupplier() {
53+
assertThrows(UncheckedIOException.class, () -> TestConstants.THROWING_IO_BOOLEAN_SUPPLIER.asBooleanSupplier().getAsBoolean());
54+
assertEquals(true, getThrowsNone(() -> TestUtils.compareAndSetThrowsIO(atomicBoolean, true)));
55+
assertEquals(true, atomicBoolean.get());
56+
assertNotEquals(TestConstants.THROWING_IO_BOOLEAN_SUPPLIER.asBooleanSupplier(), TestConstants.THROWING_IO_BOOLEAN_SUPPLIER.asBooleanSupplier());
57+
}
58+
59+
@Test
60+
public void testGet() throws IOException {
61+
assertThrows(IOException.class, () -> TestConstants.THROWING_IO_BOOLEAN_SUPPLIER.getAsBoolean());
62+
assertThrows(IOException.class, () -> {
63+
throw new IOException();
64+
});
65+
assertEquals(true, getThrowsIO(() -> TestUtils.compareAndSetThrowsIO(atomicBoolean, true)));
66+
assertEquals(true, atomicBoolean.get());
67+
}
68+
}

src/test/java/org/apache/commons/io/function/TestConstants.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,16 @@ final class TestConstants {
3838

3939
static IOBinaryOperator<?> THROWING_IO_BINARY_OPERATOR = (t, u) -> throwIOException();
4040

41+
static IOBooleanSupplier THROWING_IO_BOOLEAN_SUPPLIER = TestConstants::throwIOException;
42+
4143
static IOComparator<Object> THROWING_IO_COMPARATOR = (t, u) -> throwIOException();
4244

4345
static IOConsumer<Object> THROWING_IO_CONSUMER = t -> throwIOException();
4446

45-
static IOIntConsumer THROWING_IO_INT_CONSUMER = t -> throwIOException();
46-
4747
static IOFunction<Object, Object> THROWING_IO_FUNCTION = t -> throwIOException();
4848

49+
static IOIntConsumer THROWING_IO_INT_CONSUMER = t -> throwIOException();
50+
4951
static IOIntSupplier THROWING_IO_INT_SUPPLIER = TestConstants::throwIOException;
5052

5153
static IOLongSupplier THROWING_IO_LONG_SUPPLIER = TestConstants::throwIOException;

src/test/java/org/apache/commons/io/function/TestUtils.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,24 @@
1818
package org.apache.commons.io.function;
1919

2020
import java.io.IOException;
21+
import java.util.concurrent.atomic.AtomicBoolean;
2122
import java.util.concurrent.atomic.AtomicInteger;
2223
import java.util.concurrent.atomic.AtomicLong;
2324
import java.util.concurrent.atomic.AtomicReference;
2425

2526
final class TestUtils {
2627

28+
static boolean compareAndSetThrowsIO(final AtomicBoolean ref, final boolean update) throws IOException {
29+
return compareAndSetThrowsIO(ref, false, update);
30+
}
31+
32+
static boolean compareAndSetThrowsIO(final AtomicBoolean ref, final boolean expected, final boolean update) throws IOException {
33+
if (!ref.compareAndSet(expected, update)) {
34+
throw new IOException("Unexpected");
35+
}
36+
return ref.get(); // same as update
37+
}
38+
2739
static int compareAndSetThrowsIO(final AtomicInteger ref, final int update) throws IOException {
2840
return compareAndSetThrowsIO(ref, 0, update);
2941
}

0 commit comments

Comments
 (0)