Author: davsclaus Date: Mon Jul 25 17:02:41 2011 New Revision: 1150780 URL: http://svn.apache.org/viewvc?rev=1150780&view=rev Log: CAMEL-3961: Bean component now supports parameter values specified directly in method name option. You can now bind body, headers, fixed values etc. without any annotations or other means.
Added: camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanOverloadedMethodParameterValueTest.java - copied, changed from r1150672, camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanOverloadedMethodTest.java camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanParameterValueOgnlTest.java camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanParameterValueOverloadedTest.java camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanParameterValueTest.java Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/BeanInfo.java camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/MethodInfo.java camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/MethodNotFoundException.java camel/trunk/camel-core/src/main/java/org/apache/camel/language/bean/BeanExpression.java camel/trunk/camel-core/src/main/java/org/apache/camel/util/ObjectHelper.java camel/trunk/camel-core/src/main/java/org/apache/camel/util/StringHelper.java camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanOverloadedMethodFQNTest.java camel/trunk/camel-core/src/test/java/org/apache/camel/util/StringHelperTest.java Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/BeanInfo.java URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/BeanInfo.java?rev=1150780&r1=1150779&r2=1150780&view=diff ============================================================================== --- camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/BeanInfo.java (original) +++ camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/BeanInfo.java Mon Jul 25 17:02:41 2011 @@ -684,7 +684,7 @@ public class BeanInfo { while (it.hasNext()) { MethodInfo info = it.next(); if (!matchMethod(info.getMethod(), name)) { - // name does not match so remove it + // method does not match so remove it it.remove(); } } @@ -718,20 +718,39 @@ public class BeanInfo { for (int i = 0; i < method.getParameterTypes().length; i++) { if (it.hasNext()) { String qualifyType = (String) it.next(); + if (ObjectHelper.isEmpty(qualifyType)) { + continue; + } + qualifyType = qualifyType.trim(); + if ("*".equals(qualifyType)) { // * is a wildcard so we accept and match that parameter type continue; } - // match on either simple name or FQN decided by end user as how - // he specified the qualify type - String parameterType = method.getParameterTypes()[i].getSimpleName(); - if (qualifyType.indexOf(".") > -1) { - parameterType = method.getParameterTypes()[i].getName(); + if (qualifyType.startsWith("'") || qualifyType.startsWith("\"")) { + // if the type starts with a quote, then its a parameter value instead + continue; } - if (!parameterType.equals(qualifyType)) { - return false; + + // so it can either be a type or a parameter value + // - type: Boolean, String etc. + // - value: true, 5, 'Hello World' etc + + Class<?> qualifyClass = getCamelContext().getClassResolver().resolveClass(qualifyType); + // class resolver will return null if not a class + if (qualifyClass != null) { + Class<?> parameterClass = method.getParameterTypes()[i]; + if (!parameterClass.isAssignableFrom(qualifyClass)) { + return false; + } } + + // maybe its a FQN for simple name + if (qualifyType.equals(method.getParameterTypes()[i].getSimpleName())) { + continue; + } + } else { // there method has more parameters than was specified in the method name qualifiers return false; Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/MethodInfo.java URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/MethodInfo.java?rev=1150780&r1=1150779&r2=1150780&view=diff ============================================================================== --- camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/MethodInfo.java (original) +++ camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/MethodInfo.java Mon Jul 25 17:02:41 2011 @@ -23,6 +23,7 @@ import java.lang.reflect.InvocationTarge import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; +import java.util.Iterator; import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.atomic.AtomicBoolean; @@ -43,6 +44,7 @@ import org.apache.camel.processor.aggreg import org.apache.camel.util.CamelContextHelper; import org.apache.camel.util.ObjectHelper; import org.apache.camel.util.ServiceHelper; +import org.apache.camel.util.StringHelper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -348,34 +350,135 @@ public class MethodInfo { if (exchange.getIn().getHeader(Exchange.BEAN_MULTI_PARAMETER_ARRAY) != null) { multiParameterArray = exchange.getIn().getHeader(Exchange.BEAN_MULTI_PARAMETER_ARRAY, Boolean.class); } + + // if there was an explicit method name to invoke, then we should support using + // any provided parameter values in the method name + String methodName = exchange.getIn().getHeader(Exchange.BEAN_METHOD_NAME, "", String.class); + // the parameter values is between the parenthesis + String methodParameters = ObjectHelper.between(methodName, "(", ")"); + // use an iterator to walk the parameter values + Iterator it = null; + if (methodParameters != null) { + it = ObjectHelper.createIterator(methodParameters); + } + for (int i = 0; i < size; i++) { + // grab the parameter value for the given index + Object parameterValue = it != null && it.hasNext() ? it.next() : null; + // and the expected parameter type + Class<?> parameterType = parameters.get(i).getType(); + // the value for the parameter to use Object value = null; + if (multiParameterArray) { + // get the value from the array value = ((Object[])body)[i]; } else { + // prefer to use parameter value if given, as they override any bean parameter binding + // we should skip * as its a type placeholder to indicate any type + if (parameterValue != null && !parameterValue.equals("*")) { + // evaluate the parameter value binding + value = evaluateParameterValue(exchange, i, parameterValue, parameterType); + } + + // use bean parameter binding, if still no value Expression expression = expressions[i]; - if (expression != null) { - // use object first to avoid type conversion so we know if there is a value or not - Object result = expression.evaluate(exchange, Object.class); - if (result != null) { + if (value == null && expression != null) { + value = evaluateParameterBinding(exchange, expression, i, parameterType); + } + } + + // remember the value to use + answer[i] = value; + } + + return (T) answer; + } + + /** + * Evaluate using parameter values where the values can be provided in the method name syntax. + * + * @since 2.9 + */ + private Object evaluateParameterValue(Exchange exchange, int index, Object parameterValue, Class<?> parameterType) { + Object answer = null; + + // at first evaluate it as a simple expression as it may contain references to headers, etc + String exp = exchange.getContext().getTypeConverter().convertTo(String.class, parameterValue); + if (exp != null) { + // must trim first as there may be spaces between parameters + exp = exp.trim(); + + // TODO: make rule about how a parameter value should be defined + // and use this rule to pre determine if its class or not + // - boolean as true|false + // - numeric such as 5, 7, 123 + // - string literals which must be quoted, either single or double + + // so it can either be a type or a parameter value + // - type: Boolean, String etc. + // - value: true, 5, 'Hello World' etc + boolean isClass = false; + if (exp.startsWith("'") || exp.startsWith("\"")) { + // if the type starts with a quote, then its a parameter value + exp = StringHelper.removeLeadingAndEndingQuotes(exp); + } else { + // it could be a type, so lets so if we can resolve the class + Class<?> expClass = exchange.getContext().getClassResolver().resolveClass(exp); + if (expClass != null) { + isClass = true; + } else { + // lets try to match by simple name as well + if (exp.equals(parameterType.getSimpleName())) { + isClass = true; + } + } + } + + // if its a parameter value (not a class) then use the simple expression language to evaluate the expression + // and convert the result to the parameter type, so we can pass in the result to the method, when we invoke it + if (!isClass) { + parameterValue = exchange.getContext().resolveLanguage("simple").createExpression(exp).evaluate(exchange, Object.class); + if (parameterValue != null) { + try { // we got a value now try to convert it to the expected type - try { - value = exchange.getContext().getTypeConverter().mandatoryConvertTo(parameters.get(i).getType(), result); - if (LOG.isTraceEnabled()) { - LOG.trace("Parameter #{} evaluated as: {} type: ", new Object[]{i, value, ObjectHelper.type(value)}); - } - } catch (NoTypeConversionAvailableException e) { - throw ObjectHelper.wrapCamelExecutionException(exchange, e); + answer = exchange.getContext().getTypeConverter().mandatoryConvertTo(parameterType, parameterValue); + if (LOG.isTraceEnabled()) { + LOG.trace("Parameter #{} evaluated as: {} type: ", new Object[]{index, answer, ObjectHelper.type(answer)}); } - } else { - LOG.trace("Parameter #{} evaluated as null", i); + } catch (NoTypeConversionAvailableException e) { + throw ObjectHelper.wrapCamelExecutionException(exchange, e); } } } - // now lets try to coerce the value to the required type - answer[i] = value; } - return (T) answer; + + return answer; + } + + /** + * Evaluate using classic parameter binding using the pre compute expression + */ + private Object evaluateParameterBinding(Exchange exchange, Expression expression, int index, Class<?> parameterType) { + Object answer = null; + + // use object first to avoid type conversion so we know if there is a value or not + Object result = expression.evaluate(exchange, Object.class); + if (result != null) { + // we got a value now try to convert it to the expected type + try { + answer = exchange.getContext().getTypeConverter().mandatoryConvertTo(parameterType, result); + if (LOG.isTraceEnabled()) { + LOG.trace("Parameter #{} evaluated as: {} type: ", new Object[]{index, answer, ObjectHelper.type(answer)}); + } + } catch (NoTypeConversionAvailableException e) { + throw ObjectHelper.wrapCamelExecutionException(exchange, e); + } + } else { + LOG.trace("Parameter #{} evaluated as null", index); + } + + return answer; } @Override Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/MethodNotFoundException.java URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/MethodNotFoundException.java?rev=1150780&r1=1150779&r2=1150780&view=diff ============================================================================== --- camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/MethodNotFoundException.java (original) +++ camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/MethodNotFoundException.java Mon Jul 25 17:02:41 2011 @@ -16,10 +16,9 @@ */ package org.apache.camel.component.bean; -import java.util.List; - import org.apache.camel.CamelExchangeException; import org.apache.camel.Exchange; +import org.apache.camel.util.ObjectHelper; /** * @version @@ -32,13 +31,13 @@ public class MethodNotFoundException ext @SuppressWarnings("rawtypes") public MethodNotFoundException(Exchange exchange, Object pojo, String methodName) { - super("Method with name: " + methodName + " not found on bean: " + pojo, exchange); + super("Method with name: " + methodName + " not found on bean: " + pojo + " of type: " + ObjectHelper.className(pojo), exchange); this.methodName = methodName; this.bean = pojo; } public MethodNotFoundException(Object pojo, String methodName, Throwable cause) { - super("Method with name: " + methodName + " not found on bean: " + pojo, null, cause); + super("Method with name: " + methodName + " not found on bean: " + pojo + " of type:" + ObjectHelper.className(pojo), null, cause); this.methodName = methodName; this.bean = pojo; } Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/language/bean/BeanExpression.java URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/language/bean/BeanExpression.java?rev=1150780&r1=1150779&r2=1150780&view=diff ============================================================================== --- camel/trunk/camel-core/src/main/java/org/apache/camel/language/bean/BeanExpression.java (original) +++ camel/trunk/camel-core/src/main/java/org/apache/camel/language/bean/BeanExpression.java Mon Jul 25 17:02:41 2011 @@ -174,6 +174,9 @@ public class BeanExpression implements E Exchange resultExchange = exchange.copy(); // force to use InOut to retrieve the result on the OUT message resultExchange.setPattern(ExchangePattern.InOut); + // do not propagate any method name when using OGNL, as with OGNL we + // compute and provide the method name to explicit to invoke + resultExchange.getIn().removeHeader(Exchange.BEAN_METHOD_NAME); // current ognl path as we go along String ognlPath = ""; 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=1150780&r1=1150779&r2=1150780&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 Mon Jul 25 17:02:41 2011 @@ -745,8 +745,10 @@ public final class ObjectHelper { } else if ("double".equals(name)) { return double.class; } + return null; } + /** * Loads the given class with the provided classloader (may be null). * Will ignore any class not found and return null. @@ -760,6 +762,7 @@ public final class ObjectHelper { if (loader == null) { return null; } + try { LOG.trace("Loading class: {} using classloader: {}", name, loader); return loader.loadClass(name); @@ -767,8 +770,8 @@ public final class ObjectHelper { if (LOG.isTraceEnabled()) { LOG.trace("Cannot load class: " + name + " using classloader: " + loader, e); } - } + return null; } Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/util/StringHelper.java URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/util/StringHelper.java?rev=1150780&r1=1150779&r2=1150780&view=diff ============================================================================== --- camel/trunk/camel-core/src/main/java/org/apache/camel/util/StringHelper.java (original) +++ camel/trunk/camel-core/src/main/java/org/apache/camel/util/StringHelper.java Mon Jul 25 17:02:41 2011 @@ -76,6 +76,20 @@ public final class StringHelper { return s; } + public static String removeLeadingAndEndingQuotes(String s) { + if (ObjectHelper.isEmpty(s)) { + return s; + } + + if (s.startsWith("'") && s.endsWith("'")) { + return s.substring(1, s.length() - 1); + } + if (s.startsWith("\"") && s.endsWith("\"")) { + return s.substring(1, s.length() - 1); + } + return s; + } + /** * Encodes the text into safe XML by replacing < > and & with XML tokens * Modified: camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanOverloadedMethodFQNTest.java URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanOverloadedMethodFQNTest.java?rev=1150780&r1=1150779&r2=1150780&view=diff ============================================================================== --- camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanOverloadedMethodFQNTest.java (original) +++ camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanOverloadedMethodFQNTest.java Mon Jul 25 17:02:41 2011 @@ -18,6 +18,7 @@ package org.apache.camel.component.bean; import org.apache.camel.CamelExecutionException; import org.apache.camel.ContextTestSupport; +import org.apache.camel.NoTypeConversionAvailableException; import org.apache.camel.builder.RouteBuilder; /** @@ -65,8 +66,8 @@ public class BeanOverloadedMethodFQNTest template.sendBody("direct:start", new MyOrder()); fail("Should have thrown an exception"); } catch (CamelExecutionException e) { - AmbiguousMethodCallException cause = assertIsInstanceOf(AmbiguousMethodCallException.class, e.getCause()); - assertEquals(2, cause.getMethods().size()); + NoTypeConversionAvailableException cause = assertIsInstanceOf(NoTypeConversionAvailableException.class, e.getCause()); + assertEquals("Unknown", cause.getValue()); } } @@ -124,8 +125,8 @@ public class BeanOverloadedMethodFQNTest template.sendBody("direct:start", new MyOrder()); fail("Should have thrown an exception"); } catch (CamelExecutionException e) { - AmbiguousMethodCallException cause = assertIsInstanceOf(AmbiguousMethodCallException.class, e.getCause()); - assertEquals(2, cause.getMethods().size()); + NoTypeConversionAvailableException cause = assertIsInstanceOf(NoTypeConversionAvailableException.class, e.getCause()); + assertEquals("org.apache.camel.component.bean.BeanOverloadedMethodFQNTest$Unknown", cause.getValue()); } } Copied: camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanOverloadedMethodParameterValueTest.java (from r1150672, camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanOverloadedMethodTest.java) URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanOverloadedMethodParameterValueTest.java?p2=camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanOverloadedMethodParameterValueTest.java&p1=camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanOverloadedMethodTest.java&r1=1150672&r2=1150780&rev=1150780&view=diff ============================================================================== --- camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanOverloadedMethodTest.java (original) +++ camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanOverloadedMethodParameterValueTest.java Mon Jul 25 17:02:41 2011 @@ -16,27 +16,25 @@ */ package org.apache.camel.component.bean; -import org.apache.camel.CamelExecutionException; import org.apache.camel.ContextTestSupport; -import org.apache.camel.Header; import org.apache.camel.builder.RouteBuilder; /** * */ -public class BeanOverloadedMethodTest extends ContextTestSupport { +public class BeanOverloadedMethodParameterValueTest extends ContextTestSupport { @Override public boolean isUseRouteBuilder() { return false; } - public void testHelloOverloadedHeString() throws Exception { + public void testHelloOverloadedString() throws Exception { context.addRoutes(new RouteBuilder() { @Override public void configure() throws Exception { from("direct:start") - .bean(MyBean.class, "hello(String)") + .bean(MyBean.class, "hello(body)") .to("mock:result"); } @@ -75,7 +73,7 @@ public class BeanOverloadedMethodTest ex public void configure() throws Exception { // START SNIPPET: e2 from("direct:start") - .bean(MyBean.class, "hello(String,String)") + .bean(MyBean.class, "hello(body, header.country)") .to("mock:result"); // END SNIPPET: e2 } @@ -94,7 +92,7 @@ public class BeanOverloadedMethodTest ex @Override public void configure() throws Exception { from("direct:start") - .bean(MyBean.class, "hello(*,String)") + .bean(MyBean.class, "hello(*, ${header.country})") .to("mock:result"); } @@ -108,114 +106,31 @@ public class BeanOverloadedMethodTest ex assertMockEndpointsSatisfied(); } - public void testHelloOverloadedWildcardWildcard() throws Exception { - context.addRoutes(new RouteBuilder() { - @Override - public void configure() throws Exception { - // START SNIPPET: e3 - from("direct:start") - .bean(MyBean.class, "hello(*,*)") - .to("mock:result"); - // END SNIPPET: e3 - } - }); - context.start(); - - getMockEndpoint("mock:result").expectedBodiesReceived("Hello Claus you are from Denmark"); - - template.sendBodyAndHeader("direct:start", "Claus", "country", "Denmark"); - - assertMockEndpointsSatisfied(); - } - - public void testHelloOverloadedPickCamelAnnotated() throws Exception { + public void testTimesOverloadedStringInt() throws Exception { context.addRoutes(new RouteBuilder() { @Override public void configure() throws Exception { from("direct:start") - .bean(MyBean.class, "hello") + .bean(MyBean.class, "times(${body},3)") .to("mock:result"); } }); context.start(); - getMockEndpoint("mock:result").expectedBodiesReceived("Hello Claus you are from Denmark"); + getMockEndpoint("mock:result").expectedBodiesReceived("AAA"); - template.sendBodyAndHeader("direct:start", "Claus", "country", "Denmark"); + template.sendBody("direct:start", "A"); assertMockEndpointsSatisfied(); } - public void testHelloOverloadedAmbiguousStringStringString() throws Exception { - context.addRoutes(new RouteBuilder() { - @Override - public void configure() throws Exception { - from("direct:start") - .bean(MyBean.class, "hello(String,String,String)") - .to("mock:result"); - - } - }); - context.start(); - - try { - template.sendBodyAndHeader("direct:start", "Claus", "country", "Denmark"); - fail("Should have thrown an exception"); - } catch (CamelExecutionException e) { - AmbiguousMethodCallException cause = assertIsInstanceOf(AmbiguousMethodCallException.class, e.getCause()); - assertEquals(2, cause.getMethods().size()); - } - } - - public void testHelloOverloadedStringInt() throws Exception { - context.addRoutes(new RouteBuilder() { - @Override - public void configure() throws Exception { - from("direct:start") - .bean(MyBean.class, "hello(String,int)") - .to("mock:result"); - - } - }); - context.start(); - - try { - template.sendBodyAndHeader("direct:start", "Claus", "country", "Denmark"); - fail("Should have thrown an exception"); - } catch (CamelExecutionException e) { - AmbiguousMethodCallException cause = assertIsInstanceOf(AmbiguousMethodCallException.class, e.getCause()); - assertEquals(2, cause.getMethods().size()); - } - } - - public void testHelloOverloadedIntString() throws Exception { - context.addRoutes(new RouteBuilder() { - @Override - public void configure() throws Exception { - from("direct:start") - .bean(MyBean.class, "hello(int,String)") - .to("mock:result"); - - } - }); - context.start(); - - try { - template.sendBodyAndHeader("direct:start", "Claus", "country", "Denmark"); - fail("Should have thrown an exception"); - } catch (CamelExecutionException e) { - AmbiguousMethodCallException cause = assertIsInstanceOf(AmbiguousMethodCallException.class, e.getCause()); - assertEquals(2, cause.getMethods().size()); - } - } - - public void testTimesOverloadedStringInt() throws Exception { + public void testTimesOverloadedStringIntHeader() throws Exception { context.addRoutes(new RouteBuilder() { @Override public void configure() throws Exception { from("direct:start") - .bean(MyBean.class, "times(String,int)") + .bean(MyBean.class, "times(${body},${header.times})") .to("mock:result"); } @@ -224,7 +139,7 @@ public class BeanOverloadedMethodTest ex getMockEndpoint("mock:result").expectedBodiesReceived("AAA"); - template.sendBodyAndHeader("direct:start", "A", "times", "3"); + template.sendBodyAndHeader("direct:start", "A", "times", 3); assertMockEndpointsSatisfied(); } @@ -234,7 +149,7 @@ public class BeanOverloadedMethodTest ex @Override public void configure() throws Exception { from("direct:start") - .bean(MyBean.class, "times(byte[],int)") + .bean(MyBean.class, "times(byte[],${header.times})") .to("mock:result"); } @@ -256,11 +171,11 @@ public class BeanOverloadedMethodTest ex return "Hello " + name; } - public String hello(String name, @Header("country") String country) { + public String hello(String name, String country) { return "Hello " + name + " you are from " + country; } - public String times(String name, @Header("times") int times) { + public String times(String name, int times) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < times; i++) { sb.append(name); @@ -268,7 +183,7 @@ public class BeanOverloadedMethodTest ex return sb.toString(); } - public String times(byte[] data, @Header("times") int times) { + public String times(byte[] data, int times) { String s = new String(data); StringBuilder sb = new StringBuilder(); for (int i = 0; i < times; i++) { Added: camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanParameterValueOgnlTest.java URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanParameterValueOgnlTest.java?rev=1150780&view=auto ============================================================================== --- camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanParameterValueOgnlTest.java (added) +++ camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanParameterValueOgnlTest.java Mon Jul 25 17:02:41 2011 @@ -0,0 +1,144 @@ +/** + * 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.component.bean; + +import org.apache.camel.ContextTestSupport; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.impl.JndiRegistry; + +/** + * + */ +public class BeanParameterValueOgnlTest extends ContextTestSupport { + + public void testBeanParameterValue() throws Exception { + getMockEndpoint("mock:result").expectedBodiesReceived("Hello World"); + + template.sendBody("direct:start", "World"); + + assertMockEndpointsSatisfied(); + } + + public void testBeanParameterValueBodyOgnl() throws Exception { + getMockEndpoint("mock:result").expectedBodiesReceived("Hello Tony"); + + Animal tiger = new Animal("Tony", 13); + template.sendBody("direct:start2", tiger); + + assertMockEndpointsSatisfied(); + } + + public void testBeanParameterValueHeaderOgnl() throws Exception { + getMockEndpoint("mock:result").expectedBodiesReceived("Hello Kong"); + + Animal kong = new Animal("Kong", 34); + Animal tiger = new Animal("Tony", 13); + tiger.setFriend(kong); + + template.sendBodyAndHeader("direct:start3", "Hello World", "animal", tiger); + + assertMockEndpointsSatisfied(); + } + + @Override + protected JndiRegistry createRegistry() throws Exception { + JndiRegistry jndi = super.createRegistry(); + jndi.bind("foo", new MyBean()); + return jndi; + } + + @Override + protected RouteBuilder createRouteBuilder() throws Exception { + return new RouteBuilder() { + @Override + public void configure() throws Exception { + from("direct:start") + .to("bean:foo?method=bar(body,true)") + .to("mock:result"); + + from("direct:start2") + .to("bean:foo?method=bar(${body.name}, true)") + .to("mock:result"); + + from("direct:start3") + .to("bean:foo?method=bar(${header.animal?.friend.name}, true)") + .to("mock:result"); + } + }; + } + + public static class MyBean { + + public String bar(String body, boolean hello) { + if (hello) { + return "Hello " + body; + } else { + return body; + } + } + + public String echo(String body, int times) { + if (times > 0) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < times; i++) { + sb.append(body); + } + return sb.toString(); + } + + return body; + } + } + + public static final class Animal { + private String name; + private int age; + private Animal friend; + + private Animal(String name, int age) { + this.name = name; + this.age = age; + } + + public String getName() { + return name; + } + + public int getAge() { + return age; + } + + public Animal getFriend() { + return friend; + } + + public void setFriend(Animal friend) { + this.friend = friend; + } + + public boolean isDangerous() { + return name.contains("Tiger"); + } + + @Override + public String toString() { + return name; + } + } + + +} Added: camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanParameterValueOverloadedTest.java URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanParameterValueOverloadedTest.java?rev=1150780&view=auto ============================================================================== --- camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanParameterValueOverloadedTest.java (added) +++ camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanParameterValueOverloadedTest.java Mon Jul 25 17:02:41 2011 @@ -0,0 +1,88 @@ +/** + * 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.component.bean; + +import org.apache.camel.ContextTestSupport; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.impl.JndiRegistry; + +/** + * + */ +public class BeanParameterValueOverloadedTest extends ContextTestSupport { + + public void testBeanParameterValueBoolean() throws Exception { + getMockEndpoint("mock:result").expectedBodiesReceived("Hello World"); + + template.sendBody("direct:start", "World"); + + assertMockEndpointsSatisfied(); + } + + public void testBeanParameterValueBoolean2() throws Exception { + getMockEndpoint("mock:result").expectedBodiesReceived("Bye World"); + + template.sendBody("direct:start2", "World"); + + assertMockEndpointsSatisfied(); + } + + @Override + protected JndiRegistry createRegistry() throws Exception { + JndiRegistry jndi = super.createRegistry(); + jndi.bind("foo", new MyBean()); + return jndi; + } + + @Override + protected RouteBuilder createRouteBuilder() throws Exception { + return new RouteBuilder() { + @Override + public void configure() throws Exception { + from("direct:start") + .to("bean:foo?method=bar(*,true)") + .to("mock:result"); + + from("direct:start2") + .to("bean:foo?method=bar(body,false,true)") + .to("mock:result"); + } + }; + } + + public static class MyBean { + + public String bar(String body, boolean hello) { + if (hello) { + return "Hello " + body; + } else { + return body; + } + } + + public String bar(String body, boolean hello, boolean bye) { + if (hello) { + return "Hi " + body; + } else if (bye) { + return "Bye " + body; + } else { + return body; + } + } + + } +} Added: camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanParameterValueTest.java URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanParameterValueTest.java?rev=1150780&view=auto ============================================================================== --- camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanParameterValueTest.java (added) +++ camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanParameterValueTest.java Mon Jul 25 17:02:41 2011 @@ -0,0 +1,137 @@ +/** + * 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.component.bean; + +import org.apache.camel.ContextTestSupport; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.impl.JndiRegistry; + +/** + * + */ +public class BeanParameterValueTest extends ContextTestSupport { + + public void testBeanParameterValueBoolean() throws Exception { + getMockEndpoint("mock:result").expectedBodiesReceived("Hello World"); + + template.sendBody("direct:start", "World"); + + assertMockEndpointsSatisfied(); + } + + public void testBeanParameterValueBoolean2() throws Exception { + getMockEndpoint("mock:result").expectedBodiesReceived("Hello World"); + + template.sendBody("direct:start2", "World"); + + assertMockEndpointsSatisfied(); + } + + public void testBeanParameterValueBoolean3() throws Exception { + getMockEndpoint("mock:result").expectedBodiesReceived("Hello World"); + + template.sendBody("direct:start3", "World"); + + assertMockEndpointsSatisfied(); + } + + public void testBeanParameterValueBoolean4() throws Exception { + getMockEndpoint("mock:result").expectedBodiesReceived("Hello Camel"); + + template.sendBody("direct:start4", "World"); + + assertMockEndpointsSatisfied(); + } + + public void testBeanParameterValueInteger() throws Exception { + getMockEndpoint("mock:result").expectedBodiesReceived("WorldWorldWorld"); + + template.sendBody("direct:echo", "World"); + + assertMockEndpointsSatisfied(); + } + + public void testBeanParameterValueHeaderInteger() throws Exception { + getMockEndpoint("mock:result").expectedBodiesReceived("WorldWorld"); + + template.sendBodyAndHeader("direct:echo2", "World", "times", 2); + + assertMockEndpointsSatisfied(); + } + + @Override + protected JndiRegistry createRegistry() throws Exception { + JndiRegistry jndi = super.createRegistry(); + jndi.bind("foo", new MyBean()); + return jndi; + } + + @Override + protected RouteBuilder createRouteBuilder() throws Exception { + return new RouteBuilder() { + @Override + public void configure() throws Exception { + from("direct:start") + .to("bean:foo?method=bar(*,true)") + .to("mock:result"); + + from("direct:start2") + .to("bean:foo?method=bar(body,true)") + .to("mock:result"); + + from("direct:start3") + .to("bean:foo?method=bar(${body}, true)") + .to("mock:result"); + + from("direct:start4") + .to("bean:foo?method=bar('Camel', true)") + .to("mock:result"); + + from("direct:echo") + .to("bean:foo?method=echo(*, 3)") + .to("mock:result"); + + from("direct:echo2") + .to("bean:foo?method=echo(*, ${in.header.times})") + .to("mock:result"); + } + }; + } + + public static class MyBean { + + public String bar(String body, boolean hello) { + if (hello) { + return "Hello " + body; + } else { + return body; + } + } + + public String echo(String body, int times) { + if (times > 0) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < times; i++) { + sb.append(body); + } + return sb.toString(); + } + + return body; + } + } +} Modified: camel/trunk/camel-core/src/test/java/org/apache/camel/util/StringHelperTest.java URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/util/StringHelperTest.java?rev=1150780&r1=1150779&r2=1150780&view=diff ============================================================================== --- camel/trunk/camel-core/src/test/java/org/apache/camel/util/StringHelperTest.java (original) +++ camel/trunk/camel-core/src/test/java/org/apache/camel/util/StringHelperTest.java Mon Jul 25 17:02:41 2011 @@ -58,6 +58,16 @@ public class StringHelperTest extends Te assertEquals("foo", StringHelper.removeQuotes("'foo\"")); } + public void testRemoveLeadingAndEndingQuotes() throws Exception { + assertEquals(null, StringHelper.removeLeadingAndEndingQuotes(null)); + assertEquals("", StringHelper.removeLeadingAndEndingQuotes("")); + assertEquals(" ", StringHelper.removeLeadingAndEndingQuotes(" ")); + assertEquals("Hello World", StringHelper.removeLeadingAndEndingQuotes("Hello World")); + assertEquals("Hello World", StringHelper.removeLeadingAndEndingQuotes("'Hello World'")); + assertEquals("Hello World", StringHelper.removeLeadingAndEndingQuotes("\"Hello World\"")); + assertEquals("Hello 'Camel'", StringHelper.removeLeadingAndEndingQuotes("Hello 'Camel'")); + } + public void testHasUpper() throws Exception { assertEquals(false, StringHelper.hasUpperCase(null)); assertEquals(false, StringHelper.hasUpperCase(""));