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 {