You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by ah...@apache.org on 2018/01/23 10:57:38 UTC

[isis] 01/10: ISIS-1846 clarify corner cases for string splitting + tests

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

ahuber pushed a commit to branch ISIS-1846_internal_utils
in repository https://gitbox.apache.org/repos/asf/isis.git

commit a5931f6d1e991de0bfd5ff9c97cb54f0aaa3021d
Author: Andi Huber <ah...@apache.org>
AuthorDate: Tue Jan 23 09:01:19 2018 +0100

    ISIS-1846 clarify corner cases for string splitting + tests
---
 .../apache/isis/applib/internal/base/_Strings.java | 22 +++++--
 .../internal/base/_Strings_NaturalNames.java       |  2 +-
 .../internal/base/_Strings_SplitIterator.java      | 73 ++++++++++++++++++++++
 .../isis/applib/internal/base/StringsTest.java     | 12 +++-
 4 files changed, 101 insertions(+), 8 deletions(-)

diff --git a/core/applib/src/main/java/org/apache/isis/applib/internal/base/_Strings.java b/core/applib/src/main/java/org/apache/isis/applib/internal/base/_Strings.java
index e8f3921..52744da 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/internal/base/_Strings.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/internal/base/_Strings.java
@@ -19,10 +19,14 @@
 
 package org.apache.isis.applib.internal.base;
 
+import static org.apache.isis.applib.internal.base._Strings_SplitIterator.splitIterator;
+
 import java.util.Objects;
+import java.util.Spliterator;
+import java.util.Spliterators;
 import java.util.function.UnaryOperator;
-import java.util.regex.Pattern;
 import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
 
 import javax.annotation.Nullable;
 
@@ -127,9 +131,16 @@ public final class _Strings {
 	
 	/**
 	 * Splits the {@code input} into chunks separated by {@code separator}, 
-	 * then puts all non-empty chunks on the stream.
+	 * then puts all chunks on the stream.
+	 * <p>
+	 * Corner cases: 
+	 * <ul>
+	 * <li>{@code input} starts with {@code separator}: an empty string is the first chunk put on the stream</li>
+	 * <li>{@code input} ends with {@code separator}: an empty string is the last chunk put on the stream</li>
+	 * <li>a {@code separator} is followed by another: an empty string is put on the stream</li>
+	 * </ul> 
 	 * @param input
-	 * @param separator
+	 * @param separator non-empty string
 	 * @return empty stream if {@code input} is null
 	 * @throws {@link IllegalArgumentException} if {@code separator} is empty
 	 */
@@ -141,8 +152,9 @@ public final class _Strings {
 		if(!input.contains(separator))
 			return Stream.of(input);
 		
-		return Stream.of(input.split(Pattern.quote(separator)))
-				.filter(_Strings::isNotEmpty);
+		return StreamSupport.stream(
+		          Spliterators.spliteratorUnknownSize(splitIterator(input, separator), Spliterator.ORDERED),
+		          false); // not parallel
 	}
     
     // -- REPLACEMENT OPERATORS
diff --git a/core/applib/src/main/java/org/apache/isis/applib/internal/base/_Strings_NaturalNames.java b/core/applib/src/main/java/org/apache/isis/applib/internal/base/_Strings_NaturalNames.java
index 85192ab..3f03a84 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/internal/base/_Strings_NaturalNames.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/internal/base/_Strings_NaturalNames.java
@@ -26,7 +26,7 @@ import javax.annotation.Nullable;
  * package private mixin for utility class {@link _Strings}
  *
  */
-class _Strings_NaturalNames {
+final class _Strings_NaturalNames {
 	
 	private static final char SPACE = ' ';
  	/**
diff --git a/core/applib/src/main/java/org/apache/isis/applib/internal/base/_Strings_SplitIterator.java b/core/applib/src/main/java/org/apache/isis/applib/internal/base/_Strings_SplitIterator.java
new file mode 100644
index 0000000..3e89771
--- /dev/null
+++ b/core/applib/src/main/java/org/apache/isis/applib/internal/base/_Strings_SplitIterator.java
@@ -0,0 +1,73 @@
+/*
+ *  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.isis.applib.internal.base;
+
+import java.util.Collections;
+import java.util.Iterator;
+
+import javax.annotation.Nullable;
+
+/**
+ * 
+ * package private mixin for utility class {@link _Strings}
+ *
+ */
+final class _Strings_SplitIterator {
+	
+	public static Iterator<String> splitIterator(@Nullable final String x, final String delimiter){
+		if(_Strings.isEmpty(delimiter))
+			throw new IllegalArgumentException("a non empty delimiter is required");
+		if(_Strings.isEmpty(x))
+			return Collections.<String>emptyIterator();
+		final int dlen = delimiter.length();
+		return new Iterator<String>() {
+			private int p=0, q=-1;
+			
+			private String next = _next();
+			
+			private String _next() {
+				if(q==-2)
+					return null;
+				q = x.indexOf(delimiter, p);
+				if(q>-1) {
+					final int p0 = p; p=q+dlen; 
+					return x.substring(p0, q);
+				}
+				q = -2; // terminal
+				return x.substring(p, x.length());
+			}
+			
+			@Override
+			public boolean hasNext() {
+				return next!=null;
+			}
+			
+			@Override
+			public String next() {
+				try { 
+					return next; 
+				} finally { 
+					next=_next(); 
+				}
+			}
+		};
+	}
+	
+}
diff --git a/core/applib/src/test/java/org/apache/isis/applib/internal/base/StringsTest.java b/core/applib/src/test/java/org/apache/isis/applib/internal/base/StringsTest.java
index 0180bc1..8d8c963 100644
--- a/core/applib/src/test/java/org/apache/isis/applib/internal/base/StringsTest.java
+++ b/core/applib/src/test/java/org/apache/isis/applib/internal/base/StringsTest.java
@@ -136,7 +136,7 @@ public class StringsTest {
 		Assert.assertThat(
 				_Strings.splitThenStream("$ 1$2 a$Bc ", "$")
 				.collect(Collectors.joining("|")),
-				is(" 1|2 a|Bc "));
+				is("| 1|2 a|Bc "));
 	}
 	
 	@Test
@@ -144,7 +144,15 @@ public class StringsTest {
 		Assert.assertThat(
 				_Strings.splitThenStream(" 1$2 a$Bc $", "$")
 				.collect(Collectors.joining("|")),
-				is(" 1|2 a|Bc "));
+				is(" 1|2 a|Bc |"));
+	}
+	
+	@Test
+	public void splitThenStreamMultipleWithSeparatorsInSequence() throws Exception {
+		Assert.assertThat(
+				_Strings.splitThenStream(" 1$2 a$$Bc ", "$")
+				.collect(Collectors.joining("|")),
+				is(" 1|2 a||Bc "));
 	}
 	
 	@Test

-- 
To stop receiving notification emails like this one, please contact
ahuber@apache.org.