Author: davsclaus
Date: Tue Oct 14 12:31:55 2008
New Revision: 704632

URL: http://svn.apache.org/viewvc?rev=704632&view=rev
Log:
CAMEL-983: BeanInfo considers overridden methods when selection method. 
Polished unit test.

Added:
    
activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanInfoInheritanceTest.java
Modified:
    
activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/BeanInfo.java
    
activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/processor/BeanRecipientListTest.java
    
activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/processor/SplitterTest.java

Modified: 
activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/BeanInfo.java
URL: 
http://svn.apache.org/viewvc/activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/BeanInfo.java?rev=704632&r1=704631&r2=704632&view=diff
==============================================================================
--- 
activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/BeanInfo.java
 (original)
+++ 
activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/BeanInfo.java
 Tue Oct 14 12:31:55 2008
@@ -19,7 +19,12 @@
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 
 import org.apache.camel.Body;
@@ -36,12 +41,11 @@
 import org.apache.camel.builder.ExpressionBuilder;
 import org.apache.camel.language.LanguageAnnotation;
 import org.apache.camel.spi.Registry;
+import static org.apache.camel.util.ExchangeHelper.convertToType;
 import org.apache.camel.util.ObjectHelper;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
-import static org.apache.camel.util.ExchangeHelper.convertToType;
-
 /**
  * Represents the metadata about a bean type created via a combination of
  * introspection and annotations together with some useful sensible defaults
@@ -116,6 +120,9 @@
     }
 
     protected void introspect(Class clazz) {
+        if (LOG.isTraceEnabled()) {
+            LOG.trace("Introspecting class: " + clazz);
+        }
         Method[] methods = clazz.getDeclaredMethods();
         for (Method method : methods) {
             if (isValidMethod(clazz, method)) {
@@ -129,26 +136,68 @@
     }
 
     protected MethodInfo introspect(Class clazz, Method method) {
+        if (LOG.isTraceEnabled()) {
+            LOG.trace("Introspecting class: " + clazz + ", method: " + method);
+        }
         String opName = method.getName();
 
         MethodInfo methodInfo = createMethodInfo(clazz, method);
 
+        // skip methods that override existing methods we already have in our 
methodMap
+        if (overridesExistingMethod(methodInfo)) {
+            if (LOG.isTraceEnabled()) {
+                LOG.trace("This method is already overriden in a subclass, so 
its skipped: " + method);
+            }
+            return null;
+        }
+
+        if (LOG.isTraceEnabled()) {
+            LOG.trace("Adding operation: " + opName + " for method: " + 
methodInfo);
+        }
         operations.put(opName, methodInfo);
+        methodMap.put(method, methodInfo);
+
         if (methodInfo.hasBodyParameter()) {
             operationsWithBody.add(methodInfo);
         }
         if (methodInfo.isHasCustomAnnotation() && 
!methodInfo.hasBodyParameter()) {
             operationsWithCustomAnnotation.add(methodInfo);
         }
-        methodMap.put(method, methodInfo);
+
         return methodInfo;
     }
 
+    private boolean overridesExistingMethod(MethodInfo methodInfo) {
+        for (MethodInfo info : methodMap.values()) {
+
+            // name test
+            if 
(!info.getMethod().getName().equals(methodInfo.getMethod().getName())) {
+                continue;
+            }
+
+            // parameter types
+            if (info.getMethod().getParameterTypes().length != 
methodInfo.getMethod().getParameterTypes().length) {
+                continue;
+            }
+
+            for (int i = 0; i < info.getMethod().getParameterTypes().length; 
i++) {
+                Class type1 = info.getMethod().getParameterTypes()[i];
+                Class type2 = methodInfo.getMethod().getParameterTypes()[i];
+                if (!type1.equals(type2)) {
+                    continue;
+                }
+            }
+
+            // sanme name, same parameters, then its overrides an existing 
class
+            return true;
+        }
+
+        return false;
+    }
+
     /**
      * Returns the [EMAIL PROTECTED] MethodInfo} for the given method if it 
exists or null
      * if there is no metadata available for the given method
-     *
-     * @param method
      */
     public MethodInfo getMethodInfo(Method method) {
         MethodInfo answer = methodMap.get(method);
@@ -165,7 +214,6 @@
         return answer;
     }
 
-
     protected MethodInfo createMethodInfo(Class clazz, Method method) {
         Class[] parameterTypes = method.getParameterTypes();
         Annotation[][] parametersAnnotations = 
method.getParameterAnnotations();
@@ -240,6 +288,9 @@
         Object body = in.getBody();
         if (body != null) {
             Class bodyType = body.getClass();
+            if (LOG.isTraceEnabled()) {
+                LOG.trace("Matching for method with a single parameter that 
matches type: " + bodyType.getCanonicalName());
+            }
 
             List<MethodInfo> possibles = new ArrayList<MethodInfo>();
             for (MethodInfo methodInfo : operationList) {

Added: 
activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanInfoInheritanceTest.java
URL: 
http://svn.apache.org/viewvc/activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanInfoInheritanceTest.java?rev=704632&view=auto
==============================================================================
--- 
activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanInfoInheritanceTest.java
 (added)
+++ 
activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanInfoInheritanceTest.java
 Tue Oct 14 12:31:55 2008
@@ -0,0 +1,121 @@
+/**
+ * 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 junit.framework.Assert;
+
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.impl.DefaultExchange;
+
+/**
+ * Unit test for overridden methods in an inheritance.
+ */
+public class BeanInfoInheritanceTest extends ContextTestSupport {
+
+    public void testInheritance() throws Exception {
+        BeanInfo beanInfo = new BeanInfo(context, Y.class);
+
+        DefaultExchange exchange = new DefaultExchange(context);
+        exchange.getIn().setBody(new Request());
+
+        try {
+            MethodInvocation mi = beanInfo.createInvocation(null, exchange);
+            assertNotNull(mi);
+            assertEquals("process", mi.getMethod().getName());
+            assertEquals("Y", 
mi.getMethod().getDeclaringClass().getSimpleName());
+        } catch (AmbiguousMethodCallException e) {
+            Assert.fail("This should not be ambiguous!");
+        }
+    }
+
+    public void testNoInheritance() throws Exception {
+        BeanInfo beanInfo = new BeanInfo(context, A.class);
+
+        DefaultExchange exchange = new DefaultExchange(context);
+        exchange.getIn().setBody(new Request());
+
+        try {
+            MethodInvocation mi = beanInfo.createInvocation(null, exchange);
+            assertNotNull(mi);
+            assertEquals("process", mi.getMethod().getName());
+            assertEquals("A", 
mi.getMethod().getDeclaringClass().getSimpleName());
+        } catch (AmbiguousMethodCallException e) {
+            Assert.fail("This should not be ambiguous!");
+        }
+    }
+
+    public void testInheritanceAndOverload() throws Exception {
+        BeanInfo beanInfo = new BeanInfo(context, Z.class);
+
+        DefaultExchange exchange = new DefaultExchange(context);
+        exchange.getIn().setBody(new Request());
+
+        try {
+            MethodInvocation mi = beanInfo.createInvocation(null, exchange);
+            Assert.fail("This should be ambiguous!");
+        } catch (AmbiguousMethodCallException e) {
+            // expected (currently not supported in camel)
+        }
+    }
+
+    public static class Request {
+        int x;
+    }
+
+    public static class X {
+
+        public int process(Request request) {
+            return 0;
+        }
+    }
+
+    public static class Y extends X {
+
+        public int process(Request request) {
+            return 1;
+        }
+
+        public int compute(String body) {
+            return 2;
+        }
+    }
+
+    public static class Z extends Y {
+
+        public int compute(Request request) {
+            return 2;
+        }
+
+        public int process(Request request, String body) {
+            return 3;
+        }
+    }
+
+    public static class A {
+
+        public void doSomething(String body) {
+            // noop
+        }
+
+        public int process(Request request) {
+            return 0;
+        }
+    }
+
+}
+
+

Modified: 
activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/processor/BeanRecipientListTest.java
URL: 
http://svn.apache.org/viewvc/activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/processor/BeanRecipientListTest.java?rev=704632&r1=704631&r2=704632&view=diff
==============================================================================
--- 
activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/processor/BeanRecipientListTest.java
 (original)
+++ 
activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/processor/BeanRecipientListTest.java
 Tue Oct 14 12:31:55 2008
@@ -82,7 +82,7 @@
 
         @org.apache.camel.RecipientList
         public String[] route(String body) {
-            System.out.println("Called " + this + " with body: " + body);
+            LOG.debug("Called " + this + " with body: " + body);
             return new String[] {"mock:a", "mock:b"};
         }
     }

Modified: 
activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/processor/SplitterTest.java
URL: 
http://svn.apache.org/viewvc/activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/processor/SplitterTest.java?rev=704632&r1=704631&r2=704632&view=diff
==============================================================================
--- 
activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/processor/SplitterTest.java
 (original)
+++ 
activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/processor/SplitterTest.java
 Tue Oct 14 12:31:55 2008
@@ -141,6 +141,7 @@
     public void testSpliterWithAggregationStrategyParallelStreaming() throws 
Exception {
         MockEndpoint resultEndpoint = getMockEndpoint("mock:result");
         resultEndpoint.expectedMessageCount(5);
+        resultEndpoint.expectedBodiesReceivedInAnyOrder("James", "Guillaume", 
"Hiram", "Rob", "Roman");
 
         Exchange result = template.send("direct:parallel-streaming", new 
Processor() {
             public void process(Exchange exchange) {
@@ -155,7 +156,6 @@
 
         assertMessageHeader(out, "foo", "bar");
         assertEquals((Integer)5, result.getProperty("aggregated", 
Integer.class));
-        System.out.println(result);
     }
     
     public void testSplitterWithStreaming() throws Exception {


Reply via email to