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 ab687c99046850c08a7bf4dd5f14eb6e3aa43051 Author: Gary Gregory <gardgreg...@gmail.com> AuthorDate: Mon Aug 8 00:42:33 2022 -0400 Change parameter order of new methods, use var-args, improve tests --- src/main/java/org/apache/commons/io/FileUtils.java | 4 +- src/main/java/org/apache/commons/io/IOUtils.java | 2 +- .../java/org/apache/commons/io/function/Erase.java | 189 +++++++++++++++++++++ .../org/apache/commons/io/function/IOConsumer.java | 19 ++- .../commons/io/input/ObservableInputStream.java | 2 +- .../commons/io/output/FilterCollectionWriter.java | 2 +- .../commons/io/function/IOBiConsumerTest.java | 2 +- .../commons/io/function/IOBiFunctionTest.java | 2 +- .../io/function/IOBinaryOperatorStreamTest.java | 6 +- .../commons/io/function/IOComparatorTest.java | 4 +- .../apache/commons/io/function/IOConsumerTest.java | 41 ++++- .../apache/commons/io/function/IOFunctionTest.java | 12 +- .../commons/io/function/IOPredicateTest.java | 4 +- .../org/apache/commons/io/function/TestUtils.java | 5 + .../apache/commons/io/function/UncheckTest.java | 2 +- 15 files changed, 265 insertions(+), 31 deletions(-) diff --git a/src/main/java/org/apache/commons/io/FileUtils.java b/src/main/java/org/apache/commons/io/FileUtils.java index 7c4a9913..b0098697 100644 --- a/src/main/java/org/apache/commons/io/FileUtils.java +++ b/src/main/java/org/apache/commons/io/FileUtils.java @@ -345,7 +345,7 @@ public class FileUtils { * @see #forceDelete(File) */ public static void cleanDirectory(final File directory) throws IOException { - IOConsumer.forAll(listFiles(directory, null), FileUtils::forceDelete); + IOConsumer.forAll(FileUtils::forceDelete, listFiles(directory, null)); } /** @@ -358,7 +358,7 @@ public class FileUtils { * @see #forceDeleteOnExit(File) */ private static void cleanDirectoryOnExit(final File directory) throws IOException { - IOConsumer.forAll(listFiles(directory, null), FileUtils::forceDeleteOnExit); + IOConsumer.forAll(FileUtils::forceDeleteOnExit, listFiles(directory, null)); } /** diff --git a/src/main/java/org/apache/commons/io/IOUtils.java b/src/main/java/org/apache/commons/io/IOUtils.java index 0c9f824a..e83cab9f 100644 --- a/src/main/java/org/apache/commons/io/IOUtils.java +++ b/src/main/java/org/apache/commons/io/IOUtils.java @@ -396,7 +396,7 @@ public class IOUtils { * @since 2.8.0 */ public static void close(final Closeable... closeables) throws IOExceptionList { - IOConsumer.forAll(closeables, IOUtils::close); + IOConsumer.forAll(IOUtils::close, closeables); } /** diff --git a/src/main/java/org/apache/commons/io/function/Erase.java b/src/main/java/org/apache/commons/io/function/Erase.java new file mode 100644 index 00000000..3447b883 --- /dev/null +++ b/src/main/java/org/apache/commons/io/function/Erase.java @@ -0,0 +1,189 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.function; + +import java.io.IOException; + +/** + * Erases {@link IOException} for the compiler but still throws that exception at runtime. + */ +class Erase { + + /** + * Delegates to the given {@link IOBiConsumer} but erases its {@link IOException} for the compiler, while still throwing + * the exception at runtime. + * + * @param <T> See delegate. + * @param <U> See delegate. + * @param consumer See delegate. + * @param t See delegate. + * @param u See delegate. + * @see IOBiConsumer + */ + static <T, U> void accept(final IOBiConsumer<T, U> consumer, final T t, final U u) { + try { + consumer.accept(t, u); + } catch (final IOException ex) { + rethrow(ex); // throws IOException + } + } + + /** + * Delegates to the given {@link IOConsumer} but erases its {@link IOException} for the compiler, while still throwing + * the exception at runtime. + * + * @param <T> See delegate. + * @param consumer See delegate. + * @param t See delegate. + * @see IOConsumer + */ + static <T> void accept(final IOConsumer<T> consumer, final T t) { + try { + consumer.accept(t); + } catch (final IOException ex) { + rethrow(ex); // throws IOException + } + } + + /** + * Delegates to the given {@link IOBiFunction} but erases its {@link IOException} for the compiler, while still throwing + * the exception at runtime. + * + * @param <T> See delegate. + * @param <U> See delegate. + * @param <R> See delegate. + * @param mapper See delegate. + * @param t See delegate. + * @param u See delegate. + * @return See delegate. + * @see IOBiFunction + */ + static <T, U, R> R apply(final IOBiFunction<? super T, ? super U, ? extends R> mapper, final T t, final U u) { + try { + return mapper.apply(t, u); + } catch (final IOException e) { + throw rethrow(e); // throws IOException + } + } + + /** + * Delegates to the given {@link IOFunction} but erases its {@link IOException} for the compiler, while still throwing + * the exception at runtime. + * + * @param <T> See delegate. + * @param <R> See delegate. + * @param mapper See delegate. + * @param t See delegate. + * @return See delegate. + * @see IOFunction + */ + static <T, R> R apply(final IOFunction<? super T, ? extends R> mapper, final T t) { + try { + return mapper.apply(t); + } catch (final IOException e) { + throw rethrow(e); // throws IOException + } + } + + /** + * Delegates to the given {@link IOComparator} but erases its {@link IOException} for the compiler, while still throwing + * the exception at runtime. + * + * @param <T> See delegate. + * @param comparator See delegate. + * @param t See delegate. + * @param u See delegate. + * @return See delegate. + * @see IOComparator + */ + static <T> int compare(final IOComparator<? super T> comparator, final T t, final T u) { + try { + return comparator.compare(t, u); + } catch (final IOException e) { + throw rethrow(e); // throws IOException + } + } + + /** + * Delegates to the given {@link IOSupplier} but erases its {@link IOException} for the compiler, while still throwing + * the exception at runtime. + * + * @param <T> See delegate. + * @param supplier See delegate. + * @return See delegate. + * @see IOSupplier + */ + static <T> T get(final IOSupplier<T> supplier) { + try { + return supplier.get(); + } catch (final IOException e) { + throw rethrow(e); // throws IOException + } + } + + /** + * Throws the given throwable. + * + * @param <T> The throwable cast type. + * @param throwable The throwable to rethrow. + * @return nothing because we throw. + * @throws T Always thrown. + */ + @SuppressWarnings("unchecked") + static <T extends Throwable> RuntimeException rethrow(final Throwable throwable) throws T { + throw (T) throwable; + } + + /** + * Delegates to the given {@link IORunnable} but erases its {@link IOException} for the compiler, while still throwing + * the exception at runtime. + * + * @param runnable See delegate. + * @see IORunnable + */ + static void run(final IORunnable runnable) { + try { + runnable.run(); + } catch (final IOException e) { + throw rethrow(e); // throws IOException + } + } + + /** + * Delegates to the given {@link IOPredicate} but erases its {@link IOException} for the compiler, while still throwing + * the exception at runtime. + * + * @param <T> See delegate. + * @param predicate See delegate. + * @param t See delegate. + * @return See delegate. + * @see IOPredicate + */ + static <T> boolean test(final IOPredicate<? super T> predicate, final T t) { + try { + return predicate.test(t); + } catch (final IOException e) { + throw rethrow(e); // throws IOException + } + } + + /** No instances. */ + private Erase() { + // No instances. + } + +} diff --git a/src/main/java/org/apache/commons/io/function/IOConsumer.java b/src/main/java/org/apache/commons/io/function/IOConsumer.java index 5b912464..32c5d099 100644 --- a/src/main/java/org/apache/commons/io/function/IOConsumer.java +++ b/src/main/java/org/apache/commons/io/function/IOConsumer.java @@ -42,40 +42,41 @@ public interface IOConsumer<T> { /** * Performs an action for each element of the collection gathering any exceptions. + * @param action The action to apply to each input element. + * @param collection The input to stream. * * @param <T> The element type. - * @param collection The input to stream. - * @param action The action to apply to each input element. * @throws IOExceptionList if any I/O errors occur. * @since 2.12.0 */ - static <T> void forAll(final Iterable<T> collection, final IOConsumer<T> action) throws IOExceptionList { + static <T> void forAll(final IOConsumer<T> action, final Iterable<T> collection) throws IOExceptionList { IOStreams.forAll(IOStreams.of(collection), action); } /** * Performs an action for each element of the collection gathering any exceptions. + * @param action The action to apply to each input element. + * @param stream The input to stream. * * @param <T> The element type. - * @param stream The input to stream. - * @param action The action to apply to each input element. * @throws IOExceptionList if any I/O errors occur. * @since 2.12.0 */ - static <T> void forAll(final Stream<T> stream, final IOConsumer<T> action) throws IOExceptionList { + static <T> void forAll(final IOConsumer<T> action, final Stream<T> stream) throws IOExceptionList { IOStreams.forAll(stream, action, IOIndexedException::new); } /** * Performs an action for each element of the array gathering any exceptions. + * @param action The action to apply to each input element. + * @param array The input to stream. * * @param <T> The element type. - * @param array The input to stream. - * @param action The action to apply to each input element. * @throws IOExceptionList if any I/O errors occur. * @since 2.12.0 */ - static <T> void forAll(final T[] array, final IOConsumer<T> action) throws IOExceptionList { + @SafeVarargs + static <T> void forAll(final IOConsumer<T> action, final T... array) throws IOExceptionList { IOStreams.forAll(IOStreams.of(array), action); } diff --git a/src/main/java/org/apache/commons/io/input/ObservableInputStream.java b/src/main/java/org/apache/commons/io/input/ObservableInputStream.java index 837d0f1f..ad4653ba 100644 --- a/src/main/java/org/apache/commons/io/input/ObservableInputStream.java +++ b/src/main/java/org/apache/commons/io/input/ObservableInputStream.java @@ -175,7 +175,7 @@ public class ObservableInputStream extends ProxyInputStream { } private void forEachObserver(final IOConsumer<Observer> action) throws IOException { - IOConsumer.forAll(observers, Objects.requireNonNull(action)); + IOConsumer.forAll(Objects.requireNonNull(action), observers); } /** diff --git a/src/main/java/org/apache/commons/io/output/FilterCollectionWriter.java b/src/main/java/org/apache/commons/io/output/FilterCollectionWriter.java index 43cb981a..eadcff83 100644 --- a/src/main/java/org/apache/commons/io/output/FilterCollectionWriter.java +++ b/src/main/java/org/apache/commons/io/output/FilterCollectionWriter.java @@ -105,7 +105,7 @@ public class FilterCollectionWriter extends Writer { } private FilterCollectionWriter forAllWriters(final IOConsumer<Writer> action) throws IOExceptionList { - IOConsumer.forAll(writers(), action); + IOConsumer.forAll(action, writers()); return this; } diff --git a/src/test/java/org/apache/commons/io/function/IOBiConsumerTest.java b/src/test/java/org/apache/commons/io/function/IOBiConsumerTest.java index 8a7de2c6..20c8ef44 100644 --- a/src/test/java/org/apache/commons/io/function/IOBiConsumerTest.java +++ b/src/test/java/org/apache/commons/io/function/IOBiConsumerTest.java @@ -51,7 +51,7 @@ public class IOBiConsumerTest { } @Test - public void testAsBiConsumer() throws IOException { + public void testAsBiConsumer() { final Map<String, Integer> map = new HashMap<>(); map.put("a", 1); assertThrows(UncheckedIOException.class, () -> map.forEach(TestConstants.THROWING_IO_BI_CONSUMER.asBiConsumer())); diff --git a/src/test/java/org/apache/commons/io/function/IOBiFunctionTest.java b/src/test/java/org/apache/commons/io/function/IOBiFunctionTest.java index 941c9933..b854b4e5 100644 --- a/src/test/java/org/apache/commons/io/function/IOBiFunctionTest.java +++ b/src/test/java/org/apache/commons/io/function/IOBiFunctionTest.java @@ -79,7 +79,7 @@ public class IOBiFunctionTest { } @Test - public void testAsBiFunction() throws IOException { + public void testAsBiFunction() { final Map<String, Long> map = new HashMap<>(); map.put("1", 0L); final IOBiFunction<String, Long, Long> f = (t, u) -> Files.size(PathUtils.current()); diff --git a/src/test/java/org/apache/commons/io/function/IOBinaryOperatorStreamTest.java b/src/test/java/org/apache/commons/io/function/IOBinaryOperatorStreamTest.java index 42b4029c..c395c61c 100644 --- a/src/test/java/org/apache/commons/io/function/IOBinaryOperatorStreamTest.java +++ b/src/test/java/org/apache/commons/io/function/IOBinaryOperatorStreamTest.java @@ -52,8 +52,10 @@ public class IOBinaryOperatorStreamTest { assertEquals(TestConstants.ABS_PATH_A, Stream.of(TestConstants.ABS_PATH_A, TestConstants.ABS_PATH_A).reduce(MIN_BY_BO).get()); } + /** + */ @Test - public void testMaxBy() throws IOException { + public void testMaxBy() { assertEquals(TestConstants.ABS_PATH_A, Stream.of(TestConstants.ABS_PATH_A, TestConstants.ABS_PATH_A).reduce(MAX_BY_BO).get()); // in-line lambda ok: final IOBinaryOperator<Path> binIoOp = IOBinaryOperator.maxBy((t, u) -> t.toRealPath().compareTo(u)); @@ -68,7 +70,7 @@ public class IOBinaryOperatorStreamTest { } @Test - public void testMinBy() throws IOException { + public void testMinBy() { assertEquals(TestConstants.ABS_PATH_A, Stream.of(TestConstants.ABS_PATH_A, TestConstants.ABS_PATH_A).reduce(MIN_BY_BO).get()); // in-line lambda ok: final IOBinaryOperator<Path> binIoOp = IOBinaryOperator.minBy((t, u) -> t.toRealPath().compareTo(u)); diff --git a/src/test/java/org/apache/commons/io/function/IOComparatorTest.java b/src/test/java/org/apache/commons/io/function/IOComparatorTest.java index b263f5d1..89b488b3 100644 --- a/src/test/java/org/apache/commons/io/function/IOComparatorTest.java +++ b/src/test/java/org/apache/commons/io/function/IOComparatorTest.java @@ -39,7 +39,7 @@ public class IOComparatorTest { static final IOComparator<Path> REAL_PATH_COMP = (final Path t, final Path u) -> t.toRealPath().compareTo(u); @Test - public void testAsComparator() throws IOException { + public void testAsComparator() { assertEquals(0, REAL_PATH_COMP.asComparator().compare(TestConstants.ABS_PATH_A, TestConstants.ABS_PATH_A)); assertThrows(UncheckedIOException.class, () -> TestConstants.THROWING_IO_COMPARATOR.asComparator().compare(TestConstants.ABS_PATH_A, TestConstants.ABS_PATH_B)); @@ -56,7 +56,7 @@ public class IOComparatorTest { } @Test - public void testThrowing() throws IOException { + public void testThrowing() { assertThrows(IOException.class, () -> TestConstants.THROWING_IO_COMPARATOR.compare(TestConstants.ABS_PATH_A, TestConstants.ABS_PATH_B)); } diff --git a/src/test/java/org/apache/commons/io/function/IOConsumerTest.java b/src/test/java/org/apache/commons/io/function/IOConsumerTest.java index 8bcf93de..18bfa8ea 100644 --- a/src/test/java/org/apache/commons/io/function/IOConsumerTest.java +++ b/src/test/java/org/apache/commons/io/function/IOConsumerTest.java @@ -26,9 +26,12 @@ import java.io.IOException; import java.io.StringReader; import java.io.UncheckedIOException; import java.nio.file.Files; +import java.util.Arrays; import java.util.Optional; import java.util.concurrent.atomic.AtomicReference; +import java.util.stream.Stream; +import org.apache.commons.io.IOExceptionList; import org.apache.commons.io.IOUtils; import org.apache.commons.io.file.PathUtils; import org.apache.commons.io.test.ThrowOnCloseReader; @@ -61,14 +64,47 @@ public class IOConsumerTest { } @Test - public void testAsConsumer() throws IOException { - assertThrows(UncheckedIOException.class, () -> Optional.of("a").ifPresent(TestConstants.THROWING_IO_CONSUMER.asConsumer())); + public void testAsConsumer() { + assertThrows(UncheckedIOException.class, () -> Optional.of("a").ifPresent(TestUtils.throwingIOConsumer().asConsumer())); final AtomicReference<String> ref = new AtomicReference<>(); final IOConsumer<String> consumer1 = s -> ref.set(s + "1"); Optional.of("a").ifPresent(consumer1.asConsumer()); assertEquals("a1", ref.get()); } + @Test + public void testForAllArray() throws IOException { + IOConsumer.forAll(TestUtils.throwingIOConsumer(), (String[]) null); + assertThrows(IOExceptionList.class, () -> IOConsumer.forAll(TestUtils.throwingIOConsumer(), new String[] {"1"})); + + final AtomicReference<String> ref = new AtomicReference<>(); + final IOConsumer<String> consumer1 = s -> ref.set(s + "2"); + IOConsumer.forAll(consumer1, new String[] {"1"}); + assertEquals("12", ref.get()); + } + + @Test + public void testForAllIterable() throws IOException { + IOConsumer.forAll(TestUtils.throwingIOConsumer(), (Iterable<Object>) null); + assertThrows(IOExceptionList.class, () -> IOConsumer.forAll(TestUtils.throwingIOConsumer(), Arrays.asList("1"))); + + final AtomicReference<String> ref = new AtomicReference<>(); + final IOConsumer<String> consumer1 = s -> ref.set(s + "2"); + IOConsumer.forAll(consumer1, Arrays.asList("1")); + assertEquals("12", ref.get()); + } + + @Test + public void testForAllStream() throws IOException { + IOConsumer.forAll(TestUtils.throwingIOConsumer(), (Stream<Object>) null); + assertThrows(IOExceptionList.class, () -> IOConsumer.forAll(TestUtils.throwingIOConsumer(), Arrays.asList("1").stream())); + + final AtomicReference<String> ref = new AtomicReference<>(); + final IOConsumer<String> consumer1 = s -> ref.set(s + "2"); + IOConsumer.forAll(consumer1, Arrays.asList("1").stream()); + assertEquals("12", ref.get()); + } + @Test public void testNoop() { final Closeable nullCloseable = null; @@ -78,5 +114,4 @@ public class IOConsumerTest { assertDoesNotThrow(() -> IOUtils.close(new ThrowOnCloseReader(new StringReader("s")), noopConsumer)); } - } diff --git a/src/test/java/org/apache/commons/io/function/IOFunctionTest.java b/src/test/java/org/apache/commons/io/function/IOFunctionTest.java index 52106bb8..1032aeee 100644 --- a/src/test/java/org/apache/commons/io/function/IOFunctionTest.java +++ b/src/test/java/org/apache/commons/io/function/IOFunctionTest.java @@ -17,6 +17,7 @@ package org.apache.commons.io.function; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -114,7 +115,7 @@ public class IOFunctionTest { } @Test - public void testAsFunction() throws IOException { + public void testAsFunction() { assertThrows(UncheckedIOException.class, () -> Optional.of("a").map(TestConstants.THROWING_IO_FUNCTION.asFunction()).get()); assertEquals("a", Optional.of("a").map(IOFunction.identity().asFunction()).get()); } @@ -165,9 +166,10 @@ public class IOFunctionTest { @Test public void testIdentity() throws IOException { - final IOFunction<InputStream, InputStream> identityFunction = IOFunction.identity(); - try (InputStream is = new ByteArrayInputStream(new byte[] {(byte) 0xa, (byte) 0xb, (byte) 0xc})) { - assertEquals(is, identityFunction.apply(is)); - } + assertEquals(IOFunction.identity(), IOFunction.identity()); + final IOFunction<byte[], byte[]> identityFunction = IOFunction.identity(); + final byte[] buf = new byte[] {(byte) 0xa, (byte) 0xb, (byte) 0xc}; + assertEquals(buf, identityFunction.apply(buf)); + assertArrayEquals(buf, identityFunction.apply(buf)); } } diff --git a/src/test/java/org/apache/commons/io/function/IOPredicateTest.java b/src/test/java/org/apache/commons/io/function/IOPredicateTest.java index 9d52a13b..a5047a79 100644 --- a/src/test/java/org/apache/commons/io/function/IOPredicateTest.java +++ b/src/test/java/org/apache/commons/io/function/IOPredicateTest.java @@ -48,7 +48,7 @@ public class IOPredicateTest { private static final Object THROWING_EQUALS = new Object() { @Override public boolean equals(final Object obj) { - throw IOStreams.rethrow(new IOException("Expected")); + throw Erase.rethrow(new IOException("Expected")); } }; @@ -109,7 +109,7 @@ public class IOPredicateTest { } @Test - public void testIsEqualUnchecked() throws IOException { + public void testIsEqualUnchecked() { assertThrowsUnchecked(() -> IOPredicate.isEqual(THROWING_EQUALS).asPredicate().test("B")); assertFalse(IOPredicate.isEqual(null).asPredicate().test("A")); assertTrue(IOPredicate.isEqual("B").asPredicate().test("B")); diff --git a/src/test/java/org/apache/commons/io/function/TestUtils.java b/src/test/java/org/apache/commons/io/function/TestUtils.java index 7e62c078..db22fdd0 100644 --- a/src/test/java/org/apache/commons/io/function/TestUtils.java +++ b/src/test/java/org/apache/commons/io/function/TestUtils.java @@ -38,6 +38,11 @@ class TestUtils { return (IOBinaryOperator<T>) TestConstants.THROWING_IO_BINARY_OPERATOR; } + @SuppressWarnings("unchecked") + static <T> IOConsumer<T> throwingIOConsumer() { + return (IOConsumer<T>) TestConstants.THROWING_IO_CONSUMER; + } + @SuppressWarnings("unchecked") static <T> IOUnaryOperator<T> throwingIOUnaryOperator() { return (IOUnaryOperator<T>) TestConstants.THROWING_IO_UNARY_OPERATOR; diff --git a/src/test/java/org/apache/commons/io/function/UncheckTest.java b/src/test/java/org/apache/commons/io/function/UncheckTest.java index ab054416..dbb73299 100644 --- a/src/test/java/org/apache/commons/io/function/UncheckTest.java +++ b/src/test/java/org/apache/commons/io/function/UncheckTest.java @@ -66,7 +66,7 @@ public class UncheckTest { assertThrows(UncheckedIOException.class, () -> Uncheck.accept(t -> { throw new IOException(); }, null)); - assertThrows(UncheckedIOException.class, () -> Uncheck.accept(TestConstants.THROWING_IO_CONSUMER, null)); + assertThrows(UncheckedIOException.class, () -> Uncheck.accept(TestUtils.throwingIOConsumer(), null)); Uncheck.accept(t -> TestUtils.compareAndSetThrows(ref1, t), "new1"); assertEquals("new1", ref1.get()); }