You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by js...@apache.org on 2008/08/11 18:31:44 UTC
svn commit: r684800 - in /activemq/camel/trunk/camel-core/src:
main/java/org/apache/camel/ main/java/org/apache/camel/component/bean/
test/java/org/apache/camel/component/bean/
Author: jstrachan
Date: Mon Aug 11 09:31:43 2008
New Revision: 684800
URL: http://svn.apache.org/viewvc?rev=684800&view=rev
Log:
added a test case for CAMEL-810 showing the use of class, base class, interface and method level annotations all working together nicely
Added:
activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanInfoTest.java (contents, props changed)
- copied, changed from r684774, activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanInfoTestTest.java
Modified:
activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/OneWay.java
activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/BeanInfo.java
activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/MethodInfo.java
Modified: activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/OneWay.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/OneWay.java?rev=684800&r1=684799&r2=684800&view=diff
==============================================================================
--- activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/OneWay.java (original)
+++ activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/OneWay.java Mon Aug 11 09:31:43 2008
@@ -25,6 +25,22 @@
* Marks a method as being a one way asynchronous invocation so that if you are using some kind of
* <a href="http://activemq.apache.org/camel/spring-remoting.html">Spring Remoting</a> then the method invocation will be asynchronous.
*
+ * You can then either annotate specific methods as being oneway / asynchronous via
+ * <code>
+ * @OneWay
+ * public void myMethod() {...}
+ * </code>
+ *
+ * or you can say that all methods are by default asynchronous on an interface by annotating the interface
+ *
+ * <code>
+ * @OneWay
+ * public interface Foo {
+ * void methodOne();
+ * void methodTwo();
+ * }
+ * </code>
+ *
* If you wish to use some other {@link ExchangePattern} than {@link org.apache.camel.ExchangePattern#InOnly} you could use something like
*
* <code>
@@ -39,13 +55,27 @@
* public void myMethod() {...}
* </code>
*
+ * You can also use the annotation to disable the one way pattern on specific methods as follows...
+ *
+ * <code>
+ * @OneWay
+ * public interface Foo {
+ * void methodOne();
+ *
+ * @OneWay(ExchangePattern.InOut)
+ * void notOneWayMethod();
+ * }
+ *
+ * Where the <b>notOneWayMethod</b> will not be using one way invocation while all other methods will inherit the InOut exchange pattern
+ *
+ * </code>
* @see ExchangePattern
* @see Exchange#getPattern()
*
* @version $Revision$
*/
@Retention(RetentionPolicy.RUNTIME)
-@Target({ElementType.METHOD })
+@Target({ElementType.TYPE, ElementType.METHOD})
public @interface OneWay {
/**
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=684800&r1=684799&r2=684800&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 Mon Aug 11 09:31:43 2008
@@ -58,6 +58,7 @@
private List<MethodInfo> operationsWithBody = new ArrayList<MethodInfo>();
private List<MethodInfo> operationsWithCustomAnnotation = new ArrayList<MethodInfo>();
private Map<Method, MethodInfo> methodMap = new HashMap<Method, MethodInfo>();
+ private BeanInfo superBeanInfo;
public BeanInfo(CamelContext camelContext, Class type) {
this(camelContext, type, createParameterMappingStrategy(camelContext));
@@ -150,7 +151,18 @@
* @param method
*/
public MethodInfo getMethodInfo(Method method) {
- return methodMap.get(method);
+ MethodInfo answer = methodMap.get(method);
+ if (answer == null) {
+ // maybe the method is defined on a base class?
+ if (superBeanInfo == null && type != Object.class) {
+ Class superclass = type.getSuperclass();
+ if (superclass != null && superclass != Object.class) {
+ superBeanInfo = new BeanInfo(camelContext, superclass, strategy);
+ return superBeanInfo.getMethodInfo(method);
+ }
+ }
+ }
+ return answer;
}
Modified: activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/MethodInfo.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/MethodInfo.java?rev=684800&r1=684799&r2=684800&view=diff
==============================================================================
--- activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/MethodInfo.java (original)
+++ activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/MethodInfo.java Mon Aug 11 09:31:43 2008
@@ -22,6 +22,7 @@
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
+import java.util.ArrayList;
import org.apache.camel.Exchange;
import org.apache.camel.Expression;
@@ -51,7 +52,7 @@
this.bodyParameters = bodyParameters;
this.hasCustomAnnotation = hasCustomAnnotation;
this.parametersExpression = createParametersExpression();
- OneWay oneway = method.getAnnotation(OneWay.class);
+ OneWay oneway = findOneWayAnnotation(method);
if (oneway != null) {
pattern = oneway.value();
}
@@ -94,6 +95,17 @@
return method;
}
+ /**
+ * Returns the {@link org.apache.camel.ExchangePattern} that should be used when invoking this method. This value
+ * defaults to {@link org.apache.camel.ExchangePattern#InOut} unless some {@link OneWay} annotation is used
+ * to override the message exchange pattern.
+ *
+ * @return the exchange pattern to use for invoking this method.
+ */
+ public ExchangePattern getPattern() {
+ return pattern;
+ }
+
public Expression getParametersExpression() {
return parametersExpression;
}
@@ -169,7 +181,77 @@
};
}
- public ExchangePattern getPattern() {
- return pattern;
+ /**
+ * Finds the oneway annotation in priority order; look for method level annotations first, then the class level annotations,
+ * then super class annotations then interface annotations
+ *
+ * @param method the method on which to search
+ * @return the first matching annotation or none if it is not available
+ */
+ protected OneWay findOneWayAnnotation(Method method) {
+ OneWay answer = method.getAnnotation(OneWay.class);
+ if (answer == null) {
+ Class<?> type = method.getDeclaringClass();
+
+ // lets create the search order of types to scan
+ List<Class<?>> typesToSearch = new ArrayList<Class<?>>();
+ addTypeAndSuperTypes(type, typesToSearch);
+ Class[] interfaces = type.getInterfaces();
+ for (Class anInterface : interfaces) {
+ addTypeAndSuperTypes(anInterface, typesToSearch);
+ }
+
+ // now lets scan for a type which the current declared class overloads
+ answer = findOneWayAnnotationOnMethod(typesToSearch, method);
+ if (answer == null ){
+ answer = findOneWayAnnotation(typesToSearch);
+ }
+ }
+ return answer;
+ }
+
+ /**
+ * Adds the current class and all of its base classes (apart from {@link Object} to the given list
+ * @param type
+ * @param result
+ */
+ protected void addTypeAndSuperTypes(Class<?> type, List<Class<?>> result) {
+ for (Class<?> t = type; t != null && t != Object.class; t = t.getSuperclass()) {
+ result.add(t);
+ }
+ }
+
+ /**
+ * Finds the first annotation on the base methods defined in the list of classes
+ */
+ protected OneWay findOneWayAnnotationOnMethod(List<Class<?>> classes, Method method) {
+ for (Class<?> type : classes) {
+ try {
+ Method definedMethod = type.getMethod(method.getName(), method.getParameterTypes());
+ OneWay answer = definedMethod.getAnnotation(OneWay.class);
+ if (answer != null) {
+ return answer;
+ }
+ } catch (NoSuchMethodException e) {
+ // ignore
+ }
+ }
+ return null;
+ }
+
+
+ /**
+ * Finds the first annotation on the given list of classes
+ */
+ protected OneWay findOneWayAnnotation(List<Class<?>> classes) {
+ for (Class<?> type : classes) {
+ OneWay answer = type.getAnnotation(OneWay.class);
+ if (answer != null) {
+ return answer;
+ }
+ }
+ return null;
}
+
+
}
Copied: activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanInfoTest.java (from r684774, activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanInfoTestTest.java)
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanInfoTest.java?p2=activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanInfoTest.java&p1=activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanInfoTestTest.java&r1=684774&r2=684800&rev=684800&view=diff
==============================================================================
--- activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanInfoTestTest.java (original)
+++ activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanInfoTest.java Mon Aug 11 09:31:43 2008
@@ -22,23 +22,74 @@
import org.apache.camel.ExchangePattern;
import org.apache.camel.CamelContext;
import org.apache.camel.impl.DefaultCamelContext;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
import java.lang.reflect.Method;
/**
* @version $Revision: 1.1 $
*/
-public class BeanInfoTestTest extends TestCase {
+public class BeanInfoTest extends TestCase {
+ private static final transient Log LOG = LogFactory.getLog(BeanInfoTest.class);
+
protected CamelContext camelContext = new DefaultCamelContext();
- protected BeanInfo info = new BeanInfo(camelContext, Foo.class);
- public void testMethodPattern() throws Exception {
- assertMethodPattern("inOutMethod", ExchangePattern.InOut);
- assertMethodPattern("inOnlyMethod", ExchangePattern.InOnly);
- assertMethodPattern("robustInOnlyMethod", ExchangePattern.RobustInOnly);
+ public void testMethodPatternUsingMethodAnnotations() throws Exception {
+ BeanInfo info = createBeanInfo(Foo.class);
+
+ assertMethodPattern(info, "inOutMethod", ExchangePattern.InOut);
+ assertMethodPattern(info, "inOnlyMethod", ExchangePattern.InOnly);
+ assertMethodPattern(info, "robustInOnlyMethod", ExchangePattern.RobustInOnly);
+ }
+
+ public void testMethodPatternUsingClassAnnotationsOnInterface() throws Exception {
+ BeanInfo info = createBeanInfo(MyOneWayInterface.class);
+
+ assertMethodPattern(info, "inOnlyMethod", ExchangePattern.InOnly);
+ }
+
+ public void testMethodPatternUsingMethodAnnotationsOnInterface() throws Exception {
+ BeanInfo info = createBeanInfo(MyOneWayInterfaceWithOverloadedMethod.class);
+
+ assertMethodPattern(info, "inOnlyMethod", ExchangePattern.InOnly);
+ assertMethodPattern(info, "robustInOnlyMethod", ExchangePattern.RobustInOnly);
+ }
+
+ public void testMethodPatternUsingClassAnnotationsButOverloadingOnMethod() throws Exception {
+ BeanInfo info = createBeanInfo(OverloadOnMethod.class);
+
+ assertMethodPattern(info, "inOnlyMethod", ExchangePattern.InOnly);
+ assertMethodPattern(info, "robustInOnlyMethod", ExchangePattern.RobustInOnly);
+ }
+
+ public void testMethodPatternUsingClassAnnotationsButOverloadingOnBaseClassMethod() throws Exception {
+ BeanInfo info = createBeanInfo(OverloadOnBaseClass.class);
+
+ assertMethodPattern(info, "inOnlyMethod", ExchangePattern.InOnly);
+ assertMethodPattern(info, "robustInOnlyMethod", ExchangePattern.RobustInOnly);
+ }
+
+ public void testMethodPatternUsingClassAnnotationsOnClassWithAnnotationsOnInterface() throws Exception {
+ BeanInfo info = createBeanInfo(OverloadOnMethod.class);
+
+ assertMethodPattern(info, "inOnlyMethod", ExchangePattern.InOnly);
+ assertMethodPattern(info, "robustInOnlyMethod", ExchangePattern.RobustInOnly);
+ }
+
+ public void testMethodPatternUsingClassAnnotationsOnBaseInterfaceAndOverloadingMethodOnDerivedInterface() throws Exception {
+ BeanInfo info = createBeanInfo(OverloadOnInterface.class);
+
+ assertMethodPattern(info, "inOnlyMethod", ExchangePattern.InOnly);
+ assertMethodPattern(info, "robustInOnlyMethod", ExchangePattern.RobustInOnly);
+ }
+
+ protected BeanInfo createBeanInfo(Class type) {
+ BeanInfo info = new BeanInfo(camelContext, type);
+ return info;
}
- protected void assertMethodPattern(String methodName, ExchangePattern expectedPattern) throws NoSuchMethodException {
+ protected void assertMethodPattern(BeanInfo info, String methodName, ExchangePattern expectedPattern) throws NoSuchMethodException {
Class type = info.getType();
Method method = type.getMethod(methodName);
assertNotNull("Could not find method: " + methodName, method);
@@ -49,7 +100,7 @@
ExchangePattern actualPattern = methodInfo.getPattern();
assertEquals("Pattern for: " + method, expectedPattern, actualPattern);
- //System.out.println("Method: " + method + " has pattern: " + actualPattern);
+ LOG.info("Method: " + method + " has pattern: " + actualPattern);
}
public interface Foo {
@@ -61,4 +112,42 @@
@OneWay(ExchangePattern.RobustInOnly)
public void robustInOnlyMethod();
}
+
+ @OneWay
+ public interface MyOneWayInterface {
+ public void inOnlyMethod();
+ }
+
+ @OneWay
+ public interface MyOneWayInterfaceWithOverloadedMethod {
+ public void inOnlyMethod();
+
+ @OneWay(ExchangePattern.RobustInOnly)
+ public void robustInOnlyMethod();
+ }
+
+ public static class OverloadOnMethod implements MyOneWayInterface {
+
+ public void inOnlyMethod() {
+ }
+
+ @OneWay(ExchangePattern.RobustInOnly)
+ public void robustInOnlyMethod() {
+ }
+ }
+
+ public static class OverloadOnBaseClass extends OverloadOnMethod {
+ public void robustInOnlyMethod() {
+ }
+ }
+
+ public static class OverloadOnInterface implements MyOneWayInterfaceWithOverloadedMethod {
+
+ public void inOnlyMethod() {
+ }
+
+ public void robustInOnlyMethod() {
+ }
+ }
+
}
Propchange: activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanInfoTest.java
------------------------------------------------------------------------------
svn:eol-style = native