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));
+ }
+
+}