You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by gg...@apache.org on 2022/07/24 16:38:25 UTC

[commons-io] 02/21: Add IOQuadFunction.

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 e03ade02cdc214119032a15a5fb52b767b0aaa9b
Author: Gary Gregory <ga...@gmail.com>
AuthorDate: Sat Jul 23 19:32:47 2022 -0400

    Add IOQuadFunction.
---
 src/changes/changes.xml                            |  2 +-
 .../java/org/apache/commons/io/UncheckedIO.java    | 56 ++++++++++----
 .../apache/commons/io/function/IOQuadFunction.java | 70 +++++++++++++++++
 .../commons/io/function/IOQuadFunctionTest.java    | 90 ++++++++++++++++++++++
 4 files changed, 202 insertions(+), 16 deletions(-)

diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index bafa38d9..9ff69f60 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -410,7 +410,7 @@ The <action> type attribute can be add,update,fix,remove.
         Add PathUtils.getLastModifiedFileTime(*).
       </action>
       <action dev="ggregory" type="add" due-to="Gary Gregory">
-        Add IOBiFunction, IOTriFunction.
+        Add IOBiFunction, IOTriFunction, IOQuadFunction.
       </action>
       <!-- UPDATE -->
       <action dev="kinow" type="update" due-to="Dependabot, Gary Gregory">
diff --git a/src/main/java/org/apache/commons/io/UncheckedIO.java b/src/main/java/org/apache/commons/io/UncheckedIO.java
index c8e0791b..9289d9e4 100644
--- a/src/main/java/org/apache/commons/io/UncheckedIO.java
+++ b/src/main/java/org/apache/commons/io/UncheckedIO.java
@@ -23,6 +23,7 @@ import java.io.UncheckedIOException;
 import org.apache.commons.io.function.IOBiFunction;
 import org.apache.commons.io.function.IOConsumer;
 import org.apache.commons.io.function.IOFunction;
+import org.apache.commons.io.function.IOQuadFunction;
 import org.apache.commons.io.function.IORunnable;
 import org.apache.commons.io.function.IOSupplier;
 import org.apache.commons.io.function.IOTriFunction;
@@ -53,7 +54,7 @@ public class UncheckedIO {
     /**
      * Applies an IO bi-function with the given arguments.
      *
-     * @param biFunction the function.
+     * @param function the function.
      * @param <T> the first function argument type.
      * @param <U> the second function argument type.
      * @param <R> the return type.
@@ -63,9 +64,9 @@ public class UncheckedIO {
      * @return the function result
      * @throws UncheckedIOException if an I/O error occurs.
      */
-    public static <T, U, R> R apply(final IOBiFunction<T, U, R> biFunction, final T t, final U u) {
+    public static <T, U, R> R apply(final IOBiFunction<T, U, R> function, final T t, final U u) {
         try {
-            return biFunction.apply(t, u);
+            return function.apply(t, u);
         } catch (final IOException e) {
             throw wrap(e);
         }
@@ -91,39 +92,51 @@ public class UncheckedIO {
     }
 
     /**
-     * Applies an IO tri-function with the given arguments.
+     * Applies an IO quad-function with the given arguments.
      *
-     * @param triFunction the function.
+     * @param function the function.
      * @param <T> the first function argument type.
      * @param <U> the second function argument type.
      * @param <V> the third function argument type.
+     * @param <W> the fourth function argument type.
      * @param <R> the return type.
      *
      * @param t the first function argument
      * @param u the second function argument
      * @param v the third function argument
+     * @param w the fourth function argument
      * @return the function result
      * @throws UncheckedIOException if an I/O error occurs.
      */
-    public static <T, U, V, R> R apply(final IOTriFunction<T, U, V, R> triFunction, final T t, final U u, final V v) {
+    public static <T, U, V, W, R> R apply(final IOQuadFunction<T, U, V, W, R> function, final T t, final U u, final V v, final W w) {
         try {
-            return triFunction.apply(t, u, v);
+            return function.apply(t, u, v, w);
         } catch (final IOException e) {
             throw wrap(e);
         }
     }
 
     /**
-     * Creates a new UncheckedIOException for the given detail message.
-     * <p>
-     * This method exists because there is no String constructor in {@link UncheckedIOException}.
-     * </p>
+     * Applies an IO tri-function with the given arguments.
      *
-     * @param e The exception to wrap.
-     * @return a new {@link UncheckedIOException}.
+     * @param function the function.
+     * @param <T> the first function argument type.
+     * @param <U> the second function argument type.
+     * @param <V> the third function argument type.
+     * @param <R> the return type.
+     *
+     * @param t the first function argument
+     * @param u the second function argument
+     * @param v the third function argument
+     * @return the function result
+     * @throws UncheckedIOException if an I/O error occurs.
      */
-    private static UncheckedIOException wrap(final IOException e) {
-        return new UncheckedIOException(e);
+    public static <T, U, V, R> R apply(final IOTriFunction<T, U, V, R> function, final T t, final U u, final V v) {
+        try {
+            return function.apply(t, u, v);
+        } catch (final IOException e) {
+            throw wrap(e);
+        }
     }
 
     /**
@@ -155,4 +168,17 @@ public class UncheckedIO {
             throw wrap(e);
         }
     }
+
+    /**
+     * Creates a new UncheckedIOException for the given detail message.
+     * <p>
+     * This method exists because there is no String constructor in {@link UncheckedIOException}.
+     * </p>
+     *
+     * @param e The exception to wrap.
+     * @return a new {@link UncheckedIOException}.
+     */
+    private static UncheckedIOException wrap(final IOException e) {
+        return new UncheckedIOException(e);
+    }
 }
diff --git a/src/main/java/org/apache/commons/io/function/IOQuadFunction.java b/src/main/java/org/apache/commons/io/function/IOQuadFunction.java
new file mode 100644
index 00000000..73916364
--- /dev/null
+++ b/src/main/java/org/apache/commons/io/function/IOQuadFunction.java
@@ -0,0 +1,70 @@
+/*
+ * 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;
+import java.util.Objects;
+import java.util.function.Function;
+
+/**
+ * Represents a function that accepts four arguments and produces a result. This is the four-arity specialization of
+ * {@link IOFunction}.
+ *
+ * <p>
+ * This is a <a href="package-summary.html">functional interface</a> whose functional method is
+ * {@link #apply(Object, Object, Object, Object)}.
+ * </p>
+ *
+ * @param <T> the type of the first argument to the function
+ * @param <U> the type of the second argument to the function
+ * @param <V> the type of the third argument to the function
+ * @param <W> the type of the fourth argument to the function
+ * @param <R> the type of the result of the function
+ *
+ * @see Function
+ * @since 2.12.0
+ */
+@FunctionalInterface
+public interface IOQuadFunction<T, U, V, W, R> {
+
+    /**
+     * Applies this function to the given arguments.
+     *
+     * @param t the first function argument
+     * @param u the second function argument
+     * @param v the third function argument
+     * @param w the fourth function argument
+     * @return the function result
+     * @throws IOException if an I/O error occurs.
+     */
+    R apply(T t, U u, V v, W w) throws IOException;
+
+    /**
+     * Returns a composed function that first applies this function to its input, and then applies the {@code after}
+     * function to the result. If evaluation of either function throws an exception, it is relayed to the caller of the
+     * composed function.
+     *
+     * @param <X> the type of output of the {@code after} function, and of the composed function
+     * @param after the function to apply after this function is applied
+     * @return a composed function that first applies this function and then applies the {@code after} function
+     * @throws NullPointerException if after is null
+     */
+    default <X> IOQuadFunction<T, U, V, W, X> andThen(final IOFunction<? super R, ? extends X> after) {
+        Objects.requireNonNull(after);
+        return (final T t, final U u, final V v, final W w) -> after.apply(apply(t, u, v, w));
+    }
+}
diff --git a/src/test/java/org/apache/commons/io/function/IOQuadFunctionTest.java b/src/test/java/org/apache/commons/io/function/IOQuadFunctionTest.java
new file mode 100644
index 00000000..252de592
--- /dev/null
+++ b/src/test/java/org/apache/commons/io/function/IOQuadFunctionTest.java
@@ -0,0 +1,90 @@
+/*
+ * 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 static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.junit.jupiter.api.Test;
+
+/**
+ * Tests {@link IOQuadFunction}.
+ */
+public class IOQuadFunctionTest {
+
+    /**
+     * Tests {@link IOQuadFunction#apply(Object, Object, Object, Object)}.
+     *
+     * @throws IOException thrown on test failure
+     */
+    @Test
+    public void testAccept() throws IOException {
+        final AtomicReference<Byte> ref1 = new AtomicReference<>();
+        final AtomicReference<Short> ref2 = new AtomicReference<>();
+        final AtomicReference<String> ref3 = new AtomicReference<>();
+        final AtomicReference<Long> ref4 = new AtomicReference<>();
+        final IOQuadFunction<AtomicReference<Byte>, AtomicReference<Short>, AtomicReference<String>, AtomicReference<Long>, String> quad = (t, u, v, w) -> {
+            ref1.set(Byte.valueOf("1"));
+            ref2.set(Short.valueOf((short) 1));
+            ref3.set("z");
+            ref4.set(Long.valueOf(2));
+            return "ABCD";
+        };
+        assertEquals("ABCD", quad.apply(ref1, ref2, ref3, ref4));
+        assertEquals(Byte.valueOf("1"), ref1.get());
+        assertEquals(Short.valueOf((short) 1), ref2.get());
+        assertEquals("z", ref3.get());
+        assertEquals(Long.valueOf(2), ref4.get());
+    }
+
+    /**
+     * Tests {@link IOTriFunction#andThen(IOFunction)}.
+     *
+     * @throws IOException thrown on test failure
+     */
+    @Test
+    public void testAndThenIOFunction() throws IOException {
+        final AtomicReference<Byte> ref1 = new AtomicReference<>();
+        final AtomicReference<Short> ref2 = new AtomicReference<>();
+        final AtomicReference<String> ref3 = new AtomicReference<>();
+        final AtomicReference<Long> ref4 = new AtomicReference<>();
+        final IOQuadFunction<AtomicReference<Byte>, AtomicReference<Short>, AtomicReference<String>, AtomicReference<Long>, String> quad = (t, u, v, w) -> {
+            ref1.set(Byte.valueOf("1"));
+            ref2.set(Short.valueOf((short) 1));
+            ref3.set("z");
+            ref4.set(Long.valueOf(2));
+            return "9";
+        };
+        final IOFunction<String, BigInteger> after = t -> {
+            ref1.set(Byte.valueOf("2"));
+            ref2.set(Short.valueOf((short) 2));
+            ref3.set("zz");
+            ref4.set(Long.valueOf(3));
+            return BigInteger.valueOf(Long.parseLong(t)).add(BigInteger.ONE);
+        };
+        assertEquals(BigInteger.TEN, quad.andThen(after).apply(ref1, ref2, ref3, ref4));
+        assertEquals(Byte.valueOf("2"), ref1.get());
+        assertEquals(Short.valueOf((short) 2), ref2.get());
+        assertEquals("zz", ref3.get());
+        assertEquals(Long.valueOf(3), ref4.get());
+    }
+
+}