Change parameter order of new methods, use var-args, improve tests
MODIFY
src/main/java/org/apache/commons/io/FileUtils.java
src/main/java/org/apache/commons/io/FileUtils.java
@@ -345,7 +345,7 @@ public static long checksumCRC32(final File file) throws IOException {
* @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 static void cleanDirectory(final File directory) throws IOException {
* @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));
}
/**

MODIFY
src/main/java/org/apache/commons/io/IOUtils.java
src/main/java/org/apache/commons/io/IOUtils.java
@@ -396,7 +396,7 @@ public static void close(final Closeable closeable) throws IOException {
* @since 2.8.0
*/
public static void close(final Closeable... closeables) throws IOExceptionList {
- IOConsumer.forAll(closeables, IOUtils::close);
+ IOConsumer.forAll(IOUtils::close, closeables);
}
/**

ADD
src/main/java/org/apache/commons/io/function/Erase.java
+/*
+ * 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.
+ }
+
+}

MODIFY
src/main/java/org/apache/commons/io/function/IOConsumer.java
src/main/java/org/apache/commons/io/function/IOConsumer.java
/**
* 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);
}

MODIFY
src/main/java/org/apache/commons/io/input/ObservableInputStream.java
src/main/java/org/apache/commons/io/input/ObservableInputStream.java
@@ -175,7 +175,7 @@ public void consume() throws IOException {
}
private void forEachObserver(final IOConsumer<Observer> action) throws IOException {
- IOConsumer.forAll(observers, Objects.requireNonNull(action));
+ IOConsumer.forAll(Objects.requireNonNull(action), observers);
}
/**

MODIFY
src/main/java/org/apache/commons/io/output/FilterCollectionWriter.java
src/main/java/org/apache/commons/io/output/FilterCollectionWriter.java
@@ -105,7 +105,7 @@ public void flush() throws IOException {
}
private FilterCollectionWriter forAllWriters(final IOConsumer<Writer> action) throws IOExceptionList {
- IOConsumer.forAll(writers(), action);
+ IOConsumer.forAll(action, writers());
return this;
}

MODIFY
src/test/java/org/apache/commons/io/function/IOBiConsumerTest.java
src/test/java/org/apache/commons/io/function/IOBiConsumerTest.java
@@ -51,7 +51,7 @@ public void testAndThen() throws IOException {
}
@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()));

MODIFY
src/test/java/org/apache/commons/io/function/IOBiFunctionTest.java
src/test/java/org/apache/commons/io/function/IOBiFunctionTest.java
@@ -79,7 +79,7 @@ public void testApplyThrowsException() {
}
@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());

MODIFY
src/test/java/org/apache/commons/io/function/IOBinaryOperatorStreamTest.java
src/test/java/org/apache/commons/io/function/IOBinaryOperatorStreamTest.java
@@ -52,8 +52,10 @@ public void testAsBinaryOperator() {
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 void testMaxBy() throws IOException {
}
@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));

MODIFY
src/test/java/org/apache/commons/io/function/IOComparatorTest.java
src/test/java/org/apache/commons/io/function/IOComparatorTest.java
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 void testComparePath() throws IOException {
}
@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));
}

MODIFY
src/test/java/org/apache/commons/io/function/IOConsumerTest.java
src/test/java/org/apache/commons/io/function/IOConsumerTest.java
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 @@ void testAndThen() throws IOException {
}
@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 void testNoop() {
assertDoesNotThrow(() -> IOUtils.close(new ThrowOnCloseReader(new StringReader("s")), noopConsumer));
}
-
}

MODIFY
src/test/java/org/apache/commons/io/function/IOFunctionTest.java
src/test/java/org/apache/commons/io/function/IOFunctionTest.java
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 void testApplyThrowsException() {
}
@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 void testComposeSupplier() throws IOException {
@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));
}
}

MODIFY
src/test/java/org/apache/commons/io/function/IOPredicateTest.java
src/test/java/org/apache/commons/io/function/IOPredicateTest.java
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 void testIsEqualChecked() throws IOException {
}
@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"));

MODIFY
src/test/java/org/apache/commons/io/function/TestUtils.java
src/test/java/org/apache/commons/io/function/TestUtils.java
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;

MODIFY
src/test/java/org/apache/commons/io/function/UncheckTest.java
src/test/java/org/apache/commons/io/function/UncheckTest.java
@@ -66,7 +66,7 @@ public void testAcceptIOConsumerOfTT() {
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());
}

Change parameter order of new methods, use var-args, improve tests