Author: davsclaus Date: Tue Dec 13 14:27:07 2011 New Revision: 1213709 URL: http://svn.apache.org/viewvc?rev=1213709&view=rev Log: CAMEL-4773: Dynamic Router, Routing Slip and other EIPs which accept an expression for endpoints, should cater for bean endpoints separated by comma. Where a bean endpoint uses method name parameter using parantheses with comma included. ObjectHelper.createIterator needs to honor this, when its iterating a String value.
Added: camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanParameterMethodCallThreeBodyOgnlTest.java - copied, changed from r1213597, camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanParameterThreeBodyOgnlTest.java Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/util/ObjectHelper.java camel/trunk/camel-core/src/test/java/org/apache/camel/util/ObjectHelperTest.java Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/util/ObjectHelper.java URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/util/ObjectHelper.java?rev=1213709&r1=1213708&r2=1213709&view=diff ============================================================================== --- camel/trunk/camel-core/src/main/java/org/apache/camel/util/ObjectHelper.java (original) +++ camel/trunk/camel-core/src/main/java/org/apache/camel/util/ObjectHelper.java Tue Dec 13 14:27:07 2011 @@ -60,6 +60,7 @@ import org.slf4j.LoggerFactory; */ public final class ObjectHelper { private static final transient Logger LOG = LoggerFactory.getLogger(ObjectHelper.class); + private static final String DEFAULT_DELIMITER = ","; /** * Utility classes should not have a public constructor. @@ -447,8 +448,9 @@ public final class ObjectHelper { /** * Creates an iterator over the value if the value is a collection, an - * Object[] or a primitive type array; otherwise to simplify the caller's - * code, we just create a singleton collection iterator over a single value + * Object[], a String with values separated by comma, + * or a primitive type array; otherwise to simplify the caller's code, + * we just create a singleton collection iterator over a single value * <p/> * Will default use comma for String separating String values. * @@ -456,12 +458,13 @@ public final class ObjectHelper { * @return the iterator */ public static Iterator<Object> createIterator(Object value) { - return createIterator(value, ","); + return createIterator(value, DEFAULT_DELIMITER); } /** * Creates an iterator over the value if the value is a collection, an - * Object[] or a primitive type array; otherwise to simplify the caller's + * Object[], a String with values separated by the given delimiter, + * or a primitive type array; otherwise to simplify the caller's * code, we just create a singleton collection iterator over a single value * * @param value the value @@ -512,6 +515,21 @@ public final class ObjectHelper { if (delimiter != null && s.contains(delimiter)) { // use a scanner if it contains the delimiter Scanner scanner = new Scanner((String)value); + + if (DEFAULT_DELIMITER.equals(delimiter)) { + // we use the default delimiter which is a comma, then cater for bean expressions with OGNL + // which may have balanced parentheses pairs as well. + // if the value contains parentheses we need to balance those, to avoid iterating + // in the middle of parentheses pair, so use this regular expression (a bit hard to read) + // the regexp will split by comma, but honor parentheses pair that may include commas + // as well, eg if value = "bean=foo?method=killer(a,b),bean=bar?method=great(a,b)" + // then the regexp will split that into two: + // -> bean=foo?method=killer(a,b) + // -> bean=bar?method=great(a,b) + // http://stackoverflow.com/questions/1516090/splitting-a-title-into-separate-parts + delimiter = ",(?!(?:[^\\(,]|[^\\)],[^\\)])+\\))"; + } + scanner.useDelimiter(delimiter); return CastUtils.cast(scanner); } else { Copied: camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanParameterMethodCallThreeBodyOgnlTest.java (from r1213597, camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanParameterThreeBodyOgnlTest.java) URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanParameterMethodCallThreeBodyOgnlTest.java?p2=camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanParameterMethodCallThreeBodyOgnlTest.java&p1=camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanParameterThreeBodyOgnlTest.java&r1=1213597&r2=1213709&rev=1213709&view=diff ============================================================================== --- camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanParameterThreeBodyOgnlTest.java (original) +++ camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanParameterMethodCallThreeBodyOgnlTest.java Tue Dec 13 14:27:07 2011 @@ -26,7 +26,7 @@ import org.apache.camel.impl.JndiRegistr /** * */ -public class BeanParameterThreeBodyOgnlTest extends ContextTestSupport { +public class BeanParameterMethodCallThreeBodyOgnlTest extends ContextTestSupport { public void testBeanParameterValue() throws Exception { getMockEndpoint("mock:result").expectedBodiesReceived("3"); @@ -43,6 +43,7 @@ public class BeanParameterThreeBodyOgnlT @Override protected JndiRegistry createRegistry() throws Exception { JndiRegistry jndi = super.createRegistry(); + jndi.bind("router", new MyRouter()); jndi.bind("foo", new MyBean()); return jndi; } @@ -53,12 +54,23 @@ public class BeanParameterThreeBodyOgnlT @Override public void configure() throws Exception { from("direct:start") - .to("bean:foo?method=bar(${body[0]},${body[1]},${body[2]})") + .dynamicRouter().method("router") .to("mock:result"); } }; } + public static class MyRouter { + + public String route(Object body) { + if (body instanceof List) { + return "bean:foo?method=bar('A','B','C')"; + } else{ + return null; + } + } + } + public static class MyBean { public String bar(String order1, String order2, String order3) { @@ -71,7 +83,7 @@ public class BeanParameterThreeBodyOgnlT public String bar(String order1, String order2) { assertEquals("A", order1); - assertEquals("B", order2); + assertEquals("Hello,World", order2); return "2"; } Modified: camel/trunk/camel-core/src/test/java/org/apache/camel/util/ObjectHelperTest.java URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/util/ObjectHelperTest.java?rev=1213709&r1=1213708&r2=1213709&view=diff ============================================================================== --- camel/trunk/camel-core/src/test/java/org/apache/camel/util/ObjectHelperTest.java (original) +++ camel/trunk/camel-core/src/test/java/org/apache/camel/util/ObjectHelperTest.java Tue Dec 13 14:27:07 2011 @@ -155,6 +155,19 @@ public class ObjectHelperTest extends Te assertEquals("c", it.next()); } + public void testCreateIteratorWithStringAndCommaInParanthesesSeparator() { + String s = "bean:foo?method=bar('A','B','C')"; + Iterator<String> it = CastUtils.cast(ObjectHelper.createIterator(s, ",")); + assertEquals("bean:foo?method=bar('A','B','C')", it.next()); + } + + public void testCreateIteratorWithStringAndCommaInParanthesesSeparatorTwo() { + String s = "bean:foo?method=bar('A','B','C'),bean:bar?method=cool('A','Hello,World')"; + Iterator<String> it = CastUtils.cast(ObjectHelper.createIterator(s, ",")); + assertEquals("bean:foo?method=bar('A','B','C')", it.next()); + assertEquals("bean:bar?method=cool('A','Hello,World')", it.next()); + } + public void testBefore() { assertEquals("Hello ", ObjectHelper.before("Hello World", "World")); assertEquals("Hello ", ObjectHelper.before("Hello World Again", "World"));