Repository: camel
Updated Branches:
  refs/heads/camel-2.17.x d449324d6 -> 8ad61d39d
  refs/heads/camel-2.18.x a60fe9643 -> 7ae4a18bd


CAMEL-10424: Bean should act like transform/setBody when setting result


Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/49b1240a
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/49b1240a
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/49b1240a

Branch: refs/heads/camel-2.18.x
Commit: 49b1240a1b9c70144f5269d9965c3ad14551b196
Parents: a60fe96
Author: Claus Ibsen <davscl...@apache.org>
Authored: Sat Oct 29 12:31:15 2016 +0200
Committer: Claus Ibsen <davscl...@apache.org>
Committed: Sat Oct 29 13:24:47 2016 +0200

----------------------------------------------------------------------
 .../apache/camel/component/bean/MethodInfo.java | 56 ++++++++----
 .../BeanProcessorSpecializedMessageTest.java    | 93 ++++++++++++++++++++
 2 files changed, 133 insertions(+), 16 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/49b1240a/camel-core/src/main/java/org/apache/camel/component/bean/MethodInfo.java
----------------------------------------------------------------------
diff --git 
a/camel-core/src/main/java/org/apache/camel/component/bean/MethodInfo.java 
b/camel-core/src/main/java/org/apache/camel/component/bean/MethodInfo.java
index 532046b..41fe76c 100644
--- a/camel-core/src/main/java/org/apache/camel/component/bean/MethodInfo.java
+++ b/camel-core/src/main/java/org/apache/camel/component/bean/MethodInfo.java
@@ -37,17 +37,20 @@ import org.apache.camel.Exchange;
 import org.apache.camel.ExchangePattern;
 import org.apache.camel.Expression;
 import org.apache.camel.ExpressionEvaluationException;
+import org.apache.camel.Message;
 import org.apache.camel.NoTypeConversionAvailableException;
 import org.apache.camel.Pattern;
 import org.apache.camel.Processor;
 import org.apache.camel.RuntimeExchangeException;
 import org.apache.camel.StreamCache;
+import org.apache.camel.impl.DefaultMessage;
 import org.apache.camel.processor.DynamicRouter;
 import org.apache.camel.processor.RecipientList;
 import org.apache.camel.processor.RoutingSlip;
 import org.apache.camel.processor.aggregate.AggregationStrategy;
 import org.apache.camel.support.ExpressionAdapter;
 import org.apache.camel.util.CamelContextHelper;
+import org.apache.camel.util.ExchangeHelper;
 import org.apache.camel.util.ObjectHelper;
 import org.apache.camel.util.ServiceHelper;
 import org.apache.camel.util.StringHelper;
@@ -116,15 +119,15 @@ public class MethodInfo {
         this.hasCustomAnnotation = hasCustomAnnotation;
         this.hasHandlerAnnotation = hasHandlerAnnotation;
         this.parametersExpression = createParametersExpression();
-        
+
         Map<Class<?>, Annotation> collectedMethodAnnotation = 
collectMethodAnnotations(type, method);
 
         Pattern oneway = findOneWayAnnotation(method);
         if (oneway != null) {
             pattern = oneway.value();
         }
-        
-        org.apache.camel.RoutingSlip routingSlipAnnotation = 
+
+        org.apache.camel.RoutingSlip routingSlipAnnotation =
             
(org.apache.camel.RoutingSlip)collectedMethodAnnotation.get(org.apache.camel.RoutingSlip.class);
         if (routingSlipAnnotation != null && 
matchContext(routingSlipAnnotation.context())) {
             routingSlip = new RoutingSlip(camelContext);
@@ -138,7 +141,7 @@ public class MethodInfo {
             }
         }
 
-        org.apache.camel.DynamicRouter dynamicRouterAnnotation = 
+        org.apache.camel.DynamicRouter dynamicRouterAnnotation =
             
(org.apache.camel.DynamicRouter)collectedMethodAnnotation.get(org.apache.camel.DynamicRouter.class);
         if (dynamicRouterAnnotation != null
                 && matchContext(dynamicRouterAnnotation.context())) {
@@ -153,7 +156,7 @@ public class MethodInfo {
             }
         }
 
-        org.apache.camel.RecipientList recipientListAnnotation = 
+        org.apache.camel.RecipientList recipientListAnnotation =
             
(org.apache.camel.RecipientList)collectedMethodAnnotation.get(org.apache.camel.RecipientList.class);
         if (recipientListAnnotation != null
                 && matchContext(recipientListAnnotation.context())) {
@@ -201,7 +204,7 @@ public class MethodInfo {
         collectMethodAnnotations(c, method, annotations);
         return annotations;
     }
-    
+
     private void collectMethodAnnotations(Class<?> c, Method method, 
Map<Class<?>, Annotation> annotations) {
         for (Class<?> i : c.getInterfaces()) {
             collectMethodAnnotations(i, method, annotations);
@@ -337,16 +340,37 @@ public class MethodInfo {
     }
 
     private void fillResult(Exchange exchange, Object result) {
-        if (exchange.getPattern().isOutCapable()) {
-            // force out creating if not already created (as its lazy)
-            LOG.debug("Setting bean invocation result on the OUT message: {}", 
result);
-            exchange.getOut().setBody(result);
+        LOG.trace("Setting bean invocation result : {}", result);
+
+        // the bean component forces OUT if the MEP is OUT capable
+        boolean out = ExchangeHelper.isOutCapable(exchange) || 
exchange.hasOut();
+        Message old;
+        if (out) {
+            old = exchange.getOut();
             // propagate headers
             
exchange.getOut().getHeaders().putAll(exchange.getIn().getHeaders());
+            // propagate attachments
+            if (exchange.getIn().hasAttachments()) {
+                
exchange.getOut().getAttachments().putAll(exchange.getIn().getAttachments());
+            }
         } else {
-            // if not out then set it on the in
-            LOG.debug("Setting bean invocation result on the IN message: {}", 
result);
-            exchange.getIn().setBody(result);
+            old = exchange.getIn();
+        }
+
+        // create a new message container so we do not drag specialized 
message objects along
+        // but that is only needed if the old message is a specialized message
+        boolean copyNeeded = !(old.getClass().equals(DefaultMessage.class));
+
+        if (copyNeeded) {
+            Message msg = new DefaultMessage();
+            msg.copyFrom(old);
+            msg.setBody(result);
+
+            // replace message on exchange
+            ExchangeHelper.replaceMessage(exchange, msg, false);
+        } else {
+            // no copy needed so set replace value directly
+            old.setBody(result);
         }
     }
 
@@ -417,16 +441,16 @@ public class MethodInfo {
     public boolean isStaticMethod() {
         return Modifier.isStatic(method.getModifiers());
     }
-    
+
     /**
      * Returns true if this method is covariant with the specified method
      * (this method may above or below the specified method in the class 
hierarchy)
      */
     public boolean isCovariantWith(MethodInfo method) {
-        return 
+        return
             method.getMethod().getName().equals(this.getMethod().getName())
             && 
(method.getMethod().getReturnType().isAssignableFrom(this.getMethod().getReturnType())
-            || 
this.getMethod().getReturnType().isAssignableFrom(method.getMethod().getReturnType()))
 
+            || 
this.getMethod().getReturnType().isAssignableFrom(method.getMethod().getReturnType()))
             && Arrays.deepEquals(method.getMethod().getParameterTypes(), 
this.getMethod().getParameterTypes());
     }
 

http://git-wip-us.apache.org/repos/asf/camel/blob/49b1240a/camel-core/src/test/java/org/apache/camel/processor/BeanProcessorSpecializedMessageTest.java
----------------------------------------------------------------------
diff --git 
a/camel-core/src/test/java/org/apache/camel/processor/BeanProcessorSpecializedMessageTest.java
 
b/camel-core/src/test/java/org/apache/camel/processor/BeanProcessorSpecializedMessageTest.java
new file mode 100644
index 0000000..6e86328
--- /dev/null
+++ 
b/camel-core/src/test/java/org/apache/camel/processor/BeanProcessorSpecializedMessageTest.java
@@ -0,0 +1,93 @@
+/**
+ * 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.processor;
+
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.Exchange;
+import org.apache.camel.Predicate;
+import org.apache.camel.Processor;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.impl.DefaultMessage;
+
+/**
+ * @version 
+ */
+public class BeanProcessorSpecializedMessageTest extends ContextTestSupport {
+
+    public void testBeanSpecializedMessage() throws Exception {
+        MockEndpoint foo = getMockEndpoint("mock:foo");
+        foo.expectedBodiesReceived("Hello World");
+        foo.expectedHeaderReceived("foo", 123);
+        foo.message(0).predicate(new Predicate() {
+            public boolean matches(Exchange exchange) {
+                // this time we should have the specialized message
+                return exchange.getIn() instanceof MyMessage;
+            }
+        });
+
+        MockEndpoint result = getMockEndpoint("mock:result");
+        result.message(0).body().isNull();
+        result.expectedHeaderReceived("foo", 123);
+        result.message(0).predicate(new Predicate() {
+            public boolean matches(Exchange exchange) {
+                // this time we should have lost the specialized message
+                return !(exchange.getIn() instanceof MyMessage);
+            }
+        });
+
+        template.send("direct:start", new Processor() {
+            public void process(Exchange exchange) throws Exception {
+                MyMessage my = new MyMessage();
+                my.setBody("Hello World");
+                my.setHeader("foo", 123);
+                exchange.setIn(my);
+            }
+        });
+
+        assertMockEndpointsSatisfied();
+    }
+    
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                from("direct:start")
+                    .to("mock:foo")
+                    .bean(MyBean.class, "empty")
+                    .to("mock:result");
+            }
+        };
+    }
+
+    public static class MyMessage extends DefaultMessage {
+
+        @Override
+        public MyMessage newInstance() {
+            return new MyMessage();
+        }
+    }
+
+    public static class MyBean {
+
+        public static String empty(String body) {
+            // set null as body
+            return null;
+        }
+    }
+}

Reply via email to