You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2009/10/25 16:01:56 UTC

svn commit: r829598 - in /camel/trunk/camel-core/src: main/java/org/apache/camel/builder/ main/java/org/apache/camel/component/bean/ main/java/org/apache/camel/util/ test/java/org/apache/camel/component/bean/

Author: davsclaus
Date: Sun Oct 25 15:01:55 2009
New Revision: 829598

URL: http://svn.apache.org/viewvc?rev=829598&view=rev
Log:
CAMEL-2106: Bean component now throws NoTypeConverterException if it cannot convert to parameter type.

Added:
    camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanNoTypeConvertionPossibleTest.java   (with props)
    camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanNoTypeConvertionPossibleWhenHeaderTest.java   (with props)
    camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanWithHeaderAnnotation.java   (with props)
Modified:
    camel/trunk/camel-core/src/main/java/org/apache/camel/builder/ExpressionBuilder.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/MethodInfo.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/util/ObjectHelper.java
    camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/OrderServiceBean.java

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/builder/ExpressionBuilder.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/ExpressionBuilder.java?rev=829598&r1=829597&r2=829598&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/builder/ExpressionBuilder.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/builder/ExpressionBuilder.java Sun Oct 25 15:01:55 2009
@@ -29,6 +29,7 @@
 import org.apache.camel.Endpoint;
 import org.apache.camel.Exchange;
 import org.apache.camel.Expression;
+import org.apache.camel.InvalidPayloadException;
 import org.apache.camel.Message;
 import org.apache.camel.NoSuchEndpointException;
 import org.apache.camel.Producer;
@@ -435,6 +436,27 @@
     }
 
     /**
+     * Returns the expression for the exchanges inbound message body converted
+     * to the given type
+     */
+    public static <T> Expression mandatoryBodyExpression(final Class<T> type) {
+        return new ExpressionAdapter() {
+            public Object evaluate(Exchange exchange) {
+                try {
+                    return exchange.getIn().getMandatoryBody(type);
+                } catch(InvalidPayloadException e) {
+                    throw ObjectHelper.wrapCamelExecutionException(exchange, e);
+                }
+            }
+
+            @Override
+            public String toString() {
+                return "mandatoryBodyAs[" + type.getName() + "]";
+            }
+        };
+    }
+
+    /**
      * Returns the expression for the exchanges inbound message body type
      */
     public static Expression bodyTypeExpression() {

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=829598&r1=829597&r2=829598&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 Sun Oct 25 15:01:55 2009
@@ -311,8 +311,9 @@
                         // use exchange
                         expression = ExpressionBuilder.exchangeExpression();
                     } else {
-                        // lets assume its the body
-                        expression = ExpressionBuilder.bodyExpression(parameterType);
+                        // lets assume its the body and it must be mandatory convertable to the parameter type
+                        // so we dont pass in null as body in case Camel cannot convert to the parameter type
+                        expression = ExpressionBuilder.mandatoryBodyExpression(parameterType);
                     }
                     if (LOG.isTraceEnabled()) {
                         LOG.trace("Parameter #" + i + " is the body parameter using expression " + expression);

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=829598&r1=829597&r2=829598&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 Sun Oct 25 15:01:55 2009
@@ -223,17 +223,17 @@
                     } else {
                         Expression expression = expressions[i];
                         if (expression != null) {
-                            // use object first to avoid type convertions so we know if there is a value or not
+                            // 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
-                                value = exchange.getContext().getTypeConverter().convertTo(parameters.get(i).getType(), result);
-                                if (LOG.isTraceEnabled()) {
-                                    LOG.trace("Parameter #" + i + " evaluated as: " + value + " type: " + ObjectHelper.type(value));
-                                }
-                                if (value == null) {
-                                    Exception e = new NoTypeConversionAvailableException(result, parameters.get(i).getType()); 
-                                    throw ObjectHelper.wrapRuntimeCamelException(e);
+                                try {
+                                    value = exchange.getContext().getTypeConverter().mandatoryConvertTo(parameters.get(i).getType(), result);
+                                    if (LOG.isTraceEnabled()) {
+                                        LOG.trace("Parameter #" + i + " evaluated as: " + value + " type: " + ObjectHelper.type(value));
+                                    }
+                                } catch (NoTypeConversionAvailableException e) {
+                                    throw ObjectHelper.wrapCamelExecutionException(exchange, e);
                                 }
                             } else {
                                 if (LOG.isTraceEnabled()) {

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=829598&r1=829597&r2=829598&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 Sun Oct 25 15:01:55 2009
@@ -615,6 +615,8 @@
         // special for byte[] as its common to use
         if ("java.lang.byte[]".equals(name) || "byte[]".equals(name)) {
             return byte[].class;
+        } else if ("java.lang.String".equals(name) || "String".equals(name)) {
+            return String.class;
         }
 
         // try context class loader first

Added: camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanNoTypeConvertionPossibleTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanNoTypeConvertionPossibleTest.java?rev=829598&view=auto
==============================================================================
--- camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanNoTypeConvertionPossibleTest.java (added)
+++ camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanNoTypeConvertionPossibleTest.java Sun Oct 25 15:01:55 2009
@@ -0,0 +1,84 @@
+/**
+ * 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 java.util.Date;
+
+import org.w3c.dom.Document;
+
+import org.apache.camel.CamelExecutionException;
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.NoTypeConversionAvailableException;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+
+/**
+ * @version $Revision$
+ */
+public class BeanNoTypeConvertionPossibleTest extends ContextTestSupport {
+
+    public void testBeanNoTypeConvertionPossibleFail() throws Exception {
+        MockEndpoint mock = getMockEndpoint("mock:result");
+        mock.expectedMessageCount(0);
+
+        // we send in a Date object which cannot be converted to XML so it should fail
+        try {
+            template.requestBody("direct:start", new Date());
+            fail("Should have thrown an exception");
+        } catch (CamelExecutionException e) {
+            NoTypeConversionAvailableException ntae = assertIsInstanceOf(NoTypeConversionAvailableException.class, e.getCause().getCause());
+            assertEquals(Date.class, ntae.getFromType());
+            assertEquals(Document.class, ntae.getToType());
+            assertNotNull(ntae.getValue());
+            assertNotNull(ntae.getMessage());
+        }
+
+        assertMockEndpointsSatisfied();
+    }
+
+    public void testBeanNoTypeConvertionPossibleOK() throws Exception {
+        MockEndpoint mock = getMockEndpoint("mock:result");
+        mock.expectedBodiesReceived("77889,667,457");
+
+        template.requestBody("direct:start", "<foo>bar</foo>");
+
+        assertMockEndpointsSatisfied();
+    }
+
+    public void testBeanNoTypeConvertionPossibleOKNullBody() throws Exception {
+        MockEndpoint mock = getMockEndpoint("mock:result");
+        mock.expectedMessageCount(1);
+        mock.message(0).body().isNull();
+
+        String body = null;
+        template.requestBody("direct:start", body);
+
+        assertMockEndpointsSatisfied();
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                OrderServiceBean bean = new OrderServiceBean();
+                bean.setConverter(context.getTypeConverter());
+                from("direct:start").bean(bean, "handleXML").to("mock:result");
+            }
+        };
+    }
+}

Propchange: camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanNoTypeConvertionPossibleTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanNoTypeConvertionPossibleTest.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanNoTypeConvertionPossibleWhenHeaderTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanNoTypeConvertionPossibleWhenHeaderTest.java?rev=829598&view=auto
==============================================================================
--- camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanNoTypeConvertionPossibleWhenHeaderTest.java (added)
+++ camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanNoTypeConvertionPossibleWhenHeaderTest.java Sun Oct 25 15:01:55 2009
@@ -0,0 +1,91 @@
+/**
+ * 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.w3c.dom.Document;
+
+import org.apache.camel.CamelExecutionException;
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.NoTypeConversionAvailableException;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+
+/**
+ * @version $Revision$
+ */
+public class BeanNoTypeConvertionPossibleWhenHeaderTest extends ContextTestSupport {
+
+    public void testBeanHeaderNoTypeConvertionPossibleFail() throws Exception {
+        MockEndpoint mock = getMockEndpoint("mock:result");
+        mock.expectedMessageCount(0);
+
+        // we send in a bar string as header which cannot be converted to a number so it should fail
+        try {
+            template.requestBodyAndHeader("direct:start", "Hello World", "foo", 555);
+            fail("Should have thrown an exception");
+        } catch (CamelExecutionException e) {
+            NoTypeConversionAvailableException ntae = assertIsInstanceOf(NoTypeConversionAvailableException.class, e.getCause());
+            assertEquals(Integer.class, ntae.getFromType());
+            assertEquals(Document.class, ntae.getToType());
+            assertEquals(555, ntae.getValue());
+            assertNotNull(ntae.getMessage());
+        }
+
+        assertMockEndpointsSatisfied();
+    }
+
+    public void testBeanHeaderNoTypeConvertionPossibleOK() throws Exception {
+        MockEndpoint mock = getMockEndpoint("mock:result");
+        mock.expectedBodiesReceived("Hello World");
+
+        template.requestBodyAndHeader("direct:start", "Hello World", "foo", "<?xml version=\"1.0\"?><foo>bar</foo>");
+
+        assertMockEndpointsSatisfied();
+    }
+
+    public void testBeanHeaderNoTypeConvertionPossibleOKNullHeader() throws Exception {
+        MockEndpoint mock = getMockEndpoint("mock:result");
+        mock.expectedMessageCount(1);
+        mock.expectedBodiesReceived("Hello World");
+        mock.message(0).header("foo").isNull();
+
+        template.requestBodyAndHeader("direct:start", "Hello World", "foo", null);
+
+        assertMockEndpointsSatisfied();
+    }
+
+    public void testBeanHeaderNoTypeConvertionPossibleOKNoHeader() throws Exception {
+        MockEndpoint mock = getMockEndpoint("mock:result");
+        mock.expectedMessageCount(1);
+        mock.expectedBodiesReceived("Hello World");
+        mock.message(0).header("foo").isNull();
+
+        template.requestBody("direct:start", "Hello World");
+
+        assertMockEndpointsSatisfied();
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                from("direct:start").bean(BeanWithHeaderAnnotation.class).to("mock:result");
+            }
+        };
+    }
+}
\ No newline at end of file

Propchange: camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanNoTypeConvertionPossibleWhenHeaderTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanNoTypeConvertionPossibleWhenHeaderTest.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanWithHeaderAnnotation.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanWithHeaderAnnotation.java?rev=829598&view=auto
==============================================================================
--- camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanWithHeaderAnnotation.java (added)
+++ camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanWithHeaderAnnotation.java Sun Oct 25 15:01:55 2009
@@ -0,0 +1,30 @@
+/**
+ * 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.Header;
+import org.w3c.dom.Document;
+
+/**
+ * @version $Revision$
+ */
+public class BeanWithHeaderAnnotation {
+
+    public String hello(String body, @Header("foo") Document doc) {
+        return body;
+    }
+}

Propchange: camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanWithHeaderAnnotation.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanWithHeaderAnnotation.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Modified: camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/OrderServiceBean.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/OrderServiceBean.java?rev=829598&r1=829597&r2=829598&view=diff
==============================================================================
--- camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/OrderServiceBean.java (original)
+++ camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/OrderServiceBean.java Sun Oct 25 15:01:55 2009
@@ -46,6 +46,10 @@
     }
 
     public String handleXML(Document doc) {
+        if (doc == null) {
+            return null;
+        }
+
         String xml = converter.convertTo(String.class, doc);
 
         Integer orderId = 77889;