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

ahuber pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/causeway.git


The following commit(s) were added to refs/heads/master by this push:
     new f7eeeb1124 CAUSEWAY-3404: TextUtils: adds general purpose string 
delimiting utils
f7eeeb1124 is described below

commit f7eeeb11245c0e7dc62aa67816e27a9b1432ee8d
Author: Andi Huber <[email protected]>
AuthorDate: Thu May 11 09:57:50 2023 +0200

    CAUSEWAY-3404: TextUtils: adds general purpose string delimiting utils
---
 .../org/apache/causeway/commons/io/TextUtils.java  | 62 +++++++++++++++
 .../causeway/commons/util/StringDelimiterTest.java | 91 ++++++++++++++++++++++
 2 files changed, 153 insertions(+)

diff --git 
a/commons/src/main/java/org/apache/causeway/commons/io/TextUtils.java 
b/commons/src/main/java/org/apache/causeway/commons/io/TextUtils.java
index f7ec016dda..8540540658 100644
--- a/commons/src/main/java/org/apache/causeway/commons/io/TextUtils.java
+++ b/commons/src/main/java/org/apache/causeway/commons/io/TextUtils.java
@@ -36,6 +36,7 @@ import org.springframework.lang.Nullable;
 import org.apache.causeway.commons.collections.Can;
 import org.apache.causeway.commons.internal.assertions._Assert;
 import org.apache.causeway.commons.internal.base._Strings;
+import org.apache.causeway.commons.internal.collections._Arrays;
 
 import lombok.AccessLevel;
 import lombok.AllArgsConstructor;
@@ -205,6 +206,67 @@ public class TextUtils {
         });
     }
 
+    // -- STRING DELIMITER
+
+    public StringDelimiter delimiter(final @NonNull String delimiter) {
+        return StringDelimiter.of(delimiter, new String[0]);
+    }
+
+    /**
+     * Holder of immutable {@link String}[] elements, that provides
+     * 'path like' composition and decomposition utilities.
+     * <p>
+     * Null or empty delimited elements are ignored.
+     */
+    @AllArgsConstructor(staticName = "of", access = AccessLevel.PRIVATE)
+    public final static class StringDelimiter {
+
+        @Getter
+        private final @NonNull String delimiter;
+        private final @NonNull String[] elements;
+
+        /**
+         * Returns a new {@link StringDelimiter} instance splitting given 
{@code string}
+         * into elements using {@link String} {@link #getDelimiter()} as 
delimiter.
+         * <p>
+         * Null or empty delimited elements are ignored.
+         * @param string - null-able
+         */
+        public StringDelimiter parse(final @Nullable String string) {
+            return new StringDelimiter(delimiter,
+                _Strings.splitThenStream(string, delimiter)
+                    .filter(_Strings::isNotEmpty)
+                    .collect(_Arrays.toArray(String.class)));
+        }
+
+        /**
+         * Streams the delimited {@link String} elements, this {@link 
StringDelimiter} is holding.
+         */
+        public Stream<String> stream() {
+            return elementCount()>0
+                    ? Stream.of(elements)
+                    : Stream.empty();
+        }
+
+        /**
+         * Returns a new {@link StringDelimiter} instance that has all the
+         * delimited {@link String} elements of this and given {@code other}
+         * {@link StringDelimiter} (in sequence).
+         * @param other - null-able
+         */
+        public StringDelimiter join(final @Nullable StringDelimiter other) {
+            return other!=null
+                    ? new StringDelimiter(delimiter,
+                            _Arrays.combine(this.elements, other.elements))
+                    : this;
+        }
+
+        public int elementCount() {
+            return elements.length;
+        }
+
+    }
+
     // -- STRING CUTTER
 
     public StringCutter cutter(final @NonNull String value) {
diff --git 
a/commons/src/test/java/org/apache/causeway/commons/util/StringDelimiterTest.java
 
b/commons/src/test/java/org/apache/causeway/commons/util/StringDelimiterTest.java
new file mode 100644
index 0000000000..a6e64043dd
--- /dev/null
+++ 
b/commons/src/test/java/org/apache/causeway/commons/util/StringDelimiterTest.java
@@ -0,0 +1,91 @@
+/*
+ *  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.causeway.commons.util;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.apache.causeway.commons.collections.Can;
+import org.apache.causeway.commons.io.TextUtils;
+
+import lombok.val;
+
+class StringDelimiterTest {
+
+    @Test
+    void parsing() {
+
+        val delimiter = TextUtils.delimiter(".");
+
+        assertThatDelimiterEquals(delimiter, new String[0]);
+        assertThatDelimiterEquals(delimiter.parse(null), new String[0]);
+        assertThatDelimiterEquals(delimiter.parse(""), new String[0]);
+        assertThatDelimiterEquals(delimiter.parse("a"), "a");
+
+        // single prefix and/or suffix
+        assertThatDelimiterEquals(delimiter.parse(".a"), "a");
+        assertThatDelimiterEquals(delimiter.parse("a."), "a");
+        assertThatDelimiterEquals(delimiter.parse(".a."), "a");
+
+        // multi prefix and/or suffix
+        assertThatDelimiterEquals(delimiter.parse("..a"), "a");
+        assertThatDelimiterEquals(delimiter.parse("a.."), "a");
+        assertThatDelimiterEquals(delimiter.parse("..a.."), "a");
+
+        assertThatDelimiterEquals(delimiter.parse("a.b"), "a", "b");
+
+        // multi infix
+        assertThatDelimiterEquals(delimiter.parse("a..b"), "a", "b");
+    }
+
+    @Test
+    void joining() {
+
+        val delimiter = TextUtils.delimiter(".");
+
+        assertThatDelimiterEquals(
+                delimiter.parse(null).join(null), new String[0]);
+
+        assertThatDelimiterEquals(
+                delimiter.parse("a.b").join(null), "a", "b");
+
+        assertThatDelimiterEquals(
+                delimiter.parse(null).join(delimiter.parse("a.b")), "a", "b");
+
+        assertThatDelimiterEquals(
+                delimiter.join(delimiter.parse("a.b")), "a", "b");
+
+        assertThatDelimiterEquals(
+                delimiter.parse("a.b").join(delimiter.parse("c.d")), "a", "b", 
"c", "d");
+
+        assertThatDelimiterEquals(
+                delimiter.parse("a.b")
+                    .join(delimiter.parse("c"))
+                    .join(delimiter.parse("d")), "a", "b", "c", "d");
+    }
+
+    // -- HELPER
+
+    private static void assertThatDelimiterEquals(final 
TextUtils.StringDelimiter delimiter, final String...parts) {
+        assertEquals(Can.ofArray(parts),
+                delimiter.stream().collect(Can.toCan()));
+    }
+
+}

Reply via email to