Author: davsclaus
Date: Sun Jan 15 16:47:34 2012
New Revision: 1231704

URL: http://svn.apache.org/viewvc?rev=1231704&view=rev
Log:
CAMEL-4894: Fixed ognl parser to take into account parameter bindings encloded 
in parenthesis pairs, in the method names.

Added:
    
camel/trunk/camel-core/src/test/java/org/apache/camel/util/OgnlHelperTest.java
Modified:
    camel/trunk/camel-core/src/main/java/org/apache/camel/util/OgnlHelper.java
    
camel/trunk/camel-core/src/test/java/org/apache/camel/processor/RecipientListBeanTest.java

Modified: 
camel/trunk/camel-core/src/main/java/org/apache/camel/util/OgnlHelper.java
URL: 
http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/util/OgnlHelper.java?rev=1231704&r1=1231703&r2=1231704&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/util/OgnlHelper.java 
(original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/util/OgnlHelper.java 
Sun Jan 15 16:47:34 2012
@@ -164,14 +164,23 @@ public final class OgnlHelper {
      * Regular expression with repeating groups is a pain to get right
      * and then nobody understands the reg exp afterwards.
      * So we use a bit ugly/low-level Java code to split the OGNL into methods.
+     *
+     * @param ognl the ognl expression
+     * @return a list of methods, will return an empty list, if ognl 
expression has no methods
      */
     public static List<String> splitOgnl(String ognl) {
         List<String> methods = new ArrayList<String>();
 
+        // return an empty list if ognl is empty
+        if (ObjectHelper.isEmpty(ognl)) {
+            return methods;
+        }
+
         StringBuilder sb = new StringBuilder();
 
         int j = 0; // j is used as counter per method
-        boolean squareBracket = false; // special to keep track if we are 
inside a square bracket block - (eg [foo])
+        boolean squareBracket = false; // special to keep track if we are 
inside a square bracket block, eg: [foo]
+        boolean parenthesisBracket = false; // special to keep track if we are 
inside a parenthesis block, eg: bar(${body}, ${header.foo})
         for (int i = 0; i < ognl.length(); i++) {
             char ch = ognl.charAt(i);
             // special for starting a new method
@@ -179,12 +188,16 @@ public final class OgnlHelper {
                     || (ch != '.' && ch != '?' && ch != ']')) {
                 sb.append(ch);
                 // special if we are doing square bracket
-                if (ch == '[') {
+                if (ch == '[' && !parenthesisBracket) {
                     squareBracket = true;
+                } else if (ch == '(') {
+                    parenthesisBracket = true;
+                } else if (ch == ')') {
+                    parenthesisBracket = false;
                 }
                 j++; // advance
             } else {
-                if (ch == '.' && !squareBracket) {
+                if (ch == '.' && !squareBracket && !parenthesisBracket) {
                     // only treat dot as a method separator if not inside a 
square bracket block
                     // as dots can be used in key names when accessing maps
 
@@ -205,7 +218,7 @@ public final class OgnlHelper {
 
                     // reset j to begin a new method
                     j = 0;
-                } else if (ch == ']') {
+                } else if (ch == ']' && !parenthesisBracket) {
                     // append ending ] to method name
                     sb.append(ch);
                     String s = sb.toString();
@@ -223,11 +236,16 @@ public final class OgnlHelper {
                     squareBracket = false;
                 }
 
-                // and dont lose the char if its not an ] end marker (as we 
already added that)
-                if (ch != ']') {
+                // and don't lose the char if its not an ] end marker (as we 
already added that)
+                if (ch != ']' || parenthesisBracket) {
                     sb.append(ch);
                 }
 
+                // check for end of parenthesis
+                if (ch == ')') {
+                    parenthesisBracket = false;
+                }
+
                 // only advance if already begun on the new method
                 if (j > 0) {
                     j++;

Modified: 
camel/trunk/camel-core/src/test/java/org/apache/camel/processor/RecipientListBeanTest.java
URL: 
http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/processor/RecipientListBeanTest.java?rev=1231704&r1=1231703&r2=1231704&view=diff
==============================================================================
--- 
camel/trunk/camel-core/src/test/java/org/apache/camel/processor/RecipientListBeanTest.java
 (original)
+++ 
camel/trunk/camel-core/src/test/java/org/apache/camel/processor/RecipientListBeanTest.java
 Sun Jan 15 16:47:34 2012
@@ -46,8 +46,7 @@ public class RecipientListBeanTest exten
         assertMockEndpointsSatisfied();
     }
 
-    // @Ignore("CAMEL-4894") @Test
-    public void fixmeTestRecipientListWithParams() throws Exception {
+    public void testRecipientListWithParams() throws Exception {
         MockEndpoint mock = getMockEndpoint("mock:result");
         mock.expectedBodiesReceived("Hello b");
 
@@ -65,7 +64,7 @@ public class RecipientListBeanTest exten
         return new RouteBuilder() {
             public void configure() {
                 from("direct:start").recipientList(bean("myBean", 
"foo")).to("mock:result");
-                from("direct:params").recipientList(bean("myBean", 
"bar(header.one, header.two)"), ",").to("mock:result");
+                from("direct:params").recipientList(bean("myBean", 
"bar(${header.one}, ${header.two})"), ",").to("mock:result");
 
                 from("direct:a").transform(constant("Hello a"));
                 from("direct:b").transform(constant("Hello b"));
@@ -80,15 +79,10 @@ public class RecipientListBeanTest exten
             return body.split(",");
         }
 
-        public String foo(int one, String two) {
-            String [] recipients = two.split(",");
-            int count = Math.min(one, recipients.length);
-            StringBuilder answer = new StringBuilder();
-            for (int i = 0; i < count; i++) {
-                answer.append(i > 0 ? "," : "");
-                answer.append(recipients[i]);
-            }
-            return answer.toString();
+        public String bar(int one, String two) {
+            assertEquals(21, one);
+            assertEquals("direct:a,direct:b,direct:c", two);
+            return "direct:c,direct:b";
         }
     }
 

Added: 
camel/trunk/camel-core/src/test/java/org/apache/camel/util/OgnlHelperTest.java
URL: 
http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/util/OgnlHelperTest.java?rev=1231704&view=auto
==============================================================================
--- 
camel/trunk/camel-core/src/test/java/org/apache/camel/util/OgnlHelperTest.java 
(added)
+++ 
camel/trunk/camel-core/src/test/java/org/apache/camel/util/OgnlHelperTest.java 
Sun Jan 15 16:47:34 2012
@@ -0,0 +1,133 @@
+/**
+ * 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.util;
+
+import java.util.List;
+
+import junit.framework.TestCase;
+
+/**
+ *
+ */
+public class OgnlHelperTest extends TestCase {
+    
+    public void testSplitOgnlSimple() throws Exception {
+        List<String> methods = OgnlHelper.splitOgnl(null);
+        assertEquals(0, methods.size());
+        methods = OgnlHelper.splitOgnl("");
+        assertEquals(0, methods.size());
+        methods = OgnlHelper.splitOgnl(" ");
+        assertEquals(0, methods.size());
+
+        methods = OgnlHelper.splitOgnl("foo");
+        assertEquals(1, methods.size());
+        assertEquals("foo", methods.get(0));
+
+        methods = OgnlHelper.splitOgnl("foo.bar");
+        assertEquals(2, methods.size());
+        assertEquals("foo", methods.get(0));
+        assertEquals(".bar", methods.get(1));
+
+        methods = OgnlHelper.splitOgnl("foo.bar.baz");
+        assertEquals(3, methods.size());
+        assertEquals("foo", methods.get(0));
+        assertEquals(".bar", methods.get(1));
+        assertEquals(".baz", methods.get(2));
+    }
+
+    public void testSplitOgnlSquare() throws Exception {
+        List<String> methods = OgnlHelper.splitOgnl("foo");
+        assertEquals(1, methods.size());
+        assertEquals("foo", methods.get(0));
+
+        methods = OgnlHelper.splitOgnl("foo[0].bar");
+        assertEquals(2, methods.size());
+        assertEquals("foo[0]", methods.get(0));
+        assertEquals(".bar", methods.get(1));
+
+        methods = OgnlHelper.splitOgnl("foo[0]?.bar");
+        assertEquals(2, methods.size());
+        assertEquals("foo[0]", methods.get(0));
+        assertEquals("?.bar", methods.get(1));
+
+        methods = OgnlHelper.splitOgnl("foo['key'].bar");
+        assertEquals(2, methods.size());
+        assertEquals("foo['key']", methods.get(0));
+        assertEquals(".bar", methods.get(1));
+
+        methods = OgnlHelper.splitOgnl("foo['key']?.bar");
+        assertEquals(2, methods.size());
+        assertEquals("foo['key']", methods.get(0));
+        assertEquals("?.bar", methods.get(1));
+
+        methods = OgnlHelper.splitOgnl("foo['key'].bar[0]");
+        assertEquals(2, methods.size());
+        assertEquals("foo['key']", methods.get(0));
+        assertEquals(".bar[0]", methods.get(1));
+
+        methods = OgnlHelper.splitOgnl("foo['key']?.bar[0]");
+        assertEquals(2, methods.size());
+        assertEquals("foo['key']", methods.get(0));
+        assertEquals("?.bar[0]", methods.get(1));
+    }
+
+    public void testSplitOgnlParenthesis() throws Exception {
+        List<String> methods = OgnlHelper.splitOgnl("foo()");
+        assertEquals(1, methods.size());
+        assertEquals("foo()", methods.get(0));
+
+        methods = OgnlHelper.splitOgnl("foo(${body})");
+        assertEquals(1, methods.size());
+        assertEquals("foo(${body})", methods.get(0));
+
+        methods = OgnlHelper.splitOgnl("foo(${body}, ${header.foo})");
+        assertEquals(1, methods.size());
+        assertEquals("foo(${body}, ${header.foo})", methods.get(0));
+
+        methods = OgnlHelper.splitOgnl("foo(${body}, ${header.foo}).bar");
+        assertEquals(2, methods.size());
+        assertEquals("foo(${body}, ${header.foo})", methods.get(0));
+        assertEquals(".bar", methods.get(1));
+
+        methods = OgnlHelper.splitOgnl("foo(${body}, ${header.foo}).bar(true, 
${header.bar})");
+        assertEquals(2, methods.size());
+        assertEquals("foo(${body}, ${header.foo})", methods.get(0));
+        assertEquals(".bar(true, ${header.bar})", methods.get(1));
+
+        methods = OgnlHelper.splitOgnl("foo(${body}, ${header.foo}).bar(true, 
${header.bar}).baz['key']");
+        assertEquals(3, methods.size());
+        assertEquals("foo(${body}, ${header.foo})", methods.get(0));
+        assertEquals(".bar(true, ${header.bar})", methods.get(1));
+        assertEquals(".baz['key']", methods.get(2));
+    }
+
+    public void testSplitOgnlParenthesisAndBracket() throws Exception {
+        List<String> methods = OgnlHelper.splitOgnl("foo(${body['key']})");
+        assertEquals(1, methods.size());
+        assertEquals("foo(${body['key']})", methods.get(0));
+
+        methods = OgnlHelper.splitOgnl("foo(${body}, ${header.foo?['key']})");
+        assertEquals(1, methods.size());
+        assertEquals("foo(${body}, ${header.foo?['key']})", methods.get(0));
+
+        methods = OgnlHelper.splitOgnl("foo(${body}, ${header.foo}).bar(true, 
${header.bar[0]?.code})");
+        assertEquals(2, methods.size());
+        assertEquals("foo(${body}, ${header.foo})", methods.get(0));
+        assertEquals(".bar(true, ${header.bar[0]?.code})", methods.get(1));
+    }
+
+}


Reply via email to