You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by nf...@apache.org on 2022/10/18 12:55:31 UTC
[camel] 02/02: CAMEL-16354: camel-core - Optimize Splitter using java.util.Scanner
This is an automated email from the ASF dual-hosted git repository.
nfilotto pushed a commit to branch CAMEL-16354/optimize-splitter
in repository https://gitbox.apache.org/repos/asf/camel.git
commit 0ee5ae94fb13db71c9ff2e385da9e9eb80f17c9e
Author: Nicolas Filotto <nf...@talend.com>
AuthorDate: Tue Oct 18 14:55:04 2022 +0200
CAMEL-16354: camel-core - Optimize Splitter using java.util.Scanner
---
.../org/apache/camel/util/ObjectHelperTest.java | 40 ++++++++-
.../org/apache/camel/support/ObjectHelper.java | 100 ++++++++++++++++++++-
2 files changed, 136 insertions(+), 4 deletions(-)
diff --git a/core/camel-core/src/test/java/org/apache/camel/util/ObjectHelperTest.java b/core/camel-core/src/test/java/org/apache/camel/util/ObjectHelperTest.java
index 4527d95187a..49a36639ea0 100644
--- a/core/camel-core/src/test/java/org/apache/camel/util/ObjectHelperTest.java
+++ b/core/camel-core/src/test/java/org/apache/camel/util/ObjectHelperTest.java
@@ -29,6 +29,8 @@ import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Properties;
+import java.util.stream.Collectors;
+import java.util.stream.StreamSupport;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
@@ -47,8 +49,17 @@ import org.apache.camel.support.CamelContextHelper;
import org.apache.camel.support.DefaultMessage;
import org.apache.camel.support.ObjectHelper;
import org.junit.jupiter.api.Test;
-
-import static org.junit.jupiter.api.Assertions.*;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNotSame;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertSame;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
public class ObjectHelperTest {
@@ -1016,4 +1027,29 @@ public class ObjectHelperTest {
assertEquals("foo", out2.get(0));
assertEquals("bar", out2.get(1));
}
+
+ @Test
+ void testIterableWithNullContent() {
+ assertEquals("", StreamSupport.stream(ObjectHelper.createIterable(null, ";;").spliterator(), false)
+ .collect(Collectors.joining("-")));
+ }
+
+ @Test
+ void testIterableWithEmptyContent() {
+ assertEquals("", StreamSupport.stream(ObjectHelper.createIterable("", ";;").spliterator(), false)
+ .collect(Collectors.joining("-")));
+ }
+
+ @Test
+ void testIterableWithOneElement() {
+ assertEquals("foo", StreamSupport.stream(ObjectHelper.createIterable("foo", ";;").spliterator(), false)
+ .collect(Collectors.joining("-")));
+ }
+
+ @ParameterizedTest
+ @ValueSource(strings = { "foo;;bar", ";;foo;;bar", "foo;;bar;;", ";;foo;;bar;;" })
+ void testIterableWithTwoElements(String content) {
+ assertEquals("foo-bar", StreamSupport.stream(ObjectHelper.createIterable(content, ";;").spliterator(), false)
+ .collect(Collectors.joining("-")));
+ }
}
diff --git a/core/camel-support/src/main/java/org/apache/camel/support/ObjectHelper.java b/core/camel-support/src/main/java/org/apache/camel/support/ObjectHelper.java
index 120b2af6a95..92accefbcd1 100644
--- a/core/camel-support/src/main/java/org/apache/camel/support/ObjectHelper.java
+++ b/core/camel-support/src/main/java/org/apache/camel/support/ObjectHelper.java
@@ -550,8 +550,10 @@ public final class ObjectHelper {
int count = StringHelper.countChar(value, DEFAULT_DELIMITER_CHAR) + 1;
return () -> StringHelper.splitOnCharacterAsIterator(value, DEFAULT_DELIMITER_CHAR, count);
}
+ } else if (pattern) {
+ return () -> new Scanner(value, delimiter);
}
- return () -> new Scanner(value, delimiter);
+ return () -> new StringIterator(value, delimiter);
} else if (allowEmptyValues || org.apache.camel.util.ObjectHelper.isNotEmpty(value)) {
return Collections.singletonList(value);
} else {
@@ -770,9 +772,10 @@ public final class ObjectHelper {
return (Iterable<String>) () -> StringHelper.splitOnCharacterAsIterator(s, DEFAULT_DELIMITER_CHAR,
count);
}
- } else {
+ } else if (pattern) {
return (Iterable<String>) () -> new Scanner(s, delimiter);
}
+ return (Iterable<String>) () -> new StringIterator(s, delimiter);
} else {
return (Iterable<Object>) () -> {
// use a plain iterator that returns the value as is as there are only a single value
@@ -886,4 +889,97 @@ public final class ObjectHelper {
return false;
}
+ /**
+ * An {@link Iterator} to split an input {@code String} content according to a specific separator.
+ */
+ private static class StringIterator implements Iterator<String> {
+
+ /**
+ * Flag indicating that the indexes have already been computed.
+ */
+ private boolean computed;
+ /**
+ * The current {@code from} index.
+ */
+ private int from;
+ /**
+ * The current {@code to} index.
+ */
+ private int to;
+ /**
+ * The content to split.
+ */
+ private final String content;
+ /**
+ * The separator to use when splitting the content.
+ */
+ private final String separator;
+ /**
+ * The length of the separator.
+ */
+ private final int separatorLength;
+ /**
+ * The length of the part of the content to split.
+ */
+ private final int contentLength;
+
+ /**
+ * Construct a {@code StringIterator} with the specified content and separator.
+ *
+ * @param content
+ * @param separator
+ */
+ StringIterator(String content, String separator) {
+ this.content = content;
+ this.separator = separator;
+ this.separatorLength = separator.length();
+ boolean skipStart = content.startsWith(separator);
+ boolean skipEnd = content.endsWith(separator);
+ if (skipStart && skipEnd) {
+ from = separatorLength;
+ contentLength = content.length() - separatorLength;
+ } else if (skipStart) {
+ from = separatorLength;
+ this.contentLength = content.length();
+ } else if (skipEnd) {
+ contentLength = content.length() - separatorLength;
+ } else {
+ this.contentLength = content.length();
+ }
+ }
+
+ @Override
+ public boolean hasNext() {
+ if (computed) {
+ return to != -1;
+ } else if (to == -1) {
+ return false;
+ }
+ int index = content.indexOf(separator, from);
+ if (index == -1 || index == contentLength) {
+ to = contentLength;
+ } else {
+ to = index;
+ }
+ computed = true;
+ return true;
+ }
+
+ @Override
+ public String next() {
+ if (!hasNext()) {
+ throw new NoSuchElementException();
+ }
+ String answer;
+ if (to == contentLength) {
+ answer = content.substring(from, contentLength);
+ to = -1;
+ } else {
+ answer = content.substring(from, to);
+ from = to + separatorLength;
+ }
+ computed = false;
+ return answer;
+ }
+ }
}