You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2016/01/04 11:17:08 UTC

[1/2] camel git commit: CAMEL-9471: Tokenizer - Add option to skip first

Repository: camel
Updated Branches:
  refs/heads/master 23df4a35d -> 4545915b3


CAMEL-9471: Tokenizer - Add option to skip first


Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/ff9bfd5e
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/ff9bfd5e
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/ff9bfd5e

Branch: refs/heads/master
Commit: ff9bfd5e9077681966ffddea56bc93d9217207cd
Parents: 23df4a3
Author: Claus Ibsen <da...@apache.org>
Authored: Mon Jan 4 10:18:18 2016 +0100
Committer: Claus Ibsen <da...@apache.org>
Committed: Mon Jan 4 10:18:18 2016 +0100

----------------------------------------------------------------------
 .../apache/camel/builder/ExpressionBuilder.java | 34 +++++++++++--
 .../apache/camel/builder/ExpressionClause.java  | 41 +++++++++++++++-
 .../camel/builder/ExpressionClauseSupport.java  | 46 ++++++++++++++++++
 .../language/tokenizer/TokenizeLanguage.java    | 15 +++++-
 .../model/language/TokenizerExpression.java     | 16 +++++++
 .../org/apache/camel/util/GroupIterator.java    | 14 ++++++
 .../apache/camel/util/GroupTokenIterator.java   | 17 ++++++-
 .../processor/SplitGroupSkipFirstTest.java      | 50 ++++++++++++++++++++
 .../camel/util/GroupTokenIteratorTest.java      | 20 +++++++-
 .../SpringSplitGroupSkipFirstTest.java          | 32 +++++++++++++
 .../processor/SplitGroupSkipFirstTest.xml       | 38 +++++++++++++++
 11 files changed, 312 insertions(+), 11 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/ff9bfd5e/camel-core/src/main/java/org/apache/camel/builder/ExpressionBuilder.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/builder/ExpressionBuilder.java b/camel-core/src/main/java/org/apache/camel/builder/ExpressionBuilder.java
index f83554b..71dd6b4 100644
--- a/camel-core/src/main/java/org/apache/camel/builder/ExpressionBuilder.java
+++ b/camel-core/src/main/java/org/apache/camel/builder/ExpressionBuilder.java
@@ -1274,6 +1274,30 @@ public final class ExpressionBuilder {
     }
 
     /**
+     * Returns an expression that skips the first element
+     */
+    public static Expression skipFirstExpression(final Expression expression) {
+        return new ExpressionAdapter() {
+            public Object evaluate(Exchange exchange) {
+                Object value = expression.evaluate(exchange, Object.class);
+                Iterator it = exchange.getContext().getTypeConverter().tryConvertTo(Iterator.class, exchange, value);
+                if (it != null) {
+                    // skip first
+                    it.next();
+                    return it;
+                } else {
+                    return value;
+                }
+            }
+
+            @Override
+            public String toString() {
+                return "skipFirst(" + expression + ")";
+            }
+        };
+    }
+
+    /**
      * Returns an {@link TokenPairExpressionIterator} expression
      */
     public static Expression tokenizePairExpression(String startToken, String endToken, boolean includeTokens) {
@@ -1346,7 +1370,7 @@ public final class ExpressionBuilder {
                 Iterator<?> it = expression.evaluate(exchange, Iterator.class);
                 ObjectHelper.notNull(it, "expression: " + expression + " evaluated on " + exchange + " must return an java.util.Iterator");
                 // must use GroupTokenIterator in xml mode as we want to concat the xml parts into a single message
-                return new GroupTokenIterator(exchange, it, null, group);
+                return new GroupTokenIterator(exchange, it, null, group, false);
             }
 
             @Override
@@ -1356,16 +1380,16 @@ public final class ExpressionBuilder {
         };
     }
 
-    public static Expression groupIteratorExpression(final Expression expression, final String token, final int group) {
+    public static Expression groupIteratorExpression(final Expression expression, final String token, final int group, final boolean skipFirst) {
         return new ExpressionAdapter() {
             public Object evaluate(Exchange exchange) {
                 // evaluate expression as iterator
                 Iterator<?> it = expression.evaluate(exchange, Iterator.class);
                 ObjectHelper.notNull(it, "expression: " + expression + " evaluated on " + exchange + " must return an java.util.Iterator");
                 if (token != null) {
-                    return new GroupTokenIterator(exchange, it, token, group);
+                    return new GroupTokenIterator(exchange, it, token, group, skipFirst);
                 } else {
-                    return new GroupIterator(exchange, it, group);
+                    return new GroupIterator(exchange, it, group, skipFirst);
                 }
             }
 
@@ -1991,7 +2015,7 @@ public final class ExpressionBuilder {
             public Object evaluate(Exchange exchange) {
                 // use simple language
                 Expression exp = exchange.getContext().resolveLanguage("simple").createExpression(expression);
-                return ExpressionBuilder.groupIteratorExpression(exp, null, group).evaluate(exchange, Object.class);
+                return ExpressionBuilder.groupIteratorExpression(exp, null, group, false).evaluate(exchange, Object.class);
             }
 
             @Override

http://git-wip-us.apache.org/repos/asf/camel/blob/ff9bfd5e/camel-core/src/main/java/org/apache/camel/builder/ExpressionClause.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/builder/ExpressionClause.java b/camel-core/src/main/java/org/apache/camel/builder/ExpressionClause.java
index 64f3594..6afe039 100644
--- a/camel-core/src/main/java/org/apache/camel/builder/ExpressionClause.java
+++ b/camel-core/src/main/java/org/apache/camel/builder/ExpressionClause.java
@@ -488,7 +488,19 @@ public class ExpressionClause<T> extends ExpressionDefinition {
      * @return the builder to continue processing the DSL
      */
     public T tokenize(String token, boolean regex) {
-        return delegate.tokenize(token, regex);
+        return tokenize(token, regex, false);
+    }
+
+    /**
+     * Evaluates a token expression on the message body
+     *
+     * @param token the token
+     * @param regex whether the token is a regular expression or not
+     * @param skipFirst whether to skip the first element
+     * @return the builder to continue processing the DSL
+     */
+    public T tokenize(String token, boolean regex, boolean skipFirst) {
+        return delegate.tokenize(token, null, regex, skipFirst);
     }
 
     /**
@@ -500,7 +512,20 @@ public class ExpressionClause<T> extends ExpressionDefinition {
      * @return the builder to continue processing the DSL
      */
     public T tokenize(String token, boolean regex, int group) {
-        return delegate.tokenize(token, regex, group);
+        return tokenize(token, regex, group, false);
+    }
+
+    /**
+     * Evaluates a token expression on the message body
+     *
+     * @param token the token
+     * @param regex whether the token is a regular expression or not
+     * @param group to group by the given number
+     * @param skipFirst whether to skip the first element
+     * @return the builder to continue processing the DSL
+     */
+    public T tokenize(String token, boolean regex, int group, boolean skipFirst) {
+        return delegate.tokenize(token, null, regex, group, skipFirst);
     }
 
     /**
@@ -515,6 +540,18 @@ public class ExpressionClause<T> extends ExpressionDefinition {
     }
 
     /**
+     * Evaluates a token expression on the message body
+     *
+     * @param token the token
+     * @param group to group by the given number
+     * @param skipFirst whether to skip the first element
+     * @return the builder to continue processing the DSL
+     */
+    public T tokenize(String token, int group, boolean skipFirst) {
+        return delegate.tokenize(token, group, skipFirst);
+    }
+
+    /**
      * Evaluates a token expression on the given header
      *
      * @param token the token

http://git-wip-us.apache.org/repos/asf/camel/blob/ff9bfd5e/camel-core/src/main/java/org/apache/camel/builder/ExpressionClauseSupport.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/builder/ExpressionClauseSupport.java b/camel-core/src/main/java/org/apache/camel/builder/ExpressionClauseSupport.java
index a40b932..8abe8f3 100644
--- a/camel-core/src/main/java/org/apache/camel/builder/ExpressionClauseSupport.java
+++ b/camel-core/src/main/java/org/apache/camel/builder/ExpressionClauseSupport.java
@@ -555,6 +555,18 @@ public class ExpressionClauseSupport<T> {
      * Evaluates a token expression on the message body
      *
      * @param token the token
+     * @param group to group by the given number
+     * @param skipFirst whether to skip the very first element
+     * @return the builder to continue processing the DSL
+     */
+    public T tokenize(String token, int group, boolean skipFirst) {
+        return tokenize(token, null, false, group, skipFirst);
+    }
+
+    /**
+     * Evaluates a token expression on the message body
+     *
+     * @param token the token
      * @param regex whether the token is a regular expression or not
      * @return the builder to continue processing the DSL
      */
@@ -612,11 +624,45 @@ public class ExpressionClauseSupport<T> {
      * @return the builder to continue processing the DSL
      */
     public T tokenize(String token, String headerName, boolean regex, int group) {
+        return tokenize(token, headerName, regex, group, false);
+    }
+
+    /**
+     * Evaluates a token expression on the given header
+     *
+     * @param token the token
+     * @param headerName name of header to tokenize
+     * @param regex whether the token is a regular expression or not
+     * @param skipFirst whether to skip the very first element
+     * @return the builder to continue processing the DSL
+     */
+    public T tokenize(String token, String headerName, boolean regex, boolean skipFirst) {
+        TokenizerExpression expression = new TokenizerExpression();
+        expression.setToken(token);
+        expression.setHeaderName(headerName);
+        expression.setRegex(regex);
+        expression.setSkipFirst(skipFirst);
+        setExpressionType(expression);
+        return result;
+    }
+
+    /**
+     * Evaluates a token expression on the given header
+     *
+     * @param token the token
+     * @param headerName name of header to tokenize
+     * @param regex whether the token is a regular expression or not
+     * @param group to group by number of parts
+     * @param skipFirst whether to skip the very first element
+     * @return the builder to continue processing the DSL
+     */
+    public T tokenize(String token, String headerName, boolean regex, int group, boolean skipFirst) {
         TokenizerExpression expression = new TokenizerExpression();
         expression.setToken(token);
         expression.setHeaderName(headerName);
         expression.setRegex(regex);
         expression.setGroup(group);
+        expression.setSkipFirst(skipFirst);
         setExpressionType(expression);
         return result;
     }

http://git-wip-us.apache.org/repos/asf/camel/blob/ff9bfd5e/camel-core/src/main/java/org/apache/camel/language/tokenizer/TokenizeLanguage.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/language/tokenizer/TokenizeLanguage.java b/camel-core/src/main/java/org/apache/camel/language/tokenizer/TokenizeLanguage.java
index aa18750..22b62a2 100644
--- a/camel-core/src/main/java/org/apache/camel/language/tokenizer/TokenizeLanguage.java
+++ b/camel-core/src/main/java/org/apache/camel/language/tokenizer/TokenizeLanguage.java
@@ -47,6 +47,7 @@ public class TokenizeLanguage implements Language, IsSingleton {
     private boolean xml;
     private boolean includeTokens;
     private int group;
+    private boolean skipFirst;
 
     public static Expression tokenize(String token) {
         return tokenize(token, false);
@@ -120,6 +121,10 @@ public class TokenizeLanguage implements Language, IsSingleton {
             } else {
                 answer = ExpressionBuilder.tokenizeExpression(exp, token);
             }
+            if (group == 0 && skipFirst) {
+                // wrap in skip first (if group then it has its own skip first logic)
+                answer = ExpressionBuilder.skipFirstExpression(answer);
+            }
         }
 
         // if group then wrap answer in group expression
@@ -127,7 +132,7 @@ public class TokenizeLanguage implements Language, IsSingleton {
             if (isXml()) {
                 answer = ExpressionBuilder.groupXmlIteratorExpression(answer, group);
             } else {
-                answer = ExpressionBuilder.groupIteratorExpression(answer, token, group);
+                answer = ExpressionBuilder.groupIteratorExpression(answer, token, group, skipFirst);
             }
         }
 
@@ -205,6 +210,14 @@ public class TokenizeLanguage implements Language, IsSingleton {
         this.group = group;
     }
 
+    public boolean isSkipFirst() {
+        return skipFirst;
+    }
+
+    public void setSkipFirst(boolean skipFirst) {
+        this.skipFirst = skipFirst;
+    }
+
     public boolean isSingleton() {
         return false;
     }

http://git-wip-us.apache.org/repos/asf/camel/blob/ff9bfd5e/camel-core/src/main/java/org/apache/camel/model/language/TokenizerExpression.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/model/language/TokenizerExpression.java b/camel-core/src/main/java/org/apache/camel/model/language/TokenizerExpression.java
index cf09ca5..7c7f3d1 100644
--- a/camel-core/src/main/java/org/apache/camel/model/language/TokenizerExpression.java
+++ b/camel-core/src/main/java/org/apache/camel/model/language/TokenizerExpression.java
@@ -53,6 +53,8 @@ public class TokenizerExpression extends ExpressionDefinition {
     private Boolean includeTokens;
     @XmlAttribute
     private Integer group;
+    @XmlAttribute
+    private Boolean skipFirst;
 
     public TokenizerExpression() {
     }
@@ -155,6 +157,17 @@ public class TokenizerExpression extends ExpressionDefinition {
         this.group = group;
     }
 
+    public Boolean getSkipFirst() {
+        return skipFirst;
+    }
+
+    /**
+     * To skip the very first element
+     */
+    public void setSkipFirst(Boolean skipFirst) {
+        this.skipFirst = skipFirst;
+    }
+
     @Override
     public Expression createExpression(CamelContext camelContext) {
         // special for new line tokens, if defined from XML then its 2 characters, so we replace that back to a single char
@@ -182,6 +195,9 @@ public class TokenizerExpression extends ExpressionDefinition {
             }
             language.setGroup(group);
         }
+        if (skipFirst != null) {
+            language.setSkipFirst(skipFirst);
+        }
         return language.createExpression();
     }
 

http://git-wip-us.apache.org/repos/asf/camel/blob/ff9bfd5e/camel-core/src/main/java/org/apache/camel/util/GroupIterator.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/util/GroupIterator.java b/camel-core/src/main/java/org/apache/camel/util/GroupIterator.java
index 0ccced1..f92faf2 100644
--- a/camel-core/src/main/java/org/apache/camel/util/GroupIterator.java
+++ b/camel-core/src/main/java/org/apache/camel/util/GroupIterator.java
@@ -40,6 +40,7 @@ public final class GroupIterator implements Iterator<Object>, Closeable {
     private final Exchange exchange;
     private final Iterator<?> it;
     private final int group;
+    private final boolean skipFirst;
     private boolean closed;
 
     /**
@@ -51,6 +52,18 @@ public final class GroupIterator implements Iterator<Object>, Closeable {
      * @throws IllegalArgumentException is thrown if group is not a positive number
      */
     public GroupIterator(Exchange exchange, Iterator<?> it, int group) {
+        this(exchange, it, group, false);
+    }
+
+    /**
+     * Creates a new group iterator
+     *
+     * @param exchange  the exchange used to create this group iterator
+     * @param it            the iterator to group
+     * @param group         number of parts to group together
+     * @throws IllegalArgumentException is thrown if group is not a positive number
+     */
+    public GroupIterator(Exchange exchange, Iterator<?> it, int group, boolean skipFirst) {
         this.exchange = exchange;
         this.camelContext = exchange.getContext();
         this.it = it;
@@ -58,6 +71,7 @@ public final class GroupIterator implements Iterator<Object>, Closeable {
         if (group <= 0) {
             throw new IllegalArgumentException("Group must be a positive number, was: " + group);
         }
+        this.skipFirst = skipFirst;
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/camel/blob/ff9bfd5e/camel-core/src/main/java/org/apache/camel/util/GroupTokenIterator.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/util/GroupTokenIterator.java b/camel-core/src/main/java/org/apache/camel/util/GroupTokenIterator.java
index 4eb50e1..0bfd268 100644
--- a/camel-core/src/main/java/org/apache/camel/util/GroupTokenIterator.java
+++ b/camel-core/src/main/java/org/apache/camel/util/GroupTokenIterator.java
@@ -22,6 +22,7 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.util.Iterator;
 import java.util.Scanner;
+import java.util.concurrent.atomic.AtomicBoolean;
 
 import org.apache.camel.CamelContext;
 import org.apache.camel.Exchange;
@@ -43,6 +44,8 @@ public final class GroupTokenIterator implements Iterator<Object>, Closeable {
     private final Iterator<?> it;
     private final String token;
     private final int group;
+    private final boolean skipFirst;
+    private final AtomicBoolean hasSkipFirst;
     private boolean closed;
     private final ByteArrayOutputStream bos = new ByteArrayOutputStream();
     
@@ -66,6 +69,8 @@ public final class GroupTokenIterator implements Iterator<Object>, Closeable {
         if (group <= 0) {
             throw new IllegalArgumentException("Group must be a positive number, was: " + group);
         }
+        this.skipFirst = false;
+        this.hasSkipFirst = null;
     }
 
     /**
@@ -77,7 +82,7 @@ public final class GroupTokenIterator implements Iterator<Object>, Closeable {
      * @param group         number of parts to group together
      * @throws IllegalArgumentException is thrown if group is not a positive number
      */
-    public GroupTokenIterator(Exchange exchange, Iterator<?> it, String token, int group) {
+    public GroupTokenIterator(Exchange exchange, Iterator<?> it, String token, int group, boolean skipFirst) {
         this.exchange = exchange;
         this.camelContext = exchange.getContext();
         this.it = it;
@@ -86,6 +91,12 @@ public final class GroupTokenIterator implements Iterator<Object>, Closeable {
         if (group <= 0) {
             throw new IllegalArgumentException("Group must be a positive number, was: " + group);
         }
+        this.skipFirst = skipFirst;
+        if (skipFirst) {
+            this.hasSkipFirst = new AtomicBoolean();
+        } else {
+            this.hasSkipFirst = null;
+        }
     }
 
     @Override
@@ -143,6 +154,10 @@ public final class GroupTokenIterator implements Iterator<Object>, Closeable {
         while (count < group && it.hasNext()) {
             data = it.next();
 
+            if (skipFirst && hasSkipFirst.compareAndSet(false, true)) {
+                data = it.next();
+            }
+
             // include token in between
             if (data != null && count > 0 && token != null) {
                 bos.write(token.getBytes());

http://git-wip-us.apache.org/repos/asf/camel/blob/ff9bfd5e/camel-core/src/test/java/org/apache/camel/processor/SplitGroupSkipFirstTest.java
----------------------------------------------------------------------
diff --git a/camel-core/src/test/java/org/apache/camel/processor/SplitGroupSkipFirstTest.java b/camel-core/src/test/java/org/apache/camel/processor/SplitGroupSkipFirstTest.java
new file mode 100644
index 0000000..d85cac2
--- /dev/null
+++ b/camel-core/src/test/java/org/apache/camel/processor/SplitGroupSkipFirstTest.java
@@ -0,0 +1,50 @@
+/**
+ * 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.camel.processor;
+
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.builder.RouteBuilder;
+
+/**
+ *
+ */
+public class SplitGroupSkipFirstTest extends ContextTestSupport {
+
+    public void testSplitSkipFirst() throws Exception {
+        getMockEndpoint("mock:group").expectedBodiesReceived("ABC\nDEF\nGHI", "JKL\nMN");
+
+        template.sendBody("direct:start", "##comment\nABC\nDEF\nGHI\nJKL\nMN");
+
+        assertMockEndpointsSatisfied();
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                // START SNIPPET: e1
+                from("direct:start")
+                    // split by new line and group by 3, and skip the very first element
+                    .split().tokenize("\n", 3, true).streaming()
+                        .to("mock:group");
+                // END SNIPPET: e1
+            }
+        };
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/ff9bfd5e/camel-core/src/test/java/org/apache/camel/util/GroupTokenIteratorTest.java
----------------------------------------------------------------------
diff --git a/camel-core/src/test/java/org/apache/camel/util/GroupTokenIteratorTest.java b/camel-core/src/test/java/org/apache/camel/util/GroupTokenIteratorTest.java
index ddedb2c..84eb610 100644
--- a/camel-core/src/test/java/org/apache/camel/util/GroupTokenIteratorTest.java
+++ b/camel-core/src/test/java/org/apache/camel/util/GroupTokenIteratorTest.java
@@ -55,7 +55,23 @@ public class GroupTokenIteratorTest extends TestSupport {
         Scanner scanner = new Scanner(s);
         scanner.useDelimiter("\n");
 
-        GroupTokenIterator gi = new GroupTokenIterator(exchange, scanner, "\n", 3);
+        GroupTokenIterator gi = new GroupTokenIterator(exchange, scanner, "\n", 3, false);
+
+        assertTrue(gi.hasNext());
+        assertEquals("ABC\nDEF\nGHI", gi.next());
+        assertEquals("JKL\nMNO\nPQR", gi.next());
+        assertEquals("STU\nVW", gi.next());
+        assertFalse(gi.hasNext());
+
+        IOHelper.close(gi);
+    }
+
+    public void testGroupIteratorSkipFirst() throws Exception {
+        String s = "##comment\nABC\nDEF\nGHI\nJKL\nMNO\nPQR\nSTU\nVW";
+        Scanner scanner = new Scanner(s);
+        scanner.useDelimiter("\n");
+
+        GroupTokenIterator gi = new GroupTokenIterator(exchange, scanner, "\n", 3, true);
 
         assertTrue(gi.hasNext());
         assertEquals("ABC\nDEF\nGHI", gi.next());
@@ -80,7 +96,7 @@ public class GroupTokenIteratorTest extends TestSupport {
         scanner.useDelimiter("\n");
 
         exchange.setProperty(Exchange.CHARSET_NAME, StandardCharsets.UTF_8.displayName());
-        GroupTokenIterator gi = new GroupTokenIterator(exchange, scanner, "\n", 1);
+        GroupTokenIterator gi = new GroupTokenIterator(exchange, scanner, "\n", 1, false);
 
         assertTrue(gi.hasNext());
         assertEquals("\u00A31", gi.next());

http://git-wip-us.apache.org/repos/asf/camel/blob/ff9bfd5e/components/camel-spring/src/test/java/org/apache/camel/spring/processor/SpringSplitGroupSkipFirstTest.java
----------------------------------------------------------------------
diff --git a/components/camel-spring/src/test/java/org/apache/camel/spring/processor/SpringSplitGroupSkipFirstTest.java b/components/camel-spring/src/test/java/org/apache/camel/spring/processor/SpringSplitGroupSkipFirstTest.java
new file mode 100644
index 0000000..4181370
--- /dev/null
+++ b/components/camel-spring/src/test/java/org/apache/camel/spring/processor/SpringSplitGroupSkipFirstTest.java
@@ -0,0 +1,32 @@
+/**
+ * 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.camel.spring.processor;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.processor.SplitGroupSkipFirstTest;
+
+import static org.apache.camel.spring.processor.SpringTestHelper.createSpringCamelContext;
+
+/**
+ * @version 
+ */
+public class SpringSplitGroupSkipFirstTest extends SplitGroupSkipFirstTest {
+
+    protected CamelContext createCamelContext() throws Exception {
+        return createSpringCamelContext(this, "org/apache/camel/spring/processor/SplitGroupSkipFirstTest.xml");
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/camel/blob/ff9bfd5e/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/SplitGroupSkipFirstTest.xml
----------------------------------------------------------------------
diff --git a/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/SplitGroupSkipFirstTest.xml b/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/SplitGroupSkipFirstTest.xml
new file mode 100644
index 0000000..738992d
--- /dev/null
+++ b/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/SplitGroupSkipFirstTest.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    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.
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="
+       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+       http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd
+    ">
+
+  <!-- START SNIPPET: e1 -->
+  <camelContext xmlns="http://camel.apache.org/schema/spring">
+    <route>
+      <from uri="direct:start"/>
+      <split streaming="true">
+        <!-- split by new line and group by 3, and skip the very first element -->
+        <tokenize token="\n" group="3" skipFirst="true"/>
+        <to uri="mock:group"/>
+      </split>
+    </route>
+  </camelContext>
+  <!-- END SNIPPET: e1 -->
+
+</beans>


[2/2] camel git commit: Fixed CS

Posted by da...@apache.org.
Fixed CS


Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/4545915b
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/4545915b
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/4545915b

Branch: refs/heads/master
Commit: 4545915b3d6dbcb239a1f461b4a66f1b489ca5f7
Parents: ff9bfd5
Author: Claus Ibsen <da...@apache.org>
Authored: Mon Jan 4 10:20:49 2016 +0100
Committer: Claus Ibsen <da...@apache.org>
Committed: Mon Jan 4 10:20:49 2016 +0100

----------------------------------------------------------------------
 .../camel/impl/ScheduledPollEndpoint.java       | 47 +++++++++++++-------
 1 file changed, 30 insertions(+), 17 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/4545915b/camel-core/src/main/java/org/apache/camel/impl/ScheduledPollEndpoint.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/impl/ScheduledPollEndpoint.java b/camel-core/src/main/java/org/apache/camel/impl/ScheduledPollEndpoint.java
index 48420a4..13335c9 100644
--- a/camel-core/src/main/java/org/apache/camel/impl/ScheduledPollEndpoint.java
+++ b/camel-core/src/main/java/org/apache/camel/impl/ScheduledPollEndpoint.java
@@ -36,7 +36,7 @@ import org.apache.camel.util.IntrospectionSupport;
 /**
  * A base class for {@link org.apache.camel.Endpoint} which creates a {@link ScheduledPollConsumer}
  *
- * @version 
+ * @version
  */
 public abstract class ScheduledPollEndpoint extends DefaultEndpoint {
 
@@ -44,41 +44,54 @@ public abstract class ScheduledPollEndpoint extends DefaultEndpoint {
     private static final String QUARTZ_2_SCHEDULER = "org.apache.camel.pollconsumer.quartz2.QuartzScheduledPollConsumerScheduler";
 
     // if adding more options then align with org.apache.camel.impl.ScheduledPollConsumer
-    @UriParam(optionalPrefix = "consumer.", defaultValue = "true", label = "consumer,scheduler", description = "Whether the scheduler should be auto started.")
+    @UriParam(optionalPrefix = "consumer.", defaultValue = "true", label = "consumer,scheduler",
+            description = "Whether the scheduler should be auto started.")
     private boolean startScheduler = true;
-    @UriParam(optionalPrefix = "consumer.", defaultValue = "1000", label = "consumer,scheduler", description = "Milliseconds before the first poll starts.")
+    @UriParam(optionalPrefix = "consumer.", defaultValue = "1000", label = "consumer,scheduler",
+            description = "Milliseconds before the first poll starts.")
     private long initialDelay = 1000;
-    @UriParam(optionalPrefix = "consumer.", defaultValue = "500", label = "consumer,scheduler", description = "Milliseconds before the next poll.")
+    @UriParam(optionalPrefix = "consumer.", defaultValue = "500", label = "consumer,scheduler",
+            description = "Milliseconds before the next poll.")
     private long delay = 500;
-    @UriParam(optionalPrefix = "consumer.", defaultValue = "MILLISECONDS", label = "consumer,scheduler", description = "Time unit for initialDelay and delay options.")
+    @UriParam(optionalPrefix = "consumer.", defaultValue = "MILLISECONDS", label = "consumer,scheduler",
+            description = "Time unit for initialDelay and delay options.")
     private TimeUnit timeUnit = TimeUnit.MILLISECONDS;
-    @UriParam(optionalPrefix = "consumer.", defaultValue = "true", label = "consumer,scheduler", description = "Controls if fixed delay or fixed rate is used. See ScheduledExecutorService in JDK for details.")
+    @UriParam(optionalPrefix = "consumer.", defaultValue = "true", label = "consumer,scheduler",
+            description = "Controls if fixed delay or fixed rate is used. See ScheduledExecutorService in JDK for details.")
     private boolean useFixedDelay = true;
-    @UriParam(optionalPrefix = "consumer.", label = "consumer,advanced", description = "A pluggable org.apache.camel.PollingConsumerPollingStrategy allowing you to provide your custom implementation"
-            + " to control error handling usually occurred during the poll operation before an Exchange have been created and being routed in Camel.")
+    @UriParam(optionalPrefix = "consumer.", label = "consumer,advanced",
+            description = "A pluggable org.apache.camel.PollingConsumerPollingStrategy allowing you to provide your custom implementation"
+                    + " to control error handling usually occurred during the poll operation before an Exchange have been created and being routed in Camel.")
     private PollingConsumerPollStrategy pollStrategy = new DefaultPollingConsumerPollStrategy();
     @UriParam(optionalPrefix = "consumer.", defaultValue = "TRACE", label = "consumer,scheduler",
             description = "The consumer logs a start/complete log line when it polls. This option allows you to configure the logging level for that.")
     private LoggingLevel runLoggingLevel = LoggingLevel.TRACE;
-    @UriParam(optionalPrefix = "consumer.", label = "consumer", description = "If the polling consumer did not poll any files, you can enable this option to send an empty message (no body) instead.")
+    @UriParam(optionalPrefix = "consumer.", label = "consumer",
+            description = "If the polling consumer did not poll any files, you can enable this option to send an empty message (no body) instead.")
     private boolean sendEmptyMessageWhenIdle;
-    @UriParam(optionalPrefix = "consumer.", label = "consumer,scheduler", description = "If greedy is enabled, then the ScheduledPollConsumer will run immediately again, if the previous run polled 1 or more messages.")
+    @UriParam(optionalPrefix = "consumer.", label = "consumer,scheduler",
+            description = "If greedy is enabled, then the ScheduledPollConsumer will run immediately again, if the previous run polled 1 or more messages.")
     private boolean greedy;
-    @UriParam(optionalPrefix = "consumer.", enums = "none,spring,quartz2", defaultValue = "none", label = "consumer,scheduler", description = "To use a cron scheduler from either camel-spring or camel-quartz2 component")
+    @UriParam(optionalPrefix = "consumer.", enums = "none,spring,quartz2",
+            defaultValue = "none", label = "consumer,scheduler", description = "To use a cron scheduler from either camel-spring or camel-quartz2 component")
     private ScheduledPollConsumerScheduler scheduler;
     private String schedulerName = "none"; // used when configuring scheduler using a string value
-    @UriParam(optionalPrefix = "consumer.", label = "consumer,scheduler", description = "To configure additional properties when using a custom scheduler or any of the Quartz2, Spring based scheduler.")
+    @UriParam(optionalPrefix = "consumer.", label = "consumer,scheduler",
+            description = "To configure additional properties when using a custom scheduler or any of the Quartz2, Spring based scheduler.")
     private Map<String, Object> schedulerProperties;
     @UriParam(optionalPrefix = "consumer.", label = "consumer,scheduler",
             description = "Allows for configuring a custom/shared thread pool to use for the consumer. By default each consumer has its own single threaded thread pool.")
     private ScheduledExecutorService scheduledExecutorService;
-    @UriParam(optionalPrefix = "consumer.", label = "consumer,scheduler", description = "To let the scheduled polling consumer backoff if there has been a number of subsequent idles/errors in a row."
-            + " The multiplier is then the number of polls that will be skipped before the next actual attempt is happening again."
-            + " When this option is in use then backoffIdleThreshold and/or backoffErrorThreshold must also be configured.")
+    @UriParam(optionalPrefix = "consumer.", label = "consumer,scheduler",
+            description = "To let the scheduled polling consumer backoff if there has been a number of subsequent idles/errors in a row."
+                    + " The multiplier is then the number of polls that will be skipped before the next actual attempt is happening again."
+                    + " When this option is in use then backoffIdleThreshold and/or backoffErrorThreshold must also be configured.")
     private int backoffMultiplier;
-    @UriParam(optionalPrefix = "consumer.", label = "consumer,scheduler", description = "The number of subsequent idle polls that should happen before the backoffMultipler should kick-in.")
+    @UriParam(optionalPrefix = "consumer.", label = "consumer,scheduler",
+            description = "The number of subsequent idle polls that should happen before the backoffMultipler should kick-in.")
     private int backoffIdleThreshold;
-    @UriParam(optionalPrefix = "consumer.", label = "consumer,scheduler", description = "The number of subsequent error polls (failed due some error) that should happen before the backoffMultipler should kick-in.")
+    @UriParam(optionalPrefix = "consumer.", label = "consumer,scheduler",
+            description = "The number of subsequent error polls (failed due some error) that should happen before the backoffMultipler should kick-in.")
     private int backoffErrorThreshold;
 
     protected ScheduledPollEndpoint(String endpointUri, Component component) {