You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by cm...@apache.org on 2011/01/08 19:26:28 UTC
svn commit: r1056749 - in /camel/trunk/camel-core/src:
main/java/org/apache/camel/ main/java/org/apache/camel/component/bean/
main/java/org/apache/camel/converter/
test/java/org/apache/camel/component/bean/
test/java/org/apache/camel/converter/
Author: cmueller
Date: Sat Jan 8 18:26:28 2011
New Revision: 1056749
URL: http://svn.apache.org/viewvc?rev=1056749&view=rev
Log:
CAMEL-3311: bean parameter binding - Add support for type option to force Camel to pick method with compatible type
Modified:
camel/trunk/camel-core/src/main/java/org/apache/camel/Exchange.java
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/BeanProcessor.java
camel/trunk/camel-core/src/main/java/org/apache/camel/converter/ObjectConverter.java
camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanExplicitMethodAmbiguousTest.java
camel/trunk/camel-core/src/test/java/org/apache/camel/converter/ObjectConverterTest.java
Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/Exchange.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/Exchange.java?rev=1056749&r1=1056748&r2=1056749&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/Exchange.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/Exchange.java Sat Jan 8 18:26:28 2011
@@ -84,6 +84,7 @@ public interface Exchange {
String BATCH_COMPLETE = "CamelBatchComplete";
String BEAN_METHOD_NAME = "CamelBeanMethodName";
String BEAN_MULTI_PARAMETER_ARRAY = "CamelBeanMultiParameterArray";
+ String BEAN_TYPE_NAME = "CamelBeanTypeName";
String BINDING = "CamelBinding";
String CHARSET_NAME = "CamelCharsetName";
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=1056749&r1=1056748&r2=1056749&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 Sat Jan 8 18:26:28 2011
@@ -129,10 +129,12 @@ public class BeanInfo {
return null;
}
+ @SuppressWarnings("rawtypes")
public MethodInvocation createInvocation(Object pojo, Exchange exchange) throws AmbiguousMethodCallException, MethodNotFoundException {
MethodInfo methodInfo = null;
String name = exchange.getIn().getHeader(Exchange.BEAN_METHOD_NAME, String.class);
+ Class type = exchange.getIn().getHeader(Exchange.BEAN_TYPE_NAME, Class.class);
if (name != null) {
if (hasMethod(name)) {
List<MethodInfo> methods = getOperations(name);
@@ -143,7 +145,7 @@ public class BeanInfo {
// there are more methods with that name so we cannot decide which to use
// but first lets try to choose a method and see if that comply with the name
- methodInfo = chooseMethod(pojo, exchange, name);
+ methodInfo = chooseMethod(pojo, exchange, name, type);
if (methodInfo == null || !name.equals(methodInfo.getMethod().getName())) {
throw new AmbiguousMethodCallException(exchange, methods);
}
@@ -154,7 +156,7 @@ public class BeanInfo {
}
}
if (methodInfo == null) {
- methodInfo = chooseMethod(pojo, exchange, name);
+ methodInfo = chooseMethod(pojo, exchange, name, null);
}
if (methodInfo == null) {
methodInfo = defaultMethod;
@@ -280,7 +282,7 @@ public class BeanInfo {
return answer;
}
- @SuppressWarnings("unchecked")
+ @SuppressWarnings({ "unchecked", "rawtypes" })
protected MethodInfo createMethodInfo(Class clazz, Method method) {
Class[] parameterTypes = method.getParameterTypes();
Annotation[][] parametersAnnotations = method.getParameterAnnotations();
@@ -349,15 +351,17 @@ public class BeanInfo {
* @param pojo the bean to invoke a method on
* @param exchange the message exchange
* @param name an optional name of the method that must match, use <tt>null</tt> to indicate all methods
+ * @param type an optional type of the method parameter that must match, use <tt>null</tt> to indicate all types
* @return the method to invoke or null if no definitive method could be matched
* @throws AmbiguousMethodCallException is thrown if cannot chose method due to ambiguous
*/
- protected MethodInfo chooseMethod(Object pojo, Exchange exchange, String name) throws AmbiguousMethodCallException {
+ @SuppressWarnings("rawtypes")
+ protected MethodInfo chooseMethod(Object pojo, Exchange exchange, String name, Class type) throws AmbiguousMethodCallException {
// @Handler should be select first
// then any single method that has a custom @annotation
// or any single method that has a match parameter type that matches the Exchange payload
// and last then try to select the best among the rest
-
+
if (name != null) {
// filter all lists to only include methods with this name
removeNonMatchingMethods(operationsWithHandlerAnnotation, name);
@@ -369,6 +373,13 @@ public class BeanInfo {
removeAllSetterOrGetterMethods(operationsWithCustomAnnotation);
removeAllSetterOrGetterMethods(operationsWithBody);
}
+
+ if (type != null) {
+ // filter all lists to only include methods with this argument type
+ removeNonMatchingMethods(operationsWithHandlerAnnotation, type);
+ removeNonMatchingMethods(operationsWithCustomAnnotation, type);
+ removeNonMatchingMethods(operationsWithBody, type);
+ }
if (operationsWithHandlerAnnotation.size() > 1) {
// if we have more than 1 @Handler then its ambiguous
@@ -404,6 +415,7 @@ public class BeanInfo {
return null;
}
+ @SuppressWarnings("rawtypes")
private MethodInfo chooseMethodWithMatchingBody(Exchange exchange, Collection<MethodInfo> operationList)
throws AmbiguousMethodCallException {
// lets see if we can find a method who's body param type matches the message body
@@ -665,6 +677,19 @@ public class BeanInfo {
}
}
}
+
+ @SuppressWarnings("rawtypes")
+ private static void removeNonMatchingMethods(List<MethodInfo> methods, Class type) {
+ Iterator<MethodInfo> it = methods.iterator();
+ while (it.hasNext()) {
+ MethodInfo info = it.next();
+ Class<?>[] parameterTypes = info.getMethod().getParameterTypes();
+ if (!(parameterTypes.length > 0 && parameterTypes[0].isAssignableFrom(type))) {
+ // type does not match so remove it
+ it.remove();
+ }
+ }
+ }
private static Class<?> getTargetClass(Class<?> clazz) {
if (clazz != null && clazz.getName().contains(CGLIB_CLASS_SEPARATOR)) {
Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/BeanProcessor.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/BeanProcessor.java?rev=1056749&r1=1056748&r2=1056749&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/BeanProcessor.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/BeanProcessor.java Sat Jan 8 18:26:28 2011
@@ -47,6 +47,8 @@ public class BeanProcessor extends Servi
private String method;
private BeanHolder beanHolder;
private boolean shorthandMethod;
+ @SuppressWarnings("rawtypes")
+ private Class type;
public BeanProcessor(Object pojo, BeanInfo beanInfo) {
this(new ConstantBeanHolder(pojo, beanInfo));
@@ -74,9 +76,13 @@ public class BeanProcessor extends Servi
AsyncProcessorHelper.process(this, exchange);
}
+ @SuppressWarnings({ "unused", "rawtypes" })
public boolean process(Exchange exchange, AsyncCallback callback) {
// do we have an explicit method name we always should invoke
boolean isExplicitMethod = ObjectHelper.isNotEmpty(method);
+ // do we have an explicit parameter type we should invoke if we have multiple possible
+ // methods
+ boolean isExplicitType = ObjectHelper.isNotEmpty(type);
Object bean = beanHolder.getBean();
BeanInfo beanInfo = beanHolder.getBeanInfo();
@@ -98,7 +104,7 @@ public class BeanProcessor extends Servi
}
Message in = exchange.getIn();
-
+
// Now it gets a bit complicated as ProxyHelper can proxy beans which we later
// intend to invoke (for example to proxy and invoke using spring remoting).
// and therefore the message body contains a BeanInvocation object.
@@ -122,13 +128,14 @@ public class BeanProcessor extends Servi
return true;
}
}
-
+
// set temporary header which is a hint for the bean info that introspect the bean
if (in.getHeader(Exchange.BEAN_MULTI_PARAMETER_ARRAY) == null) {
in.setHeader(Exchange.BEAN_MULTI_PARAMETER_ARRAY, isMultiParameterArray());
}
String prevMethod = null;
+ Class prevType = null;
MethodInvocation invocation;
if (methodObject != null) {
invocation = beanInfo.createInvocation(methodObject, bean, exchange);
@@ -138,6 +145,10 @@ public class BeanProcessor extends Servi
prevMethod = in.getHeader(Exchange.BEAN_METHOD_NAME, String.class);
in.setHeader(Exchange.BEAN_METHOD_NAME, method);
}
+ if (isExplicitType) {
+ prevType = in.getHeader(Exchange.BEAN_TYPE_NAME, Class.class);
+ in.setHeader(Exchange.BEAN_TYPE_NAME, type);
+ }
try {
invocation = beanInfo.createInvocation(bean, exchange);
} catch (Throwable e) {
@@ -258,6 +269,21 @@ public class BeanProcessor extends Servi
public void setShorthandMethod(boolean shorthandMethod) {
this.shorthandMethod = shorthandMethod;
}
+
+ @SuppressWarnings("rawtypes")
+ public Class getType() {
+ return type;
+ }
+
+ /**
+ * Sets the type/class name to which the body should converted before the suitable method is
+ * determined.
+ * @param type
+ */
+ @SuppressWarnings("rawtypes")
+ public void setType(Class type) {
+ this.type = type;
+ }
// Implementation methods
//-------------------------------------------------------------------------
Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/converter/ObjectConverter.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/converter/ObjectConverter.java?rev=1056749&r1=1056748&r2=1056749&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/converter/ObjectConverter.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/converter/ObjectConverter.java Sat Jan 8 18:26:28 2011
@@ -65,6 +65,7 @@ public final class ObjectConverter {
/**
* Creates an iterator over the value
*/
+ @SuppressWarnings("rawtypes")
@Converter
public static Iterator iterator(Object value) {
return ObjectHelper.createIterator(value);
@@ -106,6 +107,21 @@ public final class ObjectConverter {
public static String fromCharArray(char[] value) {
return new String(value);
}
+
+ /**
+ * Returns the converted value, or null if the value is null
+ */
+ @SuppressWarnings("rawtypes")
+ @Converter
+ public static Class toClass(Object value) {
+ if (value instanceof Class) {
+ return (Class) value;
+ } else if (value instanceof String) {
+ return ObjectHelper.loadClass((String) value);
+ } else {
+ return null;
+ }
+ }
/**
* Returns the converted value, or null if the value is null
Modified: camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanExplicitMethodAmbiguousTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanExplicitMethodAmbiguousTest.java?rev=1056749&r1=1056748&r2=1056749&view=diff
==============================================================================
--- camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanExplicitMethodAmbiguousTest.java (original)
+++ camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanExplicitMethodAmbiguousTest.java Sat Jan 8 18:26:28 2011
@@ -17,6 +17,7 @@
package org.apache.camel.component.bean;
import java.io.ByteArrayInputStream;
+import java.io.StringReader;
import org.apache.camel.ContextTestSupport;
import org.apache.camel.builder.RouteBuilder;
@@ -49,16 +50,36 @@ public class BeanExplicitMethodAmbiguous
assertEquals("Bye Camel", out);
}
- public void testBeanExplicitMethodInvocationStringBody() throws Exception {
+ public void testBeanImplicitMethodInvocationStringBody() throws Exception {
String out = template.requestBody("direct:foo", "Camel", String.class);
assertEquals("String", out);
}
- public void testBeanExplicitMethodInvocationInputStreamBody() throws Exception {
+ public void testBeanImplicitMethodInvocationReaderBody() throws Exception {
+ String out = template.requestBody("direct:foo", new StringReader("Camel"), String.class);
+ assertEquals("Reader", out);
+ }
+
+ public void testBeanImplicitMethodInvocationInputStreamBody() throws Exception {
String out = template.requestBody("direct:foo", new ByteArrayInputStream("Camel".getBytes()), String.class);
assertEquals("InputStream", out);
}
+
+ public void testBeanExplicitMethodInvocationString() throws Exception {
+ String out = template.requestBody("direct:explicitString", new ByteArrayInputStream("Camel".getBytes()), String.class);
+ assertEquals("String", out);
+ }
+
+ public void testBeanExplicitMethodInvocationReader() throws Exception {
+ String out = template.requestBody("direct:explicitReader", new ByteArrayInputStream("Camel".getBytes()), String.class);
+ assertEquals("Reader", out);
+ }
+ public void testBeanExplicitMethodInvocationInputStream() throws Exception {
+ String out = template.requestBody("direct:explicitInputStream", "Camel", String.class);
+ assertEquals("InputStream", out);
+ }
+
@Override
protected RouteBuilder createRouteBuilder() throws Exception {
return new RouteBuilder() {
@@ -69,6 +90,12 @@ public class BeanExplicitMethodAmbiguous
from("direct:bye").beanRef("dummy");
from("direct:foo").beanRef("dummy", "bar");
+
+ from("direct:explicitString").to("bean:dummy?method=bar&type=java.lang.String");
+
+ from("direct:explicitReader").to("bean:dummy?method=bar&type=java.io.Reader");
+
+ from("direct:explicitInputStream").to("bean:dummy?method=bar&type=java.io.InputStream");
}
};
}
Modified: camel/trunk/camel-core/src/test/java/org/apache/camel/converter/ObjectConverterTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/converter/ObjectConverterTest.java?rev=1056749&r1=1056748&r2=1056749&view=diff
==============================================================================
--- camel/trunk/camel-core/src/test/java/org/apache/camel/converter/ObjectConverterTest.java (original)
+++ camel/trunk/camel-core/src/test/java/org/apache/camel/converter/ObjectConverterTest.java Sat Jan 8 18:26:28 2011
@@ -47,6 +47,13 @@ public class ObjectConverterTest extends
assertEquals(Byte.valueOf("4"), ObjectConverter.toByte("4"));
assertEquals(null, ObjectConverter.toByte(new Date()));
}
+
+ public void testToClass() {
+ assertEquals(String.class, ObjectConverter.toClass(String.class));
+ assertEquals(String.class, ObjectConverter.toClass("java.lang.String"));
+ assertEquals(null, ObjectConverter.toClass(new Integer(4)));
+ assertEquals(null, ObjectConverter.toClass("foo.Bar"));
+ }
public void testToShort() {
assertEquals(Short.valueOf("4"), ObjectConverter.toShort(Short.valueOf("4")));