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-configuration.git

commit 7d7d399d0598cb0ca5f81891de34694178156dab
Author: Gary Gregory <garydgreg...@gmail.com>
AuthorDate: Sat Mar 16 18:16:32 2024 -0400

    [CONFIGURATION-840] More tests
---
 .../convert/AbstractListDelimiterHandler.java      | 40 +++++++++++++--
 .../convert/ListDelimiterHandler.java              | 31 +++---------
 .../TestPropertiesConfiguration.java               | 58 ++++++++++++++++++----
 3 files changed, 92 insertions(+), 37 deletions(-)

diff --git 
a/src/main/java/org/apache/commons/configuration2/convert/AbstractListDelimiterHandler.java
 
b/src/main/java/org/apache/commons/configuration2/convert/AbstractListDelimiterHandler.java
index 5fbcd7f9..e4ab1554 100644
--- 
a/src/main/java/org/apache/commons/configuration2/convert/AbstractListDelimiterHandler.java
+++ 
b/src/main/java/org/apache/commons/configuration2/convert/AbstractListDelimiterHandler.java
@@ -16,9 +16,13 @@
  */
 package org.apache.commons.configuration2.convert;
 
+import java.lang.reflect.Array;
+import java.nio.file.Path;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.Set;
 
 /**
  * <p>
@@ -42,15 +46,45 @@ public abstract class AbstractListDelimiterHandler 
implements ListDelimiterHandl
      * @param target the target collection
      * @param iterator the iterator to process
      * @param limit a limit for the number of elements to extract
+     * @param dejaVue Previously visited objects.
      */
-    static void flattenIterator(final ListDelimiterHandler handler, final 
Collection<Object> target, final Iterator<?> iterator, final int limit) {
+    static void flattenIterator(final ListDelimiterHandler handler, final 
Collection<Object> target, final Iterator<?> iterator, final int limit,
+            Set<Object> dejaVue) {
         int size = target.size();
         while (size < limit && iterator.hasNext()) {
-            target.addAll(handler.flatten(iterator.next(), limit - size));
-            size = target.size();
+            final Object next = iterator.next();
+            if (!dejaVue.contains(next)) {
+                target.addAll(flatten(handler, next, limit - size, dejaVue));
+                size = target.size();
+            }
         }
     }
 
+    static Collection<?> flatten(final ListDelimiterHandler handler, final 
Object value, final int limit, final Set<Object> dejaVu) {
+        dejaVu.add(value);
+        if (value instanceof String) {
+            return handler.split((String) value, true);
+        }
+        final Collection<Object> result = new LinkedList<>();
+        if (value instanceof Path) {
+            // Don't handle as an Iterable.
+            result.add(value);
+        } else if (value instanceof Iterable) {
+            AbstractListDelimiterHandler.flattenIterator(handler, result, 
((Iterable<?>) value).iterator(), limit, dejaVu);
+        } else if (value instanceof Iterator) {
+            AbstractListDelimiterHandler.flattenIterator(handler, result, 
(Iterator<?>) value, limit, dejaVu);
+        } else if (value != null) {
+            if (value.getClass().isArray()) {
+                for (int len = Array.getLength(value), idx = 0, size = 0; idx 
< len && size < limit; idx++, size = result.size()) {
+                    result.addAll(handler.flatten(Array.get(value, idx), limit 
- size));
+                }
+            } else {
+                result.add(value);
+            }
+        }
+        return result;
+    }
+
     /**
      * {@inheritDoc} This implementation checks whether the object to be 
escaped is a string. If yes, it delegates to
      * {@link #escapeString(String)}, otherwise no escaping is performed. 
Eventually, the passed in transformer is invoked
diff --git 
a/src/main/java/org/apache/commons/configuration2/convert/ListDelimiterHandler.java
 
b/src/main/java/org/apache/commons/configuration2/convert/ListDelimiterHandler.java
index d0fc1ef0..fb194049 100644
--- 
a/src/main/java/org/apache/commons/configuration2/convert/ListDelimiterHandler.java
+++ 
b/src/main/java/org/apache/commons/configuration2/convert/ListDelimiterHandler.java
@@ -16,12 +16,11 @@
  */
 package org.apache.commons.configuration2.convert;
 
-import java.lang.reflect.Array;
-import java.nio.file.Path;
 import java.util.Collection;
-import java.util.Iterator;
-import java.util.LinkedList;
+import java.util.Collections;
+import java.util.IdentityHashMap;
 import java.util.List;
+import java.util.Set;
 
 /**
  * <p>
@@ -118,27 +117,9 @@ public interface ListDelimiterHandler {
      * @since 2.9.0
      */
     default Collection<?> flatten(final Object value, final int limit) {
-        if (value instanceof String) {
-            return split((String) value, true);
-        }
-        final Collection<Object> result = new LinkedList<>();
-        if (value instanceof Path) {
-            // Don't handle as an Iterable.
-            result.add(value);
-        } else if (value instanceof Iterable) {
-            AbstractListDelimiterHandler.flattenIterator(this, result, 
((Iterable<?>) value).iterator(), limit);
-        } else if (value instanceof Iterator) {
-            AbstractListDelimiterHandler.flattenIterator(this, result, 
(Iterator<?>) value, limit);
-        } else if (value != null) {
-            if (value.getClass().isArray()) {
-                for (int len = Array.getLength(value), idx = 0, size = 0; idx 
< len && size < limit; idx++, size = result.size()) {
-                    result.addAll(flatten(Array.get(value, idx), limit - 
size));
-                }
-            } else {
-                result.add(value);
-            }
-        }
-        return result;
+        final Set<Object> dejaVu = Collections.newSetFromMap(new 
IdentityHashMap<>());
+        dejaVu.add(value);
+        return AbstractListDelimiterHandler.flatten(this, value, limit, 
dejaVu);
     }
 
 }
diff --git 
a/src/test/java/org/apache/commons/configuration2/TestPropertiesConfiguration.java
 
b/src/test/java/org/apache/commons/configuration2/TestPropertiesConfiguration.java
index 52fd5bc0..bfd415b7 100644
--- 
a/src/test/java/org/apache/commons/configuration2/TestPropertiesConfiguration.java
+++ 
b/src/test/java/org/apache/commons/configuration2/TestPropertiesConfiguration.java
@@ -33,6 +33,8 @@ import static org.junit.jupiter.api.Assertions.assertSame;
 import static org.junit.jupiter.api.Assertions.assertThrows;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
+import java.beans.beancontext.BeanContextServicesSupport;
+import java.beans.beancontext.BeanContextSupport;
 import java.io.BufferedReader;
 import java.io.ByteArrayInputStream;
 import java.io.File;
@@ -53,8 +55,9 @@ import java.net.URLStreamHandler;
 import java.nio.charset.StandardCharsets;
 import java.nio.file.FileSystems;
 import java.nio.file.Files;
-import java.nio.file.Path;
 import java.nio.file.Paths;
+import java.sql.SQLException;
+import java.sql.SQLWarning;
 import java.util.ArrayDeque;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -62,6 +65,7 @@ import java.util.Collections;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
+import java.util.PriorityQueue;
 import java.util.Properties;
 import java.util.Set;
 
@@ -435,20 +439,56 @@ public class TestPropertiesConfiguration {
         assertFalse(conf.containsKey("!comment"));
     }
 
-    @Test
-    public void testCompress840() {
+    private void testCompress840(final Iterable<?> object) {
         final PropertiesConfiguration configuration = new 
PropertiesConfiguration();
-        final Path path = FileSystems.getDefault().getPath("bar");
         final ListDelimiterHandler listDelimiterHandler = 
configuration.getListDelimiterHandler();
-        listDelimiterHandler.flatten(path, 0);
+        listDelimiterHandler.flatten(object, 0);
         // Stack overflow:
-        listDelimiterHandler.flatten(path, 1);
-        listDelimiterHandler.flatten(path, Integer.MAX_VALUE);
-        listDelimiterHandler.parse(path);
-        configuration.addProperty("foo", path);
+        listDelimiterHandler.flatten(object, 1);
+        listDelimiterHandler.flatten(object, Integer.MAX_VALUE);
+        listDelimiterHandler.parse(object);
+        configuration.addProperty("foo", object);
         configuration.toString();
     }
 
+    @Test
+    public void testCompress840BeanContextServicesSupport() {
+        testCompress840(new BeanContextServicesSupport());
+        testCompress840(new BeanContextServicesSupport(new 
BeanContextServicesSupport()));
+        final BeanContextSupport bcs = new BeanContextSupport();
+        final BeanContextServicesSupport bcss = new 
BeanContextServicesSupport();
+        bcs.add(FileSystems.getDefault().getPath("bar"));
+        bcss.add(bcs);
+        testCompress840(bcss);
+        bcss.add(FileSystems.getDefault().getPath("bar"));
+        testCompress840(bcss);
+        bcss.add(bcss);
+        testCompress840(bcss);
+    }
+
+    @Test
+    public void testCompress840BeanContextSupport() {
+        testCompress840(new BeanContextSupport());
+        testCompress840(new BeanContextSupport(new BeanContextSupport()));
+        final BeanContextSupport bcs = new BeanContextSupport();
+        bcs.add(FileSystems.getDefault().getPath("bar"));
+        testCompress840(bcs);
+        bcs.add(bcs);
+        testCompress840(bcs);
+    }
+
+    @Test
+    public void testCompress840Path() {
+        testCompress840(FileSystems.getDefault().getPath("foo"));
+        testCompress840(FileSystems.getDefault().getPath("foo", "bar"));
+    }
+
+    @Test
+    public void testCompress840PriorityQueue() {
+        testCompress840(new PriorityQueue<>());
+        testCompress840(new 
PriorityQueue<>(Arrays.asList(FileSystems.getDefault().getPath("foo"))));
+    }
+
     /**
      * Tests copying another configuration into the test configuration. This 
test ensures that the layout object is informed
      * about the newly added properties.

Reply via email to