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/09/13 00:20:23 UTC

[commons-io] branch master updated (63af628e -> 5e0998b9)

This is an automated email from the ASF dual-hosted git repository.

ggregory pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/commons-io.git


    from 63af628e Bump maven-pmd-plugin from 3.18.0 to 3.19.0
     new 93228aa1 Add IOSpliterator
     new 5e0998b9 IOExceptionList implements Iterable.

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 src/changes/changes.xml                            |   5 +-
 .../org/apache/commons/io/IOExceptionList.java     |   8 +-
 .../apache/commons/io/function/IOSpliterator.java  | 146 +++++++++++++++++++++
 ...ratorAdapter.java => IOSpliteratorAdapter.java} |  29 ++--
 .../org/apache/commons/io/IOExceptionListTest.java |  17 +++
 .../commons/io/function/IOSpliteratorTest.java     | 136 +++++++++++++++++++
 6 files changed, 319 insertions(+), 22 deletions(-)
 create mode 100644 src/main/java/org/apache/commons/io/function/IOSpliterator.java
 copy src/main/java/org/apache/commons/io/function/{IOIteratorAdapter.java => IOSpliteratorAdapter.java} (60%)
 create mode 100644 src/test/java/org/apache/commons/io/function/IOSpliteratorTest.java


[commons-io] 01/02: Add IOSpliterator

Posted by gg...@apache.org.
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 93228aa10a06b6cb3f38c18aecd0c5eea867a16c
Author: Gary Gregory <ga...@gmail.com>
AuthorDate: Mon Sep 12 17:10:56 2022 -0700

    Add IOSpliterator
---
 src/changes/changes.xml                            |   2 +-
 .../apache/commons/io/function/IOSpliterator.java  | 146 +++++++++++++++++++++
 .../commons/io/function/IOSpliteratorAdapter.java  |  45 +++++++
 .../commons/io/function/IOSpliteratorTest.java     | 136 +++++++++++++++++++
 4 files changed, 328 insertions(+), 1 deletion(-)

diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 3b8c4d9a..9d950914 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -425,7 +425,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, IOQuadFunction, IOPredicate, IOIterator, FilesUncheck.
+        Add IOBiFunction, IOTriFunction, IOQuadFunction, IOPredicate, IOIterator, IOSpliterator, FilesUncheck.
       </action>
       <action dev="ggregory" type="add" due-to="Gary Gregory">
         Add IOUtils.consume(Reader).
diff --git a/src/main/java/org/apache/commons/io/function/IOSpliterator.java b/src/main/java/org/apache/commons/io/function/IOSpliterator.java
new file mode 100644
index 00000000..550f13a4
--- /dev/null
+++ b/src/main/java/org/apache/commons/io/function/IOSpliterator.java
@@ -0,0 +1,146 @@
+/*
+ * 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.io.UncheckedIOException;
+import java.util.Objects;
+import java.util.Spliterator;
+import java.util.function.Consumer;
+
+/**
+ * Like {@link Spliterator} but throws {@link IOException}.
+ *
+ * @param <T> the type of elements returned by this IOSpliterator.
+ * @since 2.12.0
+ */
+public interface IOSpliterator<T> {
+
+    /**
+     * Adapts the given Spliterator as an IOSpliterator.
+     *
+     * @param <E> the type of the stream elements.
+     * @param iterator The iterator to adapt
+     * @return A new IOSpliterator
+     */
+    static <E> IOSpliterator<E> adapt(final Spliterator<E> iterator) {
+        return IOSpliteratorAdapter.adapt(iterator);
+    }
+
+    /**
+     * Creates a {@link Spliterator} for this instance that throws {@link UncheckedIOException} instead of
+     * {@link IOException}.
+     *
+     * @return an {@link UncheckedIOException} {@link Spliterator}.
+     */
+    default Spliterator<T> asSpliterator() {
+        return new UncheckedIOSpliterator<>(this);
+    }
+
+    /**
+     * Like {@link Spliterator#characteristics()}.
+     *
+     * @return a representation of characteristics
+     */
+    default int characteristics() {
+        return unwrap().characteristics();
+    }
+
+    /**
+     * Like {@link Spliterator#estimateSize()}.
+     *
+     *
+     * @return the estimated size, or {@code Long.MAX_VALUE} if infinite, unknown, or too expensive to compute.
+     */
+    default long estimateSize() {
+        return unwrap().estimateSize();
+    }
+
+    /**
+     * Like {@link Spliterator#forEachRemaining(Consumer)}.
+     *
+     * @param action The action
+     * @throws NullPointerException if the specified action is null
+     */
+    default void forEachRemaining(final IOConsumer<? super T> action) {
+        while (tryAdvance(action)) { // NOPMD
+        }
+    }
+
+    /**
+     * Like {@link Spliterator#getComparator()}.
+     *
+     * @return a Comparator, or {@code null} if the elements are sorted in the natural order.
+     * @throws IllegalStateException if the spliterator does not report a characteristic of {@code SORTED}.
+     */
+    @SuppressWarnings("unchecked")
+    default IOComparator<? super T> getComparator() {
+        return (IOComparator<T>) unwrap().getComparator();
+    }
+
+    /**
+     * Like {@link Spliterator#getExactSizeIfKnown()}.
+     *
+     * @return the exact size, if known, else {@code -1}.
+     */
+    default long getExactSizeIfKnown() {
+        return unwrap().getExactSizeIfKnown();
+    }
+
+    /**
+     * Like {@link Spliterator#hasCharacteristics(int)}.
+     *
+     * @param characteristics the characteristics to check for
+     * @return {@code true} if all the specified characteristics are present, else {@code false}
+     */
+    default boolean hasCharacteristics(final int characteristics) {
+        return unwrap().hasCharacteristics(characteristics);
+    }
+
+    /**
+     * Like {@link Spliterator#tryAdvance(Consumer)}.
+     *
+     * @param action The action
+     * @return {@code false} if no remaining elements existed upon entry to this method, else {@code true}.
+     * @throws NullPointerException if the specified action is null
+     */
+    default boolean tryAdvance(IOConsumer<? super T> action) {
+        return unwrap().tryAdvance(Objects.requireNonNull(action, "action").asConsumer());
+    }
+
+    /**
+     * Like {@link Spliterator#trySplit()}.
+     *
+     * @return a {@code Spliterator} covering some portion of the elements, or {@code null} if this spliterator cannot be
+     *         split
+     */
+    default IOSpliterator<T> trySplit() {
+        return adapt(unwrap().trySplit());
+    }
+
+    /**
+     * Unwraps this instance and returns the underlying {@link Spliterator}.
+     * <p>
+     * Implementations may not have anything to unwrap and that behavior is undefined for now.
+     * </p>
+     *
+     * @return the underlying Spliterator.
+     */
+    Spliterator<T> unwrap();
+
+}
diff --git a/src/main/java/org/apache/commons/io/function/IOSpliteratorAdapter.java b/src/main/java/org/apache/commons/io/function/IOSpliteratorAdapter.java
new file mode 100644
index 00000000..8c3101c1
--- /dev/null
+++ b/src/main/java/org/apache/commons/io/function/IOSpliteratorAdapter.java
@@ -0,0 +1,45 @@
+/*
+ * 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.util.Objects;
+import java.util.Spliterator;
+
+/**
+ * Adapts an {@link Spliterator} as an {@link IOSpliterator}.
+ *
+ * @param <T> the type of the stream elements.
+ */
+final class IOSpliteratorAdapter<T> implements IOSpliterator<T> {
+
+    static <E> IOSpliteratorAdapter<E> adapt(final Spliterator<E> delegate) {
+        return new IOSpliteratorAdapter<>(delegate);
+    }
+
+    private final Spliterator<T> delegate;
+
+    IOSpliteratorAdapter(final Spliterator<T> delegate) {
+        this.delegate = Objects.requireNonNull(delegate, "delegate");
+    }
+
+    @Override
+    public Spliterator<T> unwrap() {
+        return delegate;
+    }
+
+}
diff --git a/src/test/java/org/apache/commons/io/function/IOSpliteratorTest.java b/src/test/java/org/apache/commons/io/function/IOSpliteratorTest.java
new file mode 100644
index 00000000..e3cf2764
--- /dev/null
+++ b/src/test/java/org/apache/commons/io/function/IOSpliteratorTest.java
@@ -0,0 +1,136 @@
+/*
+ * 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 static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.io.IOException;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Spliterator;
+import java.util.TreeSet;
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+/**
+ * Tests {@link IOSpliterator}.
+ */
+public class IOSpliteratorTest {
+
+    private IOSpliterator<Path> spliterator;
+
+    @BeforeEach
+    public void beforeEach() {
+        spliterator = IOSpliterator.adapt(newPathList().spliterator());
+    }
+
+    private List<Path> newPathList() {
+        return Arrays.asList(TestConstants.ABS_PATH_A, TestConstants.ABS_PATH_B);
+    }
+
+    @Test
+    public void testAdapt() {
+        spliterator = IOSpliterator.adapt(newPathList().spliterator());
+        assertEquals(2, spliterator.estimateSize());
+    }
+
+    @Test
+    public void testAsSpliterator() {
+        assertEquals(2, spliterator.estimateSize());
+        assertEquals(2, spliterator.asSpliterator().estimateSize());
+    }
+
+    @Test
+    public void testCharacteristics() {
+        assertEquals(spliterator.unwrap().characteristics(), spliterator.characteristics());
+        assertEquals(spliterator.unwrap().characteristics(), spliterator.asSpliterator().characteristics());
+    }
+
+    @Test
+    public void testEstimateSize() {
+        assertEquals(2, spliterator.estimateSize());
+        assertEquals(spliterator.unwrap().estimateSize(), spliterator.estimateSize());
+        assertEquals(spliterator.unwrap().estimateSize(), spliterator.asSpliterator().estimateSize());
+    }
+
+    @Test
+    public void testForEachRemaining() {
+        final List<Path> list = new ArrayList<>();
+        spliterator.forEachRemaining(list::add);
+        assertEquals(2, list.size());
+        assertEquals(newPathList(), list);
+    }
+
+    @Test
+    public void testGetComparator() throws IOException {
+        if (spliterator.hasCharacteristics(Spliterator.SORTED)) {
+            assertEquals(spliterator.unwrap().getComparator(), spliterator.getComparator());
+            assertEquals(spliterator.unwrap().getComparator(), spliterator.asSpliterator().getComparator());
+        } else {
+            assertThrows(IllegalStateException.class, () -> spliterator.unwrap().getComparator());
+            assertThrows(IllegalStateException.class, () -> spliterator.asSpliterator().getComparator());
+        }
+        final IOSpliterator<Path> adapted = IOSpliterator.adapt(new TreeSet<>(newPathList()).stream().sorted().spliterator());
+        final IOComparator<? super Path> comparator = adapted.getComparator();
+        assertNull(comparator);
+    }
+
+    @Test
+    public void testGetExactSizeIfKnown() {
+        assertEquals(2, spliterator.getExactSizeIfKnown());
+        assertEquals(spliterator.unwrap().getExactSizeIfKnown(), spliterator.getExactSizeIfKnown());
+        assertEquals(spliterator.unwrap().getExactSizeIfKnown(), spliterator.asSpliterator().getExactSizeIfKnown());
+    }
+
+    @Test
+    public void testHasCharacteristics() {
+        assertEquals(true, spliterator.hasCharacteristics(spliterator.characteristics()));
+        assertEquals(spliterator.unwrap().hasCharacteristics(spliterator.unwrap().characteristics()),
+            spliterator.hasCharacteristics(spliterator.characteristics()));
+        assertEquals(spliterator.unwrap().hasCharacteristics(spliterator.unwrap().characteristics()),
+            spliterator.asSpliterator().hasCharacteristics(spliterator.asSpliterator().characteristics()));
+    }
+
+    @Test
+    public void testTryAdvance() {
+        final AtomicReference<Path> ref = new AtomicReference<>();
+        assertTrue(spliterator.tryAdvance(ref::set));
+        assertEquals(TestConstants.ABS_PATH_A, ref.get());
+    }
+
+    @Test
+    public void testTrySplit() {
+        final IOSpliterator<Path> trySplit = spliterator.trySplit();
+        assertNotNull(trySplit);
+        assertTrue(spliterator.getExactSizeIfKnown() > 0);
+    }
+
+    @Test
+    public void testUnwrap() {
+        assertNotNull(spliterator.unwrap());
+    }
+
+}


[commons-io] 02/02: IOExceptionList implements Iterable.

Posted by gg...@apache.org.
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 5e0998b9f1ba3b3975cecd18b4285540b02a9749
Author: Gary Gregory <ga...@gmail.com>
AuthorDate: Mon Sep 12 17:20:17 2022 -0700

    IOExceptionList implements Iterable.
---
 src/changes/changes.xml                                 |  3 +++
 .../java/org/apache/commons/io/IOExceptionList.java     |  8 +++++++-
 .../java/org/apache/commons/io/IOExceptionListTest.java | 17 +++++++++++++++++
 3 files changed, 27 insertions(+), 1 deletion(-)

diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 9d950914..e235e294 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -442,6 +442,9 @@ The <action> type attribute can be add,update,fix,remove.
       <action dev="ggregory" type="add" due-to="Gary Gregory">
         Add TimestampedObserver.isClosed().
       </action>
+      <action dev="ggregory" type="add" due-to="Gary Gregory">
+        IOExceptionList implements Iterable.
+      </action>
       <!-- UPDATE -->
       <action dev="kinow" type="update" due-to="Dependabot, Gary Gregory">
         Bump actions/cache from 2.1.6 to 3.0.8 #307, #337.
diff --git a/src/main/java/org/apache/commons/io/IOExceptionList.java b/src/main/java/org/apache/commons/io/IOExceptionList.java
index e4343576..16e13b6a 100644
--- a/src/main/java/org/apache/commons/io/IOExceptionList.java
+++ b/src/main/java/org/apache/commons/io/IOExceptionList.java
@@ -19,6 +19,7 @@ package org.apache.commons.io;
 
 import java.io.IOException;
 import java.util.Collections;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Objects;
 
@@ -31,7 +32,7 @@ import java.util.Objects;
  *
  * @since 2.7
  */
-public class IOExceptionList extends IOException {
+public class IOExceptionList extends IOException implements Iterable<Throwable> {
 
     private static final long serialVersionUID = 1L;
 
@@ -124,4 +125,9 @@ public class IOExceptionList extends IOException {
         return (List<T>) causeList;
     }
 
+    @Override
+    public Iterator<Throwable> iterator() {
+        return getCauseList().iterator();
+    }
+
 }
diff --git a/src/test/java/org/apache/commons/io/IOExceptionListTest.java b/src/test/java/org/apache/commons/io/IOExceptionListTest.java
index 19275fa4..aad7de51 100644
--- a/src/test/java/org/apache/commons/io/IOExceptionListTest.java
+++ b/src/test/java/org/apache/commons/io/IOExceptionListTest.java
@@ -26,6 +26,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
 import java.io.EOFException;
 import java.io.PrintWriter;
 import java.io.StringWriter;
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 
@@ -67,6 +68,22 @@ public class IOExceptionListTest {
         new IOExceptionList("foo", Collections.emptyList());
     }
 
+    @Test
+    public void testIterable() {
+        final EOFException cause = new EOFException();
+        final List<EOFException> list = Collections.singletonList(cause);
+        final IOExceptionList sqlExceptionList = new IOExceptionList("Hello", list);
+        //
+        assertEquals(list, sqlExceptionList.getCauseList());
+        // No CCE:
+        final List<EOFException> causeList = sqlExceptionList.getCauseList();
+        assertEquals(list, causeList);
+        //
+        final List<Throwable> list2 = new ArrayList<>();
+        sqlExceptionList.forEach(list2::add);
+        assertEquals(list2, causeList);
+    }
+
     @Test
     public void testMessageCause() {
         final EOFException cause = new EOFException();